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,41 +1,27 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.UserController = undefined;
7
-
8
- var _cryptoUtils = require('../cryptoUtils');
9
-
10
- var _triggers = require('../triggers');
11
-
12
- var _AdaptableController = require('./AdaptableController');
13
-
14
- var _AdaptableController2 = _interopRequireDefault(_AdaptableController);
15
-
16
- var _MailAdapter = require('../Adapters/Email/MailAdapter');
17
-
18
- var _MailAdapter2 = _interopRequireDefault(_MailAdapter);
19
-
20
- var _rest = require('../rest');
21
-
22
- var _rest2 = _interopRequireDefault(_rest);
23
-
24
- var _node = require('parse/node');
25
-
26
- var _node2 = _interopRequireDefault(_node);
27
-
28
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
-
6
+ exports.default = exports.UserController = void 0;
7
+ var _cryptoUtils = require("../cryptoUtils");
8
+ var _triggers = require("../triggers");
9
+ var _AdaptableController = _interopRequireDefault(require("./AdaptableController"));
10
+ var _MailAdapter = _interopRequireDefault(require("../Adapters/Email/MailAdapter"));
11
+ var _rest = _interopRequireDefault(require("../rest"));
12
+ var _node = _interopRequireDefault(require("parse/node"));
13
+ var _AccountLockout = _interopRequireDefault(require("../AccountLockout"));
14
+ var _Config = _interopRequireDefault(require("../Config"));
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
30
16
  var RestQuery = require('../RestQuery');
31
17
  var Auth = require('../Auth');
