UNPKG

@mvx/identity

Version:

identity is oidc for mvc, type-mvc is base on koa. Decorator, Ioc, AOP mvc framework on server.

1,474 lines (1,327 loc) 152 kB
'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var tslib = _interopDefault(require('tslib')); var mvc = _interopDefault(require('@mvx/mvc')); var ioc = _interopDefault(require('@tsdi/ioc')); var koaSession = _interopDefault(require('koa-session')); var components = _interopDefault(require('@tsdi/components')); var url = _interopDefault(require('url')); var jsonwebtoken = _interopDefault(require('jsonwebtoken')); var http = _interopDefault(require('http')); var boot = _interopDefault(require('@tsdi/boot')); var https = _interopDefault(require('https')); var querystring = _interopDefault(require('querystring')); var crypto = _interopDefault(require('crypto')); var webfinger = _interopDefault(require('webfinger')); var request = _interopDefault(require('request')); var aop = _interopDefault(require('@tsdi/aop')); var core = _interopDefault(require('@tsdi/core')); function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var NoOpenIDError_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.NoOpenIDError = void 0; var NoOpenIDError = /** @class */ (function (_super) { tslib.__extends(NoOpenIDError, _super); function NoOpenIDError(message, response) { var _this = _super.call(this, 400, message) || this; _this.response = response; return _this; } NoOpenIDError.ρAnn = function () { return { "name": "NoOpenIDError" }; }; return NoOpenIDError; }(mvc.HttpError)); exports.NoOpenIDError = NoOpenIDError; }); unwrapExports(NoOpenIDError_1); var NoOpenIDError_2 = NoOpenIDError_1.NoOpenIDError; var AuthenticationError_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.AuthenticationError = void 0; /** * error. * * @export * @class OIDCError * @extends {HttpError} */ var AuthenticationError = /** @class */ (function (_super) { tslib.__extends(AuthenticationError, _super); // tslint:disable-next-line: variable-name function AuthenticationError(status, message, error_description) { var _this = _super.call(this, status, message) || this; _this.error_description = error_description; _this.name = ioc.lang.getClassName(_this); _this.error = _this.message; _this.expose = status < 500; return _this; } AuthenticationError.ρAnn = function () { return { "name": "AuthenticationError" }; }; return AuthenticationError; }(mvc.HttpError)); exports.AuthenticationError = AuthenticationError; }); unwrapExports(AuthenticationError_1); var AuthenticationError_2 = AuthenticationError_1.AuthenticationError; var OIDCError_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.OIDCError = void 0; /** * error. * * @export * @class OIDCError * @extends {HttpError} */ var OIDCError = /** @class */ (function (_super) { tslib.__extends(OIDCError, _super); function OIDCError(message, code, uri, status) { var _this = _super.call(this, status, message) || this; _this.code = code; _this.uri = uri; if (!status) { switch (code) { case 'access_denied': status = 403; break; case 'server_error': status = 502; break; case 'temporarily_unavailable': status = 503; break; } } _this.expose = status < 500; return _this; } OIDCError.ρAnn = function () { return { "name": "OIDCError" }; }; return OIDCError; }(AuthenticationError_1.AuthenticationError)); exports.OIDCError = OIDCError; }); unwrapExports(OIDCError_1); var OIDCError_2 = OIDCError_1.OIDCError; var InvalidToken_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidToken = void 0; /** * invalid token. * * @export * @class InvalidToken * @extends {AuthenticationError} */ var InvalidToken = /** @class */ (function (_super) { tslib.__extends(InvalidToken, _super); function InvalidToken(detail) { var _this = _super.call(this, 401, 'invalid_token', 'invalid token provided') || this; _this.error_detail = detail; return _this; } InvalidToken.ρAnn = function () { return { "name": "InvalidToken" }; }; return InvalidToken; }(AuthenticationError_1.AuthenticationError)); exports.InvalidToken = InvalidToken; }); unwrapExports(InvalidToken_1); var InvalidToken_2 = InvalidToken_1.InvalidToken; var InvalidRequest_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidRequest = void 0; /** * invaild request error. * * @export * @class InvalidRequest * @extends {HttpError} */ var InvalidRequest = /** @class */ (function (_super) { tslib.__extends(InvalidRequest, _super); function InvalidRequest(description, status) { if (status === void 0) { status = 400; } return _super.call(this, status, '', description || 'request is invalid') || this; } InvalidRequest.ρAnn = function () { return { "name": "InvalidRequest" }; }; return InvalidRequest; }(AuthenticationError_1.AuthenticationError)); exports.InvalidRequest = InvalidRequest; }); unwrapExports(InvalidRequest_1); var InvalidRequest_2 = InvalidRequest_1.InvalidRequest; var InternalOAuthError_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.InternalOAuthError = void 0; /** * internal oauth error. * * @export * @class InternalOAuthError * @extends {AuthenticationError} */ var InternalOAuthError = /** @class */ (function (_super) { tslib.__extends(InternalOAuthError, _super); function InternalOAuthError(message, oauthError) { var _this = _super.call(this, 400, message) || this; _this.oauthError = oauthError; return _this; } InternalOAuthError.ρAnn = function () { return { "name": "InternalOAuthError" }; }; return InternalOAuthError; }(AuthenticationError_1.AuthenticationError)); exports.InternalOAuthError = InternalOAuthError; }); unwrapExports(InternalOAuthError_1); var InternalOAuthError_2 = InternalOAuthError_1.InternalOAuthError; var errors = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); tslib.__exportStar(NoOpenIDError_1, exports); tslib.__exportStar(AuthenticationError_1, exports); tslib.__exportStar(OIDCError_1, exports); tslib.__exportStar(InvalidToken_1, exports); tslib.__exportStar(InvalidRequest_1, exports); tslib.__exportStar(InternalOAuthError_1, exports); }); unwrapExports(errors); var SessionMiddleware_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.SessionMiddleware = exports.SessionStorage = void 0; /** * Session storage. */ var SessionStorage = /** @class */ (function () { function SessionStorage() { } SessionStorage.ρAnn = function () { return { "name": "SessionStorage", "params": { "get": ["key", "maxAge", "data"], "set": ["key", "sess", "maxAge", "data"], "destroy": ["key"] } }; }; SessionStorage = tslib.__decorate([ ioc.Abstract(), tslib.__metadata("design:paramtypes", []) ], SessionStorage); return SessionStorage; }()); exports.SessionStorage = SessionStorage; /** * session middleware. * * @export * @class SessionMiddleware * @extends {MvcMiddleware} */ var SessionMiddleware = /** @class */ (function (_super) { tslib.__extends(SessionMiddleware, _super); function SessionMiddleware() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.hasInit = false; return _this; } SessionMiddleware.prototype.getMiddleware = function (context, koa) { if (!this.hasInit && !this.middleware) { var sessCfg = context.getConfiguration().session || {}; this.hasInit = true; this.sessCfg = Object.assign(sessCfg, { key: 'typemvc:sess', /** (number || 'session') maxAge in ms (default is 1 days) */ /** 'session' will result in a cookie that expires when session/browser is closed */ /** Warning: If a session cookie is stolen, this cookie will never expire */ maxAge: 36000000, overwrite: true, httpOnly: true, signed: true, rolling: false /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. default is false **/ }, sessCfg); if (!this.sessCfg.store) { var storage = context.getContainer().getService(SessionStorage); if (storage) { this.sessCfg.store = storage; } } this.middleware = koaSession(this.sessCfg, koa); } return this.middleware; }; SessionMiddleware.prototype.execute = function (ctx, next) { var _a; return tslib.__awaiter(this, void 0, void 0, function () { var middleware, error, err_1; var _this = this; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: middleware = this.getMiddleware(ctx.mvcContext, ctx.app); _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, middleware(ctx, function () { return tslib.__awaiter(_this, void 0, void 0, function () { var err_2; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, next()]; case 1: _a.sent(); return [3 /*break*/, 3]; case 2: err_2 = _a.sent(); error = err_2; throw err_2; case 3: return [2 /*return*/]; } }); }); })]; case 2: return [2 /*return*/, _b.sent()]; case 3: err_1 = _b.sent(); if (err_1 === error) { throw err_1; } else { (_a = ctx.mvcContext.getLogManager().getLogger()) === null || _a === void 0 ? void 0 : _a.error(err_1); } return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; SessionMiddleware.ρAnn = function () { return { "name": "SessionMiddleware", "params": { "getMiddleware": ["context", "koa"], "execute": ["ctx", "next"] } }; }; SessionMiddleware = tslib.__decorate([ mvc.Middleware({ name: mvc.MiddlewareTypes.Session, before: mvc.MiddlewareTypes.Cors }) ], SessionMiddleware); return SessionMiddleware; }(mvc.MvcMiddleware)); exports.SessionMiddleware = SessionMiddleware; }); unwrapExports(SessionMiddleware_1); var SessionMiddleware_2 = SessionMiddleware_1.SessionMiddleware; var SessionMiddleware_3 = SessionMiddleware_1.SessionStorage; var IAuthenticator = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.AuthenticatorToken = void 0; /** * IAuthenticator token. */ exports.AuthenticatorToken = new ioc.InjectToken('Authenticator'); }); unwrapExports(IAuthenticator); var IAuthenticator_1 = IAuthenticator.AuthenticatorToken; var IStrategy = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); }); unwrapExports(IStrategy); var ValidationResult_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidationResult = void 0; /** * auth action * * @export * @class AuthAction */ var ValidationResult = /** @class */ (function () { function ValidationResult() { } ValidationResult.ρAnn = function () { return { "name": "ValidationResult" }; }; return ValidationResult; }()); exports.ValidationResult = ValidationResult; }); unwrapExports(ValidationResult_1); var ValidationResult_2 = ValidationResult_1.ValidationResult; var FailResult_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.FailResult = void 0; /** * Fail authentication, with optional `challenge` and `status`, defaulting * to 401. * * Strategies should return this action to fail an authentication attempt. * * @param {String} challenge * @param {Number} status * @api public */ var FailResult = /** @class */ (function (_super) { tslib.__extends(FailResult, _super); function FailResult(challenge, status) { var _this = _super.call(this) || this; _this.challenge = challenge; _this.status = status; return _this; } FailResult.prototype.action = function (ctx) { ctx.failures.push({ challenge: this.challenge, status: this.status }); }; FailResult.ρAnn = function () { return { "name": "FailResult" }; }; return FailResult; }(ValidationResult_1.ValidationResult)); exports.FailResult = FailResult; }); unwrapExports(FailResult_1); var FailResult_2 = FailResult_1.FailResult; var PassResult_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.PassResult = void 0; /** * Pass without making a success or fail decision. * * Under most circumstances, Strategies should not need to call this * function. It exists primarily to allow previous authentication state * to be restored, for example from an HTTP session. * */ var PassResult = /** @class */ (function (_super) { tslib.__extends(PassResult, _super); function PassResult() { return _super !== null && _super.apply(this, arguments) || this; } PassResult.prototype.action = function (ctx) { return true; }; PassResult.ρAnn = function () { return { "name": "PassResult" }; }; return PassResult; }(ValidationResult_1.ValidationResult)); exports.PassResult = PassResult; }); unwrapExports(PassResult_1); var PassResult_2 = PassResult_1.PassResult; var RedirectResult_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.RedirectResult = void 0; /** * Redirect to `url` with optional `status`, defaulting to 302. * * Strategies should return this function to redirect the user (via their * user agent) to a third-party website for authentication. * * @param {String} url * @param {Number} status * @api public */ var RedirectResult = /** @class */ (function (_super) { tslib.__extends(RedirectResult, _super); function RedirectResult(url, status) { if (status === void 0) { status = 302; } var _this = _super.call(this) || this; _this.url = url; _this.status = status; return _this; } /** * execute. * * @param {Context} ctx * @returns {Promise<void>} * @memberof RedirectResult */ RedirectResult.prototype.action = function (ctx) { ctx.status = this.status; ctx.redirect(this.url); }; RedirectResult.ρAnn = function () { return { "name": "RedirectResult" }; }; return RedirectResult; }(ValidationResult_1.ValidationResult)); exports.RedirectResult = RedirectResult; }); unwrapExports(RedirectResult_1); var RedirectResult_2 = RedirectResult_1.RedirectResult; var SuccessResult_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.SuccessResult = void 0; /** * Authenticate `user`, with optional `info`. * * Strategies should return this action to successfully authenticate a * user. `user` should be an object supplied by the application after it * has been given an opportunity to verify credentials. `info` is an * optional argument containing additional user information. This is * useful for third-party authentication strategies to pass profile * details. * * @param {Object} user * @param {Object} info * @api public */ var SuccessResult = /** @class */ (function (_super) { tslib.__extends(SuccessResult, _super); function SuccessResult(options, user, info) { var _this = _super.call(this) || this; _this.options = options; _this.user = user; _this.info = info; return _this; } SuccessResult.prototype.action = function (ctx, callback) { return tslib.__awaiter(this, void 0, void 0, function () { var user, info, msg, options, flash, type, _a, url; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: user = this.user; info = this.info || {}; if (callback) { return [2 /*return*/, callback(null, user, info)]; } options = this.options; if (options.successFlash) { flash = options.successFlash; if (typeof flash === 'string') { flash = { type: 'success', message: flash }; } flash.type = flash.type || 'success'; type = flash.type || info.type || 'success'; msg = flash.message || info.message || info; if (typeof msg === 'string') { ctx.session.flash = { type: type, message: msg }; } } if (options.successMessage) { if (!(info.type in ctx.session.message)) { ctx.session.message[info.type] = []; } ctx.session.message[info.type].push(info.message); } if (options.userProperty) { ctx.state[options.userProperty] = user; } return [4 /*yield*/, ctx.login(user)]; case 1: _b.sent(); if (!(options.authInfo !== false)) return [3 /*break*/, 3]; _a = ctx.state; return [4 /*yield*/, ctx.passport.transformAuthInfo(info, ctx)]; case 2: _a.authInfo = _b.sent(); _b.label = 3; case 3: if (options.successReturnToOrRedirect) { url = options.successReturnToOrRedirect; if (ctx.session && ctx.session.returnTo) { url = ctx.session.returnTo; delete ctx.session.returnTo; } return [2 /*return*/, ctx.redirect(url)]; } if (options.successRedirect) { return [2 /*return*/, ctx.redirect(options.successRedirect)]; } return [2 /*return*/]; } }); }); }; SuccessResult.ρAnn = function () { return { "name": "SuccessResult" }; }; return SuccessResult; }(ValidationResult_1.ValidationResult)); exports.SuccessResult = SuccessResult; }); unwrapExports(SuccessResult_1); var SuccessResult_2 = SuccessResult_1.SuccessResult; var results = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); tslib.__exportStar(ValidationResult_1, exports); tslib.__exportStar(FailResult_1, exports); tslib.__exportStar(PassResult_1, exports); tslib.__exportStar(RedirectResult_1, exports); tslib.__exportStar(SuccessResult_1, exports); tslib.__exportStar(ValidationResult_1, exports); }); unwrapExports(results); var Strategy_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.Strategy = void 0; var Strategy = /** @class */ (function () { function Strategy() { } Strategy.ρAnn = function () { return { "name": "Strategy", "params": { "authenticate": ["ctx", "options"] } }; }; tslib.__decorate([ components.Input(), tslib.__metadata("design:type", String) ], Strategy.prototype, "name", void 0); tslib.__decorate([ ioc.Inject(IAuthenticator.AuthenticatorToken), tslib.__metadata("design:type", Object) ], Strategy.prototype, "authenticator", void 0); Strategy = tslib.__decorate([ ioc.Abstract() ], Strategy); return Strategy; }()); exports.Strategy = Strategy; }); unwrapExports(Strategy_1); var Strategy_2 = Strategy_1.Strategy; var SessionStrategy_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.SessionStrategy = void 0; /** * session. * * @export * @class SessionStrategy * @extends {Strategy} */ var SessionStrategy = /** @class */ (function (_super) { tslib.__extends(SessionStrategy, _super); /** * `SessionStrategy` constructor. * */ function SessionStrategy() { var _this = _super.call(this) || this; _this.name = 'session'; return _this; } /** * Authenticate request based on the current session state. * * The session authentication strategy uses the session to restore any login * state across requests. If a login session has been established, `req.user` * will be populated with the current user. * * This strategy is registered automatically by Passport. * */ SessionStrategy.prototype.authenticate = function (ctx, options) { return tslib.__awaiter(this, void 0, void 0, function () { var su, user, property; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: if (!ctx.passport) { throw new Error('passport.initialize() middleware not in use'); } if (ctx.session.passport) { su = ctx.session.passport.user; } if (!(su || su === 0)) return [3 /*break*/, 2]; return [4 /*yield*/, ctx.passport.deserializeUser(su, ctx)]; case 1: user = _a.sent(); if (!user) { ctx.session.passport.user = undefined; return [2 /*return*/, new results.PassResult()]; } property = ctx.passport.userProperty; ctx.state[property] = user; _a.label = 2; case 2: return [2 /*return*/, new results.PassResult()]; } }); }); }; SessionStrategy.ρAnn = function () { return { "name": "SessionStrategy" }; }; return SessionStrategy; }(Strategy_1.Strategy)); exports.SessionStrategy = SessionStrategy; }); unwrapExports(SessionStrategy_1); var SessionStrategy_2 = SessionStrategy_1.SessionStrategy; var LocalStrategy_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.LocalStrategy = void 0; /** * Local authenticate strategy * * @export * @class LocalStrategy * @extends {Strategy} * @implements {AfterInit} */ var LocalStrategy = /** @class */ (function (_super) { tslib.__extends(LocalStrategy, _super); function LocalStrategy() { return _super !== null && _super.apply(this, arguments) || this; } LocalStrategy.prototype.onAfterInit = function () { return tslib.__awaiter(this, void 0, void 0, function () { return tslib.__generator(this, function (_a) { if (!this.name) { this.name = 'local'; } if (!this.usernameField) { this.usernameField = 'username'; } if (!this.passwordField) { this.passwordField = 'password'; } return [2 /*return*/]; }); }); }; LocalStrategy.prototype.authenticate = function (ctx, options) { return tslib.__awaiter(this, void 0, void 0, function () { var username, password, _a, user, info; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: username = ctx.request.body[this.usernameField] || ctx.query[this.usernameField]; password = ctx.request.body[this.passwordField] || ctx.query[this.passwordField]; return [4 /*yield*/, this.verify(username, password, ctx)]; case 1: _a = _b.sent(), user = _a.user, info = _a.info; if (!user) { // TODO, not sure 401 is the correct meaning return [2 /*return*/, new results.FailResult(info, 401)]; } return [2 /*return*/, new results.SuccessResult(options, user, info)]; } }); }); }; LocalStrategy.ρAnn = function () { return { "name": "LocalStrategy", "params": { "authenticate": ["ctx", "options"] } }; }; tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Function) ], LocalStrategy.prototype, "verify", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Object) ], LocalStrategy.prototype, "usernameField", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Object) ], LocalStrategy.prototype, "passwordField", void 0); LocalStrategy = tslib.__decorate([ components.Component({ selector: 'local' }) ], LocalStrategy); return LocalStrategy; }(Strategy_1.Strategy)); exports.LocalStrategy = LocalStrategy; }); unwrapExports(LocalStrategy_1); var LocalStrategy_2 = LocalStrategy_1.LocalStrategy; var JwtStrategy_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.JwtRequest = exports.JwtStrategy = void 0; /** * Jwt authenticate strategy */ var JwtStrategy = /** @class */ (function (_super) { tslib.__extends(JwtStrategy, _super); function JwtStrategy() { return _super !== null && _super.apply(this, arguments) || this; } JwtStrategy.prototype.onAfterInit = function () { return tslib.__awaiter(this, void 0, void 0, function () { var _this = this; return tslib.__generator(this, function (_a) { if (!this.name) { this.name = 'jwt'; } if (this.secretOrKey) { if (this.secretOrKeyProvider) { throw new TypeError('JwtStrategy has been given both a secretOrKey and a secretOrKeyProvider'); } this.secretOrKeyProvider = function (request, rawJwtToken) { return tslib.__awaiter(_this, void 0, void 0, function () { return tslib.__generator(this, function (_a) { return [2 /*return*/, this.secretOrKey]; }); }); }; } if (!this.secretOrKeyProvider) { throw new TypeError('JwtStrategy requires a secret or key'); } if (!this.verify) { throw new TypeError('JwtStrategy requires a verify'); } if (!this.jwtFromRequest) { throw new TypeError('JwtStrategy requires a function to retrieve jwt from requests (see option jwtFromRequest)'); } return [2 /*return*/]; }); }); }; JwtStrategy.prototype.authenticate = function (ctx, options) { return tslib.__awaiter(this, void 0, void 0, function () { var token, secretOrKey, _a, payload, _b, user, info; var _this = this; return tslib.__generator(this, function (_c) { switch (_c.label) { case 0: token = this.jwtFromRequest(ctx.request); if (!token) { return [2 /*return*/, new results.FailResult('No auth token', 401)]; } _a = this; return [4 /*yield*/, this.secretOrKeyProvider(ctx.request, token)]; case 1: secretOrKey = _a.secretOrKey = _c.sent(); return [4 /*yield*/, new Promise(function (r, j) { jsonwebtoken.verify(token, secretOrKey, { audience: _this.audience, issuer: _this.issuer, algorithms: _this.algorithms, ignoreExpiration: _this.ignoreExpiration }, function (err, decoded) { if (err) { j(err); } else { r(decoded); } }); })]; case 2: payload = _c.sent(); return [4 /*yield*/, this.verify(payload, ctx)]; case 3: _b = _c.sent(), user = _b.user, info = _b.info; if (!user) { // TODO, not sure 401 is the correct meaning return [2 /*return*/, new results.FailResult(info, 401)]; } return [2 /*return*/, new results.SuccessResult(options, user, info)]; } }); }); }; JwtStrategy.prototype.sign = function (payload, secretOrKey, options) { var defer = ioc.PromiseUtil.defer(); jsonwebtoken.sign(payload, secretOrKey || this.secretOrKey, tslib.__assign({ audience: this.audience, issuer: this.issuer }, (options || {}) // ignoreExpiration: this.ignoreExpiration ), function (err, decoded) { if (err) { defer.reject(err); } else { defer.resolve(decoded); } }); return defer.promise; }; JwtStrategy.ρAnn = function () { return { "name": "JwtStrategy", "params": { "authenticate": ["ctx", "options"], "sign": ["payload", "secretOrKey", "options"] } }; }; tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Function) ], JwtStrategy.prototype, "verify", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", String) ], JwtStrategy.prototype, "issuer", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Object) ], JwtStrategy.prototype, "audience", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Array) ], JwtStrategy.prototype, "algorithms", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Boolean) ], JwtStrategy.prototype, "ignoreExpiration", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Object) ], JwtStrategy.prototype, "secretOrKey", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Function) ], JwtStrategy.prototype, "secretOrKeyProvider", void 0); tslib.__decorate([ components.Input(), tslib.__metadata("design:type", Function) ], JwtStrategy.prototype, "jwtFromRequest", void 0); JwtStrategy = tslib.__decorate([ components.Component({ selector: 'jwt' }) ], JwtStrategy); return JwtStrategy; }(Strategy_1.Strategy)); exports.JwtStrategy = JwtStrategy; var matcExp = /(\S+)\s+(\S+)/; function parseAuthHeader(hdrValue) { if (typeof hdrValue !== 'string') { return null; } var matches = hdrValue.match(matcExp); return matches && { scheme: matches[1], value: matches[2] }; } // Note: express http converts all headers // to lower case. var AUTH_HEADER = 'authorization', LEGACY_AUTH_SCHEME = 'JWT', BEARER_AUTH_SCHEME = 'bearer'; var JwtRequest; (function (JwtRequest) { function fromHeader(headerName) { return function (request) { var token = null; if (request.headers[headerName]) { token = request.headers[headerName]; } return token; }; } JwtRequest.fromHeader = fromHeader; function fromBodyField(fieldName) { return function (request) { var token = null; if (request.body && Object.prototype.hasOwnProperty.call(request.body, fieldName)) { token = request.body[fieldName]; } return token; }; } JwtRequest.fromBodyField = fromBodyField; function fromUrlQueryParameter(paramName) { return function (request) { var token = null, parsedUrl = url.parse(request.url, true); if (parsedUrl.query && Object.prototype.hasOwnProperty.call(parsedUrl.query, paramName)) { token = parsedUrl.query[paramName]; } return token; }; } JwtRequest.fromUrlQueryParameter = fromUrlQueryParameter; function fromAuthHeaderWithScheme(authScheme) { var authSchemeLower = authScheme.toLowerCase(); return function (request) { var token = null; if (request.headers[AUTH_HEADER]) { var authParams = parseAuthHeader(request.headers[AUTH_HEADER]); if (authParams && authSchemeLower === authParams.scheme.toLowerCase()) { token = authParams.value; } } return token; }; } JwtRequest.fromAuthHeaderWithScheme = fromAuthHeaderWithScheme; function fromAuthHeaderAsBearerToken() { return fromAuthHeaderWithScheme(BEARER_AUTH_SCHEME); } JwtRequest.fromAuthHeaderAsBearerToken = fromAuthHeaderAsBearerToken; function fromExtractors(extractors) { if (!Array.isArray(extractors)) { throw new TypeError('export function fromExtractors expects an array'); } return function (request) { var token = null; var index = 0; while (!token && index < length) { token = extractors[index].call(this, request); index++; } return token; }; } JwtRequest.fromExtractors = fromExtractors; /** * This extractor mimics the behavior of the v1.*.* extraction logic. * * This extractor exists only to provide an easy transition from the v1.*.* API to the v2.0.0 * API. * * This extractor first checks the auth header, if it doesn't find a token there then it checks the * specified body field and finally the url query parameters. * * @param options * authScheme: Expected scheme when JWT can be found in HTTP Authorize header. Default is JWT. * tokenBodyField: Field in request body containing token. Default is auth_token. * tokenQueryParameterName: Query parameter name containing the token. Default is auth_token. */ function versionOneCompatibility(options) { var authScheme = options.authScheme || LEGACY_AUTH_SCHEME, bodyField = options.tokenBodyField || 'auth_token', queryParam = options.tokenQueryParameterName || 'auth_token'; return function (request) { var authHeaderExtractor = fromAuthHeaderWithScheme(authScheme); var token = authHeaderExtractor(request); if (!token) { var bodyExtractor = fromBodyField(bodyField); token = bodyExtractor(request); } if (!token) { var queryExtractor = fromUrlQueryParameter(queryParam); token = queryExtractor(request); } return token; }; } JwtRequest.versionOneCompatibility = versionOneCompatibility; })(JwtRequest = exports.JwtRequest || (exports.JwtRequest = {})); }); unwrapExports(JwtStrategy_1); var JwtStrategy_2 = JwtStrategy_1.JwtRequest; var JwtStrategy_3 = JwtStrategy_1.JwtStrategy; var ContextExtends = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.contextExtends = void 0; /** * Intiate a login session for `user`. * * Options: * - `session` Save login state in session, defaults to `true` * * Examples: * * await req.logIn(user, { session: false }); * * @api public */ function login(user) { return tslib.__awaiter(this, void 0, void 0, function () { var property, obj, err_1; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: if (!this.passport) { throw new Error('passport.initialize() middleware not in use'); } property = (this.passport && this.passport.userProperty); this.state[property] = user; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, this.passport.serializeUser(user, this)]; case 2: obj = _a.sent(); return [3 /*break*/, 4]; case 3: err_1 = _a.sent(); this.state[property] = null; throw err_1; case 4: if (!this.session) { throw new Error('Should use session middleware before passport middleware'); } this.session.passport.user = obj; return [2 /*return*/]; } }); }); } /** * get current login user. * * @api public */ function getUser() { if (!this.passport || !this.session) { return null; } var property = this.passport.userProperty; return this.state[property]; } /** * get current login user roles. * * @api public */ function getRoles() { if (!this.passport || !this.session) { return null; } var property = this.passport.rolesProperty; return this.state[property]; } /** * Terminate an existing login session. * * @api public */ function logout() { if (!this.passport || !this.session) { return; } var property = this.passport.userProperty; delete this.state[property]; delete this.session.passport.user; } /** * Test if request is authenticated. * * @api public */ function isAuthenticated() { if (!this.passport) { return false; } var property = this.passport.userProperty; return (this.state[property]) ? true : false; } /** * Test if request is unauthenticated. * * @api public */ function isUnauthenticated() { return !this.isAuthenticated(); } function hasRole() { var roles = []; for (var _i = 0; _i < arguments.length; _i++) { roles[_i] = arguments[_i]; } if (!this.passport) { return false; } if (!roles.length) { return true; } var property = this.passport.rolesProperty; if ((this.state[property])) { return this.state[property].some(function (role) { return roles.indexOf(role) > 0; }); } return false; } /** * context extends. * * @export * @param {BaseContext} ctx * @returns {void} */ function contextExtends(ctx) { // add passport http.IncomingMessage extensions if (ctx.hasOwnProperty('login') || ctx.hasOwnProperty('logout') || ctx.hasOwnProperty('isAuthenticated') || ctx.hasOwnProperty('isUnauthenticated')) { return; } Object.defineProperties(ctx, { login: { value: login, writable: false, enumerable: false }, logout: { value: logout, writable: false, enumerable: false }, getUser: { value: getUser, writable: false, enumerable: false }, hasRole: { value: hasRole, writable: false, enumerable: false }, getRoles: { value: getRoles, writable: false, enumerable: false }, isAuthenticated: { value: isAuthenticated, writable: false, enumerable: false }, isUnauthenticated: { value: isUnauthenticated, writable: false, enumerable: false } }); } exports.contextExtends = contextExtends; }); unwrapExports(ContextExtends); var ContextExtends_1 = ContextExtends.contextExtends; var Authenticator_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.Authenticator = void 0; /** * `Authenticator` constructor. * */ var Authenticator = /** @class */ (function () { function Authenticator() { this._userProperty = 'user'; this._rolesProperty = 'roles'; this.strategies = new Map(); this.serializers = []; this.deserializers = []; this.infoTransformers = []; this.use(new SessionStrategy_1.SessionStrategy()); } Object.defineProperty(Authenticator.prototype, "userProperty", { get: function () { return this._userProperty; }, enumerable: false, configurable: true }); Object.defineProperty(Authenticator.prototype, "rolesProperty", { get: function () { return this._rolesProperty; }, enumerable: false, configurable: true }); /** * get strategy. * * @param {string} name * @returns {IStrategy} * @memberof IAuthenticator */ Authenticator.prototype.get = function (name) { return this.strategies.get(name); }; Authenticator.prototype.use = function (name, strategy) { if (strategy === undefined) { strategy = name; name = strategy.name; } if (!name) { throw new Error('Authentication strategies must have a name'); } this.strategies.set(name, strategy); return this; }; /** * 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'); * */ Authenticator.prototype.unuse = function (name) { this.strategies.delete(name); return 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); * }); * }); * */ Authenticator.prototype.initialize = function (options) { var _this = this; if (options === void 0) { options = {}; } this._userProperty = options.userProperty || 'user'; this._rolesProperty = options.rolesProperty || 'roles'; return function (ctx, next) { return tslib.__awaiter(_this, void 0, void 0, function () { var session; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: ctx.passport = this; session = ctx.session; if (!session) { throw new Error('Session middleware is needed with passport middleware!'); } if (!('passport' in session)) { ctx.session.passport = { user: undefined }; } if (!('message' in session)) { session.message = {}; } ctx.session = session; ContextExtends.contextExtends(ctx); return [4 /*yield*/, next()]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; }; Authenticator.prototype.authenticate = function (strategyNames, options, callback) { var _this = this; if (options === void 0) { options = {}; } if (ioc.isFunction(options)) { callback = options; options = {}; } var multi = true; // Cast `strategy` to an array, allowing authentication to pass through a chain of // strategies. The first strategy to succeed, redirect, or error will halt // the chain. Authentication failures will proceed through each strategy in // series, ultimately failing if all strategies fail. // // This is typically used on API endpoints to allow clients to authenticate // using their preferred choice of Basic, Digest, token-based schemes, etc. // It is not feasible to construct a chain of multiple strategies that involve // red