Skip to content

Central Sign-in

A shop on central sign-in sends shoppers and staff to the auth server (auth.bdgr.co.uk, the auth module) to sign in, with a password, passkey, an emailed sign-in code or Google/Apple, instead of to its own /login form. One sign-in then works on every shop that uses it.

Two kinds of account

Lives in Holds
Central identity (AuthIdentity) auth_identities, one per email across all shops Password, passkeys, social links, lockout
Shop account (User) users, one per email per site group Orders, roles, details, baskets

The auth server only checks credentials against central identities. After a central sign-in the shop finds its own account by email (OidcAuthenticationSuccessHandler), or makes one, so orders and roles carry over.

Turning it on for a shop

System → Tenants → {site} → Enable Central Auth registers the shop's OAuth client (site-<siteId>) and sets central-auth-enabled. Turning the setting on by hand isn't enough: without the client (oauth2-client-id) the shop quietly keeps its old form while the tenant page shows it enabled. Use the button, or disable and enable again to repair it.

Existing shop accounts move over on their own

Accounts made on the shop's old form have no central identity. Nothing has to be run before switching: each one moves the first time its owner signs in on the auth server with their old password (ShopAccountClaimService, run by ShopAccountClaimFilter ahead of the password login).

  1. They sign in from the shop as usual. There's no central identity for the email, but the password matches their account on that shop (the shop the sign-in came from; other shops aren't searched).
  2. A pending central identity is made with that password, re-encoded for the auth server (so the shops' older hash formats don't matter), and they're emailed a sign-in code and link to confirm their email (the same email sign-in as everywhere else, EmailSignInFlow).
  3. Typing the code, or clicking the link, confirms the identity, signs them in and takes them back to the shop.

Wrong passwords count against the shop's own back-off (SignInRateLimiter), as on its old form, and so does an email with no account on that shop (or a guest one with no password): it's checked against a dummy password, so it takes as long and the timing doesn't say who has an account. An account the shop has banned, or marked for deletion, is never claimed.

Someone who has forgotten their old password signs in with an emailed code instead, which makes a confirmed central identity for the address if there isn't one, or registers again (below). Either way their shop account, with its orders, is found by email after they're signed in.

The one-off AuthIdentityMigration (the migrate profile) predates this and isn't needed when moving a shop: it makes identities without confirming anyone owns the email.

Every new identity confirms its email first

Registering on the auth server (password, email only or passkey) or claiming a shop account makes a pending identity. Nothing signs in to it until the code emailed to the address is typed in, or its link clicked (PendingIdentityService, called when the email sign-in finishes):

  • The password and passkey logins refuse a pending identity, and so does step-up (re-checking the password before a sensitive action); the auth server won't issue it an id_token either.
  • The password and name chosen while pending are kept only if the email is confirmed in the same browser session that chose them (typing the code there, or opening the link there). Confirmed anywhere else, they're still signed in, but they have no password until they set one from their account. Otherwise a stranger could register someone's email with a password of their own and wait for its owner to confirm it.
  • Each browser that starts the same pending identity (registering, or claiming with the shop password) gets its own start, with its own password and name; the most recent five are kept. So someone registering the address from another browser never replaces the owner's password. Starting again in the same browser replaces that browser's start. A confirmed identity can't be registered again.
  • Signing in with Google, Apple or Badger Sett confirms a pending identity for the same email, since the provider has verified it, and drops its pending passwords; the name comes from the provider. This holds even for a provider that otherwise isn't allowed to join an existing identity by email: nobody has proven they own a pending one.
  • Passkey registration confirms the email first; the passkey is added from the account page afterwards.

Addresses are stored lower-cased and looked up whatever their capitals (identities made earlier may hold capitals), so typing an address differently never makes a second identity.

Before this, registering with someone's email signed you straight in, and the shops' link by email handed over that customer's account, orders included. Identities made before pending existed count as confirmed.