mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
feat(matrix): full onion support — OIDC backchannel, MXIDs, Tor-stable specs
Synapse on an onion node could never complete SSO: it has no Tor, so the http://auth.<onion> issuer was unresolvable server-side (discovery/jwks/ token), and Synapse hard-rejects non-https issuers on top. - runner/hostpin.{sh,service}: pin the onion auth host to the runner's real default gateway (node OpenResty) from /proc/net/route, Before=docker.service so nested containers see it from their first request; host-gateway is unusable in nested DinD (resolves to the inner docker0) - Synapse bind-mounts the runner's /etc/hosts; token iss stays the onion issuer the browser uses - bootstrap.service: PassEnvironment (systemd units do not inherit container env; MATRIX_MDAD_PLAYBOOK_TAGS only worked via its fallback default) - vars.yml.j2: skip_verification on onion (Synapse's escape hatch for issuers without https; Tor provides transport security per RFC 7686) - 02_render_inventory: drop the MDAD bootstrap marker + bounce the runner on inventory changes — mode=update reconfigures the nested stack at all now - MATRIX_SERVER_NAME follows matrix_domain onto the onion so MXIDs built from it (DM spec, bridge configs) reference users that exist - specs: shared Firefox onion fixture (16 files), gotoElementApp reload-retry against Element's Tor-triggered init race, seaweedfs spec gates on the filer frontend, env uses canonical_url consumer= Verified in-container: SSO 302 to onion Keycloak, admin+biber OIDC login, E2EE DM admin<->biber, CSP — all green over Tor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
5abfcfc6d6
commit
0a581f6622
26 files changed
+140
-34
No files matched your search
@@ -68,8 +68,10 @@ RUN ansible-galaxy collection install \
|
||||
COPY daemon.json /etc/docker/daemon.json
|
||||
COPY bootstrap.sh /usr/local/bin/matrix-mdad-bootstrap
|
||||
COPY bootstrap.service /etc/systemd/system/matrix-mdad-bootstrap.service
|
||||
RUN chmod 0755 /usr/local/bin/matrix-mdad-bootstrap \
|
||||
&& systemctl enable containerd.service docker.service matrix-mdad-bootstrap.service
|
||||
COPY hostpin.sh /usr/local/bin/matrix-mdad-hostpin
|
||||
COPY hostpin.service /etc/systemd/system/matrix-mdad-hostpin.service
|
||||
RUN chmod 0755 /usr/local/bin/matrix-mdad-bootstrap /usr/local/bin/matrix-mdad-hostpin \
|
||||
&& systemctl enable containerd.service docker.service matrix-mdad-bootstrap.service matrix-mdad-hostpin.service
|
||||
|
||||
WORKDIR /mdad
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
|
||||
@@ -6,6 +6,7 @@ Requires=docker.service
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Environment=PATH=/opt/ansible/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
PassEnvironment=MATRIX_MDAD_PLAYBOOK_TAGS
|
||||
ExecStartPre=/usr/bin/docker info
|
||||
ExecStart=/usr/local/bin/matrix-mdad-bootstrap
|
||||
RemainAfterExit=yes
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Pin the onion OIDC host to the node gateway before nested docker starts
|
||||
Before=docker.service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
PassEnvironment=MATRIX_OIDC_ONION_HOST
|
||||
ExecStart=/usr/local/bin/matrix-mdad-hostpin
|
||||
RemainAfterExit=yes
|
||||
StandardOutput=journal+console
|
||||
StandardError=journal+console
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ -z "${MATRIX_OIDC_ONION_HOST:-}" ]; then
|
||||
echo ">>> matrix-mdad-hostpin: MATRIX_OIDC_ONION_HOST unset, nothing to pin"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
_gw_hex="$(awk '$2 == "00000000" { print $3; exit }' /proc/net/route)"
|
||||
if [ -z "${_gw_hex}" ]; then
|
||||
echo "!!! matrix-mdad-hostpin: no default route found, skipping pin" >&2
|
||||
exit 0
|
||||
fi
|
||||
_gw="$(printf '%d.%d.%d.%d' "0x${_gw_hex:6:2}" "0x${_gw_hex:4:2}" "0x${_gw_hex:2:2}" "0x${_gw_hex:0:2}")"
|
||||
|
||||
_hosts_tmp="$(mktemp)"
|
||||
grep -v "[[:space:]]${MATRIX_OIDC_ONION_HOST}\$" /etc/hosts > "${_hosts_tmp}" || true
|
||||
printf '%s\t%s\n' "${_gw}" "${MATRIX_OIDC_ONION_HOST}" >> "${_hosts_tmp}"
|
||||
cat "${_hosts_tmp}" > /etc/hosts
|
||||
rm -f "${_hosts_tmp}"
|
||||
echo ">>> matrix-mdad-hostpin: pinned ${MATRIX_OIDC_ONION_HOST} -> ${_gw} (node OpenResty)"
|
||||
@@ -1,4 +1,4 @@
|
||||
const { expect } = require("@playwright/test");
|
||||
const { expect } = require("./onion-test");
|
||||
const { resolveTimeout } = require("./timeouts");
|
||||
const { isServiceEnabled, skipUnlessServiceEnabled } = require("./service-gating");
|
||||
const {
|
||||
@@ -49,6 +49,30 @@ function attachDiagnostics(page) {
|
||||
return { consoleErrors, pageErrors, cspRelated };
|
||||
}
|
||||
|
||||
const ELEMENT_INIT_CRASH_RE = /Unexpected error preparing the app|Element is misconfigured/i;
|
||||
|
||||
async function gotoElementApp(page, url, readyLocator) {
|
||||
const attempts = Number(process.env.PLAYWRIGHT_ELEMENT_BOOT_RETRIES) || 4;
|
||||
const perAttempt = resolveTimeout(20_000);
|
||||
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
||||
if (attempt === 1) {
|
||||
await gotoOnion(page, url, { waitUntil: "domcontentloaded" });
|
||||
} else {
|
||||
await page.reload({ waitUntil: "domcontentloaded", timeout: resolveTimeout(90_000) });
|
||||
}
|
||||
const deadline = Date.now() + perAttempt;
|
||||
while (Date.now() < deadline) {
|
||||
if (await readyLocator.isVisible().catch(() => false)) return;
|
||||
const bodyText = await page.locator("body").innerText().catch(() => "");
|
||||
if (ELEMENT_INIT_CRASH_RE.test(bodyText)) break;
|
||||
await page.waitForTimeout(2_000);
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
`Element failed to mount at ${url} after ${attempts} attempt(s) (init crash / no ready signal)`
|
||||
);
|
||||
}
|
||||
|
||||
// Matrix Element SSO flow. Element stores the selected homeserver in
|
||||
// sessionStorage during SSO initiation and reads it back when consuming the
|
||||
// `?loginToken=…` the homeserver hands it after Keycloak auth. Hitting
|
||||
@@ -60,8 +84,6 @@ function attachDiagnostics(page) {
|
||||
async function signInViaElementOidc(page, username, password, personaLabel) {
|
||||
const expectedOidcAuthUrl = `${oidcIssuerUrl}/protocol/openid-connect/auth`;
|
||||
|
||||
await gotoOnion(page, `${elementBaseUrl}/#/login`);
|
||||
|
||||
const ssoButton = page
|
||||
.locator(
|
||||
[
|
||||
@@ -76,6 +98,7 @@ async function signInViaElementOidc(page, username, password, personaLabel) {
|
||||
.locator("button, a, div[role='button']")
|
||||
.filter({ hasText: /single\s*sign[- ]*on|continue\s+with\s+(sso|oidc|keycloak|openid)|sign\s+in\s+with\s+(sso|oidc|keycloak|openid)/i })
|
||||
.first();
|
||||
await gotoElementApp(page, `${elementBaseUrl}/#/login`, ssoButton.or(ssoTextButton));
|
||||
const candidate = (await ssoButton.isVisible({ timeout: resolveTimeout(15_000) }).catch(() => false))
|
||||
? ssoButton
|
||||
: ssoTextButton;
|
||||
@@ -330,11 +353,10 @@ async function signInViaElementOidc(page, username, password, personaLabel) {
|
||||
// indistinguishable from Element's side. Skip-verification + service-worker
|
||||
// dismissal mirror the OIDC path; Synapse SSO consent does not apply.
|
||||
async function signInViaElementPassword(page, username, password, personaLabel) {
|
||||
await gotoOnion(page, `${elementBaseUrl}/#/login`);
|
||||
|
||||
const userField = page
|
||||
.locator('input[name="username"], #mx_LoginForm_username, input[name="mxid"], input[data-testid="login_field_mx_id"]')
|
||||
.first();
|
||||
await gotoElementApp(page, `${elementBaseUrl}/#/login`, userField);
|
||||
await expect(userField, `${personaLabel}: Element password login username field must appear`).toBeVisible({ timeout: resolveTimeout(30_000) });
|
||||
await userField.fill(username);
|
||||
|
||||
@@ -453,6 +475,7 @@ module.exports = {
|
||||
expectNoCspViolations,
|
||||
installCspViolationObserver,
|
||||
runGuestFlow,
|
||||
gotoElementApp,
|
||||
signInViaElementOidc,
|
||||
signInViaElementPassword,
|
||||
signInViaElement,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("../onion-test");
|
||||
const { resolveTimeout } = require("../timeouts");
|
||||
const { skipUnlessAddonEnabled } = require("../addon-gating");
|
||||
const shared = require("../_shared");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("../onion-test");
|
||||
const { resolveTimeout } = require("../timeouts");
|
||||
const { skipUnlessAddonEnabled } = require("../addon-gating");
|
||||
const shared = require("../_shared");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("../onion-test");
|
||||
const { resolveTimeout } = require("../timeouts");
|
||||
const { skipUnlessAddonEnabled } = require("../addon-gating");
|
||||
const shared = require("../_shared");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("../onion-test");
|
||||
const { resolveTimeout } = require("../timeouts");
|
||||
const { skipUnlessAddonEnabled } = require("../addon-gating");
|
||||
const shared = require("../_shared");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("../onion-test");
|
||||
const { resolveTimeout } = require("../timeouts");
|
||||
const { skipUnlessAddonEnabled } = require("../addon-gating");
|
||||
const shared = require("../_shared");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test } = require("@playwright/test");
|
||||
const { test } = require("./onion-test");
|
||||
const { resolveTimeout } = require("./timeouts");
|
||||
|
||||
const shared = require("./_shared");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("./onion-test");
|
||||
|
||||
const BRIDGE_TO_BOT_LOCALPART = {
|
||||
appservice_irc: "ircbot",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("./onion-test");
|
||||
const { gotoOnion } = require("./personas");
|
||||
|
||||
exports.register = function (shared) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("./onion-test");
|
||||
const { resolveTimeout } = require("./timeouts");
|
||||
|
||||
exports.register = function (shared) {
|
||||
@@ -62,9 +62,12 @@ exports.register = function (shared) {
|
||||
// button we need lives inside the profile panel specifically (there is a
|
||||
// separate "Send a Direct Message" button on the welcome screen that
|
||||
// opens a search dialog rather than directly messaging biber).
|
||||
await adminPage.goto(`${elementBaseUrl}/#/user/${encodeURIComponent(biberMatrixId)}`);
|
||||
|
||||
const profilePanel = adminPage.getByRole("complementary").filter({ hasText: biberMatrixId });
|
||||
await shared.gotoElementApp(
|
||||
adminPage,
|
||||
`${elementBaseUrl}/#/user/${encodeURIComponent(biberMatrixId)}`,
|
||||
profilePanel
|
||||
);
|
||||
await expect(profilePanel, "admin: biber profile panel must render").toBeVisible({ timeout: resolveTimeout(60_000) });
|
||||
|
||||
const profileSendMessageButton = profilePanel
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("./onion-test");
|
||||
|
||||
exports.register = function (shared) {
|
||||
test("element-call: Element config.json advertises a video-call backend when conferencing is enabled", async ({ request }) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test } = require("@playwright/test");
|
||||
const { test } = require("./onion-test");
|
||||
|
||||
exports.register = function (shared) {
|
||||
test("guest: public-landing → auth chain → never authenticated", async ({ page }) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test } = require("@playwright/test");
|
||||
const { test } = require("./onion-test");
|
||||
|
||||
exports.register = function (shared) {
|
||||
test("administrator: matrix element native password login (no oidc)", async ({ page }) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test } = require("@playwright/test");
|
||||
const { test } = require("./onion-test");
|
||||
|
||||
exports.register = function (shared) {
|
||||
test("administrator: matrix element OIDC login and logout", async ({ page }) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { test } = require("@playwright/test");
|
||||
const { test } = require("./onion-test");
|
||||
|
||||
exports.register = function (shared) {
|
||||
test("biber: matrix element OIDC login and logout", async ({ page }) => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// signInViaElement, and the SEAWEEDFS_* keys consumed by
|
||||
// runSeaweedfsStorageCheck.
|
||||
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const { test, expect } = require("./onion-test");
|
||||
const { resolveTimeout } = require("./timeouts");
|
||||
const { skipUnlessServiceEnabled } = require("./service-gating");
|
||||
const { runSeaweedfsStorageCheck } = require("./personas");
|
||||
@@ -31,6 +31,7 @@ test.use({ ignoreHTTPSErrors: true });
|
||||
|
||||
test("seaweedfs: an uploaded Matrix avatar is stored in the SeaweedFS bucket", async ({ page, browser }) => {
|
||||
skipUnlessServiceEnabled("seaweedfs");
|
||||
skipUnlessServiceEnabled("seaweedfs_frontend");
|
||||
test.skip(
|
||||
!(process.env.MATRIX_FLAVOR || "").toLowerCase().includes("ansible"),
|
||||
"Matrix media is offloaded to SeaweedFS only in the ansible flavor; the compose flavor stores media on local disk, so the bucket never grows.",
|
||||
|
||||
@@ -143,3 +143,4 @@ tor:
|
||||
bond: 1
|
||||
enabled: "{{ 'svc-net-tor' in group_names }}"
|
||||
shared: true # nocheck: dynamic-flag
|
||||
exclusive: true
|
||||
@@ -16,3 +16,17 @@
|
||||
src: "flavor/ansible/vars.yml.j2"
|
||||
dest: "{{ MATRIX_MDAD_DIR }}/inventory/host_vars/{{ MATRIX_SYNAPSE_DOMAIN }}/vars.yml"
|
||||
mode: "0644"
|
||||
register: _matrix_mdad_vars
|
||||
|
||||
- name: "reconfigure matrix-mdad on inventory change"
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
_mp="$(docker volume inspect -f '{% raw %}{{ .Mountpoint }}{% endraw %}' matrix_matrix_mdad_state)"
|
||||
rm -f "${_mp}/bootstrap.done"
|
||||
if docker ps -q -f name=^matrix-mdad$ | grep -q .; then
|
||||
docker restart matrix-mdad
|
||||
fi
|
||||
args:
|
||||
executable: /bin/bash
|
||||
become: true
|
||||
when: _matrix_mdad_vars is changed
|
||||
@@ -14,6 +14,9 @@
|
||||
stop_signal: SIGRTMIN+3
|
||||
environment:
|
||||
MATRIX_MDAD_PLAYBOOK_TAGS: "{{ MATRIX_MDAD_PLAYBOOK_TAGS }}"
|
||||
{% if MATRIX_OIDC_ENABLED and MATRIX_OIDC_HOST_IS_ONION %}
|
||||
MATRIX_OIDC_ONION_HOST: "{{ MATRIX_OIDC_HOST }}"
|
||||
{% endif %}
|
||||
{% set _objstore = lookup('objstore', application_id) %}
|
||||
networks:
|
||||
default: {}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
---
|
||||
matrix_domain: {{ DOMAIN_PRIMARY }}
|
||||
{% set _matrix_onion_node = lookup('config', 'svc-net-tor', 'services.tor.node', '') %}
|
||||
{% set _matrix_is_onion = (_matrix_onion_node and lookup('domain', application_id) is search('\.onion$')) %}
|
||||
matrix_domain: {{ _matrix_onion_node if _matrix_is_onion else DOMAIN_PRIMARY }}
|
||||
matrix_playbook_ssl_enabled: {{ 'false' if _matrix_is_onion else 'true' }}
|
||||
matrix_homeserver_implementation: synapse
|
||||
matrix_playbook_docker_installation_enabled: false
|
||||
matrix_playbook_migration_validated_version: "{{ MATRIX_MDAD_MIGRATION_VALIDATED_VERSION }}"
|
||||
@@ -59,11 +62,22 @@ jitsi_jicofo_container_network: host
|
||||
|
||||
matrix_livekit_jwt_service_container_port: 8030
|
||||
|
||||
{% set _synapse_extra_args = [] %}
|
||||
{% if (TLS_MODE | lower) == 'self_signed' %}
|
||||
{% set _ = _synapse_extra_args.extend([
|
||||
'--mount type=bind,src=' ~ CA_TRUST.cert_host ~ ',dst=' ~ MATRIX_CA_MOUNT_PATH ~ ',ro',
|
||||
'-e SSL_CERT_FILE=' ~ MATRIX_CA_MOUNT_PATH,
|
||||
'-e REQUESTS_CA_BUNDLE=' ~ MATRIX_CA_MOUNT_PATH,
|
||||
]) %}
|
||||
{% endif %}
|
||||
{% if MATRIX_OIDC_ENABLED and MATRIX_OIDC_HOST_IS_ONION %}
|
||||
{% set _ = _synapse_extra_args.append('--mount type=bind,src=/etc/hosts,dst=/etc/hosts,ro') %}
|
||||
{% endif %}
|
||||
{% if _synapse_extra_args | length > 0 %}
|
||||
matrix_synapse_container_extra_arguments:
|
||||
- "--mount type=bind,src={{ CA_TRUST.cert_host }},dst={{ MATRIX_CA_MOUNT_PATH }},ro"
|
||||
- "-e SSL_CERT_FILE={{ MATRIX_CA_MOUNT_PATH }}"
|
||||
- "-e REQUESTS_CA_BUNDLE={{ MATRIX_CA_MOUNT_PATH }}"
|
||||
{% for _arg in _synapse_extra_args %}
|
||||
- "{{ _arg }}"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if MATRIX_COTURN_SHARED %}
|
||||
@@ -96,6 +110,9 @@ matrix_synapse_oidc_providers:
|
||||
idp_name: "{{ OIDC.BUTTON_TEXT }}"
|
||||
discover: true
|
||||
issuer: "{{ OIDC.CLIENT.ISSUER_URL }}"
|
||||
{% if _matrix_is_onion %}
|
||||
skip_verification: true
|
||||
{% endif %}
|
||||
client_id: "{{ OIDC.CLIENT.ID }}"
|
||||
client_secret: "{{ OIDC.CLIENT.SECRET }}"
|
||||
scopes:
|
||||
|
||||
@@ -10,9 +10,9 @@ BIBER_USERNAME={{ lookup('users', 'biber').username | dotenv_quote }}
|
||||
|
||||
BRIDGES_SERVICE_ENABLED={{ (MATRIX_BRIDGE.values() | list | select | list | length > 0) | string | lower }}
|
||||
|
||||
CANONICAL_DOMAIN={{ (lookup('applications', application_id).server.domains.canonical.element) | dotenv_quote }}
|
||||
CANONICAL_DOMAIN={{ lookup('domains', application_id).element | dotenv_quote }}
|
||||
|
||||
ELEMENT_BASE_URL={{ lookup('tls', lookup('config', application_id, 'server.domains.canonical.element'), 'url.base') | dotenv_quote }}
|
||||
ELEMENT_BASE_URL={{ lookup('canonical_url', application_id, 'element') | dotenv_quote }}
|
||||
|
||||
ELEMENT_CALL_SERVICE_ENABLED={{ MATRIX_CONFERENCING_ELEMENT_CALL | string | lower }}
|
||||
|
||||
@@ -30,7 +30,7 @@ MATOMO_BASE_URL={{ lookup('tls', 'web-app-matomo', 'url.base') | dotenv_quote }}
|
||||
# nocheck: playwright-service-gate — consumed via shared persona helpers (roles/test-e2e-playwright/files/personas/)
|
||||
MATOMO_SERVICE_ENABLED={{ lookup('config', application_id, 'services.matomo.enabled') | string | lower }}
|
||||
|
||||
MATRIX_BASE_URL={{ lookup('tls', lookup('config', application_id, 'server.domains.canonical.synapse'), 'url.base') | dotenv_quote }}
|
||||
MATRIX_BASE_URL={{ lookup('canonical_url', application_id, 'synapse') | dotenv_quote }}
|
||||
|
||||
MATRIX_FLAVOR={{ lookup('config', application_id, 'services.matrix.flavor') | dotenv_quote }}
|
||||
|
||||
@@ -46,10 +46,12 @@ SEAWEEDFS_ADMIN_USERNAME={{ MATRIX_ADMINISTRATOR_USERNAME | dotenv_quote }}
|
||||
|
||||
SEAWEEDFS_APP_BUCKET={{ lookup('objstore', application_id, 'bucket') | dotenv_quote }}
|
||||
|
||||
SEAWEEDFS_FILER_URL={{ ((lookup('tls', 'web-app-seaweedfs', 'protocols.web') ~ '://' ~ lookup('config', 'web-app-seaweedfs', 'server.domains.canonical.filer')) if (lookup('config', application_id, 'services.seaweedfs.enabled') | bool) else '') | dotenv_quote }}
|
||||
SEAWEEDFS_FILER_URL={{ lookup('canonical_url', 'web-app-seaweedfs', 'filer', consumer=application_id) | dotenv_quote }}
|
||||
|
||||
SEAWEEDFS_SERVICE_ENABLED={{ lookup('config', application_id, 'services.seaweedfs.enabled') | string | lower }}
|
||||
|
||||
SEAWEEDFS_FRONTEND_SERVICE_ENABLED={{ lookup('config', 'web-app-seaweedfs', 'services.frontend.enabled', false) | string | lower }}
|
||||
|
||||
SSO_SERVICE_ENABLED={{ lookup('config', application_id, 'services.sso.enabled') | string | lower }}
|
||||
|
||||
{% for bridge in MATRIX_BRIDGES | default([], true) %}
|
||||
|
||||
@@ -3,7 +3,8 @@ application_id: "web-app-matrix"
|
||||
|
||||
location_upload: "~ ^/_matrix/media/v3/"
|
||||
|
||||
MATRIX_SERVER_NAME: "{{ lookup('config', application_id, 'services.matrix.server_name') }}"
|
||||
MATRIX_ONION_NODE: "{{ lookup('config', 'svc-net-tor', 'services.tor.node', '') }}"
|
||||
MATRIX_SERVER_NAME: "{{ MATRIX_ONION_NODE if (MATRIX_ONION_NODE and lookup('domain', application_id) is search('\\.onion$')) else lookup('config', application_id, 'services.matrix.server_name') }}"
|
||||
MATRIX_ADMINISTRATOR_USERNAME: "{{ lookup('users', 'administrator').username }}"
|
||||
MATRIX_ADMINISTRATOR_PASSWORD: "{{ lookup('users', 'administrator').password }}"
|
||||
MATRIX_WELL_KNOWN_DIRECTORY: "{{ [ lookup('nginx','directories.data.well_known'), 'matrix' ] | path_join }}"
|
||||
@@ -12,6 +13,8 @@ MATRIX_REGISTRATION_FILE_FOLDER: "/data/"
|
||||
MATRIX_REGISTRATION_SHARED_SECRET: "{{ lookup('config', application_id, 'credentials.registration_shared_secret') }}"
|
||||
MATRIX_FEDERATION_PORT: "{{ lookup('config', 'web-app-matrix', 'services.synapse.ports.public.federation') }}"
|
||||
MATRIX_OIDC_ENABLED: "{{ lookup('config', application_id, 'services.sso.enabled') }}"
|
||||
MATRIX_OIDC_HOST: "{{ lookup('domain', 'web-app-keycloak') }}"
|
||||
MATRIX_OIDC_HOST_IS_ONION: "{{ MATRIX_OIDC_HOST is search('\\.onion$') }}"
|
||||
MATRIX_BASE_URL: "{{ lookup('tls', application_id, 'protocols.web') }}://{{ DOMAIN_PRIMARY }}"
|
||||
|
||||
MATRIX_SYNAPSE_VERSION: "{{ lookup('config', application_id, 'services.synapse.version') }}"
|
||||
@@ -25,7 +28,7 @@ MATRIX_SYNAPSE_CONFIG_PATH_HOST: "{{ [ lookup('container', application_id, 'dire
|
||||
MATRIX_SYNAPSE_CONFIG_PATH_CONTAINER: "/data/homeserver.yaml"
|
||||
MATRIX_SYNAPSE_LOG_PATH_HOST: "{{ [ lookup('container', application_id, 'directories.config'), MATRIX_SYNAPSE_DOMAIN ~'.log.config' ] | path_join }}"
|
||||
MATRIX_SYNAPSE_LOG_PATH_CONTAINER: "/data/{{ MATRIX_SYNAPSE_DOMAIN }}.log.config"
|
||||
MATRIX_SYNAPSE_URL: "{{ lookup('tls', application_id, 'protocols.web') }}://{{ MATRIX_SYNAPSE_DOMAIN }}"
|
||||
MATRIX_SYNAPSE_URL: "{{ lookup('canonical_url', application_id, 'synapse') }}"
|
||||
MATRIX_SYNAPSE_LISTEN_FLAGS: "{{ MATRIX_FEDERATION_PORT }} {{ 'ssl ' if (lookup('tls', application_id, 'enabled') | bool) else '' }} default_server"
|
||||
|
||||
MATRIX_ELEMENT_VERSION: "{{ lookup('config', application_id, 'services.element.version') }}"
|
||||
|
||||
Reference in new issue
Block a user