import * as Soap from "@soapjs/soap"; export type AuthResult = Soap.AuthResult; export type AuthStrategy = Soap.AuthStrategy; import { LocalStrategyConfig } from "./strategies/local/local.types"; import { OAuth2ProviderConfig } from "./strategies/oauth2/oauth2.types"; import { ApiKeyStrategyConfig } from "./strategies/api-key/api-key.types"; import { BasicStrategyConfig } from "./strategies/basic/basic.types"; import { JwtConfig } from "./strategies/jwt/jwt.types"; export type AuthCategories = "http" | "socket" | "grpc" | "webhook" | "edge" | "isa" | "event"; export interface SessionStore { getSession(sid: string, ...args: unknown[]): Promise; setSession(sid: string, session: T, ...args: unknown[]): void | Promise; destroySession(sid: string, ...args: unknown[]): void | Promise; touchSession(sid: string, session: T, ...args: unknown[]): void | Promise; getSessionIds(): Promise; } export type SessionData = { [key: string]: any; } | any; export type SessionInfo = { sessionId: string; data: TData; }; export interface SessionConfig { secret: string; resave?: boolean; saveUninitialized?: boolean; store?: SessionStore; sessionKey?: string; sessionHeader?: string; generateSessionId?: (...args: unknown[]) => string; createSessionData?: (data?: unknown, context?: unknown) => T; embedSessionId?: (context: any, sessionId: string) => void; getSessionId(context: any): string | null; [key: string]: any; } export type Credentials = { id: string; hashedPassword: string; [key: string]: unknown; }; export interface AuthResultConfig { onSuccess?: (action: string, context: AuthSuccessContext) => Promise | void; onFailure?: (action: string, context: AuthFailureContext) => Promise | void; } export interface AuthThrottleConfig { incrementFailedAttempts?: (identifier: string, ...rest: unknown[]) => Promise; resetFailedAttempts?: (identifier: string, ...rest: unknown[]) => Promise; getFailedAttempts?: (identifier: string, ...rest: unknown[]) => Promise; maxFailedAttempts?: number; } export interface BaseAuthStrategyConfig extends AuthResultConfig { mfa?: MfaConfig; session?: SessionConfig; role?: RoleAuthorizationConfig; rateLimit?: RateLimitConfig; throttle?: AuthThrottleConfig; lock?: AccountLockConfig; } export interface MfaConfig { extractMfaCode?: (context?: TContext) => string; sendMfaCode?: (user: TUser, context?: TContext) => Promise; validateMfaCode?: (user: TUser, code: string) => Promise; isMfaRequired?: (user: TUser) => boolean; generateMfaSecret?: (user: TUser) => Promise; verifyMfaSetup?: (user: TUser, secret: string) => Promise; disableMfa?: (user: TUser) => Promise; generateBackupCodes?: (user: TUser) => Promise; validateBackupCode?: (user: TUser, code: string) => Promise; maxMfaAttempts?: number; lockMfaOnFailure?: (user: TUser) => Promise; getMfaAttempts?: (user: TUser) => Promise; resetMfaAttempts?: (user: TUser) => Promise; incrementMfaAttempts?: (user: TUser) => Promise; } export type PasswordType = "default" | "one-time" | "temporary"; export type NewPasswordOptions = { expiresIn?: string | number; type: PasswordType; additional?: Record; }; export type PasswordInfo = { type: PasswordType; expiresIn?: string | number; lastChangeDate?: Date; }; export interface PasswordPolicyConfig { validatePassword?: (password: string, previousPassword?: string) => Promise; getPasswordPasswordInfo?: (identifier: string) => Promise; passwordExpirationDays?: number; generateResetToken?: (identifier: string) => Promise; sendPasswordResetEmail?: (identifier: string, token: string) => Promise; validatePasswordResetToken?: (token: string) => Promise; updatePassword?: (identifier: string, newPassword: string, options?: NewPasswordOptions) => Promise; generatePassword?: (identifier: string, options: NewPasswordOptions) => Promise; } export interface UserConfig { fetchUser: (payload: unknown) => Promise; validateUser?: (payload: unknown) => Promise; } export type CredentailsConfig = CredentialsConfig; export interface CredentialsConfig { extractCredentials: (context: TContext) => TCredentials; verifyCredentials: (identifier: string, password: string) => Promise; } export interface CredentialAuthStrategyConfig extends BaseAuthStrategyConfig { passwordPolicy?: PasswordPolicyConfig; credentials?: CredentialsConfig; jwt?: TokenAuthConfig; user?: UserConfig; allowGuest?: boolean; routes: { login: AuthRouteConfig; logout: AuthRouteConfig; resetPassword?: AuthRouteConfig; changePassword?: AuthRouteConfig; requestPasswordReset?: AuthRouteConfig; }; } export type AuthRouteConfig = { path: string; method: string; }; export interface TokenAuthConfig { accessToken?: TokenConfig; refreshToken?: RefreshTokenConfig; } export interface TokenAuthStrategyConfig extends BaseAuthStrategyConfig, TokenAuthConfig { user?: UserConfig; routes: { login?: AuthRouteConfig; logout?: AuthRouteConfig; refresh?: AuthRouteConfig; [key: string]: AuthRouteConfig; }; } export interface AccountLockConfig { logFailedAttempt?: (account: any, context?: TContext) => Promise; lockAccount: (account: any) => Promise; removeAccountLock: (account: any) => Promise; hasAccountLockExpired: (account: any) => Promise; isAccountLocked: (account: any, context?: TContext) => Promise; lockoutDuration?: number; notifyOnLockout?: (account: any) => Promise; } export interface RateLimitConfig { checkRateLimit: (...args: unknown[]) => Promise; incrementRequestCount?: (...args: unknown[]) => Promise; } export interface RoleAuthorizationConfig { authorizeByRoles?: (user: TUser, roles: string[]) => Promise; roles?: string[]; } export type AuthSuccessContext = { user?: TUser; context?: TContext; session?: SessionInfo; tokens?: Record; identifier?: string; email?: string; additional?: Record; }; export type AuthFailureContext = { error: Error; context?: TContext; identifier?: string; email?: string; additional?: Record; }; export interface SoapHttpAuthConfig { local?: LocalStrategyConfig; jwt?: JwtConfig; oauth2?: { [provider: string]: OAuth2ProviderConfig; }; hybridOAuth2?: { [provider: string]: OAuth2ProviderConfig; }; apiKey?: ApiKeyStrategyConfig; basic?: BasicStrategyConfig; custom?: { [label: string]: Soap.AuthStrategy; }; } export interface SoapSocketAuthConfig { jwt?: JwtConfig; apiKey?: ApiKeyStrategyConfig; custom?: { [provider: string]: Soap.AuthStrategy; }; } export interface SoapAuthConfig { session?: SessionConfig; jwt?: TokenAuthConfig; http?: SoapHttpAuthConfig; socket?: SoapSocketAuthConfig; logger?: Soap.Logger; } export interface CookieStorageOptions { cookieName: string; httpOnly: boolean; secure: boolean; sameSite?: "strict" | "lax" | "none"; maxAge?: number; } export interface HeaderStorageOptions { headerName: string; scheme?: string; extractor: (scheme: string) => string | null; } export interface BodyStorageOptions { name: string; extractor: (name: string) => string | null; } export interface QueryStorageOptions { name: string; extractor: (name: string) => string | null; } export interface SessionStorageOptions { name: string; extractor: (name: string) => string | null; } export interface DatabaseOptions { extractor: (...args: unknown[]) => Promise; } export interface StorageContext { storeInHeader?: (data: string, options?: HeaderStorageOptions) => Promise | void; storeInCookie?: (data: string, options?: CookieStorageOptions) => Promise | void; storeInSession?: (data: string, name?: string) => Promise | void; storeInBody?: (data: string, name?: string) => Promise | void; getFromHeader?: (options?: HeaderStorageOptions) => Promise | string | null; getFromCookie?: (cookieName: string) => Promise | string | undefined; getFromSession?: (name: string) => Promise | string | undefined; getFromBodyField?: (name: string) => Promise | string | undefined; removeFromCookie?: (cookieName: string) => Promise | void; removeFromSession?: (name: string) => Promise | void; encrypt?: (data: string) => Promise | string; decrypt?: (data: string) => Promise | string; } export interface TokenIssuerConfig { secretKey: string; options: { expiresIn: string | number; audience?: string | string[]; issuer?: string | string[]; subject?: string; [option: string]: unknown; }; buildPayload?: (user: any, context?: TContext) => Record; generate?: (data: any, context?: TContext) => string; } export interface TokenVerifierConfig { options: { [option: string]: unknown; }; verify?: (token: string) => Promise; } export interface PersistenceMetadata { key?: string; name?: string; expiration?: number; expiresIn?: string | number; [key: string]: unknown; } export interface PersistenceConfig { store?: (data: any, context?: TContext | null, metadata?: PersistenceMetadata, ...args: any[]) => Promise | void; read?: (context?: TContext | null, key?: string, ...args: any[]) => Promise | T | null; remove?: (context?: TContext | null, key?: string, ...args: any[]) => Promise | void; } export interface ContextOperationConfig { embed?: (context: TContext, data: TData) => void; extract?: (context: TContext) => TData | null; } export interface TokenConfig extends ContextOperationConfig { rotation?: TokenRotationConfig; issuer?: TokenIssuerConfig; verifier?: TokenVerifierConfig; persistence?: PersistenceConfig; additional?: Record; } export interface RefreshTokenConfig extends TokenConfig { absoluteExpiry?: AbsoluteExpiryConfig; } export interface AbsoluteExpiryConfig { payloadField?: string; onExpiry?: "error" | "logout" | "ignore"; } export interface TokenRotationConfig { maxRotations?: number; getRotationCount?: (token: string, user: TUser, context: TContext) => Promise; rotateToken?: (oldToken: string, user: TUser, context: TContext) => Promise<{ newToken: string; newRotationCount?: number; }>; afterRotation?: (oldToken: string, newToken: string, user: TUser, context: TContext, rotationCount?: number) => Promise; isLimitReached?: (rotationCount: number, maxRotations: number | undefined, user: TUser, context: TContext) => boolean; } export interface PKCEConfig { challenge: { expiresIn?: number; generate?: (codeVerifier: string) => string; embed?: (context: TContext, challenge: string) => void; extract?: (context: TContext) => string | null; persistence?: PersistenceConfig; }; verifier: { expiresIn?: number; generate?: () => string; embed?: (context: TContext, codeVerifier: string) => void; extract?: (context: TContext) => string | null; persistence?: PersistenceConfig; }; }