UNPKG

@cauth/express

Version:

Express integration for CAuth authentication system.

331 lines (330 loc) 8.77 kB
import { NextFunction, Request, Response } from "express"; import z$1, { z } from "zod"; import ms from "ms"; //#region ../core/src/types/auth.t.d.ts type Account = { id: string; phoneNumber: string; email: string; role: string; lastLogin: Date; createdAt: Date; updatedAt: Date; }; type Tokens = { accessToken: string; refreshToken: string; }; declare const AuthModelSchema: z$1.ZodObject<{ id: z$1.ZodString; phoneNumber: z$1.ZodString; email: z$1.ZodString; passwordHash: z$1.ZodOptional<z$1.ZodString>; role: z$1.ZodString; lastLogin: z$1.ZodDate; refreshTokens: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>; createdAt: z$1.ZodDate; updatedAt: z$1.ZodDate; }, z$1.z.core.$strip>; type AuthModel = z$1.infer<typeof AuthModelSchema>; //#endregion //#region ../core/src/types/result.t.d.ts type FNError = { type: string; error: Error; }; /** * @description Core Result type. * @template T - The type of the value. * @template E - The type of the errors, which must extend { type: string; error: Error }. */ type Result<T, E extends FNError = FNError> = { success: true; value: T; } | { success: false; errors: E[]; }; //#endregion //#region ../core/src/types/otp-purpose.t.d.ts type OtpPurpose = 'LOGIN' | 'RESET_PASSWORD' | 'ACTION'; //#endregion //#region ../core/src/types/database.contract.d.ts interface DatabaseContract { findAccountById<T = AuthModel>({ ...args }: { id: string; select?: any; }): Promise<T | undefined>; findAccountWithCredential<T = AuthModel>({ ...args }: { email?: string | undefined; phoneNumber?: string | undefined; select?: any; }): Promise<T | undefined>; createAccount<T = AuthModel>({ ...args }: { data: any; select?: any; }): Promise<T>; updateAccount<T = AuthModel>({ ...args }: { id: string; data: any; select?: any; }): Promise<T>; updateAccountLogin<T = AuthModel>({ ...args }: { id: string; refreshToken: string; select?: any; }): Promise<T>; removeAndAddRefreshToken({ ...args }: { id: string; refreshToken: string; newRefreshToken?: string; select?: any; }): Promise<any>; deleteAccount({ ...args }: { id: string; }): Promise<void>; createOTP<T = { code: string; purpose: string; expiresAt: Date; }>({ config }: { config: CAuthOptions; }, { ...args }: { id: string; purpose: OtpPurpose; }): Promise<T>; verifyOTP<T = { isValid: boolean; }>({ ...args }: { id: string; code: string; purpose: OtpPurpose; }): Promise<T>; } //#endregion //#region ../core/src/types/config.t.d.ts declare const CAuthOptionsSchema: z$1.ZodObject<{ dbContractor: z$1.ZodCustom<DatabaseContract, DatabaseContract>; routeContractor: z$1.ZodCustom<RoutesContract<(...args: any[]) => any>, RoutesContract<(...args: any[]) => any>>; roles: z$1.ZodArray<z$1.ZodString>; jwtConfig: z$1.ZodObject<{ refreshTokenSecret: z$1.ZodString; accessTokenSecret: z$1.ZodString; accessTokenLifeSpan: z$1.ZodOptional<z$1.ZodCustom<ms.StringValue, ms.StringValue>>; refreshTokenLifeSpan: z$1.ZodOptional<z$1.ZodCustom<ms.StringValue, ms.StringValue>>; }, z$1.z.core.$strip>; otpConfig: z$1.ZodObject<{ expiresIn: z$1.ZodOptional<z$1.ZodNumber>; length: z$1.ZodOptional<z$1.ZodNumber>; }, z$1.z.core.$strip>; }, z$1.z.core.$strip>; type CAuthOptions = z$1.infer<typeof CAuthOptionsSchema>; //#endregion //#region ../core/src/types/dto-schemas.t.d.ts declare const LoginSchema: z.ZodUnion<readonly [z.ZodObject<{ email: z.ZodEmail; phoneNumber: z.ZodOptional<z.ZodNever>; password: z.ZodString; }, z.core.$strip>, z.ZodObject<{ phoneNumber: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>; email: z.ZodOptional<z.ZodNever>; password: z.ZodString; }, z.core.$strip>]>; type LoginSchemaType = z.infer<typeof LoginSchema>; declare const RegisterSchema: z.ZodObject<{ phoneNumber: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>; email: z.ZodOptional<z.ZodEmail>; role: z.ZodString; password: z.ZodString; }, z.core.$strip>; type RegisterSchemaType = z.infer<typeof RegisterSchema>; declare const RefreshTokenSchema: z.ZodObject<{ refreshToken: z.ZodString; }, z.core.$strip>; type RefreshTokenSchemaType = z.infer<typeof RefreshTokenSchema>; declare const LogoutSchema: z.ZodObject<{ refreshToken: z.ZodString; }, z.core.$strip>; type LogoutSchemaType = z.infer<typeof LogoutSchema>; declare const ChangePasswordSchema: z.ZodObject<{ accountId: z.ZodString; oldPassword: z.ZodString; newPassword: z.ZodString; }, z.core.$strip>; type ChangePasswordSchemaType = z.infer<typeof ChangePasswordSchema>; //#endregion //#region ../core/src/cauth.d.ts declare class _CAuth<T extends string[], TContractor extends RoutesContract<any> = RoutesContract<any>> { #private; constructor(config: Omit<CAuthOptions, 'roles'> & { roles: T; routeContractor: TContractor; }); get RoleType(): T[number]; /** * @description Auth guard middleware — roles optional. * Automatically typed as the handler type from the contractor (e.g. Express.RequestHandler). */ Guard: (roles?: Array<T[number]>) => (...args: any[]) => any; /** * Route Handlers — typed from the contractor automatically. */ Routes: { Register: () => ReturnType<TContractor["Register"]>; Login: () => ReturnType<TContractor["Login"]>; Logout: () => ReturnType<TContractor["Logout"]>; Refresh: () => ReturnType<TContractor["Refresh"]>; ChangePassword: (userId: string) => ReturnType<TContractor["ChangePassword"]>; }; FN: { Login: ({ ...args }: LoginSchemaType) => Promise<Result<{ account: Account; tokens: Tokens; }>>; Register: ({ ...args }: RegisterSchemaType) => Promise<Result<{ account: Account; tokens: Tokens; }>>; Logout: ({ ...args }: LogoutSchemaType) => Promise<Result<unknown>>; Refresh: ({ ...args }: RefreshTokenSchemaType) => Promise<Result<{ account: Account; tokens: Tokens; }>>; ChangePassword: ({ ...args }: ChangePasswordSchemaType) => Promise<Result<unknown>>; RequestOTPCode: ({ ...args }: Omit<LoginSchemaType, "password"> & { password?: string; usePassword?: boolean; otpPurpose: OtpPurpose; }) => Promise<Result<{ id: string; code: string; }>>; LoginWithOTP: (args: Omit<LoginSchemaType, "password"> & { code: string; }) => Promise<Result<{ account: Account; tokens: Tokens; }>>; VerifyOTP: (args: { id: string; code: string; otpPurpose: OtpPurpose; }) => Promise<Result<{ isValid: boolean; }>>; }; Tokens: { GenerateRefreshToken: (payload: any) => Promise<string>; GenerateAccessToken: (payload: any) => Promise<string>; GenerateTokenPairs: (payload: any) => Promise<{ accessToken: string; refreshToken: string; }>; VerifyRefreshToken: <R>(token: any) => Promise<R | null>; VerifyAccessToken: <R>(token: any) => Promise<R | null>; }; } //#endregion //#region ../core/src/types/routes.contract.t.d.ts type RouteDeps = { config: CAuthOptions; tokens: _CAuth<any>['Tokens']; }; type AuthGuardDeps = { config: CAuthOptions; tokens: _CAuth<any>['Tokens']; roles?: Array<string>; }; /** * Generic RoutesContract * THandler is generic, defaults to any function */ interface RoutesContract<THandler extends (...args: any[]) => any = (...args: any[]) => any> { Login({ ...config }: RouteDeps): THandler; Register({ ...config }: RouteDeps): THandler; Logout({ ...config }: RouteDeps): THandler; Guard({ ...config }: AuthGuardDeps): THandler; Refresh({ ...config }: AuthGuardDeps): THandler; ChangePassword({ ...config }: RouteDeps & { userId: string; }): THandler; } //#endregion //#region src/express.contractor.d.ts type OptionalNextHandler = (req: Request, res: Response, next?: NextFunction) => any; declare class ExpressContractor<THandler extends (...args: any[]) => any = OptionalNextHandler> implements RoutesContract<THandler> { Register: ({ config, tokens }: RouteDeps) => THandler; Login: ({ config, tokens }: RouteDeps) => THandler; Logout: ({ config, tokens }: RouteDeps) => THandler; Refresh: ({ config, tokens }: RouteDeps) => THandler; ChangePassword: ({ config, tokens, userId }: RouteDeps & { userId: string; }) => THandler; Guard: ({ config, tokens, roles }: AuthGuardDeps) => THandler; } //#endregion export { ExpressContractor };