import { Request } from 'express'; import { type Algorithm } from 'jsonwebtoken'; import { Strategy } from 'passport-strategy'; import { type TokenStorage } from './MemoryStorage.js'; export type User = Record; /** * JWT payload structure */ export interface JWTPayload { user: User; iat: number; exp?: number; } /** * Custom token creation function signature * Receives the payload and TTL, returns a signed token string */ export type CreateToken = (payload: JWTPayload, ttlSeconds: number) => Promise; /** * Custom token verification function signature * Receives a token string, returns the verified payload (or throws on invalid) */ export type VerifyToken = (token: string) => Promise; /** * Strategy configuration options */ export type MagicLinkOptions = { userFields: string[]; tokenField: string; ttl?: number; allowPost?: boolean; passReqToCallbacks?: boolean; verifyUserAfterToken?: boolean; storage?: TokenStorage; } & ({ secret: string; algorithm?: Algorithm; createToken?: never; verifyToken?: never; } | { secret?: never; algorithm?: never; createToken: CreateToken; verifyToken: VerifyToken; }); /** * Authentication options for authenticate method */ export interface MagicLinkAuthenticateOptions { action?: 'requestToken' | 'acceptToken'; authMessage?: string; allowReuse?: boolean; userPrimaryKey?: string; tokenAlreadyUsedMessage?: string; } declare module 'passport' { interface AuthenticateOptions extends MagicLinkAuthenticateOptions { } } /** * Send token callback signatures */ type SendTokenCallback = (user: User, token: string) => Promise; type SendTokenCallbackWithReq = (req: Request, user: User, token: string) => Promise; export type SendToken = SendTokenCallback | SendTokenCallbackWithReq; /** * Verify user callback signatures */ type VerifyUserCallback = (userFields: Record) => Promise; type VerifyUserCallbackWithReq = (req: Request, userFields: Record) => Promise; export type VerifyUser = VerifyUserCallback | VerifyUserCallbackWithReq; /** * Magic Link Authentication Strategy for Passport.js * * Implements passwordless authentication using JWT tokens delivered via "magic links" * Supports two-phase authentication: requestToken (generate/send) and acceptToken (verify) */ export declare class MagicLinkStrategy extends Strategy { readonly name: string; private readonly ttlSeconds; private readonly allowPost; private readonly userFields; private readonly tokenField; private readonly storage; private readonly createTokenFn; private readonly verifyTokenFn; private readonly sendToken; private readonly verifyUser; private readonly passReqToCallbacks; private readonly verifyUserAfterToken; /** * Constructor with overloads to handle optional req parameter in callbacks */ constructor(options: MagicLinkOptions & { passReqToCallbacks: true; }, sendToken: SendTokenCallbackWithReq, verifyUser: VerifyUserCallbackWithReq); constructor(options: MagicLinkOptions & { passReqToCallbacks?: false; }, sendToken: SendTokenCallback, verifyUser: VerifyUserCallback); constructor(options: MagicLinkOptions, sendToken: SendToken, verifyUser: VerifyUser); /** * Main authentication method called by Passport.js */ authenticate(req: Request, options?: MagicLinkAuthenticateOptions): Promise; /** * Handle token request phase - generate and deliver JWT token */ private requestToken; /** * Extract user fields from request */ private extractUserFields; /** * Extract a single field from request body or query */ private extractSingleField; /** * Verify user before token generation (if configured) */ private verifyUserBeforeToken; /** * Generate JWT token */ private generateToken; /** * Deliver token to user via sendToken callback */ private deliverToken; /** * Handle token acceptance phase - verify JWT and authenticate user */ private acceptToken; /** * Extract token from request (body, query, or params) */ private extractToken; /** * Verify JWT token and extract payload */ private verifyJwtToken; /** * Verify user after token verification (if configured) */ private verifyUserAfterTokenVerification; /** * Check if token has been used before and mark as used */ private checkTokenReuse; } export {};