docs(test): add OIDC/MSC3861 test section + local MAS dev loop
LOTUS_TESTING.md section N (N1-N6): OIDC login flow, session-persist-on-reload, token refresh, logout revocation, account-management link, and the non-OIDC regression check. Backed by dev/oidc-test/ — a runnable local Matrix Authentication Service + Synapse(msc3861) loop (compose skeleton, the Synapse experimental_features delta, and the public/config.json override) so the flow can be verified without a mozilla.org tester. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -410,6 +410,50 @@ Settings → Appearance → theme picker → try each of the 5 new themes.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## N. OIDC / Next-Gen Auth login (MSC3861) — P4-6
|
||||||
|
|
||||||
|
The Lotus client can now sign into OIDC-native homeservers (ones that delegate
|
||||||
|
auth to a Matrix Authentication Service / MAS), e.g. mozilla.org. lotusguild's
|
||||||
|
own server is **not** MSC3861, so test EITHER against a **local MAS dev loop**
|
||||||
|
(full setup in `dev/oidc-test/README.md` — docker-compose + Synapse `msc3861`
|
||||||
|
delta + a `config.json` override) OR against **mozilla.org** with a real account.
|
||||||
|
|
||||||
|
### N1. OIDC login flow (the core test) — needs a MAS homeserver
|
||||||
|
|
||||||
|
1. On the login screen, select the OIDC homeserver (local `localhost:8008`, or `mozilla.org`).
|
||||||
|
2. **Expected:** instead of the username/password form, a single **"Continue with single sign-on"** button appears (password + legacy-SSO are suppressed for that server).
|
||||||
|
3. Click it → redirected to the provider's login page (MAS / `chat.mozilla.org`).
|
||||||
|
4. Authenticate there → redirected back to `…/auth/oidc/callback` → a brief "Signing you in…" spinner → you land in the app, logged in.
|
||||||
|
|
||||||
|
**Expected:** no console CSP violations; you reach the room list as the OIDC user.
|
||||||
|
|
||||||
|
### N2. Session persists across reload (token storage)
|
||||||
|
|
||||||
|
After N1, hard-refresh the page.
|
||||||
|
**Expected:** you stay logged in — the OIDC session (access + refresh token + issuer/clientId/claims) was persisted (`cinny_refresh_token`, `cinny_oidc_*` keys in localStorage).
|
||||||
|
|
||||||
|
### N3. Token refresh (long-lived session)
|
||||||
|
|
||||||
|
Leave the session past the access-token lifetime (MAS default is short — or revoke the access token in the MAS admin UI to force a 401).
|
||||||
|
**Expected:** the client refreshes transparently (no logout); the stored access token rotates (reactive 401 refresh via the wired `OidcTokenRefresher`).
|
||||||
|
|
||||||
|
### N4. Logout revokes at the issuer
|
||||||
|
|
||||||
|
Log out from Settings.
|
||||||
|
**Expected:** back to login; OIDC tokens are revoked at the issuer's `revocation_endpoint` (best-effort) and all `cinny_*` / `cinny_oidc_*` keys are cleared. Logging back in works.
|
||||||
|
|
||||||
|
### N5. Account-management deep-link
|
||||||
|
|
||||||
|
Settings → Account.
|
||||||
|
**Expected:** on an OIDC server a **"Manage account"** card appears (opens the provider's account page in a new tab). On a non-OIDC server (lotusguild) the card is **absent**.
|
||||||
|
|
||||||
|
### N6. Non-OIDC regression — password login unchanged
|
||||||
|
|
||||||
|
Log into **matrix.lotusguild.org** (password) and **matrix.org**.
|
||||||
|
**Expected:** identical to before — username/password form (+ SSO button where offered). The OIDC path only activates when discovery advertises an issuer, so nothing changes for these servers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Priority if you're short on time
|
## Priority if you're short on time
|
||||||
|
|
||||||
1. **A4** (in-call banner) + **A3** (ringtone) — newest, most logic, hardest to reproduce.
|
1. **A4** (in-call banner) + **A3** (ringtone) — newest, most logic, hardest to reproduce.
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
# Local OIDC / next-gen-auth (MSC3861) test loop
|
||||||
|
|
||||||
|
The Lotus client gained MSC3861/MSC2965 OIDC login (P4-6). lotusguild's own
|
||||||
|
homeserver is **not** MSC3861, so to exercise the flow without a mozilla.org
|
||||||
|
tester you need a local homeserver that delegates auth to a **Matrix
|
||||||
|
Authentication Service (MAS)**. This is the dev loop.
|
||||||
|
|
||||||
|
> Status: the Lotus-client side is unit-tested + gate-green; this server loop is
|
||||||
|
> the manual end-to-end check. It hasn't been run in CI (no container runtime
|
||||||
|
> there), so treat version pins as a starting point and bump as needed.
|
||||||
|
|
||||||
|
## 1. Stand up MAS + Synapse
|
||||||
|
|
||||||
|
The simplest path is the **upstream MAS docker-compose quickstart** — it's
|
||||||
|
maintained and handles key generation + the database:
|
||||||
|
<https://element-hq.github.io/matrix-authentication-service/setup/installation.html>
|
||||||
|
(`docker compose` section). Use it to get MAS + Synapse + Postgres running, then
|
||||||
|
apply the two Lotus-specific deltas below.
|
||||||
|
|
||||||
|
A minimal `compose.yaml` skeleton (generate MAS keys first — do **not** hand-write them):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16
|
||||||
|
environment: { POSTGRES_USER: synapse, POSTGRES_PASSWORD: pw, POSTGRES_DB: synapse }
|
||||||
|
mas:
|
||||||
|
image: ghcr.io/element-hq/matrix-authentication-service:latest
|
||||||
|
command: server
|
||||||
|
ports: ['8090:8080'] # MAS issuer on http://localhost:8090
|
||||||
|
volumes: ['./mas:/data']
|
||||||
|
# First run once: `docker compose run --rm mas config generate -o /data/config.yaml`
|
||||||
|
# then edit /data/mas/config.yaml (see §1a) before `up`.
|
||||||
|
synapse:
|
||||||
|
image: ghcr.io/element-hq/synapse:latest
|
||||||
|
ports: ['8008:8008'] # client/federation API
|
||||||
|
volumes: ['./synapse:/data']
|
||||||
|
depends_on: [postgres, mas]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1a. MAS `config.yaml` — the parts that matter
|
||||||
|
After `config generate` (which fills in `secrets.keys` + `encryption`), set:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
http:
|
||||||
|
public_base: http://localhost:8090/
|
||||||
|
issuer: http://localhost:8090/
|
||||||
|
database:
|
||||||
|
uri: postgresql://synapse:pw@postgres/synapse
|
||||||
|
matrix:
|
||||||
|
homeserver: localhost # the server_name
|
||||||
|
endpoint: http://synapse:8008/
|
||||||
|
secret: "REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN"
|
||||||
|
clients:
|
||||||
|
- client_id: "0000000000000000000SYNAPSE"
|
||||||
|
client_auth_method: client_secret_basic
|
||||||
|
client_secret: "REPLACE_WITH_A_SHARED_CLIENT_SECRET"
|
||||||
|
passwords: # so you can create a local test account in the MAS UI
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1b. Synapse `homeserver.yaml` — delegate auth to MAS
|
||||||
|
See `synapse-msc3861.yaml` in this folder; the key block is:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
experimental_features:
|
||||||
|
msc3861:
|
||||||
|
enabled: true
|
||||||
|
issuer: http://localhost:8090/
|
||||||
|
client_id: "0000000000000000000SYNAPSE"
|
||||||
|
client_auth_method: client_secret_basic
|
||||||
|
client_secret: "REPLACE_WITH_A_SHARED_CLIENT_SECRET" # == MAS clients[].client_secret
|
||||||
|
admin_token: "REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN" # == MAS matrix.secret
|
||||||
|
account_management_url: "http://localhost:8090/account"
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a test user via the MAS UI (`http://localhost:8090/`) or
|
||||||
|
`docker compose exec mas mas-cli manage register-user`.
|
||||||
|
|
||||||
|
Sanity check discovery (the client relies on this):
|
||||||
|
```bash
|
||||||
|
curl -s http://localhost:8008/.well-known/matrix/client | jq '."m.authentication"'
|
||||||
|
# -> { "issuer": "http://localhost:8090/", "account": "http://localhost:8090/account" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Point the Lotus dev client at it
|
||||||
|
|
||||||
|
Run the client: `npm start` (vite dev). Override `public/config.json` so the
|
||||||
|
local server is selectable and custom servers are allowed:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"defaultHomeserver": 0,
|
||||||
|
"homeserverList": ["localhost:8008"],
|
||||||
|
"allowCustomHomeservers": true,
|
||||||
|
"hashRouter": { "enabled": false, "basename": "/" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Dynamic client registration handles the redirect URI automatically — it's
|
||||||
|
`<vite-origin>/auth/oidc/callback` (e.g. `http://localhost:5173/auth/oidc/callback`),
|
||||||
|
and MAS allows `http://localhost` redirects in dev.
|
||||||
|
|
||||||
|
## 3. Run the checklist
|
||||||
|
|
||||||
|
See **section N** of `../../LOTUS_TESTING.md` for the actual pass/fail steps
|
||||||
|
(login redirect, callback, session-persist-on-reload, token refresh, logout
|
||||||
|
revocation, account-management link, and the non-OIDC-regression check).
|
||||||
|
|
||||||
|
## Files here
|
||||||
|
- `synapse-msc3861.yaml` — the Synapse experimental-features delta.
|
||||||
|
- `config.local.json` — the Lotus `public/config.json` override.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"defaultHomeserver": 0,
|
||||||
|
"homeserverList": ["localhost:8008"],
|
||||||
|
"allowCustomHomeservers": true,
|
||||||
|
"featuredCommunities": { "openAsDefault": false, "spaces": [], "rooms": [], "servers": [] },
|
||||||
|
"hashRouter": { "enabled": false, "basename": "/" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Synapse experimental-features delta to delegate auth to a local MAS (MSC3861).
|
||||||
|
# Merge this into your test homeserver.yaml. The client_secret + admin_token MUST
|
||||||
|
# match the MAS config (clients[].client_secret and matrix.secret respectively).
|
||||||
|
experimental_features:
|
||||||
|
msc3861:
|
||||||
|
enabled: true
|
||||||
|
issuer: http://localhost:8090/
|
||||||
|
client_id: "0000000000000000000SYNAPSE"
|
||||||
|
client_auth_method: client_secret_basic
|
||||||
|
client_secret: "REPLACE_WITH_A_SHARED_CLIENT_SECRET"
|
||||||
|
admin_token: "REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN"
|
||||||
|
account_management_url: "http://localhost:8090/account"
|
||||||
|
|
||||||
|
# With msc3861 enabled, Synapse disables its own password/SSO login and advertises
|
||||||
|
# `m.authentication` in /.well-known/matrix/client — which is exactly what the
|
||||||
|
# Lotus client's getOidcIssuer() reads to switch into the OIDC flow.
|
||||||
Reference in New Issue
Block a user