remix-auth-totp-dev
Version:
A Time-Based One-Time Password (TOTP) Authentication Strategy for Remix-Auth.
323 lines (322 loc) • 8.75 kB
TypeScript
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;
}