1{
2 config,
3 lib,
4 options,
5 pkgs,
6 ...
7}:
8let
9 cfg = config.services.ergochat;
10in
11{
12 options = {
13 services.ergochat = {
14
15 enable = lib.mkEnableOption "Ergo IRC daemon";
16
17 openFilesLimit = lib.mkOption {
18 type = lib.types.int;
19 default = 1024;
20 description = ''
21 Maximum number of open files. Limits the clients and server connections.
22 '';
23 };
24
25 configFile = lib.mkOption {
26 type = lib.types.path;
27 default = (pkgs.formats.yaml { }).generate "ergo.conf" cfg.settings;
28 defaultText = lib.literalMD "generated config file from `settings`";
29 description = ''
30 Path to configuration file.
31 Setting this will skip any configuration done via `settings`
32 '';
33 };
34
35 settings = lib.mkOption {
36 type = (pkgs.formats.yaml { }).type;
37 description = ''
38 Ergo IRC daemon configuration file.
39 https://raw.githubusercontent.com/ergochat/ergo/master/default.yaml
40 '';
41 default = {
42 network = {
43 name = "testnetwork";
44 };
45 server = {
46 name = "example.com";
47 listeners = {
48 ":6667" = { };
49 };
50 casemapping = "permissive";
51 enforce-utf = true;
52 lookup-hostnames = false;
53 ip-cloaking = {
54 enabled = false;
55 };
56 forward-confirm-hostnames = false;
57 check-ident = false;
58 relaymsg = {
59 enabled = false;
60 };
61 max-sendq = "1M";
62 ip-limits = {
63 count = false;
64 throttle = false;
65 };
66 };
67 datastore = {
68 autoupgrade = true;
69 # this points to the StateDirectory of the systemd service
70 path = "/var/lib/ergo/ircd.db";
71 };
72 accounts = {
73 authentication-enabled = true;
74 registration = {
75 enabled = true;
76 allow-before-connect = true;
77 throttling = {
78 enabled = true;
79 duration = "10m";
80 max-attempts = 30;
81 };
82 bcrypt-cost = 4;
83 email-verification.enabled = false;
84 };
85 multiclient = {
86 enabled = true;
87 allowed-by-default = true;
88 always-on = "opt-out";
89 auto-away = "opt-out";
90 };
91 };
92 channels = {
93 default-modes = "+ntC";
94 registration = {
95 enabled = true;
96 };
97 };
98 limits = {
99 nicklen = 32;
100 identlen = 20;
101 channellen = 64;
102 awaylen = 390;
103 kicklen = 390;
104 topiclen = 390;
105 };
106 history = {
107 enabled = true;
108 channel-length = 2048;
109 client-length = 256;
110 autoresize-window = "3d";
111 autoreplay-on-join = 0;
112 chathistory-maxmessages = 100;
113 znc-maxmessages = 2048;
114 restrictions = {
115 expire-time = "1w";
116 query-cutoff = "none";
117 grace-period = "1h";
118 };
119 retention = {
120 allow-individual-delete = false;
121 enable-account-indexing = false;
122 };
123 tagmsg-storage = {
124 default = false;
125 whitelist = [
126 "+draft/react"
127 "+react"
128 ];
129 };
130 };
131 };
132 };
133
134 };
135 };
136 config = lib.mkIf cfg.enable {
137
138 environment.etc."ergo.yaml".source = cfg.configFile;
139
140 # merge configured values with default values
141 services.ergochat.settings = lib.mapAttrsRecursive (
142 _: lib.mkDefault
143 ) options.services.ergochat.settings.default;
144
145 systemd.services.ergochat = {
146 description = "Ergo IRC daemon";
147 wantedBy = [ "multi-user.target" ];
148 # reload is not applying the changed config. further investigation is needed
149 # at some point this should be enabled, since we don't want to restart for
150 # every config change
151 # reloadIfChanged = true;
152 restartTriggers = [ cfg.configFile ];
153 serviceConfig = {
154 ExecStart = "${pkgs.ergochat}/bin/ergo run --conf /etc/ergo.yaml";
155 ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID";
156 DynamicUser = true;
157 StateDirectory = "ergo";
158 LimitNOFILE = toString cfg.openFilesLimit;
159 };
160 };
161
162 };
163 meta.maintainers = with lib.maintainers; [
164 lassulus
165 tv
166 ];
167}