diff --git a/.just/vars.just b/.just/vars.just index 2ae9a44..62a8bd9 100644 --- a/.just/vars.just +++ b/.just/vars.just @@ -43,14 +43,14 @@ generate machine: # Skip if we already have a value [ $(just vars get "{{ machine }}" "$key" | jq -r) ] && continue - just vars _rotate "{{ machine }}" "$key" + just _rotate "{{ machine }}" "$key" done [doc('Regenerate var values for {machine}')] [script] _rotate machine key: # Exit if there's no script - [ -f "{{ justfile_directory() }}/script/{{ key }}" ] || exit 0 + [ -f "{{ justfile_directory() }}/script/{{ key }}" ] || exit echo "Executing script for {{ key }}" just vars set "{{ machine }}" "{{ key }}" "$(cd -- "$(dirname "{{ justfile_directory() }}/script/{{ key }}")" && source "./$(basename "{{ key }}")")" diff --git a/logs/bridge-2026-04-15T09-11-43.612.log b/logs/bridge-2026-04-15T09-11-43.612.log deleted file mode 100644 index df81d78..0000000 --- a/logs/bridge-2026-04-15T09-11-43.612.log +++ /dev/null @@ -1,2 +0,0 @@ -{"level":"fatal","error":"homeserver.address not configured","time":"2026-04-15T09:10:06.949460064Z","message":"Configuration error"} -{"level":"info","time":"2026-04-15T09:10:06.949840013Z","message":"See https://docs.mau.fi/faq/field-unconfigured for more info"} diff --git a/logs/bridge.log b/logs/bridge.log deleted file mode 100644 index 63567e0..0000000 --- a/logs/bridge.log +++ /dev/null @@ -1,2 +0,0 @@ -{"level":"fatal","error":"appservice.as_token not configured. Did you forget to generate the registration? ","time":"2026-04-15T09:11:43.617908298Z","message":"Configuration error"} -{"level":"info","time":"2026-04-15T09:11:43.618232253Z","message":"See https://docs.mau.fi/faq/field-unconfigured for more info"} diff --git a/modules/nixos/services/communication/matrix/default.nix b/modules/nixos/services/communication/matrix/default.nix index c9c11f1..d2e47b0 100644 --- a/modules/nixos/services/communication/matrix/default.nix +++ b/modules/nixos/services/communication/matrix/default.nix @@ -6,7 +6,7 @@ ... }: let inherit (builtins) toString toJSON; - inherit (lib) mkIf mkEnableOption mkMerge; + inherit (lib) mkIf mkEnableOption; cfg = config.${namespace}.services.communication.matrix; @@ -16,35 +16,6 @@ database = "synapse"; keyFile = "/var/lib/element-call/key"; - - mkMautrix = bridge: i: conf: { - ${bridge} = - { - enable = true; - registerToSynapse = true; - - settings = { - appservice = { - # hostname = "[::]"; - # port = 40010 + i; - # address = "http://${config.services.${bridge}.settings.appservice.hostname}:${toString config.services.${bridge}.settings.appservice.port}"; - provisioning.enabled = false; - }; - - homeserver = { - inherit domain; - address = "http://[::1]:${toString port}"; - }; - - bridge = { - permissions = { - "@chris:${domain}" = "admin"; - }; - }; - }; - } - // conf; - }; in { options.${namespace}.services.communication.matrix = { enable = mkEnableOption "Matrix server (Synapse)"; @@ -53,8 +24,27 @@ in { config = mkIf cfg.enable { ${namespace}.services = { persistance.postgresql.enable = true; + # virtualisation.podman.enable = true; networking.caddy = { + # globalConfig = '' + # layer4 { + # 127.0.0.1:4004 + # route { + # proxy { + # upstream synapse:4004 + # } + # } + # } + # 127.0.0.1:4005 + # route { + # proxy { + # upstream synapse:4005 + # } + # } + # } + # } + # ''; hosts = let server = { "m.server" = "${fqn}:443"; @@ -106,166 +96,238 @@ in { }; }; - services = mkMerge [ - (mkMautrix "mautrix-signal" 1 {}) - (mkMautrix "mautrix-telegram" 2 {}) - (mkMautrix "mautrix-whatsapp" 3 {}) - (mkMautrix "arrtrix" 4 {}) - { - matrix-synapse = { - enable = true; + services = { + matrix-synapse = { + enable = true; - extras = ["oidc"]; + extras = ["oidc"]; - extraConfigFiles = [ - config.sops.templates."synapse.yaml".path - config.sops.templates."synapse-oidc.yaml".path - ]; + extraConfigFiles = [ + config.sops.templates."synapse-oidc.yaml".path + ]; - settings = { - server_name = domain; - public_baseurl = "https://${fqn}"; + settings = { + server_name = domain; + public_baseurl = "https://${fqn}"; - enable_metrics = true; + enable_metrics = true; - url_preview_enabled = true; - precence.enabled = true; + registration_shared_secret = "tZtBnlhEmLbMwF0lQ112VH1Rl5MkZzYH9suI4pEoPXzk6nWUB8FJF4eEnwLkbstz"; - # Since we'll be using OIDC for auth disable all local options - enable_registration = false; - enable_registration_without_verification = false; - password_config.enabled = true; - backchannel_logout_enabled = true; + url_preview_enabled = true; + precence.enabled = true; - # Element Call options - max_event_delay_duration = "24h"; - rc_message = { - per_second = 0.5; - burst_count = 30; - }; - rc_delayed_event_mgmt = { - per_second = 1; - burst_count = 20; - }; - turn_uris = ["turn:turn.${domain}:4004?transport=udp" "turn:turn.${domain}:4004?transport=tcp"]; + # Since we'll be using OIDC for auth disable all local options + enable_registration = false; + enable_registration_without_verification = false; + password_config.enabled = true; + backchannel_logout_enabled = true; - experimental_features = { - # MSC2965: OAuth 2.0 Authorization Server Metadata discovery - msc2965_enabled = true; - - # MSC3266: Room summary API. Used for knocking over federation - msc3266_enabled = true; - # MSC4222 needed for syncv2 state_after. This allow clients to - # correctly track the state of the room. - msc4222_enabled = true; - }; - - sso = { - client_whitelist = ["http://[::1]:9092/" "https://auth.kruining.eu/"]; - update_profile_information = true; - }; - - database = { - # this is postgresql (also the default, but I prefer to be explicit) - name = "psycopg2"; - args = { - database = database; - user = database; - }; - }; - - listeners = [ - { - bind_addresses = ["::"]; - port = port; - type = "http"; - tls = false; - x_forwarded = true; - - resources = [ - { - names = ["client" "federation" "openid" "metrics" "media" "health"]; - compress = true; - } - ]; - } - ]; + # Element Call options + max_event_delay_duration = "24h"; + rc_message = { + per_second = 0.5; + burst_count = 30; }; - }; + rc_delayed_event_mgmt = { + per_second = 1; + burst_count = 20; + }; + turn_uris = ["turn:turn.${domain}:4004?transport=udp" "turn:turn.${domain}:4004?transport=tcp"]; - postgresql = { - ensureDatabases = [database]; - ensureUsers = [ + experimental_features = { + # MSC2965: OAuth 2.0 Authorization Server Metadata discovery + msc2965_enabled = true; + + # MSC3266: Room summary API. Used for knocking over federation + msc3266_enabled = true; + # MSC4222 needed for syncv2 state_after. This allow clients to + # correctly track the state of the room. + msc4222_enabled = true; + }; + + sso = { + client_whitelist = ["http://[::1]:9092/" "https://auth.kruining.eu/"]; + update_profile_information = true; + }; + + database = { + # this is postgresql (also the default, but I prefer to be explicit) + name = "psycopg2"; + args = { + database = database; + user = database; + }; + }; + + listeners = [ { - name = database; - ensureDBOwnership = true; + bind_addresses = ["::"]; + port = port; + type = "http"; + tls = false; + x_forwarded = true; + + resources = [ + { + names = ["client" "federation" "openid" "metrics" "media" "health"]; + compress = true; + } + ]; } ]; }; + }; - livekit = { - enable = true; - openFirewall = true; - inherit keyFile; + mautrix-signal = { + enable = true; + registerToSynapse = true; - settings = { - port = 4002; - room.auto_create = false; + settings = { + appservice = { + provisioning.enabled = false; + }; + + homeserver = { + address = "http://[::1]:${toString port}"; + domain = domain; + }; + + bridge = { + permissions = { + "@chris:${domain}" = "admin"; + }; }; }; + }; - lk-jwt-service = { - enable = true; - port = 4003; - # can be on the same virtualHost as synapse - livekitUrl = "wss://${domain}/livekit/sfu"; - inherit keyFile; - }; + mautrix-telegram = { + enable = true; + registerToSynapse = true; - coturn = rec { - enable = true; - listening-port = 4004; - tls-listening-port = 40004; - no-cli = true; - no-tcp-relay = true; - min-port = 50000; - max-port = 50100; - use-auth-secret = true; - static-auth-secret-file = config.sops.secrets."coturn/secret".path; - realm = "turn.${domain}"; - # cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; - # pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; - extraConfig = '' - # for debugging - verbose - # ban private IP ranges - no-multicast-peers - denied-peer-ip=0.0.0.0-0.255.255.255 - denied-peer-ip=10.0.0.0-10.255.255.255 - denied-peer-ip=100.64.0.0-100.127.255.255 - denied-peer-ip=127.0.0.0-127.255.255.255 - denied-peer-ip=169.254.0.0-169.254.255.255 - denied-peer-ip=172.16.0.0-172.31.255.255 - denied-peer-ip=192.0.0.0-192.0.0.255 - denied-peer-ip=192.0.2.0-192.0.2.255 - denied-peer-ip=192.88.99.0-192.88.99.255 - denied-peer-ip=192.168.0.0-192.168.255.255 - denied-peer-ip=198.18.0.0-198.19.255.255 - denied-peer-ip=198.51.100.0-198.51.100.255 - denied-peer-ip=203.0.113.0-203.0.113.255 - denied-peer-ip=240.0.0.0-255.255.255.255 - denied-peer-ip=::1 - denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff - denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 - denied-peer-ip=100::-100::ffff:ffff:ffff:ffff - denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff - ''; + settings = { + telegram = { + api_id = 32770816; + api_hash = "7b63778a976619c9d4ab62adc51cde79"; + bot_token = "disabled"; + + catch_up = true; + sequential_updates = true; + }; + + appservice = { + port = 40011; + provisioning.enabled = false; + }; + + homeserver = { + address = "http://[::1]:${toString port}"; + domain = domain; + }; + + bridge = { + permissions = { + "@chris:${domain}" = "admin"; + }; + }; }; - } - ]; + }; + + mautrix-whatsapp = { + enable = true; + registerToSynapse = true; + + settings = { + appservice = { + provisioning.enabled = false; + }; + + homeserver = { + address = "http://[::1]:${toString port}"; + domain = domain; + }; + + bridge = { + permissions = { + "@chris:${domain}" = "admin"; + }; + }; + }; + }; + + postgresql = { + enable = true; + ensureDatabases = [database]; + ensureUsers = [ + { + name = database; + ensureDBOwnership = true; + } + ]; + }; + + livekit = { + enable = true; + openFirewall = true; + inherit keyFile; + + settings = { + port = 4002; + room.auto_create = false; + }; + }; + + lk-jwt-service = { + enable = true; + port = 4003; + # can be on the same virtualHost as synapse + livekitUrl = "wss://${domain}/livekit/sfu"; + inherit keyFile; + }; + + coturn = rec { + enable = true; + listening-port = 4004; + tls-listening-port = 40004; + no-cli = true; + no-tcp-relay = true; + min-port = 50000; + max-port = 50100; + use-auth-secret = true; + static-auth-secret-file = config.sops.secrets."coturn/secret".path; + realm = "turn.${domain}"; + # cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; + # pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; + extraConfig = '' + # for debugging + verbose + # ban private IP ranges + no-multicast-peers + denied-peer-ip=0.0.0.0-0.255.255.255 + denied-peer-ip=10.0.0.0-10.255.255.255 + denied-peer-ip=100.64.0.0-100.127.255.255 + denied-peer-ip=127.0.0.0-127.255.255.255 + denied-peer-ip=169.254.0.0-169.254.255.255 + denied-peer-ip=172.16.0.0-172.31.255.255 + denied-peer-ip=192.0.0.0-192.0.0.255 + denied-peer-ip=192.0.2.0-192.0.2.255 + denied-peer-ip=192.88.99.0-192.88.99.255 + denied-peer-ip=192.168.0.0-192.168.255.255 + denied-peer-ip=198.18.0.0-198.19.255.255 + denied-peer-ip=198.51.100.0-198.51.100.255 + denied-peer-ip=203.0.113.0-203.0.113.255 + denied-peer-ip=240.0.0.0-255.255.255.255 + denied-peer-ip=::1 + denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff + denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 + denied-peer-ip=100::-100::ffff:ffff:ffff:ffff + denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff + ''; + }; + }; networking.firewall = { allowedTCPPortRanges = []; @@ -314,9 +376,6 @@ in { "synapse/oidc_secret" = { restartUnits = ["synapse-matrix.service"]; }; - "synapse/shared_secret" = { - restartUnits = ["synapse-matrix.service"]; - }; "coturn/secret" = { owner = config.systemd.services.coturn.serviceConfig.User; group = config.systemd.services.coturn.serviceConfig.Group; @@ -325,13 +384,6 @@ in { }; templates = { - "synapse.yaml" = { - owner = "matrix-synapse"; - content = '' - registration_shared_secret: ${config.sops.placeholder."synapse/shared_secret"} - ''; - restartUnits = ["matrix-synapse.service"]; - }; "synapse-oidc.yaml" = { owner = "matrix-synapse"; content = '' diff --git a/modules/nixos/services/media/servarr/default.nix b/modules/nixos/services/media/servarr/default.nix index ae0e3b0..a98399d 100644 --- a/modules/nixos/services/media/servarr/default.nix +++ b/modules/nixos/services/media/servarr/default.nix @@ -129,12 +129,11 @@ in { port = 2007; }; - postgresql = let - databases = [] ++ (cfg |> lib.attrNames); - in { - ensureDatabases = databases; + postgresql = { + ensureDatabases = cfg |> lib.attrNames; ensureUsers = - databases + cfg + |> lib.attrNames |> lib.map (service: { name = service; ensureDBOwnership = true; diff --git a/modules/nixos/temp/services/arrtrix/default.nix b/modules/nixos/temp/services/arrtrix/default.nix deleted file mode 100644 index dfd7b32..0000000 --- a/modules/nixos/temp/services/arrtrix/default.nix +++ /dev/null @@ -1,200 +0,0 @@ -{ - config, - lib, - pkgs, - namespace, - ... -}: let - inherit (lib) mkEnableOption mkPackageOption mkIf mkOption optionalAttrs recursiveUpdate types baseNameOf; - - cfg = config.services.arrtrix; - dataDir = "/var/lib/arrtrix"; - registrationFile = "${dataDir}/arrtrix-registration.yaml"; - settingsFile = "${dataDir}/config.yaml"; - settingsFileUnsubstituted = settingsFormat.generate "arrtrix-config-unsubstituted.json" cfg.settings; - settingsFormat = pkgs.formats.json {}; - - defaultConfig = { - bridge = { - command_prefix = "!arr"; - relay.enabled = true; - permissions."*" = "relay"; - }; - database = { - type = "sqlite3"; - uri = "file:${dataDir}/arrtrix.db?_txlock=immediate"; - }; - homeserver = { - address = "http://localhost:8448"; - domain = config.services.matrix-synapse.settings.server_name or "example.com"; - }; - appservice = { - hostname = "[::]"; - port = 29329; - id = "arrtrix"; - bot = { - username = "arrtrixbot"; - displayname = "arrtrix Bot"; - }; - as_token = ""; - hs_token = ""; - username_template = "arrtrix_{{.}}"; - }; - double_puppet = { - servers = {}; - secrets = {}; - }; - # By default, the following keys/secrets are set to `generate`. This would break when the service - # is restarted, since the previously generated configuration will be overwritten everytime. - # If encryption is enabled, it's recommended to set those keys via `environmentFile`. - encryption.pickle_key = ""; - provisioning.shared_secret = ""; - public_media.signing_key = ""; - direct_media.server_key = ""; - logging = { - min_level = "info"; - writers = lib.singleton { - type = "stdout"; - format = "pretty-colored"; - time_format = " "; - }; - }; - }; -in { - options.services.arrtrix = { - enable = mkEnableOption "Arr-focused Matrix appservice foundation"; - - package = mkPackageOption pkgs.${namespace} "arrtrix" {}; - - registerToSynapse = mkOption { - type = types.bool; - default = config.services.matrix-synapse.enable; - defaultText = lib.literalExpression '' - config.services.matrix-synapse.enable - ''; - description = '' - Whether to add the bridge's app service registration file to - `services.matrix-synapse.settings.app_service_config_files`. - ''; - }; - - settings = mkOption { - apply = lib.recursiveUpdate defaultConfig; - type = settingsFormat.type; - default = defaultConfig; - description = '' - {file}`config.yaml` configuration as a Nix attribute set. - Configuration options should match those described in the example configuration. - Get an example configuration by executing `arrtrix -c example.yaml --generate-example-config` - Secret tokens should be specified using {option}`environmentFile` - instead of this world-readable attribute set. - ''; - example = {}; - }; - - serviceDependencies = lib.mkOption { - type = with lib.types; listOf str; - default = - (lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit) - ++ (lib.optional config.services.matrix-conduit.enable "conduit.service"); - defaultText = lib.literalExpression '' - (optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit) - ++ (optional config.services.matrix-conduit.enable "conduit.service") - ''; - description = '' - List of systemd units to require and wait for when starting the application service. - ''; - }; - }; - - config = mkIf cfg.enable { - users = { - users."arrtrix" = { - isSystemUser = true; - group = "arrtrix"; - }; - groups."arrtrix" = {}; - }; - - services.matrix-synapse = lib.mkIf cfg.registerToSynapse { - settings.app_service_config_files = [registrationFile]; - }; - systemd.services.matrix-synapse = lib.mkIf cfg.registerToSynapse { - serviceConfig.SupplementaryGroups = ["arrtrix"]; - }; - - systemd.services.arrtrix = { - description = "arrtrix, A *arr stack to matrix bridge for *arr-notifications"; - - wantedBy = ["multi-user.target"]; - after = ["network-online.target"]; - wants = ["network-online.target"]; - restartTriggers = [settingsFileUnsubstituted]; - - preStart = '' - # substitute the settings file by environment variables - # in this case read from EnvironmentFile - test -f '${settingsFile}' && rm -f '${settingsFile}' - - old_umask=$(umask) - umask 0177 - ${lib.getExe pkgs.envsubst} -o '${settingsFile}' -i '${settingsFileUnsubstituted}' - umask $old_umask - - if [ ! -f '${registrationFile}' ]; then - ${lib.getExe cfg.package} --generate-registration --config='${settingsFile}' --registration='${registrationFile}' - fi - chmod 640 ${registrationFile} - - # 1. Overwrite registration tokens in config - # 2. If environment variable MAUTRIX_SIGNAL_BRIDGE_LOGIN_SHARED_SECRET - # is set, set it as the login shared secret value for the configured - # homeserver domain. - umask 0177 - ${lib.getExe pkgs.yq} -s '.[0].appservice.as_token = .[1].as_token - | .[0].appservice.hs_token = .[1].hs_token - | .[0] - | if env.MAUTRIX_SIGNAL_BRIDGE_LOGIN_SHARED_SECRET then .double_puppet.secrets.[.homeserver.domain] = env.MAUTRIX_SIGNAL_BRIDGE_LOGIN_SHARED_SECRET else . end' \ - '${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp' - mv '${settingsFile}.tmp' '${settingsFile}' - umask $old_umask - ''; - - serviceConfig = { - Type = "simple"; - User = "arrtrix"; - Group = "arrtrix"; - - StateDirectory = baseNameOf dataDir; - WorkingDirectory = dataDir; - - ExecStart = '' - ${lib.getExe cfg.package} --config='${settingsFile}' --registration='${registrationFile}' - ''; - - Restart = "on-failure"; - RestartSec = "30s"; - - NoNewPrivileges = true; - PrivateTmp = true; - ProtectHome = true; - ProtectSystem = "strict"; - ProtectClock = true; - ProtectControlGroups = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - LockPersonality = true; - MemoryDenyWriteExecute = true; - - SystemCallArchitectures = "native"; - SystemCallErrorNumber = "EPERM"; - SystemCallFilter = ["@system-service"]; - UMask = "0027"; - }; - }; - }; -} diff --git a/packages/arrtrix/cmd/arrtrix/main.go b/packages/arrtrix/cmd/arrtrix/main.go deleted file mode 100644 index 7958a39..0000000 --- a/packages/arrtrix/cmd/arrtrix/main.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "maunium.net/go/mautrix/bridgev2/matrix/mxmain" - - "sneeuwvlok/packages/arrtrix/pkg/connector" -) - -var ( - Tag = "unknown" - Commit = "unknown" - BuildTime = "unknown" -) - -var m = mxmain.BridgeMain{ - Name: "arrtrix", - URL: "https://github.com/chris-kruining/sneeuwvlok", - Description: "An Arr-focused Matrix appservice bridge.", - Version: "0.1.0", - Connector: &connector.ArrtrixConnector{}, -} - -func main() { - m.InitVersion(Tag, Commit, BuildTime) - m.Run() -} diff --git a/packages/arrtrix/default.nix b/packages/arrtrix/default.nix deleted file mode 100644 index 81950f9..0000000 --- a/packages/arrtrix/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - buildGoModule, - lib, - olm, - versionCheckHook, -}: -buildGoModule rec { - pname = "arrtrix"; - version = "0.1.0"; - tag = "v0.1.0"; - - src = lib.cleanSource ./.; - - vendorHash = "sha256-FbatoXcxZcnqVUmoj/jeSMFO/iTmD8uga47MoTdGcRw="; - subPackages = ["cmd/arrtrix"]; - - buildInputs = [olm]; - - ldflags = [ - "-X main.Tag=${tag}" - ]; - - doInstallCheck = true; - nativeInstallCheckInputs = [versionCheckHook]; - - meta = { - description = "*arr-stack Matrix bridge"; - homepage = "https://github.com/chris-kruining/sneeuwvlok"; - license = lib.licenses.mit; - maintainers = []; - mainProgram = "arrtrix"; - }; -} diff --git a/packages/arrtrix/go.mod b/packages/arrtrix/go.mod deleted file mode 100644 index eed27b5..0000000 --- a/packages/arrtrix/go.mod +++ /dev/null @@ -1,43 +0,0 @@ -module sneeuwvlok/packages/arrtrix - -go 1.25.0 - -require ( - go.mau.fi/util v0.9.7 - maunium.net/go/mautrix v0.26.4 -) - -require ( - github.com/kr/pretty v0.3.1 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect -) - -require ( - filippo.io/edwards25519 v1.2.0 // indirect - github.com/coder/websocket v1.8.14 // indirect - github.com/coreos/go-systemd/v22 v22.6.0 // indirect - github.com/lib/pq v1.11.2 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.34 // indirect - github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect - github.com/rs/xid v1.6.0 // indirect - github.com/rs/zerolog v1.34.0 // indirect - github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect - github.com/tidwall/gjson v1.18.0 // indirect - github.com/tidwall/match v1.2.0 // indirect - github.com/tidwall/pretty v1.2.1 // indirect - github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.16 // indirect - go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/crypto v0.49.0 // indirect - golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect - golang.org/x/net v0.52.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/text v0.35.0 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - maunium.net/go/mauflag v1.0.0 // indirect -) diff --git a/packages/arrtrix/go.sum b/packages/arrtrix/go.sum deleted file mode 100644 index d8e9404..0000000 --- a/packages/arrtrix/go.sum +++ /dev/null @@ -1,91 +0,0 @@ -filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= -filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= -github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= -github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= -github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= -github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= -github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= -github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE= -github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= -github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= -github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= -github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= -github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= -github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= -github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.7 h1:AWGNbJfz1zRcQOKeOEYhKUG2fT+/26Gy6kyqcH8tnBg= -go.mau.fi/util v0.9.7/go.mod h1:5T2f3ZWZFAGgmFwg3dGw7YK6kIsb9lryDzvynoR98pE= -go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= -go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= -golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= -gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= -maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.4 h1:enHSnkf0L2V9+VnfJfNhKSReSW6pBKS/x3Su+v+Vovs= -maunium.net/go/mautrix v0.26.4/go.mod h1:YWw8NWTszsbyFAznboicBObwHPgTSLcuTbVX2kY7U2M= diff --git a/packages/arrtrix/pkg/connector/config.go b/packages/arrtrix/pkg/connector/config.go deleted file mode 100644 index 98a0916..0000000 --- a/packages/arrtrix/pkg/connector/config.go +++ /dev/null @@ -1,18 +0,0 @@ -package connector - -import ( - _ "embed" - - up "go.mau.fi/util/configupgrade" -) - -//go:embed example-config.yaml -var ExampleConfig string - -type Config struct{} - -func upgradeConfig(helper up.Helper) {} - -func (s *ArrtrixConnector) GetConfig() (string, any, up.Upgrader) { - return ExampleConfig, &s.Config, up.SimpleUpgrader(upgradeConfig) -} diff --git a/packages/arrtrix/pkg/connector/connector.go b/packages/arrtrix/pkg/connector/connector.go deleted file mode 100644 index e90ed46..0000000 --- a/packages/arrtrix/pkg/connector/connector.go +++ /dev/null @@ -1,107 +0,0 @@ -package connector - -import ( - "context" - "fmt" - - "maunium.net/go/mautrix/bridgev2" - "maunium.net/go/mautrix/bridgev2/database" - "maunium.net/go/mautrix/bridgev2/networkid" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" -) - -type ArrtrixConnector struct { - Bridge *bridgev2.Bridge - Config Config -} - -var _ bridgev2.NetworkConnector = (*ArrtrixConnector)(nil) - -func (s *ArrtrixConnector) GetName() bridgev2.BridgeName { - return bridgev2.BridgeName{ - DisplayName: "Arrtrix", - NetworkURL: "https://wiki.servarr.com/", - NetworkID: "arrtrix", - BeeperBridgeType: "arrtrix", - DefaultPort: 29329, - DefaultCommandPrefix: "!arr", - } -} - -func (s *ArrtrixConnector) Init(bridge *bridgev2.Bridge) { - s.Bridge = bridge -} - -func (s *ArrtrixConnector) Start(context.Context) error { - return nil -} - -func (s *ArrtrixConnector) GetDBMetaTypes() database.MetaTypes { - return database.MetaTypes{} -} - -func (s *ArrtrixConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities { - return &bridgev2.NetworkGeneralCapabilities{} -} - -func (s *ArrtrixConnector) LoadUserLogin(_ context.Context, login *bridgev2.UserLogin) error { - login.Client = &ArrtrixClient{ - Main: s, - UserLogin: login, - } - return nil -} - -func (s *ArrtrixConnector) GetLoginFlows() []bridgev2.LoginFlow { - return nil -} - -func (s *ArrtrixConnector) CreateLogin(_ context.Context, _ *bridgev2.User, flowID string) (bridgev2.LoginProcess, error) { - return nil, fmt.Errorf("login flow %q is not implemented", flowID) -} - -func (s *ArrtrixConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 1 -} - -type ArrtrixClient struct { - Main *ArrtrixConnector - UserLogin *bridgev2.UserLogin -} - -var _ bridgev2.NetworkAPI = (*ArrtrixClient)(nil) - -func (c *ArrtrixClient) Connect(context.Context) {} - -func (c *ArrtrixClient) Disconnect() {} - -func (c *ArrtrixClient) IsLoggedIn() bool { - return false -} - -func (c *ArrtrixClient) LogoutRemote(context.Context) {} - -func (c *ArrtrixClient) IsThisUser(context.Context, networkid.UserID) bool { - return false -} - -func (c *ArrtrixClient) GetChatInfo(context.Context, *bridgev2.Portal) (*bridgev2.ChatInfo, error) { - return &bridgev2.ChatInfo{}, nil -} - -func (c *ArrtrixClient) GetUserInfo(context.Context, *bridgev2.Ghost) (*bridgev2.UserInfo, error) { - return &bridgev2.UserInfo{}, nil -} - -func (c *ArrtrixClient) GetCapabilities(context.Context, *bridgev2.Portal) *event.RoomFeatures { - return &event.RoomFeatures{} -} - -func (c *ArrtrixClient) HandleMatrixMessage(context.Context, *bridgev2.MatrixMessage) (*bridgev2.MatrixMessageResponse, error) { - return nil, fmt.Errorf("bridging Matrix messages is not implemented") -} - -func (c *ArrtrixClient) GenerateTransactionID(userID id.UserID, roomID id.RoomID, eventType event.Type) networkid.RawTransactionID { - return networkid.RawTransactionID("") -} diff --git a/packages/arrtrix/pkg/connector/example-config.yaml b/packages/arrtrix/pkg/connector/example-config.yaml deleted file mode 100644 index 63a205e..0000000 --- a/packages/arrtrix/pkg/connector/example-config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# No network-specific config is required yet. -# -# Future Arr-specific runtime options, such as webhook handling, can be added -# here without changing the shared mautrix bridge CLI/runtime shape. -# -# The CLI-provided config file is still fully used by the bridge runtime for -# all shared sections like bridge, database, homeserver, and appservice. diff --git a/script/synapse/shared_secret b/script/synapse/shared_secret deleted file mode 100644 index 85fc69f..0000000 --- a/script/synapse/shared_secret +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -pwgen -s 128 1 diff --git a/systems/x86_64-linux/ulmo/secrets.yml b/systems/x86_64-linux/ulmo/secrets.yml index 869e63e..43c2b4c 100644 --- a/systems/x86_64-linux/ulmo/secrets.yml +++ b/systems/x86_64-linux/ulmo/secrets.yml @@ -10,7 +10,6 @@ forgejo: synapse: oidc_id: ENC[AES256_GCM,data:XbCpyGq0LeRJWq8dv/5Dipvp,iv:YDhgl26z1NBbIQLoLdGVz0+ze6o1ZcmgVHPfwoRj57I=,tag:y2vUuqnDmtTvVQmZCAlnLg==,type:str] oidc_secret: ENC[AES256_GCM,data:nVFi5EFbNMZ0mvrDHVYC0NiwJlo2eEw44D+Fcv9SKSb2oO00lGEDkP/oXDj5YgDq6RLQSe3f/SUOn77ntwnZYg==,iv:awe7VNUYOn9ofl1QlQTrEN5d0i5WkVM35qndruL4VXo=,tag:8Yoc9lFF9aWbtAa5fzQGEA==,type:str] - shared_secret: ENC[AES256_GCM,data:IkzZ6QV1gLzChAFSsYsK3HM5dKFD4AoDJ53xgoxNpgt5tb45mMw/LRxu4NArGVLUtVGBy6jk6arU+Nxvi8bxPOC8c2UFCRUF+FM1phICEbb4Chgy5g803VKNFOu6BLaEmwDmuZSQP7CwX1hy8TX8yChboHGp7hH+n5SAZpejrLg=,iv:d+Ab91yCltYwudDWhrWPw0Xod/TKriCsoGD8i6PD4H4=,tag:xOXnzNuajcOz+imjMJr3Dg==,type:str] radarr: apikey: ENC[AES256_GCM,data:G141GW4PyS5pbAV39HcVscMw3s30txOgTZzWaL7o+ccZfnfDLv796O6xKXdqGZ8saLsveghLw9Z6a5luusHyQ3Q5ESL6W7SVeZVTuSqSC3i/4jl75FJxhnsgVsfrnYxzLGpKiw==,iv:sZl/XLh6y3WgSAn6nH3sFB6atBifZdghm+QsCNDbcjY=,tag:Tw+R80nrF0T0yDti0Uf+ig==,type:str] sonarr: @@ -63,7 +62,7 @@ sops: TTRWaHhpNWlkVDFmMFN4ZTNHMUxyNVkKV693pzTKRkZboQCMPr9IyMGSgxfuHXcb Y6BNcp6Qg6PWtX5QI7wRkPNINAK1TEbRBba+b8h6gMmVU4DliQyFiQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-04-16T05:20:18Z" - mac: ENC[AES256_GCM,data:YqkxwV30uqSHhsn4niFEODxxl9R2ZuiyyX4g8zONVjMvdA52C08zPpxdxjtXnUT9m3sT7iSmWcJJZwhMhRIb8LJ2sdIJ4v+wpG9I4pPokhEXI2ozqbzw3k68GnZOzYu3kePQBJjQx1fmlM63dgILIwx7ytPnpm9arQ1rszZynNs=,iv:hxdhU5oH9h9mRH3m76oFkYVNA68PnivVJpJRjxSRtTw=,tag:Fyyg6cWPb96c/Vap+PifUQ==,type:str] + lastmodified: "2026-04-12T15:00:06Z" + mac: ENC[AES256_GCM,data:oklhIZY2AHJh/RaY58R4JZzd8l+aSqxco0qNEhHKskuxB6TPHsybJy93J0oFP/VkuOheuMG4Z32WBAL9dSntjKoWCFdlUf9IMXPUYXy+yD2J0/Lf6w7hXNPQFlDrPfZ+2klamJDZDpkY5SAcgLFHG8oZVLsJtCj6uH+dQKG9QXI=,iv:ZKnwGjqy/to0auzUZnU7bCARZg54hqskr+FOXwxS/dY=,tag:NVkqznP3Qcsyui/EAD9QJA==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0