UsersRouter.js 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = exports.UsersRouter = void 0;
  6. var _node = _interopRequireDefault(require("parse/node"));
  7. var _Config = _interopRequireDefault(require("../Config"));
  8. var _AccountLockout = _interopRequireDefault(require("../AccountLockout"));
  9. var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter"));
  10. var _rest = _interopRequireDefault(require("../rest"));
  11. var _Auth = _interopRequireDefault(require("../Auth"));
  12. var _password = _interopRequireDefault(require("../password"));
  13. var _triggers = require("../triggers");
  14. var _middlewares = require("../middlewares");
  15. var _RestWrite = _interopRequireDefault(require("../RestWrite"));
  16. var _logger = require("../logger");
  17. function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
  18. function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
  19. function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
  20. function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
  21. function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
  22. function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // These methods handle the User-related routes.
  23. class UsersRouter extends _ClassesRouter.default {
  24. className() {
  25. return '_User';
  26. }
  27. /**
  28. * Removes all "_" prefixed properties from an object, except "__type"
  29. * @param {Object} obj An object.
  30. */
  31. static removeHiddenProperties(obj) {
  32. for (var key in obj) {
  33. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  34. // Regexp comes from Parse.Object.prototype.validate
  35. if (key !== '__type' && !/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) {
  36. delete obj[key];
  37. }
  38. }
  39. }
  40. }
  41. /**
  42. * After retrieving a user directly from the database, we need to remove the
  43. * password from the object (for security), and fix an issue some SDKs have
  44. * with null values
  45. */
  46. _sanitizeAuthData(user) {
  47. delete user.password;
  48. // Sometimes the authData still has null on that keys
  49. // https://github.com/parse-community/parse-server/issues/935
  50. if (user.authData) {
  51. Object.keys(user.authData).forEach(provider => {
  52. if (user.authData[provider] === null) {
  53. delete user.authData[provider];
  54. }
  55. });
  56. if (Object.keys(user.authData).length == 0) {
  57. delete user.authData;
  58. }
  59. }
  60. }
  61. /**
  62. * Validates a password request in login and verifyPassword
  63. * @param {Object} req The request
  64. * @returns {Object} User object
  65. * @private
  66. */
  67. _authenticateUserFromRequest(req) {
  68. return new Promise((resolve, reject) => {
  69. // Use query parameters instead if provided in url
  70. let payload = req.body;
  71. if (!payload.username && req.query && req.query.username || !payload.email && req.query && req.query.email) {
  72. payload = req.query;
  73. }
  74. const {
  75. username,
  76. email,
  77. password,
  78. ignoreEmailVerification
  79. } = payload;
  80. // TODO: use the right error codes / descriptions.
  81. if (!username && !email) {
  82. throw new _node.default.Error(_node.default.Error.USERNAME_MISSING, 'username/email is required.');
  83. }
  84. if (!password) {
  85. throw new _node.default.Error(_node.default.Error.PASSWORD_MISSING, 'password is required.');
  86. }
  87. if (typeof password !== 'string' || email && typeof email !== 'string' || username && typeof username !== 'string') {
  88. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
  89. }
  90. let user;
  91. let isValidPassword = false;
  92. let query;
  93. if (email && username) {
  94. query = {
  95. email,
  96. username
  97. };
  98. } else if (email) {
  99. query = {
  100. email
  101. };
  102. } else {
  103. query = {
  104. $or: [{
  105. username
  106. }, {
  107. email: username
  108. }]
  109. };
  110. }
  111. return req.config.database.find('_User', query, {}, _Auth.default.maintenance(req.config)).then(results => {
  112. if (!results.length) {
  113. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
  114. }
  115. if (results.length > 1) {
  116. // corner case where user1 has username == user2 email
  117. req.config.loggerController.warn("There is a user which email is the same as another user's username, logging in based on username");
  118. user = results.filter(user => user.username === username)[0];
  119. } else {
  120. user = results[0];
  121. }
  122. return _password.default.compare(password, user.password);
  123. }).then(correct => {
  124. isValidPassword = correct;
  125. const accountLockoutPolicy = new _AccountLockout.default(user, req.config);
  126. return accountLockoutPolicy.handleLoginAttempt(isValidPassword);
  127. }).then(async () => {
  128. if (!isValidPassword) {
  129. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
  130. }
  131. // Ensure the user isn't locked out
  132. // A locked out user won't be able to login
  133. // To lock a user out, just set the ACL to `masterKey` only ({}).
  134. // Empty ACL is OK
  135. if (!req.auth.isMaster && user.ACL && Object.keys(user.ACL).length == 0) {
  136. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
  137. }
  138. // Create request object for verification functions
  139. const request = {
  140. master: req.auth.isMaster,
  141. ip: req.config.ip,
  142. installationId: req.auth.installationId,
  143. object: _node.default.User.fromJSON(Object.assign({
  144. className: '_User'
  145. }, user))
  146. };
  147. // If request doesn't use master or maintenance key with ignoring email verification
  148. if (!((req.auth.isMaster || req.auth.isMaintenance) && ignoreEmailVerification)) {
  149. // Get verification conditions which can be booleans or functions; the purpose of this async/await
  150. // structure is to avoid unnecessarily executing subsequent functions if previous ones fail in the
  151. // conditional statement below, as a developer may decide to execute expensive operations in them
  152. const verifyUserEmails = async () => req.config.verifyUserEmails === true || typeof req.config.verifyUserEmails === 'function' && (await Promise.resolve(req.config.verifyUserEmails(request))) === true;
  153. const preventLoginWithUnverifiedEmail = async () => req.config.preventLoginWithUnverifiedEmail === true || typeof req.config.preventLoginWithUnverifiedEmail === 'function' && (await Promise.resolve(req.config.preventLoginWithUnverifiedEmail(request))) === true;
  154. if ((await verifyUserEmails()) && (await preventLoginWithUnverifiedEmail()) && !user.emailVerified) {
  155. throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, 'User email is not verified.');
  156. }
  157. }
  158. this._sanitizeAuthData(user);
  159. return resolve(user);
  160. }).catch(error => {
  161. return reject(error);
  162. });
  163. });
  164. }
  165. handleMe(req) {
  166. if (!req.info || !req.info.sessionToken) {
  167. throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token');
  168. }
  169. const sessionToken = req.info.sessionToken;
  170. return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', {
  171. sessionToken
  172. }, {
  173. include: 'user'
  174. }, req.info.clientSDK, req.info.context).then(response => {
  175. if (!response.results || response.results.length == 0 || !response.results[0].user) {
  176. throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token');
  177. } else {
  178. const user = response.results[0].user;
  179. // Send token back on the login, because SDKs expect that.
  180. user.sessionToken = sessionToken;
  181. // Remove hidden properties.
  182. UsersRouter.removeHiddenProperties(user);
  183. return {
  184. response: user
  185. };
  186. }
  187. });
  188. }
  189. async handleLogIn(req) {
  190. const user = await this._authenticateUserFromRequest(req);
  191. const authData = req.body && req.body.authData;
  192. // Check if user has provided their required auth providers
  193. _Auth.default.checkIfUserHasProvidedConfiguredProvidersForLogin(req, authData, user.authData, req.config);
  194. let authDataResponse;
  195. let validatedAuthData;
  196. if (authData) {
  197. const res = await _Auth.default.handleAuthDataValidation(authData, new _RestWrite.default(req.config, req.auth, '_User', {
  198. objectId: user.objectId
  199. }, req.body, user, req.info.clientSDK, req.info.context), user);
  200. authDataResponse = res.authDataResponse;
  201. validatedAuthData = res.authData;
  202. }
  203. // handle password expiry policy
  204. if (req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) {
  205. let changedAt = user._password_changed_at;
  206. if (!changedAt) {
  207. // password was created before expiry policy was enabled.
  208. // simply update _User object so that it will start enforcing from now
  209. changedAt = new Date();
  210. req.config.database.update('_User', {
  211. username: user.username
  212. }, {
  213. _password_changed_at: _node.default._encode(changedAt)
  214. });
  215. } else {
  216. // check whether the password has expired
  217. if (changedAt.__type == 'Date') {
  218. changedAt = new Date(changedAt.iso);
  219. }
  220. // Calculate the expiry time.
  221. const expiresAt = new Date(changedAt.getTime() + 86400000 * req.config.passwordPolicy.maxPasswordAge);
  222. if (expiresAt < new Date())
  223. // fail of current time is past password expiry time
  224. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your password has expired. Please reset your password.');
  225. }
  226. }
  227. // Remove hidden properties.
  228. UsersRouter.removeHiddenProperties(user);
  229. await req.config.filesController.expandFilesInObject(req.config, user);
  230. // Before login trigger; throws if failure
  231. await (0, _triggers.maybeRunTrigger)(_triggers.Types.beforeLogin, req.auth, _node.default.User.fromJSON(Object.assign({
  232. className: '_User'
  233. }, user)), null, req.config, req.info.context);
  234. // If we have some new validated authData update directly
  235. if (validatedAuthData && Object.keys(validatedAuthData).length) {
  236. await req.config.database.update('_User', {
  237. objectId: user.objectId
  238. }, {
  239. authData: validatedAuthData
  240. }, {});
  241. }
  242. const {
  243. sessionData,
  244. createSession
  245. } = _RestWrite.default.createSession(req.config, {
  246. userId: user.objectId,
  247. createdWith: {
  248. action: 'login',
  249. authProvider: 'password'
  250. },
  251. installationId: req.info.installationId
  252. });
  253. user.sessionToken = sessionData.sessionToken;
  254. await createSession();
  255. const afterLoginUser = _node.default.User.fromJSON(Object.assign({
  256. className: '_User'
  257. }, user));
  258. await (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogin, _objectSpread(_objectSpread({}, req.auth), {}, {
  259. user: afterLoginUser
  260. }), afterLoginUser, null, req.config, req.info.context);
  261. if (authDataResponse) {
  262. user.authDataResponse = authDataResponse;
  263. }
  264. await req.config.authDataManager.runAfterFind(req, user.authData);
  265. return {
  266. response: user
  267. };
  268. }
  269. /**
  270. * This allows master-key clients to create user sessions without access to
  271. * user credentials. This enables systems that can authenticate access another
  272. * way (API key, app administrators) to act on a user's behalf.
  273. *
  274. * We create a new session rather than looking for an existing session; we
  275. * want this to work in situations where the user is logged out on all
  276. * devices, since this can be used by automated systems acting on the user's
  277. * behalf.
  278. *
  279. * For the moment, we're omitting event hooks and lockout checks, since
  280. * immediate use cases suggest /loginAs could be used for semantically
  281. * different reasons from /login
  282. */
  283. async handleLogInAs(req) {
  284. if (!req.auth.isMaster) {
  285. throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, 'master key is required');
  286. }
  287. const userId = req.body.userId || req.query.userId;
  288. if (!userId) {
  289. throw new _node.default.Error(_node.default.Error.INVALID_VALUE, 'userId must not be empty, null, or undefined');
  290. }
  291. const queryResults = await req.config.database.find('_User', {
  292. objectId: userId
  293. });
  294. const user = queryResults[0];
  295. if (!user) {
  296. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'user not found');
  297. }
  298. this._sanitizeAuthData(user);
  299. const {
  300. sessionData,
  301. createSession
  302. } = _RestWrite.default.createSession(req.config, {
  303. userId,
  304. createdWith: {
  305. action: 'login',
  306. authProvider: 'masterkey'
  307. },
  308. installationId: req.info.installationId
  309. });
  310. user.sessionToken = sessionData.sessionToken;
  311. await createSession();
  312. return {
  313. response: user
  314. };
  315. }
  316. handleVerifyPassword(req) {
  317. return this._authenticateUserFromRequest(req).then(user => {
  318. // Remove hidden properties.
  319. UsersRouter.removeHiddenProperties(user);
  320. return {
  321. response: user
  322. };
  323. }).catch(error => {
  324. throw error;
  325. });
  326. }
  327. async handleLogOut(req) {
  328. const success = {
  329. response: {}
  330. };
  331. if (req.info && req.info.sessionToken) {
  332. const records = await _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', {
  333. sessionToken: req.info.sessionToken
  334. }, undefined, req.info.clientSDK, req.info.context);
  335. if (records.results && records.results.length) {
  336. await _rest.default.del(req.config, _Auth.default.master(req.config), '_Session', records.results[0].objectId, req.info.context);
  337. await (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogout, req.auth, _node.default.Session.fromJSON(Object.assign({
  338. className: '_Session'
  339. }, records.results[0])), null, req.config);
  340. }
  341. }
  342. return success;
  343. }
  344. _throwOnBadEmailConfig(req) {
  345. try {
  346. _Config.default.validateEmailConfiguration({
  347. emailAdapter: req.config.userController.adapter,
  348. appName: req.config.appName,
  349. publicServerURL: req.config.publicServerURL,
  350. emailVerifyTokenValidityDuration: req.config.emailVerifyTokenValidityDuration,
  351. emailVerifyTokenReuseIfValid: req.config.emailVerifyTokenReuseIfValid
  352. });
  353. } catch (e) {
  354. if (typeof e === 'string') {
  355. // Maybe we need a Bad Configuration error, but the SDKs won't understand it. For now, Internal Server Error.
  356. throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'An appName, publicServerURL, and emailAdapter are required for password reset and email verification functionality.');
  357. } else {
  358. throw e;
  359. }
  360. }
  361. }
  362. async handleResetRequest(req) {
  363. this._throwOnBadEmailConfig(req);
  364. const {
  365. email
  366. } = req.body;
  367. if (!email) {
  368. throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email');
  369. }
  370. if (typeof email !== 'string') {
  371. throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string');
  372. }
  373. const userController = req.config.userController;
  374. try {
  375. await userController.sendPasswordResetEmail(email);
  376. return {
  377. response: {}
  378. };
  379. } catch (err) {
  380. if (err.code === _node.default.Error.OBJECT_NOT_FOUND) {
  381. var _req$config$passwordP;
  382. if (((_req$config$passwordP = req.config.passwordPolicy) === null || _req$config$passwordP === void 0 ? void 0 : _req$config$passwordP.resetPasswordSuccessOnInvalidEmail) ?? true) {
  383. return {
  384. response: {}
  385. };
  386. }
  387. err.message = `A user with that email does not exist.`;
  388. }
  389. throw err;
  390. }
  391. }
  392. async handleVerificationEmailRequest(req) {
  393. this._throwOnBadEmailConfig(req);
  394. const {
  395. email
  396. } = req.body;
  397. if (!email) {
  398. throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email');
  399. }
  400. if (typeof email !== 'string') {
  401. throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string');
  402. }
  403. const results = await req.config.database.find('_User', {
  404. email: email
  405. }, {}, _Auth.default.maintenance(req.config));
  406. if (!results.length || results.length < 1) {
  407. throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`);
  408. }
  409. const user = results[0];
  410. // remove password field, messes with saving on postgres
  411. delete user.password;
  412. if (user.emailVerified) {
  413. throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, `Email ${email} is already verified.`);
  414. }
  415. const userController = req.config.userController;
  416. const send = await userController.regenerateEmailVerifyToken(user, req.auth.isMaster, req.auth.installationId, req.ip);
  417. if (send) {
  418. userController.sendVerificationEmail(user, req);
  419. }
  420. return {
  421. response: {}
  422. };
  423. }
  424. async handleChallenge(req) {
  425. const {
  426. username,
  427. email,
  428. password,
  429. authData,
  430. challengeData
  431. } = req.body;
  432. // if username or email provided with password try to authenticate the user by username
  433. let user;
  434. if (username || email) {
  435. if (!password) {
  436. throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'You provided username or email, you need to also provide password.');
  437. }
  438. user = await this._authenticateUserFromRequest(req);
  439. }
  440. if (!challengeData) {
  441. throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'Nothing to challenge.');
  442. }
  443. if (typeof challengeData !== 'object') {
  444. throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'challengeData should be an object.');
  445. }
  446. let request;
  447. let parseUser;
  448. // Try to find user by authData
  449. if (authData) {
  450. if (typeof authData !== 'object') {
  451. throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'authData should be an object.');
  452. }
  453. if (user) {
  454. throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'You cannot provide username/email and authData, only use one identification method.');
  455. }
  456. if (Object.keys(authData).filter(key => authData[key].id).length > 1) {
  457. throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'You cannot provide more than one authData provider with an id.');
  458. }
  459. const results = await _Auth.default.findUsersWithAuthData(req.config, authData);
  460. try {
  461. if (!results[0] || results.length > 1) {
  462. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'User not found.');
  463. }
  464. // Find the provider used to find the user
  465. const provider = Object.keys(authData).find(key => authData[key].id);
  466. parseUser = _node.default.User.fromJSON(_objectSpread({
  467. className: '_User'
  468. }, results[0]));
  469. request = (0, _triggers.getRequestObject)(undefined, req.auth, parseUser, parseUser, req.config);
  470. request.isChallenge = true;
  471. // Validate authData used to identify the user to avoid brute-force attack on `id`
  472. const {
  473. validator
  474. } = req.config.authDataManager.getValidatorForProvider(provider);
  475. const validatorResponse = await validator(authData[provider], req, parseUser, request);
  476. if (validatorResponse && validatorResponse.validator) {
  477. await validatorResponse.validator();
  478. }
  479. } catch (e) {
  480. // Rewrite the error to avoid guess id attack
  481. _logger.logger.error(e);
  482. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'User not found.');
  483. }
  484. }
  485. if (!parseUser) {
  486. parseUser = user ? _node.default.User.fromJSON(_objectSpread({
  487. className: '_User'
  488. }, user)) : undefined;
  489. }
  490. if (!request) {
  491. request = (0, _triggers.getRequestObject)(undefined, req.auth, parseUser, parseUser, req.config);
  492. request.isChallenge = true;
  493. }
  494. const acc = {};
  495. // Execute challenge step-by-step with consistent order for better error feedback
  496. // and to avoid to trigger others challenges if one of them fails
  497. for (const provider of Object.keys(challengeData).sort()) {
  498. try {
  499. const authAdapter = req.config.authDataManager.getValidatorForProvider(provider);
  500. if (!authAdapter) {
  501. continue;
  502. }
  503. const {
  504. adapter: {
  505. challenge
  506. }
  507. } = authAdapter;
  508. if (typeof challenge === 'function') {
  509. const providerChallengeResponse = await challenge(challengeData[provider], authData && authData[provider], req.config.auth[provider], request);
  510. acc[provider] = providerChallengeResponse || true;
  511. }
  512. } catch (err) {
  513. const e = (0, _triggers.resolveError)(err, {
  514. code: _node.default.Error.SCRIPT_FAILED,
  515. message: 'Challenge failed. Unknown error.'
  516. });
  517. const userString = req.auth && req.auth.user ? req.auth.user.id : undefined;
  518. _logger.logger.error(`Failed running auth step challenge for ${provider} for user ${userString} with Error: ` + JSON.stringify(e), {
  519. authenticationStep: 'challenge',
  520. error: e,
  521. user: userString,
  522. provider
  523. });
  524. throw e;
  525. }
  526. }
  527. return {
  528. response: {
  529. challengeData: acc
  530. }
  531. };
  532. }
  533. mountRoutes() {
  534. this.route('GET', '/users', req => {
  535. return this.handleFind(req);
  536. });
  537. this.route('POST', '/users', _middlewares.promiseEnsureIdempotency, req => {
  538. return this.handleCreate(req);
  539. });
  540. this.route('GET', '/users/me', req => {
  541. return this.handleMe(req);
  542. });
  543. this.route('GET', '/users/:objectId', req => {
  544. return this.handleGet(req);
  545. });
  546. this.route('PUT', '/users/:objectId', _middlewares.promiseEnsureIdempotency, req => {
  547. return this.handleUpdate(req);
  548. });
  549. this.route('DELETE', '/users/:objectId', req => {
  550. return this.handleDelete(req);
  551. });
  552. this.route('GET', '/login', req => {
  553. return this.handleLogIn(req);
  554. });
  555. this.route('POST', '/login', req => {
  556. return this.handleLogIn(req);
  557. });
  558. this.route('POST', '/loginAs', req => {
  559. return this.handleLogInAs(req);
  560. });
  561. this.route('POST', '/logout', req => {
  562. return this.handleLogOut(req);
  563. });
  564. this.route('POST', '/requestPasswordReset', req => {
  565. return this.handleResetRequest(req);
  566. });
  567. this.route('POST', '/verificationEmailRequest', req => {
  568. return this.handleVerificationEmailRequest(req);
  569. });
  570. this.route('GET', '/verifyPassword', req => {
  571. return this.handleVerifyPassword(req);
  572. });
  573. this.route('POST', '/verifyPassword', req => {
  574. return this.handleVerifyPassword(req);
  575. });
  576. this.route('POST', '/challenge', req => {
  577. return this.handleChallenge(req);
  578. });
  579. }
  580. }
  581. exports.UsersRouter = UsersRouter;
  582. var _default = exports.default = UsersRouter;
  583. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbm9kZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX0NvbmZpZyIsIl9BY2NvdW50TG9ja291dCIsIl9DbGFzc2VzUm91dGVyIiwiX3Jlc3QiLCJfQXV0aCIsIl9wYXNzd29yZCIsIl90cmlnZ2VycyIsIl9taWRkbGV3YXJlcyIsIl9SZXN0V3JpdGUiLCJfbG9nZ2VyIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0Iiwib3duS2V5cyIsInIiLCJ0IiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiX3RvUHJvcGVydHlLZXkiLCJ2YWx1ZSIsImNvbmZpZ3VyYWJsZSIsIndyaXRhYmxlIiwiaSIsIl90b1ByaW1pdGl2ZSIsIlN5bWJvbCIsInRvUHJpbWl0aXZlIiwiY2FsbCIsIlR5cGVFcnJvciIsIlN0cmluZyIsIk51bWJlciIsIlVzZXJzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsInJlbW92ZUhpZGRlblByb3BlcnRpZXMiLCJvYmoiLCJrZXkiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsInRlc3QiLCJfc2FuaXRpemVBdXRoRGF0YSIsInVzZXIiLCJwYXNzd29yZCIsImF1dGhEYXRhIiwicHJvdmlkZXIiLCJfYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0IiwicmVxIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJwYXlsb2FkIiwiYm9keSIsInVzZXJuYW1lIiwicXVlcnkiLCJlbWFpbCIsImlnbm9yZUVtYWlsVmVyaWZpY2F0aW9uIiwiUGFyc2UiLCJFcnJvciIsIlVTRVJOQU1FX01JU1NJTkciLCJQQVNTV09SRF9NSVNTSU5HIiwiT0JKRUNUX05PVF9GT1VORCIsImlzVmFsaWRQYXNzd29yZCIsIiRvciIsImNvbmZpZyIsImRhdGFiYXNlIiwiZmluZCIsIkF1dGgiLCJtYWludGVuYW5jZSIsInRoZW4iLCJyZXN1bHRzIiwibG9nZ2VyQ29udHJvbGxlciIsIndhcm4iLCJwYXNzd29yZENyeXB0byIsImNvbXBhcmUiLCJjb3JyZWN0IiwiYWNjb3VudExvY2tvdXRQb2xpY3kiLCJBY2NvdW50TG9ja291dCIsImhhbmRsZUxvZ2luQXR0ZW1wdCIsImF1dGgiLCJpc01hc3RlciIsIkFDTCIsInJlcXVlc3QiLCJtYXN0ZXIiLCJpcCIsImluc3RhbGxhdGlvbklkIiwib2JqZWN0IiwiVXNlciIsImZyb21KU09OIiwiYXNzaWduIiwiaXNNYWludGVuYW5jZSIsInZlcmlmeVVzZXJFbWFpbHMiLCJwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIiwiZW1haWxWZXJpZmllZCIsIkVNQUlMX05PVF9GT1VORCIsImNhdGNoIiwiZXJyb3IiLCJoYW5kbGVNZSIsImluZm8iLCJzZXNzaW9uVG9rZW4iLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJyZXN0IiwiaW5jbHVkZSIsImNsaWVudFNESyIsImNvbnRleHQiLCJyZXNwb25zZSIsImhhbmRsZUxvZ0luIiwiY2hlY2tJZlVzZXJIYXNQcm92aWRlZENvbmZpZ3VyZWRQcm92aWRlcnNGb3JMb2dpbiIsImF1dGhEYXRhUmVzcG9uc2UiLCJ2YWxpZGF0ZWRBdXRoRGF0YSIsInJlcyIsImhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiIsIlJlc3RXcml0ZSIsIm9iamVjdElkIiwicGFzc3dvcmRQb2xpY3kiLCJtYXhQYXNzd29yZEFnZSIsImNoYW5nZWRBdCIsIl9wYXNzd29yZF9jaGFuZ2VkX2F0IiwiRGF0ZSIsInVwZGF0ZSIsIl9lbmNvZGUiLCJfX3R5cGUiLCJpc28iLCJleHBpcmVzQXQiLCJnZXRUaW1lIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsIm1heWJlUnVuVHJpZ2dlciIsIlRyaWdnZXJUeXBlcyIsImJlZm9yZUxvZ2luIiwic2Vzc2lvbkRhdGEiLCJjcmVhdGVTZXNzaW9uIiwidXNlcklkIiwiY3JlYXRlZFdpdGgiLCJhY3Rpb24iLCJhdXRoUHJvdmlkZXIiLCJhZnRlckxvZ2luVXNlciIsImFmdGVyTG9naW4iLCJhdXRoRGF0YU1hbmFnZXIiLCJydW5BZnRlckZpbmQiLCJoYW5kbGVMb2dJbkFzIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsIklOVkFMSURfVkFMVUUiLCJxdWVyeVJlc3VsdHMiLCJoYW5kbGVWZXJpZnlQYXNzd29yZCIsImhhbmRsZUxvZ091dCIsInN1Y2Nlc3MiLCJyZWNvcmRzIiwidW5kZWZpbmVkIiwiZGVsIiwiYWZ0ZXJMb2dvdXQiLCJTZXNzaW9uIiwiX3Rocm93T25CYWRFbWFpbENvbmZpZyIsIkNvbmZpZyIsInZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uIiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImhhbmRsZVJlc2V0UmVxdWVzdCIsIkVNQUlMX01JU1NJTkciLCJJTlZBTElEX0VNQUlMX0FERFJFU1MiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwiZXJyIiwiY29kZSIsIl9yZXEkY29uZmlnJHBhc3N3b3JkUCIsInJlc2V0UGFzc3dvcmRTdWNjZXNzT25JbnZhbGlkRW1haWwiLCJtZXNzYWdlIiwiaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0IiwiT1RIRVJfQ0FVU0UiLCJzZW5kIiwicmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4iLCJzZW5kVmVyaWZpY2F0aW9uRW1haWwiLCJoYW5kbGVDaGFsbGVuZ2UiLCJjaGFsbGVuZ2VEYXRhIiwicGFyc2VVc2VyIiwiaWQiLCJmaW5kVXNlcnNXaXRoQXV0aERhdGEiLCJnZXRSZXF1ZXN0T2JqZWN0IiwiaXNDaGFsbGVuZ2UiLCJ2YWxpZGF0b3IiLCJnZXRWYWxpZGF0b3JGb3JQcm92aWRlciIsInZhbGlkYXRvclJlc3BvbnNlIiwibG9nZ2VyIiwiYWNjIiwic29ydCIsImF1dGhBZGFwdGVyIiwiY2hhbGxlbmdlIiwicHJvdmlkZXJDaGFsbGVuZ2VSZXNwb25zZSIsInJlc29sdmVFcnJvciIsIlNDUklQVF9GQUlMRUQiLCJ1c2VyU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsImF1dGhlbnRpY2F0aW9uU3RlcCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJoYW5kbGVGaW5kIiwicHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlR2V0IiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIiwiZXhwb3J0cyIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL1JvdXRlcnMvVXNlcnNSb3V0ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhlc2UgbWV0aG9kcyBoYW5kbGUgdGhlIFVzZXItcmVsYXRlZCByb3V0ZXMuXG5cbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBDb25maWcgZnJvbSAnLi4vQ29uZmlnJztcbmltcG9ydCBBY2NvdW50TG9ja291dCBmcm9tICcuLi9BY2NvdW50TG9ja291dCc7XG5pbXBvcnQgQ2xhc3Nlc1JvdXRlciBmcm9tICcuL0NsYXNzZXNSb3V0ZXInO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5pbXBvcnQgQXV0aCBmcm9tICcuLi9BdXRoJztcbmltcG9ydCBwYXNzd29yZENyeXB0byBmcm9tICcuLi9wYXNzd29yZCc7XG5pbXBvcnQge1xuICBtYXliZVJ1blRyaWdnZXIsXG4gIFR5cGVzIGFzIFRyaWdnZXJUeXBlcyxcbiAgZ2V0UmVxdWVzdE9iamVjdCxcbiAgcmVzb2x2ZUVycm9yLFxufSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgeyBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kgfSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUmVzdFdyaXRlIGZyb20gJy4uL1Jlc3RXcml0ZSc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuXG5leHBvcnQgY2xhc3MgVXNlcnNSb3V0ZXIgZXh0ZW5kcyBDbGFzc2VzUm91dGVyIHtcbiAgY2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnX1VzZXInO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYWxsIFwiX1wiIHByZWZpeGVkIHByb3BlcnRpZXMgZnJvbSBhbiBvYmplY3QsIGV4Y2VwdCBcIl9fdHlwZVwiXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmogQW4gb2JqZWN0LlxuICAgKi9cbiAgc3RhdGljIHJlbW92ZUhpZGRlblByb3BlcnRpZXMob2JqKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgLy8gUmVnZXhwIGNvbWVzIGZyb20gUGFyc2UuT2JqZWN0LnByb3RvdHlwZS52YWxpZGF0ZVxuICAgICAgICBpZiAoa2V5ICE9PSAnX190eXBlJyAmJiAhL15bQS1aYS16XVswLTlBLVphLXpfXSokLy50ZXN0KGtleSkpIHtcbiAgICAgICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWZ0ZXIgcmV0cmlldmluZyBhIHVzZXIgZGlyZWN0bHkgZnJvbSB0aGUgZGF0YWJhc2UsIHdlIG5lZWQgdG8gcmVtb3ZlIHRoZVxuICAgKiBwYXNzd29yZCBmcm9tIHRoZSBvYmplY3QgKGZvciBzZWN1cml0eSksIGFuZCBmaXggYW4gaXNzdWUgc29tZSBTREtzIGhhdmVcbiAgICogd2l0aCBudWxsIHZhbHVlc1xuICAgKi9cbiAgX3Nhbml0aXplQXV0aERhdGEodXNlcikge1xuICAgIGRlbGV0ZSB1c2VyLnBhc3N3b3JkO1xuXG4gICAgLy8gU29tZXRpbWVzIHRoZSBhdXRoRGF0YSBzdGlsbCBoYXMgbnVsbCBvbiB0aGF0IGtleXNcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGFyc2UtY29tbXVuaXR5L3BhcnNlLXNlcnZlci9pc3N1ZXMvOTM1XG4gICAgaWYgKHVzZXIuYXV0aERhdGEpIHtcbiAgICAgIE9iamVjdC5rZXlzKHVzZXIuYXV0aERhdGEpLmZvckVhY2gocHJvdmlkZXIgPT4ge1xuICAgICAgICBpZiAodXNlci5hdXRoRGF0YVtwcm92aWRlcl0gPT09IG51bGwpIHtcbiAgICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHVzZXIuYXV0aERhdGEpLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGRlbGV0ZSB1c2VyLmF1dGhEYXRhO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBwYXNzd29yZCByZXF1ZXN0IGluIGxvZ2luIGFuZCB2ZXJpZnlQYXNzd29yZFxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFVzZXIgb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBVc2UgcXVlcnkgcGFyYW1ldGVycyBpbnN0ZWFkIGlmIHByb3ZpZGVkIGluIHVybFxuICAgICAgbGV0IHBheWxvYWQgPSByZXEuYm9keTtcbiAgICAgIGlmIChcbiAgICAgICAgKCFwYXlsb2FkLnVzZXJuYW1lICYmIHJlcS5xdWVyeSAmJiByZXEucXVlcnkudXNlcm5hbWUpIHx8XG4gICAgICAgICghcGF5bG9hZC5lbWFpbCAmJiByZXEucXVlcnkgJiYgcmVxLnF1ZXJ5LmVtYWlsKVxuICAgICAgKSB7XG4gICAgICAgIHBheWxvYWQgPSByZXEucXVlcnk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IHVzZXJuYW1lLCBlbWFpbCwgcGFzc3dvcmQsIGlnbm9yZUVtYWlsVmVyaWZpY2F0aW9uIH0gPSBwYXlsb2FkO1xuXG4gICAgICAvLyBUT0RPOiB1c2UgdGhlIHJpZ2h0IGVycm9yIGNvZGVzIC8gZGVzY3JpcHRpb25zLlxuICAgICAgaWYgKCF1c2VybmFtZSAmJiAhZW1haWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVTRVJOQU1FX01JU1NJTkcsICd1c2VybmFtZS9lbWFpbCBpcyByZXF1aXJlZC4nKTtcbiAgICAgIH1cbiAgICAgIGlmICghcGFzc3dvcmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlBBU1NXT1JEX01JU1NJTkcsICdwYXNzd29yZCBpcyByZXF1aXJlZC4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHBhc3N3b3JkICE9PSAnc3RyaW5nJyB8fFxuICAgICAgICAoZW1haWwgJiYgdHlwZW9mIGVtYWlsICE9PSAnc3RyaW5nJykgfHxcbiAgICAgICAgKHVzZXJuYW1lICYmIHR5cGVvZiB1c2VybmFtZSAhPT0gJ3N0cmluZycpXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgfVxuXG4gICAgICBsZXQgdXNlcjtcbiAgICAgIGxldCBpc1ZhbGlkUGFzc3dvcmQgPSBmYWxzZTtcbiAgICAgIGxldCBxdWVyeTtcbiAgICAgIGlmIChlbWFpbCAmJiB1c2VybmFtZSkge1xuICAgICAgICBxdWVyeSA9IHsgZW1haWwsIHVzZXJuYW1lIH07XG4gICAgICB9IGVsc2UgaWYgKGVtYWlsKSB7XG4gICAgICAgIHF1ZXJ5ID0geyBlbWFpbCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnkgPSB7ICRvcjogW3sgdXNlcm5hbWUgfSwgeyBlbWFpbDogdXNlcm5hbWUgfV0gfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgIC5maW5kKCdfVXNlcicsIHF1ZXJ5LCB7fSwgQXV0aC5tYWludGVuYW5jZShyZXEuY29uZmlnKSlcbiAgICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgICAgaWYgKCFyZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIC8vIGNvcm5lciBjYXNlIHdoZXJlIHVzZXIxIGhhcyB1c2VybmFtZSA9PSB1c2VyMiBlbWFpbFxuICAgICAgICAgICAgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLndhcm4oXG4gICAgICAgICAgICAgIFwiVGhlcmUgaXMgYSB1c2VyIHdoaWNoIGVtYWlsIGlzIHRoZSBzYW1lIGFzIGFub3RoZXIgdXNlcidzIHVzZXJuYW1lLCBsb2dnaW5nIGluIGJhc2VkIG9uIHVzZXJuYW1lXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB1c2VyID0gcmVzdWx0cy5maWx0ZXIodXNlciA9PiB1c2VyLnVzZXJuYW1lID09PSB1c2VybmFtZSlbMF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBwYXNzd29yZENyeXB0by5jb21wYXJlKHBhc3N3b3JkLCB1c2VyLnBhc3N3b3JkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oY29ycmVjdCA9PiB7XG4gICAgICAgICAgaXNWYWxpZFBhc3N3b3JkID0gY29ycmVjdDtcbiAgICAgICAgICBjb25zdCBhY2NvdW50TG9ja291dFBvbGljeSA9IG5ldyBBY2NvdW50TG9ja291dCh1c2VyLCByZXEuY29uZmlnKTtcbiAgICAgICAgICByZXR1cm4gYWNjb3VudExvY2tvdXRQb2xpY3kuaGFuZGxlTG9naW5BdHRlbXB0KGlzVmFsaWRQYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBpZiAoIWlzVmFsaWRQYXNzd29yZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBFbnN1cmUgdGhlIHVzZXIgaXNuJ3QgbG9ja2VkIG91dFxuICAgICAgICAgIC8vIEEgbG9ja2VkIG91dCB1c2VyIHdvbid0IGJlIGFibGUgdG8gbG9naW5cbiAgICAgICAgICAvLyBUbyBsb2NrIGEgdXNlciBvdXQsIGp1c3Qgc2V0IHRoZSBBQ0wgdG8gYG1hc3RlcktleWAgb25seSAgKHt9KS5cbiAgICAgICAgICAvLyBFbXB0eSBBQ0wgaXMgT0tcbiAgICAgICAgICBpZiAoIXJlcS5hdXRoLmlzTWFzdGVyICYmIHVzZXIuQUNMICYmIE9iamVjdC5rZXlzKHVzZXIuQUNMKS5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBDcmVhdGUgcmVxdWVzdCBvYmplY3QgZm9yIHZlcmlmaWNhdGlvbiBmdW5jdGlvbnNcbiAgICAgICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgbWFzdGVyOiByZXEuYXV0aC5pc01hc3RlcixcbiAgICAgICAgICAgIGlwOiByZXEuY29uZmlnLmlwLFxuICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5hdXRoLmluc3RhbGxhdGlvbklkLFxuICAgICAgICAgICAgb2JqZWN0OiBQYXJzZS5Vc2VyLmZyb21KU09OKE9iamVjdC5hc3NpZ24oeyBjbGFzc05hbWU6ICdfVXNlcicgfSwgdXNlcikpLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvLyBJZiByZXF1ZXN0IGRvZXNuJ3QgdXNlIG1hc3RlciBvciBtYWludGVuYW5jZSBrZXkgd2l0aCBpZ25vcmluZyBlbWFpbCB2ZXJpZmljYXRpb25cbiAgICAgICAgICBpZiAoISgocmVxLmF1dGguaXNNYXN0ZXIgfHwgcmVxLmF1dGguaXNNYWludGVuYW5jZSkgJiYgaWdub3JlRW1haWxWZXJpZmljYXRpb24pKSB7XG5cbiAgICAgICAgICAgIC8vIEdldCB2ZXJpZmljYXRpb24gY29uZGl0aW9ucyB3aGljaCBjYW4gYmUgYm9vbGVhbnMgb3IgZnVuY3Rpb25zOyB0aGUgcHVycG9zZSBvZiB0aGlzIGFzeW5jL2F3YWl0XG4gICAgICAgICAgICAvLyBzdHJ1Y3R1cmUgaXMgdG8gYXZvaWQgdW5uZWNlc3NhcmlseSBleGVjdXRpbmcgc3Vic2VxdWVudCBmdW5jdGlvbnMgaWYgcHJldmlvdXMgb25lcyBmYWlsIGluIHRoZVxuICAgICAgICAgICAgLy8gY29uZGl0aW9uYWwgc3RhdGVtZW50IGJlbG93LCBhcyBhIGRldmVsb3BlciBtYXkgZGVjaWRlIHRvIGV4ZWN1dGUgZXhwZW5zaXZlIG9wZXJhdGlvbnMgaW4gdGhlbVxuICAgICAgICAgICAgY29uc3QgdmVyaWZ5VXNlckVtYWlscyA9IGFzeW5jICgpID0+IHJlcS5jb25maWcudmVyaWZ5VXNlckVtYWlscyA9PT0gdHJ1ZSB8fCAodHlwZW9mIHJlcS5jb25maWcudmVyaWZ5VXNlckVtYWlscyA9PT0gJ2Z1bmN0aW9uJyAmJiBhd2FpdCBQcm9taXNlLnJlc29sdmUocmVxLmNvbmZpZy52ZXJpZnlVc2VyRW1haWxzKHJlcXVlc3QpKSA9PT0gdHJ1ZSk7XG4gICAgICAgICAgICBjb25zdCBwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsID0gYXN5bmMgKCkgPT4gcmVxLmNvbmZpZy5wcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsID09PSB0cnVlIHx8ICh0eXBlb2YgcmVxLmNvbmZpZy5wcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsID09PSAnZnVuY3Rpb24nICYmIGF3YWl0IFByb21pc2UucmVzb2x2ZShyZXEuY29uZmlnLnByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwocmVxdWVzdCkpID09PSB0cnVlKTtcbiAgICAgICAgICAgIGlmIChhd2FpdCB2ZXJpZnlVc2VyRW1haWxzKCkgJiYgYXdhaXQgcHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCgpICYmICF1c2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX05PVF9GT1VORCwgJ1VzZXIgZW1haWwgaXMgbm90IHZlcmlmaWVkLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX3Nhbml0aXplQXV0aERhdGEodXNlcik7XG5cbiAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh1c2VyKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVNZShyZXEpIHtcbiAgICBpZiAoIXJlcS5pbmZvIHx8ICFyZXEuaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICB9XG4gICAgY29uc3Qgc2Vzc2lvblRva2VuID0gcmVxLmluZm8uc2Vzc2lvblRva2VuO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuIH0sXG4gICAgICAgIHsgaW5jbHVkZTogJ3VzZXInIH0sXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCB8fCAhcmVzcG9uc2UucmVzdWx0c1swXS51c2VyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHVzZXIgPSByZXNwb25zZS5yZXN1bHRzWzBdLnVzZXI7XG4gICAgICAgICAgLy8gU2VuZCB0b2tlbiBiYWNrIG9uIHRoZSBsb2dpbiwgYmVjYXVzZSBTREtzIGV4cGVjdCB0aGF0LlxuICAgICAgICAgIHVzZXIuc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgICAgLy8gUmVtb3ZlIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICAgICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXModXNlcik7XG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVMb2dJbihyZXEpIHtcbiAgICBjb25zdCB1c2VyID0gYXdhaXQgdGhpcy5fYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSk7XG4gICAgY29uc3QgYXV0aERhdGEgPSByZXEuYm9keSAmJiByZXEuYm9keS5hdXRoRGF0YTtcbiAgICAvLyBDaGVjayBpZiB1c2VyIGhhcyBwcm92aWRlZCB0aGVpciByZXF1aXJlZCBhdXRoIHByb3ZpZGVyc1xuICAgIEF1dGguY2hlY2tJZlVzZXJIYXNQcm92aWRlZENvbmZpZ3VyZWRQcm92aWRlcnNGb3JMb2dpbihcbiAgICAgIHJlcSxcbiAgICAgIGF1dGhEYXRhLFxuICAgICAgdXNlci5hdXRoRGF0YSxcbiAgICAgIHJlcS5jb25maWdcbiAgICApO1xuXG4gICAgbGV0IGF1dGhEYXRhUmVzcG9uc2U7XG4gICAgbGV0IHZhbGlkYXRlZEF1dGhEYXRhO1xuICAgIGlmIChhdXRoRGF0YSkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgQXV0aC5oYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24oXG4gICAgICAgIGF1dGhEYXRhLFxuICAgICAgICBuZXcgUmVzdFdyaXRlKFxuICAgICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7IG9iamVjdElkOiB1c2VyLm9iamVjdElkIH0sXG4gICAgICAgICAgcmVxLmJvZHksXG4gICAgICAgICAgdXNlcixcbiAgICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgICApLFxuICAgICAgICB1c2VyXG4gICAgICApO1xuICAgICAgYXV0aERhdGFSZXNwb25zZSA9IHJlcy5hdXRoRGF0YVJlc3BvbnNlO1xuICAgICAgdmFsaWRhdGVkQXV0aERhdGEgPSByZXMuYXV0aERhdGE7XG4gICAgfVxuXG4gICAgLy8gaGFuZGxlIHBhc3N3b3JkIGV4cGlyeSBwb2xpY3lcbiAgICBpZiAocmVxLmNvbmZpZy5wYXNzd29yZFBvbGljeSAmJiByZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlKSB7XG4gICAgICBsZXQgY2hhbmdlZEF0ID0gdXNlci5fcGFzc3dvcmRfY2hhbmdlZF9hdDtcblxuICAgICAgaWYgKCFjaGFuZ2VkQXQpIHtcbiAgICAgICAgLy8gcGFzc3dvcmQgd2FzIGNyZWF0ZWQgYmVmb3JlIGV4cGlyeSBwb2xpY3kgd2FzIGVuYWJsZWQuXG4gICAgICAgIC8vIHNpbXBseSB1cGRhdGUgX1VzZXIgb2JqZWN0IHNvIHRoYXQgaXQgd2lsbCBzdGFydCBlbmZvcmNpbmcgZnJvbSBub3dcbiAgICAgICAgY2hhbmdlZEF0ID0gbmV3IERhdGUoKTtcbiAgICAgICAgcmVxLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7IHVzZXJuYW1lOiB1c2VyLnVzZXJuYW1lIH0sXG4gICAgICAgICAgeyBfcGFzc3dvcmRfY2hhbmdlZF9hdDogUGFyc2UuX2VuY29kZShjaGFuZ2VkQXQpIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIHBhc3N3b3JkIGhhcyBleHBpcmVkXG4gICAgICAgIGlmIChjaGFuZ2VkQXQuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICAgIGNoYW5nZWRBdCA9IG5ldyBEYXRlKGNoYW5nZWRBdC5pc28pO1xuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZXhwaXJ5IHRpbWUuXG4gICAgICAgIGNvbnN0IGV4cGlyZXNBdCA9IG5ldyBEYXRlKFxuICAgICAgICAgIGNoYW5nZWRBdC5nZXRUaW1lKCkgKyA4NjQwMDAwMCAqIHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2VcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGV4cGlyZXNBdCA8IG5ldyBEYXRlKCkpXG4gICAgICAgICAgLy8gZmFpbCBvZiBjdXJyZW50IHRpbWUgaXMgcGFzdCBwYXNzd29yZCBleHBpcnkgdGltZVxuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAnWW91ciBwYXNzd29yZCBoYXMgZXhwaXJlZC4gUGxlYXNlIHJlc2V0IHlvdXIgcGFzc3dvcmQuJ1xuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXModXNlcik7XG5cbiAgICBhd2FpdCByZXEuY29uZmlnLmZpbGVzQ29udHJvbGxlci5leHBhbmRGaWxlc0luT2JqZWN0KHJlcS5jb25maWcsIHVzZXIpO1xuXG4gICAgLy8gQmVmb3JlIGxvZ2luIHRyaWdnZXI7IHRocm93cyBpZiBmYWlsdXJlXG4gICAgYXdhaXQgbWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgVHJpZ2dlclR5cGVzLmJlZm9yZUxvZ2luLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICBQYXJzZS5Vc2VyLmZyb21KU09OKE9iamVjdC5hc3NpZ24oeyBjbGFzc05hbWU6ICdfVXNlcicgfSwgdXNlcikpLFxuICAgICAgbnVsbCxcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgKTtcblxuICAgIC8vIElmIHdlIGhhdmUgc29tZSBuZXcgdmFsaWRhdGVkIGF1dGhEYXRhIHVwZGF0ZSBkaXJlY3RseVxuICAgIGlmICh2YWxpZGF0ZWRBdXRoRGF0YSAmJiBPYmplY3Qua2V5cyh2YWxpZGF0ZWRBdXRoRGF0YSkubGVuZ3RoKSB7XG4gICAgICBhd2FpdCByZXEuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgeyBvYmplY3RJZDogdXNlci5vYmplY3RJZCB9LFxuICAgICAgICB7IGF1dGhEYXRhOiB2YWxpZGF0ZWRBdXRoRGF0YSB9LFxuICAgICAgICB7fVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBSZXN0V3JpdGUuY3JlYXRlU2Vzc2lvbihyZXEuY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHVzZXIub2JqZWN0SWQsXG4gICAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgICBhY3Rpb246ICdsb2dpbicsXG4gICAgICAgIGF1dGhQcm92aWRlcjogJ3Bhc3N3b3JkJyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICB1c2VyLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25EYXRhLnNlc3Npb25Ub2tlbjtcblxuICAgIGF3YWl0IGNyZWF0ZVNlc3Npb24oKTtcblxuICAgIGNvbnN0IGFmdGVyTG9naW5Vc2VyID0gUGFyc2UuVXNlci5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1VzZXInIH0sIHVzZXIpKTtcbiAgICBhd2FpdCBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYWZ0ZXJMb2dpbixcbiAgICAgIHsgLi4ucmVxLmF1dGgsIHVzZXI6IGFmdGVyTG9naW5Vc2VyIH0sXG4gICAgICBhZnRlckxvZ2luVXNlcixcbiAgICAgIG51bGwsXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG5cbiAgICBpZiAoYXV0aERhdGFSZXNwb25zZSkge1xuICAgICAgdXNlci5hdXRoRGF0YVJlc3BvbnNlID0gYXV0aERhdGFSZXNwb25zZTtcbiAgICB9XG4gICAgYXdhaXQgcmVxLmNvbmZpZy5hdXRoRGF0YU1hbmFnZXIucnVuQWZ0ZXJGaW5kKHJlcSwgdXNlci5hdXRoRGF0YSk7XG5cbiAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgYWxsb3dzIG1hc3Rlci1rZXkgY2xpZW50cyB0byBjcmVhdGUgdXNlciBzZXNzaW9ucyB3aXRob3V0IGFjY2VzcyB0b1xuICAgKiB1c2VyIGNyZWRlbnRpYWxzLiBUaGlzIGVuYWJsZXMgc3lzdGVtcyB0aGF0IGNhbiBhdXRoZW50aWNhdGUgYWNjZXNzIGFub3RoZXJcbiAgICogd2F5IChBUEkga2V5LCBhcHAgYWRtaW5pc3RyYXRvcnMpIHRvIGFjdCBvbiBhIHVzZXIncyBiZWhhbGYuXG4gICAqXG4gICAqIFdlIGNyZWF0ZSBhIG5ldyBzZXNzaW9uIHJhdGhlciB0aGFuIGxvb2tpbmcgZm9yIGFuIGV4aXN0aW5nIHNlc3Npb247IHdlXG4gICAqIHdhbnQgdGhpcyB0byB3b3JrIGluIHNpdHVhdGlvbnMgd2hlcmUgdGhlIHVzZXIgaXMgbG9nZ2VkIG91dCBvbiBhbGxcbiAgICogZGV2aWNlcywgc2luY2UgdGhpcyBjYW4gYmUgdXNlZCBieSBhdXRvbWF0ZWQgc3lzdGVtcyBhY3Rpbmcgb24gdGhlIHVzZXInc1xuICAgKiBiZWhhbGYuXG4gICAqXG4gICAqIEZvciB0aGUgbW9tZW50LCB3ZSdyZSBvbWl0dGluZyBldmVudCBob29rcyBhbmQgbG9ja291dCBjaGVja3MsIHNpbmNlXG4gICAqIGltbWVkaWF0ZSB1c2UgY2FzZXMgc3VnZ2VzdCAvbG9naW5BcyBjb3VsZCBiZSB1c2VkIGZvciBzZW1hbnRpY2FsbHlcbiAgICogZGlmZmVyZW50IHJlYXNvbnMgZnJvbSAvbG9naW5cbiAgICovXG4gIGFzeW5jIGhhbmRsZUxvZ0luQXMocmVxKSB7XG4gICAgaWYgKCFyZXEuYXV0aC5pc01hc3Rlcikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sICdtYXN0ZXIga2V5IGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlcklkID0gcmVxLmJvZHkudXNlcklkIHx8IHJlcS5xdWVyeS51c2VySWQ7XG4gICAgaWYgKCF1c2VySWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9WQUxVRSxcbiAgICAgICAgJ3VzZXJJZCBtdXN0IG5vdCBiZSBlbXB0eSwgbnVsbCwgb3IgdW5kZWZpbmVkJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeVJlc3VsdHMgPSBhd2FpdCByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBvYmplY3RJZDogdXNlcklkIH0pO1xuICAgIGNvbnN0IHVzZXIgPSBxdWVyeVJlc3VsdHNbMF07XG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ3VzZXIgbm90IGZvdW5kJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc2FuaXRpemVBdXRoRGF0YSh1c2VyKTtcblxuICAgIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IFJlc3RXcml0ZS5jcmVhdGVTZXNzaW9uKHJlcS5jb25maWcsIHtcbiAgICAgIHVzZXJJZCxcbiAgICAgIGNyZWF0ZWRXaXRoOiB7XG4gICAgICAgIGFjdGlvbjogJ2xvZ2luJyxcbiAgICAgICAgYXV0aFByb3ZpZGVyOiAnbWFzdGVya2V5JyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICB1c2VyLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25EYXRhLnNlc3Npb25Ub2tlbjtcblxuICAgIGF3YWl0IGNyZWF0ZVNlc3Npb24oKTtcblxuICAgIHJldHVybiB7IHJlc3BvbnNlOiB1c2VyIH07XG4gIH1cblxuICBoYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpIHtcbiAgICByZXR1cm4gdGhpcy5fYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSlcbiAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICAvLyBSZW1vdmUgaGlkZGVuIHByb3BlcnRpZXMuXG4gICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXModXNlcik7XG5cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlTG9nT3V0KHJlcSkge1xuICAgIGNvbnN0IHN1Y2Nlc3MgPSB7IHJlc3BvbnNlOiB7fSB9O1xuICAgIGlmIChyZXEuaW5mbyAmJiByZXEuaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIGNvbnN0IHJlY29yZHMgPSBhd2FpdCByZXN0LmZpbmQoXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLFxuICAgICAgICAnX1Nlc3Npb24nLFxuICAgICAgICB7IHNlc3Npb25Ub2tlbjogcmVxLmluZm8uc2Vzc2lvblRva2VuIH0sXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgcmVxLmluZm8uY2xpZW50U0RLLFxuICAgICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgICApO1xuICAgICAgaWYgKHJlY29yZHMucmVzdWx0cyAmJiByZWNvcmRzLnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgIGF3YWl0IHJlc3QuZGVsKFxuICAgICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICAgJ19TZXNzaW9uJyxcbiAgICAgICAgICByZWNvcmRzLnJlc3VsdHNbMF0ub2JqZWN0SWQsXG4gICAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBtYXliZVJ1blRyaWdnZXIoXG4gICAgICAgICAgVHJpZ2dlclR5cGVzLmFmdGVyTG9nb3V0LFxuICAgICAgICAgIHJlcS5hdXRoLFxuICAgICAgICAgIFBhcnNlLlNlc3Npb24uZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19TZXNzaW9uJyB9LCByZWNvcmRzLnJlc3VsdHNbMF0pKSxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIHJlcS5jb25maWdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN1Y2Nlc3M7XG4gIH1cblxuICBfdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSkge1xuICAgIHRyeSB7XG4gICAgICBDb25maWcudmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgICAgICBlbWFpbEFkYXB0ZXI6IHJlcS5jb25maWcudXNlckNvbnRyb2xsZXIuYWRhcHRlcixcbiAgICAgICAgYXBwTmFtZTogcmVxLmNvbmZpZy5hcHBOYW1lLFxuICAgICAgICBwdWJsaWNTZXJ2ZXJVUkw6IHJlcS5jb25maWcucHVibGljU2VydmVyVVJMLFxuICAgICAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjogcmVxLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICAgICAgZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZDogcmVxLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKHR5cGVvZiBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAvLyBNYXliZSB3ZSBuZWVkIGEgQmFkIENvbmZpZ3VyYXRpb24gZXJyb3IsIGJ1dCB0aGUgU0RLcyB3b24ndCB1bmRlcnN0YW5kIGl0LiBGb3Igbm93LCBJbnRlcm5hbCBTZXJ2ZXIgRXJyb3IuXG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgJ0FuIGFwcE5hbWUsIHB1YmxpY1NlcnZlclVSTCwgYW5kIGVtYWlsQWRhcHRlciBhcmUgcmVxdWlyZWQgZm9yIHBhc3N3b3JkIHJlc2V0IGFuZCBlbWFpbCB2ZXJpZmljYXRpb24gZnVuY3Rpb25hbGl0eS4nXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVJlc2V0UmVxdWVzdChyZXEpIHtcbiAgICB0aGlzLl90aHJvd09uQmFkRW1haWxDb25maWcocmVxKTtcblxuICAgIGNvbnN0IHsgZW1haWwgfSA9IHJlcS5ib2R5O1xuICAgIGlmICghZW1haWwpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9NSVNTSU5HLCAneW91IG11c3QgcHJvdmlkZSBhbiBlbWFpbCcpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGVtYWlsICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0VNQUlMX0FERFJFU1MsXG4gICAgICAgICd5b3UgbXVzdCBwcm92aWRlIGEgdmFsaWQgZW1haWwgc3RyaW5nJ1xuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB1c2VyQ29udHJvbGxlci5zZW5kUGFzc3dvcmRSZXNldEVtYWlsKGVtYWlsKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlOiB7fSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgaWYgKHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3k/LnJlc2V0UGFzc3dvcmRTdWNjZXNzT25JbnZhbGlkRW1haWwgPz8gdHJ1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXNwb25zZToge30sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlcnIubWVzc2FnZSA9IGBBIHVzZXIgd2l0aCB0aGF0IGVtYWlsIGRvZXMgbm90IGV4aXN0LmA7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSkge1xuICAgIHRoaXMuX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpO1xuXG4gICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHk7XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX01JU1NJTkcsICd5b3UgbXVzdCBwcm92aWRlIGFuIGVtYWlsJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUyxcbiAgICAgICAgJ3lvdSBtdXN0IHByb3ZpZGUgYSB2YWxpZCBlbWFpbCBzdHJpbmcnXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBlbWFpbDogZW1haWwgfSwge30sIEF1dGgubWFpbnRlbmFuY2UocmVxLmNvbmZpZykpO1xuICAgIGlmICghcmVzdWx0cy5sZW5ndGggfHwgcmVzdWx0cy5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTk9UX0ZPVU5ELCBgTm8gdXNlciBmb3VuZCB3aXRoIGVtYWlsICR7ZW1haWx9YCk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuXG4gICAgLy8gcmVtb3ZlIHBhc3N3b3JkIGZpZWxkLCBtZXNzZXMgd2l0aCBzYXZpbmcgb24gcG9zdGdyZXNcbiAgICBkZWxldGUgdXNlci5wYXNzd29yZDtcblxuICAgIGlmICh1c2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgYEVtYWlsICR7ZW1haWx9IGlzIGFscmVhZHkgdmVyaWZpZWQuYCk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIGNvbnN0IHNlbmQgPSBhd2FpdCB1c2VyQ29udHJvbGxlci5yZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbih1c2VyLCByZXEuYXV0aC5pc01hc3RlciwgcmVxLmF1dGguaW5zdGFsbGF0aW9uSWQsIHJlcS5pcCk7XG4gICAgaWYgKHNlbmQpIHtcbiAgICAgIHVzZXJDb250cm9sbGVyLnNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VyLCByZXEpO1xuICAgIH1cbiAgICByZXR1cm4geyByZXNwb25zZToge30gfTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUNoYWxsZW5nZShyZXEpIHtcbiAgICBjb25zdCB7IHVzZXJuYW1lLCBlbWFpbCwgcGFzc3dvcmQsIGF1dGhEYXRhLCBjaGFsbGVuZ2VEYXRhIH0gPSByZXEuYm9keTtcblxuICAgIC8vIGlmIHVzZXJuYW1lIG9yIGVtYWlsIHByb3ZpZGVkIHdpdGggcGFzc3dvcmQgdHJ5IHRvIGF1dGhlbnRpY2F0ZSB0aGUgdXNlciBieSB1c2VybmFtZVxuICAgIGxldCB1c2VyO1xuICAgIGlmICh1c2VybmFtZSB8fCBlbWFpbCkge1xuICAgICAgaWYgKCFwYXNzd29yZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsXG4gICAgICAgICAgJ1lvdSBwcm92aWRlZCB1c2VybmFtZSBvciBlbWFpbCwgeW91IG5lZWQgdG8gYWxzbyBwcm92aWRlIHBhc3N3b3JkLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHVzZXIgPSBhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKTtcbiAgICB9XG5cbiAgICBpZiAoIWNoYWxsZW5nZURhdGEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgJ05vdGhpbmcgdG8gY2hhbGxlbmdlLicpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY2hhbGxlbmdlRGF0YSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgJ2NoYWxsZW5nZURhdGEgc2hvdWxkIGJlIGFuIG9iamVjdC4nKTtcbiAgICB9XG5cbiAgICBsZXQgcmVxdWVzdDtcbiAgICBsZXQgcGFyc2VVc2VyO1xuXG4gICAgLy8gVHJ5IHRvIGZpbmQgdXNlciBieSBhdXRoRGF0YVxuICAgIGlmIChhdXRoRGF0YSkge1xuICAgICAgaWYgKHR5cGVvZiBhdXRoRGF0YSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCAnYXV0aERhdGEgc2hvdWxkIGJlIGFuIG9iamVjdC4nKTtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSxcbiAgICAgICAgICAnWW91IGNhbm5vdCBwcm92aWRlIHVzZXJuYW1lL2VtYWlsIGFuZCBhdXRoRGF0YSwgb25seSB1c2Ugb25lIGlkZW50aWZpY2F0aW9uIG1ldGhvZC4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChPYmplY3Qua2V5cyhhdXRoRGF0YSkuZmlsdGVyKGtleSA9PiBhdXRoRGF0YVtrZXldLmlkKS5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSxcbiAgICAgICAgICAnWW91IGNhbm5vdCBwcm92aWRlIG1vcmUgdGhhbiBvbmUgYXV0aERhdGEgcHJvdmlkZXIgd2l0aCBhbiBpZC4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBBdXRoLmZpbmRVc2Vyc1dpdGhBdXRoRGF0YShyZXEuY29uZmlnLCBhdXRoRGF0YSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghcmVzdWx0c1swXSB8fCByZXN1bHRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1VzZXIgbm90IGZvdW5kLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZpbmQgdGhlIHByb3ZpZGVyIHVzZWQgdG8gZmluZCB0aGUgdXNlclxuICAgICAgICBjb25zdCBwcm92aWRlciA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKS5maW5kKGtleSA9PiBhdXRoRGF0YVtrZXldLmlkKTtcblxuICAgICAgICBwYXJzZVVzZXIgPSBQYXJzZS5Vc2VyLmZyb21KU09OKHsgY2xhc3NOYW1lOiAnX1VzZXInLCAuLi5yZXN1bHRzWzBdIH0pO1xuICAgICAgICByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh1bmRlZmluZWQsIHJlcS5hdXRoLCBwYXJzZVVzZXIsIHBhcnNlVXNlciwgcmVxLmNvbmZpZyk7XG4gICAgICAgIHJlcXVlc3QuaXNDaGFsbGVuZ2UgPSB0cnVlO1xuICAgICAgICAvLyBWYWxpZGF0ZSBhdXRoRGF0YSB1c2VkIHRvIGlkZW50aWZ5IHRoZSB1c2VyIHRvIGF2b2lkIGJydXRlLWZvcmNlIGF0dGFjayBvbiBgaWRgXG4gICAgICAgIGNvbnN0IHsgdmFsaWRhdG9yIH0gPSByZXEuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5nZXRWYWxpZGF0b3JGb3JQcm92aWRlcihwcm92aWRlcik7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRvclJlc3BvbnNlID0gYXdhaXQgdmFsaWRhdG9yKGF1dGhEYXRhW3Byb3ZpZGVyXSwgcmVxLCBwYXJzZVVzZXIsIHJlcXVlc3QpO1xuICAgICAgICBpZiAodmFsaWRhdG9yUmVzcG9uc2UgJiYgdmFsaWRhdG9yUmVzcG9uc2UudmFsaWRhdG9yKSB7XG4gICAgICAgICAgYXdhaXQgdmFsaWRhdG9yUmVzcG9uc2UudmFsaWRhdG9yKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gUmV3cml0ZSB0aGUgZXJyb3IgdG8gYXZvaWQgZ3Vlc3MgaWQgYXR0YWNrXG4gICAgICAgIGxvZ2dlci5lcnJvcihlKTtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdVc2VyIG5vdCBmb3VuZC4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhcnNlVXNlcikge1xuICAgICAgcGFyc2VVc2VyID0gdXNlciA/IFBhcnNlLlVzZXIuZnJvbUpTT04oeyBjbGFzc05hbWU6ICdfVXNlcicsIC4uLnVzZXIgfSkgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKCFyZXF1ZXN0KSB7XG4gICAgICByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh1bmRlZmluZWQsIHJlcS5hdXRoLCBwYXJzZVVzZXIsIHBhcnNlVXNlciwgcmVxLmNvbmZpZyk7XG4gICAgICByZXF1ZXN0LmlzQ2hhbGxlbmdlID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgYWNjID0ge307XG4gICAgLy8gRXhlY3V0ZSBjaGFsbGVuZ2Ugc3RlcC1ieS1zdGVwIHdpdGggY29uc2lzdGVudCBvcmRlciBmb3IgYmV0dGVyIGVycm9yIGZlZWRiYWNrXG4gICAgLy8gYW5kIHRvIGF2b2lkIHRvIHRyaWdnZXIgb3RoZXJzIGNoYWxsZW5nZXMgaWYgb25lIG9mIHRoZW0gZmFpbHNcbiAgICBmb3IgKGNvbnN0IHByb3ZpZGVyIG9mIE9iamVjdC5rZXlzKGNoYWxsZW5nZURhdGEpLnNvcnQoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYXV0aEFkYXB0ZXIgPSByZXEuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5nZXRWYWxpZGF0b3JGb3JQcm92aWRlcihwcm92aWRlcik7XG4gICAgICAgIGlmICghYXV0aEFkYXB0ZXIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgYWRhcHRlcjogeyBjaGFsbGVuZ2UgfSxcbiAgICAgICAgfSA9IGF1dGhBZGFwdGVyO1xuICAgICAgICBpZiAodHlwZW9mIGNoYWxsZW5nZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGNvbnN0IHByb3ZpZGVyQ2hhbGxlbmdlUmVzcG9uc2UgPSBhd2FpdCBjaGFsbGVuZ2UoXG4gICAgICAgICAgICBjaGFsbGVuZ2VEYXRhW3Byb3ZpZGVyXSxcbiAgICAgICAgICAgIGF1dGhEYXRhICYmIGF1dGhEYXRhW3Byb3ZpZGVyXSxcbiAgICAgICAgICAgIHJlcS5jb25maWcuYXV0aFtwcm92aWRlcl0sXG4gICAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICAgKTtcbiAgICAgICAgICBhY2NbcHJvdmlkZXJdID0gcHJvdmlkZXJDaGFsbGVuZ2VSZXNwb25zZSB8fCB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc3QgZSA9IHJlc29sdmVFcnJvcihlcnIsIHtcbiAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELFxuICAgICAgICAgIG1lc3NhZ2U6ICdDaGFsbGVuZ2UgZmFpbGVkLiBVbmtub3duIGVycm9yLicsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB1c2VyU3RyaW5nID0gcmVxLmF1dGggJiYgcmVxLmF1dGgudXNlciA/IHJlcS5hdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG4gICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYXV0aCBzdGVwIGNoYWxsZW5nZSBmb3IgJHtwcm92aWRlcn0gZm9yIHVzZXIgJHt1c2VyU3RyaW5nfSB3aXRoIEVycm9yOiBgICtcbiAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGUpLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uU3RlcDogJ2NoYWxsZW5nZScsXG4gICAgICAgICAgICBlcnJvcjogZSxcbiAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICBwcm92aWRlcixcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHJlc3BvbnNlOiB7IGNoYWxsZW5nZURhdGE6IGFjYyB9IH07XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91c2VycycsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNyZWF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvdXNlcnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvdXNlcnMvOm9iamVjdElkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvbG9naW4nLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW4ocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9sb2dpbicsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dJbihyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ2luQXMnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW5BcyhyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ291dCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dPdXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yZXF1ZXN0UGFzc3dvcmRSZXNldCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNldFJlcXVlc3QocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92ZXJpZmljYXRpb25FbWFpbFJlcXVlc3QnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy92ZXJpZnlQYXNzd29yZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL3ZlcmlmeVBhc3N3b3JkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVZlcmlmeVBhc3N3b3JkKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvY2hhbGxlbmdlJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNoYWxsZW5nZShyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJzUm91dGVyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQSxJQUFBQSxLQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxlQUFBLEdBQUFILHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRyxjQUFBLEdBQUFKLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBSSxLQUFBLEdBQUFMLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBSyxLQUFBLEdBQUFOLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBTSxTQUFBLEdBQUFQLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBTyxTQUFBLEdBQUFQLE9BQUE7QUFNQSxJQUFBUSxZQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyxVQUFBLEdBQUFWLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBVSxPQUFBLEdBQUFWLE9BQUE7QUFBbUMsU0FBQUQsdUJBQUFZLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUFBQSxTQUFBRyxRQUFBSCxDQUFBLEVBQUFJLENBQUEsUUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLElBQUEsQ0FBQVAsQ0FBQSxPQUFBTSxNQUFBLENBQUFFLHFCQUFBLFFBQUFDLENBQUEs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QUFFLFFBQVEsRUFBRXpKLEdBQUcsSUFBSTtNQUNsQyxPQUFPLElBQUksQ0FBQzJELFdBQVcsQ0FBQzNELEdBQUcsQ0FBQztJQUM5QixDQUFDLENBQUM7SUFDRixJQUFJLENBQUN5SixLQUFLLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRXpKLEdBQUcsSUFBSTtNQUNwQyxPQUFPLElBQUksQ0FBQzZGLGFBQWEsQ0FBQzdGLEdBQUcsQ0FBQztJQUNoQyxDQUFDLENBQUM7SUFDRixJQUFJLENBQUN5SixLQUFLLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRXpKLEdBQUcsSUFBSTtNQUNuQyxPQUFPLElBQUksQ0FBQ2tHLFlBQVksQ0FBQ2xHLEdBQUcsQ0FBQztJQUMvQixDQUFDLENBQUM7SUFDRixJQUFJLENBQUN5SixLQUFLLENBQUMsTUFBTSxFQUFFLHVCQUF1QixFQUFFekosR0FBRyxJQUFJO01BQ2pELE9BQU8sSUFBSSxDQUFDb0gsa0JBQWtCLENBQUNwSCxHQUFHLENBQUM7SUFDckMsQ0FBQyxDQUFDO0lBQ0YsSUFBSSxDQUFDeUosS0FBSyxDQUFDLE1BQU0sRUFBRSwyQkFBMkIsRUFBRXpKLEdBQUcsSUFBSTtNQUNyRCxPQUFPLElBQUksQ0FBQzZILDhCQUE4QixDQUFDN0gsR0FBRyxDQUFDO0lBQ2pELENBQUMsQ0FBQztJQUNGLElBQUksQ0FBQ3lKLEtBQUssQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLEVBQUV6SixHQUFHLElBQUk7TUFDMUMsT0FBTyxJQUFJLENBQUNpRyxvQkFBb0IsQ0FBQ2pHLEdBQUcsQ0FBQztJQUN2QyxDQUFDLENBQUM7SUFDRixJQUFJLENBQUN5SixLQUFLLENBQUMsTUFBTSxFQUFFLGlCQUFpQixFQUFFekosR0FBRyxJQUFJO01BQzNDLE9BQU8sSUFBSSxDQUFDaUcsb0JBQW9CLENBQUNqRyxHQUFHLENBQUM7SUFDdkMsQ0FBQyxDQUFDO0lBQ0YsSUFBSSxDQUFDeUosS0FBSyxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUV6SixHQUFHLElBQUk7TUFDdEMsT0FBTyxJQUFJLENBQUNrSSxlQUFlLENBQUNsSSxHQUFHLENBQUM7SUFDbEMsQ0FBQyxDQUFDO0VBQ0o7QUFDRjtBQUFDZ0ssT0FBQSxDQUFBL0ssV0FBQSxHQUFBQSxXQUFBO0FBQUEsSUFBQWdMLFFBQUEsR0FBQUQsT0FBQSxDQUFBaE4sT0FBQSxHQUVjaUMsV0FBVyIsImlnbm9yZUxpc3QiOltdfQ==