Skip to content

Promote test → preview (2026-09-10): verification link carries the address - #47

Merged
EddyOne81 merged 2 commits into
previewfrom
test
Sep 10, 2026
Merged

EddyOne81 merged 2 commits into
previewfrom
test

Conversation

@EddyOne81

Copy link
Copy Markdown
Collaborator

Promotion testpreview, requested by Duy (2026-09-10). Half one of a two-repo pairdrumee/signup carries the front-end half and follows immediately after this.

origin/preview was back-merged into test first (2da2bdf): clean, and content-neutral, so test did not change.

What ships

fix(signup): the verification link carries the address (#46) — Huân, 09-09. The verification URL now appends &email= alongside the token.

Why the pair must not be split

loby mints the link; signup's verified/index.js + router/index.js are what read the parameter. Merging signup without this would leave its resend screen with no address to use. This half is inert on its own (an extra fragment parameter nobody reads yet), which is why it goes first.

Per Huân's note on the change, the recovery path could previously only resolve an account from a token that was already dead by definition — every arrival at the "Verification failed" screen is a token failure — so Resend answered no_pending_signup permanently. Measured on stage: 25 of 44 outstanding tokens could not be resent, with a single signup_data row in total.

The address rides in the URL fragment, so it is never sent to a server, written to an access log, or leaked in a Referer — the same reach as the token beside it, and the mailbox receiving it already knows its own address.

Verification

  • 1 file, +21/−1 (service/signup.js).
  • CD green on the test endpoint for a7fceed2 (09-09 03:38).

🤖 Generated with Claude Code

resend_verification can resolve an account from an email, a LIVE token, or a
signup_data row keyed by a session that no longer exists (create_account
stopped establishing one). But every failure that lands the user on the
"Verification failed" screen is a failure of the token: consumed by an earlier
click or by a mail scanner prefetching the URL, or superseded, since
drumate_set_verification_token_v2 DELETEs the previous row whenever a newer
link is minted. So the recovery path's only usable credential was guaranteed
dead exactly when recovery was needed, and Resend answered no_pending_signup
forever.

Measured on stage: of 44 outstanding tokens, 15 no longer joined to a drumate
and 10 more pointed at accounts with no unverified_email staged, so 25 could
not be resent at all. signup_data held one row in total.

Putting the address next to the token gives that screen something that
survives the token. It lives in the fragment, so it never reaches a server, an
access log or a Referer -- the same reach as the far more sensitive token
beside it, in a mailbox that already knows its own address -- and it grants no
new access: resend_verification already accepts an arbitrary address and still
refuses any account whose unverified_email is not already staged.

Co-authored-by: Drumee Dev <drumee@debian.local.drumee>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@EddyOne81
EddyOne81 merged commit c0e3d20 into preview Sep 10, 2026
9 of 11 checks passed
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.

2 participants