parse-server 2.8.4 → 8.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/LICENSE +167 -25
  2. package/NOTICE +10 -0
  3. package/README.md +929 -278
  4. package/lib/AccountLockout.js +47 -30
  5. package/lib/Adapters/AdapterLoader.js +21 -6
  6. package/lib/Adapters/Analytics/AnalyticsAdapter.js +15 -12
  7. package/lib/Adapters/Auth/AuthAdapter.js +116 -13
  8. package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +99 -0
  9. package/lib/Adapters/Auth/OAuth1Client.js +27 -46
  10. package/lib/Adapters/Auth/apple.js +123 -0
  11. package/lib/Adapters/Auth/facebook.js +162 -35
  12. package/lib/Adapters/Auth/gcenter.js +217 -0
  13. package/lib/Adapters/Auth/github.js +118 -48
  14. package/lib/Adapters/Auth/google.js +160 -51
  15. package/lib/Adapters/Auth/gpgames.js +125 -0
  16. package/lib/Adapters/Auth/httpsRequest.js +6 -7
  17. package/lib/Adapters/Auth/index.js +170 -62
  18. package/lib/Adapters/Auth/instagram.js +114 -40
  19. package/lib/Adapters/Auth/janraincapture.js +52 -23
  20. package/lib/Adapters/Auth/janrainengage.js +19 -36
  21. package/lib/Adapters/Auth/keycloak.js +148 -0
  22. package/lib/Adapters/Auth/ldap.js +167 -0
  23. package/lib/Adapters/Auth/line.js +125 -0
  24. package/lib/Adapters/Auth/linkedin.js +111 -55
  25. package/lib/Adapters/Auth/meetup.js +24 -34
  26. package/lib/Adapters/Auth/mfa.js +324 -0
  27. package/lib/Adapters/Auth/microsoft.js +111 -0
  28. package/lib/Adapters/Auth/oauth2.js +97 -162
  29. package/lib/Adapters/Auth/phantauth.js +53 -0
  30. package/lib/Adapters/Auth/qq.js +108 -49
  31. package/lib/Adapters/Auth/spotify.js +107 -55
  32. package/lib/Adapters/Auth/twitter.js +188 -48
  33. package/lib/Adapters/Auth/utils.js +28 -0
  34. package/lib/Adapters/Auth/vkontakte.js +26 -39
  35. package/lib/Adapters/Auth/wechat.js +106 -44
  36. package/lib/Adapters/Auth/weibo.js +132 -58
  37. package/lib/Adapters/Cache/CacheAdapter.js +13 -8
  38. package/lib/Adapters/Cache/InMemoryCache.js +3 -13
  39. package/lib/Adapters/Cache/InMemoryCacheAdapter.js +5 -13
  40. package/lib/Adapters/Cache/LRUCache.js +13 -27
  41. package/lib/Adapters/Cache/NullCacheAdapter.js +3 -8
  42. package/lib/Adapters/Cache/RedisCacheAdapter.js +85 -76
  43. package/lib/Adapters/Cache/SchemaCache.js +25 -0
  44. package/lib/Adapters/Email/MailAdapter.js +10 -8
  45. package/lib/Adapters/Files/FilesAdapter.js +83 -25
  46. package/lib/Adapters/Files/GridFSBucketAdapter.js +231 -0
  47. package/lib/Adapters/Files/GridStoreAdapter.js +4 -91
  48. package/lib/Adapters/Logger/LoggerAdapter.js +18 -14
  49. package/lib/Adapters/Logger/WinstonLogger.js +69 -88
  50. package/lib/Adapters/Logger/WinstonLoggerAdapter.js +7 -16
  51. package/lib/Adapters/MessageQueue/EventEmitterMQ.js +8 -26
  52. package/lib/Adapters/PubSub/EventEmitterPubSub.js +12 -25
  53. package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
  54. package/lib/Adapters/PubSub/RedisPubSub.js +42 -19
  55. package/lib/Adapters/Push/PushAdapter.js +14 -7
  56. package/lib/Adapters/Storage/Mongo/MongoCollection.js +137 -45
  57. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +158 -63
  58. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +320 -168
  59. package/lib/Adapters/Storage/Mongo/MongoTransform.js +279 -306
  60. package/lib/Adapters/Storage/Postgres/PostgresClient.js +14 -10
  61. package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +47 -21
  62. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +854 -468
  63. package/lib/Adapters/Storage/Postgres/sql/index.js +4 -6
  64. package/lib/Adapters/Storage/StorageAdapter.js +1 -1
  65. package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
  66. package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
  67. package/lib/Auth.js +488 -125
  68. package/lib/ClientSDK.js +2 -6
  69. package/lib/Config.js +525 -94
  70. package/lib/Controllers/AdaptableController.js +5 -25
  71. package/lib/Controllers/AnalyticsController.js +22 -23
  72. package/lib/Controllers/CacheController.js +10 -31
  73. package/lib/Controllers/DatabaseController.js +767 -313
  74. package/lib/Controllers/FilesController.js +49 -54
  75. package/lib/Controllers/HooksController.js +80 -84
  76. package/lib/Controllers/LiveQueryController.js +35 -22
  77. package/lib/Controllers/LoggerController.js +22 -58
  78. package/lib/Controllers/ParseGraphQLController.js +293 -0
  79. package/lib/Controllers/PushController.js +58 -49
  80. package/lib/Controllers/SchemaController.js +916 -422
  81. package/lib/Controllers/UserController.js +265 -180
  82. package/lib/Controllers/index.js +90 -125
  83. package/lib/Controllers/types.js +1 -1
  84. package/lib/Deprecator/Deprecations.js +30 -0
  85. package/lib/Deprecator/Deprecator.js +127 -0
  86. package/lib/Error.js +48 -0
  87. package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
  88. package/lib/GraphQL/ParseGraphQLServer.js +214 -0
  89. package/lib/GraphQL/helpers/objectsMutations.js +30 -0
  90. package/lib/GraphQL/helpers/objectsQueries.js +246 -0
  91. package/lib/GraphQL/loaders/configMutations.js +87 -0
  92. package/lib/GraphQL/loaders/configQueries.js +79 -0
  93. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
  94. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
  95. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1098 -0
  96. package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
  97. package/lib/GraphQL/loaders/filesMutations.js +107 -0
  98. package/lib/GraphQL/loaders/functionsMutations.js +78 -0
  99. package/lib/GraphQL/loaders/parseClassMutations.js +268 -0
  100. package/lib/GraphQL/loaders/parseClassQueries.js +127 -0
  101. package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
  102. package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
  103. package/lib/GraphQL/loaders/schemaMutations.js +162 -0
  104. package/lib/GraphQL/loaders/schemaQueries.js +81 -0
  105. package/lib/GraphQL/loaders/schemaTypes.js +341 -0
  106. package/lib/GraphQL/loaders/usersMutations.js +433 -0
  107. package/lib/GraphQL/loaders/usersQueries.js +90 -0
  108. package/lib/GraphQL/parseGraphQLUtils.js +63 -0
  109. package/lib/GraphQL/transformers/className.js +14 -0
  110. package/lib/GraphQL/transformers/constraintType.js +53 -0
  111. package/lib/GraphQL/transformers/inputType.js +51 -0
  112. package/lib/GraphQL/transformers/mutation.js +274 -0
  113. package/lib/GraphQL/transformers/outputType.js +51 -0
  114. package/lib/GraphQL/transformers/query.js +237 -0
  115. package/lib/GraphQL/transformers/schemaFields.js +99 -0
  116. package/lib/KeyPromiseQueue.js +48 -0
  117. package/lib/LiveQuery/Client.js +25 -33
  118. package/lib/LiveQuery/Id.js +2 -5
  119. package/lib/LiveQuery/ParseCloudCodePublisher.js +26 -23
  120. package/lib/LiveQuery/ParseLiveQueryServer.js +560 -285
  121. package/lib/LiveQuery/ParsePubSub.js +7 -16
  122. package/lib/LiveQuery/ParseWebSocketServer.js +42 -39
  123. package/lib/LiveQuery/QueryTools.js +76 -15
  124. package/lib/LiveQuery/RequestSchema.js +111 -97
  125. package/lib/LiveQuery/SessionTokenCache.js +23 -36
  126. package/lib/LiveQuery/Subscription.js +8 -17
  127. package/lib/LiveQuery/equalObjects.js +2 -3
  128. package/lib/Options/Definitions.js +1355 -382
  129. package/lib/Options/docs.js +301 -62
  130. package/lib/Options/index.js +11 -1
  131. package/lib/Options/parsers.js +14 -10
  132. package/lib/Page.js +44 -0
  133. package/lib/ParseMessageQueue.js +6 -13
  134. package/lib/ParseServer.js +474 -235
  135. package/lib/ParseServerRESTController.js +102 -40
  136. package/lib/PromiseRouter.js +39 -50
  137. package/lib/Push/PushQueue.js +24 -30
  138. package/lib/Push/PushWorker.js +32 -56
  139. package/lib/Push/utils.js +22 -35
  140. package/lib/RestQuery.js +361 -139
  141. package/lib/RestWrite.js +713 -344
  142. package/lib/Routers/AggregateRouter.js +97 -71
  143. package/lib/Routers/AnalyticsRouter.js +8 -14
  144. package/lib/Routers/AudiencesRouter.js +16 -35
  145. package/lib/Routers/ClassesRouter.js +86 -72
  146. package/lib/Routers/CloudCodeRouter.js +28 -37
  147. package/lib/Routers/FeaturesRouter.js +22 -25
  148. package/lib/Routers/FilesRouter.js +266 -171
  149. package/lib/Routers/FunctionsRouter.js +87 -103
  150. package/lib/Routers/GlobalConfigRouter.js +94 -33
  151. package/lib/Routers/GraphQLRouter.js +41 -0
  152. package/lib/Routers/HooksRouter.js +43 -47
  153. package/lib/Routers/IAPValidationRouter.js +57 -70
  154. package/lib/Routers/InstallationsRouter.js +17 -25
  155. package/lib/Routers/LogsRouter.js +10 -25
  156. package/lib/Routers/PagesRouter.js +647 -0
  157. package/lib/Routers/PublicAPIRouter.js +104 -112
  158. package/lib/Routers/PurgeRouter.js +19 -29
  159. package/lib/Routers/PushRouter.js +14 -28
  160. package/lib/Routers/RolesRouter.js +7 -14
  161. package/lib/Routers/SchemasRouter.js +63 -42
  162. package/lib/Routers/SecurityRouter.js +34 -0
  163. package/lib/Routers/SessionsRouter.js +25 -38
  164. package/lib/Routers/UsersRouter.js +463 -190
  165. package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
  166. package/lib/SchemaMigrations/Migrations.js +30 -0
  167. package/lib/Security/Check.js +109 -0
  168. package/lib/Security/CheckGroup.js +44 -0
  169. package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
  170. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +96 -0
  171. package/lib/Security/CheckGroups/CheckGroups.js +21 -0
  172. package/lib/Security/CheckRunner.js +213 -0
  173. package/lib/SharedRest.js +29 -0
  174. package/lib/StatusHandler.js +96 -93
  175. package/lib/TestUtils.js +70 -14
  176. package/lib/Utils.js +468 -0
  177. package/lib/batch.js +74 -40
  178. package/lib/cache.js +8 -8
  179. package/lib/cli/definitions/parse-live-query-server.js +4 -3
  180. package/lib/cli/definitions/parse-server.js +4 -3
  181. package/lib/cli/parse-live-query-server.js +9 -17
  182. package/lib/cli/parse-server.js +49 -47
  183. package/lib/cli/utils/commander.js +20 -29
  184. package/lib/cli/utils/runner.js +31 -32
  185. package/lib/cloud-code/Parse.Cloud.js +711 -36
  186. package/lib/cloud-code/Parse.Server.js +21 -0
  187. package/lib/cryptoUtils.js +6 -11
  188. package/lib/defaults.js +21 -15
  189. package/lib/deprecated.js +1 -1
  190. package/lib/index.js +78 -67
  191. package/lib/logger.js +12 -20
  192. package/lib/middlewares.js +484 -160
  193. package/lib/password.js +10 -6
  194. package/lib/request.js +175 -0
  195. package/lib/requiredParameter.js +4 -3
  196. package/lib/rest.js +157 -82
  197. package/lib/triggers.js +627 -185
  198. package/lib/vendor/README.md +3 -3
  199. package/lib/vendor/mongodbUrl.js +224 -137
  200. package/package.json +135 -57
  201. package/postinstall.js +38 -50
  202. package/public_html/invalid_verification_link.html +3 -3
  203. package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
  204. package/types/@types/deepcopy/index.d.ts +5 -0
  205. package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
  206. package/types/Options/index.d.ts +301 -0
  207. package/types/ParseServer.d.ts +65 -0
  208. package/types/eslint.config.mjs +30 -0
  209. package/types/index.d.ts +21 -0
  210. package/types/logger.d.ts +2 -0
  211. package/types/tests.ts +44 -0
  212. package/types/tsconfig.json +24 -0
  213. package/CHANGELOG.md +0 -1246
  214. package/PATENTS +0 -37
  215. package/bin/dev +0 -37
  216. package/lib/.DS_Store +0 -0
  217. package/lib/Adapters/Auth/common.js +0 -2
  218. package/lib/Adapters/Auth/facebookaccountkit.js +0 -69
  219. package/lib/Controllers/SchemaCache.js +0 -97
  220. package/lib/LiveQuery/.DS_Store +0 -0
  221. package/lib/cli/utils/parsers.js +0 -77
  222. package/lib/cloud-code/.DS_Store +0 -0
  223. package/lib/cloud-code/HTTPResponse.js +0 -57
  224. package/lib/cloud-code/Untitled-1 +0 -123
  225. package/lib/cloud-code/httpRequest.js +0 -102
  226. package/lib/cloud-code/team.html +0 -123
  227. package/lib/graphql/ParseClass.js +0 -234
  228. package/lib/graphql/Schema.js +0 -197
  229. package/lib/graphql/index.js +0 -1
  230. package/lib/graphql/types/ACL.js +0 -35
  231. package/lib/graphql/types/Date.js +0 -25
  232. package/lib/graphql/types/File.js +0 -24
  233. package/lib/graphql/types/GeoPoint.js +0 -35
  234. package/lib/graphql/types/JSONObject.js +0 -30
  235. package/lib/graphql/types/NumberInput.js +0 -43
  236. package/lib/graphql/types/NumberQuery.js +0 -42
  237. package/lib/graphql/types/Pointer.js +0 -35
  238. package/lib/graphql/types/QueryConstraint.js +0 -61
  239. package/lib/graphql/types/StringQuery.js +0 -39
  240. package/lib/graphql/types/index.js +0 -110
