vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / netbird / dashboard.nix
blob788b724231be315d2500a30161c27dee690e7f03
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 let
9   inherit (lib)
10     boolToString
11     concatStringsSep
12     hasAttr
13     isBool
14     mapAttrs
15     mkDefault
16     mkEnableOption
17     mkIf
18     mkOption
19     mkPackageOption
20     ;
22   inherit (lib.types)
23     attrsOf
24     bool
25     either
26     package
27     str
28     submodule
29     ;
31   toStringEnv = value: if isBool value then boolToString value else toString value;
33   cfg = config.services.netbird.server.dashboard;
37   options.services.netbird.server.dashboard = {
38     enable = mkEnableOption "the static netbird dashboard frontend";
40     package = mkPackageOption pkgs "netbird-dashboard" { };
42     enableNginx = mkEnableOption "Nginx reverse-proxy to serve the dashboard";
44     domain = mkOption {
45       type = str;
46       default = "localhost";
47       description = "The domain under which the dashboard runs.";
48     };
50     managementServer = mkOption {
51       type = str;
52       description = "The address of the management server, used for the API endpoints.";
53     };
55     settings = mkOption {
56       type = submodule { freeformType = attrsOf (either str bool); };
58       defaultText = ''
59         {
60           AUTH_AUDIENCE = "netbird";
61           AUTH_CLIENT_ID = "netbird";
62           AUTH_SUPPORTED_SCOPES = "openid profile email";
63           NETBIRD_TOKEN_SOURCE = "idToken";
64           USE_AUTH0 = false;
65         }
66       '';
68       description = ''
69         An attribute set that will be used to substitute variables when building the dashboard.
70         Any values set here will be templated into the frontend and be public for anyone that can reach your website.
71         The exact values sadly aren't documented anywhere.
72         A starting point when searching for valid values is this [script](https://github.com/netbirdio/dashboard/blob/main/docker/init_react_envs.sh)
73         The only mandatory value is 'AUTH_AUTHORITY' as we cannot set a default value here.
74       '';
75     };
77     finalDrv = mkOption {
78       readOnly = true;
79       type = package;
80       description = ''
81         The derivation containing the final templated dashboard.
82       '';
83     };
84   };
86   config = mkIf cfg.enable {
87     assertions = [
88       {
89         assertion = hasAttr "AUTH_AUTHORITY" cfg.settings;
90         message = "The setting AUTH_AUTHORITY is required for the dasboard to function.";
91       }
92     ];
94     services.netbird.server.dashboard = {
95       settings =
96         {
97           # Due to how the backend and frontend work this secret will be templated into the backend
98           # and then served statically from your website
99           # This enables you to login without the normally needed indirection through the backend
100           # but this also means anyone that can reach your website can
101           # fetch this secret, which is why there is no real need to put it into
102           # special options as its public anyway
103           # As far as I know leaking this secret is just
104           # an information leak as one can fetch some basic app
105           # informations from the IDP
106           # To actually do something one still needs to have login
107           # data and this secret so this being public will not
108           # suffice for anything just decreasing security
109           AUTH_CLIENT_SECRET = "";
111           NETBIRD_MGMT_API_ENDPOINT = cfg.managementServer;
112           NETBIRD_MGMT_GRPC_API_ENDPOINT = cfg.managementServer;
113         }
114         // (mapAttrs (_: mkDefault) {
115           # Those values have to be easily overridable
116           AUTH_AUDIENCE = "netbird"; # must be set for your devices to be able to log in
117           AUTH_CLIENT_ID = "netbird";
118           AUTH_SUPPORTED_SCOPES = "openid profile email";
119           NETBIRD_TOKEN_SOURCE = "idToken";
120           USE_AUTH0 = false;
121         });
123       # The derivation containing the templated dashboard
124       finalDrv =
125         pkgs.runCommand "netbird-dashboard"
126           {
127             nativeBuildInputs = [ pkgs.gettext ];
128             env = {
129               ENV_STR = concatStringsSep " " [
130                 "$AUTH_AUDIENCE"
131                 "$AUTH_AUTHORITY"
132                 "$AUTH_CLIENT_ID"
133                 "$AUTH_CLIENT_SECRET"
134                 "$AUTH_REDIRECT_URI"
135                 "$AUTH_SILENT_REDIRECT_URI"
136                 "$AUTH_SUPPORTED_SCOPES"
137                 "$NETBIRD_DRAG_QUERY_PARAMS"
138                 "$NETBIRD_GOOGLE_ANALYTICS_ID"
139                 "$NETBIRD_HOTJAR_TRACK_ID"
140                 "$NETBIRD_MGMT_API_ENDPOINT"
141                 "$NETBIRD_MGMT_GRPC_API_ENDPOINT"
142                 "$NETBIRD_TOKEN_SOURCE"
143                 "$USE_AUTH0"
144               ];
145             } // (mapAttrs (_: toStringEnv) cfg.settings);
146           }
147           ''
148             cp -R ${cfg.package} build
150             find build -type d -exec chmod 755 {} \;
151             OIDC_TRUSTED_DOMAINS="build/OidcTrustedDomains.js"
153             envsubst "$ENV_STR" < "$OIDC_TRUSTED_DOMAINS.tmpl" > "$OIDC_TRUSTED_DOMAINS"
155             for f in $(grep -R -l AUTH_SUPPORTED_SCOPES build/); do
156               mv "$f" "$f.copy"
157               envsubst "$ENV_STR" < "$f.copy" > "$f"
158               rm "$f.copy"
159             done
161             cp -R build $out
162           '';
163     };
165     services.nginx = mkIf cfg.enableNginx {
166       enable = true;
168       virtualHosts.${cfg.domain} = {
169         locations = {
170           "/" = {
171             root = cfg.finalDrv;
172             tryFiles = "$uri $uri.html $uri/ =404";
173           };
175           "/404.html".extraConfig = ''
176             internal;
177           '';
178         };
180         extraConfig = ''
181           error_page 404 /404.html;
182         '';
183       };
184     };
185   };