UNPKG

@webda/core

Version:

Expose API with Lambda

361 lines (360 loc) 9.87 kB
import { Counter, EventWithContext } from "../core.js"; import { CoreModelDefinition } from "../models/coremodel.js"; import { Ident } from "../models/ident.js"; import { User } from "../models/user.js"; import { Service, ServiceParameters } from "../services/service.js"; import { Store } from "../stores/store.js"; import { OperationContext, WebContext } from "../utils/context.js"; import { HttpMethodType } from "../utils/httpcontext.js"; import CryptoService from "./cryptoservice.js"; import { Mailer } from "./mailer.js"; /** * Emitted when the /me route is called */ export interface EventAuthenticationGetMe extends EventWithContext { user: User; } /** * Emitted when new user registered */ export interface EventAuthenticationRegister extends EventAuthenticationGetMe { data: any; identId: string; } /** * Emitted when user logout */ export interface EventAuthenticationLogout extends EventWithContext { } /** * Sent when a user update his password */ export interface EventAuthenticationPasswordUpdate extends EventAuthenticationGetMe { password: string; } /** * Emitted when user login */ export interface EventAuthenticationLogin extends EventWithContext { userId: string; user?: User; identId: string; ident: Ident; } /** * Export when a user failed to authenticate with his password */ export interface EventAuthenticationLoginFailed extends EventAuthenticationGetMe { } /** * Implement a PasswordVerifier so you can implement * your own rules */ export interface PasswordVerifier extends Service { /** * If the password is not valid, send a 400 exception or * return false * * @param password to verify * @param user to verify from */ validate(password: string, user?: User): Promise<boolean>; } /** * Information required to reset a password */ export interface PasswordRecoveryInfos { /** * Links are short lived */ expire: number; /** * Generated token */ token: string; /** * Login to reset password fors */ login: string; } interface PasswordRecoveryBody extends PasswordRecoveryInfos { /** * Password to set */ password: string; } /** * Login info * * If register = true, you can add many other information * * @SchemaAdditionalProperties */ interface LoginBody { login: string; register?: boolean; token?: string; email?: string; password?: string; } export declare class AuthenticationParameters extends ServiceParameters { /** * Idents store for authentication identifiers * * @default "Webda/Ident" */ identModel?: string; /** * User store for authentication users * * @default "Webda/User" */ userModel?: string; /** * @default "/auth" */ url?: string; /** * Enable the email authentication */ email?: { /** * Mailer service name */ mailer?: string; /** * Allow user to create their account without validating their email first */ postValidation: boolean; /** * Do not even validate the email at all */ skipEmailValidation: boolean; /** * Minimal delay between two password recovery or validation email * * @default 3600000 * 4 */ delay: number; /** * When a delay is added between two attempt to authenticate * * @default 3 */ failedLoginBeforeDelay: number; }; password: { /** * Password verifier Service name */ verifier?: string; /** * Regexp that password must check * @default "{8,}" */ regexp?: string; }; /** * Number of salt iteration for bcrypt.hashSync */ salt: string; /** * Redirect to this page when email validation failed */ failureRedirect: string; /** * Redirect to this page when email validation succeed */ successRedirect: string; /** * Redirect to this page once email is validate to finish the registration process */ registerRedirect: string; constructor(params: any); } export type AuthenticationEvents = { "Authentication.GetMe": EventAuthenticationGetMe; "Authentication.Register": EventAuthenticationRegister; "Authentication.PasswordUpdate": EventAuthenticationPasswordUpdate; "Authentication.Logout": EventAuthenticationLogout; "Authentication.Login": EventAuthenticationLogin; "Authentication.LoginFailed": EventAuthenticationLoginFailed; "Authentication.PasswordCreate": EventAuthenticationPasswordUpdate; }; /** * This class is known as the Authentication module * It handles OAuth for several providers for now (Facebook, Google, Amazon, GitHub and Twitter) * It also handles email authentication with prevalidation or postvalidation of the email * * It requires two Store to work one `idents` and one `users` * * The parameters are * ``` * providerName: { * clientID: '...', * clientSecret: '...', * scope: '' * }, * email: { * postValidation: true|false // If postValidation=true, account created without email verification * } * url: 'url' // By default /auth * ``` * * @category CoreServices * @WebdaModda */ declare class Authentication<T extends AuthenticationParameters = AuthenticationParameters, E extends AuthenticationEvents = AuthenticationEvents> extends Service<T, E> { _identModel: CoreModelDefinition<Ident>; _userModel: CoreModelDefinition<User>; /** * Used for hmac */ cryptoService: CryptoService; _passwordVerifier: PasswordVerifier; providers: Set<string>; metrics: { login: Counter; logout: Counter; loginFailed?: Counter; recovery?: Counter; recovered?: Counter; registration?: Counter; }; /** * Load the parameters for a service */ loadParameters(params: any): AuthenticationParameters; /** * Get the user store * @returns */ getUserStore<K extends User = User>(): Store<K>; /** * Get the user store * @returns */ getIdentStore<K extends Ident = Ident>(): Store<K>; /** * @ignore * Setup the default routes */ computeParameters(): void; /** * @override */ initMetrics(): void; /** * Add a provider to the oauth scheme * @param name */ addProvider(name: string): void; /** * Ensure email is enabled for all emails routes * @override */ getUrl(url: string, methods: HttpMethodType[]): string; /** * Send or resend an email to validate the email address * * @param ctx * @throws 409 if ident is linked to someone else * @throws 412 if the email is already validated * @throws 429 if a validation email has been sent recently */ _sendEmailValidation(ctx: any): Promise<void>; /** * Return current user * @param ctx */ _getMe(ctx: OperationContext): Promise<void>; /** * Handle both list of available authentication * and logout with method 'DELETE' * * @param ctx * @returns */ _listAuthentications(ctx: WebContext): Promise<void>; onIdentLogin(ctx: WebContext, provider: string, identId: string, profile: any, tokens?: any): Promise<void>; /** * Create a new User with the link ident * @param ident */ createUserWithIdent(provider: string, identId: string, profile?: any): Promise<void>; registerUser(ctx: WebContext, data: any, identId: string, user?: User): Promise<User>; getPasswordRecoveryInfos(uuid: string | User, interval?: number): Promise<PasswordRecoveryInfos>; /** * Manage password recovery * @param ctx */ _passwordRecoveryEmail(ctx: WebContext): Promise<void>; _verifyPassword(password: string, user?: User): Promise<void>; _passwordRecovery(ctx: WebContext<PasswordRecoveryBody>): Promise<void>; /** * Callback to validate an email address * @param ctx * @returns */ _handleEmailCallback(ctx: WebContext): Promise<void>; /** * Send an email to recover the user password * * @param ctx * @param user * @param email * @returns */ sendRecoveryEmail(ctx: WebContext, user: any, email: string): Promise<any>; /** * Send an email to validate the user email by sending a unique link to * his email * * @param ctx * @param email * @returns */ sendValidationEmail(ctx: WebContext, email: string): Promise<any>; /** * Check the password match the stored hash * @param hash generate prior by hashPassword * @param password as entered by the user */ checkPassword(hash: string, pass: string): boolean; /** * Hash the password according to good practices * * @param pass to hash */ hashPassword(pass: string): string; /** * Logout user */ logout(ctx: WebContext): Promise<void>; /** * Login a user * * @param ctx * @param user * @param ident * @returns */ login(ctx: WebContext, user: User | string, ident: Ident, provider: string): Promise<any[]>; getMailMan(): Mailer; /** * Handle a user login request * * @param ctx * @param ident */ protected handleLogin(ctx: WebContext<LoginBody>, ident: Ident): Promise<void>; /** * Handle the POST /auth/email * * @param ctx * @returns */ _handleEmail(ctx: WebContext<LoginBody>): Promise<any>; generateEmailValidationToken(user: string, email: string): Promise<string>; } export { Authentication };