@@ -1,42 +1,25 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.UsersRouter = undefined;
7
-
8
- var _node = require('parse/node');
9
-
10
- var _node2 = _interopRequireDefault(_node);
11
-
12
- var _Config = require('../Config');
13
-
14
- var _Config2 = _interopRequireDefault(_Config);
15
-
16
- var _AccountLockout = require('../AccountLockout');
17
-
18
- var _AccountLockout2 = _interopRequireDefault(_AccountLockout);
19
-
20
- var _ClassesRouter = require('./ClassesRouter');
21
-
22
- var _ClassesRouter2 = _interopRequireDefault(_ClassesRouter);
23
-
24
- var _rest = require('../rest');
25
-
26
- var _rest2 = _interopRequireDefault(_rest);
27
-
28
- var _Auth = require('../Auth');
29
-
30
- var _Auth2 = _interopRequireDefault(_Auth);
31
-
32
- var _password = require('../password');
33
-
34
- var _password2 = _interopRequireDefault(_password);
35
-
36
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
-
38
- class UsersRouter extends _ClassesRouter2.default {
39
-
6
+ exports.default = exports.UsersRouter = void 0;
7
+ var _node = _interopRequireDefault(require("parse/node"));
8
+ var _Config = _interopRequireDefault(require("../Config"));
9
+ var _AccountLockout = _interopRequireDefault(require("../AccountLockout"));
10
+ var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter"));
11
+ var _rest = _interopRequireDefault(require("../rest"));
12
+ var _Auth = _interopRequireDefault(require("../Auth"));
13
+ var _password = _interopRequireDefault(require("../password"));
14
+ var _triggers = require("../triggers");
15
+ var _middlewares = require("../middlewares");
16
+ var _RestWrite = _interopRequireDefault(require("../RestWrite"));
17
+ var _logger = require("../logger");
18
+ var _Error = require("../Error");
19
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
20
+ // These methods handle the User-related routes.
21
+
22
+ class UsersRouter extends _ClassesRouter.default {
40
23
  className() {
41
24
  return '_User';
42
25
  }
@@ -47,15 +30,37 @@ class UsersRouter extends _ClassesRouter2.default {
47
30
  */
48
31
  static removeHiddenProperties(obj) {
49
32
  for (var key in obj) {
50
- if (obj.hasOwnProperty(key)) {
33
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
51
34
  // Regexp comes from Parse.Object.prototype.validate
52
- if (key !== "__type" && !/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) {
35
+ if (key !== '__type' && !/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) {
53
36
  delete obj[key];
54
37
  }
55
38
  }
56
39
  }
57
40
  }
58
41
 
42
+ /**
43
+ * After retrieving a user directly from the database, we need to remove the
44
+ * password from the object (for security), and fix an issue some SDKs have
45
+ * with null values
46
+ */
47
+ _sanitizeAuthData(user) {
48
+ delete user.password;
49
+
50
+ // Sometimes the authData still has null on that keys
51
+ // https://github.com/parse-community/parse-server/issues/935
52
+ if (user.authData) {
53
+ Object.keys(user.authData).forEach(provider => {
54
+ if (user.authData[provider] === null) {
55
+ delete user.authData[provider];
56
+ }
57
+ });
58
+ if (Object.keys(user.authData).length == 0) {
59
+ delete user.authData;
60
+ }
61
+ }
62
+ }
63
+
59
64
  /**
60
65
  * Validates a password request in login and verifyPassword
61
66
  * @param {Object} req The request
@@ -65,100 +70,115 @@ class UsersRouter extends _ClassesRouter2.default {
65
70
  _authenticateUserFromRequest(req) {
66
71
  return new Promise((resolve, reject) => {
67
72
  // Use query parameters instead if provided in url
68
- let payload = req.body;
69
- if (!payload.username && req.query.username || !payload.email && req.query.email) {
73
+ let payload = req.body || {};
74
+ if (!payload.username && req.query && req.query.username || !payload.email && req.query && req.query.email) {
70
75
  payload = req.query;
71
76
  }
72
77
  const {
73
78
  username,
74
79
  email,
75
- password
80
+ password,
81
+ ignoreEmailVerification
76
82
  } = payload;
77
83
 
78
84
  // TODO: use the right error codes / descriptions.
79
85
  if (!username && !email) {
80
- throw new _node2.default.Error(_node2.default.Error.USERNAME_MISSING, 'username/email is required.');
86
+ throw new _node.default.Error(_node.default.Error.USERNAME_MISSING, 'username/email is required.');
81
87
  }
82
88
  if (!password) {
83
- throw new _node2.default.Error(_node2.default.Error.PASSWORD_MISSING, 'password is required.');
89
+ throw new _node.default.Error(_node.default.Error.PASSWORD_MISSING, 'password is required.');
84
90
  }
85
91
  if (typeof password !== 'string' || email && typeof email !== 'string' || username && typeof username !== 'string') {
86
- throw new _node2.default.Error(_node2.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
92
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
87
93
  }
88
-
89
94
  let user;
90
95
  let isValidPassword = false;
91
96
  let query;
92
97
  if (email && username) {
93
- query = { email, username };
98
+ query = {
99
+ email,
100
+ username
101
+ };
94
102
  } else if (email) {
95
- query = { email };
103
+ query = {
104
+ email
105
+ };
96
106
  } else {
97
- query = { $or: [{ username }, { email: username }] };
107
+ query = {
108
+ $or: [{
109
+ username
110
+ }, {
111
+ email: username
112
+ }]
113
+ };
98
114
  }
99
- return req.config.database.find('_User', query).then(results => {
115
+ return req.config.database.find('_User', query, {}, _Auth.default.maintenance(req.config)).then(results => {
100
116
  if (!results.length) {
101
- throw new _node2.default.Error(_node2.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
117
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
102
118
  }
103
-
104
119
  if (results.length > 1) {
105
120
  // corner case where user1 has username == user2 email
106
- req.config.loggerController.warn('There is a user which email is the same as another user\'s username, logging in based on username');
121
+ req.config.loggerController.warn("There is a user which email is the same as another user's username, logging in based on username");
107
122
  user = results.filter(user => user.username === username)[0];
108
123
  } else {
109
124
  user = results[0];
110
125
  }
111
-
112
- return _password2.default.compare(password, user.password);
126
+ return _password.default.compare(password, user.password);
113
127
  }).then(correct => {
114
128
  isValidPassword = correct;
115
- const accountLockoutPolicy = new _AccountLockout2.default(user, req.config);
129
+ const accountLockoutPolicy = new _AccountLockout.default(user, req.config);
116
130
  return accountLockoutPolicy.handleLoginAttempt(isValidPassword);
117
- }).then(() => {
131
+ }).then(async () => {
118
132
  if (!isValidPassword) {
119
- throw new _node2.default.Error(_node2.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
133
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
120
134
  }
121
135
  // Ensure the user isn't locked out
122
136
  // A locked out user won't be able to login
123
137
  // To lock a user out, just set the ACL to `masterKey` only ({}).
124
138
  // Empty ACL is OK
125
139
  if (!req.auth.isMaster && user.ACL && Object.keys(user.ACL).length == 0) {
126
- throw new _node2.default.Error(_node2.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
140
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
127
141
  }
128
- if (req.config.verifyUserEmails && req.config.preventLoginWithUnverifiedEmail && !user.emailVerified) {
129
- throw new _node2.default.Error(_node2.default.Error.EMAIL_NOT_FOUND, 'User email is not verified.');
130
- }
131
-
132
- delete user.password;
133
-
134
- // Sometimes the authData still has null on that keys
135
- // https://github.com/parse-community/parse-server/issues/935
136
- if (user.authData) {
137
- Object.keys(user.authData).forEach(provider => {
138
- if (user.authData[provider] === null) {
139
- delete user.authData[provider];
140
- }
141
- });
142
- if (Object.keys(user.authData).length == 0) {
143
- delete user.authData;
142
+ // Create request object for verification functions
143
+ const request = {
144
+ master: req.auth.isMaster,
145
+ ip: req.config.ip,
146
+ installationId: req.auth.installationId,
147
+ object: _node.default.User.fromJSON(Object.assign({
148
+ className: '_User'
149
+ }, user))
150
+ };
151
+
152
+ // If request doesn't use master or maintenance key with ignoring email verification
153
+ if (!((req.auth.isMaster || req.auth.isMaintenance) && ignoreEmailVerification)) {
154
+ // Get verification conditions which can be booleans or functions; the purpose of this async/await
155
+ // structure is to avoid unnecessarily executing subsequent functions if previous ones fail in the
156
+ // conditional statement below, as a developer may decide to execute expensive operations in them
157
+ const verifyUserEmails = async () => req.config.verifyUserEmails === true || typeof req.config.verifyUserEmails === 'function' && (await Promise.resolve(req.config.verifyUserEmails(request))) === true;
158
+ const preventLoginWithUnverifiedEmail = async () => req.config.preventLoginWithUnverifiedEmail === true || typeof req.config.preventLoginWithUnverifiedEmail === 'function' && (await Promise.resolve(req.config.preventLoginWithUnverifiedEmail(request))) === true;
159
+ if ((await verifyUserEmails()) && (await preventLoginWithUnverifiedEmail()) && !user.emailVerified) {
160
+ throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, 'User email is not verified.');
144
161
  }
145
162
  }
146
-
163
+ this._sanitizeAuthData(user);
147
164
  return resolve(user);
148
165
  }).catch(error => {
149
166
  return reject(error);
150
167
  });
151
168
  });
152
169
  }
153
-
154
170
  handleMe(req) {
155
171
  if (!req.info || !req.info.sessionToken) {
156
- throw new _node2.default.Error(_node2.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token');
172
+ throw (0, _Error.createSanitizedError)(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token', req.config);
157
173
  }
158
174
  const sessionToken = req.info.sessionToken;
159
- return _rest2.default.find(req.config, _Auth2.default.master(req.config), '_Session', { sessionToken }, { include: 'user' }, req.info.clientSDK).then(response => {
175
+ return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', {
176
+ sessionToken
177
+ }, {
178
+ include: 'user'
179
+ }, req.info.clientSDK, req.info.context).then(response => {
160
180
  if (!response.results || response.results.length == 0 || !response.results[0].user) {
161
- throw new _node2.default.Error(_node2.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token');
181
+ throw (0, _Error.createSanitizedError)(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token', req.config);
162
182
  } else {
163
183
  const user = response.results[0].user;
164
184
  // Send token back on the login, because SDKs expect that.
@@ -166,168 +186,414 @@ class UsersRouter extends _ClassesRouter2.default {
166
186
 
167
187
  // Remove hidden properties.
168
188
  UsersRouter.removeHiddenProperties(user);
169
-
170
- return { response: user };
189
+ return {
190
+ response: user
191
+ };
171
192
  }
172
193
  });
173
194
  }
195
+ async handleLogIn(req) {
196
+ const user = await this._authenticateUserFromRequest(req);
197
+ const authData = req.body && req.body.authData;
198
+ // Check if user has provided their required auth providers
199
+ _Auth.default.checkIfUserHasProvidedConfiguredProvidersForLogin(req, authData, user.authData, req.config);
200
+ let authDataResponse;
201
+ let validatedAuthData;
202
+ if (authData) {
203
+ const res = await _Auth.default.handleAuthDataValidation(authData, new _RestWrite.default(req.config, req.auth, '_User', {
204
+ objectId: user.objectId
205
+ }, req.body || {}, user, req.info.clientSDK, req.info.context), user);
206
+ authDataResponse = res.authDataResponse;
207
+ validatedAuthData = res.authData;
208
+ }
174
209
 
175
- handleLogIn(req) {
176
- let user;
177
- return this._authenticateUserFromRequest(req).then(res => {
178
-
179
- user = res;
180
-
181
- // handle password expiry policy
182
- if (req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) {
183
- let changedAt = user._password_changed_at;
184
-
185
- if (!changedAt) {
186
- // password was created before expiry policy was enabled.
187
- // simply update _User object so that it will start enforcing from now
188
- changedAt = new Date();
189
- req.config.database.update('_User', { username: user.username }, { _password_changed_at: _node2.default._encode(changedAt) });
190
- } else {
191
- // check whether the password has expired
192
- if (changedAt.__type == 'Date') {
193
- changedAt = new Date(changedAt.iso);
194
- }
195
- // Calculate the expiry time.
196
- const expiresAt = new Date(changedAt.getTime() + 86400000 * req.config.passwordPolicy.maxPasswordAge);
197
- if (expiresAt < new Date()) // fail of current time is past password expiry time
198
- throw new _node2.default.Error(_node2.default.Error.OBJECT_NOT_FOUND, 'Your password has expired. Please reset your password.');
210
+ // handle password expiry policy
211
+ if (req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) {
212
+ let changedAt = user._password_changed_at;
213
+ if (!changedAt) {
214
+ // password was created before expiry policy was enabled.
215
+ // simply update _User object so that it will start enforcing from now
216
+ changedAt = new Date();
217
+ req.config.database.update('_User', {
218
+ username: user.username
219
+ }, {
220
+ _password_changed_at: _node.default._encode(changedAt)
221
+ });
222
+ } else {
223
+ // check whether the password has expired
224
+ if (changedAt.__type == 'Date') {
225
+ changedAt = new Date(changedAt.iso);
199
226
  }
227
+ // Calculate the expiry time.
228
+ const expiresAt = new Date(changedAt.getTime() + 86400000 * req.config.passwordPolicy.maxPasswordAge);
229
+ if (expiresAt < new Date())
230
+ // fail of current time is past password expiry time
231
+ {
232
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your password has expired. Please reset your password.');
233
+ }
200
234
  }
235
+ }
201
236
 
202
- // Remove hidden properties.
203
- UsersRouter.removeHiddenProperties(user);
204
-
205
- const {
206
- sessionData,
207
- createSession
208
- } = _Auth2.default.createSession(req.config, {
209
- userId: user.objectId, createdWith: {
210
- 'action': 'login',
211
- 'authProvider': 'password'
212
- }, installationId: req.info.installationId
213
- });
214
-
215
- user.sessionToken = sessionData.sessionToken;
216
-
217
- req.config.filesController.expandFilesInObject(req.config, user);
218
-
219
- return createSession();
220
- }).then(() => {
221
- return { response: user };
237
+ // Remove hidden properties.
238
+ UsersRouter.removeHiddenProperties(user);
239
+ await req.config.filesController.expandFilesInObject(req.config, user);
240
+
241
+ // Before login trigger; throws if failure
242
+ await (0, _triggers.maybeRunTrigger)(_triggers.Types.beforeLogin, req.auth, _node.default.User.fromJSON(Object.assign({
243
+ className: '_User'
244
+ }, user)), null, req.config, req.info.context);
245
+
246
+ // If we have some new validated authData update directly
247
+ if (validatedAuthData && Object.keys(validatedAuthData).length) {
248
+ await req.config.database.update('_User', {
249
+ objectId: user.objectId
250
+ }, {
251
+ authData: validatedAuthData
252
+ }, {});
253
+ }
254
+ const {
255
+ sessionData,
256
+ createSession
257
+ } = _RestWrite.default.createSession(req.config, {
258
+ userId: user.objectId,
259
+ createdWith: {
260
+ action: 'login',
261
+ authProvider: 'password'
262
+ },
263
+ installationId: req.info.installationId
222
264
  });
265
+ user.sessionToken = sessionData.sessionToken;
266
+ await createSession();
267
+ const afterLoginUser = _node.default.User.fromJSON(Object.assign({
268
+ className: '_User'
269
+ }, user));
270
+ await (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogin, {
271
+ ...req.auth,
272
+ user: afterLoginUser
273
+ }, afterLoginUser, null, req.config, req.info.context);
274
+ if (authDataResponse) {
275
+ user.authDataResponse = authDataResponse;
276
+ }
277
+ await req.config.authDataManager.runAfterFind(req, user.authData);
278
+ return {
279
+ response: user
280
+ };
223
281
  }
224
282
 
283
+ /**
284
+ * This allows master-key clients to create user sessions without access to
285
+ * user credentials. This enables systems that can authenticate access another
286
+ * way (API key, app administrators) to act on a user's behalf.
287
+ *
288
+ * We create a new session rather than looking for an existing session; we
289
+ * want this to work in situations where the user is logged out on all
290
+ * devices, since this can be used by automated systems acting on the user's
291
+ * behalf.
292
+ *
293
+ * For the moment, we're omitting event hooks and lockout checks, since
294
+ * immediate use cases suggest /loginAs could be used for semantically
295
+ * different reasons from /login
296
+ */
297
+ async handleLogInAs(req) {
298
+ if (!req.auth.isMaster) {
299
+ throw (0, _Error.createSanitizedError)(_node.default.Error.OPERATION_FORBIDDEN, 'master key is required', req.config);
300
+ }
301
+ const userId = req.body?.userId || req.query.userId;
302
+ if (!userId) {
303
+ throw new _node.default.Error(_node.default.Error.INVALID_VALUE, 'userId must not be empty, null, or undefined');
304
+ }
305
+ const queryResults = await req.config.database.find('_User', {
306
+ objectId: userId
307
+ });
308
+ const user = queryResults[0];
309
+ if (!user) {
310
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'user not found');
311
+ }
312
+ this._sanitizeAuthData(user);
313
+ const {
314
+ sessionData,
315
+ createSession
316
+ } = _RestWrite.default.createSession(req.config, {
317
+ userId,
318
+ createdWith: {
319
+ action: 'login',
320
+ authProvider: 'masterkey'
321
+ },
322
+ installationId: req.info.installationId
323
+ });
324
+ user.sessionToken = sessionData.sessionToken;
325
+ await createSession();
326
+ return {
327
+ response: user
328
+ };
329
+ }
225
330
  handleVerifyPassword(req) {
226
331
  return this._authenticateUserFromRequest(req).then(user => {
227
-
228
332
  // Remove hidden properties.
229
333
  UsersRouter.removeHiddenProperties(user);
230
-
231
- return { response: user };
334
+ return {
335
+ response: user
336
+ };
232
337
  }).catch(error => {
233
338
  throw error;
234
339
  });
235
340
  }
236
-
237
- handleLogOut(req) {
238
- const success = { response: {} };
341
+ async handleLogOut(req) {
342
+ const success = {
343
+ response: {}
344
+ };
239
345
  if (req.info && req.info.sessionToken) {
240
- return _rest2.default.find(req.config, _Auth2.default.master(req.config), '_Session', { sessionToken: req.info.sessionToken }, undefined, req.info.clientSDK).then(records => {
241
- if (records.results && records.results.length) {
242
- return _rest2.default.del(req.config, _Auth2.default.master(req.config), '_Session', records.results[0].objectId).then(() => {
243
- return Promise.resolve(success);
244
- });
245
- }
246
- return Promise.resolve(success);
247
- });
346
+ const records = await _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', {
347
+ sessionToken: req.info.sessionToken
348
+ }, undefined, req.info.clientSDK, req.info.context);
349
+ if (records.results && records.results.length) {
350
+ await _rest.default.del(req.config, _Auth.default.master(req.config), '_Session', records.results[0].objectId, req.info.context);
351
+ await (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogout, req.auth, _node.default.Session.fromJSON(Object.assign({
352
+ className: '_Session'
353
+ }, records.results[0])), null, req.config);
354
+ }
248
355
  }
249
- return Promise.resolve(success);
356
+ return success;
250
357
  }
251
-
252
358
  _throwOnBadEmailConfig(req) {
253
359
  try {
254
- _Config2.default.validateEmailConfiguration({
360
+ _Config.default.validateEmailConfiguration({
255
361
  emailAdapter: req.config.userController.adapter,
256
362
  appName: req.config.appName,
257
- publicServerURL: req.config.publicServerURL,
258
- emailVerifyTokenValidityDuration: req.config.emailVerifyTokenValidityDuration
363
+ publicServerURL: req.config.publicServerURL || req.config._publicServerURL,
364
+ emailVerifyTokenValidityDuration: req.config.emailVerifyTokenValidityDuration,
365
+ emailVerifyTokenReuseIfValid: req.config.emailVerifyTokenReuseIfValid
259
366
  });
260
367
  } catch (e) {
261
368
  if (typeof e === 'string') {
262
369
  // Maybe we need a Bad Configuration error, but the SDKs won't understand it. For now, Internal Server Error.
263
- throw new _node2.default.Error(_node2.default.Error.INTERNAL_SERVER_ERROR, 'An appName, publicServerURL, and emailAdapter are required for password reset and email verification functionality.');
370
+ 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.');
264
371
  } else {
265
372
  throw e;
266
373
  }
267
374
  }
268
375
  }
269
-
270
- handleResetRequest(req) {
376
+ async handleResetRequest(req) {
271
377
  this._throwOnBadEmailConfig(req);
272
-
273
- const { email } = req.body;
274
- if (!email) {
275
- throw new _node2.default.Error(_node2.default.Error.EMAIL_MISSING, "you must provide an email");
378
+ let email = req.body?.email;
379
+ const token = req.body?.token;
380
+ if (!email && !token) {
381
+ throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email');
382
+ }
383
+ let userResults = null;
384
+ let userData = null;
385
+
386
+ // We can find the user using token
387
+ if (token) {
388
+ userResults = await req.config.database.find('_User', {
389
+ _perishable_token: token,
390
+ _perishable_token_expires_at: {
391
+ $lt: _node.default._encode(new Date())
392
+ }
393
+ });
394
+ if (userResults?.length > 0) {
395
+ userData = userResults[0];
396
+ if (userData.email) {
397
+ email = userData.email;
398
+ }
399
+ }
400
+ // Or using email if no token provided
401
+ } else if (typeof email === 'string') {
402
+ userResults = await req.config.database.find('_User', {
403
+ $or: [{
404
+ email
405
+ }, {
406
+ username: email,
407
+ email: {
408
+ $exists: false
409
+ }
410
+ }]
411
+ }, {
412
+ limit: 1
413
+ }, _Auth.default.maintenance(req.config));
414
+ if (userResults?.length > 0) {
415
+ userData = userResults[0];
416
+ }
276
417
  }
277
418
  if (typeof email !== 'string') {
278
- throw new _node2.default.Error(_node2.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string');
419
+ throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string');
420
+ }
421
+ if (userData) {
422
+ this._sanitizeAuthData(userData);
423
+ // Get files attached to user
424
+ await req.config.filesController.expandFilesInObject(req.config, userData);
425
+ const user = (0, _triggers.inflate)('_User', userData);
426
+ await (0, _triggers.maybeRunTrigger)(_triggers.Types.beforePasswordResetRequest, req.auth, user, null, req.config, req.info.context);
279
427
  }
280
428
  const userController = req.config.userController;
281
- return userController.sendPasswordResetEmail(email).then(() => {
282
- return Promise.resolve({
429
+ try {
430
+ await userController.sendPasswordResetEmail(email);
431
+ return {
283
432
  response: {}
284
- });
285
- }, err => {
286
- if (err.code === _node2.default.Error.OBJECT_NOT_FOUND) {
287
- throw new _node2.default.Error(_node2.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}.`);
288
- } else {
289
- throw err;
433
+ };
434
+ } catch (err) {
435
+ if (err.code === _node.default.Error.OBJECT_NOT_FOUND) {
436
+ if (req.config.passwordPolicy?.resetPasswordSuccessOnInvalidEmail ?? true) {
437
+ return {
438
+ response: {}
439
+ };
440
+ }
441
+ err.message = `A user with that email does not exist.`;
290
442
  }
291
- });
443
+ throw err;
444
+ }
292
445
  }
293
-
294
- handleVerificationEmailRequest(req) {
446
+ async handleVerificationEmailRequest(req) {
295
447
  this._throwOnBadEmailConfig(req);
296
-
297
- const { email } = req.body;
448
+ const {
449
+ email
450
+ } = req.body || {};
298
451
  if (!email) {
299
- throw new _node2.default.Error(_node2.default.Error.EMAIL_MISSING, 'you must provide an email');
452
+ throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email');
300
453
  }
301
454
  if (typeof email !== 'string') {
302
- throw new _node2.default.Error(_node2.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string');
455
+ throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string');
303
456
  }
457
+ const results = await req.config.database.find('_User', {
458
+ email: email
459
+ }, {}, _Auth.default.maintenance(req.config));
460
+ if (!results.length || results.length < 1) {
461
+ throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`);
462
+ }
463
+ const user = results[0];
304
464
 
305
- return req.config.database.find('_User', { email: email }).then(results => {
306
- if (!results.length || results.length < 1) {
307
- throw new _node2.default.Error(_node2.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`);
465
+ // remove password field, messes with saving on postgres
466
+ delete user.password;
467
+ if (user.emailVerified) {
468
+ throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, `Email ${email} is already verified.`);
469
+ }
470
+ const userController = req.config.userController;
471
+ const send = await userController.regenerateEmailVerifyToken(user, req.auth.isMaster, req.auth.installationId, req.ip);
472
+ if (send) {
473
+ userController.sendVerificationEmail(user, req);
474
+ }
475
+ return {
476
+ response: {}
477
+ };
478
+ }
479
+ async handleChallenge(req) {
480
+ const {
481
+ username,
482
+ email,
483
+ password,
484
+ authData,
485
+ challengeData
486
+ } = req.body || {};
487
+
488
+ // if username or email provided with password try to authenticate the user by username
489
+ let user;
490
+ if (username || email) {
491
+ if (!password) {
492
+ throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'You provided username or email, you need to also provide password.');
308
493
  }
309
- const user = results[0];
310
-
311
- // remove password field, messes with saving on postgres
312
- delete user.password;
494
+ user = await this._authenticateUserFromRequest(req);
495
+ }
496
+ if (!challengeData) {
497
+ throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'Nothing to challenge.');
498
+ }
499
+ if (typeof challengeData !== 'object') {
500
+ throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'challengeData should be an object.');
501
+ }
502
+ let request;
503
+ let parseUser;
313
504
 
314
- if (user.emailVerified) {
315
- throw new _node2.default.Error(_node2.default.Error.OTHER_CAUSE, `Email ${email} is already verified.`);
505
+ // Try to find user by authData
506
+ if (authData) {
507
+ if (typeof authData !== 'object') {
508
+ throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'authData should be an object.');
316
509
  }
317
-
318
- const userController = req.config.userController;
319
- return userController.regenerateEmailVerifyToken(user).then(() => {
320
- userController.sendVerificationEmail(user);
321
- return { response: {} };
322
- });
323
- });
510
+ if (user) {
511
+ throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'You cannot provide username/email and authData, only use one identification method.');
512
+ }
513
+ if (Object.keys(authData).filter(key => authData[key].id).length > 1) {
514
+ throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, 'You cannot provide more than one authData provider with an id.');
515
+ }
516
+ const results = await _Auth.default.findUsersWithAuthData(req.config, authData);
517
+ try {
518
+ if (!results[0] || results.length > 1) {
519
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'User not found.');
520
+ }
521
+ // Find the provider used to find the user
522
+ const provider = Object.keys(authData).find(key => authData[key].id);
523
+ parseUser = _node.default.User.fromJSON({
524
+ className: '_User',
525
+ ...results[0]
526
+ });
527
+ request = (0, _triggers.getRequestObject)(undefined, req.auth, parseUser, parseUser, req.config);
528
+ request.isChallenge = true;
529
+ // Validate authData used to identify the user to avoid brute-force attack on `id`
530
+ const {
531
+ validator
532
+ } = req.config.authDataManager.getValidatorForProvider(provider);
533
+ const validatorResponse = await validator(authData[provider], req, parseUser, request);
534
+ if (validatorResponse && validatorResponse.validator) {
535
+ await validatorResponse.validator();
536
+ }
537
+ } catch (e) {
538
+ // Rewrite the error to avoid guess id attack
539
+ _logger.logger.error(e);
540
+ throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'User not found.');
541
+ }
542
+ }
543
+ if (!parseUser) {
544
+ parseUser = user ? _node.default.User.fromJSON({
545
+ className: '_User',
546
+ ...user
547
+ }) : undefined;
548
+ }
549
+ if (!request) {
550
+ request = (0, _triggers.getRequestObject)(undefined, req.auth, parseUser, parseUser, req.config);
551
+ request.isChallenge = true;
552
+ }
553
+ const acc = {};
554
+ // Execute challenge step-by-step with consistent order for better error feedback
555
+ // and to avoid to trigger others challenges if one of them fails
556
+ for (const provider of Object.keys(challengeData).sort()) {
557
+ try {
558
+ const authAdapter = req.config.authDataManager.getValidatorForProvider(provider);
559
+ if (!authAdapter) {
560
+ continue;
561
+ }
562
+ const {
563
+ adapter: {
564
+ challenge
565
+ }
566
+ } = authAdapter;
567
+ if (typeof challenge === 'function') {
568
+ const providerChallengeResponse = await challenge(challengeData[provider], authData && authData[provider], req.config.auth[provider], request);
569
+ acc[provider] = providerChallengeResponse || true;
570
+ }
571
+ } catch (err) {
572
+ const e = (0, _triggers.resolveError)(err, {
573
+ code: _node.default.Error.SCRIPT_FAILED,
574
+ message: 'Challenge failed. Unknown error.'
575
+ });
576
+ const userString = req.auth && req.auth.user ? req.auth.user.id : undefined;
577
+ _logger.logger.error(`Failed running auth step challenge for ${provider} for user ${userString} with Error: ` + JSON.stringify(e), {
578
+ authenticationStep: 'challenge',
579
+ error: e,
580
+ user: userString,
581
+ provider
582
+ });
583
+ throw e;
584
+ }
585
+ }
586
+ return {
587
+ response: {
588
+ challengeData: acc
589
+ }
590
+ };
324
591
  }
325
-
326
592
  mountRoutes() {
327
593
  this.route('GET', '/users', req => {
328
594
  return this.handleFind(req);
329
595
  });
330
- this.route('POST', '/users', req => {
596
+ this.route('POST', '/users', _middlewares.promiseEnsureIdempotency, req => {
331
597
  return this.handleCreate(req);
332
598
  });
333
599
  this.route('GET', '/users/me', req => {
@@ -336,7 +602,7 @@ class UsersRouter extends _ClassesRouter2.default {
336
602
  this.route('GET', '/users/:objectId', req => {
337
603
  return this.handleGet(req);
338
604
  });
339
- this.route('PUT', '/users/:objectId', req => {
605
+ this.route('PUT', '/users/:objectId', _middlewares.promiseEnsureIdempotency, req => {
340
606
  return this.handleUpdate(req);
341
607
  });
342
608
  this.route('DELETE', '/users/:objectId', req => {
@@ -348,6 +614,9 @@ class UsersRouter extends _ClassesRouter2.default {
348
614
  this.route('POST', '/login', req => {
349
615
  return this.handleLogIn(req);
350
616
  });
617
+ this.route('POST', '/loginAs', req => {
618
+ return this.handleLogInAs(req);
619
+ });
351
620
  this.route('POST', '/logout', req => {
352
621
  return this.handleLogOut(req);
353
622
  });
@@ -360,10 +629,14 @@ class UsersRouter extends _ClassesRouter2.default {
360
629
  this.route('GET', '/verifyPassword', req => {
361
630
  return this.handleVerifyPassword(req);
362
631
  });
632
+ this.route('POST', '/verifyPassword', req => {
633
+ return this.handleVerifyPassword(req);
634
+ });
635
+ this.route('POST', '/challenge', req => {
636
+ return this.handleChallenge(req);
637
+ });
363
638
  }
364
639
  }
365
-
366
- exports.UsersRouter = UsersRouter; // These methods handle the User-related routes.
367
-
368
- exports.default = UsersRouter;
369
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1VzZXJzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlVzZXJzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsInJlbW92ZUhpZGRlblByb3BlcnRpZXMiLCJvYmoiLCJrZXkiLCJoYXNPd25Qcm9wZXJ0eSIsInRlc3QiLCJfYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0IiwicmVxIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJwYXlsb2FkIiwiYm9keSIsInVzZXJuYW1lIiwicXVlcnkiLCJlbWFpbCIsInBhc3N3b3JkIiwiUGFyc2UiLCJFcnJvciIsIlVTRVJOQU1FX01JU1NJTkciLCJQQVNTV09SRF9NSVNTSU5HIiwiT0JKRUNUX05PVF9GT1VORCIsInVzZXIiLCJpc1ZhbGlkUGFzc3dvcmQiLCIkb3IiLCJjb25maWciLCJkYXRhYmFzZSIsImZpbmQiLCJ0aGVuIiwicmVzdWx0cyIsImxlbmd0aCIsImxvZ2dlckNvbnRyb2xsZXIiLCJ3YXJuIiwiZmlsdGVyIiwicGFzc3dvcmRDcnlwdG8iLCJjb21wYXJlIiwiY29ycmVjdCIsImFjY291bnRMb2Nrb3V0UG9saWN5IiwiQWNjb3VudExvY2tvdXQiLCJoYW5kbGVMb2dpbkF0dGVtcHQiLCJhdXRoIiwiaXNNYXN0ZXIiLCJBQ0wiLCJPYmplY3QiLCJrZXlzIiwidmVyaWZ5VXNlckVtYWlscyIsInByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwiLCJlbWFpbFZlcmlmaWVkIiwiRU1BSUxfTk9UX0ZPVU5EIiwiYXV0aERhdGEiLCJmb3JFYWNoIiwicHJvdmlkZXIiLCJjYXRjaCIsImVycm9yIiwiaGFuZGxlTWUiLCJpbmZvIiwic2Vzc2lvblRva2VuIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwicmVzdCIsIkF1dGgiLCJtYXN0ZXIiLCJpbmNsdWRlIiwiY2xpZW50U0RLIiwicmVzcG9uc2UiLCJoYW5kbGVMb2dJbiIsInJlcyIsInBhc3N3b3JkUG9saWN5IiwibWF4UGFzc3dvcmRBZ2UiLCJjaGFuZ2VkQXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsIkRhdGUiLCJ1cGRhdGUiLCJfZW5jb2RlIiwiX190eXBlIiwiaXNvIiwiZXhwaXJlc0F0IiwiZ2V0VGltZSIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsInVzZXJJZCIsIm9iamVjdElkIiwiY3JlYXRlZFdpdGgiLCJpbnN0YWxsYXRpb25JZCIsImZpbGVzQ29udHJvbGxlciIsImV4cGFuZEZpbGVzSW5PYmplY3QiLCJoYW5kbGVWZXJpZnlQYXNzd29yZCIsImhhbmRsZUxvZ091dCIsInN1Y2Nlc3MiLCJ1bmRlZmluZWQiLCJyZWNvcmRzIiwiZGVsIiwiX3Rocm93T25CYWRFbWFpbENvbmZpZyIsIkNvbmZpZyIsInZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uIiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImhhbmRsZVJlc2V0UmVxdWVzdCIsIkVNQUlMX01JU1NJTkciLCJJTlZBTElEX0VNQUlMX0FERFJFU1MiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwiZXJyIiwiY29kZSIsImhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCIsIk9USEVSX0NBVVNFIiwicmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4iLCJzZW5kVmVyaWZpY2F0aW9uRW1haWwiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiaGFuZGxlRmluZCIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZUdldCIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUVBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7QUFFTyxNQUFNQSxXQUFO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QU87QUFBRSxhQUFPLEtBQUsrRyxZQUFMLENBQWtCL0csR0FBbEIsQ0FBUDtBQUFnQyxLQUFsRjtBQUNBLFNBQUswRyxLQUFMLENBQVcsS0FBWCxFQUFrQixRQUFsQixFQUE0QjFHLE9BQU87QUFBRSxhQUFPLEtBQUt5RCxXQUFMLENBQWlCekQsR0FBakIsQ0FBUDtBQUErQixLQUFwRTtBQUNBLFNBQUswRyxLQUFMLENBQVcsTUFBWCxFQUFtQixRQUFuQixFQUE2QjFHLE9BQU87QUFBRSxhQUFPLEtBQUt5RCxXQUFMLENBQWlCekQsR0FBakIsQ0FBUDtBQUErQixLQUFyRTtBQUNBLFNBQUswRyxLQUFMLENBQVcsTUFBWCxFQUFtQixTQUFuQixFQUE4QjFHLE9BQU87QUFBRSxhQUFPLEtBQUsrRSxZQUFMLENBQWtCL0UsR0FBbEIsQ0FBUDtBQUFnQyxLQUF2RTtBQUNBLFNBQUswRyxLQUFMLENBQVcsTUFBWCxFQUFtQix1QkFBbkIsRUFBNEMxRyxPQUFPO0FBQUUsYUFBTyxLQUFLK0Ysa0JBQUwsQ0FBd0IvRixHQUF4QixDQUFQO0FBQXNDLEtBQTNGO0FBQ0EsU0FBSzBHLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLDJCQUFuQixFQUFnRDFHLE9BQU87QUFBRSxhQUFPLEtBQUtxRyw4QkFBTCxDQUFvQ3JHLEdBQXBDLENBQVA7QUFBa0QsS0FBM0c7QUFDQSxTQUFLMEcsS0FBTCxDQUFXLEtBQVgsRUFBa0IsaUJBQWxCLEVBQXFDMUcsT0FBTztBQUFFLGFBQU8sS0FBSzhFLG9CQUFMLENBQTBCOUUsR0FBMUIsQ0FBUDtBQUF3QyxLQUF0RjtBQUNEO0FBL1Q0Qzs7UUFBbENULFcsR0FBQUEsVyxFQVZiOztrQkE0VWVBLFciLCJmaWxlIjoiVXNlcnNSb3V0ZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGVzZSBtZXRob2RzIGhhbmRsZSB0aGUgVXNlci1yZWxhdGVkIHJvdXRlcy5cblxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IEFjY291bnRMb2Nrb3V0IGZyb20gJy4uL0FjY291bnRMb2Nrb3V0JztcbmltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCBBdXRoIGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IHBhc3N3b3JkQ3J5cHRvIGZyb20gJy4uL3Bhc3N3b3JkJztcblxuZXhwb3J0IGNsYXNzIFVzZXJzUm91dGVyIGV4dGVuZHMgQ2xhc3Nlc1JvdXRlciB7XG5cbiAgY2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnX1VzZXInO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYWxsIFwiX1wiIHByZWZpeGVkIHByb3BlcnRpZXMgZnJvbSBhbiBvYmplY3QsIGV4Y2VwdCBcIl9fdHlwZVwiXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmogQW4gb2JqZWN0LlxuICAgKi9cbiAgc3RhdGljIHJlbW92ZUhpZGRlblByb3BlcnRpZXMob2JqKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIC8vIFJlZ2V4cCBjb21lcyBmcm9tIFBhcnNlLk9iamVjdC5wcm90b3R5cGUudmFsaWRhdGVcbiAgICAgICAgaWYgKGtleSAhPT0gXCJfX3R5cGVcIiAmJiAhKC9eW0EtWmEtel1bMC05QS1aYS16X10qJC8pLnRlc3Qoa2V5KSkge1xuICAgICAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBwYXNzd29yZCByZXF1ZXN0IGluIGxvZ2luIGFuZCB2ZXJpZnlQYXNzd29yZFxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFVzZXIgb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBVc2UgcXVlcnkgcGFyYW1ldGVycyBpbnN0ZWFkIGlmIHByb3ZpZGVkIGluIHVybFxuICAgICAgbGV0IHBheWxvYWQgPSByZXEuYm9keTtcbiAgICAgIGlmICghcGF5bG9hZC51c2VybmFtZSAmJiByZXEucXVlcnkudXNlcm5hbWUgfHwgIXBheWxvYWQuZW1haWwgJiYgcmVxLnF1ZXJ5LmVtYWlsKSB7XG4gICAgICAgIHBheWxvYWQgPSByZXEucXVlcnk7XG4gICAgICB9XG4gICAgICBjb25zdCB7XG4gICAgICAgIHVzZXJuYW1lLFxuICAgICAgICBlbWFpbCxcbiAgICAgICAgcGFzc3dvcmQsXG4gICAgICB9ID0gcGF5bG9hZDtcblxuICAgICAgLy8gVE9ETzogdXNlIHRoZSByaWdodCBlcnJvciBjb2RlcyAvIGRlc2NyaXB0aW9ucy5cbiAgICAgIGlmICghdXNlcm5hbWUgJiYgIWVtYWlsKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5VU0VSTkFNRV9NSVNTSU5HLCAndXNlcm5hbWUvZW1haWwgaXMgcmVxdWlyZWQuJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXBhc3N3b3JkKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAncGFzc3dvcmQgaXMgcmVxdWlyZWQuJyk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHBhc3N3b3JkICE9PSAnc3RyaW5nJ1xuICAgICAgICB8fCBlbWFpbCAmJiB0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnXG4gICAgICAgIHx8IHVzZXJuYW1lICYmIHR5cGVvZiB1c2VybmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgfVxuXG4gICAgICBsZXQgdXNlcjtcbiAgICAgIGxldCBpc1ZhbGlkUGFzc3dvcmQgPSBmYWxzZTtcbiAgICAgIGxldCBxdWVyeTtcbiAgICAgIGlmIChlbWFpbCAmJiB1c2VybmFtZSkge1xuICAgICAgICBxdWVyeSA9IHsgZW1haWwsIHVzZXJuYW1lIH07XG4gICAgICB9IGVsc2UgaWYgKGVtYWlsKSB7XG4gICAgICAgIHF1ZXJ5ID0geyBlbWFpbCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnkgPSB7ICRvcjogW3sgdXNlcm5hbWUgfSwgeyBlbWFpbDogdXNlcm5hbWUgfV0gfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgcXVlcnkpXG4gICAgICAgIC50aGVuKChyZXN1bHRzKSA9PiB7XG4gICAgICAgICAgaWYgKCFyZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDEpIHsgLy8gY29ybmVyIGNhc2Ugd2hlcmUgdXNlcjEgaGFzIHVzZXJuYW1lID09IHVzZXIyIGVtYWlsXG4gICAgICAgICAgICByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIud2FybignVGhlcmUgaXMgYSB1c2VyIHdoaWNoIGVtYWlsIGlzIHRoZSBzYW1lIGFzIGFub3RoZXIgdXNlclxcJ3MgdXNlcm5hbWUsIGxvZ2dpbmcgaW4gYmFzZWQgb24gdXNlcm5hbWUnKTtcbiAgICAgICAgICAgIHVzZXIgPSByZXN1bHRzLmZpbHRlcigodXNlcikgPT4gdXNlci51c2VybmFtZSA9PT0gdXNlcm5hbWUpWzBdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcGFzc3dvcmRDcnlwdG8uY29tcGFyZShwYXNzd29yZCwgdXNlci5wYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChjb3JyZWN0KSA9PiB7XG4gICAgICAgICAgaXNWYWxpZFBhc3N3b3JkID0gY29ycmVjdDtcbiAgICAgICAgICBjb25zdCBhY2NvdW50TG9ja291dFBvbGljeSA9IG5ldyBBY2NvdW50TG9ja291dCh1c2VyLCByZXEuY29uZmlnKTtcbiAgICAgICAgICByZXR1cm4gYWNjb3VudExvY2tvdXRQb2xpY3kuaGFuZGxlTG9naW5BdHRlbXB0KGlzVmFsaWRQYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICBpZiAoIWlzVmFsaWRQYXNzd29yZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBFbnN1cmUgdGhlIHVzZXIgaXNuJ3QgbG9ja2VkIG91dFxuICAgICAgICAgIC8vIEEgbG9ja2VkIG91dCB1c2VyIHdvbid0IGJlIGFibGUgdG8gbG9naW5cbiAgICAgICAgICAvLyBUbyBsb2NrIGEgdXNlciBvdXQsIGp1c3Qgc2V0IHRoZSBBQ0wgdG8gYG1hc3RlcktleWAgb25seSAgKHt9KS5cbiAgICAgICAgICAvLyBFbXB0eSBBQ0wgaXMgT0tcbiAgICAgICAgICBpZiAoIXJlcS5hdXRoLmlzTWFzdGVyICYmIHVzZXIuQUNMICYmIE9iamVjdC5rZXlzKHVzZXIuQUNMKS5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVxLmNvbmZpZy52ZXJpZnlVc2VyRW1haWxzICYmIHJlcS5jb25maWcucHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCAmJiAhdXNlci5lbWFpbFZlcmlmaWVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTk9UX0ZPVU5ELCAnVXNlciBlbWFpbCBpcyBub3QgdmVyaWZpZWQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVsZXRlIHVzZXIucGFzc3dvcmQ7XG5cbiAgICAgICAgICAvLyBTb21ldGltZXMgdGhlIGF1dGhEYXRhIHN0aWxsIGhhcyBudWxsIG9uIHRoYXQga2V5c1xuICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wYXJzZS1jb21tdW5pdHkvcGFyc2Utc2VydmVyL2lzc3Vlcy85MzVcbiAgICAgICAgICBpZiAodXNlci5hdXRoRGF0YSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModXNlci5hdXRoRGF0YSkuZm9yRWFjaCgocHJvdmlkZXIpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh1c2VyKTtcbiAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlTWUocmVxKSB7XG4gICAgaWYgKCFyZXEuaW5mbyB8fCAhcmVxLmluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlc3Npb25Ub2tlbiA9IHJlcS5pbmZvLnNlc3Npb25Ub2tlbjtcbiAgICByZXR1cm4gcmVzdC5maW5kKHJlcS5jb25maWcsIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLCAnX1Nlc3Npb24nLFxuICAgICAgeyBzZXNzaW9uVG9rZW4gfSxcbiAgICAgIHsgaW5jbHVkZTogJ3VzZXInIH0sIHJlcS5pbmZvLmNsaWVudFNESylcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHxcbiAgICAgICAgICByZXNwb25zZS5yZXN1bHRzLmxlbmd0aCA9PSAwIHx8XG4gICAgICAgICAgIXJlc3BvbnNlLnJlc3VsdHNbMF0udXNlcikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB1c2VyID0gcmVzcG9uc2UucmVzdWx0c1swXS51c2VyO1xuICAgICAgICAgIC8vIFNlbmQgdG9rZW4gYmFjayBvbiB0aGUgbG9naW4sIGJlY2F1c2UgU0RLcyBleHBlY3QgdGhhdC5cbiAgICAgICAgICB1c2VyLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcblxuICAgICAgICAgIC8vIFJlbW92ZSBoaWRkZW4gcHJvcGVydGllcy5cbiAgICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBoYW5kbGVMb2dJbihyZXEpIHtcbiAgICBsZXQgdXNlcjtcbiAgICByZXR1cm4gdGhpcy5fYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSlcbiAgICAgIC50aGVuKChyZXMpID0+IHtcblxuICAgICAgICB1c2VyID0gcmVzO1xuXG4gICAgICAgIC8vIGhhbmRsZSBwYXNzd29yZCBleHBpcnkgcG9saWN5XG4gICAgICAgIGlmIChyZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UpIHtcbiAgICAgICAgICBsZXQgY2hhbmdlZEF0ID0gdXNlci5fcGFzc3dvcmRfY2hhbmdlZF9hdDtcblxuICAgICAgICAgIGlmICghY2hhbmdlZEF0KSB7XG4gICAgICAgICAgICAvLyBwYXNzd29yZCB3YXMgY3JlYXRlZCBiZWZvcmUgZXhwaXJ5IHBvbGljeSB3YXMgZW5hYmxlZC5cbiAgICAgICAgICAgIC8vIHNpbXBseSB1cGRhdGUgX1VzZXIgb2JqZWN0IHNvIHRoYXQgaXQgd2lsbCBzdGFydCBlbmZvcmNpbmcgZnJvbSBub3dcbiAgICAgICAgICAgIGNoYW5nZWRBdCA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICByZXEuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCB7IHVzZXJuYW1lOiB1c2VyLnVzZXJuYW1lIH0sXG4gICAgICAgICAgICAgIHsgX3Bhc3N3b3JkX2NoYW5nZWRfYXQ6IFBhcnNlLl9lbmNvZGUoY2hhbmdlZEF0KSB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgcGFzc3dvcmQgaGFzIGV4cGlyZWRcbiAgICAgICAgICAgIGlmIChjaGFuZ2VkQXQuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICAgICAgICBjaGFuZ2VkQXQgPSBuZXcgRGF0ZShjaGFuZ2VkQXQuaXNvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZXhwaXJ5IHRpbWUuXG4gICAgICAgICAgICBjb25zdCBleHBpcmVzQXQgPSBuZXcgRGF0ZShjaGFuZ2VkQXQuZ2V0VGltZSgpICsgODY0MDAwMDAgKiByZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlKTtcbiAgICAgICAgICAgIGlmIChleHBpcmVzQXQgPCBuZXcgRGF0ZSgpKSAvLyBmYWlsIG9mIGN1cnJlbnQgdGltZSBpcyBwYXN0IHBhc3N3b3JkIGV4cGlyeSB0aW1lXG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnWW91ciBwYXNzd29yZCBoYXMgZXhwaXJlZC4gUGxlYXNlIHJlc2V0IHlvdXIgcGFzc3dvcmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBzZXNzaW9uRGF0YSxcbiAgICAgICAgICBjcmVhdGVTZXNzaW9uXG4gICAgICAgIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24ocmVxLmNvbmZpZywge1xuICAgICAgICAgIHVzZXJJZDogdXNlci5vYmplY3RJZCwgY3JlYXRlZFdpdGg6IHtcbiAgICAgICAgICAgICdhY3Rpb24nOiAnbG9naW4nLFxuICAgICAgICAgICAgJ2F1dGhQcm92aWRlcic6ICdwYXNzd29yZCdcbiAgICAgICAgICB9LCBpbnN0YWxsYXRpb25JZDogcmVxLmluZm8uaW5zdGFsbGF0aW9uSWRcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdXNlci5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uRGF0YS5zZXNzaW9uVG9rZW47XG5cbiAgICAgICAgcmVxLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdChyZXEuY29uZmlnLCB1c2VyKTtcblxuICAgICAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlVmVyaWZ5UGFzc3dvcmQocmVxKSB7XG4gICAgcmV0dXJuIHRoaXMuX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdChyZXEpXG4gICAgICAudGhlbigodXNlcikgPT4ge1xuXG4gICAgICAgIC8vIFJlbW92ZSBoaWRkZW4gcHJvcGVydGllcy5cbiAgICAgICAgVXNlcnNSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyh1c2VyKTtcblxuICAgICAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gIH1cblxuICBoYW5kbGVMb2dPdXQocmVxKSB7XG4gICAgY29uc3Qgc3VjY2VzcyA9IHsgcmVzcG9uc2U6IHt9IH07XG4gICAgaWYgKHJlcS5pbmZvICYmIHJlcS5pbmZvLnNlc3Npb25Ub2tlbikge1xuICAgICAgcmV0dXJuIHJlc3QuZmluZChyZXEuY29uZmlnLCBBdXRoLm1hc3RlcihyZXEuY29uZmlnKSwgJ19TZXNzaW9uJyxcbiAgICAgICAgeyBzZXNzaW9uVG9rZW46IHJlcS5pbmZvLnNlc3Npb25Ub2tlbiB9LCB1bmRlZmluZWQsIHJlcS5pbmZvLmNsaWVudFNES1xuICAgICAgKS50aGVuKChyZWNvcmRzKSA9PiB7XG4gICAgICAgIGlmIChyZWNvcmRzLnJlc3VsdHMgJiYgcmVjb3Jkcy5yZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiByZXN0LmRlbChyZXEuY29uZmlnLCBBdXRoLm1hc3RlcihyZXEuY29uZmlnKSwgJ19TZXNzaW9uJyxcbiAgICAgICAgICAgIHJlY29yZHMucmVzdWx0c1swXS5vYmplY3RJZFxuICAgICAgICAgICkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHN1Y2Nlc3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc3VjY2Vzcyk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzdWNjZXNzKTtcbiAgfVxuXG4gIF90aHJvd09uQmFkRW1haWxDb25maWcocmVxKSB7XG4gICAgdHJ5IHtcbiAgICAgIENvbmZpZy52YWxpZGF0ZUVtYWlsQ29uZmlndXJhdGlvbih7XG4gICAgICAgIGVtYWlsQWRhcHRlcjogcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlci5hZGFwdGVyLFxuICAgICAgICBhcHBOYW1lOiByZXEuY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIHB1YmxpY1NlcnZlclVSTDogcmVxLmNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwsXG4gICAgICAgIGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uOiByZXEuY29uZmlnLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIC8vIE1heWJlIHdlIG5lZWQgYSBCYWQgQ29uZmlndXJhdGlvbiBlcnJvciwgYnV0IHRoZSBTREtzIHdvbid0IHVuZGVyc3RhbmQgaXQuIEZvciBub3csIEludGVybmFsIFNlcnZlciBFcnJvci5cbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0FuIGFwcE5hbWUsIHB1YmxpY1NlcnZlclVSTCwgYW5kIGVtYWlsQWRhcHRlciBhcmUgcmVxdWlyZWQgZm9yIHBhc3N3b3JkIHJlc2V0IGFuZCBlbWFpbCB2ZXJpZmljYXRpb24gZnVuY3Rpb25hbGl0eS4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlUmVzZXRSZXF1ZXN0KHJlcSkge1xuICAgIHRoaXMuX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpO1xuXG4gICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHk7XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX01JU1NJTkcsIFwieW91IG11c3QgcHJvdmlkZSBhbiBlbWFpbFwiKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0VNQUlMX0FERFJFU1MsICd5b3UgbXVzdCBwcm92aWRlIGEgdmFsaWQgZW1haWwgc3RyaW5nJyk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlcjtcbiAgICByZXR1cm4gdXNlckNvbnRyb2xsZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChlbWFpbCkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgcmVzcG9uc2U6IHt9XG4gICAgICB9KTtcbiAgICB9LCBlcnIgPT4ge1xuICAgICAgaWYgKGVyci5jb2RlID09PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsIGBObyB1c2VyIGZvdW5kIHdpdGggZW1haWwgJHtlbWFpbH0uYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVWZXJpZmljYXRpb25FbWFpbFJlcXVlc3QocmVxKSB7XG4gICAgdGhpcy5fdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSk7XG5cbiAgICBjb25zdCB7IGVtYWlsIH0gPSByZXEuYm9keTtcbiAgICBpZiAoIWVtYWlsKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTUlTU0lORywgJ3lvdSBtdXN0IHByb3ZpZGUgYW4gZW1haWwnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0VNQUlMX0FERFJFU1MsICd5b3UgbXVzdCBwcm92aWRlIGEgdmFsaWQgZW1haWwgc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCB7IGVtYWlsOiBlbWFpbCB9KS50aGVuKChyZXN1bHRzKSA9PiB7XG4gICAgICBpZiAoIXJlc3VsdHMubGVuZ3RoIHx8IHJlc3VsdHMubGVuZ3RoIDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTk9UX0ZPVU5ELCBgTm8gdXNlciBmb3VuZCB3aXRoIGVtYWlsICR7ZW1haWx9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCB1c2VyID0gcmVzdWx0c1swXTtcblxuICAgICAgLy8gcmVtb3ZlIHBhc3N3b3JkIGZpZWxkLCBtZXNzZXMgd2l0aCBzYXZpbmcgb24gcG9zdGdyZXNcbiAgICAgIGRlbGV0ZSB1c2VyLnBhc3N3b3JkO1xuXG4gICAgICBpZiAodXNlci5lbWFpbFZlcmlmaWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgYEVtYWlsICR7ZW1haWx9IGlzIGFscmVhZHkgdmVyaWZpZWQuYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlcjtcbiAgICAgIHJldHVybiB1c2VyQ29udHJvbGxlci5yZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbih1c2VyKS50aGVuKCgpID0+IHtcbiAgICAgICAgdXNlckNvbnRyb2xsZXIuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHVzZXIpO1xuICAgICAgICByZXR1cm4geyByZXNwb25zZToge30gfTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzJywgcmVxID0+IHsgcmV0dXJuIHRoaXMuaGFuZGxlRmluZChyZXEpOyB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91c2VycycsIHJlcSA9PiB7IHJldHVybiB0aGlzLmhhbmRsZUNyZWF0ZShyZXEpOyB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzL21lJywgcmVxID0+IHsgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTsgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy91c2Vycy86b2JqZWN0SWQnLCByZXEgPT4geyByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTsgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy91c2Vycy86b2JqZWN0SWQnLCByZXEgPT4geyByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTsgfSk7XG4gICAgdGhpcy5yb3V0ZSgnREVMRVRFJywgJy91c2Vycy86b2JqZWN0SWQnLCByZXEgPT4geyByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTsgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9sb2dpbicsIHJlcSA9PiB7IHJldHVybiB0aGlzLmhhbmRsZUxvZ0luKHJlcSk7IH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ2luJywgcmVxID0+IHsgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW4ocmVxKTsgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvbG9nb3V0JywgcmVxID0+IHsgcmV0dXJuIHRoaXMuaGFuZGxlTG9nT3V0KHJlcSk7IH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL3JlcXVlc3RQYXNzd29yZFJlc2V0JywgcmVxID0+IHsgcmV0dXJuIHRoaXMuaGFuZGxlUmVzZXRSZXF1ZXN0KHJlcSk7IH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL3ZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCcsIHJlcSA9PiB7IHJldHVybiB0aGlzLmhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdChyZXEpOyB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3ZlcmlmeVBhc3N3b3JkJywgcmVxID0+IHsgcmV0dXJuIHRoaXMuaGFuZGxlVmVyaWZ5UGFzc3dvcmQocmVxKTsgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVXNlcnNSb3V0ZXI7XG4iXX0=
640
+ exports.UsersRouter = UsersRouter;
641
+ var _default = exports.default = UsersRouter;
642
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbm9kZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX0NvbmZpZyIsIl9BY2NvdW50TG9ja291dCIsIl9DbGFzc2VzUm91dGVyIiwiX3Jlc3QiLCJfQXV0aCIsIl9wYXNzd29yZCIsIl90cmlnZ2VycyIsIl9taWRkbGV3YXJlcyIsIl9SZXN0V3JpdGUiLCJfbG9nZ2VyIiwiX0Vycm9yIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiVXNlcnNSb3V0ZXIiLCJDbGFzc2VzUm91dGVyIiwiY2xhc3NOYW1lIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsIm9iaiIsImtleSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInRlc3QiLCJfc2FuaXRpemVBdXRoRGF0YSIsInVzZXIiLCJwYXNzd29yZCIsImF1dGhEYXRhIiwia2V5cyIsImZvckVhY2giLCJwcm92aWRlciIsImxlbmd0aCIsIl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QiLCJyZXEiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInBheWxvYWQiLCJib2R5IiwidXNlcm5hbWUiLCJxdWVyeSIsImVtYWlsIiwiaWdub3JlRW1haWxWZXJpZmljYXRpb24iLCJQYXJzZSIsIkVycm9yIiwiVVNFUk5BTUVfTUlTU0lORyIsIlBBU1NXT1JEX01JU1NJTkciLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiaXNWYWxpZFBhc3N3b3JkIiwiJG9yIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwiQXV0aCIsIm1haW50ZW5hbmNlIiwidGhlbiIsInJlc3VsdHMiLCJsb2dnZXJDb250cm9sbGVyIiwid2FybiIsImZpbHRlciIsInBhc3N3b3JkQ3J5cHRvIiwiY29tcGFyZSIsImNvcnJlY3QiLCJhY2NvdW50TG9ja291dFBvbGljeSIsIkFjY291bnRMb2Nrb3V0IiwiaGFuZGxlTG9naW5BdHRlbXB0IiwiYXV0aCIsImlzTWFzdGVyIiwiQUNMIiwicmVxdWVzdCIsIm1hc3RlciIsImlwIiwiaW5zdGFsbGF0aW9uSWQiLCJvYmplY3QiLCJVc2VyIiwiZnJvbUpTT04iLCJhc3NpZ24iLCJpc01haW50ZW5hbmNlIiwidmVyaWZ5VXNlckVtYWlscyIsInByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwiLCJlbWFpbFZlcmlmaWVkIiwiRU1BSUxfTk9UX0ZPVU5EIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZU1lIiwiaW5mbyIsInNlc3Npb25Ub2tlbiIsImNyZWF0ZVNhbml0aXplZEVycm9yIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwicmVzdCIsImluY2x1ZGUiLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzcG9uc2UiLCJoYW5kbGVMb2dJbiIsImNoZWNrSWZVc2VySGFzUHJvdmlkZWRDb25maWd1cmVkUHJvdmlkZXJzRm9yTG9naW4iLCJhdXRoRGF0YVJlc3BvbnNlIiwidmFsaWRhdGVkQXV0aERhdGEiLCJyZXMiLCJoYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24iLCJSZXN0V3JpdGUiLCJvYmplY3RJZCIsInBhc3N3b3JkUG9saWN5IiwibWF4UGFzc3dvcmRBZ2UiLCJjaGFuZ2VkQXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsIkRhdGUiLCJ1cGRhdGUiLCJfZW5jb2RlIiwiX190eXBlIiwiaXNvIiwiZXhwaXJlc0F0IiwiZ2V0VGltZSIsImZpbGVzQ29udHJvbGxlciIsImV4cGFuZEZpbGVzSW5PYmplY3QiLCJtYXliZVJ1blRyaWdnZXIiLCJUcmlnZ2VyVHlwZXMiLCJiZWZvcmVMb2dpbiIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsInVzZXJJZCIsImNyZWF0ZWRXaXRoIiwiYWN0aW9uIiwiYXV0aFByb3ZpZGVyIiwiYWZ0ZXJMb2dpblVzZXIiLCJhZnRlckxvZ2luIiwiYXV0aERhdGFNYW5hZ2VyIiwicnVuQWZ0ZXJGaW5kIiwiaGFuZGxlTG9nSW5BcyIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJJTlZBTElEX1ZBTFVFIiwicXVlcnlSZXN1bHRzIiwiaGFuZGxlVmVyaWZ5UGFzc3dvcmQiLCJoYW5kbGVMb2dPdXQiLCJzdWNjZXNzIiwicmVjb3JkcyIsInVuZGVmaW5lZCIsImRlbCIsImFmdGVyTG9nb3V0IiwiU2Vzc2lvbiIsIl90aHJvd09uQmFkRW1haWxDb25maWciLCJDb25maWciLCJ2YWxpZGF0ZUVtYWlsQ29uZmlndXJhdGlvbiIsImVtYWlsQWRhcHRlciIsInVzZXJDb250cm9sbGVyIiwiYWRhcHRlciIsImFwcE5hbWUiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJfcHVibGljU2VydmVyVVJMIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiaGFuZGxlUmVzZXRSZXF1ZXN0IiwidG9rZW4iLCJFTUFJTF9NSVNTSU5HIiwidXNlclJlc3VsdHMiLCJ1c2VyRGF0YSIsIl9wZXJpc2hhYmxlX3Rva2VuIiwiX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCIsIiRsdCIsIiRleGlzdHMiLCJsaW1pdCIsIklOVkFMSURfRU1BSUxfQUREUkVTUyIsImluZmxhdGUiLCJiZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCIsInNlbmRQYXNzd29yZFJlc2V0RW1haWwiLCJlcnIiLCJjb2RlIiwicmVzZXRQYXNzd29yZFN1Y2Nlc3NPbkludmFsaWRFbWFpbCIsIm1lc3NhZ2UiLCJoYW5kbGVWZXJpZmljYXRpb25FbWFpbFJlcXVlc3QiLCJPVEhFUl9DQVVTRSIsInNlbmQiLCJyZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbiIsInNlbmRWZXJpZmljYXRpb25FbWFpbCIsImhhbmRsZUNoYWxsZW5nZSIsImNoYWxsZW5nZURhdGEiLCJwYXJzZVVzZXIiLCJpZCIsImZpbmRVc2Vyc1dpdGhBdXRoRGF0YSIsImdldFJlcXVlc3RPYmplY3QiLCJpc0NoYWxsZW5nZSIsInZhbGlkYXRvciIsImdldFZhbGlkYXRvckZvclByb3ZpZGVyIiwidmFsaWRhdG9yUmVzcG9uc2UiLCJsb2dnZXIiLCJhY2MiLCJzb3J0IiwiYXV0aEFkYXB0ZXIiLCJjaGFsbGVuZ2UiLCJwcm92aWRlckNoYWxsZW5nZVJlc3BvbnNlIiwicmVzb2x2ZUVycm9yIiwiU0NSSVBUX0ZBSUxFRCIsInVzZXJTdHJpbmciLCJKU09OIiwic3RyaW5naWZ5IiwiYXV0aGVudGljYXRpb25TdGVwIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImhhbmRsZUZpbmQiLCJwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kiLCJoYW5kbGVDcmVhdGUiLCJoYW5kbGVHZXQiLCJoYW5kbGVVcGRhdGUiLCJoYW5kbGVEZWxldGUiLCJleHBvcnRzIiwiX2RlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvUm91dGVycy9Vc2Vyc1JvdXRlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGVzZSBtZXRob2RzIGhhbmRsZSB0aGUgVXNlci1yZWxhdGVkIHJvdXRlcy5cblxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IEFjY291bnRMb2Nrb3V0IGZyb20gJy4uL0FjY291bnRMb2Nrb3V0JztcbmltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCBBdXRoIGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IHBhc3N3b3JkQ3J5cHRvIGZyb20gJy4uL3Bhc3N3b3JkJztcbmltcG9ydCB7XG4gIG1heWJlUnVuVHJpZ2dlcixcbiAgVHlwZXMgYXMgVHJpZ2dlclR5cGVzLFxuICBnZXRSZXF1ZXN0T2JqZWN0LFxuICByZXNvbHZlRXJyb3IsXG4gIGluZmxhdGUsXG59IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCB7IHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCBSZXN0V3JpdGUgZnJvbSAnLi4vUmVzdFdyaXRlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBjcmVhdGVTYW5pdGl6ZWRFcnJvciB9IGZyb20gJy4uL0Vycm9yJztcblxuZXhwb3J0IGNsYXNzIFVzZXJzUm91dGVyIGV4dGVuZHMgQ2xhc3Nlc1JvdXRlciB7XG4gIGNsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ19Vc2VyJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFsbCBcIl9cIiBwcmVmaXhlZCBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0LCBleGNlcHQgXCJfX3R5cGVcIlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqIEFuIG9iamVjdC5cbiAgICovXG4gIHN0YXRpYyByZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKG9iaikge1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgIC8vIFJlZ2V4cCBjb21lcyBmcm9tIFBhcnNlLk9iamVjdC5wcm90b3R5cGUudmFsaWRhdGVcbiAgICAgICAgaWYgKGtleSAhPT0gJ19fdHlwZScgJiYgIS9eW0EtWmEtel1bMC05QS1aYS16X10qJC8udGVzdChrZXkpKSB7XG4gICAgICAgICAgZGVsZXRlIG9ialtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFmdGVyIHJldHJpZXZpbmcgYSB1c2VyIGRpcmVjdGx5IGZyb20gdGhlIGRhdGFiYXNlLCB3ZSBuZWVkIHRvIHJlbW92ZSB0aGVcbiAgICogcGFzc3dvcmQgZnJvbSB0aGUgb2JqZWN0IChmb3Igc2VjdXJpdHkpLCBhbmQgZml4IGFuIGlzc3VlIHNvbWUgU0RLcyBoYXZlXG4gICAqIHdpdGggbnVsbCB2YWx1ZXNcbiAgICovXG4gIF9zYW5pdGl6ZUF1dGhEYXRhKHVzZXIpIHtcbiAgICBkZWxldGUgdXNlci5wYXNzd29yZDtcblxuICAgIC8vIFNvbWV0aW1lcyB0aGUgYXV0aERhdGEgc3RpbGwgaGFzIG51bGwgb24gdGhhdCBrZXlzXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BhcnNlLWNvbW11bml0eS9wYXJzZS1zZXJ2ZXIvaXNzdWVzLzkzNVxuICAgIGlmICh1c2VyLmF1dGhEYXRhKSB7XG4gICAgICBPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgICAgaWYgKHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5sZW5ndGggPT0gMCkge1xuICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgcGFzc3dvcmQgcmVxdWVzdCBpbiBsb2dpbiBhbmQgdmVyaWZ5UGFzc3dvcmRcbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcSBUaGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBVc2VyIG9iamVjdFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdChyZXEpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gVXNlIHF1ZXJ5IHBhcmFtZXRlcnMgaW5zdGVhZCBpZiBwcm92aWRlZCBpbiB1cmxcbiAgICAgIGxldCBwYXlsb2FkID0gcmVxLmJvZHkgfHwge307XG4gICAgICBpZiAoXG4gICAgICAgICghcGF5bG9hZC51c2VybmFtZSAmJiByZXEucXVlcnkgJiYgcmVxLnF1ZXJ5LnVzZXJuYW1lKSB8fFxuICAgICAgICAoIXBheWxvYWQuZW1haWwgJiYgcmVxLnF1ZXJ5ICYmIHJlcS5xdWVyeS5lbWFpbClcbiAgICAgICkge1xuICAgICAgICBwYXlsb2FkID0gcmVxLnF1ZXJ5O1xuICAgICAgfVxuICAgICAgY29uc3QgeyB1c2VybmFtZSwgZW1haWwsIHBhc3N3b3JkLCBpZ25vcmVFbWFpbFZlcmlmaWNhdGlvbiB9ID0gcGF5bG9hZDtcblxuICAgICAgLy8gVE9ETzogdXNlIHRoZSByaWdodCBlcnJvciBjb2RlcyAvIGRlc2NyaXB0aW9ucy5cbiAgICAgIGlmICghdXNlcm5hbWUgJiYgIWVtYWlsKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5VU0VSTkFNRV9NSVNTSU5HLCAndXNlcm5hbWUvZW1haWwgaXMgcmVxdWlyZWQuJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXBhc3N3b3JkKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAncGFzc3dvcmQgaXMgcmVxdWlyZWQuJyk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBwYXNzd29yZCAhPT0gJ3N0cmluZycgfHxcbiAgICAgICAgKGVtYWlsICYmIHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHx8XG4gICAgICAgICh1c2VybmFtZSAmJiB0eXBlb2YgdXNlcm5hbWUgIT09ICdzdHJpbmcnKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHVzZXI7XG4gICAgICBsZXQgaXNWYWxpZFBhc3N3b3JkID0gZmFsc2U7XG4gICAgICBsZXQgcXVlcnk7XG4gICAgICBpZiAoZW1haWwgJiYgdXNlcm5hbWUpIHtcbiAgICAgICAgcXVlcnkgPSB7IGVtYWlsLCB1c2VybmFtZSB9O1xuICAgICAgfSBlbHNlIGlmIChlbWFpbCkge1xuICAgICAgICBxdWVyeSA9IHsgZW1haWwgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXJ5ID0geyAkb3I6IFt7IHVzZXJuYW1lIH0sIHsgZW1haWw6IHVzZXJuYW1lIH1dIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgICAuZmluZCgnX1VzZXInLCBxdWVyeSwge30sIEF1dGgubWFpbnRlbmFuY2UocmVxLmNvbmZpZykpXG4gICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgIGlmICghcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAvLyBjb3JuZXIgY2FzZSB3aGVyZSB1c2VyMSBoYXMgdXNlcm5hbWUgPT0gdXNlcjIgZW1haWxcbiAgICAgICAgICAgIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlci53YXJuKFxuICAgICAgICAgICAgICBcIlRoZXJlIGlzIGEgdXNlciB3aGljaCBlbWFpbCBpcyB0aGUgc2FtZSBhcyBhbm90aGVyIHVzZXIncyB1c2VybmFtZSwgbG9nZ2luZyBpbiBiYXNlZCBvbiB1c2VybmFtZVwiXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdXNlciA9IHJlc3VsdHMuZmlsdGVyKHVzZXIgPT4gdXNlci51c2VybmFtZSA9PT0gdXNlcm5hbWUpWzBdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcGFzc3dvcmRDcnlwdG8uY29tcGFyZShwYXNzd29yZCwgdXNlci5wYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNvcnJlY3QgPT4ge1xuICAgICAgICAgIGlzVmFsaWRQYXNzd29yZCA9IGNvcnJlY3Q7XG4gICAgICAgICAgY29uc3QgYWNjb3VudExvY2tvdXRQb2xpY3kgPSBuZXcgQWNjb3VudExvY2tvdXQodXNlciwgcmVxLmNvbmZpZyk7XG4gICAgICAgICAgcmV0dXJuIGFjY291bnRMb2Nrb3V0UG9saWN5LmhhbmRsZUxvZ2luQXR0ZW1wdChpc1ZhbGlkUGFzc3dvcmQpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgaWYgKCFpc1ZhbGlkUGFzc3dvcmQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gRW5zdXJlIHRoZSB1c2VyIGlzbid0IGxvY2tlZCBvdXRcbiAgICAgICAgICAvLyBBIGxvY2tlZCBvdXQgdXNlciB3b24ndCBiZSBhYmxlIHRvIGxvZ2luXG4gICAgICAgICAgLy8gVG8gbG9jayBhIHVzZXIgb3V0LCBqdXN0IHNldCB0aGUgQUNMIHRvIGBtYXN0ZXJLZXlgIG9ubHkgICh7fSkuXG4gICAgICAgICAgLy8gRW1wdHkgQUNMIGlzIE9LXG4gICAgICAgICAgaWYgKCFyZXEuYXV0aC5pc01hc3RlciAmJiB1c2VyLkFDTCAmJiBPYmplY3Qua2V5cyh1c2VyLkFDTCkubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ3JlYXRlIHJlcXVlc3Qgb2JqZWN0IGZvciB2ZXJpZmljYXRpb24gZnVuY3Rpb25zXG4gICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgIG1hc3RlcjogcmVxLmF1dGguaXNNYXN0ZXIsXG4gICAgICAgICAgICBpcDogcmVxLmNvbmZpZy5pcCxcbiAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiByZXEuYXV0aC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgIG9iamVjdDogUGFyc2UuVXNlci5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1VzZXInIH0sIHVzZXIpKSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLy8gSWYgcmVxdWVzdCBkb2Vzbid0IHVzZSBtYXN0ZXIgb3IgbWFpbnRlbmFuY2Uga2V5IHdpdGggaWdub3JpbmcgZW1haWwgdmVyaWZpY2F0aW9uXG4gICAgICAgICAgaWYgKCEoKHJlcS5hdXRoLmlzTWFzdGVyIHx8IHJlcS5hdXRoLmlzTWFpbnRlbmFuY2UpICYmIGlnbm9yZUVtYWlsVmVyaWZpY2F0aW9uKSkge1xuXG4gICAgICAgICAgICAvLyBHZXQgdmVyaWZpY2F0aW9uIGNvbmRpdGlvbnMgd2hpY2ggY2FuIGJlIGJvb2xlYW5zIG9yIGZ1bmN0aW9uczsgdGhlIHB1cnBvc2Ugb2YgdGhpcyBhc3luYy9hd2FpdFxuICAgICAgICAgICAgLy8gc3RydWN0dXJlIGlzIHRvIGF2b2lkIHVubmVjZXNzYXJpbHkgZXhlY3V0aW5nIHN1YnNlcXVlbnQgZnVuY3Rpb25zIGlmIHByZXZpb3VzIG9uZXMgZmFpbCBpbiB0aGVcbiAgICAgICAgICAgIC8vIGNvbmRpdGlvbmFsIHN0YXRlbWVudCBiZWxvdywgYXMgYSBkZXZlbG9wZXIgbWF5IGRlY2lkZSB0byBleGVjdXRlIGV4cGVuc2l2ZSBvcGVyYXRpb25zIGluIHRoZW1cbiAgICAgICAgICAgIGNvbnN0IHZlcmlmeVVzZXJFbWFpbHMgPSBhc3luYyAoKSA9PiByZXEuY29uZmlnLnZlcmlmeVVzZXJFbWFpbHMgPT09IHRydWUgfHwgKHR5cGVvZiByZXEuY29uZmlnLnZlcmlmeVVzZXJFbWFpbHMgPT09ICdmdW5jdGlvbicgJiYgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHJlcS5jb25maWcudmVyaWZ5VXNlckVtYWlscyhyZXF1ZXN0KSkgPT09IHRydWUpO1xuICAgICAgICAgICAgY29uc3QgcHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCA9IGFzeW5jICgpID0+IHJlcS5jb25maWcucHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCA9PT0gdHJ1ZSB8fCAodHlwZW9mIHJlcS5jb25maWcucHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCA9PT0gJ2Z1bmN0aW9uJyAmJiBhd2FpdCBQcm9taXNlLnJlc29sdmUocmVxLmNvbmZpZy5wcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsKHJlcXVlc3QpKSA9PT0gdHJ1ZSk7XG4gICAgICAgICAgICBpZiAoYXdhaXQgdmVyaWZ5VXNlckVtYWlscygpICYmIGF3YWl0IHByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwoKSAmJiAhdXNlci5lbWFpbFZlcmlmaWVkKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsICdVc2VyIGVtYWlsIGlzIG5vdCB2ZXJpZmllZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLl9zYW5pdGl6ZUF1dGhEYXRhKHVzZXIpO1xuXG4gICAgICAgICAgcmV0dXJuIHJlc29sdmUodXNlcik7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlTWUocmVxKSB7XG4gICAgaWYgKCFyZXEuaW5mbyB8fCAhcmVxLmluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgICB0aHJvdyBjcmVhdGVTYW5pdGl6ZWRFcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nLCByZXEuY29uZmlnKTtcbiAgICB9XG4gICAgY29uc3Qgc2Vzc2lvblRva2VuID0gcmVxLmluZm8uc2Vzc2lvblRva2VuO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuIH0sXG4gICAgICAgIHsgaW5jbHVkZTogJ3VzZXInIH0sXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCB8fCAhcmVzcG9uc2UucmVzdWx0c1swXS51c2VyKSB7XG4gICAgICAgICAgdGhyb3cgY3JlYXRlU2FuaXRpemVkRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJywgcmVxLmNvbmZpZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgdXNlciA9IHJlc3BvbnNlLnJlc3VsdHNbMF0udXNlcjtcbiAgICAgICAgICAvLyBTZW5kIHRva2VuIGJhY2sgb24gdGhlIGxvZ2luLCBiZWNhdXNlIFNES3MgZXhwZWN0IHRoYXQuXG4gICAgICAgICAgdXNlci5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uVG9rZW47XG5cbiAgICAgICAgICAvLyBSZW1vdmUgaGlkZGVuIHByb3BlcnRpZXMuXG4gICAgICAgICAgVXNlcnNSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyh1c2VyKTtcbiAgICAgICAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUxvZ0luKHJlcSkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKTtcbiAgICBjb25zdCBhdXRoRGF0YSA9IHJlcS5ib2R5ICYmIHJlcS5ib2R5LmF1dGhEYXRhO1xuICAgIC8vIENoZWNrIGlmIHVzZXIgaGFzIHByb3ZpZGVkIHRoZWlyIHJlcXVpcmVkIGF1dGggcHJvdmlkZXJzXG4gICAgQXV0aC5jaGVja0lmVXNlckhhc1Byb3ZpZGVkQ29uZmlndXJlZFByb3ZpZGVyc0ZvckxvZ2luKFxuICAgICAgcmVxLFxuICAgICAgYXV0aERhdGEsXG4gICAgICB1c2VyLmF1dGhEYXRhLFxuICAgICAgcmVxLmNvbmZpZ1xuICAgICk7XG5cbiAgICBsZXQgYXV0aERhdGFSZXNwb25zZTtcbiAgICBsZXQgdmFsaWRhdGVkQXV0aERhdGE7XG4gICAgaWYgKGF1dGhEYXRhKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBBdXRoLmhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbihcbiAgICAgICAgYXV0aERhdGEsXG4gICAgICAgIG5ldyBSZXN0V3JpdGUoXG4gICAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHsgb2JqZWN0SWQ6IHVzZXIub2JqZWN0SWQgfSxcbiAgICAgICAgICByZXEuYm9keSB8fCB7fSxcbiAgICAgICAgICB1c2VyLFxuICAgICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgICAgICksXG4gICAgICAgIHVzZXJcbiAgICAgICk7XG4gICAgICBhdXRoRGF0YVJlc3BvbnNlID0gcmVzLmF1dGhEYXRhUmVzcG9uc2U7XG4gICAgICB2YWxpZGF0ZWRBdXRoRGF0YSA9IHJlcy5hdXRoRGF0YTtcbiAgICB9XG5cbiAgICAvLyBoYW5kbGUgcGFzc3dvcmQgZXhwaXJ5IHBvbGljeVxuICAgIGlmIChyZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UpIHtcbiAgICAgIGxldCBjaGFuZ2VkQXQgPSB1c2VyLl9wYXNzd29yZF9jaGFuZ2VkX2F0O1xuXG4gICAgICBpZiAoIWNoYW5nZWRBdCkge1xuICAgICAgICAvLyBwYXNzd29yZCB3YXMgY3JlYXRlZCBiZWZvcmUgZXhwaXJ5IHBvbGljeSB3YXMgZW5hYmxlZC5cbiAgICAgICAgLy8gc2ltcGx5IHVwZGF0ZSBfVXNlciBvYmplY3Qgc28gdGhhdCBpdCB3aWxsIHN0YXJ0IGVuZm9yY2luZyBmcm9tIG5vd1xuICAgICAgICBjaGFuZ2VkQXQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICByZXEuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHsgdXNlcm5hbWU6IHVzZXIudXNlcm5hbWUgfSxcbiAgICAgICAgICB7IF9wYXNzd29yZF9jaGFuZ2VkX2F0OiBQYXJzZS5fZW5jb2RlKGNoYW5nZWRBdCkgfVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgcGFzc3dvcmQgaGFzIGV4cGlyZWRcbiAgICAgICAgaWYgKGNoYW5nZWRBdC5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgY2hhbmdlZEF0ID0gbmV3IERhdGUoY2hhbmdlZEF0Lmlzbyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBleHBpcnkgdGltZS5cbiAgICAgICAgY29uc3QgZXhwaXJlc0F0ID0gbmV3IERhdGUoXG4gICAgICAgICAgY2hhbmdlZEF0LmdldFRpbWUoKSArIDg2NDAwMDAwICogcmVxLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZVxuICAgICAgICApO1xuICAgICAgICBpZiAoZXhwaXJlc0F0IDwgbmV3IERhdGUoKSlcbiAgICAgICAgLy8gZmFpbCBvZiBjdXJyZW50IHRpbWUgaXMgcGFzdCBwYXNzd29yZCBleHBpcnkgdGltZVxuICAgICAgICB7IHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICdZb3VyIHBhc3N3b3JkIGhhcyBleHBpcmVkLiBQbGVhc2UgcmVzZXQgeW91ciBwYXNzd29yZC4nXG4gICAgICAgICk7IH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgaGlkZGVuIHByb3BlcnRpZXMuXG4gICAgVXNlcnNSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyh1c2VyKTtcblxuICAgIGF3YWl0IHJlcS5jb25maWcuZmlsZXNDb250cm9sbGVyLmV4cGFuZEZpbGVzSW5PYmplY3QocmVxLmNvbmZpZywgdXNlcik7XG5cbiAgICAvLyBCZWZvcmUgbG9naW4gdHJpZ2dlcjsgdGhyb3dzIGlmIGZhaWx1cmVcbiAgICBhd2FpdCBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYmVmb3JlTG9naW4sXG4gICAgICByZXEuYXV0aCxcbiAgICAgIFBhcnNlLlVzZXIuZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19Vc2VyJyB9LCB1c2VyKSksXG4gICAgICBudWxsLFxuICAgICAgcmVxLmNvbmZpZyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApO1xuXG4gICAgLy8gSWYgd2UgaGF2ZSBzb21lIG5ldyB2YWxpZGF0ZWQgYXV0aERhdGEgdXBkYXRlIGRpcmVjdGx5XG4gICAgaWYgKHZhbGlkYXRlZEF1dGhEYXRhICYmIE9iamVjdC5rZXlzKHZhbGlkYXRlZEF1dGhEYXRhKS5sZW5ndGgpIHtcbiAgICAgIGF3YWl0IHJlcS5jb25maWcuZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAnX1VzZXInLFxuICAgICAgICB7IG9iamVjdElkOiB1c2VyLm9iamVjdElkIH0sXG4gICAgICAgIHsgYXV0aERhdGE6IHZhbGlkYXRlZEF1dGhEYXRhIH0sXG4gICAgICAgIHt9XG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IFJlc3RXcml0ZS5jcmVhdGVTZXNzaW9uKHJlcS5jb25maWcsIHtcbiAgICAgIHVzZXJJZDogdXNlci5vYmplY3RJZCxcbiAgICAgIGNyZWF0ZWRXaXRoOiB7XG4gICAgICAgIGFjdGlvbjogJ2xvZ2luJyxcbiAgICAgICAgYXV0aFByb3ZpZGVyOiAncGFzc3dvcmQnLFxuICAgICAgfSxcbiAgICAgIGluc3RhbGxhdGlvbklkOiByZXEuaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICB9KTtcblxuICAgIHVzZXIuc2Vzc2lvblRva2VuID0gc2Vzc2lvbkRhdGEuc2Vzc2lvblRva2VuO1xuXG4gICAgYXdhaXQgY3JlYXRlU2Vzc2lvbigpO1xuXG4gICAgY29uc3QgYWZ0ZXJMb2dpblVzZXIgPSBQYXJzZS5Vc2VyLmZyb21KU09OKE9iamVjdC5hc3NpZ24oeyBjbGFzc05hbWU6ICdfVXNlcicgfSwgdXNlcikpO1xuICAgIGF3YWl0IG1heWJlUnVuVHJpZ2dlcihcbiAgICAgIFRyaWdnZXJUeXBlcy5hZnRlckxvZ2luLFxuICAgICAgeyAuLi5yZXEuYXV0aCwgdXNlcjogYWZ0ZXJMb2dpblVzZXIgfSxcbiAgICAgIGFmdGVyTG9naW5Vc2VyLFxuICAgICAgbnVsbCxcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgKTtcblxuICAgIGlmIChhdXRoRGF0YVJlc3BvbnNlKSB7XG4gICAgICB1c2VyLmF1dGhEYXRhUmVzcG9uc2UgPSBhdXRoRGF0YVJlc3BvbnNlO1xuICAgIH1cbiAgICBhd2FpdCByZXEuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5ydW5BZnRlckZpbmQocmVxLCB1c2VyLmF1dGhEYXRhKTtcblxuICAgIHJldHVybiB7IHJlc3BvbnNlOiB1c2VyIH07XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBhbGxvd3MgbWFzdGVyLWtleSBjbGllbnRzIHRvIGNyZWF0ZSB1c2VyIHNlc3Npb25zIHdpdGhvdXQgYWNjZXNzIHRvXG4gICAqIHVzZXIgY3JlZGVudGlhbHMuIFRoaXMgZW5hYmxlcyBzeXN0ZW1zIHRoYXQgY2FuIGF1dGhlbnRpY2F0ZSBhY2Nlc3MgYW5vdGhlclxuICAgKiB3YXkgKEFQSSBrZXksIGFwcCBhZG1pbmlzdHJhdG9ycykgdG8gYWN0IG9uIGEgdXNlcidzIGJlaGFsZi5cbiAgICpcbiAgICogV2UgY3JlYXRlIGEgbmV3IHNlc3Npb24gcmF0aGVyIHRoYW4gbG9va2luZyBmb3IgYW4gZXhpc3Rpbmcgc2Vzc2lvbjsgd2VcbiAgICogd2FudCB0aGlzIHRvIHdvcmsgaW4gc2l0dWF0aW9ucyB3aGVyZSB0aGUgdXNlciBpcyBsb2dnZWQgb3V0IG9uIGFsbFxuICAgKiBkZXZpY2VzLCBzaW5jZSB0aGlzIGNhbiBiZSB1c2VkIGJ5IGF1dG9tYXRlZCBzeXN0ZW1zIGFjdGluZyBvbiB0aGUgdXNlcidzXG4gICAqIGJlaGFsZi5cbiAgICpcbiAgICogRm9yIHRoZSBtb21lbnQsIHdlJ3JlIG9taXR0aW5nIGV2ZW50IGhvb2tzIGFuZCBsb2Nrb3V0IGNoZWNrcywgc2luY2VcbiAgICogaW1tZWRpYXRlIHVzZSBjYXNlcyBzdWdnZXN0IC9sb2dpbkFzIGNvdWxkIGJlIHVzZWQgZm9yIHNlbWFudGljYWxseVxuICAgKiBkaWZmZXJlbnQgcmVhc29ucyBmcm9tIC9sb2dpblxuICAgKi9cbiAgYXN5bmMgaGFuZGxlTG9nSW5BcyhyZXEpIHtcbiAgICBpZiAoIXJlcS5hdXRoLmlzTWFzdGVyKSB7XG4gICAgICB0aHJvdyBjcmVhdGVTYW5pdGl6ZWRFcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgJ21hc3RlciBrZXkgaXMgcmVxdWlyZWQnLFxuICAgICAgICByZXEuY29uZmlnXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJJZCA9IHJlcS5ib2R5Py51c2VySWQgfHwgcmVxLnF1ZXJ5LnVzZXJJZDtcbiAgICBpZiAoIXVzZXJJZCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1ZBTFVFLFxuICAgICAgICAndXNlcklkIG11c3Qgbm90IGJlIGVtcHR5LCBudWxsLCBvciB1bmRlZmluZWQnXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5UmVzdWx0cyA9IGF3YWl0IHJlcS5jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCB7IG9iamVjdElkOiB1c2VySWQgfSk7XG4gICAgY29uc3QgdXNlciA9IHF1ZXJ5UmVzdWx0c1swXTtcbiAgICBpZiAoIXVzZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAndXNlciBub3QgZm91bmQnKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zYW5pdGl6ZUF1dGhEYXRhKHVzZXIpO1xuXG4gICAgY29uc3QgeyBzZXNzaW9uRGF0YSwgY3JlYXRlU2Vzc2lvbiB9ID0gUmVzdFdyaXRlLmNyZWF0ZVNlc3Npb24ocmVxLmNvbmZpZywge1xuICAgICAgdXNlcklkLFxuICAgICAgY3JlYXRlZFdpdGg6IHtcbiAgICAgICAgYWN0aW9uOiAnbG9naW4nLFxuICAgICAgICBhdXRoUHJvdmlkZXI6ICdtYXN0ZXJrZXknLFxuICAgICAgfSxcbiAgICAgIGluc3RhbGxhdGlvbklkOiByZXEuaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICB9KTtcblxuICAgIHVzZXIuc2Vzc2lvblRva2VuID0gc2Vzc2lvbkRhdGEuc2Vzc2lvblRva2VuO1xuXG4gICAgYXdhaXQgY3JlYXRlU2Vzc2lvbigpO1xuXG4gICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgfVxuXG4gIGhhbmRsZVZlcmlmeVBhc3N3b3JkKHJlcSkge1xuICAgIHJldHVybiB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKVxuICAgICAgLnRoZW4odXNlciA9PiB7XG4gICAgICAgIC8vIFJlbW92ZSBoaWRkZW4gcHJvcGVydGllcy5cbiAgICAgICAgVXNlcnNSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyh1c2VyKTtcblxuICAgICAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVMb2dPdXQocmVxKSB7XG4gICAgY29uc3Qgc3VjY2VzcyA9IHsgcmVzcG9uc2U6IHt9IH07XG4gICAgaWYgKHJlcS5pbmZvICYmIHJlcS5pbmZvLnNlc3Npb25Ub2tlbikge1xuICAgICAgY29uc3QgcmVjb3JkcyA9IGF3YWl0IHJlc3QuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuOiByZXEuaW5mby5zZXNzaW9uVG9rZW4gfSxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgICk7XG4gICAgICBpZiAocmVjb3Jkcy5yZXN1bHRzICYmIHJlY29yZHMucmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgYXdhaXQgcmVzdC5kZWwoXG4gICAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgICBBdXRoLm1hc3RlcihyZXEuY29uZmlnKSxcbiAgICAgICAgICAnX1Nlc3Npb24nLFxuICAgICAgICAgIHJlY29yZHMucmVzdWx0c1swXS5vYmplY3RJZCxcbiAgICAgICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IG1heWJlUnVuVHJpZ2dlcihcbiAgICAgICAgICBUcmlnZ2VyVHlwZXMuYWZ0ZXJMb2dvdXQsXG4gICAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgICAgUGFyc2UuU2Vzc2lvbi5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1Nlc3Npb24nIH0sIHJlY29yZHMucmVzdWx0c1swXSkpLFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgcmVxLmNvbmZpZ1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3VjY2VzcztcbiAgfVxuXG4gIF90aHJvd09uQmFkRW1haWxDb25maWcocmVxKSB7XG4gICAgdHJ5IHtcbiAgICAgIENvbmZpZy52YWxpZGF0ZUVtYWlsQ29uZmlndXJhdGlvbih7XG4gICAgICAgIGVtYWlsQWRhcHRlcjogcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlci5hZGFwdGVyLFxuICAgICAgICBhcHBOYW1lOiByZXEuY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIHB1YmxpY1NlcnZlclVSTDogcmVxLmNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwgfHwgcmVxLmNvbmZpZy5fcHVibGljU2VydmVyVVJMLFxuICAgICAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjogcmVxLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICAgICAgZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZDogcmVxLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKHR5cGVvZiBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAvLyBNYXliZSB3ZSBuZWVkIGEgQmFkIENvbmZpZ3VyYXRpb24gZXJyb3IsIGJ1dCB0aGUgU0RLcyB3b24ndCB1bmRlcnN0YW5kIGl0LiBGb3Igbm93LCBJbnRlcm5hbCBTZXJ2ZXIgRXJyb3IuXG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgJ0FuIGFwcE5hbWUsIHB1YmxpY1NlcnZlclVSTCwgYW5kIGVtYWlsQWRhcHRlciBhcmUgcmVxdWlyZWQgZm9yIHBhc3N3b3JkIHJlc2V0IGFuZCBlbWFpbCB2ZXJpZmljYXRpb24gZnVuY3Rpb25hbGl0eS4nXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVJlc2V0UmVxdWVzdChyZXEpIHtcbiAgICB0aGlzLl90aHJvd09uQmFkRW1haWxDb25maWcocmVxKTtcblxuICAgIGxldCBlbWFpbCA9IHJlcS5ib2R5Py5lbWFpbDtcbiAgICBjb25zdCB0b2tlbiA9IHJlcS5ib2R5Py50b2tlbjtcblxuICAgIGlmICghZW1haWwgJiYgIXRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTUlTU0lORywgJ3lvdSBtdXN0IHByb3ZpZGUgYW4gZW1haWwnKTtcbiAgICB9XG5cbiAgICBsZXQgdXNlclJlc3VsdHMgPSBudWxsO1xuICAgIGxldCB1c2VyRGF0YSA9IG51bGw7XG5cbiAgICAvLyBXZSBjYW4gZmluZCB0aGUgdXNlciB1c2luZyB0b2tlblxuICAgIGlmICh0b2tlbikge1xuICAgICAgdXNlclJlc3VsdHMgPSBhd2FpdCByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywge1xuICAgICAgICBfcGVyaXNoYWJsZV90b2tlbjogdG9rZW4sXG4gICAgICAgIF9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ6IHsgJGx0OiBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpIH0sXG4gICAgICB9KTtcbiAgICAgIGlmICh1c2VyUmVzdWx0cz8ubGVuZ3RoID4gMCkge1xuICAgICAgICB1c2VyRGF0YSA9IHVzZXJSZXN1bHRzWzBdO1xuICAgICAgICBpZiAodXNlckRhdGEuZW1haWwpIHtcbiAgICAgICAgICBlbWFpbCA9IHVzZXJEYXRhLmVtYWlsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgLy8gT3IgdXNpbmcgZW1haWwgaWYgbm8gdG9rZW4gcHJvdmlkZWRcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbWFpbCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHVzZXJSZXN1bHRzID0gYXdhaXQgcmVxLmNvbmZpZy5kYXRhYmFzZS5maW5kKFxuICAgICAgICAnX1VzZXInLFxuICAgICAgICB7ICRvcjogW3sgZW1haWwgfSwgeyB1c2VybmFtZTogZW1haWwsIGVtYWlsOiB7ICRleGlzdHM6IGZhbHNlIH0gfV0gfSxcbiAgICAgICAgeyBsaW1pdDogMSB9LFxuICAgICAgICBBdXRoLm1haW50ZW5hbmNlKHJlcS5jb25maWcpXG4gICAgICApO1xuICAgICAgaWYgKHVzZXJSZXN1bHRzPy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHVzZXJEYXRhID0gdXNlclJlc3VsdHNbMF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9FTUFJTF9BRERSRVNTLFxuICAgICAgICAneW91IG11c3QgcHJvdmlkZSBhIHZhbGlkIGVtYWlsIHN0cmluZydcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHVzZXJEYXRhKSB7XG4gICAgICB0aGlzLl9zYW5pdGl6ZUF1dGhEYXRhKHVzZXJEYXRhKTtcbiAgICAgIC8vIEdldCBmaWxlcyBhdHRhY2hlZCB0byB1c2VyXG4gICAgICBhd2FpdCByZXEuY29uZmlnLmZpbGVzQ29udHJvbGxlci5leHBhbmRGaWxlc0luT2JqZWN0KHJlcS5jb25maWcsIHVzZXJEYXRhKTtcblxuICAgICAgY29uc3QgdXNlciA9IGluZmxhdGUoJ19Vc2VyJywgdXNlckRhdGEpO1xuXG4gICAgICBhd2FpdCBtYXliZVJ1blRyaWdnZXIoXG4gICAgICAgIFRyaWdnZXJUeXBlcy5iZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHVzZXIsXG4gICAgICAgIG51bGwsXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB1c2VyQ29udHJvbGxlci5zZW5kUGFzc3dvcmRSZXNldEVtYWlsKGVtYWlsKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlOiB7fSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgaWYgKHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3k/LnJlc2V0UGFzc3dvcmRTdWNjZXNzT25JbnZhbGlkRW1haWwgPz8gdHJ1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXNwb25zZToge30sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlcnIubWVzc2FnZSA9IGBBIHVzZXIgd2l0aCB0aGF0IGVtYWlsIGRvZXMgbm90IGV4aXN0LmA7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSkge1xuICAgIHRoaXMuX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpO1xuXG4gICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHkgfHwge307XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX01JU1NJTkcsICd5b3UgbXVzdCBwcm92aWRlIGFuIGVtYWlsJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUyxcbiAgICAgICAgJ3lvdSBtdXN0IHByb3ZpZGUgYSB2YWxpZCBlbWFpbCBzdHJpbmcnXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBlbWFpbDogZW1haWwgfSwge30sIEF1dGgubWFpbnRlbmFuY2UocmVxLmNvbmZpZykpO1xuICAgIGlmICghcmVzdWx0cy5sZW5ndGggfHwgcmVzdWx0cy5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTk9UX0ZPVU5ELCBgTm8gdXNlciBmb3VuZCB3aXRoIGVtYWlsICR7ZW1haWx9YCk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuXG4gICAgLy8gcmVtb3ZlIHBhc3N3b3JkIGZpZWxkLCBtZXNzZXMgd2l0aCBzYXZpbmcgb24gcG9zdGdyZXNcbiAgICBkZWxldGUgdXNlci5wYXNzd29yZDtcblxuICAgIGlmICh1c2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgYEVtYWlsICR7ZW1haWx9IGlzIGFscmVhZHkgdmVyaWZpZWQuYCk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIGNvbnN0IHNlbmQgPSBhd2FpdCB1c2VyQ29udHJvbGxlci5yZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbih1c2VyLCByZXEuYXV0aC5pc01hc3RlciwgcmVxLmF1dGguaW5zdGFsbGF0aW9uSWQsIHJlcS5pcCk7XG4gICAgaWYgKHNlbmQpIHtcbiAgICAgIHVzZXJDb250cm9sbGVyLnNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VyLCByZXEpO1xuICAgIH1cbiAgICByZXR1cm4geyByZXNwb25zZToge30gfTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUNoYWxsZW5nZShyZXEpIHtcbiAgICBjb25zdCB7IHVzZXJuYW1lLCBlbWFpbCwgcGFzc3dvcmQsIGF1dGhEYXRhLCBjaGFsbGVuZ2VEYXRhIH0gPSByZXEuYm9keSB8fCB7fTtcblxuICAgIC8vIGlmIHVzZXJuYW1lIG9yIGVtYWlsIHByb3ZpZGVkIHdpdGggcGFzc3dvcmQgdHJ5IHRvIGF1dGhlbnRpY2F0ZSB0aGUgdXNlciBieSB1c2VybmFtZVxuICAgIGxldCB1c2VyO1xuICAgIGlmICh1c2VybmFtZSB8fCBlbWFpbCkge1xuICAgICAgaWYgKCFwYXNzd29yZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsXG4gICAgICAgICAgJ1lvdSBwcm92aWRlZCB1c2VybmFtZSBvciBlbWFpbCwgeW91IG5lZWQgdG8gYWxzbyBwcm92aWRlIHBhc3N3b3JkLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHVzZXIgPSBhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKTtcbiAgICB9XG5cbiAgICBpZiAoIWNoYWxsZW5nZURhdGEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgJ05vdGhpbmcgdG8gY2hhbGxlbmdlLicpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY2hhbGxlbmdlRGF0YSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgJ2NoYWxsZW5nZURhdGEgc2hvdWxkIGJlIGFuIG9iamVjdC4nKTtcbiAgICB9XG5cbiAgICBsZXQgcmVxdWVzdDtcbiAgICBsZXQgcGFyc2VVc2VyO1xuXG4gICAgLy8gVHJ5IHRvIGZpbmQgdXNlciBieSBhdXRoRGF0YVxuICAgIGlmIChhdXRoRGF0YSkge1xuICAgICAgaWYgKHR5cGVvZiBhdXRoRGF0YSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCAnYXV0aERhdGEgc2hvdWxkIGJlIGFuIG9iamVjdC4nKTtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSxcbiAgICAgICAgICAnWW91IGNhbm5vdCBwcm92aWRlIHVzZXJuYW1lL2VtYWlsIGFuZCBhdXRoRGF0YSwgb25seSB1c2Ugb25lIGlkZW50aWZpY2F0aW9uIG1ldGhvZC4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChPYmplY3Qua2V5cyhhdXRoRGF0YSkuZmlsdGVyKGtleSA9PiBhdXRoRGF0YVtrZXldLmlkKS5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSxcbiAgICAgICAgICAnWW91IGNhbm5vdCBwcm92aWRlIG1vcmUgdGhhbiBvbmUgYXV0aERhdGEgcHJvdmlkZXIgd2l0aCBhbiBpZC4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBBdXRoLmZpbmRVc2Vyc1dpdGhBdXRoRGF0YShyZXEuY29uZmlnLCBhdXRoRGF0YSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghcmVzdWx0c1swXSB8fCByZXN1bHRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1VzZXIgbm90IGZvdW5kLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZpbmQgdGhlIHByb3ZpZGVyIHVzZWQgdG8gZmluZCB0aGUgdXNlclxuICAgICAgICBjb25zdCBwcm92aWRlciA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKS5maW5kKGtleSA9PiBhdXRoRGF0YVtrZXldLmlkKTtcblxuICAgICAgICBwYXJzZVVzZXIgPSBQYXJzZS5Vc2VyLmZyb21KU09OKHsgY2xhc3NOYW1lOiAnX1VzZXInLCAuLi5yZXN1bHRzWzBdIH0pO1xuICAgICAgICByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh1bmRlZmluZWQsIHJlcS5hdXRoLCBwYXJzZVVzZXIsIHBhcnNlVXNlciwgcmVxLmNvbmZpZyk7XG4gICAgICAgIHJlcXVlc3QuaXNDaGFsbGVuZ2UgPSB0cnVlO1xuICAgICAgICAvLyBWYWxpZGF0ZSBhdXRoRGF0YSB1c2VkIHRvIGlkZW50aWZ5IHRoZSB1c2VyIHRvIGF2b2lkIGJydXRlLWZvcmNlIGF0dGFjayBvbiBgaWRgXG4gICAgICAgIGNvbnN0IHsgdmFsaWRhdG9yIH0gPSByZXEuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5nZXRWYWxpZGF0b3JGb3JQcm92aWRlcihwcm92aWRlcik7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRvclJlc3BvbnNlID0gYXdhaXQgdmFsaWRhdG9yKGF1dGhEYXRhW3Byb3ZpZGVyXSwgcmVxLCBwYXJzZVVzZXIsIHJlcXVlc3QpO1xuICAgICAgICBpZiAodmFsaWRhdG9yUmVzcG9uc2UgJiYgdmFsaWRhdG9yUmVzcG9uc2UudmFsaWRhdG9yKSB7XG4gICAgICAgICAgYXdhaXQgdmFsaWRhdG9yUmVzcG9uc2UudmFsaWRhdG9yKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gUmV3cml0ZSB0aGUgZXJyb3IgdG8gYXZvaWQgZ3Vlc3MgaWQgYXR0YWNrXG4gICAgICAgIGxvZ2dlci5lcnJvcihlKTtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdVc2VyIG5vdCBmb3VuZC4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhcnNlVXNlcikge1xuICAgICAgcGFyc2VVc2VyID0gdXNlciA/IFBhcnNlLlVzZXIuZnJvbUpTT04oeyBjbGFzc05hbWU6ICdfVXNlcicsIC4uLnVzZXIgfSkgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKCFyZXF1ZXN0KSB7XG4gICAgICByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh1bmRlZmluZWQsIHJlcS5hdXRoLCBwYXJzZVVzZXIsIHBhcnNlVXNlciwgcmVxLmNvbmZpZyk7XG4gICAgICByZXF1ZXN0LmlzQ2hhbGxlbmdlID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgYWNjID0ge307XG4gICAgLy8gRXhlY3V0ZSBjaGFsbGVuZ2Ugc3RlcC1ieS1zdGVwIHdpdGggY29uc2lzdGVudCBvcmRlciBmb3IgYmV0dGVyIGVycm9yIGZlZWRiYWNrXG4gICAgLy8gYW5kIHRvIGF2b2lkIHRvIHRyaWdnZXIgb3RoZXJzIGNoYWxsZW5nZXMgaWYgb25lIG9mIHRoZW0gZmFpbHNcbiAgICBmb3IgKGNvbnN0IHByb3ZpZGVyIG9mIE9iamVjdC5rZXlzKGNoYWxsZW5nZURhdGEpLnNvcnQoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYXV0aEFkYXB0ZXIgPSByZXEuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5nZXRWYWxpZGF0b3JGb3JQcm92aWRlcihwcm92aWRlcik7XG4gICAgICAgIGlmICghYXV0aEFkYXB0ZXIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgYWRhcHRlcjogeyBjaGFsbGVuZ2UgfSxcbiAgICAgICAgfSA9IGF1dGhBZGFwdGVyO1xuICAgICAgICBpZiAodHlwZW9mIGNoYWxsZW5nZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGNvbnN0IHByb3ZpZGVyQ2hhbGxlbmdlUmVzcG9uc2UgPSBhd2FpdCBjaGFsbGVuZ2UoXG4gICAgICAgICAgICBjaGFsbGVuZ2VEYXRhW3Byb3ZpZGVyXSxcbiAgICAgICAgICAgIGF1dGhEYXRhICYmIGF1dGhEYXRhW3Byb3ZpZGVyXSxcbiAgICAgICAgICAgIHJlcS5jb25maWcuYXV0aFtwcm92aWRlcl0sXG4gICAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICAgKTtcbiAgICAgICAgICBhY2NbcHJvdmlkZXJdID0gcHJvdmlkZXJDaGFsbGVuZ2VSZXNwb25zZSB8fCB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc3QgZSA9IHJlc29sdmVFcnJvcihlcnIsIHtcbiAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELFxuICAgICAgICAgIG1lc3NhZ2U6ICdDaGFsbGVuZ2UgZmFpbGVkLiBVbmtub3duIGVycm9yLicsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB1c2VyU3RyaW5nID0gcmVxLmF1dGggJiYgcmVxLmF1dGgudXNlciA/IHJlcS5hdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG4gICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYXV0aCBzdGVwIGNoYWxsZW5nZSBmb3IgJHtwcm92aWRlcn0gZm9yIHVzZXIgJHt1c2VyU3RyaW5nfSB3aXRoIEVycm9yOiBgICtcbiAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGUpLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uU3RlcDogJ2NoYWxsZW5nZScsXG4gICAgICAgICAgICBlcnJvcjogZSxcbiAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICBwcm92aWRlcixcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHJlc3BvbnNlOiB7IGNoYWxsZW5nZURhdGE6IGFjYyB9IH07XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91c2VycycsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNyZWF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvdXNlcnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvdXNlcnMvOm9iamVjdElkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvbG9naW4nLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW4ocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9sb2dpbicsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dJbihyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ2luQXMnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW5BcyhyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ291dCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dPdXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yZXF1ZXN0UGFzc3dvcmRSZXNldCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNldFJlcXVlc3QocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92ZXJpZmljYXRpb25FbWFpbFJlcXVlc3QnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy92ZXJpZnlQYXNzd29yZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL3ZlcmlmeVBhc3N3b3JkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVZlcmlmeVBhc3N3b3JkKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvY2hhbGxlbmdlJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNoYWxsZW5nZShyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJzUm91dGVyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQSxJQUFBQSxLQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxlQUFBLEdBQUFILHNCQUFBLENBQUFD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