Because:
- 321done could not complete a sign-in: one environment variable served
both demo clients, and the shared secrets file overrode the
per-instance config, so the untrusted app sent the wrong secret.
- An untrusted client's sign-in redirected straight back to the relying
party, telling the user nothing about the profile information it reads.
- No functional test drove the untrusted client, so both gaps were
invisible.
This commit:
- Loads the per-instance 123done config after the shared secrets file,
and keeps CI's CLIENT_SECRET_123DONE out of 321done, so each client
resolves its own secret.
- Adds a React consent screen at /signin_permissions that lists the
email and display name an untrusted client can read, recording what
it showed in the `permissions` field Backbone also writes.
- Gates useFinishOAuthFlowHandler on a new isUntrusted(), so every flow
that completes OAuth shows the screen, not only sign-in.
- Returns access_denied to the relying party when the user cancels.
- Badges the untrusted demo app, and adds page objects, Playwright
tests, and unit tests for the consent rules.