import type { AppRequest, MiddlewareHandler } from '@rudderjs/contracts'; import type { Authenticatable } from './contracts.js'; /** * Implement on your User model to opt into email verification. * * @example * class User extends Model implements Authenticatable, MustVerifyEmail { * hasVerifiedEmail() { return this.emailVerifiedAt !== null } * async markEmailAsVerified() { await User.update(this.id, { emailVerifiedAt: new Date() }) } * getEmailForVerification() { return this.email } * } */ export interface MustVerifyEmail { hasVerifiedEmail(): boolean; markEmailAsVerified(): Promise; getEmailForVerification(): string; } /** Type guard for users that must verify email. */ export declare function mustVerifyEmail(user: unknown): user is Authenticatable & MustVerifyEmail; /** * Middleware that requires the authenticated user to have a verified email. * Returns 403 if unverified. * * @example * import { RequireAuth, EnsureEmailIsVerified } from '@rudderjs/auth' * router.get('/dashboard', RequireAuth(), EnsureEmailIsVerified(), handler) */ export declare function EnsureEmailIsVerified(): MiddlewareHandler; /** * Generate a signed email verification URL for a user. * Requires `@rudderjs/router` with a named route 'verification.verify'. * * @example * // Register the verification route: * router.get('/email/verify/:id/:hash', verifyHandler, [ValidateSignature()]) * .name('verification.verify') * * // Generate the URL (e.g. in a notification): * const url = verificationUrl(user) */ export declare function verificationUrl(user: MustVerifyEmail & { id?: string | number; getAuthIdentifier?(): string; }): string; /** * Verify a signed verification REQUEST end to end: re-check the URL signature, * then match the email hash and mark the user verified. * * Prefer this over the bare {@link handleEmailVerification} form. The email hash * in the URL is an *unkeyed* `sha256(email)` — anyone who knows a target's email * can compute it — so the ONLY thing that makes a verification link * unforgeable is the URL signature (the `APP_KEY` HMAC). `handleEmailVerification` * trusts the caller to have validated that signature via `ValidateSignature()` * middleware; if the route forgets it, verification becomes forgeable for any * known email. This helper validates the signature itself, so it fails closed * regardless of middleware wiring (Laravel `EmailVerificationRequest` parity). * * @example * router.get('/email/verify/:id/:hash', async (req, res) => { * const ok = await verifyEmailFromRequest(req, (id) => User.find(id)) * res.status(ok ? 200 : 403).json({ message: ok ? 'Email verified.' : 'Invalid link.' }) * }).name('verification.verify') */ export declare function verifyEmailFromRequest(req: AppRequest, findUser: (id: string) => Promise<(MustVerifyEmail & Record) | null>): Promise; /** * Verifies the email hash matches and marks the user as verified. * Use inside the verification route handler. * * NOTE: this does NOT validate the URL signature — the route MUST mount * `ValidateSignature()` (the email hash is an unkeyed `sha256(email)`, so the * signature is the only forgery defense). Prefer {@link verifyEmailFromRequest}, * which enforces the signature itself and cannot be left unguarded. * * @example * router.get('/email/verify/:id/:hash', async (req, res) => { * await handleEmailVerification(req.params.id, req.params.hash, async (id) => { * return User.find(id) * }) * res.json({ message: 'Email verified.' }) * }, [ValidateSignature()]).name('verification.verify') */ export declare function handleEmailVerification(id: string, hash: string, findUser: (id: string) => Promise<(MustVerifyEmail & Record) | null>): Promise; //# sourceMappingURL=verification.d.ts.map