import type { AuthenticationResponseJSON, RegistrationResponseJSON } from '@simplewebauthn/types'; import type { APIGatewayProxyEvent, Context as LambdaContext } from 'aws-lambda'; import type { CorsConfig, CorsContext, PartialRequest } from '@cedarjs/api'; interface SignupFlowOptions> { /** * Allow users to sign up. Defaults to true. * Needs to be explicitly set to false to disable the flow */ enabled?: boolean; /** * Whatever you want to happen to your data on new user signup. Redwood will * check for duplicate usernames before calling this handler. At a minimum * you need to save the `username`, `hashedPassword` and `salt` to your * user table. `userAttributes` contains any additional object members that * were included in the object given to the `signUp()` function you got * from `useAuth()` */ handler: (signupHandlerOptions: SignupHandlerOptions) => any; /** * Validate the user-supplied password with whatever logic you want. Return * `true` if valid, throw `PasswordValidationError` if not. */ passwordValidation?: (password: string) => boolean; /** * Object containing error strings */ errors?: { fieldMissing?: string; usernameTaken?: string; flowNotEnabled?: string; }; /** * Allows the user to define if the UserCheck for their selected db provider should use case insensitive */ usernameMatch?: string; } interface ForgotPasswordFlowOptions { /** * Allow users to request a new password via a call to forgotPassword. Defaults to true. * Needs to be explicitly set to false to disable the flow */ enabled?: boolean; handler: (user: TUser, token: string) => any; errors?: { usernameNotFound?: string; usernameRequired?: string; flowNotEnabled?: string; }; expires: number; } interface LoginFlowOptions { /** * Allow users to login. Defaults to true. * Needs to be explicitly set to false to disable the flow */ enabled?: boolean; /** * Anything you want to happen before logging the user in. This can include * throwing an error to prevent login. If you do want to allow login, this * function must return an object representing the user you want to be logged * in, containing at least an `id` field (whatever named field was provided * for `authFields.id`). For example: `return { id: user.id }` */ handler: (user: TUser) => any; /** * Object containing error strings */ errors?: { usernameOrPasswordMissing?: string; usernameNotFound?: string; incorrectPassword?: string; flowNotEnabled?: string; }; /** * How long a user will remain logged in, in seconds */ expires: number; /** * Allows the user to define if the UserCheck for their selected db provider should use case insensitive */ usernameMatch?: string; } interface ResetPasswordFlowOptions { /** * Allow users to reset their password via a code from a call to forgotPassword. Defaults to true. * Needs to be explicitly set to false to disable the flow */ enabled?: boolean; handler: (user: TUser) => boolean | Promise; allowReusedPassword: boolean; errors?: { resetTokenExpired?: string; resetTokenInvalid?: string; resetTokenRequired?: string; reusedPassword?: string; flowNotEnabled?: string; }; } interface WebAuthnFlowOptions { enabled: boolean; expires: number; name: string; domain: string; origin: string; timeout?: number; type: 'any' | 'platform' | 'cross-platform'; credentialFields: { id: string; userId: string; publicKey: string; transports: string; counter: string; }; } export type UserType = Record; export type DbAuthResponse = Promise<{ headers: { [x: string]: string | string[]; }; body?: string | undefined; statusCode: number; }>; type AuthMethodOutput = [ string | Record | boolean | undefined, Headers?, { statusCode: number; }? ]; export interface DbAuthHandlerOptions, TDb extends object = Record> { /** * Provide prisma db client * * Typed generically so that `authModelAccessor` and `credentialModelAccessor` * below are constrained to the model names that actually exist in the user's * schema, without importing @prisma/client. A real PrismaClient instance * always satisfies `Record`. */ db: TDb; /** * The name of the property you'd call on `db` to access your user table. * ie. if your Prisma model is named `User` this value would be `user`, as in `db.user` */ authModelAccessor: keyof TDb; /** * The name of the property you'd call on `db` to access your user credentials table. * ie. if your Prisma model is named `UserCredential` this value would be `userCredential`, as in `db.userCredential` */ credentialModelAccessor?: keyof TDb; /** * The fields that are allowed to be returned from the user table when * invoking handlers that return a user object (like forgotPassword and signup) * Defaults to `id` and `email` if not set at all. */ allowedUserFields?: string[]; /** * A map of what dbAuth calls a field to what your database calls it. * `id` is whatever column you use to uniquely identify a user (probably * something like `id` or `userId` or even `email`) */ authFields: { id: string; username: string; hashedPassword: string; salt: string; resetToken: string; resetTokenExpiresAt: string; challenge?: string; }; /** * Object containing cookie config options */ cookie?: { /** @deprecated set this option in `cookie.attributes` */ Path?: string; /** @deprecated set this option in `cookie.attributes` */ HttpOnly?: boolean; /** @deprecated set this option in `cookie.attributes` */ Secure?: boolean; /** @deprecated set this option in `cookie.attributes` */ SameSite?: string; /** @deprecated set this option in `cookie.attributes` */ Domain?: string; attributes?: { Path?: string; HttpOnly?: boolean; Secure?: boolean; SameSite?: string; Domain?: string; }; /** * The name of the cookie that dbAuth sets * * %port% will be replaced with the port the api server is running on. * If you have multiple RW apps running on the same host, you'll need to * make sure they all use unique cookie names */ name?: string; }; /** * Object containing forgot password options */ forgotPassword: ForgotPasswordFlowOptions | { enabled: false; }; /** * Object containing login options */ login: LoginFlowOptions | { enabled: false; }; /** * Object containing reset password options */ resetPassword: ResetPasswordFlowOptions | { enabled: false; }; /** * Object containing login options */ signup: SignupFlowOptions | { enabled: false; }; /** * Object containing WebAuthn options */ webAuthn?: WebAuthnFlowOptions | { enabled: false; }; /** * CORS settings, same as in createGraphqlHandler */ cors?: CorsConfig; } export interface SignupHandlerOptions { username: string; hashedPassword: string; salt: string; userAttributes?: TUserAttributes; } export type AuthMethodNames = 'forgotPassword' | 'getToken' | 'login' | 'logout' | 'resetPassword' | 'signup' | 'webAuthnAuthenticate' | 'webAuthnAuthOptions' | 'webAuthnRegOptions' | 'webAuthnRegister' | 'validateResetToken'; type Params = AuthenticationResponseJSON & RegistrationResponseJSON & { username?: string; password?: string; resetToken?: string; method: AuthMethodNames; [key: string]: any; } & { transports?: string; }; type DbAuthSession = Record; type CorsHeaders = Record; export declare class DbAuthHandler, TDb extends object = Record> { event: Request | APIGatewayProxyEvent; _normalizedRequest: PartialRequest | undefined; httpMethod: string; options: DbAuthHandlerOptions; cookie: string; db: TDb; dbAccessor: any; dbCredentialAccessor: any; allowedUserFields: string[]; hasInvalidSession: boolean; session: DbAuthSession | undefined; sessionCsrfToken: string | undefined; corsContext: CorsContext | undefined; sessionExpiresDate: string; webAuthnExpiresDate: string; encryptedSession: string | null; createResponse: (response: { body?: string; statusCode: number; headers?: Headers; }, corsHeaders: CorsHeaders) => { headers: Record; body?: string | undefined; statusCode: number; }; get normalizedRequest(): PartialRequest; static get METHODS(): AuthMethodNames[]; static get VERBS(): { forgotPassword: string; getToken: string; login: string; logout: string; resetPassword: string; signup: string; validateResetToken: string; webAuthnRegOptions: string; webAuthnRegister: string; webAuthnAuthOptions: string; webAuthnAuthenticate: string; }; static get PAST_EXPIRES_DATE(): string; static get CSRF_TOKEN(): string; static get AVAILABLE_WEBAUTHN_TRANSPORTS(): string[]; /** * Returns the set-cookie header to mark the cookie as expired ("deletes" the session) * * The header keys are case insensitive, but Fastify prefers these to be lowercase. * Therefore, we want to ensure that the headers are always lowercase and unique * for compliance with HTTP/2. * * @see: https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2 */ get _deleteSessionHeader(): Headers; constructor(event: APIGatewayProxyEvent | Request, _context: LambdaContext, // @TODO: options: DbAuthHandlerOptions); init(): Promise; invoke(): Promise<{ headers: Record; body?: string | undefined; statusCode: number; }>; forgotPassword(): Promise; getToken(): Promise; login(): Promise; logout(): AuthMethodOutput; resetPassword(): Promise; signup(): Promise; validateResetToken(): Promise; webAuthnAuthenticate(): Promise; webAuthnAuthOptions(): Promise; webAuthnRegOptions(): Promise; webAuthnRegister(): Promise; _validateOptions(): void; _saveChallenge(userId: string | number, value: string | null): Promise; _webAuthnCookie(id: string, expires: string): string; _sanitizeUser(user: Record): any; _decodeEvent(): void; _cookieAttributes({ expires, options, }: { expires?: 'now' | string; options?: DbAuthHandlerOptions['cookie']; }): (string | null)[]; _createAuthProviderCookieString(): string; _createSessionCookieString(data: DbAuthSession, csrfToken: string): string; _validateCsrf(): Promise; _findUserByToken(token: string): Promise; _clearResetToken(user: Record): Promise; _verifyUser(username: string | undefined, password: string | undefined): Promise; _verifyPassword(user: Record, password: string): Promise>; _getCurrentUser(): Promise; _createUser(): Promise; _getAuthMethod(): Promise; _validateField(name: string, value: string | undefined): value is string; _loginResponse(user: Record, statusCode?: number): [{ id: string; }, Headers, { statusCode: number; }]; _logoutResponse(response?: Record): AuthMethodOutput; _ok(body: string | boolean | undefined | Record, headers?: Headers, options?: { statusCode: number; }): { statusCode: number; body: string; headers: Headers; }; _notFound(): { statusCode: number; }; _badRequest(message: string): { statusCode: number; body: string; headers: Headers; }; _getUserMatchCriteriaOptions(username: string, usernameMatchFlowOption: string | undefined): { [x: string]: string; } | { [x: string]: { equals: string; mode: string; }; }; } export {}; //# sourceMappingURL=DbAuthHandler.d.ts.map