@orthacms/identity-provider-fake is a deterministic identity provider: no
network, no tenant, no clock skew.
- Published, and installed in every generated app.
- Registered by no composition root. It signs in whoever it was scripted to, without anyone authenticating.
- It really verifies: responses are signed, and
completechecks the signature,stateand nonce, each with its ownSsoVerificationError.
Never in a deployment
Registering it adds a sign-in button that needs no password. Keep it behind a test-only or development-only branch.
Register (tests or local dev only)
import { createFakeSsoProvider } from '@orthacms/identity-provider-fake';
const idp = createFakeSsoProvider({
label: 'Fake IdP', // default
users: [
{ subject: 'idp-ada', email: 'ada@example.com', name: 'Ada', groups: ['cms-editors'] },
{ subject: 'idp-grace', email: 'grace@example.com', emailVerified: false }
]
});
IdentityPlugin(config.plugins.identity, {
sso: {
providers: process.env.NODE_ENV === 'test' ? [{ name: 'fake', provider: idp }] : []
}
});FakeSsoProviderConfig is { users, label?, secret? }. Each user is
{ subject, email, emailVerified?, name?, groups? }; emailVerified defaults
to true. At least one user is required.
Drive it
| Member | What it does |
|---|---|
signInAs(subject) | Who the next authorize hands back. Throws for an unknown subject |
failNextVerification(reason?) | The next complete rejects, once |
calls() | { authorize, complete } counts |
logoutToken({ sessionId?, subject? }) | A back-channel logout token it will accept |
idp.signInAs('idp-grace'); // unverified address: cannot claim an existing account
idp.failNextVerification(); // next callback lands on /identity/signin?error=sso
expect(idp.calls()).toEqual({ authorize: 1, complete: 1 });The whole handshake with curl
The fake’s authorize URL points straight back at the callback, so the flow runs with no browser:
API=http://localhost:3000
# 1. Listed
curl -s $API/api/auth/sso
# [{"name":"fake","label":"Fake IdP","kind":"oidc"}]
# 2. Start: sets the attempt cookie, 302s to the callback with a signed code
CALLBACK=$(curl -s -c jar.txt -o /dev/null -w '%{redirect_url}' $API/api/auth/sso/fake/start)
# 3. Callback: completes sign-in, sets orthacms_session, 302s into the admin
curl -si -b jar.txt -c jar.txt "$CALLBACK" | grep -i '^location\|^set-cookie'
# 4. Signed in as the scripted user
curl -s -b jar.txt $API/api/auth/meBack-channel logout:
# TOKEN = idp.logoutToken({ subject: 'idp-ada' }), taken from your test harness
curl -s -X POST $API/api/auth/sso/fake/backchannel-logout -d "logout_token=$TOKEN"
# {"revoked":1}Testing the linking rule
A first sign-in may claim an existing account only when the provider says
the email is verified. Script emailVerified: false to exercise the refusal.
See what a sign-in may do.
It also sends the PKCE challenge, never the verifier, so the conformance kit’s check is meaningful. It is the worked example for writing an SSO provider.