This walkthrough covers Password Reset and Email Verification. An existing account system, a database supporting transactions, an email delivery adapter and a fixed trusted application URL. Use a local mail sink during development.
The video is an illustrated code walkthrough with AI narration. Code blocks are integration excerpts, not a complete tested application. Helper names such as stores, middleware and clients describe responsibilities you must implement in your existing project. No live server, payment provider or device execution is claimed.
Before you begin
Use a separate development environment, fictional data and test credentials. Record dependency versions and follow the official references below for your installed versions. Keep a working baseline and add one workflow at a time.
1. Separate the token purposes
Password reset and email verification have different effects, so model them as separate token purposes. Store only a digest of a high-entropy random token, together with its user, expiry, and use state. A verification token must not work as a reset token. Define the lifetime and revocation policy for each purpose, and remove stale records on a maintenance schedule.
tokens:
token_hash
user_id
purpose: reset | verify_email
expires_at
used_at2. Avoid account discovery
Respond consistently whether or not an address belongs to an account. Avoid revealing account existence through status codes, text, or obvious timing differences. Apply per-account and network-level abuse controls without making account lockout a denial-of-service tool. Queue email work rather than exposing provider timing directly. Keep a support path for users who no longer control their email address.
app.post("/api/reset-request", rateLimit, async (req,res) => {
await queueResetIfAccountExists(normalizedEmail);
res.json({message: "If eligible, an email will arrive."});
});3. Build links from trusted configuration
Construct reset links from an allowlisted application URL in server configuration, not an untrusted host header. Persist the token's purpose and expiry before sending. Avoid recording raw tokens in logs or analytics. The destination page should avoid third-party content that could leak the URL, and use an appropriate referrer policy. Email delivery needs retries, but retries must not accidentally change the token's meaning.
const raw = randomBytes(32).toString("hex");
const tokenHash = digest(raw);
const url = new URL("/reset-password", APP_BASE_URL);
url.searchParams.set("token", raw);
await tokenStore.create({tokenHash, userId, purpose: "reset"});4. Consume the token atomically
Validate and consume the token in the same transaction as the password update. Lock the matching row or use an equivalent atomic conditional operation so two concurrent requests can't both succeed. Check purpose, expiry, and unused status. Store the new password using the account system's established hashing method. Revoke sessions according to policy and send a separate notification that the password changed.
BEGIN;
SELECT * FROM recovery_tokens
WHERE token_hash=? AND purpose="reset" FOR UPDATE;
-- Check unused and unexpired; update password hash.
-- Mark token used and revoke sessions.
COMMIT;5. Keep verification scoped to the address
Email verification proves control of a particular address at a particular point in the workflow. Bind the token to the intended address as well as the account. If the address changes, invalidate earlier verification links or require an exact address match. Decide which features remain unavailable before verification. Don't automatically grant unrelated privileges just because an email link was opened.
verification = {userId, emailToVerify, tokenHash, expiresAt};
// On use: match the intended current email address.
// An old token must not verify a newly changed address.6. Handle the React reset form
Collect the new password without displaying the raw token unnecessarily. Handle used, invalid, and expired links with a clear route to request another email. Don't automatically sign the user in unless that behaviour is deliberately designed and reviewed. After a successful reset, remove sensitive link data from the visible location where practical and guide the user through the normal sign-in flow.
await fetch("/api/reset-password", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({token, password})
});
// Show one-use/expired link guidance and a new-request path.7. Test email without real customers
Use a controlled mail sink for local development and inject an email adapter in automated tests. Assert the intended recipient and trusted link destination without contacting real customers. Test delivery failure separately from token consumption. In deployment, configure verified sending domains, provider credentials, retry policy, and monitoring. A unit test of token generation isn't proof that email delivery or inbox placement works.
Development: local mail sink
Tests: injected sendMail adapter
Check recipient, trusted URL and token purpose
Never print production credentials or reset tokensIntegration checks
Test unknown accounts, expired tokens, replay, wrong purpose, changed addresses, simultaneous submissions, delivery failure and session revocation after reset.
These are verification instructions, not reported test results. The excerpts have not been executed as a complete integrated application. Review authentication, database schema, dependency versions and operational settings before deployment.
Official references
Explore CodeKits development services.

