feat: in-app Chat (Matrix JWT SSO) + Drive (embedded oCIS)

- api: matrix-sso module (tuwunel jwt -> login/get_token), POST /matrix/session, GET /matrix/identity, drive controller
- web: /chat full-height Element view, /files Library+Drive tabs, embedded-app frame component
- edge: /hub-sso.html handshake route (origin-pinned CSP), X-Frame-Options strip on files
- oCIS: csp.yaml frame-ancestors app.occupymedia.cc
- server config still required: tuwunel [global.jwt], MATRIX_SSO_JWT_SECRET, oCIS restart
This commit is contained in:
glass beadian 2026-10-13 14:57:07 +00:00
parent a2aa70c961
commit fe5f2403d6
22 changed files with 1057 additions and 8 deletions

View file

@ -85,6 +85,14 @@ services:
ARCHIVE_PROVISIONER_HOMESERVER_URL: ${ARCHIVE_PROVISIONER_HOMESERVER_URL:-}
ARCHIVE_PROVISIONER_USER: ${ARCHIVE_PROVISIONER_USER:-}
ARCHIVE_PROVISIONER_PASSWORD: ${ARCHIVE_PROVISIONER_PASSWORD:-}
# In-app Chat sign-in: same secret as [global.jwt] key in tuwunel.toml.
# Unset = the Chat view falls back to Element's own sign-in screen.
MATRIX_SSO_JWT_SECRET: ${MATRIX_SSO_JWT_SECRET:-}
MATRIX_SSO_HOMESERVER_URL: ${MATRIX_SSO_HOMESERVER_URL:-https://chat.occupymedia.cc}
MATRIX_SSO_LOCALPART_PREFIX: ${MATRIX_SSO_LOCALPART_PREFIX:-}
# In-app Drive: oCIS web origin + auth mode (interactive | oidc).
FILES_DRIVE_URL: ${FILES_DRIVE_URL:-https://files.occupymedia.cc}
FILES_DRIVE_AUTH: ${FILES_DRIVE_AUTH:-interactive}
ports: ["3000:3000"]
depends_on:
postgres: { condition: service_healthy }