Repository navigation
fix(plugin-auth): a change-email request notifies the current address whatever way the caller is signed in - #30166
Conversation
…sport (wip) Claude-Session: https://claude.ai/code/session_01QSeKYn5CmmdShCJifm6WYj Co-authored-by: Claude <noreply@anthropic.com>
… whatever way the caller is signed in The notice's recipient is read from the session the endpoint itself acted on, in the global after-hook; the separate session read in the global before-hook is removed. Pins cover each way of signing in, and a refused request still mails nothing. Claude-Session: https://claude.ai/code/session_01QSeKYn5CmmdShCJifm6WYj Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QSeKYn5CmmdShCJifm6WYj Co-authored-by: Claude <noreply@anthropic.com>
…ddress union Claude-Session: https://claude.ai/code/session_01QSeKYn5CmmdShCJifm6WYj Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check4 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 — 22 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 f833d29249bd0240000db929d5b55ec166e1d49d && git checkout f833d29249bd0240000db929d5b55ec166e1d49d
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin fc869c24e0a0041d24485802286fce3f9caedc13 a014cda92fafb4789abc61f1d26e40bfe3c499a3 && git checkout -B drift-repro fc869c24e0a0041d24485802286fce3f9caedc13 && git merge --no-ff a014cda92fafb4789abc61f1d26e40bfe3c499a3
node scripts/docs-audit/affected-docs.mjs --json fc869c24e0a0041d24485802286fce3f9caedc13 |
|
security#1 · os-justin · session_01QSeKYn5CmmdShCJifm6WYj 席位核对ACCEPT · head
|
Clause-②: no
Metadata-protocol: none
维护者速读
POST /api/v1/auth/change-email被接受后发往账号当前邮箱的auth.email_change_notice,收件人改为在全局 after-hook 里从端点自己解析出的会话读取;全局 before-hook 里那一段单独的会话读取删除。packages/plugins/plugin-auth/src/auth-manager-after-hook.ts(/change-email一段与changeEmailFrom);auth-manager-before-hook.ts(删除的一段);change-email-delete-user-wiring.test.ts新增的顶层 describe。pnpm --filter @objectstack/plugin-auth exec vitest run --maxWorkers=2 src/change-email-delete-user-wiring.test.ts,预期 20 个用例全部通过,其中新增 5 个。What changes
POST /api/v1/auth/change-emailrequest mails the account's current address theauth.email_change_notice, whatever way the caller is signed in.auth-manager-after-hook.ts: the/change-emailsection takes the notice's recipient from the user of the session the endpoint itself acted on,ctx.context.session.user. better-auth'ssensitiveSessionMiddlewarerecords that session before the handler runs, and the handler does not write it, so it names the account the request changes, with the address it holds as the request arrives. A small helper,changeEmailFrom, shapes the recipient. The success gate, the failure-swallowing send and the refusal coding that follow are unchanged.auth-manager-before-hook.ts: the/change-emailcapture is removed, since the after-hook now reads the address itself; the module header's list of moved sections no longer names it.auth-manager-auth-instance.ts: one comment pointer that named the removed key now namesauth-manager-after-hook.ts.identity-mail-sibling.test.ts,auth-email-locale.test.ts: the three fixtures that drive the after-hook directly hand itcontext.session.userin place of the removed key; their assertions are unchanged.change-email-notice-every-sign-in.md:@objectstack/plugin-authpatch.Tests
A new top-level describe in
change-email-delete-user-wiring.test.ts, the change-email harness, named for the rule: "a change-email request notifies the current address whatever way the caller is signed in".400 VALIDATION_ERROR) mails nothing at all.Acceptance notes
auth-manager-before-hook.tsandauth-manager-auth-instance.ts; neither PR depends on the other, their hunks are at least 50 lines apart, andgit merge-treeof the two heads is clean, with no reference to the removed key left in the combined tree.mainwas merged in before opening (seven commits, none underpackages/plugins/plugin-auth);@objectstack/specand@objectstack/driver-sql, which the merge touched, were rebuilt before the typecheck and the final test runs. The full plugin-auth suite ran on the pre-merge tree with the fix applied (below); per AGENTS.md §10 it was not re-run after a merge with no overlap.Verification
Tests and typecheck
One-shot reverse verification
Gates
Generated by Claude Code