UNPKG

@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
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; }