UNPKG

payload

Version:

Node, React and MongoDB Headless CMS and Application Framework

205 lines (204 loc) • 25.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return _default; } }); const _jsonwebtoken = /*#__PURE__*/ _interop_require_default(require("jsonwebtoken")); const _utils = require("../../collections/operations/utils"); const _errors = require("../../errors"); const _afterRead = require("../../fields/hooks/afterRead"); const _commitTransaction = require("../../utilities/commitTransaction"); const _getCookieExpiration = /*#__PURE__*/ _interop_require_default(require("../../utilities/getCookieExpiration")); const _initTransaction = require("../../utilities/initTransaction"); const _killTransaction = require("../../utilities/killTransaction"); const _sanitizeInternalFields = /*#__PURE__*/ _interop_require_default(require("../../utilities/sanitizeInternalFields")); const _isLocked = /*#__PURE__*/ _interop_require_default(require("../isLocked")); const _authenticate = require("../strategies/local/authenticate"); const _incrementLoginAttempts = require("../strategies/local/incrementLoginAttempts"); const _resetLoginAttempts = require("../strategies/local/resetLoginAttempts"); const _getFieldsToSign = require("./getFieldsToSign"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } async function login(incomingArgs) { let args = incomingArgs; try { const shouldCommit = await (0, _initTransaction.initTransaction)(args.req); // ///////////////////////////////////// // beforeOperation - Collection // ///////////////////////////////////// await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook)=>{ await priorHook; args = await hook({ args, collection: args.collection?.config, context: args.req.context, operation: 'login', req: args.req }) || args; }, Promise.resolve()); const { collection: { config: collectionConfig }, data, depth, overrideAccess, req, req: { fallbackLocale, locale, payload, payload: { config, secret } }, showHiddenFields } = args; // ///////////////////////////////////// // Login // ///////////////////////////////////// const { email: unsanitizedEmail, password } = data; const email = unsanitizedEmail ? unsanitizedEmail.toLowerCase().trim() : null; let user = await payload.db.findOne({ collection: collectionConfig.slug, req, where: { email: { equals: email.toLowerCase() } } }); if (!user || args.collection.config.auth.verify && user._verified === false) { throw new _errors.AuthenticationError(req.t); } if (user && (0, _isLocked.default)(user.lockUntil)) { throw new _errors.LockedAuth(req.t); } const authResult = await (0, _authenticate.authenticateLocalStrategy)({ doc: user, password }); user = (0, _sanitizeInternalFields.default)(user); const maxLoginAttemptsEnabled = args.collection.config.auth.maxLoginAttempts > 0; if (!authResult) { if (maxLoginAttemptsEnabled) { await (0, _incrementLoginAttempts.incrementLoginAttempts)({ collection: collectionConfig, doc: user, payload: req.payload, req }); } if (shouldCommit) await (0, _commitTransaction.commitTransaction)(req); throw new _errors.AuthenticationError(req.t); } if (maxLoginAttemptsEnabled) { await (0, _resetLoginAttempts.resetLoginAttempts)({ collection: collectionConfig, doc: user, payload: req.payload, req }); } const fieldsToSign = (0, _getFieldsToSign.getFieldsToSign)({ collectionConfig, email, user }); await collectionConfig.hooks.beforeLogin.reduce(async (priorHook, hook)=>{ await priorHook; user = await hook({ collection: args.collection?.config, context: args.req.context, req: args.req, user }) || user; }, Promise.resolve()); const token = _jsonwebtoken.default.sign(fieldsToSign, secret, { expiresIn: collectionConfig.auth.tokenExpiration }); if (args.res) { const cookieOptions = { domain: undefined, expires: (0, _getCookieExpiration.default)(collectionConfig.auth.tokenExpiration), httpOnly: true, path: '/', sameSite: collectionConfig.auth.cookies.sameSite, secure: collectionConfig.auth.cookies.secure }; if (collectionConfig.auth.cookies.domain) cookieOptions.domain = collectionConfig.auth.cookies.domain; args.res.cookie(`${config.cookiePrefix}-token`, token, cookieOptions); } req.user = user; // ///////////////////////////////////// // afterLogin - Collection // ///////////////////////////////////// await collectionConfig.hooks.afterLogin.reduce(async (priorHook, hook)=>{ await priorHook; user = await hook({ collection: args.collection?.config, context: args.req.context, req: args.req, token, user }) || user; }, Promise.resolve()); // ///////////////////////////////////// // afterRead - Fields // ///////////////////////////////////// user = await (0, _afterRead.afterRead)({ collection: collectionConfig, context: req.context, depth, doc: user, fallbackLocale, global: null, locale, overrideAccess, req, showHiddenFields }); // ///////////////////////////////////// // afterRead - Collection // ///////////////////////////////////// await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook)=>{ await priorHook; user = await hook({ collection: args.collection?.config, context: req.context, doc: user, req }) || user; }, Promise.resolve()); // ///////////////////////////////////// // afterRead - Collection // ///////////////////////////////////// await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook)=>{ await priorHook; user = await hook({ collection: args.collection?.config, context: req.context, doc: user, req }) || user; }, Promise.resolve()); let result = { exp: _jsonwebtoken.default.decode(token).exp, token, user }; // ///////////////////////////////////// // afterOperation - Collection // ///////////////////////////////////// result = await (0, _utils.buildAfterOperation)({ args, collection: args.collection?.config, operation: 'login', result }); if (collectionConfig.auth.removeTokenFromResponses) { delete result.token; } // ///////////////////////////////////// // Return results // ///////////////////////////////////// if (shouldCommit) await (0, _commitTransaction.commitTransaction)(req); return result; } catch (error) { await (0, _killTransaction.killTransaction)(args.req); throw error; } } const _default = login; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdXRoL29wZXJhdGlvbnMvbG9naW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBDb29raWVPcHRpb25zLCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnXG5cbmltcG9ydCBqd3QgZnJvbSAnanNvbndlYnRva2VuJ1xuXG5pbXBvcnQgdHlwZSB7IEdlbmVyYXRlZFR5cGVzIH0gZnJvbSAnLi4vLi4vJ1xuaW1wb3J0IHR5cGUgeyBDb2xsZWN0aW9uIH0gZnJvbSAnLi4vLi4vY29sbGVjdGlvbnMvY29uZmlnL3R5cGVzJ1xuaW1wb3J0IHR5cGUgeyBQYXlsb2FkUmVxdWVzdCB9IGZyb20gJy4uLy4uL2V4cHJlc3MvdHlwZXMnXG5pbXBvcnQgdHlwZSB7IFVzZXIgfSBmcm9tICcuLi90eXBlcydcblxuaW1wb3J0IHsgYnVpbGRBZnRlck9wZXJhdGlvbiB9IGZyb20gJy4uLy4uL2NvbGxlY3Rpb25zL29wZXJhdGlvbnMvdXRpbHMnXG5pbXBvcnQgeyBBdXRoZW50aWNhdGlvbkVycm9yLCBMb2NrZWRBdXRoIH0gZnJvbSAnLi4vLi4vZXJyb3JzJ1xuaW1wb3J0IHsgYWZ0ZXJSZWFkIH0gZnJvbSAnLi4vLi4vZmllbGRzL2hvb2tzL2FmdGVyUmVhZCdcbmltcG9ydCB7IGNvbW1pdFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2NvbW1pdFRyYW5zYWN0aW9uJ1xuaW1wb3J0IGdldENvb2tpZUV4cGlyYXRpb24gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2dldENvb2tpZUV4cGlyYXRpb24nXG5pbXBvcnQgeyBpbml0VHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi91dGlsaXRpZXMvaW5pdFRyYW5zYWN0aW9uJ1xuaW1wb3J0IHsga2lsbFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2tpbGxUcmFuc2FjdGlvbidcbmltcG9ydCBzYW5pdGl6ZUludGVybmFsRmllbGRzIGZyb20gJy4uLy4uL3V0aWxpdGllcy9zYW5pdGl6ZUludGVybmFsRmllbGRzJ1xuaW1wb3J0IGlzTG9ja2VkIGZyb20gJy4uL2lzTG9ja2VkJ1xuaW1wb3J0IHsgYXV0aGVudGljYXRlTG9jYWxTdHJhdGVneSB9IGZyb20gJy4uL3N0cmF0ZWdpZXMvbG9jYWwvYXV0aGVudGljYXRlJ1xuaW1wb3J0IHsgaW5jcmVtZW50TG9naW5BdHRlbXB0cyB9IGZyb20gJy4uL3N0cmF0ZWdpZXMvbG9jYWwvaW5jcmVtZW50TG9naW5BdHRlbXB0cydcbmltcG9ydCB7IHJlc2V0TG9naW5BdHRlbXB0cyB9IGZyb20gJy4uL3N0cmF0ZWdpZXMvbG9jYWwvcmVzZXRMb2dpbkF0dGVtcHRzJ1xuaW1wb3J0IHsgZ2V0RmllbGRzVG9TaWduIH0gZnJvbSAnLi9nZXRGaWVsZHNUb1NpZ24nXG5cbmV4cG9ydCB0eXBlIFJlc3VsdCA9IHtcbiAgZXhwPzogbnVtYmVyXG4gIHRva2VuPzogc3RyaW5nXG4gIHVzZXI/OiBVc2VyXG59XG5cbmV4cG9ydCB0eXBlIEFyZ3VtZW50cyA9IHtcbiAgY29sbGVjdGlvbjogQ29sbGVjdGlvblxuICBkYXRhOiB7XG4gICAgZW1haWw6IHN0cmluZ1xuICAgIHBhc3N3b3JkOiBzdHJpbmdcbiAgfVxuICBkZXB0aD86IG51bWJlclxuICBvdmVycmlkZUFjY2Vzcz86IGJvb2xlYW5cbiAgcmVxOiBQYXlsb2FkUmVxdWVzdFxuICByZXM/OiBSZXNwb25zZVxuICBzaG93SGlkZGVuRmllbGRzPzogYm9vbGVhblxufVxuXG5hc3luYyBmdW5jdGlvbiBsb2dpbjxUU2x1ZyBleHRlbmRzIGtleW9mIEdlbmVyYXRlZFR5cGVzWydjb2xsZWN0aW9ucyddPihcbiAgaW5jb21pbmdBcmdzOiBBcmd1bWVudHMsXG4pOiBQcm9taXNlPFJlc3VsdCAmIHsgdXNlcjogR2VuZXJhdGVkVHlwZXNbJ2NvbGxlY3Rpb25zJ11bVFNsdWddIH0+IHtcbiAgbGV0IGFyZ3MgPSBpbmNvbWluZ0FyZ3NcblxuICB0cnkge1xuICAgIGNvbnN0IHNob3VsZENvbW1pdCA9IGF3YWl0IGluaXRUcmFuc2FjdGlvbihhcmdzLnJlcSlcblxuICAgIC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBiZWZvcmVPcGVyYXRpb24gLSBDb2xsZWN0aW9uXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgYXdhaXQgYXJncy5jb2xsZWN0aW9uLmNvbmZpZy5ob29rcy5iZWZvcmVPcGVyYXRpb24ucmVkdWNlKGFzeW5jIChwcmlvckhvb2ssIGhvb2spID0+IHtcbiAgICAgIGF3YWl0IHByaW9ySG9va1xuXG4gICAgICBhcmdzID1cbiAgICAgICAgKGF3YWl0IGhvb2soe1xuICAgICAgICAgIGFyZ3MsXG4gICAgICAgICAgY29sbGVjdGlvbjogYXJncy5jb2xsZWN0aW9uPy5jb25maWcsXG4gICAgICAgICAgY29udGV4dDogYXJncy5yZXEuY29udGV4dCxcbiAgICAgICAgICBvcGVyYXRpb246ICdsb2dpbicsXG4gICAgICAgICAgcmVxOiBhcmdzLnJlcSxcbiAgICAgICAgfSkpIHx8IGFyZ3NcbiAgICB9LCBQcm9taXNlLnJlc29sdmUoKSlcblxuICAgIGNvbnN0IHtcbiAgICAgIGNvbGxlY3Rpb246IHsgY29uZmlnOiBjb2xsZWN0aW9uQ29uZmlnIH0sXG4gICAgICBkYXRhLFxuICAgICAgZGVwdGgsXG4gICAgICBvdmVycmlkZUFjY2VzcyxcbiAgICAgIHJlcSxcbiAgICAgIHJlcToge1xuICAgICAgICBmYWxsYmFja0xvY2FsZSxcbiAgICAgICAgbG9jYWxlLFxuICAgICAgICBwYXlsb2FkLFxuICAgICAgICBwYXlsb2FkOiB7IGNvbmZpZywgc2VjcmV0IH0sXG4gICAgICB9LFxuICAgICAgc2hvd0hpZGRlbkZpZWxkcyxcbiAgICB9ID0gYXJnc1xuXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIExvZ2luXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgY29uc3QgeyBlbWFpbDogdW5zYW5pdGl6ZWRFbWFpbCwgcGFzc3dvcmQgfSA9IGRhdGFcblxuICAgIGNvbnN0IGVtYWlsID0gdW5zYW5pdGl6ZWRFbWFpbCA/IHVuc2FuaXRpemVkRW1haWwudG9Mb3dlckNhc2UoKS50cmltKCkgOiBudWxsXG5cbiAgICBsZXQgdXNlciA9IGF3YWl0IHBheWxvYWQuZGIuZmluZE9uZTxhbnk+KHtcbiAgICAgIGNvbGxlY3Rpb246IGNvbGxlY3Rpb25Db25maWcuc2x1ZyxcbiAgICAgIHJlcSxcbiAgICAgIHdoZXJlOiB7IGVtYWlsOiB7IGVxdWFsczogZW1haWwudG9Mb3dlckNhc2UoKSB9IH0sXG4gICAgfSlcblxuICAgIGlmICghdXNlciB8fCAoYXJncy5jb2xsZWN0aW9uLmNvbmZpZy5hdXRoLnZlcmlmeSAmJiB1c2VyLl92ZXJpZmllZCA9PT0gZmFsc2UpKSB7XG4gICAgICB0aHJvdyBuZXcgQXV0aGVudGljYXRpb25FcnJvcihyZXEudClcbiAgICB9XG5cbiAgICBpZiAodXNlciAmJiBpc0xvY2tlZCh1c2VyLmxvY2tVbnRpbCkpIHtcbiAgICAgIHRocm93IG5ldyBMb2NrZWRBdXRoKHJlcS50KVxuICAgIH1cblxuICAgIGNvbnN0IGF1dGhSZXN1bHQgPSBhd2FpdCBhdXRoZW50aWNhdGVMb2NhbFN0cmF0ZWd5KHsgZG9jOiB1c2VyLCBwYXNzd29yZCB9KVxuXG4gICAgdXNlciA9IHNhbml0aXplSW50ZXJuYWxGaWVsZHModXNlcilcblxuICAgIGNvbnN0IG1heExvZ2luQXR0ZW1wdHNFbmFibGVkID0gYXJncy5jb2xsZWN0aW9uLmNvbmZpZy5hdXRoLm1heExvZ2luQXR0ZW1wdHMgPiAwXG5cbiAgICBpZiAoIWF1dGhSZXN1bHQpIHtcbiAgICAgIGlmIChtYXhMb2dpbkF0dGVtcHRzRW5hYmxlZCkge1xuICAgICAgICBhd2FpdCBpbmNyZW1lbnRMb2dpbkF0dGVtcHRzKHtcbiAgICAgICAgICBjb2xsZWN0aW9uOiBjb2xsZWN0aW9uQ29uZmlnLFxuICAgICAgICAgIGRvYzogdXNlcixcbiAgICAgICAgICBwYXlsb2FkOiByZXEucGF5bG9hZCxcbiAgICAgICAgICByZXEsXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGlmIChzaG91bGRDb21taXQpIGF3YWl0IGNvbW1pdFRyYW5zYWN0aW9uKHJlcSlcblxuICAgICAgdGhyb3cgbmV3IEF1dGhlbnRpY2F0aW9uRXJyb3IocmVxLnQpXG4gICAgfVxuXG4gICAgaWYgKG1heExvZ2luQXR0ZW1wdHNFbmFibGVkKSB7XG4gICAgICBhd2FpdCByZXNldExvZ2luQXR0ZW1wdHMoe1xuICAgICAgICBjb2xsZWN0aW9uOiBjb2xsZWN0aW9uQ29uZmlnLFxuICAgICAgICBkb2M6IHVzZXIsXG4gICAgICAgIHBheWxvYWQ6IHJlcS5wYXlsb2FkLFxuICAgICAgICByZXEsXG4gICAgICB9KVxuICAgIH1cblxuICAgIGNvbnN0IGZpZWxkc1RvU2lnbiA9IGdldEZpZWxkc1RvU2lnbih7XG4gICAgICBjb2xsZWN0aW9uQ29uZmlnLFxuICAgICAgZW1haWwsXG4gICAgICB1c2VyLFxuICAgIH0pXG5cbiAgICBhd2FpdCBjb2xsZWN0aW9uQ29uZmlnLmhvb2tzLmJlZm9yZUxvZ2luLnJlZHVjZShhc3luYyAocHJpb3JIb29rLCBob29rKSA9PiB7XG4gICAgICBhd2FpdCBwcmlvckhvb2tcblxuICAgICAgdXNlciA9XG4gICAgICAgIChhd2FpdCBob29rKHtcbiAgICAgICAgICBjb2xsZWN0aW9uOiBhcmdzLmNvbGxlY3Rpb24/LmNvbmZpZyxcbiAgICAgICAgICBjb250ZXh0OiBhcmdzLnJlcS5jb250ZXh0LFxuICAgICAgICAgIHJlcTogYXJncy5yZXEsXG4gICAgICAgICAgdXNlcixcbiAgICAgICAgfSkpIHx8IHVzZXJcbiAgICB9LCBQcm9taXNlLnJlc29sdmUoKSlcblxuICAgIGNvbnN0IHRva2VuID0gand0LnNpZ24oZmllbGRzVG9TaWduLCBzZWNyZXQsIHtcbiAgICAgIGV4cGlyZXNJbjogY29sbGVjdGlvbkNvbmZpZy5hdXRoLnRva2VuRXhwaXJhdGlvbixcbiAgICB9KVxuXG4gICAgaWYgKGFyZ3MucmVzKSB7XG4gICAgICBjb25zdCBjb29raWVPcHRpb25zOiBDb29raWVPcHRpb25zID0ge1xuICAgICAgICBkb21haW46IHVuZGVmaW5lZCxcbiAgICAgICAgZXhwaXJlczogZ2V0Q29va2llRXhwaXJhdGlvbihjb2xsZWN0aW9uQ29uZmlnLmF1dGgudG9rZW5FeHBpcmF0aW9uKSxcbiAgICAgICAgaHR0cE9ubHk6IHRydWUsXG4gICAgICAgIHBhdGg6ICcvJyxcbiAgICAgICAgc2FtZVNpdGU6IGNvbGxlY3Rpb25Db25maWcuYXV0aC5jb29raWVzLnNhbWVTaXRlLFxuICAgICAgICBzZWN1cmU6IGNvbGxlY3Rpb25Db25maWcuYXV0aC5jb29raWVzLnNlY3VyZSxcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbGxlY3Rpb25Db25maWcuYXV0aC5jb29raWVzLmRvbWFpbilcbiAgICAgICAgY29va2llT3B0aW9ucy5kb21haW4gPSBjb2xsZWN0aW9uQ29uZmlnLmF1dGguY29va2llcy5kb21haW5cblxuICAgICAgYXJncy5yZXMuY29va2llKGAke2NvbmZpZy5jb29raWVQcmVmaXh9LXRva2VuYCwgdG9rZW4sIGNvb2tpZU9wdGlvbnMpXG4gICAgfVxuXG4gICAgcmVxLnVzZXIgPSB1c2VyXG5cbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gYWZ0ZXJMb2dpbiAtIENvbGxlY3Rpb25cbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICBhd2FpdCBjb2xsZWN0aW9uQ29uZmlnLmhvb2tzLmFmdGVyTG9naW4ucmVkdWNlKGFzeW5jIChwcmlvckhvb2ssIGhvb2spID0+IHtcbiAgICAgIGF3YWl0IHByaW9ySG9va1xuXG4gICAgICB1c2VyID1cbiAgICAgICAgKGF3YWl0IGhvb2soe1xuICAgICAgICAgIGNvbGxlY3Rpb246IGFyZ3MuY29sbGVjdGlvbj8uY29uZmlnLFxuICAgICAgICAgIGNvbnRleHQ6IGFyZ3MucmVxLmNvbnRleHQsXG4gICAgICAgICAgcmVxOiBhcmdzLnJlcSxcbiAgICAgICAgICB0b2tlbixcbiAgICAgICAgICB1c2VyLFxuICAgICAgICB9KSkgfHwgdXNlclxuICAgIH0sIFByb21pc2UucmVzb2x2ZSgpKVxuXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIGFmdGVyUmVhZCAtIEZpZWxkc1xuICAgIC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgIHVzZXIgPSBhd2FpdCBhZnRlclJlYWQoe1xuICAgICAgY29sbGVjdGlvbjogY29sbGVjdGlvbkNvbmZpZyxcbiAgICAgIGNvbnRleHQ6IHJlcS5jb250ZXh0LFxuICAgICAgZGVwdGgsXG4gICAgICBkb2M6IHVzZXIsXG4gICAgICBmYWxsYmFja0xvY2FsZSxcbiAgICAgIGdsb2JhbDogbnVsbCxcbiAgICAgIGxvY2FsZSxcbiAgICAgIG92ZXJyaWRlQWNjZXNzLFxuICAgICAgcmVxLFxuICAgICAgc2hvd0hpZGRlbkZpZWxkcyxcbiAgICB9KVxuXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIGFmdGVyUmVhZCAtIENvbGxlY3Rpb25cbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICBhd2FpdCBjb2xsZWN0aW9uQ29uZmlnLmhvb2tzLmFmdGVyUmVhZC5yZWR1Y2UoYXN5bmMgKHByaW9ySG9vaywgaG9vaykgPT4ge1xuICAgICAgYXdhaXQgcHJpb3JIb29rXG5cbiAgICAgIHVzZXIgPVxuICAgICAgICAoYXdhaXQgaG9vayh7XG4gICAgICAgICAgY29sbGVjdGlvbjogYXJncy5jb2xsZWN0aW9uPy5jb25maWcsXG4gICAgICAgICAgY29udGV4dDogcmVxLmNvbnRleHQsXG4gICAgICAgICAgZG9jOiB1c2VyLFxuICAgICAgICAgIHJlcSxcbiAgICAgICAgfSkpIHx8IHVzZXJcbiAgICB9LCBQcm9taXNlLnJlc29sdmUoKSlcblxuICAgIC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBhZnRlclJlYWQgLSBDb2xsZWN0aW9uXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgYXdhaXQgY29sbGVjdGlvbkNvbmZpZy5ob29rcy5hZnRlclJlYWQucmVkdWNlKGFzeW5jIChwcmlvckhvb2ssIGhvb2spID0+IHtcbiAgICAgIGF3YWl0IHByaW9ySG9va1xuXG4gICAgICB1c2VyID1cbiAgICAgICAgKGF3YWl0IGhvb2soe1xuICAgICAgICAgIGNvbGxlY3Rpb246IGFyZ3MuY29sbGVjdGlvbj8uY29uZmlnLFxuICAgICAgICAgIGNvbnRleHQ6IHJlcS5jb250ZXh0LFxuICAgICAgICAgIGRvYzogdXNlcixcbiAgICAgICAgICByZXEsXG4gICAgICAgIH0pKSB8fCB1c2VyXG4gICAgfSwgUHJvbWlzZS5yZXNvbHZlKCkpXG5cbiAgICBsZXQgcmVzdWx0OiBSZXN1bHQgJiB7IHVzZXI6IEdlbmVyYXRlZFR5cGVzWydjb2xsZWN0aW9ucyddW1RTbHVnXSB9ID0ge1xuICAgICAgZXhwOiAoand0LmRlY29kZSh0b2tlbikgYXMgand0Lkp3dFBheWxvYWQpLmV4cCxcbiAgICAgIHRva2VuLFxuICAgICAgdXNlcixcbiAgICB9XG5cbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gYWZ0ZXJPcGVyYXRpb24gLSBDb2xsZWN0aW9uXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgcmVzdWx0ID0gYXdhaXQgYnVpbGRBZnRlck9wZXJhdGlvbjxHZW5lcmF0ZWRUeXBlc1snY29sbGVjdGlvbnMnXVtUU2x1Z10+KHtcbiAgICAgIGFyZ3MsXG4gICAgICBjb2xsZWN0aW9uOiBhcmdzLmNvbGxlY3Rpb24/LmNvbmZpZyxcbiAgICAgIG9wZXJhdGlvbjogJ2xvZ2luJyxcbiAgICAgIHJlc3VsdCxcbiAgICB9KVxuXG4gICAgaWYgKGNvbGxlY3Rpb25Db25maWcuYXV0aC5yZW1vdmVUb2tlbkZyb21SZXNwb25zZXMpIHtcbiAgICAgIGRlbGV0ZSByZXN1bHQudG9rZW5cbiAgICB9XG5cbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gUmV0dXJuIHJlc3VsdHNcbiAgICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICBpZiAoc2hvdWxkQ29tbWl0KSBhd2FpdCBjb21taXRUcmFuc2FjdGlvbihyZXEpXG5cbiAgICByZXR1cm4gcmVzdWx0XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgYXdhaXQga2lsbFRyYW5zYWN0aW9uKGFyZ3MucmVxKVxuICAgIHRocm93IGVycm9yXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbG9naW5cbiJdLCJuYW1lcyI6WyJsb2dpbiIsImluY29taW5nQXJncyIsImFyZ3MiLCJzaG91bGRDb21taXQiLCJpbml0VHJhbnNhY3Rpb24iLCJyZXEiLCJjb2xsZWN0aW9uIiwiY29uZmlnIiwiaG9va3MiLCJiZWZvcmVPcGVyYXRpb24iLCJyZWR1Y2UiLCJwcmlvckhvb2siLCJob29rIiwiY29udGV4dCIsIm9wZXJhdGlvbiIsIlByb21pc2UiLCJyZXNvbHZlIiwiY29sbGVjdGlvbkNvbmZpZyIsImRhdGEiLCJkZXB0aCIsIm92ZXJyaWRlQWNjZXNzIiwiZmFsbGJhY2tMb2NhbGUiLCJsb2NhbGUiLCJwYXlsb2FkIiwic2VjcmV0Iiwic2hvd0hpZGRlbkZpZWxkcyIsImVtYWlsIiwidW5zYW5pdGl6ZWRFbWFpbCIsInBhc3N3b3JkIiwidG9Mb3dlckNhc2UiLCJ0cmltIiwidXNlciIsImRiIiwiZmluZE9uZSIsInNsdWciLCJ3aGVyZSIsImVxdWFscyIsImF1dGgiLCJ2ZXJpZnkiLCJfdmVyaWZpZWQiLCJBdXRoZW50aWNhdGlvbkVycm9yIiwidCIsImlzTG9ja2VkIiwibG9ja1VudGlsIiwiTG9ja2VkQXV0aCIsImF1dGhSZXN1bHQiLCJhdXRoZW50aWNhdGVMb2NhbFN0cmF0ZWd5IiwiZG9jIiwic2FuaXRpemVJbnRlcm5hbEZpZWxkcyIsIm1heExvZ2luQXR0ZW1wdHNFbmFibGVkIiwibWF4TG9naW5BdHRlbXB0cyIsImluY3JlbWVudExvZ2luQXR0ZW1wdHMiLCJjb21taXRUcmFuc2FjdGlvbiIsInJlc2V0TG9naW5BdHRlbXB0cyIsImZpZWxkc1RvU2lnbiIsImdldEZpZWxkc1RvU2lnbiIsImJlZm9yZUxvZ2luIiwidG9rZW4iLCJqd3QiLCJzaWduIiwiZXhwaXJlc0luIiwidG9rZW5FeHBpcmF0aW9uIiwicmVzIiwiY29va2llT3B0aW9ucyIsImRvbWFpbiIsInVuZGVmaW5lZCIsImV4cGlyZXMiLCJnZXRDb29raWVFeHBpcmF0aW9uIiwiaHR0cE9ubHkiLCJwYXRoIiwic2FtZVNpdGUiLCJjb29raWVzIiwic2VjdXJlIiwiY29va2llIiwiY29va2llUHJlZml4IiwiYWZ0ZXJMb2dpbiIsImFmdGVyUmVhZCIsImdsb2JhbCIsInJlc3VsdCIsImV4cCIsImRlY29kZSIsImJ1aWxkQWZ0ZXJPcGVyYXRpb24iLCJyZW1vdmVUb2tlbkZyb21SZXNwb25zZXMiLCJlcnJvciIsImtpbGxUcmFuc2FjdGlvbiJdLCJtYXBwaW5ncyI6Ijs7OzsrQkFrUkE7OztlQUFBOzs7cUVBaFJnQjt1QkFPb0I7d0JBQ1k7MkJBQ3RCO21DQUNROzRFQUNGO2lDQUNBO2lDQUNBOytFQUNHO2lFQUNkOzhCQUNxQjt3Q0FDSDtvQ0FDSjtpQ0FDSDs7Ozs7O0FBcUJoQyxlQUFlQSxNQUNiQyxZQUF1QjtJQUV2QixJQUFJQyxPQUFPRDtJQUVYLElBQUk7UUFDRixNQUFNRSxlQUFlLE1BQU1DLElBQUFBLGdDQUFlLEVBQUNGLEtBQUtHLEdBQUc7UUFFbkQsd0NBQXdDO1FBQ3hDLCtCQUErQjtRQUMvQix3Q0FBd0M7UUFFeEMsTUFBTUgsS0FBS0ksVUFBVSxDQUFDQyxNQUFNLENBQUNDLEtBQUssQ0FBQ0MsZUFBZSxDQUFDQyxNQUFNLENBQUMsT0FBT0MsV0FBV0M7WUFDMUUsTUFBTUQ7WUFFTlQsT0FDRSxBQUFDLE1BQU1VLEtBQUs7Z0JBQ1ZWO2dCQUNBSSxZQUFZSixLQUFLSSxVQUFVLEVBQUVDO2dCQUM3Qk0sU0FBU1gsS0FBS0csR0FBRyxDQUFDUSxPQUFPO2dCQUN6QkMsV0FBVztnQkFDWFQsS0FBS0gsS0FBS0csR0FBRztZQUNmLE1BQU9IO1FBQ1gsR0FBR2EsUUFBUUMsT0FBTztRQUVsQixNQUFNLEVBQ0pWLFlBQVksRUFBRUMsUUFBUVUsZ0JBQWdCLEVBQUUsRUFDeENDLElBQUksRUFDSkMsS0FBSyxFQUNMQyxjQUFjLEVBQ2RmLEdBQUcsRUFDSEEsS0FBSyxFQUNIZ0IsY0FBYyxFQUNkQyxNQUFNLEVBQ05DLE9BQU8sRUFDUEEsU0FBUyxFQUFFaEIsTUFBTSxFQUFFaUIsTUFBTSxFQUFFLEVBQzVCLEVBQ0RDLGdCQUFnQixFQUNqQixHQUFHdkI7UUFFSix3Q0FBd0M7UUFDeEMsUUFBUTtRQUNSLHdDQUF3QztRQUV4QyxNQUFNLEVBQUV3QixPQUFPQyxnQkFBZ0IsRUFBRUMsUUFBUSxFQUFFLEdBQUdWO1FBRTlDLE1BQU1RLFFBQVFDLG1CQUFtQkEsaUJBQWlCRSxXQUFXLEdBQUdDLElBQUksS0FBSztRQUV6RSxJQUFJQyxPQUFPLE1BQU1SLFFBQVFTLEVBQUUsQ0FBQ0MsT0FBTyxDQUFNO1lBQ3ZDM0IsWUFBWVcsaUJBQWlCaUIsSUFBSTtZQUNqQzdCO1lBQ0E4QixPQUFPO2dCQUFFVCxPQUFPO29CQUFFVSxRQUFRVixNQUFNRyxXQUFXO2dCQUFHO1lBQUU7UUFDbEQ7UUFFQSxJQUFJLENBQUNFLFFBQVM3QixLQUFLSSxVQUFVLENBQUNDLE1BQU0sQ0FBQzhCLElBQUksQ0FBQ0MsTUFBTSxJQUFJUCxLQUFLUSxTQUFTLEtBQUssT0FBUTtZQUM3RSxNQUFNLElBQUlDLDJCQUFtQixDQUFDbkMsSUFBSW9DLENBQUM7UUFDckM7UUFFQSxJQUFJVixRQUFRVyxJQUFBQSxpQkFBUSxFQUFDWCxLQUFLWSxTQUFTLEdBQUc7WUFDcEMsTUFBTSxJQUFJQyxrQkFBVSxDQUFDdkMsSUFBSW9DLENBQUM7UUFDNUI7UUFFQSxNQUFNSSxhQUFhLE1BQU1DLElBQUFBLHVDQUF5QixFQUFDO1lBQUVDLEtBQUtoQjtZQUFNSDtRQUFTO1FBRXpFRyxPQUFPaUIsSUFBQUEsK0JBQXNCLEVBQUNqQjtRQUU5QixNQUFNa0IsMEJBQTBCL0MsS0FBS0ksVUFBVSxDQUFDQyxNQUFNLENBQUM4QixJQUFJLENBQUNhLGdCQUFnQixHQUFHO1FBRS9FLElBQUksQ0FBQ0wsWUFBWTtZQUNmLElBQUlJLHlCQUF5QjtnQkFDM0IsTUFBTUUsSUFBQUEsOENBQXNCLEVBQUM7b0JBQzNCN0MsWUFBWVc7b0JBQ1o4QixLQUFLaEI7b0JBQ0xSLFNBQVNsQixJQUFJa0IsT0FBTztvQkFDcEJsQjtnQkFDRjtZQUNGO1lBRUEsSUFBSUYsY0FBYyxNQUFNaUQsSUFBQUEsb0NBQWlCLEVBQUMvQztZQUUxQyxNQUFNLElBQUltQywyQkFBbUIsQ0FBQ25DLElBQUlvQyxDQUFDO1FBQ3JDO1FBRUEsSUFBSVEseUJBQXlCO1lBQzNCLE1BQU1JLElBQUFBLHNDQUFrQixFQUFDO2dCQUN2Qi9DLFlBQVlXO2dCQUNaOEIsS0FBS2hCO2dCQUNMUixTQUFTbEIsSUFBSWtCLE9BQU87Z0JBQ3BCbEI7WUFDRjtRQUNGO1FBRUEsTUFBTWlELGVBQWVDLElBQUFBLGdDQUFlLEVBQUM7WUFDbkN0QztZQUNBUztZQUNBSztRQUNGO1FBRUEsTUFBTWQsaUJBQWlCVCxLQUFLLENBQUNnRCxXQUFXLENBQUM5QyxNQUFNLENBQUMsT0FBT0MsV0FBV0M7WUFDaEUsTUFBTUQ7WUFFTm9CLE9BQ0UsQUFBQyxNQUFNbkIsS0FBSztnQkFDVk4sWUFBWUosS0FBS0ksVUFBVSxFQUFFQztnQkFDN0JNLFNBQVNYLEtBQUtHLEdBQUcsQ0FBQ1EsT0FBTztnQkFDekJSLEtBQUtILEtBQUtHLEdBQUc7Z0JBQ2IwQjtZQUNGLE1BQU9BO1FBQ1gsR0FBR2hCLFFBQVFDLE9BQU87UUFFbEIsTUFBTXlDLFFBQVFDLHFCQUFHLENBQUNDLElBQUksQ0FBQ0wsY0FBYzlCLFFBQVE7WUFDM0NvQyxXQUFXM0MsaUJBQWlCb0IsSUFBSSxDQUFDd0IsZUFBZTtRQUNsRDtRQUVBLElBQUkzRCxLQUFLNEQsR0FBRyxFQUFFO1lBQ1osTUFBTUMsZ0JBQStCO2dCQUNuQ0MsUUFBUUM7Z0JBQ1JDLFNBQVNDLElBQUFBLDRCQUFtQixFQUFDbEQsaUJBQWlCb0IsSUFBSSxDQUFDd0IsZUFBZTtnQkFDbEVPLFVBQVU7Z0JBQ1ZDLE1BQU07Z0JBQ05DLFVBQVVyRCxpQkFBaUJvQixJQUFJLENBQUNrQyxPQUFPLENBQUNELFFBQVE7Z0JBQ2hERSxRQUFRdkQsaUJBQWlCb0IsSUFBSSxDQUFDa0MsT0FBTyxDQUFDQyxNQUFNO1lBQzlDO1lBRUEsSUFBSXZELGlCQUFpQm9CLElBQUksQ0FBQ2tDLE9BQU8sQ0FBQ1AsTUFBTSxFQUN0Q0QsY0FBY0MsTUFBTSxHQUFHL0MsaUJBQWlCb0IsSUFBSSxDQUFDa0MsT0FBTyxDQUFDUCxNQUFNO1lBRTdEOUQsS0FBSzRELEdBQUcsQ0FBQ1csTUFBTSxDQUFDLENBQUMsRUFBRWxFLE9BQU9tRSxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUVqQixPQUFPTTtRQUN6RDtRQUVBMUQsSUFBSTBCLElBQUksR0FBR0E7UUFFWCx3Q0FBd0M7UUFDeEMsMEJBQTBCO1FBQzFCLHdDQUF3QztRQUV4QyxNQUFNZCxpQkFBaUJULEtBQUssQ0FBQ21FLFVBQVUsQ0FBQ2pFLE1BQU0sQ0FBQyxPQUFPQyxXQUFXQztZQUMvRCxNQUFNRDtZQUVOb0IsT0FDRSxBQUFDLE1BQU1uQixLQUFLO2dCQUNWTixZQUFZSixLQUFLSSxVQUFVLEVBQUVDO2dCQUM3Qk0sU0FBU1gsS0FBS0csR0FBRyxDQUFDUSxPQUFPO2dCQUN6QlIsS0FBS0gsS0FBS0csR0FBRztnQkFDYm9EO2dCQUNBMUI7WUFDRixNQUFPQTtRQUNYLEdBQUdoQixRQUFRQyxPQUFPO1FBRWxCLHdDQUF3QztRQUN4QyxxQkFBcUI7UUFDckIsd0NBQXdDO1FBRXhDZSxPQUFPLE1BQU02QyxJQUFBQSxvQkFBUyxFQUFDO1lBQ3JCdEUsWUFBWVc7WUFDWkosU0FBU1IsSUFBSVEsT0FBTztZQUNwQk07WUFDQTRCLEtBQUtoQjtZQUNMVjtZQUNBd0QsUUFBUTtZQUNSdkQ7WUFDQUY7WUFDQWY7WUFDQW9CO1FBQ0Y7UUFFQSx3Q0FBd0M7UUFDeEMseUJBQXlCO1FBQ3pCLHdDQUF3QztRQUV4QyxNQUFNUixpQkFBaUJULEtBQUssQ0FBQ29FLFNBQVMsQ0FBQ2xFLE1BQU0sQ0FBQyxPQUFPQyxXQUFXQztZQUM5RCxNQUFNRDtZQUVOb0IsT0FDRSxBQUFDLE1BQU1uQixLQUFLO2dCQUNWTixZQUFZSixLQUFLSSxVQUFVLEVBQUVDO2dCQUM3Qk0sU0FBU1IsSUFBSVEsT0FBTztnQkFDcEJrQyxLQUFLaEI7Z0JBQ0wxQjtZQUNGLE1BQU8wQjtRQUNYLEdBQUdoQixRQUFRQyxPQUFPO1FBRWxCLHdDQUF3QztRQUN4Qyx5QkFBeUI7UUFDekIsd0NBQXdDO1FBRXhDLE1BQU1DLGlCQUFpQlQsS0FBSyxDQUFDb0UsU0FBUyxDQUFDbEUsTUFBTSxDQUFDLE9BQU9DLFdBQVdDO1lBQzlELE1BQU1EO1lBRU5vQixPQUNFLEFBQUMsTUFBTW5CLEtBQUs7Z0JBQ1ZOLFlBQVlKLEtBQUtJLFVBQVUsRUFBRUM7Z0JBQzdCTSxTQUFTUixJQUFJUSxPQUFPO2dCQUNwQmtDLEtBQUtoQjtnQkFDTDFCO1lBQ0YsTUFBTzBCO1FBQ1gsR0FBR2hCLFFBQVFDLE9BQU87UUFFbEIsSUFBSThELFNBQWtFO1lBQ3BFQyxLQUFLLEFBQUNyQixxQkFBRyxDQUFDc0IsTUFBTSxDQUFDdkIsT0FBMEJzQixHQUFHO1lBQzlDdEI7WUFDQTFCO1FBQ0Y7UUFFQSx3Q0FBd0M7UUFDeEMsOEJBQThCO1FBQzlCLHdDQUF3QztRQUV4QytDLFNBQVMsTUFBTUcsSUFBQUEsMEJBQW1CLEVBQXVDO1lBQ3ZFL0U7WUFDQUksWUFBWUosS0FBS0ksVUFBVSxFQUFFQztZQUM3Qk8sV0FBVztZQUNYZ0U7UUFDRjtRQUVBLElBQUk3RCxpQkFBaUJvQixJQUFJLENBQUM2Qyx3QkFBd0IsRUFBRTtZQUNsRCxPQUFPSixPQUFPckIsS0FBSztRQUNyQjtRQUVBLHdDQUF3QztRQUN4QyxpQkFBaUI7UUFDakIsd0NBQXdDO1FBRXhDLElBQUl0RCxjQUFjLE1BQU1pRCxJQUFBQSxvQ0FBaUIsRUFBQy9DO1FBRTFDLE9BQU95RTtJQUNULEVBQUUsT0FBT0ssT0FBZ0I7UUFDdkIsTUFBTUMsSUFBQUEsZ0NBQWUsRUFBQ2xGLEtBQUtHLEdBQUc7UUFDOUIsTUFBTThFO0lBQ1I7QUFDRjtNQUVBLFdBQWVuRiJ9