/** * Checks the rows `password-reset-service.ts` reads from * `password_reset_tokens` to make each reset link work once. * * @module */ import type { SQLOutputValue } from "node:sqlite"; /** * Stored by `requestPasswordReset` when it emails a reset link, and read back * by `resetPassword` when the link is used. */ export interface PasswordResetTokenRow { /** The signed token itself, which the reset link carries. */ token: string; user_id: string; /** * Lets `db/startup.ts` purge old rows. The token's own `exp` is what ends * the link. */ expires_at: string; /** Set when the link is used, and reset to null if the reset then fails. */ used_at: string | null; [key: string]: SQLOutputValue; } /** * Checks whether `obj`, a row `resetPassword` selected, is a * {@link PasswordResetTokenRow}. */ export function isPasswordResetTokenRow( obj: unknown, ): obj is PasswordResetTokenRow { return !!obj && typeof obj === "object" && "token" in obj && typeof obj.token === "string" && "user_id" in obj && typeof obj.user_id === "string" && "expires_at" in obj && typeof obj.expires_at === "string" && "used_at" in obj && (obj.used_at === null || typeof obj.used_at === "string"); }