mirror of
https://github.com/outline/outline.git
synced 2025-12-30 23:40:46 -06:00
93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
import { randomInt } from "crypto";
|
|
import { Minute } from "@shared/utils/time";
|
|
import RedisAdapter from "@server/storage/redis";
|
|
|
|
/**
|
|
* This class manages verification codes for email authentication.
|
|
* It stores and retrieves 6-digit codes in Redis with a 10-minute TTL.
|
|
*/
|
|
export class VerificationCode {
|
|
/**
|
|
* Redis client instance
|
|
*/
|
|
private static redis = RedisAdapter.defaultClient;
|
|
|
|
/**
|
|
* TTL for verification codes in milliseconds (10 minutes)
|
|
*/
|
|
private static readonly TTL = Minute.ms * 10;
|
|
|
|
/**
|
|
* Prefix for Redis keys
|
|
*/
|
|
private static readonly KEY_PREFIX = "email_verification_code:";
|
|
|
|
/**
|
|
* Generate a random 6-digit code
|
|
*
|
|
* @returns A string representing a 6-digit code
|
|
*/
|
|
public static generate(): string {
|
|
// Generate a random integer between 100000 and 999999 (6 digits)
|
|
return randomInt(100000, 1000000).toString().padStart(6, "0");
|
|
}
|
|
|
|
/**
|
|
* Store a verification code in Redis with a 10-minute TTL
|
|
*
|
|
* @param email The email address associated with the code
|
|
* @param code The 6-digit verification code
|
|
* @returns Promise resolving to true if successful
|
|
*/
|
|
public static async store(email: string, code: string): Promise<boolean> {
|
|
const key = this.getKey(email);
|
|
await this.redis.set(key, code, "PX", this.TTL);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a verification code from Redis
|
|
*
|
|
* @param email The email address associated with the code
|
|
* @returns Promise resolving to the code or null if not found
|
|
*/
|
|
public static async retrieve(email: string): Promise<string | null> {
|
|
const key = this.getKey(email);
|
|
return await this.redis.get(key);
|
|
}
|
|
|
|
/**
|
|
* Verify if a given code matches the stored code for an email
|
|
*
|
|
* @param email The email address associated with the code
|
|
* @param code The code to verify
|
|
* @returns Promise resolving to true if the code matches, false otherwise
|
|
*/
|
|
public static async verify(email: string, code: string): Promise<boolean> {
|
|
const storedCode = await this.retrieve(email);
|
|
return storedCode === code;
|
|
}
|
|
|
|
/**
|
|
* Delete a verification code from Redis
|
|
*
|
|
* @param email The email address associated with the code
|
|
* @returns Promise resolving to true if successful
|
|
*/
|
|
public static async delete(email: string): Promise<boolean> {
|
|
const key = this.getKey(email);
|
|
await this.redis.del(key);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get the Redis key for an email address
|
|
*
|
|
* @param email The email address
|
|
* @returns The Redis key
|
|
*/
|
|
private static getKey(email: string): string {
|
|
return `${this.KEY_PREFIX}${email.toLowerCase()}`;
|
|
}
|
|
}
|