summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services/networking/thelounge.nix
blob: d46aef2f32e58bf89733a6ea44589fd0a3260cf8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
{
  pkgs,
  lib,
  config,
  ...
}:

with lib;

let
  cfg = config.services.thelounge;
  dataDir = "/var/lib/thelounge";
  configJsData =
    "module.exports = " + builtins.toJSON ({ inherit (cfg) public port; } // cfg.extraConfig);
  pluginManifest = {
    dependencies = builtins.listToAttrs (
      map (pkg: {
        name = getName pkg;
        value = getVersion pkg;
      }) cfg.plugins
    );
  };
  plugins =
    pkgs.runCommand "thelounge-plugins"
      {
        preferLocalBuild = true;
      }
      ''
        mkdir -p $out/node_modules
        echo ${escapeShellArg (builtins.toJSON pluginManifest)} >> $out/package.json
        ${concatMapStringsSep "\n" (pkg: ''
          ln -s ${pkg}/lib/node_modules/${getName pkg} $out/node_modules/${getName pkg}
        '') cfg.plugins}
      '';
in
{
  imports = [
    (mkRemovedOptionModule [
      "services"
      "thelounge"
      "private"
    ] "The option was renamed to `services.thelounge.public` to follow upstream changes.")
  ];

  options.services.thelounge = {
    enable = mkEnableOption "The Lounge web IRC client";

    package = mkPackageOption pkgs "thelounge" { };

    public = mkOption {
      type = types.bool;
      default = false;
      description = ''
        Make your The Lounge instance public.
        Setting this to `false` will require you to configure user
        accounts by using the ({command}`thelounge`) command or by adding
        entries in {file}`${dataDir}/users`. You might need to restart
        The Lounge after making changes to the state directory.
      '';
    };

    port = mkOption {
      type = types.port;
      default = 9000;
      description = "TCP port to listen on for http connections.";
    };

    extraConfig = mkOption {
      default = { };
      type = types.attrs;
      example = literalExpression ''
        {
          reverseProxy = true;
          defaults = {
            name = "Your Network";
            host = "localhost";
            port = 6697;
          };
        }
      '';
      description = ''
        The Lounge's {file}`config.js` contents as attribute set (will be
        converted to JSON to generate the configuration file).

        The options defined here will be merged to the default configuration file.
        Note: In case of duplicate configuration, options from {option}`extraConfig` have priority.

        Documentation: <https://thelounge.chat/docs/server/configuration>
      '';
    };

    plugins = mkOption {
      default = [ ];
      type = types.listOf types.package;
      example = literalExpression "[ pkgs.theLoungePlugins.themes.solarized ]";
      description = ''
        The Lounge plugins to install. Plugins can be found in
        `pkgs.theLoungePlugins.plugins` and `pkgs.theLoungePlugins.themes`.
      '';
    };
  };

  config = mkIf cfg.enable {
    users.users.thelounge = {
      description = "The Lounge service user";
      group = "thelounge";
      isSystemUser = true;
    };

    users.groups.thelounge = { };

    systemd.services.thelounge = {
      description = "The Lounge web IRC client";
      wantedBy = [ "multi-user.target" ];
      after = [ "network-online.target" ];
      wants = [ "network-online.target" ];
      preStart = "ln -sf ${pkgs.writeText "config.js" configJsData} ${dataDir}/config.js";
      environment.THELOUNGE_PACKAGES = mkIf (cfg.plugins != [ ]) "${plugins}";
      serviceConfig = {
        User = "thelounge";
        StateDirectory = baseNameOf dataDir;
        ExecStart = "${getExe cfg.package} start";
      };
    };

    environment.systemPackages = [ cfg.package ];
  };

  meta = {
    maintainers = with lib.maintainers; [ winter ];
  };
}