mtg: OIDC login with Google
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- rust, typescript
Direzione di ricerca
Start by reading ADR-0002 and the glossaries at libs/galvyn-identity/GLOSSARY.md and services/mtg/GLOSSARY.md, then trace IdentitySetup and the auth handlers in services/mtg/src/http/handler_frontend/auth/handler.rs. The issue names config.rs, dev/common/env.common, deploy/mtg/env.example, the frontend login and signup pages, and the admin dashboard as implementation entry points. Run the specified HTTP harness tests and just ci; done means the acceptance criteria pass, including signup, returning login, locked accounts, collision handling, and no recovery or signup mail for external accounts.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Feature branch: mtg-oidc-login (starts with the glossary commit 32be03bd).
Goal
People can sign up for and log in to mtg with their Google account, as an alternative to Passkeys. This is the first OIDC login in the repo, built as the OIDC login method of libs/galvyn-identity that ADR-0002 already decided on.
Vocabulary follows libs/galvyn-identity/GLOSSARY.md and services/mtg/GLOSSARY.md (Local Account, External Account, External identity, OpenID provider). "Social login" is not a domain term; the UI may say "Continue with Google".
Decisions
- Google only, through generic OIDC. An OpenID provider is configured by issuer, client id, client secret and display name. GitHub and Discord are not OIDC and stay out (a separate decision). Apple comes later as its own step; the module should leave room for a signed (JWT) client secret and a
form_postcallback, but builds neither now. - Local or external, never both, never switching (ADR-0002). A Local Account cannot add Google; an External Account cannot add a Passkey. No migration path in either direction.
- Google admits people on their first OIDC login. No Registration link needed.
- Username step. On a first OIDC login with an unknown External identity, the person picks a username. Until then a short-lived pending state in the session holds issuer, subject and email. Identity, External identity and Account are only created when the username is submitted; abandoning the step creates nothing.
- Email comes from the provider and is only accepted when
email_verifiedis true; the person never types one. It is stored once and never synced on later logins (mtg has no email change for any Account). - Email collision. If the verified email already belongs to an Account, the first OIDC login is refused with a hint to use Passkey login or recovery. Revealing that the address is in use is acceptable here: only the address's owner can present it verified.
- No recovery for External Accounts. Whoever controls the Google account can log in; if the Google account is gone, so is the mtg Account. The Identity module may support recovery for external Identities, mtg does not offer it.
- Lock works as for Local Accounts: OIDC login refused with
locked, existing sessions fail on their next request. - Deletion removes the Identity and External identity too. A later login with the same Google account goes through the username step and creates a new Account; the old public decks stay with the Tombstone.
- One button "Continue with Google" on both the login and the signup page. No username asked first: a known External identity logs in, an unknown one goes to the username step.
- Provider configuration via env vars, loaded with
EnvLoader. Each provider is optional: without its env vars it is off and its button is hidden. An open endpoint lists the active providers (id + display name) for the frontend. No admin UI for providers. - Admin dashboard shows whether an Account is local or external, and the provider, in both the Account list and the Account detail. Display only. The Admin log is unchanged.
Scope
libs/galvyn-identity: new oidc cargo feature
- Models: External identity (issuer + subject, bound to exactly one external Identity), with a unique constraint on (issuer, subject). Cascade on Identity deletion.
- Provider setup in
IdentitySetup(issuer, client id, secret, display name, whether it admits on first login), discovery from the issuer. - Login ceremony: authorization code flow with PKCE,
stateandnonce, ID token validation (issuer, audience, expiry, nonce, signature via JWKS). Session keys stay owned by the module. - Outcome of a finished OIDC login: either the known Identity (logged in,
last_login_atupdated) or an unknown External identity held as the pending state, plus the verified email for the service. - An operation that binds the pending External identity to a fresh Identity, called by the service inside the transaction that creates its Account.
- An Identity is local or external: Passkey enrollment refused for an external Identity, OIDC enrollment refused for a local one.
- Updates to the crate docs (
lib.rs), itsGLOSSARY.mdonly if a new term emerges.
services/mtg
- Enable the
oidcfeature, provider env vars inconfig.rs,dev/common/env.commonanddeploy/mtg/env.example. - Handlers: start OIDC login, callback, submit username for the pending state, list active providers. Username validation and the taken-username error as in signup.
- Email collision check (decision 6) before the username step.
- Fix
recover_account(src/http/handler_frontend/auth/handler.rs): an External Account gets the same silent200and no mail. Today it would mail a Registration link that binds a Passkey to an external Identity. - Fix
prepare_signup(same file): the "username taken but not yet registered" branch must check "has any login method", not "has a Passkey". Today a stranger could trigger an invite mail to an External Account's address by signing up with its username. - Admin dashboard schema: login method (local / external + provider) on Account list and detail.
- Migrations via
just make-migrations mtg. - HTTP tests (harness) with a fake OpenID provider: first login + username step, returning login, email collision, locked Account, recovery for an External Account is silent, signup with an External Account's username sends nothing.
frontend/mtg
- "Continue with Google" on login and signup, shown only when the provider is active.
- Username step page for the pending state.
- Error states: email in use, Account locked, email not verified.
- Admin dashboard: login method column / field.
- i18n keys per
CODING_STANDARDS.md;just gen-api mtg.
Out of scope
- Apple, GitHub, Discord.
- Switching an Account between local and external.
- Recovery for External Accounts.
- Email change for any Account.
- OIDC for semmelei (the module makes it possible, nothing is wired).
Acceptance
- A new person can sign up with Google, pick a username and land logged in; the Account is external and has the Google email.
- The same person logs in again with one click, without a username.
- A Google login whose verified email belongs to a Local Account is refused with the hint.
- A locked External Account cannot log in, and its sessions die.
- Recovery and signup never mail anything for an External Account.
- Without Google env vars the button is gone and the service starts normally.
- Admins see local / external (+ provider) per Account.
just ciand the gen-api drift check pass.
- Lingua principale
- TypeScript
- Stelle
- 0
- Fork
- 1
- Merge medio
- 10h 20m
- PR unite (30g)
- 36
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di myOmikron/code
-
wayfinder:task
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
I maintainer di solito rispondono entro 1 giorno
-
wayfinder:task
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
myOmikron/code#102 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
needs-triage
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
I maintainer di solito rispondono entro 1 giorno
-
mtg: tournament plannerApertaready-for-agent
Difficoltà 5/5 Più di una settimana Idoneità per principianti 18/100
I maintainer di solito rispondono entro 1 giorno
-
needs-triage
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di myOmikron/code
Issue simili
-
[Bug]: REST API URL starting with "http" but no scheme (e.g. httpbin.org/get) is not given an http:// prefixForse già presa @ItsDeadlyProgrammer l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
appsmithorg/appsmith#42471 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
ehmpathy/rhachet-roles-bhrain#705 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Status: Triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
mermaid-js/mermaid#8546 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
braintrustdata/braintrust-sdk-javascript#2659 ·
I maintainer di solito rispondono entro 1 giorno