diff --git a/clients/quadraticserver/bridges.nix b/clients/quadraticserver/bridges.nix new file mode 100644 index 0000000..b344fb3 --- /dev/null +++ b/clients/quadraticserver/bridges.nix @@ -0,0 +1,70 @@ +{ + pkgs, + inputs, + config, + ... +}: let + settings = { + backfill.enabled = true; + + appservice = { + as_token = "$CUSTOM_AS_TOKEN"; + hs_token = "$CUSTOM_HS_TOKEN"; + }; + + homeserver = { + domain = config.services.grapevine.settings.server_name; + address = config.services.grapevine.settings.server_discovery.client.base_url; + }; + + bridge = { + encryption = { + allow = true; + default = true; + require = false; + }; + permissions = { + "${config.services.grapevine.settings.server_name}" = "user"; + "@quadradical:${config.services.grapevine.settings.server_name}" = "admin"; + }; + }; + }; +in { + imports = [inputs.nix-matrix-appservices.nixosModule inputs.ooye.modules.default]; + + services = let + domain = "ooye.federated.nexus"; + in { + matrix-appservices.services = builtins.mapAttrs (name: value: + value + // { + inherit settings; + format = "mautrix-go"; + port = 8000; + package = value.package.override {withGoolm = true;}; + }) { + whatsapp = { + host = "127.0.0.4"; + serviceConfig.EnvironmentFile = config.age.secrets."whatsapp.age".path; + package = pkgs.mautrix-whatsapp; + }; + gmessages = { + host = "127.0.0.5"; + serviceConfig.EnvironmentFile = config.age.secrets."gmessages.age".path; + package = inputs.nixpkgs-goolm.legacyPackages.${pkgs.system}.mautrix-gmessages; + }; + }; + + matrix-ooye = { + enable = true; + homeserver = config.services.grapevine.settings.server_discovery.client.base_url; + homeserverName = "federated.nexus"; + discordTokenPath = config.age.secrets."discordToken.age".path; + discordClientSecretPath = config.age.secrets."discordClientSecret.age".path; + socket = "8081"; + bridgeOrigin = "https://${domain}"; + }; + + caddy.virtualHosts."${domain}".extraConfig = "reverse_proxy 127.0.0.1:8081"; + }; +} diff --git a/clients/quadraticserver/caddy.nix b/clients/quadraticserver/caddy.nix index 058f470..18d0395 100644 --- a/clients/quadraticserver/caddy.nix +++ b/clients/quadraticserver/caddy.nix @@ -1,19 +1,12 @@ -{ - pkgs, - lib, - ... -}: { +{pkgs, ...}: { networking.firewall.allowedTCPPorts = [443]; - services = { - nginx.enable = lib.mkForce false; - caddy = { - enable = true; - email = "hen" + "ry@he" + "nryhi" + "les.c" + "om"; + services.caddy = { + enable = true; + email = "hen" + "ry@he" + "nryhi" + "les.c" + "om"; - package = pkgs.caddy.withPlugins { - plugins = ["github.com/ggicci/caddy-jwt@v1.1.0"]; - hash = "sha256-sdhX/dAQ7lIxBo/ZW6XYX8SRuacLO9HobtIVKD/cw0o="; - }; + package = pkgs.caddy.withPlugins { + plugins = ["github.com/ggicci/caddy-jwt@v1.1.0"]; + hash = "sha256-sdhX/dAQ7lIxBo/ZW6XYX8SRuacLO9HobtIVKD/cw0o="; }; }; } diff --git a/clients/quadraticserver/docs.nix b/clients/quadraticserver/docs.nix new file mode 100644 index 0000000..c11efb1 --- /dev/null +++ b/clients/quadraticserver/docs.nix @@ -0,0 +1,115 @@ +{ + config, + pkgs, + ... +}: let + authDomain = "auth.federated.nexus"; + domain = "docs.federated.nexus"; + socket = "/run/lasuite-docs/socket"; + s3Domain = "http://127.0.0.1${config.services.minio.listenAddress}"; + s3Url = "${s3Domain}/lasuite-docs"; +in { + services = { + lasuite-docs = { + enable = true; + enableNginx = false; + redis.createLocally = true; + postgresql.createLocally = true; + bind = "unix:${socket}"; + inherit s3Url domain; + + settings = { + OIDC_CREATE_USER = true; + OIDC_OP_AUTHORIZATION_ENDPOINT = "https://federated.nexus/login"; + OIDC_OP_TOKEN_ENDPOINT = "http://${authDomain}/token"; + OIDC_OP_USER_ENDPOINT = "http://${authDomain}/userinfo"; + OIDC_RP_SIGN_ALGO = "HS256"; + OIDC_USERINFO_FULLNAME_FIELDS = ''["name"]''; + OIDC_USERINFO_SHORTNAME_FIELD = "name"; + + AWS_S3_ENDPOINT_URL = s3Domain; + AWS_S3_ACCESS_KEY_ID = "minioadmin"; + AWS_STORAGE_BUCKET_NAME = "lasuite-docs"; + MEDIA_BASE_URL = "http://${domain}"; + + DJANGO_ALLOWED_HOSTS = domain; + }; + + environmentFile = config.age.secrets."lasuiteSecrets.age".path; + }; + + minio = { + enable = true; + browser = false; + rootCredentialsFile = config.age.secrets."minioCredentials.age".path; + }; + + caddy.virtualHosts."${domain}".extraConfig = let + cfg = config.services.lasuite-docs; + in '' + handle_errors { + @401 expression {http.error.status_code} == 401 + rewrite @401 /401 + + @403 expression {http.error.status_code} == 403 + rewrite @403 /403 + + @404 expression {http.error.status_code} == 404 + rewrite @404 /404 + } + + root * ${pkgs.lasuite-docs-frontend} + file_server + + @uuidDocs path_regexp uuidDocs ^/docs/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/?$ + rewrite @uuidDocs /docs/[id]/index.html + + reverse_proxy /api/* unix/${socket} + + reverse_proxy /admin/* unix/${socket} + + reverse_proxy /collaboration/ws/* http://localhost:${toString cfg.collaborationServer.port} { + transport http { + versions h2c 1.1 + } + } + + reverse_proxy /collaboration/api/* http://localhost:${toString cfg.collaborationServer.port} + + rewrite /media-auth /api/v1.0/documents/media-auth/ + reverse_proxy /api/v1.0/documents/media-auth/ unix/${socket} { + header_up X-Original-URL {uri} + header_up -Content-Length + header_up X-Original-Method {method} + header_up -X-Forwarded-For + } + + rewrite /media/* /lasuite-docs + reverse_proxy /lasuite-docs ${s3Domain} { + header_up Authorization {http.reverse_proxy.header.X-Upstream-Authorization} + header_up X-Amz-Date {http.reverse_proxy.header.X-Upstream-X-Amz-Date} + header_up X-Amz-Content-SHA256 {http.reverse_proxy.header.X-Upstream-X-Amz-Content-Sha256} + } + ''; + }; + + systemd.services.minio-init = { + description = "Create MinIO bucket"; + after = ["minio.service"]; + requires = ["minio.service"]; + wantedBy = ["multi-user.target"]; + path = [pkgs.getent pkgs.minio-client]; + + serviceConfig = { + Type = "oneshot"; + after = ["minio.service"]; + requires = ["minio.service"]; + + EnvironmentFile = config.age.secrets."minioCredentials.age".path; + ExecStart = pkgs.writeShellScript "init-minio" '' + mc alias set minio ${s3Domain} "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD" --api s3v4 + mc --config-dir "$CONFIG_DIR" mb --ignore-existing minio/lasuite-docs + ''; + }; + }; +} diff --git a/flake.lock b/flake.lock index b2e0e76..e135a6d 100644 --- a/flake.lock +++ b/flake.lock @@ -188,11 +188,11 @@ "base16-helix": { "flake": false, "locked": { - "lastModified": 1748408240, - "narHash": "sha256-9M2b1rMyMzJK0eusea0x3lyh3mu5nMeEDSc4RZkGm+g=", + "lastModified": 1752979451, + "narHash": "sha256-0CQM+FkYy0fOO/sMGhOoNL80ftsAzYCg9VhIrodqusM=", "owner": "tinted-theming", "repo": "base16-helix", - "rev": "6c711ab1a9db6f51e2f6887cc3345530b33e152e", + "rev": "27cf1e66e50abc622fb76a3019012dc07c678fac", "type": "github" }, "original": { @@ -233,22 +233,6 @@ "type": "github" } }, - "blobs": { - "flake": false, - "locked": { - "lastModified": 1604995301, - "narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=", - "owner": "simple-nixos-mailserver", - "repo": "blobs", - "rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265", - "type": "gitlab" - }, - "original": { - "owner": "simple-nixos-mailserver", - "repo": "blobs", - "type": "gitlab" - } - }, "cachix": { "inputs": { "devenv": [ @@ -746,22 +730,6 @@ } }, "flake-compat_4": { - "flake": false, - "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_5": { "flake": false, "locked": { "lastModified": 1641205782, @@ -777,7 +745,7 @@ "type": "github" } }, - "flake-compat_6": { + "flake-compat_5": { "flake": false, "locked": { "lastModified": 1747046372, @@ -1066,32 +1034,6 @@ "type": "github" } }, - "git-hooks": { - "inputs": { - "flake-compat": [ - "mailserver", - "flake-compat" - ], - "gitignore": "gitignore", - "nixpkgs": [ - "mailserver", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1750779888, - "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, "git-hooks-nix": { "inputs": { "flake-compat": [ @@ -1121,28 +1063,6 @@ "type": "github" } }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "mailserver", - "git-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, "gitignore-nix": { "inputs": { "nixpkgs": [ @@ -1275,11 +1195,11 @@ ] }, "locked": { - "lastModified": 1753181343, - "narHash": "sha256-CLQfNtUqirNVSYoW/kYbvL4PeeNasmZonaPnjO3+1YQ=", + "lastModified": 1753373145, + "narHash": "sha256-UhuUj46dobD/POOdVNxKvAvP3luI2T0MZPm2IXl266Y=", "owner": "nix-community", "repo": "home-manager", - "rev": "0cdfcdbb525b77b951c889b6131047bc374f48fe", + "rev": "64796151f79e6f3834bfc55f07c5487708bb5b3f", "type": "github" }, "original": { @@ -1499,30 +1419,6 @@ "type": "github" } }, - "mailserver": { - "inputs": { - "blobs": "blobs", - "flake-compat": "flake-compat_4", - "git-hooks": "git-hooks", - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgs-25_05": "nixpkgs-25_05" - }, - "locked": { - "lastModified": 1753026197, - "narHash": "sha256-v8uYdWXzPPatsK5LerstRhtG9h9PV9b2oUqCvqySqvk=", - "ref": "refs/heads/pr-oauth2", - "rev": "57e1944ff77ffdb5a1a4bd5ba6aea2b361103e88", - "revCount": 774, - "type": "git", - "url": "file:///home/quadradical/Documents/Code/nixos-mailserver" - }, - "original": { - "type": "git", - "url": "file:///home/quadradical/Documents/Code/nixos-mailserver" - } - }, "matrixoidc": { "inputs": { "flake-parts": "flake-parts_3", @@ -1963,7 +1859,7 @@ "nix-matrix-appservices": { "inputs": { "devshell": "devshell", - "flake-compat": "flake-compat_5", + "flake-compat": "flake-compat_4", "nixlib": "nixlib", "nixpkgs": [ "nixpkgs" @@ -2220,22 +2116,6 @@ "type": "github" } }, - "nixpkgs-25_05": { - "locked": { - "lastModified": 1751741127, - "narHash": "sha256-t75Shs76NgxjZSgvvZZ9qOmz5zuBE8buUaYD28BMTxg=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "29e290002bfff26af1db6f64d070698019460302", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-25.05", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs-alsa-ucm-conf": { "locked": { "lastModified": 1749323015, @@ -2380,11 +2260,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1752950548, - "narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=", + "lastModified": 1753250450, + "narHash": "sha256-i+CQV2rPmP8wHxj0aq4siYyohHwVlsh40kV89f3nw1s=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c87b95e25065c028d31a94f06a62927d18763fdf", + "rev": "fc02ee70efb805d3b2865908a13ddd4474557ecf", "type": "github" }, "original": { @@ -2641,11 +2521,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1753212822, - "narHash": "sha256-l+xtl7MlXGthEVomOCCmAxnatPfcQcf++8D0WBpNlxU=", + "lastModified": 1753373813, + "narHash": "sha256-HiPFNgtvBotd3qM0ihi12uxs3PLTiLaF3ArHY36eja8=", "owner": "wamserma", "repo": "flake-programs-sqlite", - "rev": "44129ce7e322055bdd3383bba6f4a67da25cd63f", + "rev": "523515549c510943583a6610f5f8f7718348975f", "type": "github" }, "original": { @@ -2681,7 +2561,6 @@ "gnome-mobile": "gnome-mobile", "grapevine": "grapevine", "home-manager": "home-manager_2", - "mailserver": "mailserver", "matrixoidc": "matrixoidc", "nix-matrix-appservices": "nix-matrix-appservices", "nixpkgs": "nixpkgs_2", @@ -2809,7 +2688,7 @@ "disko": "disko_2", "emacs-overlay": "emacs-overlay", "fenix": "fenix_2", - "flake-compat": "flake-compat_6", + "flake-compat": "flake-compat_5", "flake-parts": "flake-parts_4", "flake-schemas": "flake-schemas", "flake-utils": "flake-utils_4", @@ -2919,11 +2798,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1753117651, - "narHash": "sha256-7gWBlUOe2c0nYGyoVDa9hw15pI3DXDR0KK+nYh9KOpU=", + "lastModified": 1753372006, + "narHash": "sha256-eyIYqerHPYHl2Eq802wJSOwMwZ3tdvJ4D+vckDe2mD8=", "owner": "danth", "repo": "stylix", - "rev": "ea60526c8c2a1c5df2743a9495814dc0b319ef3b", + "rev": "ceda12a6da2181e424d8ed7e68ed291745f06f49", "type": "github" }, "original": { diff --git a/secrets/lasuiteSecrets.age b/secrets/lasuiteSecrets.age new file mode 100644 index 0000000..5b4b002 --- /dev/null +++ b/secrets/lasuiteSecrets.age @@ -0,0 +1,11 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFZLUVVkUSA1eHY4 +Q2UvTnllWTlzbVBaNjA0NDVYN0pLRURKM01vM1I5Nk04d0xVcjJzCk90UHR4Snpu +TmVyQ3BQN205QkRIelRrZlVXUE01L1pDd3AvRVdpVzZrSTAKLT4gVHRRIS1ncmVh +c2Ugc3V1diJZSncgOX4KWUNlTldaRkVETitwclVtdmIwYVFkUnQ1VTdrek8rcVdF +RHJWTmtXOW5XSTdNemt4RmtCSVYrTVhVNlhLWE1VUwpmMm9xUUs0OFF3ZlFVVS9Z +OEZNTmgxNVRoZG9pZlVFQgotLS0gZHlRRk1oL3VhTmJTOHY1aWdNVVBVL3YyUGZu +UEU4RkJJUDVxWCtMYVlBdwpmVV67p+mRvSoWikGr53MDxYMCFQ0/LKzs/kHw7iZF +0huOB/IJwFyu1Pi+A+hz5y9W6aP/5uE1NtDqbAkKz4gOwMrWo8WmyxAsU9xrLGoH +s+gVvu/VdslMzSxGzA== +-----END AGE ENCRYPTED FILE----- diff --git a/secrets/minioCredentials.age b/secrets/minioCredentials.age new file mode 100644 index 0000000..6ec376c --- /dev/null +++ b/secrets/minioCredentials.age @@ -0,0 +1,11 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFZLUVVkUSBFV1J0 +WTVLMnBKeUVmMmpCV0ZhTmF5dVFwOG51cEZPaUJVNHpoeHU3UWp3CmZWZk5GV2x4 +VEpsWjArSkV2Ujh6L2dIWmJiQUlZek5hVWZHbHNKbmdITWcKLT4gci1BKFsxSzQt +Z3JlYXNlIC4naHQ3ZipoIHc/SWo2eyBRVyNiXQpZb0I2bitGbVlHK09WeWp5VjRT +VEdzdFlXSUFLOVFRa2tPZ2NHSEp5ZkFFem9BYU1pZHFVb3RkcGJnCi0tLSB6S3ZZ +c2p2REdBN3l4KzVHU2dzeVhMSmE3cStNVmtKYmFjNDE1RDBtLzRZCof3BKKr51ef +jZ1VjdSxMbHYN/PkBGqLc7Zh4/6Apuu1k39PbAl3CnW6YE6++XO/XdCfsHb4yYEC +jZD4D6dcTRxeFqAGLLCBTGfOTBb9KfZxu0lwek4qpl2QiSlY1/8lI3oOaqw22BEf +pU7bLXc0mKEpBw== +-----END AGE ENCRYPTED FILE-----