authkit-js
Version:
Express auth toolkit (JWT, Sessions with Redis, Google/GitHub OAuth) in JavaScript
205 lines (179 loc) • 7.12 kB
TypeScript
import { Request, Response, NextFunction, Router } from 'express';
export interface CookieNames {
access?: string;
refresh?: string;
session?: string;
csrf?: string;
}
export interface CookieConfig {
names?: CookieNames;
domain?: string;
path?: string;
sameSite?: 'lax' | 'strict' | 'none';
secure?: boolean;
env?: string;
crossSite?: boolean;
}
export interface JwtOptions {
issuer?: string;
audience?: string;
accessTokenTtlSec?: number;
refreshTokenTtlSec?: number;
algorithm?: 'HS256' | 'HS384' | 'HS512';
}
export interface JWTStrategyConfig {
secret: string;
opts?: JwtOptions;
cookie?: CookieConfig;
deserializeUser?: (payload: any) => Promise<any>;
refreshStore?: {
get: (userId: string) => Promise<string | null>;
set: (userId: string, token: string, ttlSec?: number) => Promise<void>;
del: (userId: string) => Promise<void>;
} | null;
}
export interface SessionStore {
get(id: string): Promise<any | null>;
set(id: string, data: any, ttlSec: number): Promise<void>;
del(id: string): Promise<void>;
}
export interface SessionStrategyConfig {
store: SessionStore;
opts?: { ttlSec?: number };
cookie?: CookieConfig;
serializeUser?: (user: any) => Promise<any>;
deserializeUser?: (data: any) => Promise<any>;
}
export class JWTStrategy {
constructor(cfg: JWTStrategyConfig);
login(res: Response, user: any): Promise<{ accessToken: string; refreshToken: string }>;
authenticate(req: Request): Promise<{ user: any; token: string } | null>;
refresh(req: Request, res: Response): Promise<{ accessToken: string; refreshToken: string }>;
logout(res: Response): Promise<void>;
}
export class SessionStrategy {
constructor(cfg: SessionStrategyConfig);
login(res: Response, user: any): Promise<{ sessionId: string; csrf: string }>;
authenticate(req: Request): Promise<{ user: any; sessionId: string } | null>;
assertCsrf(req: Request): Promise<void>;
logout(req: Request, res: Response): Promise<void>;
}
export interface GoogleOAuthStrategyConfig {
clientId: string;
clientSecret: string;
redirectUri: string;
verify?: (payload: any, tokens?: any) => Promise<any>;
}
export class GoogleOAuthStrategy {
constructor(cfg: GoogleOAuthStrategyConfig);
getAuthUrl(scope?: string[] | string): string;
handleCallback(code: string): Promise<{ user: any; tokens: any; profile: any }>;
}
export interface GitHubOAuthStrategyConfig {
clientId: string;
clientSecret: string;
redirectUri: string;
verify?: (profile: any, accessToken?: string) => Promise<any>;
}
export class GitHubOAuthStrategy {
constructor(cfg: GitHubOAuthStrategyConfig);
getAuthUrl(scope?: string): string;
handleCallback(code: string): Promise<{ user: any; accessToken: string; profile: any }>;
}
export interface FacebookOAuthStrategyConfig {
clientId: string;
clientSecret: string;
redirectUri: string;
verify?: (profile: any, accessToken?: string) => Promise<any>;
}
export class FacebookOAuthStrategy {
constructor(cfg: FacebookOAuthStrategyConfig);
getAuthUrl(scope?: string[] | string): string;
handleCallback(code: string): Promise<{ user: any; accessToken: string; profile: any }>;
}
export interface AppleOAuthStrategyConfig {
clientId: string;
clientSecret: string;
redirectUri: string;
verify?: (idTokenPayload: any, tokens?: any) => Promise<any>;
}
export class AppleOAuthStrategy {
constructor(cfg: AppleOAuthStrategyConfig);
getAuthUrl(scope?: string[] | string): string;
handleCallback(code: string): Promise<{ user: any; tokens: any; profile: any }>;
}
export class MemorySessionStore implements SessionStore {
constructor();
get(id: string): Promise<any | null>;
set(id: string, data: any, ttlSec: number): Promise<void>;
del(id: string): Promise<void>;
}
export class RedisSessionStore implements SessionStore {
constructor(client: any);
get(id: string): Promise<any | null>;
set(id: string, data: any, ttlSec: number): Promise<void>;
del(id: string): Promise<void>;
}
export class MemoryRefreshStore {
constructor();
get(userId: string): Promise<string | null>;
set(userId: string, token: string, ttlSec?: number): Promise<void>;
del(userId: string): Promise<void>;
}
export class RedisRefreshStore {
constructor(client: any, keyPrefix?: string);
get(userId: string): Promise<string | null>;
set(userId: string, token: string, ttlSec?: number): Promise<void>;
del(userId: string): Promise<void>;
}
export interface AuthKitConfig {
jwt?: JWTStrategyConfig;
session?: SessionStrategyConfig;
google?: GoogleOAuthStrategy;
github?: GitHubOAuthStrategy;
facebook?: FacebookOAuthStrategy;
apple?: AppleOAuthStrategy;
defaultStrategy?: 'jwt' | 'session';
}
export class AuthKit {
constructor(cfg?: AuthKitConfig);
jwt?: JWTStrategy;
session?: SessionStrategy;
google?: GoogleOAuthStrategy;
github?: GitHubOAuthStrategy;
facebook?: FacebookOAuthStrategy;
apple?: AppleOAuthStrategy;
authenticate(req: Request, name?: 'jwt' | 'session'): Promise<any>;
}
export function makeAuthenticate(kit: AuthKit, strategyName?: 'jwt' | 'session'): (req: Request, res: Response, next: NextFunction) => Promise<void>;
export function requireAuth(): (req: Request, res: Response, next: NextFunction) => void;
export function attachAuth(kit: AuthKit, strategyName?: 'jwt' | 'session'): (req: Request, res: Response, next: NextFunction) => Promise<void>;
export function makeAuthRouter(kit: AuthKit, options?: Record<string, unknown>): Router;
export interface CorsOptions {
origin?: string | string[] | RegExp | ((origin: string | undefined) => boolean);
methods?: string[];
headers?: string[];
credentials?: boolean;
maxAge?: number;
}
export function makeCors(options?: CorsOptions): (req: Request, res: Response, next: NextFunction) => void;
export function makeRateLimit(options?: { capacity?: number; intervalMs?: number; key?: (req: Request) => string }): (req: Request, res: Response, next: NextFunction) => void;
// Guards
export function requireAuthGuard(): (req: Request, res: Response, next: NextFunction) => void;
export function requireRole(role: string): (req: Request, res: Response, next: NextFunction) => void;
export function requirePermission(permission: string): (req: Request, res: Response, next: NextFunction) => void;
// Errors
export const Errors: {
UNAUTHORIZED: (msg?: string) => Error;
FORBIDDEN: (msg?: string) => Error;
BAD_REQUEST: (msg?: string) => Error;
TOKEN_INVALID: (msg?: string) => Error;
TOKEN_EXPIRED: (msg?: string) => Error;
TOKEN_REUSE: (msg?: string) => Error;
};
// 2FA
export namespace TwoFA {
function generateSecret(label: string): { ascii: string; hex: string; base32: string; otpauth_url: string };
function generateQRCodeDataURL(otpauthUrl: string): Promise<string>;
function verifyToken(secretBase32: string, token: string, window?: number): boolean;
}