///
import * as Bluebird from 'bluebird';
import { RouterContext, Middleware } from './router';
export interface Acl {
isAllowed(userId: string, resource: string, permissions: string | string[]): Bluebird;
addUserRoles(userId: string, roles: string | string[]): Bluebird;
removeUserRoles(userId: string, roles: string | string[]): Bluebird;
userRoles(userId: string): Bluebird;
}
/** Raised when a user is not found during authentication. */
export declare class UserNotFoundError extends Error {
constructor(message?: string);
}
/** Raised when a token has expired. */
export declare class TokenExpiryError extends Error {
constructor(message?: string);
}
/** Raised when a token is invalid. */
export declare class TokenInvalidError extends Error {
constructor(message?: string);
}
/** Raised when access to a route isn't allowed */
export declare class AuthorisationError extends Error {
constructor(message?: string);
}
/**
* The payload representation of a bearer token.
* This is encrypted into a secure token when sent to clients.
*/
export interface AuthPayload {
/** The subject of the token (i.e. user identifier). */
sub: string;
/** The token issue time (in unix). */
iat: number;
/** The expiry time of the token (in unix). */
exp: number;
}
/**
* A bearer authentication token that can be sent and received by clients.
*/
export declare type AuthToken = string;
/**
* Options for configuring the auth init route.
*/
export interface AuthInitOptions {
/** The name of the header to look for the bearer token. */
header?: string;
/**
* Whether authentication is optional, i.e. whether
* other routes should be inaccessible
* if the user is not logged. Defaults to false.
*/
optional?: boolean;
}
/**
* Manages backend authentication for a web application using bearer tokens.
*
* This should be extended by an application-specific child class
* with the relevant method overrides to work with an application's
* internal representation of a user model.
*
* It's important that the relevant middleware is used on either
* the application or a router.
*
* @see init, login, register
* @param T The type representing a user model.
*/
export declare abstract class Auth {
/**
* The secret key used to encrypt/decrypt the tokens.
*
* Changing the secret key will invalidate all existing logins
* to the system and there is no guarantee that this will work smoothly
* with whatever MVC frontend a client is using.
*/
protected secret: string;
/**
* The number of days that generated authentication tokens will
* last for. This should be a high number and defaults
* to two weeks.
*/
protected expiryDays: number;
/**
* The ACL authorisation to check permissions with
*/
protected acl: Acl;
/**
* @param secret The secret key.
* @param expiryDays The number of days auth tokens will be valid for.
*/
constructor(secret: string, expiryDays?: number, acl?: Acl);
/**
* Produces a bearer token that can be sent to a client securely and then used
* to login to the web application.
*
* It is crucial that this is only sent to a user upon successful
* login or registration, as this token will give them full access to
* the relevant user model.
*
* @see consumeToken
* @param user The user to generate an auth token for.
* @returns A promise that resolves to an auth token.
*/
protected produceToken(user: T): Promise;
/**
* Consumes a bearer token and translates it to the relevant user model.
* This will fail if the user could not be found or the token has expired.
*
* @see produceToken
* @throws TokenExpiryError, UserNotFoundError
* @param token The auth token to find a user from.
* @returns A promise that resolves to the user model, or rejects if not
* found/the token has expired.
*/
protected consumeToken(token: AuthToken): Promise;
/**
* An abstract method that fetches a user from a relevant identifier.
* This should be implemented by a child class and will be used to
* find a user from a decrypted token's original identifier value.
* This will fail if the user could not be found.
*
* @rejects UserNotFoundError
* @param id The identifier.
* @returns A promise that resolves to the user model, or rejects if not found.
*/
protected abstract getUser(id: string): Promise;
/**
* An abstract method that fetches the identifier for a specific user
* in order to generate an auth token.
*
* The identifier should be unique as it in turn will be used to find a user
* when the token is decrypted. It is however not necessarily a constraint
* of this design to have the identifier not unique if required.
*
* @param user The user to get the identifier for.
* @returns The user identifier.
*/
protected abstract getIdentifier(user: T): string;
/**
* An abstract method that fetches the roles for a specific user
* in order to restrict access to resources/routes
*
* @param user The user to get the roles for
* @returns The user roles
*/
protected abstract getRoles(user: T): Promise;
/**
* Log a user in using a provided router context
* with all of the request information available.
* This should reject with a UserNotFoundError
* if the login details were incorrect.
* If the promise resolves with a user,
* then the a new token will be immediately
* sent to the user marking a successful login.
*
* This must be implemented by the child
* authentication manager class if a login route
* is required. Without a child implementation
* it will always reject.
*
* @rejects UserNotFoundError, Error
* @see login
*/
protected loginUser(_ctx: RouterContext): Promise;
/**
* Register a user in using a provided router context
* with all of the request information available.
* If the promise resolves with a user,
* then the a new token will be immediately
* sent to the user marking a successful login.
*
* This must be implemented by the child
* authentication manager class if a register route
* is required. Without a child implementation
* it will always reject.
*
* @rejects Error
* @see login
*/
protected registerUser(_ctx: RouterContext): Promise;
/**
* A middleware used to check if the user is authed,
* and if so populates the router context with the user
* object.
*
* This should be added on the application during
* its configuration.
*
* @returns The auth initialization middleware.
*/
authenticated(options?: AuthInitOptions): Middleware;
/**
* A middleware used to login a user.
*
* This should be added on the router at the relevant URL.
*
* @returns The auth login middleware.
*/
login(): Middleware;
/**
* A middleware used to register a user.
*
* This should be added on the router at the relevant URL.
*
* @returns The auth registration middleware.
*/
register(): Middleware;
/**
* A middleware used to ensure a user is authorised to access a route
*
* This should be added on the router at the relevant URL.
*
* @returns The authorisation middleware
*/
authorised(resource: string, permissions: string | string[]): Middleware;
}