32
-
33
- class UserController extends _AdaptableController2.default {
34
-
18
+ class UserController extends _AdaptableController.default {
35
19
  constructor(adapter, appId, options = {}) {
36
20
  super(adapter, appId, options);
37
21
  }
38
-
22
+ get config() {
23
+ return _Config.default.get(this.appId);
24
+ }
39
25
  validateAdapter(adapter) {
40
26
  // Allow no adapter
41
27
  if (!adapter && !this.shouldVerifyEmails) {
@@ -43,79 +29,89 @@ class UserController extends _AdaptableController2.default {
43
29
  }
44
30
  super.validateAdapter(adapter);
45
31
  }
46
-
47
32
  expectedAdapterType() {
48
- return _MailAdapter2.default;
33
+ return _MailAdapter.default;
49
34
  }
50
-
51
35
  get shouldVerifyEmails() {
52
- return this.options.verifyUserEmails;
36
+ return (this.config || this.options).verifyUserEmails;
53
37
  }
54
-
55
- setEmailVerifyToken(user) {
56
- if (this.shouldVerifyEmails) {
57
- user._email_verify_token = (0, _cryptoUtils.randomString)(25);
38
+ async setEmailVerifyToken(user, req, storage = {}) {
39
+ const shouldSendEmail = this.shouldVerifyEmails === true || typeof this.shouldVerifyEmails === 'function' && (await Promise.resolve(this.shouldVerifyEmails(req))) === true;
40
+ if (!shouldSendEmail) {
41
+ return false;
42
+ }
43
+ storage.sendVerificationEmail = true;
44
+ user._email_verify_token = (0, _cryptoUtils.randomString)(25);
45
+ if (!storage.fieldsChangedByTrigger || !storage.fieldsChangedByTrigger.includes('emailVerified')) {
58
46
  user.emailVerified = false;
59
-
60
- if (this.config.emailVerifyTokenValidityDuration) {
61
- user._email_verify_token_expires_at = _node2.default._encode(this.config.generateEmailVerifyTokenExpiresAt());
62
- }
63
47
  }
48
+ if (this.config.emailVerifyTokenValidityDuration) {
49
+ user._email_verify_token_expires_at = _node.default._encode(this.config.generateEmailVerifyTokenExpiresAt());
50
+ }
51
+ return true;
64
52
  }
65
-
66
- verifyEmail(username, token) {
53
+ async verifyEmail(token) {
67
54
  if (!this.shouldVerifyEmails) {
68
55
  // Trying to verify email when not enabled
69
56
  // TODO: Better error here.
70
57
  throw undefined;
71
58
  }
72
-
73
- const query = { username: username, _email_verify_token: token };
74
- const updateFields = { emailVerified: true, _email_verify_token: { __op: 'Delete' } };
59
+ const query = {
60
+ _email_verify_token: token
61
+ };
62
+ const updateFields = {
63
+ emailVerified: true,
64
+ _email_verify_token: {
65
+ __op: 'Delete'
66
+ }
67
+ };
75
68
 
76
69
  // if the email verify token needs to be validated then
77
70
  // add additional query params and additional fields that need to be updated
78
71
  if (this.config.emailVerifyTokenValidityDuration) {
79
72
  query.emailVerified = false;
80
- query._email_verify_token_expires_at = { $gt: _node2.default._encode(new Date()) };
81
-
82
- updateFields._email_verify_token_expires_at = { __op: 'Delete' };
73
+ query._email_verify_token_expires_at = {
74
+ $gt: _node.default._encode(new Date())
75
+ };
76
+ updateFields._email_verify_token_expires_at = {
77
+ __op: 'Delete'
78
+ };
83
79
  }
84
- const masterAuth = Auth.master(this.config);
85
- var checkIfAlreadyVerified = new RestQuery(this.config, Auth.master(this.config), '_User', { username: username, emailVerified: true });
86
- return checkIfAlreadyVerified.execute().then(result => {
87
- if (result.results.length) {
88
- return Promise.resolve(result.results.length[0]);
89
- }
90
- return _rest2.default.update(this.config, masterAuth, '_User', query, updateFields);
80
+ const maintenanceAuth = Auth.maintenance(this.config);
81
+ const restQuery = await RestQuery({
82
+ method: RestQuery.Method.get,
83
+ config: this.config,
84
+ auth: maintenanceAuth,
85
+ className: '_User',
86
+ restWhere: query
91
87
  });
88
+ const result = await restQuery.execute();
89
+ if (result.results.length) {
90
+ query.objectId = result.results[0].objectId;
91
+ }
92
+ return await _rest.default.update(this.config, maintenanceAuth, '_User', query, updateFields);
92
93
  }
93
-
94
- checkResetTokenValidity(username, token) {
95
- return this.config.database.find('_User', {
96
- username: username,
94
+ async checkResetTokenValidity(token) {
95
+ const results = await this.config.database.find('_User', {
97
96
  _perishable_token: token
98
- }, { limit: 1 }).then(results => {
99
- if (results.length != 1) {
100
- throw undefined;
97
+ }, {
98
+ limit: 1
99
+ }, Auth.maintenance(this.config));
100
+ if (results.length !== 1) {
101
+ throw 'Failed to reset password: username / email / token is invalid';
102
+ }
103
+ if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
104
+ let expiresDate = results[0]._perishable_token_expires_at;
105
+ if (expiresDate && expiresDate.__type == 'Date') {
106
+ expiresDate = new Date(expiresDate.iso);
101
107
  }
102
-
103
- if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
104
- let expiresDate = results[0]._perishable_token_expires_at;
105
- if (expiresDate && expiresDate.__type == 'Date') {
106
- expiresDate = new Date(expiresDate.iso);
107
- }
108
- if (expiresDate < new Date()) throw 'The password reset link has expired';
108
+ if (expiresDate < new Date()) {
109
+ throw 'The password reset link has expired';
109
110
  }
110
-
111
- return results[0];
112
- });
113
- }
114
-
115
- getUserIfNeeded(user) {
116
- if (user.username && user.email) {
117
- return Promise.resolve(user);
118
111
  }
112
+ return results[0];
113
+ }
114
+ async getUserIfNeeded(user) {
119
115
  var where = {};
120
116
  if (user.username) {
121
117
  where.username = user.username;
@@ -123,37 +119,56 @@ class UserController extends _AdaptableController2.default {
123
119
  if (user.email) {
124
120
  where.email = user.email;
125
121
  }
126
-
127
- var query = new RestQuery(this.config, Auth.master(this.config), '_User', where);
128
- return query.execute().then(function (result) {
129
- if (result.results.length != 1) {
130
- throw undefined;
131
- }
132
- return result.results[0];
122
+ if (user._email_verify_token) {
123
+ where._email_verify_token = user._email_verify_token;
124
+ }
125
+ var query = await RestQuery({
126
+ method: RestQuery.Method.get,
127
+ config: this.config,
128
+ runBeforeFind: false,
129
+ auth: Auth.master(this.config),
130
+ className: '_User',
131
+ restWhere: where
133
132
  });
133
+ const result = await query.execute();
134
+ if (result.results.length != 1) {
135
+ throw undefined;
136
+ }
137
+ return result.results[0];
134
138
  }
135
-
136
- sendVerificationEmail(user) {
139
+ async sendVerificationEmail(user, req) {
137
140
  if (!this.shouldVerifyEmails) {
138
141
  return;
139
142
  }
140
143
  const token = encodeURIComponent(user._email_verify_token);
141
- // We may need to fetch the user in case of update email
142
- this.getUserIfNeeded(user).then(user => {
143
- const username = encodeURIComponent(user.username);
144
-
145
- const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config);
146
- const options = {
147
- appName: this.config.appName,
148
- link: link,
149
- user: (0, _triggers.inflate)('_User', user)
150
- };
151
- if (this.adapter.sendVerificationEmail) {
152
- this.adapter.sendVerificationEmail(options);
153
- } else {
154
- this.adapter.sendMail(this.defaultVerificationEmail(options));
155
- }
156
- });
144
+ // We may need to fetch the user in case of update email; only use the `fetchedUser`
145
+ // from this point onwards; do not use the `user` as it may not contain all fields.
146
+ const fetchedUser = await this.getUserIfNeeded(user);
147
+ let shouldSendEmail = this.config.sendUserEmailVerification;
148
+ if (typeof shouldSendEmail === 'function') {
149
+ const response = await Promise.resolve(this.config.sendUserEmailVerification({
150
+ user: _node.default.Object.fromJSON({
151
+ className: '_User',
152
+ ...fetchedUser
153
+ }),
154
+ master: req.auth?.isMaster
155
+ }));
156
+ shouldSendEmail = !!response;
157
+ }
158
+ if (!shouldSendEmail) {
159
+ return;
160
+ }
161
+ const link = buildEmailLink(this.config.verifyEmailURL, token, this.config);
162
+ const options = {
163
+ appName: this.config.appName,
164
+ link: link,
165
+ user: (0, _triggers.inflate)('_User', fetchedUser)
166
+ };
167
+ if (this.adapter.sendVerificationEmail) {
168
+ this.adapter.sendVerificationEmail(options);
169
+ } else {
170
+ this.adapter.sendMail(this.defaultVerificationEmail(options));
171
+ }
157
172
  }
158
173
 
159
174
  /**
@@ -162,109 +177,179 @@ class UserController extends _AdaptableController2.default {
162
177
  * @param user
163
178
  * @returns {*}
164
179
  */
165
- regenerateEmailVerifyToken(user) {
166
- this.setEmailVerifyToken(user);
167
- return this.config.database.update('_User', { username: user.username }, user);
180
+ async regenerateEmailVerifyToken(user, master, installationId, ip) {
181
+ const {
182
+ _email_verify_token
183
+ } = user;
184
+ let {
185
+ _email_verify_token_expires_at
186
+ } = user;
187
+ if (_email_verify_token_expires_at && _email_verify_token_expires_at.__type === 'Date') {
188
+ _email_verify_token_expires_at = _email_verify_token_expires_at.iso;
189
+ }
190
+ if (this.config.emailVerifyTokenReuseIfValid && this.config.emailVerifyTokenValidityDuration && _email_verify_token && new Date() < new Date(_email_verify_token_expires_at)) {
191
+ return Promise.resolve(true);
192
+ }
193
+ const shouldSend = await this.setEmailVerifyToken(user, {
194
+ object: _node.default.User.fromJSON(Object.assign({
195
+ className: '_User'
196
+ }, user)),
197
+ master,
198
+ installationId,
199
+ ip,
200
+ resendRequest: true
201
+ });
202
+ if (!shouldSend) {
203
+ return;
204
+ }
205
+ return this.config.database.update('_User', {
206
+ username: user.username
207
+ }, user);
168
208
  }
169
-
170
- resendVerificationEmail(username) {
171
- return this.getUserIfNeeded({ username: username }).then(aUser => {
172
- if (!aUser || aUser.emailVerified) {
173
- throw undefined;
174
- }
175
- return this.regenerateEmailVerifyToken(aUser).then(() => {
176
- this.sendVerificationEmail(aUser);
177
- });
209
+ async resendVerificationEmail(username, req, token) {
210
+ const aUser = await this.getUserIfNeeded({
211
+ username,
212
+ _email_verify_token: token
178
213
  });
214
+ if (!aUser || aUser.emailVerified) {
215
+ throw undefined;
216
+ }
217
+ const generate = await this.regenerateEmailVerifyToken(aUser, req.auth?.isMaster, req.auth?.installationId, req.ip);
218
+ if (generate) {
219
+ this.sendVerificationEmail(aUser, req);
220
+ }
179
221
  }
180
-
181
222
  setPasswordResetToken(email) {
182
- const token = { _perishable_token: (0, _cryptoUtils.randomString)(25) };
183
-
223
+ const token = {
224
+ _perishable_token: (0, _cryptoUtils.randomString)(25)
225
+ };
184
226
  if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
185
- token._perishable_token_expires_at = _node2.default._encode(this.config.generatePasswordResetTokenExpiresAt());
227
+ token._perishable_token_expires_at = _node.default._encode(this.config.generatePasswordResetTokenExpiresAt());
186
228
  }
187
-
188
- return this.config.database.update('_User', { $or: [{ email }, { username: email, email: { $exists: false } }] }, token, {}, true);
229
+ return this.config.database.update('_User', {
230
+ $or: [{
231
+ email
232
+ }, {
233
+ username: email,
234
+ email: {
235
+ $exists: false
236
+ }
237
+ }]
238
+ }, token, {}, true);
189
239
  }
190
-
191
- sendPasswordResetEmail(email) {
240
+ async sendPasswordResetEmail(email) {
192
241
  if (!this.adapter) {
193
- throw "Trying to send a reset password but no adapter is set";
242
+ throw 'Trying to send a reset password but no adapter is set';
194
243
  // TODO: No adapter?
195
244
  }
196
-
197
- return this.setPasswordResetToken(email).then(user => {
198
- const token = encodeURIComponent(user._perishable_token);
199
- const username = encodeURIComponent(user.username);
200
-
201
- const link = buildEmailLink(this.config.requestResetPasswordURL, username, token, this.config);
202
- const options = {
203
- appName: this.config.appName,
204
- link: link,
205
- user: (0, _triggers.inflate)('_User', user)
206
- };
207
-
208
- if (this.adapter.sendPasswordResetEmail) {
209
- this.adapter.sendPasswordResetEmail(options);
210
- } else {
211
- this.adapter.sendMail(this.defaultResetPasswordEmail(options));
245
+ let user;
246
+ if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenReuseIfValid && this.config.passwordPolicy.resetTokenValidityDuration) {
247
+ const results = await this.config.database.find('_User', {
248
+ $or: [{
249
+ email,
250
+ _perishable_token: {
251
+ $exists: true
252
+ }
253
+ }, {
254
+ username: email,
255
+ email: {
256
+ $exists: false
257
+ },
258
+ _perishable_token: {
259
+ $exists: true
260
+ }
261
+ }]
262
+ }, {
263
+ limit: 1
264
+ }, Auth.maintenance(this.config));
265
+ if (results.length == 1) {
266
+ let expiresDate = results[0]._perishable_token_expires_at;
267
+ if (expiresDate && expiresDate.__type == 'Date') {
268
+ expiresDate = new Date(expiresDate.iso);
269
+ }
270
+ if (expiresDate > new Date()) {
271
+ user = results[0];
272
+ }
212
273
  }
213
-
214
- return Promise.resolve(user);
215
- });
274
+ }
275
+ if (!user || !user._perishable_token) {
276
+ user = await this.setPasswordResetToken(email);
277
+ }
278
+ const token = encodeURIComponent(user._perishable_token);
279
+ const link = buildEmailLink(this.config.requestResetPasswordURL, token, this.config);
280
+ const options = {
281
+ appName: this.config.appName,
282
+ link: link,
283
+ user: (0, _triggers.inflate)('_User', user)
284
+ };
285
+ if (this.adapter.sendPasswordResetEmail) {
286
+ this.adapter.sendPasswordResetEmail(options);
287
+ } else {
288
+ this.adapter.sendMail(this.defaultResetPasswordEmail(options));
289
+ }
290
+ return Promise.resolve(user);
216
291
  }
217
-
218
- updatePassword(username, token, password) {
219
- return this.checkResetTokenValidity(username, token).then(user => updateUserPassword(user.objectId, password, this.config))
220
- // clear reset password token
221
- .then(() => this.config.database.update('_User', { username }, {
222
- _perishable_token: { __op: 'Delete' },
223
- _perishable_token_expires_at: { __op: 'Delete' }
224
- })).catch(error => {
225
- if (error.message) {
292
+ async updatePassword(token, password) {
293
+ try {
294
+ const rawUser = await this.checkResetTokenValidity(token);
295
+ const user = await updateUserPassword(rawUser, password, this.config);
296
+ const accountLockoutPolicy = new _AccountLockout.default(user, this.config);
297
+ return await accountLockoutPolicy.unlockAccount();
298
+ } catch (error) {
299
+ if (error && error.message) {
226
300
  // in case of Parse.Error, fail with the error message only
227
301
  return Promise.reject(error.message);
228
- } else {
229
- return Promise.reject(error);
230
302
  }
231
- });
303
+ return Promise.reject(error);
304
+ }
232
305
  }
233
-
234
- defaultVerificationEmail({ link, user, appName }) {
235
- const text = "Hi,\n\n" + "You are being asked to confirm the e-mail address " + user.get("email") + " with " + appName + "\n\n" + "" + "Click here to confirm it:\n" + link;
236
- const to = user.get("email");
306
+ defaultVerificationEmail({
307
+ link,
308
+ user,
309
+ appName
310
+ }) {
311
+ const text = 'Hi,\n\n' + 'You are being asked to confirm the e-mail address ' + user.get('email') + ' with ' + appName + '\n\n' + '' + 'Click here to confirm it:\n' + link;
312
+ const to = user.get('email');
237
313
  const subject = 'Please verify your e-mail for ' + appName;
238
- return { text, to, subject };
314
+ return {
315
+ text,
316
+ to,
317
+ subject
318
+ };
239
319
  }
240
-
241
- defaultResetPasswordEmail({ link, user, appName }) {
242
- const text = "Hi,\n\n" + "You requested to reset your password for " + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : "") + ".\n\n" + "" + "Click here to reset it:\n" + link;
243
- const to = user.get("email") || user.get('username');
320
+ defaultResetPasswordEmail({
321
+ link,
322
+ user,
323
+ appName
324
+ }) {
325
+ const text = 'Hi,\n\n' + 'You requested to reset your password for ' + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : '') + '.\n\n' + '' + 'Click here to reset it:\n' + link;
326
+ const to = user.get('email') || user.get('username');
244
327
  const subject = 'Password Reset for ' + appName;
245
- return { text, to, subject };
328
+ return {
329
+ text,
330
+ to,
331
+ subject
332
+ };
246
333
  }
247
334
  }
248
335
 
249
- exports.UserController = UserController; // Mark this private
250
-
251
- function updateUserPassword(userId, password, config) {
252
- return _rest2.default.update(config, Auth.master(config), '_User', { objectId: userId }, {
336
+ // Mark this private
337
+ exports.UserController = UserController;
338
+ function updateUserPassword(user, password, config) {
339
+ return _rest.default.update(config, Auth.master(config), '_User', {
340
+ objectId: user.objectId
341
+ }, {
253
342
  password: password
254
- });
343
+ }).then(() => user);
255
344
  }
256
-
257
- function buildEmailLink(destination, username, token, config) {
258
- const usernameAndToken = `token=${token}&username=${username}`;
259
-
345
+ function buildEmailLink(destination, token, config) {
346
+ token = `token=${token}`;
260
347
  if (config.parseFrameURL) {
261
348
  const destinationWithoutHost = destination.replace(config.publicServerURL, '');
262
-
263
- return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${usernameAndToken}`;
349
+ return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${token}`;
264
350
  } else {
265
- return `${destination}?${usernameAndToken}`;
351
+ return `${destination}?${token}`;
266
352
  }
267
353
  }
268
-
269
- exports.default = UserController;
270
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Vc2VyQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJSZXN0UXVlcnkiLCJyZXF1aXJlIiwiQXV0aCIsIlVzZXJDb250cm9sbGVyIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsInNob3VsZFZlcmlmeUVtYWlscyIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJNYWlsQWRhcHRlciIsInZlcmlmeVVzZXJFbWFpbHMiLCJzZXRFbWFpbFZlcmlmeVRva2VuIiwidXNlciIsIl9lbWFpbF92ZXJpZnlfdG9rZW4iLCJlbWFpbFZlcmlmaWVkIiwiY29uZmlnIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQiLCJQYXJzZSIsIl9lbmNvZGUiLCJnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQiLCJ2ZXJpZnlFbWFpbCIsInVzZXJuYW1lIiwidG9rZW4iLCJ1bmRlZmluZWQiLCJxdWVyeSIsInVwZGF0ZUZpZWxkcyIsIl9fb3AiLCIkZ3QiLCJEYXRlIiwibWFzdGVyQXV0aCIsIm1hc3RlciIsImNoZWNrSWZBbHJlYWR5VmVyaWZpZWQiLCJleGVjdXRlIiwidGhlbiIsInJlc3VsdCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlc3QiLCJ1cGRhdGUiLCJjaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSIsImRhdGFiYXNlIiwiZmluZCIsIl9wZXJpc2hhYmxlX3Rva2VuIiwibGltaXQiLCJwYXNzd29yZFBvbGljeSIsInJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZXhwaXJlc0RhdGUiLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiX190eXBlIiwiaXNvIiwiZ2V0VXNlcklmTmVlZGVkIiwiZW1haWwiLCJ3aGVyZSIsInNlbmRWZXJpZmljYXRpb25FbWFpbCIsImVuY29kZVVSSUNvbXBvbmVudCIsImxpbmsiLCJidWlsZEVtYWlsTGluayIsInZlcmlmeUVtYWlsVVJMIiwiYXBwTmFtZSIsInNlbmRNYWlsIiwiZGVmYXVsdFZlcmlmaWNhdGlvbkVtYWlsIiwicmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4iLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImFVc2VyIiwic2V0UGFzc3dvcmRSZXNldFRva2VuIiwiZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQiLCIkb3IiLCIkZXhpc3RzIiwic2VuZFBhc3N3b3JkUmVzZXRFbWFpbCIsInJlcXVlc3RSZXNldFBhc3N3b3JkVVJMIiwiZGVmYXVsdFJlc2V0UGFzc3dvcmRFbWFpbCIsInVwZGF0ZVBhc3N3b3JkIiwicGFzc3dvcmQiLCJ1cGRhdGVVc2VyUGFzc3dvcmQiLCJvYmplY3RJZCIsImNhdGNoIiwiZXJyb3IiLCJtZXNzYWdlIiwicmVqZWN0IiwidGV4dCIsImdldCIsInRvIiwic3ViamVjdCIsInVzZXJJZCIsImRlc3RpbmF0aW9uIiwidXNlcm5hbWVBbmRUb2tlbiIsInBhcnNlRnJhbWVVUkwiLCJkZXN0aW5hdGlvbldpdGhvdXRIb3N0IiwicmVwbGFjZSIsInB1YmxpY1NlcnZlclVSTCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7QUFFQSxJQUFJQSxZQUFZQyxRQUFRLGNBQVIsQ0FBaEI7QUFDQSxJQUFJQyxPQUFPRCxRQUFRLFNBQVIsQ0FBWDs7QUFFTyxNQUFNRSxjQUFOLFNBQTZCQyw2QkFBN0IsQ0FBaUQ7O0FBRXREQyxjQUFZQyxPQUFaLEVBQXFCQyxLQUFyQixFQUE0QkMsVUFBVSxFQUF0QyxFQUEwQztBQUN4QyxVQUFNRixPQUFOLEVBQWVDLEtBQWYsRUFBc0JDLE9BQXRCO0FBQ0Q7O0FBRURDLGtCQUFnQkgsT0FBaEIsRUFBeUI7QUFDdkI7QUFD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LFFBQXBDLEVBQThDNUQsTUFBOUMsRUFBc0Q7QUFDcEQsU0FBT3lCLGVBQUtDLE1BQUwsQ0FBWTFCLE1BQVosRUFBb0JoQixLQUFLZ0MsTUFBTCxDQUFZaEIsTUFBWixDQUFwQixFQUF5QyxPQUF6QyxFQUFrRCxFQUFFOEQsVUFBVVMsTUFBWixFQUFsRCxFQUF3RTtBQUM3RVgsY0FBVUE7QUFEbUUsR0FBeEUsQ0FBUDtBQUdEOztBQUVELFNBQVNoQixjQUFULENBQXdCNEIsV0FBeEIsRUFBcUNqRSxRQUFyQyxFQUErQ0MsS0FBL0MsRUFBc0RSLE1BQXRELEVBQThEO0FBQzVELFFBQU15RSxtQkFBb0IsU0FBUWpFLEtBQU0sYUFBWUQsUUFBUyxFQUE3RDs7QUFFQSxNQUFJUCxPQUFPMEUsYUFBWCxFQUEwQjtBQUN4QixVQUFNQyx5QkFBeUJILFlBQVlJLE9BQVosQ0FBb0I1RSxPQUFPNkUsZUFBM0IsRUFBNEMsRUFBNUMsQ0FBL0I7O0FBRUEsV0FBUSxHQUFFN0UsT0FBTzBFLGFBQWMsU0FBUWhDLG1CQUFtQmlDLHNCQUFuQixDQUEyQyxJQUFHRixnQkFBaUIsRUFBdEc7QUFDRCxHQUpELE1BSU87QUFDTCxXQUFRLEdBQUVELFdBQVksSUFBR0MsZ0JBQWlCLEVBQTFDO0FBQ0Q7QUFDRjs7a0JBRWN4RixjIiwiZmlsZSI6IlVzZXJDb250cm9sbGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmFuZG9tU3RyaW5nIH0gICAgZnJvbSAnLi4vY3J5cHRvVXRpbHMnO1xuaW1wb3J0IHsgaW5mbGF0ZSB9ICAgICAgICAgZnJvbSAnLi4vdHJpZ2dlcnMnO1xuaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCBNYWlsQWRhcHRlciAgICAgICAgIGZyb20gJy4uL0FkYXB0ZXJzL0VtYWlsL01haWxBZGFwdGVyJztcbmltcG9ydCByZXN0ICAgICAgICAgICAgICAgIGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IFBhcnNlICAgICAgICAgICAgICAgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbnZhciBSZXN0UXVlcnkgPSByZXF1aXJlKCcuLi9SZXN0UXVlcnknKTtcbnZhciBBdXRoID0gcmVxdWlyZSgnLi4vQXV0aCcpO1xuXG5leHBvcnQgY2xhc3MgVXNlckNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcblxuICBjb25zdHJ1Y3RvcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgdmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpIHtcbiAgICAvLyBBbGxvdyBubyBhZGFwdGVyXG4gICAgaWYgKCFhZGFwdGVyICYmICF0aGlzLnNob3VsZFZlcmlmeUVtYWlscykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzdXBlci52YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcik7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBNYWlsQWRhcHRlcjtcbiAgfVxuXG4gIGdldCBzaG91bGRWZXJpZnlFbWFpbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy52ZXJpZnlVc2VyRW1haWxzO1xuICB9XG5cbiAgc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyKSB7XG4gICAgaWYgKHRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW4gPSByYW5kb21TdHJpbmcoMjUpO1xuICAgICAgdXNlci5lbWFpbFZlcmlmaWVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IFBhcnNlLl9lbmNvZGUodGhpcy5jb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0KCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZlcmlmeUVtYWlsKHVzZXJuYW1lLCB0b2tlbikge1xuICAgIGlmICghdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIC8vIFRyeWluZyB0byB2ZXJpZnkgZW1haWwgd2hlbiBub3QgZW5hYmxlZFxuICAgICAgLy8gVE9ETzogQmV0dGVyIGVycm9yIGhlcmUuXG4gICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgcXVlcnkgPSB7dXNlcm5hbWU6IHVzZXJuYW1lLCBfZW1haWxfdmVyaWZ5X3Rva2VuOiB0b2tlbn07XG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0geyBlbWFpbFZlcmlmaWVkOiB0cnVlLCBfZW1haWxfdmVyaWZ5X3Rva2VuOiB7X19vcDogJ0RlbGV0ZSd9fTtcblxuICAgIC8vIGlmIHRoZSBlbWFpbCB2ZXJpZnkgdG9rZW4gbmVlZHMgdG8gYmUgdmFsaWRhdGVkIHRoZW5cbiAgICAvLyBhZGQgYWRkaXRpb25hbCBxdWVyeSBwYXJhbXMgYW5kIGFkZGl0aW9uYWwgZmllbGRzIHRoYXQgbmVlZCB0byBiZSB1cGRhdGVkXG4gICAgaWYgKHRoaXMuY29uZmlnLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICBxdWVyeS5lbWFpbFZlcmlmaWVkID0gZmFsc2U7XG4gICAgICBxdWVyeS5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgPSB7ICRndDogUGFyc2UuX2VuY29kZShuZXcgRGF0ZSgpKSB9O1xuXG4gICAgICB1cGRhdGVGaWVsZHMuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0ge19fb3A6ICdEZWxldGUnfTtcbiAgICB9XG4gICAgY29uc3QgbWFzdGVyQXV0aCA9IEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKTtcbiAgICB2YXIgY2hlY2tJZkFscmVhZHlWZXJpZmllZCA9IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSwgJ19Vc2VyJywge3VzZXJuYW1lOiB1c2VybmFtZSwgZW1haWxWZXJpZmllZDogdHJ1ZX0pO1xuICAgIHJldHVybiBjaGVja0lmQWxyZWFkeVZlcmlmaWVkLmV4ZWN1dGUoKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICBpZiAocmVzdWx0LnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0LnJlc3VsdHMubGVuZ3RoWzBdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN0LnVwZGF0ZSh0aGlzLmNvbmZpZywgbWFzdGVyQXV0aCwgJ19Vc2VyJywgcXVlcnksIHVwZGF0ZUZpZWxkcyk7XG4gICAgfSk7XG4gIH1cblxuICBjaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCB7XG4gICAgICB1c2VybmFtZTogdXNlcm5hbWUsXG4gICAgICBfcGVyaXNoYWJsZV90b2tlbjogdG9rZW5cbiAgICB9LCB7bGltaXQ6IDF9KS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgICAgbGV0IGV4cGlyZXNEYXRlID0gcmVzdWx0c1swXS5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0O1xuICAgICAgICBpZiAoZXhwaXJlc0RhdGUgJiYgZXhwaXJlc0RhdGUuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICAgIGV4cGlyZXNEYXRlID0gbmV3IERhdGUoZXhwaXJlc0RhdGUuaXNvKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhwaXJlc0RhdGUgPCBuZXcgRGF0ZSgpKVxuICAgICAgICAgIHRocm93ICdUaGUgcGFzc3dvcmQgcmVzZXQgbGluayBoYXMgZXhwaXJlZCc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRzWzBdO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0VXNlcklmTmVlZGVkKHVzZXIpIHtcbiAgICBpZiAodXNlci51c2VybmFtZSAmJiB1c2VyLmVtYWlsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVzZXIpO1xuICAgIH1cbiAgICB2YXIgd2hlcmUgPSB7fTtcbiAgICBpZiAodXNlci51c2VybmFtZSkge1xuICAgICAgd2hlcmUudXNlcm5hbWUgPSB1c2VyLnVzZXJuYW1lO1xuICAgIH1cbiAgICBpZiAodXNlci5lbWFpbCkge1xuICAgICAgd2hlcmUuZW1haWwgPSB1c2VyLmVtYWlsO1xuICAgIH1cblxuICAgIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSwgJ19Vc2VyJywgd2hlcmUpO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlKCkudGhlbihmdW5jdGlvbihyZXN1bHQpe1xuICAgICAgaWYgKHJlc3VsdC5yZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQucmVzdWx0c1swXTtcbiAgICB9KVxuICB9XG5cbiAgc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHVzZXIpIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRva2VuID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbik7XG4gICAgLy8gV2UgbWF5IG5lZWQgdG8gZmV0Y2ggdGhlIHVzZXIgaW4gY2FzZSBvZiB1cGRhdGUgZW1haWxcbiAgICB0aGlzLmdldFVzZXJJZk5lZWRlZCh1c2VyKS50aGVuKCh1c2VyKSA9PiB7XG4gICAgICBjb25zdCB1c2VybmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLnVzZXJuYW1lKTtcblxuICAgICAgY29uc3QgbGluayA9IGJ1aWxkRW1haWxMaW5rKHRoaXMuY29uZmlnLnZlcmlmeUVtYWlsVVJMLCB1c2VybmFtZSwgdG9rZW4sIHRoaXMuY29uZmlnKTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgIGFwcE5hbWU6IHRoaXMuY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIGxpbms6IGxpbmssXG4gICAgICAgIHVzZXI6IGluZmxhdGUoJ19Vc2VyJywgdXNlciksXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMuYWRhcHRlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwpIHtcbiAgICAgICAgdGhpcy5hZGFwdGVyLnNlbmRWZXJpZmljYXRpb25FbWFpbChvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWRhcHRlci5zZW5kTWFpbCh0aGlzLmRlZmF1bHRWZXJpZmljYXRpb25FbWFpbChvcHRpb25zKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVnZW5lcmF0ZXMgdGhlIGdpdmVuIHVzZXIncyBlbWFpbCB2ZXJpZmljYXRpb24gdG9rZW5cbiAgICpcbiAgICogQHBhcmFtIHVzZXJcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICByZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbih1c2VyKSB7XG4gICAgdGhpcy5zZXRFbWFpbFZlcmlmeVRva2VuKHVzZXIpO1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoJ19Vc2VyJywgeyB1c2VybmFtZTogdXNlci51c2VybmFtZSB9LCB1c2VyKTtcbiAgfVxuXG4gIHJlc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHVzZXJuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VXNlcklmTmVlZGVkKHt1c2VybmFtZTogdXNlcm5hbWV9KS50aGVuKChhVXNlcikgPT4ge1xuICAgICAgaWYgKCFhVXNlciB8fCBhVXNlci5lbWFpbFZlcmlmaWVkKSB7XG4gICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuKGFVc2VyKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZW5kVmVyaWZpY2F0aW9uRW1haWwoYVVzZXIpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRQYXNzd29yZFJlc2V0VG9rZW4oZW1haWwpIHtcbiAgICBjb25zdCB0b2tlbiA9IHsgX3BlcmlzaGFibGVfdG9rZW46IHJhbmRvbVN0cmluZygyNSkgfTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeSAmJiB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgdG9rZW4uX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCA9IFBhcnNlLl9lbmNvZGUodGhpcy5jb25maWcuZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCB7ICRvcjogW3tlbWFpbH0sIHt1c2VybmFtZTogZW1haWwsIGVtYWlsOiB7JGV4aXN0czogZmFsc2V9fV0gfSwgdG9rZW4sIHt9LCB0cnVlKVxuICB9XG5cbiAgc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChlbWFpbCkge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKSB7XG4gICAgICB0aHJvdyBcIlRyeWluZyB0byBzZW5kIGEgcmVzZXQgcGFzc3dvcmQgYnV0IG5vIGFkYXB0ZXIgaXMgc2V0XCI7XG4gICAgICAvLyAgVE9ETzogTm8gYWRhcHRlcj9cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zZXRQYXNzd29yZFJlc2V0VG9rZW4oZW1haWwpXG4gICAgICAudGhlbih1c2VyID0+IHtcbiAgICAgICAgY29uc3QgdG9rZW4gPSBlbmNvZGVVUklDb21wb25lbnQodXNlci5fcGVyaXNoYWJsZV90b2tlbik7XG4gICAgICAgIGNvbnN0IHVzZXJuYW1lID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXIudXNlcm5hbWUpO1xuXG4gICAgICAgIGNvbnN0IGxpbmsgPSBidWlsZEVtYWlsTGluayh0aGlzLmNvbmZpZy5yZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCwgdXNlcm5hbWUsIHRva2VuLCB0aGlzLmNvbmZpZyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgYXBwTmFtZTogdGhpcy5jb25maWcuYXBwTmFtZSxcbiAgICAgICAgICBsaW5rOiBsaW5rLFxuICAgICAgICAgIHVzZXI6IGluZmxhdGUoJ19Vc2VyJywgdXNlciksXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHRoaXMuYWRhcHRlci5zZW5kUGFzc3dvcmRSZXNldEVtYWlsKSB7XG4gICAgICAgICAgdGhpcy5hZGFwdGVyLnNlbmRQYXNzd29yZFJlc2V0RW1haWwob3B0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5hZGFwdGVyLnNlbmRNYWlsKHRoaXMuZGVmYXVsdFJlc2V0UGFzc3dvcmRFbWFpbChvcHRpb25zKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVzZXIpO1xuICAgICAgfSk7XG4gIH1cblxuICB1cGRhdGVQYXNzd29yZCh1c2VybmFtZSwgdG9rZW4sIHBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hlY2tSZXNldFRva2VuVmFsaWRpdHkodXNlcm5hbWUsIHRva2VuKVxuICAgICAgLnRoZW4odXNlciA9PiB1cGRhdGVVc2VyUGFzc3dvcmQodXNlci5vYmplY3RJZCwgcGFzc3dvcmQsIHRoaXMuY29uZmlnKSlcbiAgICAgIC8vIGNsZWFyIHJlc2V0IHBhc3N3b3JkIHRva2VuXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoJ19Vc2VyJywge3VzZXJuYW1lfSwge1xuICAgICAgICBfcGVyaXNoYWJsZV90b2tlbjoge19fb3A6ICdEZWxldGUnfSxcbiAgICAgICAgX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdDoge19fb3A6ICdEZWxldGUnfVxuICAgICAgfSkpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSkgeyAgLy8gaW4gY2FzZSBvZiBQYXJzZS5FcnJvciwgZmFpbCB3aXRoIHRoZSBlcnJvciBtZXNzYWdlIG9ubHlcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IubWVzc2FnZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBkZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwoe2xpbmssIHVzZXIsIGFwcE5hbWUsIH0pIHtcbiAgICBjb25zdCB0ZXh0ID0gXCJIaSxcXG5cXG5cIiArXG4gICAgICAgIFwiWW91IGFyZSBiZWluZyBhc2tlZCB0byBjb25maXJtIHRoZSBlLW1haWwgYWRkcmVzcyBcIiArIHVzZXIuZ2V0KFwiZW1haWxcIikgKyBcIiB3aXRoIFwiICsgYXBwTmFtZSArIFwiXFxuXFxuXCIgK1xuICAgICAgICBcIlwiICtcbiAgICAgICAgXCJDbGljayBoZXJlIHRvIGNvbmZpcm0gaXQ6XFxuXCIgKyBsaW5rO1xuICAgIGNvbnN0IHRvID0gdXNlci5nZXQoXCJlbWFpbFwiKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gJ1BsZWFzZSB2ZXJpZnkgeW91ciBlLW1haWwgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cblxuICBkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsKHtsaW5rLCB1c2VyLCBhcHBOYW1lLCB9KSB7XG4gICAgY29uc3QgdGV4dCA9IFwiSGksXFxuXFxuXCIgK1xuICAgICAgICBcIllvdSByZXF1ZXN0ZWQgdG8gcmVzZXQgeW91ciBwYXNzd29yZCBmb3IgXCIgKyBhcHBOYW1lICtcbiAgICAgICAgKHVzZXIuZ2V0KCd1c2VybmFtZScpID8gKFwiICh5b3VyIHVzZXJuYW1lIGlzICdcIiArIHVzZXIuZ2V0KCd1c2VybmFtZScpICsgXCInKVwiKSA6IFwiXCIpICsgXCIuXFxuXFxuXCIgK1xuICAgICAgICBcIlwiICtcbiAgICAgICAgXCJDbGljayBoZXJlIHRvIHJlc2V0IGl0OlxcblwiICsgbGluaztcbiAgICBjb25zdCB0byA9IHVzZXIuZ2V0KFwiZW1haWxcIikgfHwgdXNlci5nZXQoJ3VzZXJuYW1lJyk7XG4gICAgY29uc3Qgc3ViamVjdCA9ICAnUGFzc3dvcmQgUmVzZXQgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cbn1cblxuLy8gTWFyayB0aGlzIHByaXZhdGVcbmZ1bmN0aW9uIHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VySWQsIHBhc3N3b3JkLCBjb25maWcpIHtcbiAgcmV0dXJuIHJlc3QudXBkYXRlKGNvbmZpZywgQXV0aC5tYXN0ZXIoY29uZmlnKSwgJ19Vc2VyJywgeyBvYmplY3RJZDogdXNlcklkIH0sIHtcbiAgICBwYXNzd29yZDogcGFzc3dvcmRcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRW1haWxMaW5rKGRlc3RpbmF0aW9uLCB1c2VybmFtZSwgdG9rZW4sIGNvbmZpZykge1xuICBjb25zdCB1c2VybmFtZUFuZFRva2VuID0gYHRva2VuPSR7dG9rZW59JnVzZXJuYW1lPSR7dXNlcm5hbWV9YFxuXG4gIGlmIChjb25maWcucGFyc2VGcmFtZVVSTCkge1xuICAgIGNvbnN0IGRlc3RpbmF0aW9uV2l0aG91dEhvc3QgPSBkZXN0aW5hdGlvbi5yZXBsYWNlKGNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwsICcnKTtcblxuICAgIHJldHVybiBgJHtjb25maWcucGFyc2VGcmFtZVVSTH0/bGluaz0ke2VuY29kZVVSSUNvbXBvbmVudChkZXN0aW5hdGlvbldpdGhvdXRIb3N0KX0mJHt1c2VybmFtZUFuZFRva2VufWA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGAke2Rlc3RpbmF0aW9ufT8ke3VzZXJuYW1lQW5kVG9rZW59YDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVc2VyQ29udHJvbGxlcjtcbiJdfQ==
354
+ var _default = exports.default = UserController;
355
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY3J5cHRvVXRpbHMiLCJyZXF1aXJlIiwiX3RyaWdnZXJzIiwiX0FkYXB0YWJsZUNvbnRyb2xsZXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX01haWxBZGFwdGVyIiwiX3Jlc3QiLCJfbm9kZSIsIl9BY2NvdW50TG9ja291dCIsIl9Db25maWciLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJSZXN0UXVlcnkiLCJBdXRoIiwiVXNlckNvbnRyb2xsZXIiLCJBZGFwdGFibGVDb250cm9sbGVyIiwiY29uc3RydWN0b3IiLCJhZGFwdGVyIiwiYXBwSWQiLCJvcHRpb25zIiwiY29uZmlnIiwiQ29uZmlnIiwiZ2V0IiwidmFsaWRhdGVBZGFwdGVyIiwic2hvdWxkVmVyaWZ5RW1haWxzIiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIk1haWxBZGFwdGVyIiwidmVyaWZ5VXNlckVtYWlscyIsInNldEVtYWlsVmVyaWZ5VG9rZW4iLCJ1c2VyIiwicmVxIiwic3RvcmFnZSIsInNob3VsZFNlbmRFbWFpbCIsIlByb21pc2UiLCJyZXNvbHZlIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiX2VtYWlsX3ZlcmlmeV90b2tlbiIsInJhbmRvbVN0cmluZyIsImZpZWxkc0NoYW5nZWRCeVRyaWdnZXIiLCJpbmNsdWRlcyIsImVtYWlsVmVyaWZpZWQiLCJlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbiIsIl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCIsIlBhcnNlIiwiX2VuY29kZSIsImdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCIsInZlcmlmeUVtYWlsIiwidG9rZW4iLCJ1bmRlZmluZWQiLCJxdWVyeSIsInVwZGF0ZUZpZWxkcyIsIl9fb3AiLCIkZ3QiLCJEYXRlIiwibWFpbnRlbmFuY2VBdXRoIiwibWFpbnRlbmFuY2UiLCJyZXN0UXVlcnkiLCJtZXRob2QiLCJNZXRob2QiLCJhdXRoIiwiY2xhc3NOYW1lIiwicmVzdFdoZXJlIiwicmVzdWx0IiwiZXhlY3V0ZSIsInJlc3VsdHMiLCJsZW5ndGgiLCJvYmplY3RJZCIsInJlc3QiLCJ1cGRhdGUiLCJjaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSIsImRhdGFiYXNlIiwiZmluZCIsIl9wZXJpc2hhYmxlX3Rva2VuIiwibGltaXQiLCJwYXNzd29yZFBvbGljeSIsInJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZXhwaXJlc0RhdGUiLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiX190eXBlIiwiaXNvIiwiZ2V0VXNlcklmTmVlZGVkIiwid2hlcmUiLCJ1c2VybmFtZSIsImVtYWlsIiwicnVuQmVmb3JlRmluZCIsIm1hc3RlciIsImVuY29kZVVSSUNvbXBvbmVudCIsImZldGNoZWRVc2VyIiwic2VuZFVzZXJFbWFpbFZlcmlmaWNhdGlvbiIsInJlc3BvbnNlIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJpc01hc3RlciIsImxpbmsiLCJidWlsZEVtYWlsTGluayIsInZlcmlmeUVtYWlsVVJMIiwiYXBwTmFtZSIsImluZmxhdGUiLCJzZW5kTWFpbCIsImRlZmF1bHRWZXJpZmljYXRpb25FbWFpbCIsInJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuIiwiaW5zdGFsbGF0aW9uSWQiLCJpcCIsImVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQiLCJzaG91bGRTZW5kIiwib2JqZWN0IiwiVXNlciIsImFzc2lnbiIsInJlc2VuZFJlcXVlc3QiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImFVc2VyIiwiZ2VuZXJhdGUiLCJzZXRQYXNzd29yZFJlc2V0VG9rZW4iLCJnZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCIsIiRvciIsIiRleGlzdHMiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwicmVzZXRUb2tlblJldXNlSWZWYWxpZCIsInJlcXVlc3RSZXNldFBhc3N3b3JkVVJMIiwiZGVmYXVsdFJlc2V0UGFzc3dvcmRFbWFpbCIsInVwZGF0ZVBhc3N3b3JkIiwicGFzc3dvcmQiLCJyYXdVc2VyIiwidXBkYXRlVXNlclBhc3N3b3JkIiwiYWNjb3VudExvY2tvdXRQb2xpY3kiLCJBY2NvdW50TG9ja291dCIsInVubG9ja0FjY291bnQiLCJlcnJvciIsIm1lc3NhZ2UiLCJyZWplY3QiLCJ0ZXh0IiwidG8iLCJzdWJqZWN0IiwiZXhwb3J0cyIsInRoZW4iLCJkZXN0aW5hdGlvbiIsInBhcnNlRnJhbWVVUkwiLCJkZXN0aW5hdGlvbldpdGhvdXRIb3N0IiwicmVwbGFjZSIsInB1YmxpY1NlcnZlclVSTCIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL0NvbnRyb2xsZXJzL1VzZXJDb250cm9sbGVyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbVN0cmluZyB9IGZyb20gJy4uL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGluZmxhdGUgfSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IE1haWxBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL0VtYWlsL01haWxBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IEFjY291bnRMb2Nrb3V0IGZyb20gJy4uL0FjY291bnRMb2Nrb3V0JztcbmltcG9ydCBDb25maWcgZnJvbSAnLi4vQ29uZmlnJztcblxudmFyIFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4uL1Jlc3RRdWVyeScpO1xudmFyIEF1dGggPSByZXF1aXJlKCcuLi9BdXRoJyk7XG5cbmV4cG9ydCBjbGFzcyBVc2VyQ29udHJvbGxlciBleHRlbmRzIEFkYXB0YWJsZUNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3RvcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgZ2V0IGNvbmZpZygpIHtcbiAgICByZXR1cm4gQ29uZmlnLmdldCh0aGlzLmFwcElkKTtcbiAgfVxuXG4gIHZhbGlkYXRlQWRhcHRlcihhZGFwdGVyKSB7XG4gICAgLy8gQWxsb3cgbm8gYWRhcHRlclxuICAgIGlmICghYWRhcHRlciAmJiAhdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc3VwZXIudmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpO1xuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gTWFpbEFkYXB0ZXI7XG4gIH1cblxuICBnZXQgc2hvdWxkVmVyaWZ5RW1haWxzKCkge1xuICAgIHJldHVybiAodGhpcy5jb25maWcgfHwgdGhpcy5vcHRpb25zKS52ZXJpZnlVc2VyRW1haWxzO1xuICB9XG5cbiAgYXN5bmMgc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyLCByZXEsIHN0b3JhZ2UgPSB7fSkge1xuICAgIGNvbnN0IHNob3VsZFNlbmRFbWFpbCA9XG4gICAgICB0aGlzLnNob3VsZFZlcmlmeUVtYWlscyA9PT0gdHJ1ZSB8fFxuICAgICAgKHR5cGVvZiB0aGlzLnNob3VsZFZlcmlmeUVtYWlscyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICAoYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKHJlcSkpKSA9PT0gdHJ1ZSk7XG4gICAgaWYgKCFzaG91bGRTZW5kRW1haWwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgc3RvcmFnZS5zZW5kVmVyaWZpY2F0aW9uRW1haWwgPSB0cnVlO1xuICAgIHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbiA9IHJhbmRvbVN0cmluZygyNSk7XG4gICAgaWYgKFxuICAgICAgIXN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlciB8fFxuICAgICAgIXN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlci5pbmNsdWRlcygnZW1haWxWZXJpZmllZCcpXG4gICAgKSB7XG4gICAgICB1c2VyLmVtYWlsVmVyaWZpZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0gUGFyc2UuX2VuY29kZShcbiAgICAgICAgdGhpcy5jb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0KClcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5RW1haWwodG9rZW4pIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICAvLyBUcnlpbmcgdG8gdmVyaWZ5IGVtYWlsIHdoZW4gbm90IGVuYWJsZWRcbiAgICAgIC8vIFRPRE86IEJldHRlciBlcnJvciBoZXJlLlxuICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5ID0geyBfZW1haWxfdmVyaWZ5X3Rva2VuOiB0b2tlbiB9O1xuICAgIGNvbnN0IHVwZGF0ZUZpZWxkcyA9IHtcbiAgICAgIGVtYWlsVmVyaWZpZWQ6IHRydWUsXG4gICAgICBfZW1haWxfdmVyaWZ5X3Rva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0sXG4gICAgfTtcblxuICAgIC8vIGlmIHRoZSBlbWFpbCB2ZXJpZnkgdG9rZW4gbmVlZHMgdG8gYmUgdmFsaWRhdGVkIHRoZW5cbiAgICAvLyBhZGQgYWRkaXRpb25hbCBxdWVyeSBwYXJhbXMgYW5kIGFkZGl0aW9uYWwgZmllbGRzIHRoYXQgbmVlZCB0byBiZSB1cGRhdGVkXG4gICAgaWYgKHRoaXMuY29uZmlnLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICBxdWVyeS5lbWFpbFZlcmlmaWVkID0gZmFsc2U7XG4gICAgICBxdWVyeS5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgPSB7ICRndDogUGFyc2UuX2VuY29kZShuZXcgRGF0ZSgpKSB9O1xuXG4gICAgICB1cGRhdGVGaWVsZHMuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0geyBfX29wOiAnRGVsZXRlJyB9O1xuICAgIH1cbiAgICBjb25zdCBtYWludGVuYW5jZUF1dGggPSBBdXRoLm1haW50ZW5hbmNlKHRoaXMuY29uZmlnKTtcbiAgICBjb25zdCByZXN0UXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgICAgbWV0aG9kOiBSZXN0UXVlcnkuTWV0aG9kLmdldCxcbiAgICAgIGNvbmZpZzogdGhpcy5jb25maWcsXG4gICAgICBhdXRoOiBtYWludGVuYW5jZUF1dGgsXG4gICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICByZXN0V2hlcmU6IHF1ZXJ5LFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzdFF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICBpZiAocmVzdWx0LnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICBxdWVyeS5vYmplY3RJZCA9IHJlc3VsdC5yZXN1bHRzWzBdLm9iamVjdElkO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgcmVzdC51cGRhdGUodGhpcy5jb25maWcsIG1haW50ZW5hbmNlQXV0aCwgJ19Vc2VyJywgcXVlcnksIHVwZGF0ZUZpZWxkcyk7XG4gIH1cblxuICBhc3luYyBjaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh0b2tlbikge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmNvbmZpZy5kYXRhYmFzZS5maW5kKFxuICAgICAgJ19Vc2VyJyxcbiAgICAgIHtcbiAgICAgICAgX3BlcmlzaGFibGVfdG9rZW46IHRva2VuLFxuICAgICAgfSxcbiAgICAgIHsgbGltaXQ6IDEgfSxcbiAgICAgIEF1dGgubWFpbnRlbmFuY2UodGhpcy5jb25maWcpXG4gICAgKTtcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93ICdGYWlsZWQgdG8gcmVzZXQgcGFzc3dvcmQ6IHVzZXJuYW1lIC8gZW1haWwgLyB0b2tlbiBpcyBpbnZhbGlkJztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIGxldCBleHBpcmVzRGF0ZSA9IHJlc3VsdHNbMF0uX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdDtcbiAgICAgIGlmIChleHBpcmVzRGF0ZSAmJiBleHBpcmVzRGF0ZS5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgICAgIGV4cGlyZXNEYXRlID0gbmV3IERhdGUoZXhwaXJlc0RhdGUuaXNvKTtcbiAgICAgIH1cbiAgICAgIGlmIChleHBpcmVzRGF0ZSA8IG5ldyBEYXRlKCkpIHtcbiAgICAgICAgdGhyb3cgJ1RoZSBwYXNzd29yZCByZXNldCBsaW5rIGhhcyBleHBpcmVkJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0c1swXTtcbiAgfVxuXG4gIGFzeW5jIGdldFVzZXJJZk5lZWRlZCh1c2VyKSB7XG4gICAgdmFyIHdoZXJlID0ge307XG4gICAgaWYgKHVzZXIudXNlcm5hbWUpIHtcbiAgICAgIHdoZXJlLnVzZXJuYW1lID0gdXNlci51c2VybmFtZTtcbiAgICB9XG4gICAgaWYgKHVzZXIuZW1haWwpIHtcbiAgICAgIHdoZXJlLmVtYWlsID0gdXNlci5lbWFpbDtcbiAgICB9XG4gICAgaWYgKHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbikge1xuICAgICAgd2hlcmUuX2VtYWlsX3ZlcmlmeV90b2tlbiA9IHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbjtcbiAgICB9XG5cbiAgICB2YXIgcXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgICAgbWV0aG9kOiBSZXN0UXVlcnkuTWV0aG9kLmdldCxcbiAgICAgIGNvbmZpZzogdGhpcy5jb25maWcsXG4gICAgICBydW5CZWZvcmVGaW5kOiBmYWxzZSxcbiAgICAgIGF1dGg6IEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSxcbiAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgIHJlc3RXaGVyZTogd2hlcmUsXG4gICAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcXVlcnkuZXhlY3V0ZSgpO1xuICAgIGlmIChyZXN1bHQucmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0LnJlc3VsdHNbMF07XG4gIH1cblxuICBhc3luYyBzZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlciwgcmVxKSB7XG4gICAgaWYgKCF0aGlzLnNob3VsZFZlcmlmeUVtYWlscykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0b2tlbiA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW4pO1xuICAgIC8vIFdlIG1heSBuZWVkIHRvIGZldGNoIHRoZSB1c2VyIGluIGNhc2Ugb2YgdXBkYXRlIGVtYWlsOyBvbmx5IHVzZSB0aGUgYGZldGNoZWRVc2VyYFxuICAgIC8vIGZyb20gdGhpcyBwb2ludCBvbndhcmRzOyBkbyBub3QgdXNlIHRoZSBgdXNlcmAgYXMgaXQgbWF5IG5vdCBjb250YWluIGFsbCBmaWVsZHMuXG4gICAgY29uc3QgZmV0Y2hlZFVzZXIgPSBhd2FpdCB0aGlzLmdldFVzZXJJZk5lZWRlZCh1c2VyKTtcbiAgICBsZXQgc2hvdWxkU2VuZEVtYWlsID0gdGhpcy5jb25maWcuc2VuZFVzZXJFbWFpbFZlcmlmaWNhdGlvbjtcbiAgICBpZiAodHlwZW9mIHNob3VsZFNlbmRFbWFpbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgIHRoaXMuY29uZmlnLnNlbmRVc2VyRW1haWxWZXJpZmljYXRpb24oe1xuICAgICAgICAgIHVzZXI6IFBhcnNlLk9iamVjdC5mcm9tSlNPTih7IGNsYXNzTmFtZTogJ19Vc2VyJywgLi4uZmV0Y2hlZFVzZXIgfSksXG4gICAgICAgICAgbWFzdGVyOiByZXEuYXV0aD8uaXNNYXN0ZXIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgc2hvdWxkU2VuZEVtYWlsID0gISFyZXNwb25zZTtcbiAgICB9XG4gICAgaWYgKCFzaG91bGRTZW5kRW1haWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGluayA9IGJ1aWxkRW1haWxMaW5rKHRoaXMuY29uZmlnLnZlcmlmeUVtYWlsVVJMLCB0b2tlbiwgdGhpcy5jb25maWcpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICBhcHBOYW1lOiB0aGlzLmNvbmZpZy5hcHBOYW1lLFxuICAgICAgbGluazogbGluayxcbiAgICAgIHVzZXI6IGluZmxhdGUoJ19Vc2VyJywgZmV0Y2hlZFVzZXIpLFxuICAgIH07XG4gICAgaWYgKHRoaXMuYWRhcHRlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwpIHtcbiAgICAgIHRoaXMuYWRhcHRlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwob3B0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWRhcHRlci5zZW5kTWFpbCh0aGlzLmRlZmF1bHRWZXJpZmljYXRpb25FbWFpbChvcHRpb25zKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2VuZXJhdGVzIHRoZSBnaXZlbiB1c2VyJ3MgZW1haWwgdmVyaWZpY2F0aW9uIHRva2VuXG4gICAqXG4gICAqIEBwYXJhbSB1c2VyXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgYXN5bmMgcmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4odXNlciwgbWFzdGVyLCBpbnN0YWxsYXRpb25JZCwgaXApIHtcbiAgICBjb25zdCB7IF9lbWFpbF92ZXJpZnlfdG9rZW4gfSA9IHVzZXI7XG4gICAgbGV0IHsgX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0IH0gPSB1c2VyO1xuICAgIGlmIChfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgJiYgX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0Ll9fdHlwZSA9PT0gJ0RhdGUnKSB7XG4gICAgICBfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgPSBfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQuaXNvO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkICYmXG4gICAgICB0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbiAmJlxuICAgICAgX2VtYWlsX3ZlcmlmeV90b2tlbiAmJlxuICAgICAgbmV3IERhdGUoKSA8IG5ldyBEYXRlKF9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdClcbiAgICApIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XG4gICAgfVxuICAgIGNvbnN0IHNob3VsZFNlbmQgPSBhd2FpdCB0aGlzLnNldEVtYWlsVmVyaWZ5VG9rZW4odXNlciwge1xuICAgICAgb2JqZWN0OiBQYXJzZS5Vc2VyLmZyb21KU09OKE9iamVjdC5hc3NpZ24oeyBjbGFzc05hbWU6ICdfVXNlcicgfSwgdXNlcikpLFxuICAgICAgbWFzdGVyLFxuICAgICAgaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpcCxcbiAgICAgIHJlc2VuZFJlcXVlc3Q6IHRydWVcbiAgICB9KTtcbiAgICBpZiAoIXNob3VsZFNlbmQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCB7IHVzZXJuYW1lOiB1c2VyLnVzZXJuYW1lIH0sIHVzZXIpO1xuICB9XG5cbiAgYXN5bmMgcmVzZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlcm5hbWUsIHJlcSwgdG9rZW4pIHtcbiAgICBjb25zdCBhVXNlciA9IGF3YWl0IHRoaXMuZ2V0VXNlcklmTmVlZGVkKHsgdXNlcm5hbWUsIF9lbWFpbF92ZXJpZnlfdG9rZW46IHRva2VuIH0pO1xuICAgIGlmICghYVVzZXIgfHwgYVVzZXIuZW1haWxWZXJpZmllZCkge1xuICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBnZW5lcmF0ZSA9IGF3YWl0IHRoaXMucmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4oYVVzZXIsIHJlcS5hdXRoPy5pc01hc3RlciwgcmVxLmF1dGg/Lmluc3RhbGxhdGlvbklkLCByZXEuaXApO1xuICAgIGlmIChnZW5lcmF0ZSkge1xuICAgICAgdGhpcy5zZW5kVmVyaWZpY2F0aW9uRW1haWwoYVVzZXIsIHJlcSk7XG4gICAgfVxuICB9XG5cbiAgc2V0UGFzc3dvcmRSZXNldFRva2VuKGVtYWlsKSB7XG4gICAgY29uc3QgdG9rZW4gPSB7IF9wZXJpc2hhYmxlX3Rva2VuOiByYW5kb21TdHJpbmcoMjUpIH07XG5cbiAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHRva2VuLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICB0aGlzLmNvbmZpZy5nZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCgpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAnX1VzZXInLFxuICAgICAgeyAkb3I6IFt7IGVtYWlsIH0sIHsgdXNlcm5hbWU6IGVtYWlsLCBlbWFpbDogeyAkZXhpc3RzOiBmYWxzZSB9IH1dIH0sXG4gICAgICB0b2tlbixcbiAgICAgIHt9LFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBhc3luYyBzZW5kUGFzc3dvcmRSZXNldEVtYWlsKGVtYWlsKSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdUcnlpbmcgdG8gc2VuZCBhIHJlc2V0IHBhc3N3b3JkIGJ1dCBubyBhZGFwdGVyIGlzIHNldCc7XG4gICAgICAvLyAgVE9ETzogTm8gYWRhcHRlcj9cbiAgICB9XG4gICAgbGV0IHVzZXI7XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uXG4gICAgKSB7XG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAge1xuICAgICAgICAgICRvcjogW1xuICAgICAgICAgICAgeyBlbWFpbCwgX3BlcmlzaGFibGVfdG9rZW46IHsgJGV4aXN0czogdHJ1ZSB9IH0sXG4gICAgICAgICAgICB7IHVzZXJuYW1lOiBlbWFpbCwgZW1haWw6IHsgJGV4aXN0czogZmFsc2UgfSwgX3BlcmlzaGFibGVfdG9rZW46IHsgJGV4aXN0czogdHJ1ZSB9IH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBsaW1pdDogMSB9LFxuICAgICAgICBBdXRoLm1haW50ZW5hbmNlKHRoaXMuY29uZmlnKVxuICAgICAgKTtcbiAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIGxldCBleHBpcmVzRGF0ZSA9IHJlc3VsdHNbMF0uX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdDtcbiAgICAgICAgaWYgKGV4cGlyZXNEYXRlICYmIGV4cGlyZXNEYXRlLl9fdHlwZSA9PSAnRGF0ZScpIHtcbiAgICAgICAgICBleHBpcmVzRGF0ZSA9IG5ldyBEYXRlKGV4cGlyZXNEYXRlLmlzbyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4cGlyZXNEYXRlID4gbmV3IERhdGUoKSkge1xuICAgICAgICAgIHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghdXNlciB8fCAhdXNlci5fcGVyaXNoYWJsZV90b2tlbikge1xuICAgICAgdXNlciA9IGF3YWl0IHRoaXMuc2V0UGFzc3dvcmRSZXNldFRva2VuKGVtYWlsKTtcbiAgICB9XG4gICAgY29uc3QgdG9rZW4gPSBlbmNvZGVVUklDb21wb25lbnQodXNlci5fcGVyaXNoYWJsZV90b2tlbik7XG4gICAgY29uc3QgbGluayA9IGJ1aWxkRW1haWxMaW5rKHRoaXMuY29uZmlnLnJlcXVlc3RSZXNldFBhc3N3b3JkVVJMLCB0b2tlbiwgdGhpcy5jb25maWcpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICBhcHBOYW1lOiB0aGlzLmNvbmZpZy5hcHBOYW1lLFxuICAgICAgbGluazogbGluayxcbiAgICAgIHVzZXI6IGluZmxhdGUoJ19Vc2VyJywgdXNlciksXG4gICAgfTtcblxuICAgIGlmICh0aGlzLmFkYXB0ZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCkge1xuICAgICAgdGhpcy5hZGFwdGVyLnNlbmRQYXNzd29yZFJlc2V0RW1haWwob3B0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWRhcHRlci5zZW5kTWFpbCh0aGlzLmRlZmF1bHRSZXNldFBhc3N3b3JkRW1haWwob3B0aW9ucykpO1xuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlcik7XG4gIH1cblxuICBhc3luYyB1cGRhdGVQYXNzd29yZCh0b2tlbiwgcGFzc3dvcmQpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3VXNlciA9IGF3YWl0IHRoaXMuY2hlY2tSZXNldFRva2VuVmFsaWRpdHkodG9rZW4pO1xuICAgICAgY29uc3QgdXNlciA9IGF3YWl0IHVwZGF0ZVVzZXJQYXNzd29yZChyYXdVc2VyLCBwYXNzd29yZCwgdGhpcy5jb25maWcpO1xuXG4gICAgICBjb25zdCBhY2NvdW50TG9ja291dFBvbGljeSA9IG5ldyBBY2NvdW50TG9ja291dCh1c2VyLCB0aGlzLmNvbmZpZyk7XG4gICAgICByZXR1cm4gYXdhaXQgYWNjb3VudExvY2tvdXRQb2xpY3kudW5sb2NrQWNjb3VudCgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAvLyBpbiBjYXNlIG9mIFBhcnNlLkVycm9yLCBmYWlsIHdpdGggdGhlIGVycm9yIG1lc3NhZ2Ugb25seVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGRlZmF1bHRWZXJpZmljYXRpb25FbWFpbCh7IGxpbmssIHVzZXIsIGFwcE5hbWUgfSkge1xuICAgIGNvbnN0IHRleHQgPVxuICAgICAgJ0hpLFxcblxcbicgK1xuICAgICAgJ1lvdSBhcmUgYmVpbmcgYXNrZWQgdG8gY29uZmlybSB0aGUgZS1tYWlsIGFkZHJlc3MgJyArXG4gICAgICB1c2VyLmdldCgnZW1haWwnKSArXG4gICAgICAnIHdpdGggJyArXG4gICAgICBhcHBOYW1lICtcbiAgICAgICdcXG5cXG4nICtcbiAgICAgICcnICtcbiAgICAgICdDbGljayBoZXJlIHRvIGNvbmZpcm0gaXQ6XFxuJyArXG4gICAgICBsaW5rO1xuICAgIGNvbnN0IHRvID0gdXNlci5nZXQoJ2VtYWlsJyk7XG4gICAgY29uc3Qgc3ViamVjdCA9ICdQbGVhc2UgdmVyaWZ5IHlvdXIgZS1tYWlsIGZvciAnICsgYXBwTmFtZTtcbiAgICByZXR1cm4geyB0ZXh0LCB0bywgc3ViamVjdCB9O1xuICB9XG5cbiAgZGVmYXVsdFJlc2V0UGFzc3dvcmRFbWFpbCh7IGxpbmssIHVzZXIsIGFwcE5hbWUgfSkge1xuICAgIGNvbnN0IHRleHQgPVxuICAgICAgJ0hpLFxcblxcbicgK1xuICAgICAgJ1lvdSByZXF1ZXN0ZWQgdG8gcmVzZXQgeW91ciBwYXNzd29yZCBmb3IgJyArXG4gICAgICBhcHBOYW1lICtcbiAgICAgICh1c2VyLmdldCgndXNlcm5hbWUnKSA/IFwiICh5b3VyIHVzZXJuYW1lIGlzICdcIiArIHVzZXIuZ2V0KCd1c2VybmFtZScpICsgXCInKVwiIDogJycpICtcbiAgICAgICcuXFxuXFxuJyArXG4gICAgICAnJyArXG4gICAgICAnQ2xpY2sgaGVyZSB0byByZXNldCBpdDpcXG4nICtcbiAgICAgIGxpbms7XG4gICAgY29uc3QgdG8gPSB1c2VyLmdldCgnZW1haWwnKSB8fCB1c2VyLmdldCgndXNlcm5hbWUnKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gJ1Bhc3N3b3JkIFJlc2V0IGZvciAnICsgYXBwTmFtZTtcbiAgICByZXR1cm4geyB0ZXh0LCB0bywgc3ViamVjdCB9O1xuICB9XG59XG5cbi8vIE1hcmsgdGhpcyBwcml2YXRlXG5mdW5jdGlvbiB1cGRhdGVVc2VyUGFzc3dvcmQodXNlciwgcGFzc3dvcmQsIGNvbmZpZykge1xuICByZXR1cm4gcmVzdFxuICAgIC51cGRhdGUoXG4gICAgICBjb25maWcsXG4gICAgICBBdXRoLm1hc3Rlcihjb25maWcpLFxuICAgICAgJ19Vc2VyJyxcbiAgICAgIHsgb2JqZWN0SWQ6IHVzZXIub2JqZWN0SWQgfSxcbiAgICAgIHtcbiAgICAgICAgcGFzc3dvcmQ6IHBhc3N3b3JkLFxuICAgICAgfVxuICAgIClcbiAgICAudGhlbigoKSA9PiB1c2VyKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRFbWFpbExpbmsoZGVzdGluYXRpb24sIHRva2VuLCBjb25maWcpIHtcbiAgdG9rZW4gPSBgdG9rZW49JHt0b2tlbn1gO1xuICBpZiAoY29uZmlnLnBhcnNlRnJhbWVVUkwpIHtcbiAgICBjb25zdCBkZXN0aW5hdGlvbldpdGhvdXRIb3N0ID0gZGVzdGluYXRpb24ucmVwbGFjZShjb25maWcucHVibGljU2VydmVyVVJMLCAnJyk7XG5cbiAgICByZXR1cm4gYCR7Y29uZmlnLnBhcnNlRnJhbWVVUkx9P2xpbms9JHtlbmNvZGVVUklDb21wb25lbnQoZGVzdGluYXRpb25XaXRob3V0SG9zdCl9JiR7dG9rZW59YDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYCR7ZGVzdGluYXRpb259PyR7dG9rZW59YDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVc2VyQ29udHJvbGxlcjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsWUFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsU0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsb0JBQUEsR0FBQUMsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFJLFlBQUEsR0FBQUQsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFLLEtBQUEsR0FBQUYsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFNLEtBQUEsR0FBQUgsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFPLGVBQUEsR0FBQUosc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFRLE9BQUEsR0FBQUwsc0JBQUEsQ0FBQUgsT0FBQTtBQUErQixTQUFBRyx1QkFBQU0sQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQUUvQixJQUFJRyxTQUFTLEdBQUdaLE9BQU8sQ0FBQyxjQUFjLENBQUM7QUFDdkMsSUFBSWEsSUFBSSxHQUFHYixPQUFPLENBQUMsU0FBUyxDQUFDO0FBRXRCLE1BQU1jLGNBQWMsU0FBU0MsNEJBQW1CLENBQUM7RUFDdERDLFdBQVdBLENBQUNDLE9BQU8sRUFBRUMsS0FBSyxFQUFFQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLEVBQUU7SUFDeEMsS0FBSyxDQUFDRixPQUFPLEVBQUVDLEtBQUssRUFBRUMsT0FBTyxDQUFDO0VBQ2hDO0VBRUEsSUFBSUMsTUFBTUEsQ0FB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