Skip to content

feat: remember the last sign-in method - #47

Merged
KacemMathlouthi merged 2 commits into
mainfrom
feat/last-login-method
Jul 28, 2026
Merged

KacemMathlouthi merged 2 commits into
mainfrom
feat/last-login-method

Conversation

@KacemMathlouthi

Copy link
Copy Markdown
Owner

Returning users had no cue which of the three sign-in methods they used last. This adds Better Auth's lastLoginMethod plugin and surfaces it on /auth.

What it does

A muted line above the sign-in options names the method:

You last signed in with Google.

Values are Google, GitHub, or an email link. An unrecognised method — removed provider, or a cookie from an older build — renders nothing rather than a half-written sentence.

Notes for review

Cookie-only, no storeInDatabase. The value has to be readable before a session exists, which is exactly when the database column isn't reachable. That option would only buy analytics, at the cost of a migration.

The magic-link value is "magic-link", not "email". The plugin docs suggest wiring customResolveMethod for magic links and their UI example compares against "email" — both are stale for the installed 1.6.19, which resolves /magic-link/verify natively. Following the docs would have meant the hint silently never rendering for our primary sign-in path. Pinned by a test case.

The hint sits outside the buttons deliberately. The first attempt put a badge inside the matching button; it shifted that button's centred label out of line with the others, and its fill fought the primary button's. A test asserts the hint is not inside a button so that can't come back quietly.

SocialButton is extracted only to satisfy the complexity ceiling. Removing the badge still left AuthPage at 23 against a max of 20. It's the one structural change to a file that otherwise just gained a caption — if you'd rather keep auth-page.tsx closer to its original shape, the alternative is extracting the "check your email" panel instead.

Privacy policy updated. The cookie is non-essential under GDPR and there's no consent banner to gate it behind, so §4 now names it, what it stores, and that clearing it costs nothing. beforeStoreCookie is the lever if a banner ever lands.

Testing

typecheck, ultracite check, knip, and the full suite all green; react-doctor --scope changed reported 100/100.

Six new tests cover all three labels, the no-cookie case, an unrecognised method, and the placement decision. They mock the auth client, so the cookie round-trip is unverified by CI — worth confirming by hand that signing in with Google then signing out shows the Google line, and that a magic-link sign-in switches it to "an email link".

Adds Better Auth's lastLoginMethod plugin. Cookie-only: the value has to
be readable before a session exists, which is exactly when the
storeInDatabase column isn't reachable, so that option would only buy
analytics at the cost of a migration. Note the plugin resolves the magic
link as "magic-link" (not "email"), which is what the client will match
on. The web half that reads the cookie lands next.

Also ignore docs/ as a whole directory instead of enumerating files —
a doc added later would otherwise leak by omission, and this repo is
going public.
Reads the cookie the lastLoginMethod plugin sets and names the method in
a muted line above the sign-in options, so a returning user doesn't have
to remember which one they used. An unrecognised method (removed
provider, cookie from an older build) renders nothing rather than a
half-written sentence.

The hint sits outside the buttons deliberately: a badge inside one
shifted its centred label out of line with the others and carried a fill
that fought the primary button's. A test pins that placement so it can't
be reintroduced quietly.

SocialButton is extracted only to stay under the complexity ceiling —
removing the badge still left AuthPage at 23 against a max of 20.

Also discloses the cookie in the privacy policy: it is non-essential
under GDPR and there is no consent banner to gate it behind.
@vercel

vercel Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
animus-api Building Building Preview, Comment Jul 28, 2026 11:07pm
animus-web Ready Ready Preview, Comment Jul 28, 2026 11:07pm

@KacemMathlouthi
KacemMathlouthi merged commit 4be5819 into main Jul 28, 2026
8 of 9 checks passed
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 50.65% 4785 / 9446
🔵 Statements 50.65% 4785 / 9446
🔵 Functions 68.94% 222 / 322
🔵 Branches 87% 810 / 931
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
apps/web/src/lib/auth-client.ts 100% 100% 100% 100%
apps/web/src/pages/auth-page.tsx 67.49% 47.61% 30.76% 67.49% 24-28, 35-36, 38-39, 129-130, 136-149, 152-169, 211-260, 274-279, 304-306, 337
Generated in workflow #116 for commit e0b3f94 by the Vitest Coverage Report Action

@vercel
vercel Bot temporarily deployed to Preview – animus-api July 28, 2026 23:09 Inactive

This branch was successfully deployed

1 active and 1 inactive deployments
Preview – animus-api — e0b3f949 Deployed Jul 28, 2026 by vercel[bot]
Preview – animus-web — e0b3f949 Deployed Jul 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant