@mvx/identity
Version:
identity is oidc for mvc, type-mvc is base on koa. Decorator, Ioc, AOP mvc framework on server.
452 lines (451 loc) • 16 kB
TypeScript
import { InjectToken, ObjectMap, Type } from '@tsdi/ioc';
import { MvcContext, IContext, MvcConfiguration } from '@mvx/mvc';
import { Middleware, Context } from 'koa';
import { IStrategy } from './IStrategy';
/**
* deserialize user interface.
*
* @export
* @interface IDeserializeUser
*/
export interface IDeserializeUser {
deserializeUser(obj: any, ctx?: IContext): Promise<any>;
}
export declare type DeserializeUserOption = Type<IDeserializeUser> | ((obj: any, ctx?: IContext) => Promise<any>);
export interface ISerializeUser {
serializeUser(user: any, ctx: IContext): Promise<any>;
}
export declare type SerializeUserOption = Type<ISerializeUser> | ((user: any, ctx: IContext) => Promise<any>);
export interface ITransformAuthInfo {
authInfo(info: any, ctx: IContext): Promise<any>;
}
export declare type TransformAuthInfoOption = Type<ITransformAuthInfo> | ((info: any, ctx: IContext) => Promise<any>);
export interface IAuthFlowOption {
strategy: string | string[];
options: AuthenticateOption;
}
/**
* strategy option.
*
* @export
* @interface IStrategyOption
*/
export interface IStrategyOption extends ObjectMap {
strategy: string;
name?: string;
verify?: Function;
}
/**
* init auth option.
*/
export interface InitAuthOption {
/**
* assign deserializer user info to ctx state via this property name.
*/
userProperty?: string;
/**
* assign deserializer user role to ctx state via this property name.
*/
rolesProperty?: string;
}
export interface PassportConfigure {
default?: IAuthFlowOption;
/**
* @deprecated
*/
initialize?: InitAuthOption;
strategies: IStrategyOption[];
serializers?: SerializeUserOption[];
deserializers?: DeserializeUserOption[];
authInfos?: TransformAuthInfoOption[];
}
/**
* authenticate option.
*
* @export
* @interface AuthenticateOption
*/
export interface AuthenticateOption extends InitAuthOption, ObjectMap<any> {
session?: boolean;
successRedirect?: string;
successReturnToOrRedirect?: string;
/**
* assign deserializer user info to ctx state via this property name.
* @deprecated use userProperty instead.
*/
assignProperty?: any;
/**
* auth faild to redirect to.
*/
failureRedirect?: string;
failureFlash?: string | {
type: string;
message: string;
};
failureMessage?: string | boolean;
failWithError?: boolean;
successFlash?: string | {
type: string;
message: string;
};
successMessage?: string | boolean;
authInfo?: boolean;
}
export interface VaildFailure {
challenge: string | any;
status: number;
}
declare module '@mvx/mvc' {
interface IConfiguration extends MvcConfiguration {
/**
* passports config.
*
* @memberof IConfiguration
*/
passports?: PassportConfigure;
}
}
declare module 'koa' {
interface Context {
/**
* passport.
*/
passport: IAuthenticator;
/**
* auth failues.
*/
failures: VaildFailure[];
/**
* mvc application context.
*/
mvcContext: MvcContext;
connection?: any;
/**
* get current login user.
*/
getUser<T = any>(): T;
/**
* get current login user roles.
*/
getRoles<T = string>(): T[];
/**
* current login user has this roles or not.
* @param role roles.
*/
hasRole(...role: string[]): boolean;
/**
* Intiate a login session for `user`.
*
* Options:
* - `session` Save login state in session, defaults to `true`
*
* Examples:
*
* await req.logIn(user, { session: false });
* @param user
* @param options
*/
login(user: any, options?: any): Promise<void>;
/**
* Intiate a login session for `user`.
* @param user
* @param options
* @param done
*/
logIn(user: any, options: any, done: any): any;
/**
* the current user logout.
*/
logout(): void;
/**
* the current user logout.
*/
logOut(): void;
/**
* Test if request is authenticated.
*/
isAuthenticated(): boolean;
/**
* Test if request is unauthenticated.
*/
isUnauthenticated(): boolean;
}
}
/**
* IAuthenticator token.
*/
export declare const AuthenticatorToken: InjectToken<IAuthenticator>;
/**
* `Authenticator` constructor.
*
*/
export interface IAuthenticator {
/**
* user property.
*
* @type {string}
* @memberof IAuthenticator
*/
readonly userProperty: string;
/**
* user roles property.
*
* @type {string}
* @memberof IAuthenticator
*/
readonly rolesProperty: string;
/**
* get strategy.
*
* @param {string} name
* @returns {IStrategy}
* @memberof IAuthenticator
*/
get(name: string): IStrategy;
/**
* Utilize the given `strategy` with optional `name`, overridding the strategy's
* default name.
*
* Examples:
*
* passport.use(new TwitterStrategy(...));
*
* passport.use('api', new http.BasicStrategy(...));
*
*/
use(strategy: IStrategy): any;
use(name: string, strategy: IStrategy): any;
/**
* Un-utilize the `strategy` with given `name`.
*
* In typical applications, the necessary authentication strategies are static,
* configured once and always available. As such, there is often no need to
* invoke this function.
*
* However, in certain situations, applications may need dynamically configure
* and de-configure authentication strategies. The `use()`/`unuse()`
* combination satisfies these scenarios.
*
* Examples:
*
* passport.unuse('legacy-api');
*
*/
unuse(name: string): this;
/**
* Passport's primary initialization middleware.
*
* Intializes Passport for incoming requests, allowing
* authentication strategies to be applied.
*
* If sessions are being utilized, applications must set up Passport with
* functions to serialize a user into and out of a session. For example, a
* common pattern is to serialize just the user ID into the session (due to the
* fact that it is desirable to store the minimum amount of data in a session).
* When a subsequent request arrives for the session, the full User object can
* be loaded from the database by ID.
*
* Note that additional middleware is required to persist login state, so we
* must use the `connect.session()` middleware _before_ `passport.initialize()`.
*
* If sessions are being used, this middleware must be in use by the
* Koa application for Passport to operate. If the application is
* entirely stateless (not using sessions), this middleware is not necessary,
* but its use will not have any adverse impact.
*
* Options:
* - `userProperty` Property to set on `ctx.state` upon login, defaults to _user_
*
* Examples:
* app.use(connect.cookieParser());
*
* app.use(connect.session({ secret: 'keyboard cat' }));
* app.use(passport.initialize());
* app.use(passport.initialize({ userProperty: 'currentUser' }));
* app.use(passport.session());
*
* passport.serializeUser(function(user, done) {
* done(null, user.id);
* });
*
* passport.deserializeUser(function(id, done) {
* User.findById(id, function (err, user) {
* done(err, user);
* });
* });
*
*/
initialize(options?: InitAuthOption): Middleware;
/**
* Authenticates requests.
*
* Applies the `name`ed strategy (or strategies) to the incoming request, in
* order to authenticate the request. If authentication is successful, the user
* will be logged in and populated at `ctx.request.state.user` and a session will be
* established by default. If authentication fails, an unauthorized response
* will be sent.
*
* Options:
* - `session` Save login state in session, defaults to _true_
* - `successRedirect` After successful login, redirect to given URL
* - `failureRedirect` After failed login, redirect to given URL
* - `assignProperty` Assign the object provided by the verify callback to given property
*
* An optional `callback` can be supplied to allow the application to overrride
* the default manner in which authentication attempts are handled. The
* callback has the following signature, where `user` will be set to the
* authenticated user on a successful authentication attempt, or `false`
* otherwise. An optional `info` argument will be passed, containing additional
* details provided by the strategy's verify callback.
*
* app.get('/protected', function(ctx, next) {
* passport.authenticate('local', function(err, user, info) {
* if (err) { return next(err) }
* if (!user) { return ctx.redirect('/signin') }
* ctx.redirect('/account');
* })(ctx, next);
* });
*
* Note that if a callback is supplied, it becomes the application's
* responsibility to log-in the user, establish a session, and otherwise perform
* the desired operations.
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' })(ctx);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return ctx.redirect('/login'); }
* ctx.end('Authenticated!');
* })(ctx);
*
* passport.authenticate('basic', { session: false })(ctx);
*
* app.get('/auth/twitter', passport.authenticate('twitter'), function(ctx) {
* // request will be redirected to Twitter
* });
*/
authenticate(strategyNames: string | string[], callback?: (this: void, err: Error, user?: any, info?: any, status?: any) => void): Middleware;
authenticate(strategyNames: string | string[], options: AuthenticateOption, callback?: (this: void, err: Error, user?: any, info?: any, status?: any) => void): Middleware;
/**
* Middleware that will authorize a third-party account using the given
* `strategy` name, with optional `options`.
*
* If authorization is successful, the result provided by the strategy's verify
* callback will be assigned to `ctx.state.account`. The existing login session and
* `ctx.state.user` will be unaffected.
*
* This function is particularly useful when connecting third-party accounts
* to the local account of a user that is currently authenticated.
*
* Examples:
*
* passport.authorize('twitter-authz', { failureRedirect: '/account' });
*/
authorize(strategy: string | string[], options?: AuthenticateOption, callback?: any): Middleware;
/**
* Middleware that will restore login state from a session.
*
* Web applications typically use sessions to maintain login state between
* requests. For example, a user will authenticate by entering credentials into
* a form which is submitted to the server. If the credentials are valid, a
* login session is established by setting a cookie containing a session
* identifier in the user's web browser. The web browser will send this cookie
* in subsequent requests to the server, allowing a session to be maintained.
*
* If sessions are being utilized, and a login session has been established,
* this middleware will populate `req.user` with the current user.
*
* Note that sessions are not strictly required for Passport to operate.
* However, as a general rule, most web applications will make use of sessions.
* An exception to this rule would be an API server, which expects each HTTP
* request to provide credentials in an Authorization header.
*
* Examples:
*
* app.use(connect.cookieParser());
* app.use(connect.session({ secret: 'keyboard cat' }));
* app.use(passport.initialize());
* app.use(passport.session());
*
* Options:
* - `pauseStream` Pause the request stream before deserializing the user
* object from the session. Defaults to _false_. Should
* be set to true in cases where middleware consuming the
* request body is configured after passport and the
* deserializeUser method is asynchronous.
*
* @api public
*/
session(options?: AuthenticateOption): Middleware;
/**
* Registers a function used to serialize user objects into the session.
*
* Examples:
*
* passport.serializeUser(function(user, done) {
* done(null, user.id);
* });
*
* @api public
*/
serializeUser(fn: (user: any, ctx: Context) => Promise<any>): any;
serializeUser(user: object, ctx?: Context): Promise<any>;
/**
* Registers a function used to deserialize user objects out of the session.
*
* Examples:
*
* passport.deserializeUser(function(id, done) {
* User.findById(id, function (err, user) {
* done(err, user);
* });
* });
*
* @api public
*/
deserializeUser(fn: (obj: any, ctx: Context) => Promise<any>): any;
deserializeUser(obj: any, ctx?: Context): Promise<any>;
/**
* Registers a function used to transform auth info.
*
* In some circumstances authorization details are contained in authentication
* credentials or loaded as part of verification.
*
* For example, when using bearer tokens for API authentication, the tokens may
* encode (either directly or indirectly in a database), details such as scope
* of access or the client to which the token was issued.
*
* Such authorization details should be enforced separately from authentication.
* Because Passport deals only with the latter, this is the responsiblity of
* middleware or routes further along the chain. However, it is not optimal to
* decode the same data or execute the same database query later. To avoid
* this, Passport accepts optional `info` along with the authenticated `user`
* in a strategy's `success()` action. This info is set at `req.authInfo`,
* where said later middlware or routes can access it.
*
* Optionally, applications can register transforms to proccess this info,
* which take effect prior to `req.authInfo` being set. This is useful, for
* example, when the info contains a client ID. The transform can load the
* client from the database and include the instance in the transformed info,
* allowing the full set of client properties to be convieniently accessed.
*
* If no transforms are registered, `info` supplied by the strategy will be left
* unmodified.
*
* Examples:
*
* passport.transformAuthInfo(function(info, done) {
* Client.findById(info.clientID, function (err, client) {
* info.client = client;
* done(err, info);
* });
* });
*
* @api public
*/
transformAuthInfo(fn: (info: any, ctx: Context) => Promise<any>): void;
transformAuthInfo(info: {
type: string;
message: string;
}, ctx: Context): any;
}