UNPKG

remix-auth-totp-dev

Version:

A Time-Based One-Time Password (TOTP) Authentication Strategy for Remix-Auth.

323 lines (322 loc) 8.75 kB
import { Strategy } from 'remix-auth/strategy'; import { type SetCookieInit } from '@mjackson/headers'; /** * The TOTP JWE data containing the secret. */ export interface TOTPData { /** * The TOTP secret. */ secret: string; /** * The time the TOTP was generated. */ createdAt: number; } /** * The TOTP data stored in the cookie. */ export interface TOTPCookieData { /** * The TOTP JWE of TOTPData. */ jwe: string; /** * The number of attempts the user tried to verify the TOTP. * @default 0 */ attempts: number; } /** * The TOTP generation configuration. */ export interface TOTPGenerationOptions { /** * The secret used to generate the TOTP. * It should be Base32 encoded (Feel free to use: https://npm.im/thirty-two). * * Defaults to a random Base32 secret. * @default random */ secret?: string; /** * The algorithm used to generate the TOTP. * @default 'SHA-256' */ algorithm?: string; /** * The character set used to generate the TOTP. * @default 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' */ charSet?: string; /** * The number of digits used to generate the TOTP. * @default 6 */ digits?: number; /** * The number of seconds the TOTP will be valid. * @default 60 */ period?: number; /** * The max number of attempts the user can try to verify the TOTP. * @default 3 */ maxAttempts?: number; } /** * The send TOTP configuration. */ export interface SendTOTPOptions { /** * The email address provided by the user. */ email: string; /** * The decrypted TOTP code. */ code: string; /** * The Magic Link URL. */ magicLink: string; /** * The request to generate the TOTP. */ request: Request; /** * The form data of the request. */ formData: FormData; } /** * The sender email method. * @param options The SendTOTPOptions options. */ export interface SendTOTP { (options: SendTOTPOptions): Promise<void>; } /** * The validate email method. * Useful to ensure it's not a disposable email address. * * @param email The email address to validate. */ export interface ValidateEmail { (email: string): Promise<boolean>; } /** * The custom errors configuration. */ export interface CustomErrorsOptions { /** * The required email error message. */ requiredEmail?: string; /** * The invalid email error message. */ invalidEmail?: string; /** * The invalid TOTP error message. */ invalidTotp?: string; /** * The rate limit exceeded error message. */ rateLimitExceeded?: string; /** * The expired TOTP error message. */ expiredTotp?: string; /** * The missing session email error message. */ missingSessionEmail?: string; /** * The missing session totp error message. */ missingSessionTotp?: string; } /** * The TOTP Strategy options. */ export interface TOTPStrategyOptions { /** * The secret used to encrypt the TOTP data. * Must be string of 64 hexadecimal characters. */ secret: string; /** * The optional cookie options. * @default undefined */ cookieOptions?: Omit<SetCookieInit, 'name' | 'value'>; /** * The TOTP generation configuration. */ totpGeneration?: TOTPGenerationOptions; /** * The URL path for the Magic Link. * @default '/magic-link' */ magicLinkPath?: string; /** * The custom errors configuration. */ customErrors?: CustomErrorsOptions; /** * The form input name used to get the email address. * @default "email" */ emailFieldKey?: string; /** * The form input name used to get the TOTP. * @default "code" */ codeFieldKey?: string; /** * The send TOTP method. */ sendTOTP: SendTOTP; /** * The validate email method. */ validateEmail?: ValidateEmail; /** * The redirect URL thrown after sending email. */ emailSentRedirect: string; /** * The redirect URL thrown after verification success. */ successRedirect: string; /** * The redirect URL thrown after verification failure. */ failureRedirect: string; } /** * The verify method callback. * Returns the email user to be stored in the session. */ export interface TOTPVerifyParams<Context = unknown> { /** * The email address provided by the user. */ email: string; /** * The formData object from the Request. */ formData?: FormData; /** * The Request object. */ request: Request; /** * The context passed from the authenticator's authenticate method. */ context?: Context; } /** * The TOTP Strategy. */ export declare class TOTPStrategy<User, Context = unknown> extends Strategy<User, TOTPVerifyParams<Context>> { name: string; private readonly secret; private readonly cookieOptions; private readonly totpGeneration; private readonly magicLinkPath; private readonly customErrors; private readonly emailFieldKey; private readonly codeFieldKey; private readonly sendTOTP; private readonly validateEmail; private _emailSentRedirect; private _successRedirect; private _failureRedirect; private readonly _totpGenerationDefaults; private readonly _customErrorsDefaults; constructor(options: TOTPStrategyOptions, verify: Strategy.VerifyFunction<User, TOTPVerifyParams<Context>>); /** Gets the email sent redirect URL. */ get emailSentRedirect(): string; /** Sets the email sent redirect URL. */ set emailSentRedirect(url: string); /** Gets the success redirect URL. */ get successRedirect(): string; /** Sets the success redirect URL. */ set successRedirect(url: string); /** Gets the failure redirect URL. */ get failureRedirect(): string; /** Sets the failure redirect URL. */ set failureRedirect(url: string); /** * Authenticates a user using TOTP. * If the user is already authenticated, simply returns the user. * * | Method | Email | Code | Sess. Email | Sess. TOTP | Action/Logic | * |--------|-------|------|-------------|------------|------------------------------------------| * | POST | ✓ | - | - | - | Generate/Send TOTP using form email. | * | POST | ✗ | ✗ | ✓ | - | Generate/Send TOTP using session email. | * | POST | ✗ | ✓ | ✓ | ✓ | Validate form TOTP code. | * | GET | - | - | ✓ | ✓ | Validate magic-link TOTP. | * * @param {Request} request - The request object. * @param {Context} context - Optional context passed by the authenticator. * @returns {Promise<User>} The authenticated user. */ authenticate(request: Request, context?: Context): Promise<User>; /** * Reads the form data from the request. * @param request - The request object. * @returns The form data. */ private _readFormData; /** * Validates the TOTP. * @param code - The TOTP code. * @param sessionTotp - The TOTP session data. * @param store - The TOTP store. * @param urlExpires - The TOTP code expiry date in milliseconds. */ private _validateTOTP; /** * Generates the TOTP. * @param email - The email address. * @param request - The request object. * @returns The TOTP data. */ private _generateTOTP; /** * Encrypts magic link parameters. * @param params - The parameters to encrypt. * @returns The encrypted JWE token. */ private _encryptUrlParams; /** * Decrypts and validates magic link parameters. * @param encrypted - The encrypted JWE token. * @returns The decrypted and validated parameters. */ private _decryptUrlParams; /** * Generates the magic link. * @param code - The TOTP code. * @param request - The request object. * @returns The magic link. */ private _generateMagicLink; /** * Gets the magic link code from the request. * @param request - The request object. * @returns The magic link code. */ private _getMagicLinkCode; /** * Validates the email format. * @param email - The email address. * @returns Whether the email is valid. */ private _validateEmailDefault; }