Password reset
Kilat implements a self-service password reset flow in
src/server/routes/auth.routes.ts with hashed reset tokens and pluggable email
delivery.
GET /forgot-password— renders the email form.POST /forgot-password— if the email exists, creates a reset token and emails a link. Always renders{ status: "sent" }regardless of whether the account exists — no user enumeration.GET /reset-password?email=…&token=…— renders the new-password form, pre-filled from the query string.POST /reset-password— validates the token, checks password confirmation, hashes the new password, clears all reset tokens for that email, and redirects to/login?notice=password_reset.
const token = await createPasswordReset(user.email);const link = `${config.appUrl}/reset-password?email=${encodeURIComponent(user.email)}&token=${token}`;await sendMail({ to: user.email, subject: "Reset your password", text: `Reset your password:\n${link}\n\nThis link expires in 60 minutes.`, html: `<p><a href="${link}">Reset password</a></p>`,});Hashed reset tokens
Section titled “Hashed reset tokens”Reset tokens are 256-bit random and hashed at rest — the password_resets
table stores only SHA-256(token), never the raw token. The raw token travels
only in the email link.
export const RESET_TOKEN_TTL_MS = 60 * 60 * 1000; // 1 hour| Property | Value |
|---|---|
| Token length | 256-bit random, hex-encoded |
| Stored as | SHA-256 hash (token_hash PK) |
| Expiry | 60 minutes (RESET_TOKEN_TTL_MS) |
| Cleanup | All tokens for the email cleared after reset |
verifyPasswordReset checks both the hash match and the expiry timestamp.
Expired or invalid tokens return a 422 with “This reset link is invalid or has
expired.”
Email delivery (MAIL_DRIVER)
Section titled “Email delivery (MAIL_DRIVER)”Mail drivers live in src/server/mailer.ts — plain fetch, zero dependencies.
Select one via MAIL_DRIVER in wrangler.toml [vars].
| Driver | Use case | Required env |
|---|---|---|
log |
Dev / tests | none — prints to console, records in sentMails |
resend |
Production (Resend.com) | RESEND_API_KEY, MAIL_FROM |
mailtrap |
Testing (Mailtrap.io) | MAILTRAP_API_TOKEN, optional MAILTRAP_INBOX_ID |
[vars]MAIL_DRIVER = "log"MAIL_FROM = "no-reply@example.com"For production with Resend:
wrangler secret put RESEND_API_KEY[vars]MAIL_DRIVER = "resend"MAIL_FROM = "you@yourdomain.com"config.ts validates the driver: MAIL_DRIVER=resend requires
RESEND_API_KEY; MAIL_DRIVER=mailtrap requires MAILTRAP_API_TOKEN. An
invalid driver name throws at boot.
The log driver
Section titled “The log driver”The log driver pushes every sent mail into an exported sentMails array and
prints a formatted box to the console. This is what the test suite asserts
against — no SMTP server needed.