Module: database/repositories/verificationTokenRepo

Email verification token CRUD backed by SQLite (migration 003).

Encapsulates all verification_tokens queries so route handlers never write raw SQL — per AGENT.md: "Do not write raw SQL in route handlers."

Source:

Methods

(static) claim(token) → {Object|null}

Atomically claim a token — marks it as used only if it is still unused and not expired. Returns the token row on success, or null if the token was missing, already used, or expired.

This eliminates the TOCTOU race between SELECT and UPDATE by performing a single atomic UPDATE and checking changes > 0.

Parameters:
Name Type Description
token string

The verification token to claim.

Source:
Returns:

The token row (with usedAt now set), or null.

Type
Object | null

(static) create(token, userId, email, expiresAt)

Create a new verification token, invalidating any existing unused tokens for the same user first (only the latest token should be valid).

Parameters:
Name Type Description
token string

Cryptographically random base64url string.

userId string

The user requesting verification.

email string

The email address to verify.

expiresAt string

ISO 8601 expiry timestamp.

Source:

(static) deleteExpired() → {number}

Delete all expired tokens (both used and unused) — called by the periodic cleanup job so the table stays small.

Source:
Returns:

Number of deleted rows.

Type
number

(static) deleteUnusedByUserId(userId) → {number}

Delete all unused tokens for a user (called after successful verification to invalidate any other outstanding verification links).

Parameters:
Name Type Description
userId string
Source:
Returns:

Number of deleted rows.

Type
number

(static) getUnusedByUserId(userId) → {Object|undefined}

Get the most recent unused verification token for a user. Used to check if a resend is needed or if a token is still pending.

Parameters:
Name Type Description
userId string
Source:
Returns:
Type
Object | undefined