Add passkey authentication and responsive team navigation - #11
Merged
Conversation
Enable passkeys via Better Auth's passkey plugin, alongside a few UI and tooling fixes made along the way. Passkeys: - Add @better-auth/passkey (bumps better-auth 1.6.23 -> 1.6.26, where the plugin moved into its own package) - Add the Passkey model and an additive migration - Pin rpID to the BETTER_AUTH_URL hostname so passkeys stay scoped to this app rather than a shared parent domain, and document the optional PASSKEY_RP_ID override - Add a passkey management dialog (list/add/remove) to the user menu, hidden while impersonating since the endpoints resolve the real session rather than the impersonation override - Add passkey sign-in plus browser autofill (conditional UI) on /signin - Surface auth errors without inventing a cause (src/lib/auth-errors.ts) UI: - Team pages: vertical nav on tablet/desktop, shadcn Select on mobile - Declare color-scheme per theme so browser-rendered UI (select popups, scrollbars) follows dark mode instead of always painting light - Add the Google mark to the Google sign-in/sign-up buttons Tooling: - Pass both ignore paths to Prettier. Passing only --ignore-path .gitignore replaced the default list, so .prettierignore was never read; ignore the lockfile and generated output, and reflow the files that had drifted from the pinned Prettier 3.8. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Enables passkeys via Better Auth, plus a few UI and tooling fixes made along the way.
Passkeys
@better-auth/passkey(bumpsbetter-auth1.6.23 → 1.6.26, where the plugin moved into its own package).Passkeymodel and an additive migration — no changes to existing tables./signin.Subdomain scoping
rpIDis pinned to theBETTER_AUTH_URLhostname, so passkeys registered ontemplate.c4g.devare scoped to that host and are never offered to sibling apps on otherc4g.devsubdomains. Verified against a running server:BETTER_AUTH_URLrpIdreturnedhttp://localhost:3000localhosthttps://template.c4g.devtemplate.c4g.devPASSKEY_RP_IDcan override this if shared sign-in across subdomains is ever wanted — but that would let any sibling subdomain assert those credentials.Important
BETTER_AUTH_URLmust be set in production. The plugin's fallback when it is unset islocalhost, which fails confusingly rather than loudly.UI
Selecton mobile (mdbreakpoint).color-schemeper theme. The theme only swapped CSS variables, so browser-rendered UI (select popups, scrollbars) always painted light regardless of theme — this affects every page, not just the new dropdown.Tooling
pnpm formatwas failing on 9 files before this branch. Passing only--ignore-path .gitignorereplaces Prettier's default ignore list, so.prettierignorewas never read. Now passes both paths, ignores the lockfile and generated output, and reflows the files that had drifted from the pinned Prettier 3.8.Notes for review
Testing
pnpm format,pnpm lint,tsc --noEmit, 45 tests, andpnpm buildall pass.Verified in Chrome: mobile dropdown opens, navigates, and themes correctly in both light and dark; the desktop sidebar and mobile dropdown swap correctly at the breakpoint; passkey endpoints return 401 rather than 500 once the Prisma client includes the model.
Not verified: a full register/sign-in ceremony with a real authenticator. Worth exercising before merge.
🤖 Generated with Claude Code