1{
2 pkgs,
3 lib,
4 config,
5 ...
6}:
7
8with lib;
9
10let
11 cfg = config.services.thelounge;
12 dataDir = "/var/lib/thelounge";
13 configJsData =
14 "module.exports = " + builtins.toJSON ({ inherit (cfg) public port; } // cfg.extraConfig);
15 pluginManifest = {
16 dependencies = builtins.listToAttrs (
17 builtins.map (pkg: {
18 name = getName pkg;
19 value = getVersion pkg;
20 }) cfg.plugins
21 );
22 };
23 plugins =
24 pkgs.runCommand "thelounge-plugins"
25 {
26 preferLocalBuild = true;
27 }
28 ''
29 mkdir -p $out/node_modules
30 echo ${escapeShellArg (builtins.toJSON pluginManifest)} >> $out/package.json
31 ${concatMapStringsSep "\n" (pkg: ''
32 ln -s ${pkg}/lib/node_modules/${getName pkg} $out/node_modules/${getName pkg}
33 '') cfg.plugins}
34 '';
35in
36{
37 imports = [
38 (mkRemovedOptionModule [
39 "services"
40 "thelounge"
41 "private"
42 ] "The option was renamed to `services.thelounge.public` to follow upstream changes.")
43 ];
44
45 options.services.thelounge = {
46 enable = mkEnableOption "The Lounge web IRC client";
47
48 package = mkPackageOption pkgs "thelounge" { };
49
50 public = mkOption {
51 type = types.bool;
52 default = false;
53 description = ''
54 Make your The Lounge instance public.
55 Setting this to `false` will require you to configure user
56 accounts by using the ({command}`thelounge`) command or by adding
57 entries in {file}`${dataDir}/users`. You might need to restart
58 The Lounge after making changes to the state directory.
59 '';
60 };
61
62 port = mkOption {
63 type = types.port;
64 default = 9000;
65 description = "TCP port to listen on for http connections.";
66 };
67
68 extraConfig = mkOption {
69 default = { };
70 type = types.attrs;
71 example = literalExpression ''
72 {
73 reverseProxy = true;
74 defaults = {
75 name = "Your Network";
76 host = "localhost";
77 port = 6697;
78 };
79 }
80 '';
81 description = ''
82 The Lounge's {file}`config.js` contents as attribute set (will be
83 converted to JSON to generate the configuration file).
84
85 The options defined here will be merged to the default configuration file.
86 Note: In case of duplicate configuration, options from {option}`extraConfig` have priority.
87
88 Documentation: <https://thelounge.chat/docs/server/configuration>
89 '';
90 };
91
92 plugins = mkOption {
93 default = [ ];
94 type = types.listOf types.package;
95 example = literalExpression "[ pkgs.theLoungePlugins.themes.solarized ]";
96 description = ''
97 The Lounge plugins to install. Plugins can be found in
98 `pkgs.theLoungePlugins.plugins` and `pkgs.theLoungePlugins.themes`.
99 '';
100 };
101 };
102
103 config = mkIf cfg.enable {
104 users.users.thelounge = {
105 description = "The Lounge service user";
106 group = "thelounge";
107 isSystemUser = true;
108 };
109
110 users.groups.thelounge = { };
111
112 systemd.services.thelounge = {
113 description = "The Lounge web IRC client";
114 wantedBy = [ "multi-user.target" ];
115 preStart = "ln -sf ${pkgs.writeText "config.js" configJsData} ${dataDir}/config.js";
116 environment.THELOUNGE_PACKAGES = mkIf (cfg.plugins != [ ]) "${plugins}";
117 serviceConfig = {
118 User = "thelounge";
119 StateDirectory = baseNameOf dataDir;
120 ExecStart = "${getExe cfg.package} start";
121 };
122 };
123
124 environment.systemPackages = [ cfg.package ];
125 };
126
127 meta = {
128 maintainers = with lib.maintainers; [ winter ];
129 };
130}