From 5a8227f4d9af48afa11441b59bbd4267b939cfb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Sat, 19 Sep 2026 11:37:44 +0200 Subject: [PATCH] chore: correct in docs what the userinfo email claim identifies --- .env | 8 ++++++-- src/Security/EpAuthenticator.php | 11 ++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.env b/.env index 976acf0..b75e064 100644 --- a/.env +++ b/.env @@ -56,8 +56,12 @@ MAILER_DSN=null://null # https://ephub.ddev.site/auth/check for local dev, plus the production host. Leave the id and # secret empty until then -- the login page detects it and says so. # -# `email` is the identity claim. Do NOT use profile.communication.email: it comes from the CRM -# address record and is not necessarily the login email. +# `email` is the address the account actually signed in with, and it is what the local `user` +# table is keyed on. It is not myep's account identifier -- that is the opaque, stable `sub` +# claim, which myep's consumer guide asks consumers to match on. Keying on email here is +# deliberate, at the price of a myep-side email change reading as a new account, so such a +# change has to be applied to the `user` table too. Do NOT use profile.communication.email: it +# is the first contact address on the BusPro record, shared by every account of the same person. EP_OAUTH2_CLIENT_ID= EP_OAUTH2_CLIENT_SECRET= EP_OAUTH2_URL_AUTHORIZE=https://myep.ddev.site/authorize diff --git a/src/Security/EpAuthenticator.php b/src/Security/EpAuthenticator.php index 55b74d3..cdd97ee 100644 --- a/src/Security/EpAuthenticator.php +++ b/src/Security/EpAuthenticator.php @@ -75,9 +75,14 @@ class EpAuthenticator extends AbstractAuthenticator throw new CustomUserMessageAuthenticationException('Anmeldung über myep fehlgeschlagen.'); } - // The guide is explicit that profile.communication.email comes from the CRM address - // record and is NOT necessarily the login email -- one address can hold several - // contacts. The top-level claim is the identity, and it is what User is keyed on. + // `email` is the address this session actually authenticated with, and it is what User + // is keyed on. It is not myep's account identifier -- that is the opaque, stable `sub` + // claim, which myep's consumer guide asks consumers to match on; keying on email here + // is deliberate, at the price of a myep-side email change reading as a new account. + // Never profile.communication.email: that is the first contact address on the BusPro + // record, shared by every account of the same person. myep patches this claim from the + // authenticated account and exports no fallback, so an absent one is a myep-side fault + // rather than an ungranted scope -- refused either way. $email = $userinfo['email'] ?? null; if (!\is_string($email) || '' === $email) { $this->logger->error('Login via myep failed: userinfo carried no email claim');