Repository navigation
fix(plugin-auth): the Magic Link mail states the lifetime the link really has, five minutes - #25238
Conversation
…ally has, five minutes The magicLink() mount states expiresIn from one constant (300 s, the lifetime the vendor default already gave the link) and the mail's expiresInMinutes is derived from it, instead of a hard-coded 10. Claude-Session: https://claude.ai/code/session_016g7nYP9wdNx1GDa5XDr7Uy Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 18 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6fe880d22a28e17e3a3fe97c423539fcda4c90ec && git checkout 6fe880d22a28e17e3a3fe97c423539fcda4c90ec
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 03de83bfe145eea8f495bcbc9886105715721b3f 1459742566eb4d1b2271aa01d4c622f231ab345b && git checkout -B drift-repro 03de83bfe145eea8f495bcbc9886105715721b3f && git merge --no-ff 1459742566eb4d1b2271aa01d4c622f231ab345b
node scripts/docs-audit/affected-docs.mjs --json 03de83bfe145eea8f495bcbc9886105715721b3f |
席位核对 · ACCEPT · 2026-10-22T14:04Z
The seat prepended the project attribution block to the PR body; the dev's text is unchanged below it. Generated by Claude Code |
Requested by Sales · project thread
Fixes #25112
Clause-②: no
Metadata-protocol: none
What changed
The
auth.magic_linkmail said "This link expires in 10 minutes" while the link it carries lived 300 s:magicLink()was mounted withoutexpiresIn(so better-auth's own default applied) andsendMagicLinkpassed a separate hard-codedexpiresInMinutes: 10.packages/plugins/plugin-auth/src/auth-manager.ts: one local constant,magicLinkExpiresInSec = 5 * 60, beside the mount. The mount now passesexpiresIn: magicLinkExpiresInSec, and the mail'sexpiresInMinutesisMath.round(magicLinkExpiresInSec / 60). The copy and the link read one source.dist/plugins/magic-link/index.mjs,expiresAt: new Date(Date.now() + (opts.expiresIn || 300) * 1e3)), and it stays 300 s, now stated rather than inherited, so a dependency bump cannot move it under the mail.Where the fix lives, and why not in plugin-email
All four locale rows of
auth.magic_linkinpackages/plugins/plugin-email/src/templates/auth-templates.ts(en-US, zh-CN, ja-JP, es-ES), HTML and text faces, render the lifetime only from{{expiresInMinutes}}. None hard-codes a number. The false value was produced entirely by the producer in plugin-auth, so plugin-email does not move and takes no changeset.Tests
auth-email-locale.test.ts: the existing payload pin asserted the false10; it now asserts5. A new pin asserts the mount statesexpiresIn: 300and that the mail'sexpiresInMinutes * 60equals the mount'sexpiresIn.145974256with the fix committed first, throughscripts/ablation-replace.mjs(anchor hit 1, then 0; blob restored to the HEAD blobc3dd34d7bf34both times):expiresInMinutesset back to the literal10: 2 failed / 67 passed (expected 10 to be 5,expected 600 to be 300).expiresIndeleted from the mount: 1 failed / 68 passed (expected undefined to be 300).pnpm --filter @objectstack/plugin-auth build && typecheck && test: 185 files passed, 3487 passed and 10 skipped.Gates
dispatch-gates --commandsderived 70 commands for this diff, and all 70 exited 0. Reconciliation:70 derived, 70 run, 0 NOT-MEASURED, 0 UNRUN. Two of them first answered PREREQUISITE NOT MET (exit 3):check-plugin-teardown-shape --self-teston a shallow clone, andcheck:dual-build-cjs-loadswithout a full build. Both were re-run aftergit fetch --unshallowandpnpm build, and both exited 0.Acceptance notes
plugin-email's template tests feedauth.magic_linkthe sample valueexpiresInMinutes: 10(plain-text-faces.test.ts,auth-templates-locales.test.ts). It is only render data and makes no claim about the link's lifetime, so it is left as is.check:auth-mount-ledgertracks route mounts, not plugin options, so it does not read this change.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_016g7nYP9wdNx1GDa5XDr7Uy