@webda/core
Version:
Expose API with Lambda
361 lines (360 loc) • 9.87 kB
TypeScript
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 };