Watch
0
0
Fork
You've already forked hyperhive
0

serve matrix discovery at the swarm apex, keep the pinned hive case

This commit is contained in:
atlas 2026-10-25 11:13:22 +01:00 • committed by mara
commit 2e7d49bb88
10 changed files with 187 additions and 83 deletions

View file

@ -1,16 +1,17 @@
# Glue: serve the swarm homeserver's discovery on the hive domain's vhost
# wherever both run.
# Glue: matrix's links on the hive domain's vhost.
#
# ONE PAIRING PER FILE — matrix → hive domain vhost, and nothing else.
# Deleting this leaves federation and clients with no `.well-known/matrix/*`
# answer at the server name, and the legacy `<hive>/matrix/*` links 404.
#
# The locations sit on the hive domain because the matrix spec reads
# delegation off the *server name*: it is the hive answering "where is my
# homeserver", not the homeserver answering for itself (./hive-matrix.nix's
# vhost on `gatewayHost` carries the rest).
# Two pieces, each under its own condition:
# - `.well-known/matrix/{client,server}` is served here only when the hive
# domain IS the homeserver's server name (a homeserver that pinned
# `swarm.matrix.serverName` to it): the spec reads delegation off the
# *server name*. The host need not run the homeserver, since the JSON is
# built from `swarm.matrix.gatewayHost` alone. For the default server name
# (the swarm domain) the swarm UI's apex vhost answers (./swarm-ui.nix).
# - `<hive>/matrix/*` redirects to the homeserver where the homeserver runs.
#
# ⚠️ The condition repeats the one ./hive-c0re/vhosts.nix declares the hive
# ⚠️ Both conditions repeat the one ./hive-c0re/vhosts.nix declares the hive
# domain vhost under. With it looser, this file alone would declare that
# vhost, with discovery and no `/` redirect.
{
@ -24,53 +25,58 @@ let
matrixCfg = hyperhiveCfg.swarm.matrix;
homeserverUrl = "https://${matrixCfg.gatewayHost}";
onHiveVhost =
matrixCfg.gatewayHost != null
&& hyperhiveCfg.deploy.hive-controller.enable
&& gatewayCfg.enable
&& hyperhiveCfg.swarm.dashboardDomain != null;
# Same default as `effectiveServerName` in ./hive-matrix.nix.
serverName =
if matrixCfg.serverName != null then matrixCfg.serverName else hyperhiveCfg.swarm.domain;
in
{
config =
lib.mkIf
(
hyperhiveCfg.deploy.matrix.enable
&& matrixCfg.gatewayHost != null
&& hyperhiveCfg.deploy.hive-controller.enable
&& gatewayCfg.enable
&& hyperhiveCfg.swarm.dashboardDomain != null
)
{
services.hyperhive.gateway.vhosts.${hyperhiveCfg.domain}.locations = {
# `<hive>/matrix/*` → 301 → `gatewayHost`'s vhost/$1 (`chat.<swarm-domain>`
# by default; legacy deep-link shim for the fluffychat sub-domain).
# See `docs/networking/gateway.md`.
"/matrix/" = {
extraConfig = ''
rewrite ^/matrix/(.*)$ ${homeserverUrl}/$1 permanent;
'';
};
config = lib.mkMerge [
(lib.mkIf (onHiveVhost && hyperhiveCfg.deploy.matrix.enable) {
# `<hive>/matrix/*` → 301 → `gatewayHost`'s vhost/$1 (`chat.<swarm-domain>`
# by default; legacy deep-link shim for the fluffychat sub-domain).
# See `docs/networking/gateway.md`.
services.hyperhive.gateway.vhosts.${hyperhiveCfg.domain}.locations."/matrix/" = {
extraConfig = ''
rewrite ^/matrix/(.*)$ ${homeserverUrl}/$1 permanent;
'';
};
})
# `.well-known/matrix/{client,server}` discovery JSON, pointing
# clients and peers at `gatewayHost`: the homeserver has no other
# address. CORS `*` per matrix spec. See `docs/networking/gateway.md`.
"= /.well-known/matrix/client" = {
extraConfig = ''
default_type application/json;
${gatewayCfg.lib.securityHeaders}
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver":{"base_url":"${homeserverUrl}"}}';
'';
};
# `m.server` is NOT a URL: per the matrix server-server spec
# (Resolving Server Names) a delegated host with NO port resolves
# to the federation default 8448 (after the SRV check) — the
# https-implies-443 rule does NOT apply here. So the port must be
# explicit even when it's the HTTPS default, unlike the client
# base_url above. Without it, peers federate to <gatewayHost>:8448
# (closed) while the endpoint actually lives on the gateway's 443
# vhost. See docs/networking/gateway.md discovery flow.
"= /.well-known/matrix/server" = {
extraConfig = ''
default_type application/json;
return 200 '{"m.server":"${matrixCfg.gatewayHost}:443"}';
'';
};
(lib.mkIf (onHiveVhost && hyperhiveCfg.domain == serverName) {
services.hyperhive.gateway.vhosts.${hyperhiveCfg.domain}.locations = {
# `.well-known/matrix/{client,server}` discovery JSON, pointing
# clients and peers at `gatewayHost`: the homeserver has no other
# address. CORS `*` per matrix spec. See `docs/networking/gateway.md`.
"= /.well-known/matrix/client" = {
extraConfig = ''
default_type application/json;
${gatewayCfg.lib.securityHeaders}
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver":{"base_url":"${homeserverUrl}"}}';
'';
};
# `m.server` is NOT a URL: per the matrix server-server spec
# (Resolving Server Names) a delegated host with NO port resolves
# to the federation default 8448 (after the SRV check) — the
# https-implies-443 rule does NOT apply here. So the port must be
# explicit even when it's the HTTPS default, unlike the client
# base_url above. Without it, peers federate to <gatewayHost>:8448
# (closed) while the endpoint actually lives on the gateway's 443
# vhost. See docs/networking/gateway.md discovery flow.
"= /.well-known/matrix/server" = {
extraConfig = ''
default_type application/json;
return 200 '{"m.server":"${matrixCfg.gatewayHost}:443"}';
'';
};
};
})
];
}