Repository navigation
Conversation
Third phase of #132: a vertical slice of sign-in for Plone Aurora, from the login page's provider buttons to a stored session, sharing identity-core with the Volto add-on. - frontend/aurora is a harness generated from Cookieplone's aurora_addon template, its own pnpm workspace beside the Volto one. A dev-only harness add-on deduplicates identity-core's peers in Vite. - frontend/packages/aurora-identity lists the providers in the login page's loginActions slot (fetched by a rootLoaderData utility on /login only), starts a sign-in at /login-identity/start/<provider> and finishes it at /login-identity, storing the token in Aurora's session cookie. Backend calls name Aurora's public origin through a virtual-host URL, so the provider sends the user back to Aurora, and the backend's flow cookie is relayed to the browser and back. - Translations come from identity-core's gettext catalogues, written into i18next's common.json by `pnpm i18n`. - identity-core gains CallbackCard, used by both frontends, and expiryFromToken. Its styles are plain CSS, compiled once from the SCSS. - Both harnesses install identity-core, so each corrects for the other: volto-identity's razzle.extend.js aliases core's peers to Volto's copies, typechecking maps them in tsconfig.typecheck.json (never tsconfig.json, which Volto turns into webpack aliases), and Storybook's globs stay inside packages/*/src. - Root make targets aurora-install, aurora-start, aurora-build, aurora-lint and aurora-test drive the harness. CI does not run them yet.
This was referenced Oct 4, 2026
Draft
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third phase of #132, stacked on #134. Draft: please don't merge. Each phase gets its own PR, built on the previous one, and none is merged until the whole series has been reviewed.
A vertical slice of sign-in for Plone Aurora: the login page lists the identity providers, a button starts a sign-in, and the provider's redirect back ends in a signed-in Aurora session. It shares
identity-corewith the Volto add-on.Verified end to end
I ran a real OIDC sign-in through Aurora against a local Dex identity provider. The setup:
The sequence:
/loginserves a Dex button under Aurora's own password form, in the server-rendered HTML./login-identity/start/dex. That answers with a redirect to Dex carryingredirect_uri=http://localhost:3001/login-identity, andSet-Cookie: __pas_identity_flow=…; Path=/; HttpOnly; SameSite=Lax./login-identity, then landed on/with Log Out in Aurora's header.The failure paths, checked against the server's answers:
?error=access_deniedcode/stateHow Aurora talks to the backend
Volto's browser reaches the backend through Volto's proxy, which rewrites every request into a virtual-host URL naming the public origin. Aurora's routes call the backend from the server, so
aurora-identity/lib/backend.tsdoes what that proxy did:backendUrl()builds the sameVirtualHostBase/<proto>/<host>:<port>/<site>/++api++/VirtualHostRootURL. The backend builds the callback URL from the portal URL; without this it would give the providerhttp://localhost:8080/Plone/login-identity.__pas_identity_flow(state, PKCE verifier, nonce), and finishing it reads that cookie back. The start route passes the backend'sSet-Cookieto the browser unchanged. It names no domain, so the browser files it under Aurora's host. The callback forwards that one cookie and nothing else; Aurora's own session cookie is not the backend's to see.Authorization, so a signed-in user linking a second identity is linked to their own account.The add-on
config/server.tsrootLoaderDatautility that fetches@login-providersfor/loginonly, so the buttons are in the served page and no other page pays for themslots/LoginProviders.tsxProviderButtonper provider in theloginActionsslot, the email "provider" left out. A whole-page navigation, because the start route redirects off-siteroutes/start.tsPROVIDER_ID_PATTERN, starts the flow, follows only anhttp(s)authorize URLroutes/callback.tsxsetAuthOnResponse, with an expiry read from the token. Returns tocame_fromonly when it is a path on this sitecomponents/IdentityUI/AuroraIdentityUI.tsxIdentityUIProvider: i18next and the routerLinkThe callback path is
/login-identity, the same as Volto's. It is the redirect URI registered with each provider, so it has to be the same whichever frontend serves the site.Translations
Core's gettext catalogues stay the one source of truth.
pnpm i18ninfrontend/aurorawrites them intoaurora-identity/locales/<lang>/common.json, under oneidentitykey:de,es,pt-BRenMessage ids are English sentences full of the
.and:i18next treats as separators.translateWith()therefore:keySeparator: '\u001f'andnsSeparator: false;{placeholders}with core'sinterpolate, because i18next expects{{name}}.Its tests run a real i18next instance and check that Aurora's own nested keys are not disturbed.
make ci-i18nin the harness fails when the committed files are behind core's.Changes to
identity-coreCallbackCard: the card a provider redirect lands on. Volto'sCallbacknow renders it too: its 17 existing tests pass unchanged, and the messages keep their ids, so the existing translations came along. It adds anunavailablereason, reusing the translated "That sign-in option is not available right now."expiryFromToken, besideuseridFromToken, both now reading the claims through one function.sass; all 19 comment blocks were checked to survive.Two harnesses, one
packages/frontend/aurorais its own pnpm workspace: React 19, pnpm 11, Aurora1.0.0-alpha.15. Both harnesses installidentity-core, so itsnode_modulespoints at whichever installed last. Each problem below was reproduced before it was fixed:volto-identity/razzle.extend.jsaliases core's peers to Volto's copies, skipping any Volto aliases itself. A no-op in a project installing the published packagesfrontend/aurora/harness/vite.extend.js, a private dev-only add-on, deduplicates core's peers and lets Vite serve../packagestypecheckuses atsconfig.typecheck.jsonmapping core's peers to its own copies, and the add-ons include core's sourcestsconfig.json; Volto turns an add-on'stsconfigpathsinto webpack aliases (getAliasesFromTSConfig), soreactresolved to@types/reactand Storybook stopped buildingtsconfig.typecheck.jsonpackages/**glob followedaurora-identity'snode_modulesinto Aurora's own storiespackages/*/srcjsdom: catalog:failed the Aurora installcatalog:andworkspace:*only for entries both workspaces have. Itsi18nruns Volto'si18n.cjsby pathAfter the fixes, the production bundles of both orders were checked:
AGENTS.mddocuments all of these under "Two harnesses sharefrontend/packages".Other changes
maketargetsaurora-install,aurora-start,aurora-build,aurora-lintandaurora-test. They are opt-in: CI does not run them yet, andAGENTS.mdandcontributing.mdsay so.frontend/with--config, because ESLint ignores files outside a config's base path.frontend/packages/aurora-identity/news/, and updated tables inAGENTS.mdandcontributing.md..cookieplone.jsonheld a local email address. Also left out: the template's GitHub workflows, Dockerfile, Playwright and Storybook, which belong in the CI and polish pass.Not in this PR
came_from, since there is no identities page yet.Checks
CallbackCard, +4expiryFromToken). Volto 70 / 682, unchanged. Aurora add-on 3 / 19make -C frontend lint,make aurora-lintci-i18n, both harnessesmake docs-build; Valemake -C frontend storybook-buildpnpm build(Volto),make aurora-build