@beiguancyc/parse-server 9.9.0-ruixiang.1

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 (251) hide show
  1. package/LICENSE +176 -0
  2. package/NOTICE +10 -0
  3. package/README.md +1311 -0
  4. package/bin/parse-live-query-server +3 -0
  5. package/bin/parse-server +3 -0
  6. package/lib/AccountLockout.js +149 -0
  7. package/lib/Adapters/AdapterLoader.js +60 -0
  8. package/lib/Adapters/Analytics/AnalyticsAdapter.js +32 -0
  9. package/lib/Adapters/Auth/AuthAdapter.js +132 -0
  10. package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +119 -0
  11. package/lib/Adapters/Auth/OAuth1Client.js +204 -0
  12. package/lib/Adapters/Auth/apple.js +125 -0
  13. package/lib/Adapters/Auth/facebook.js +187 -0
  14. package/lib/Adapters/Auth/gcenter.js +217 -0
  15. package/lib/Adapters/Auth/github.js +125 -0
  16. package/lib/Adapters/Auth/google.js +122 -0
  17. package/lib/Adapters/Auth/gpgames.js +125 -0
  18. package/lib/Adapters/Auth/httpsRequest.js +41 -0
  19. package/lib/Adapters/Auth/index.js +248 -0
  20. package/lib/Adapters/Auth/instagram.js +118 -0
  21. package/lib/Adapters/Auth/janraincapture.js +85 -0
  22. package/lib/Adapters/Auth/janrainengage.js +57 -0
  23. package/lib/Adapters/Auth/keycloak.js +168 -0
  24. package/lib/Adapters/Auth/ldap.js +193 -0
  25. package/lib/Adapters/Auth/line.js +125 -0
  26. package/lib/Adapters/Auth/linkedin.js +117 -0
  27. package/lib/Adapters/Auth/meetup.js +44 -0
  28. package/lib/Adapters/Auth/mfa.js +334 -0
  29. package/lib/Adapters/Auth/microsoft.js +111 -0
  30. package/lib/Adapters/Auth/oauth2.js +115 -0
  31. package/lib/Adapters/Auth/phantauth.js +53 -0
  32. package/lib/Adapters/Auth/qq.js +113 -0
  33. package/lib/Adapters/Auth/spotify.js +115 -0
  34. package/lib/Adapters/Auth/twitter.js +197 -0
  35. package/lib/Adapters/Auth/utils.js +28 -0
  36. package/lib/Adapters/Auth/vkontakte.js +55 -0
  37. package/lib/Adapters/Auth/wechat.js +110 -0
  38. package/lib/Adapters/Auth/weibo.js +141 -0
  39. package/lib/Adapters/Cache/CacheAdapter.js +40 -0
  40. package/lib/Adapters/Cache/InMemoryCache.js +61 -0
  41. package/lib/Adapters/Cache/InMemoryCacheAdapter.js +34 -0
  42. package/lib/Adapters/Cache/LRUCache.js +35 -0
  43. package/lib/Adapters/Cache/NullCacheAdapter.js +26 -0
  44. package/lib/Adapters/Cache/RedisCacheAdapter.js +109 -0
  45. package/lib/Adapters/Cache/SchemaCache.js +25 -0
  46. package/lib/Adapters/Email/MailAdapter.js +32 -0
  47. package/lib/Adapters/Files/FilesAdapter.js +129 -0
  48. package/lib/Adapters/Files/GridFSBucketAdapter.js +280 -0
  49. package/lib/Adapters/Files/GridStoreAdapter.js +5 -0
  50. package/lib/Adapters/Logger/LoggerAdapter.js +27 -0
  51. package/lib/Adapters/Logger/WinstonLogger.js +107 -0
  52. package/lib/Adapters/Logger/WinstonLoggerAdapter.js +63 -0
  53. package/lib/Adapters/MessageQueue/EventEmitterMQ.js +55 -0
  54. package/lib/Adapters/PubSub/EventEmitterPubSub.js +53 -0
  55. package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
  56. package/lib/Adapters/PubSub/RedisPubSub.js +49 -0
  57. package/lib/Adapters/Push/PushAdapter.js +40 -0
  58. package/lib/Adapters/Storage/Mongo/MongoCollection.js +212 -0
  59. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +334 -0
  60. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +1047 -0
  61. package/lib/Adapters/Storage/Mongo/MongoTransform.js +1397 -0
  62. package/lib/Adapters/Storage/Postgres/PostgresClient.js +38 -0
  63. package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +73 -0
  64. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +2409 -0
  65. package/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql +11 -0
  66. package/lib/Adapters/Storage/Postgres/sql/array/add.sql +11 -0
  67. package/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql +14 -0
  68. package/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql +14 -0
  69. package/lib/Adapters/Storage/Postgres/sql/array/contains.sql +11 -0
  70. package/lib/Adapters/Storage/Postgres/sql/array/remove.sql +11 -0
  71. package/lib/Adapters/Storage/Postgres/sql/index.js +32 -0
  72. package/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql +19 -0
  73. package/lib/Adapters/Storage/StorageAdapter.js +2 -0
  74. package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
  75. package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
  76. package/lib/Auth.js +687 -0
  77. package/lib/AuthDataLock.js +53 -0
  78. package/lib/ClientSDK.js +39 -0
  79. package/lib/Config.js +879 -0
  80. package/lib/Controllers/AdaptableController.js +72 -0
  81. package/lib/Controllers/AnalyticsController.js +43 -0
  82. package/lib/Controllers/CacheController.js +71 -0
  83. package/lib/Controllers/DatabaseController.js +1685 -0
  84. package/lib/Controllers/FilesController.js +122 -0
  85. package/lib/Controllers/HooksController.js +254 -0
  86. package/lib/Controllers/LiveQueryController.js +72 -0
  87. package/lib/Controllers/LoggerController.js +222 -0
  88. package/lib/Controllers/ParseGraphQLController.js +294 -0
  89. package/lib/Controllers/PushController.js +224 -0
  90. package/lib/Controllers/SchemaController.js +1563 -0
  91. package/lib/Controllers/UserController.js +364 -0
  92. package/lib/Controllers/index.js +251 -0
  93. package/lib/Controllers/types.js +2 -0
  94. package/lib/Deprecator/Deprecations.js +100 -0
  95. package/lib/Deprecator/Deprecator.js +140 -0
  96. package/lib/Error.js +50 -0
  97. package/lib/FileUrlValidator.js +69 -0
  98. package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
  99. package/lib/GraphQL/ParseGraphQLServer.js +241 -0
  100. package/lib/GraphQL/helpers/objectsMutations.js +30 -0
  101. package/lib/GraphQL/helpers/objectsQueries.js +246 -0
  102. package/lib/GraphQL/helpers/queryComplexity.js +138 -0
  103. package/lib/GraphQL/loaders/configMutations.js +87 -0
  104. package/lib/GraphQL/loaders/configQueries.js +79 -0
  105. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
  106. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
  107. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1099 -0
  108. package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
  109. package/lib/GraphQL/loaders/filesMutations.js +107 -0
  110. package/lib/GraphQL/loaders/functionsMutations.js +77 -0
  111. package/lib/GraphQL/loaders/parseClassMutations.js +267 -0
  112. package/lib/GraphQL/loaders/parseClassQueries.js +126 -0
  113. package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
  114. package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
  115. package/lib/GraphQL/loaders/schemaMutations.js +161 -0
  116. package/lib/GraphQL/loaders/schemaQueries.js +80 -0
  117. package/lib/GraphQL/loaders/schemaTypes.js +341 -0
  118. package/lib/GraphQL/loaders/usersMutations.js +433 -0
  119. package/lib/GraphQL/loaders/usersQueries.js +90 -0
  120. package/lib/GraphQL/parseGraphQLUtils.js +71 -0
  121. package/lib/GraphQL/transformers/className.js +14 -0
  122. package/lib/GraphQL/transformers/constraintType.js +53 -0
  123. package/lib/GraphQL/transformers/inputType.js +51 -0
  124. package/lib/GraphQL/transformers/mutation.js +280 -0
  125. package/lib/GraphQL/transformers/outputType.js +51 -0
  126. package/lib/GraphQL/transformers/query.js +237 -0
  127. package/lib/GraphQL/transformers/schemaFields.js +99 -0
  128. package/lib/InstallationDedup.js +178 -0
  129. package/lib/KeyPromiseQueue.js +48 -0
  130. package/lib/LiveQuery/Client.js +90 -0
  131. package/lib/LiveQuery/Id.js +20 -0
  132. package/lib/LiveQuery/ParseCloudCodePublisher.js +54 -0
  133. package/lib/LiveQuery/ParseLiveQueryServer.js +1071 -0
  134. package/lib/LiveQuery/ParsePubSub.js +37 -0
  135. package/lib/LiveQuery/ParseWebSocketServer.js +66 -0
  136. package/lib/LiveQuery/QueryTools.js +443 -0
  137. package/lib/LiveQuery/RequestSchema.js +161 -0
  138. package/lib/LiveQuery/SessionTokenCache.js +51 -0
  139. package/lib/LiveQuery/Subscription.js +47 -0
  140. package/lib/LiveQuery/equalObjects.js +50 -0
  141. package/lib/Options/Definitions.js +1599 -0
  142. package/lib/Options/docs.js +389 -0
  143. package/lib/Options/index.js +12 -0
  144. package/lib/Options/parsers.js +89 -0
  145. package/lib/Page.js +44 -0
  146. package/lib/ParseMessageQueue.js +24 -0
  147. package/lib/ParseServer.js +632 -0
  148. package/lib/ParseServerRESTController.js +173 -0
  149. package/lib/PromiseRouter.js +208 -0
  150. package/lib/Push/PushQueue.js +67 -0
  151. package/lib/Push/PushWorker.js +101 -0
  152. package/lib/Push/utils.js +129 -0
  153. package/lib/RestQuery.js +1208 -0
  154. package/lib/RestWrite.js +1671 -0
  155. package/lib/Routers/AggregateRouter.js +150 -0
  156. package/lib/Routers/AnalyticsRouter.js +26 -0
  157. package/lib/Routers/AudiencesRouter.js +54 -0
  158. package/lib/Routers/ClassesRouter.js +191 -0
  159. package/lib/Routers/CloudCodeRouter.js +87 -0
  160. package/lib/Routers/FeaturesRouter.js +72 -0
  161. package/lib/Routers/FilesRouter.js +772 -0
  162. package/lib/Routers/FunctionsRouter.js +341 -0
  163. package/lib/Routers/GlobalConfigRouter.js +123 -0
  164. package/lib/Routers/GraphQLRouter.js +41 -0
  165. package/lib/Routers/HooksRouter.js +121 -0
  166. package/lib/Routers/IAPValidationRouter.js +113 -0
  167. package/lib/Routers/InstallationsRouter.js +46 -0
  168. package/lib/Routers/LogsRouter.js +57 -0
  169. package/lib/Routers/PagesRouter.js +676 -0
  170. package/lib/Routers/PurgeRouter.js +45 -0
  171. package/lib/Routers/PushRouter.js +75 -0
  172. package/lib/Routers/RolesRouter.js +33 -0
  173. package/lib/Routers/SchemasRouter.js +118 -0
  174. package/lib/Routers/SecurityRouter.js +34 -0
  175. package/lib/Routers/SessionsRouter.js +126 -0
  176. package/lib/Routers/UsersRouter.js +733 -0
  177. package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
  178. package/lib/SchemaMigrations/Migrations.js +30 -0
  179. package/lib/Security/Check.js +109 -0
  180. package/lib/Security/CheckGroup.js +44 -0
  181. package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
  182. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +160 -0
  183. package/lib/Security/CheckGroups/CheckGroups.js +21 -0
  184. package/lib/Security/CheckRunner.js +213 -0
  185. package/lib/SharedRest.js +34 -0
  186. package/lib/StatusHandler.js +329 -0
  187. package/lib/TestUtils.js +87 -0
  188. package/lib/Utils.js +577 -0
  189. package/lib/batch.js +185 -0
  190. package/lib/cache.js +12 -0
  191. package/lib/cli/definitions/parse-live-query-server.js +9 -0
  192. package/lib/cli/definitions/parse-server.js +9 -0
  193. package/lib/cli/parse-live-query-server.js +14 -0
  194. package/lib/cli/parse-server.js +101 -0
  195. package/lib/cli/utils/commander.js +132 -0
  196. package/lib/cli/utils/runner.js +53 -0
  197. package/lib/cloud-code/Parse.Cloud.js +797 -0
  198. package/lib/cloud-code/Parse.Server.js +21 -0
  199. package/lib/cryptoUtils.js +54 -0
  200. package/lib/defaults.js +58 -0
  201. package/lib/deprecated.js +12 -0
  202. package/lib/index.js +89 -0
  203. package/lib/logger.js +40 -0
  204. package/lib/middlewares.js +810 -0
  205. package/lib/password.js +40 -0
  206. package/lib/request.js +175 -0
  207. package/lib/requiredParameter.js +11 -0
  208. package/lib/rest.js +264 -0
  209. package/lib/triggers.js +949 -0
  210. package/lib/vendor/README.md +8 -0
  211. package/lib/vendor/mongodbUrl.js +1012 -0
  212. package/package.json +172 -0
  213. package/postinstall.js +38 -0
  214. package/public/custom_json.html +17 -0
  215. package/public/custom_json.json +23 -0
  216. package/public/custom_page.html +15 -0
  217. package/public/de/email_verification_link_expired.html +24 -0
  218. package/public/de/email_verification_link_invalid.html +21 -0
  219. package/public/de/email_verification_send_fail.html +21 -0
  220. package/public/de/email_verification_send_success.html +19 -0
  221. package/public/de/email_verification_success.html +18 -0
  222. package/public/de/password_reset.html +65 -0
  223. package/public/de/password_reset_link_invalid.html +19 -0
  224. package/public/de/password_reset_success.html +18 -0
  225. package/public/de-AT/email_verification_link_expired.html +24 -0
  226. package/public/de-AT/email_verification_link_invalid.html +21 -0
  227. package/public/de-AT/email_verification_send_fail.html +21 -0
  228. package/public/de-AT/email_verification_send_success.html +19 -0
  229. package/public/de-AT/email_verification_success.html +18 -0
  230. package/public/de-AT/password_reset.html +65 -0
  231. package/public/de-AT/password_reset_link_invalid.html +19 -0
  232. package/public/de-AT/password_reset_success.html +18 -0
  233. package/public/email_verification_link_expired.html +24 -0
  234. package/public/email_verification_link_invalid.html +21 -0
  235. package/public/email_verification_send_fail.html +21 -0
  236. package/public/email_verification_send_success.html +19 -0
  237. package/public/email_verification_success.html +18 -0
  238. package/public/password_reset.html +65 -0
  239. package/public/password_reset_link_invalid.html +19 -0
  240. package/public/password_reset_success.html +18 -0
  241. package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
  242. package/types/@types/deepcopy/index.d.ts +5 -0
  243. package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
  244. package/types/Options/index.d.ts +320 -0
  245. package/types/ParseServer.d.ts +65 -0
  246. package/types/eslint.config.mjs +30 -0
  247. package/types/index.d.ts +21 -0
  248. package/types/logger.d.ts +2 -0
  249. package/types/tests.ts +44 -0
  250. package/types/tsconfig.json +24 -0
  251. package/views/choose_password +215 -0
@@ -0,0 +1,334 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _otpauth = require("otpauth");
8
+ var _cryptoUtils = require("../../cryptoUtils");
9
+ var _AuthAdapter = _interopRequireDefault(require("./AuthAdapter"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ /**
12
+ * Parse Server authentication adapter for Multi-Factor Authentication (MFA).
13
+ *
14
+ * @class MFAAdapter
15
+ * @param {Object} options - The adapter options.
16
+ * @param {Array<String>} options.options - Supported MFA methods. Must include `"SMS"` or `"TOTP"`.
17
+ * @param {Number} [options.digits=6] - The number of digits for the one-time password (OTP). Must be between 4 and 10.
18
+ * @param {Number} [options.period=30] - The validity period of the OTP in seconds. Must be greater than 10.
19
+ * @param {String} [options.algorithm="SHA1"] - The algorithm used for TOTP generation. Defaults to `"SHA1"`.
20
+ * @param {Function} [options.sendSMS] - A callback function for sending SMS OTPs. Required if `"SMS"` is included in `options`.
21
+ *
22
+ * @description
23
+ * ## Parse Server Configuration
24
+ * To configure Parse Server for MFA, use the following structure:
25
+ * ```javascript
26
+ * {
27
+ * auth: {
28
+ * mfa: {
29
+ * options: ["SMS", "TOTP"],
30
+ * digits: 6,
31
+ * period: 30,
32
+ * algorithm: "SHA1",
33
+ * sendSMS: (token, mobile) => {
34
+ * // Send the SMS using your preferred SMS provider.
35
+ * console.log(`Sending SMS to ${mobile} with token: ${token}`);
36
+ * }
37
+ * }
38
+ * }
39
+ * }
40
+ * ```
41
+ *
42
+ * ## MFA Methods
43
+ * - **SMS**:
44
+ * - Requires a valid mobile number.
45
+ * - Sends a one-time password (OTP) via SMS for login or verification.
46
+ * - Uses the `sendSMS` callback for sending the OTP.
47
+ *
48
+ * - **TOTP**:
49
+ * - Requires a secret key for setup.
50
+ * - Validates the user's OTP against a time-based one-time password (TOTP) generated using the secret key.
51
+ * - Supports configurable digits, period, and algorithm for TOTP generation.
52
+ * - Generates two single-use recovery codes during enrollment. Each recovery code can be used once
53
+ * in place of a TOTP token and is consumed after use.
54
+ *
55
+ * ## MFA Payload
56
+ * The adapter requires the following `authData` fields:
57
+ * - **For SMS-based MFA**:
58
+ * - `mobile`: The user's mobile number (required for setup).
59
+ * - `token`: The OTP provided by the user for login or verification.
60
+ * - **For TOTP-based MFA**:
61
+ * - `secret`: The TOTP secret key for the user (required for setup).
62
+ * - `token`: The OTP provided by the user for login or verification.
63
+ *
64
+ * ## Example Payloads
65
+ * ### SMS Setup Payload
66
+ * ```json
67
+ * {
68
+ * "mobile": "+1234567890"
69
+ * }
70
+ * ```
71
+ *
72
+ * ### TOTP Setup Payload
73
+ * ```json
74
+ * {
75
+ * "secret": "BASE32ENCODEDSECRET",
76
+ * "token": "123456"
77
+ * }
78
+ * ```
79
+ *
80
+ * ### Login Payload
81
+ * ```json
82
+ * {
83
+ * "token": "123456"
84
+ * }
85
+ * ```
86
+ *
87
+ * @see {@link https://en.wikipedia.org/wiki/Time-based_One-Time_Password_algorithm Time-based One-Time Password Algorithm (TOTP)}
88
+ * @see {@link https://tools.ietf.org/html/rfc6238 RFC 6238: TOTP: Time-Based One-Time Password Algorithm}
89
+ */
90
+
91
+ class MFAAdapter extends _AuthAdapter.default {
92
+ validateOptions(opts) {
93
+ const validOptions = opts.options;
94
+ if (!Array.isArray(validOptions)) {
95
+ throw 'mfa.options must be an array';
96
+ }
97
+ this.sms = validOptions.includes('SMS');
98
+ this.totp = validOptions.includes('TOTP');
99
+ if (!this.sms && !this.totp) {
100
+ throw 'mfa.options must include SMS or TOTP';
101
+ }
102
+ const digits = opts.digits || 6;
103
+ const period = opts.period || 30;
104
+ if (typeof digits !== 'number') {
105
+ throw 'mfa.digits must be a number';
106
+ }
107
+ if (typeof period !== 'number') {
108
+ throw 'mfa.period must be a number';
109
+ }
110
+ if (digits < 4 || digits > 10) {
111
+ throw 'mfa.digits must be between 4 and 10';
112
+ }
113
+ if (period < 10) {
114
+ throw 'mfa.period must be greater than 10';
115
+ }
116
+ const sendSMS = opts.sendSMS;
117
+ if (this.sms && typeof sendSMS !== 'function') {
118
+ throw 'mfa.sendSMS callback must be defined when using SMS OTPs';
119
+ }
120
+ this.smsCallback = sendSMS;
121
+ this.digits = digits;
122
+ this.period = period;
123
+ this.algorithm = opts.algorithm || 'SHA1';
124
+ }
125
+ validateSetUp(mfaData) {
126
+ if (mfaData.mobile && this.sms) {
127
+ return this.setupMobileOTP(mfaData.mobile);
128
+ }
129
+ if (this.totp) {
130
+ return this.setupTOTP(mfaData);
131
+ }
132
+ throw 'Invalid MFA data';
133
+ }
134
+ async validateLogin(loginData, _, req) {
135
+ const saveResponse = {
136
+ doNotSave: true
137
+ };
138
+ const token = loginData.token;
139
+ const auth = req.original.get('authData') || {};
140
+ const {
141
+ secret,
142
+ recovery,
143
+ mobile,
144
+ token: saved,
145
+ expiry
146
+ } = auth.mfa || {};
147
+ if (this.sms && mobile) {
148
+ if (token === 'request') {
149
+ const {
150
+ token: sendToken,
151
+ expiry
152
+ } = await this.sendSMS(mobile);
153
+ auth.mfa.token = sendToken;
154
+ auth.mfa.expiry = expiry;
155
+ req.object.set('authData', auth);
156
+ await req.object.save(null, {
157
+ useMasterKey: true
158
+ });
159
+ throw 'Please enter the token';
160
+ }
161
+ if (!saved || token !== saved) {
162
+ throw 'Invalid MFA token 1';
163
+ }
164
+ if (new Date() > expiry) {
165
+ throw 'Invalid MFA token 2';
166
+ }
167
+ delete auth.mfa.token;
168
+ delete auth.mfa.expiry;
169
+ return {
170
+ save: auth.mfa
171
+ };
172
+ }
173
+ if (this.totp) {
174
+ if (typeof token !== 'string') {
175
+ throw 'Invalid MFA token';
176
+ }
177
+ if (!secret) {
178
+ return saveResponse;
179
+ }
180
+ const recoveryIndex = recovery?.indexOf(token) ?? -1;
181
+ if (recoveryIndex >= 0) {
182
+ const updatedRecovery = [...recovery];
183
+ updatedRecovery.splice(recoveryIndex, 1);
184
+ return {
185
+ save: {
186
+ ...auth.mfa,
187
+ recovery: updatedRecovery
188
+ }
189
+ };
190
+ }
191
+ const totp = new _otpauth.TOTP({
192
+ algorithm: this.algorithm,
193
+ digits: this.digits,
194
+ period: this.period,
195
+ secret: _otpauth.Secret.fromBase32(secret)
196
+ });
197
+ const valid = totp.validate({
198
+ token
199
+ });
200
+ if (valid === null) {
201
+ throw 'Invalid MFA token';
202
+ }
203
+ }
204
+ return saveResponse;
205
+ }
206
+ async validateUpdate(authData, _, req) {
207
+ if (req.master) {
208
+ return;
209
+ }
210
+ if (authData.mobile && this.sms) {
211
+ if (!authData.token) {
212
+ throw 'MFA is already set up on this account';
213
+ }
214
+ return this.confirmSMSOTP(authData, req.original.get('authData')?.mfa || {});
215
+ }
216
+ if (this.totp) {
217
+ await this.validateLogin({
218
+ token: authData.old
219
+ }, null, req);
220
+ return this.validateSetUp(authData);
221
+ }
222
+ throw 'Invalid MFA data';
223
+ }
224
+ afterFind(authData, options, req) {
225
+ if (req.master) {
226
+ return;
227
+ }
228
+ if (this.totp && authData.secret) {
229
+ return {
230
+ status: 'enabled'
231
+ };
232
+ }
233
+ if (this.sms && authData.mobile) {
234
+ return {
235
+ status: 'enabled'
236
+ };
237
+ }
238
+ return {
239
+ status: 'disabled'
240
+ };
241
+ }
242
+ policy(req, auth) {
243
+ if (this.sms && auth?.pending && Object.keys(auth).length === 1) {
244
+ return 'default';
245
+ }
246
+ return 'additional';
247
+ }
248
+ async setupMobileOTP(mobile) {
249
+ const {
250
+ token,
251
+ expiry
252
+ } = await this.sendSMS(mobile);
253
+ return {
254
+ save: {
255
+ pending: {
256
+ [mobile]: {
257
+ token,
258
+ expiry
259
+ }
260
+ }
261
+ }
262
+ };
263
+ }
264
+ async sendSMS(mobile) {
265
+ if (!/^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]*$/g.test(mobile)) {
266
+ throw 'Invalid mobile number.';
267
+ }
268
+ let token = '';
269
+ while (token.length < this.digits) {
270
+ token += (0, _cryptoUtils.randomString)(10).replace(/\D/g, '');
271
+ }
272
+ token = token.substring(0, this.digits);
273
+ await Promise.resolve(this.smsCallback(token, mobile));
274
+ const expiry = new Date(new Date().getTime() + this.period * 1000);
275
+ return {
276
+ token,
277
+ expiry
278
+ };
279
+ }
280
+ async confirmSMSOTP(inputData, authData) {
281
+ const {
282
+ mobile,
283
+ token
284
+ } = inputData;
285
+ if (!authData.pending?.[mobile]) {
286
+ throw 'This number is not pending';
287
+ }
288
+ const pendingData = authData.pending[mobile];
289
+ if (token !== pendingData.token) {
290
+ throw 'Invalid MFA token';
291
+ }
292
+ if (new Date() > pendingData.expiry) {
293
+ throw 'Invalid MFA token';
294
+ }
295
+ delete authData.pending[mobile];
296
+ authData.mobile = mobile;
297
+ return {
298
+ save: authData
299
+ };
300
+ }
301
+ setupTOTP(mfaData) {
302
+ const {
303
+ secret,
304
+ token
305
+ } = mfaData;
306
+ if (!secret || !token || secret.length < 20) {
307
+ throw 'Invalid MFA data';
308
+ }
309
+ const totp = new _otpauth.TOTP({
310
+ algorithm: this.algorithm,
311
+ digits: this.digits,
312
+ period: this.period,
313
+ secret: _otpauth.Secret.fromBase32(secret)
314
+ });
315
+ const valid = totp.validate({
316
+ token
317
+ });
318
+ if (valid === null) {
319
+ throw 'Invalid MFA token';
320
+ }
321
+ const recovery = [(0, _cryptoUtils.randomString)(30), (0, _cryptoUtils.randomString)(30)];
322
+ return {
323
+ response: {
324
+ recovery: recovery.join(', ')
325
+ },
326
+ save: {
327
+ secret,
328
+ recovery
329
+ }
330
+ };
331
+ }
332
+ }
333
+ var _default = exports.default = new MFAAdapter();
334
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfb3RwYXV0aCIsInJlcXVpcmUiLCJfY3J5cHRvVXRpbHMiLCJfQXV0aEFkYXB0ZXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiTUZBQWRhcHRlciIsIkF1dGhBZGFwdGVyIiwidmFsaWRhdGVPcHRpb25zIiwib3B0cyIsInZhbGlkT3B0aW9ucyIsIm9wdGlvbnMiLCJBcnJheSIsImlzQXJyYXkiLCJzbXMiLCJpbmNsdWRlcyIsInRvdHAiLCJkaWdpdHMiLCJwZXJpb2QiLCJzZW5kU01TIiwic21zQ2FsbGJhY2siLCJhbGdvcml0aG0iLCJ2YWxpZGF0ZVNldFVwIiwibWZhRGF0YSIsIm1vYmlsZSIsInNldHVwTW9iaWxlT1RQIiwic2V0dXBUT1RQIiwidmFsaWRhdGVMb2dpbiIsImxvZ2luRGF0YSIsIl8iLCJyZXEiLCJzYXZlUmVzcG9uc2UiLCJkb05vdFNhdmUiLCJ0b2tlbiIsImF1dGgiLCJvcmlnaW5hbCIsImdldCIsInNlY3JldCIsInJlY292ZXJ5Iiwic2F2ZWQiLCJleHBpcnkiLCJtZmEiLCJzZW5kVG9rZW4iLCJvYmplY3QiLCJzZXQiLCJzYXZlIiwidXNlTWFzdGVyS2V5IiwiRGF0ZSIsInJlY292ZXJ5SW5kZXgiLCJpbmRleE9mIiwidXBkYXRlZFJlY292ZXJ5Iiwic3BsaWNlIiwiVE9UUCIsIlNlY3JldCIsImZyb21CYXNlMzIiLCJ2YWxpZCIsInZhbGlkYXRlIiwidmFsaWRhdGVVcGRhdGUiLCJhdXRoRGF0YSIsIm1hc3RlciIsImNvbmZpcm1TTVNPVFAiLCJvbGQiLCJhZnRlckZpbmQiLCJzdGF0dXMiLCJwb2xpY3kiLCJwZW5kaW5nIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsInRlc3QiLCJyYW5kb21TdHJpbmciLCJyZXBsYWNlIiwic3Vic3RyaW5nIiwiUHJvbWlzZSIsInJlc29sdmUiLCJnZXRUaW1lIiwiaW5wdXREYXRhIiwicGVuZGluZ0RhdGEiLCJyZXNwb25zZSIsImpvaW4iLCJfZGVmYXVsdCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvQWRhcHRlcnMvQXV0aC9tZmEuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJzZSBTZXJ2ZXIgYXV0aGVudGljYXRpb24gYWRhcHRlciBmb3IgTXVsdGktRmFjdG9yIEF1dGhlbnRpY2F0aW9uIChNRkEpLlxuICpcbiAqIEBjbGFzcyBNRkFBZGFwdGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBhZGFwdGVyIG9wdGlvbnMuXG4gKiBAcGFyYW0ge0FycmF5PFN0cmluZz59IG9wdGlvbnMub3B0aW9ucyAtIFN1cHBvcnRlZCBNRkEgbWV0aG9kcy4gTXVzdCBpbmNsdWRlIGBcIlNNU1wiYCBvciBgXCJUT1RQXCJgLlxuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLmRpZ2l0cz02XSAtIFRoZSBudW1iZXIgb2YgZGlnaXRzIGZvciB0aGUgb25lLXRpbWUgcGFzc3dvcmQgKE9UUCkuIE11c3QgYmUgYmV0d2VlbiA0IGFuZCAxMC5cbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5wZXJpb2Q9MzBdIC0gVGhlIHZhbGlkaXR5IHBlcmlvZCBvZiB0aGUgT1RQIGluIHNlY29uZHMuIE11c3QgYmUgZ3JlYXRlciB0aGFuIDEwLlxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFsZ29yaXRobT1cIlNIQTFcIl0gLSBUaGUgYWxnb3JpdGhtIHVzZWQgZm9yIFRPVFAgZ2VuZXJhdGlvbi4gRGVmYXVsdHMgdG8gYFwiU0hBMVwiYC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLnNlbmRTTVNdIC0gQSBjYWxsYmFjayBmdW5jdGlvbiBmb3Igc2VuZGluZyBTTVMgT1RQcy4gUmVxdWlyZWQgaWYgYFwiU01TXCJgIGlzIGluY2x1ZGVkIGluIGBvcHRpb25zYC5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBNRkEsIHVzZSB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHtcbiAqICAgYXV0aDoge1xuICogICAgIG1mYToge1xuICogICAgICAgb3B0aW9uczogW1wiU01TXCIsIFwiVE9UUFwiXSxcbiAqICAgICAgIGRpZ2l0czogNixcbiAqICAgICAgIHBlcmlvZDogMzAsXG4gKiAgICAgICBhbGdvcml0aG06IFwiU0hBMVwiLFxuICogICAgICAgc2VuZFNNUzogKHRva2VuLCBtb2JpbGUpID0+IHtcbiAqICAgICAgICAgLy8gU2VuZCB0aGUgU01TIHVzaW5nIHlvdXIgcHJlZmVycmVkIFNNUyBwcm92aWRlci5cbiAqICAgICAgICAgY29uc29sZS5sb2coYFNlbmRpbmcgU01TIHRvICR7bW9iaWxlfSB3aXRoIHRva2VuOiAke3Rva2VufWApO1xuICogICAgICAgfVxuICogICAgIH1cbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogIyMgTUZBIE1ldGhvZHNcbiAqIC0gKipTTVMqKjpcbiAqICAgLSBSZXF1aXJlcyBhIHZhbGlkIG1vYmlsZSBudW1iZXIuXG4gKiAgIC0gU2VuZHMgYSBvbmUtdGltZSBwYXNzd29yZCAoT1RQKSB2aWEgU01TIGZvciBsb2dpbiBvciB2ZXJpZmljYXRpb24uXG4gKiAgIC0gVXNlcyB0aGUgYHNlbmRTTVNgIGNhbGxiYWNrIGZvciBzZW5kaW5nIHRoZSBPVFAuXG4gKlxuICogLSAqKlRPVFAqKjpcbiAqICAgLSBSZXF1aXJlcyBhIHNlY3JldCBrZXkgZm9yIHNldHVwLlxuICogICAtIFZhbGlkYXRlcyB0aGUgdXNlcidzIE9UUCBhZ2FpbnN0IGEgdGltZS1iYXNlZCBvbmUtdGltZSBwYXNzd29yZCAoVE9UUCkgZ2VuZXJhdGVkIHVzaW5nIHRoZSBzZWNyZXQga2V5LlxuICogICAtIFN1cHBvcnRzIGNvbmZpZ3VyYWJsZSBkaWdpdHMsIHBlcmlvZCwgYW5kIGFsZ29yaXRobSBmb3IgVE9UUCBnZW5lcmF0aW9uLlxuICogICAtIEdlbmVyYXRlcyB0d28gc2luZ2xlLXVzZSByZWNvdmVyeSBjb2RlcyBkdXJpbmcgZW5yb2xsbWVudC4gRWFjaCByZWNvdmVyeSBjb2RlIGNhbiBiZSB1c2VkIG9uY2VcbiAqICAgICBpbiBwbGFjZSBvZiBhIFRPVFAgdG9rZW4gYW5kIGlzIGNvbnN1bWVkIGFmdGVyIHVzZS5cbiAqXG4gKiAjIyBNRkEgUGF5bG9hZFxuICogVGhlIGFkYXB0ZXIgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBgYXV0aERhdGFgIGZpZWxkczpcbiAqIC0gKipGb3IgU01TLWJhc2VkIE1GQSoqOlxuICogICAtIGBtb2JpbGVgOiBUaGUgdXNlcidzIG1vYmlsZSBudW1iZXIgKHJlcXVpcmVkIGZvciBzZXR1cCkuXG4gKiAgIC0gYHRva2VuYDogVGhlIE9UUCBwcm92aWRlZCBieSB0aGUgdXNlciBmb3IgbG9naW4gb3IgdmVyaWZpY2F0aW9uLlxuICogLSAqKkZvciBUT1RQLWJhc2VkIE1GQSoqOlxuICogICAtIGBzZWNyZXRgOiBUaGUgVE9UUCBzZWNyZXQga2V5IGZvciB0aGUgdXNlciAocmVxdWlyZWQgZm9yIHNldHVwKS5cbiAqICAgLSBgdG9rZW5gOiBUaGUgT1RQIHByb3ZpZGVkIGJ5IHRoZSB1c2VyIGZvciBsb2dpbiBvciB2ZXJpZmljYXRpb24uXG4gKlxuICogIyMgRXhhbXBsZSBQYXlsb2Fkc1xuICogIyMjIFNNUyBTZXR1cCBQYXlsb2FkXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwibW9iaWxlXCI6IFwiKzEyMzQ1Njc4OTBcIlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIFRPVFAgU2V0dXAgUGF5bG9hZFxuICogYGBganNvblxuICoge1xuICogICBcInNlY3JldFwiOiBcIkJBU0UzMkVOQ09ERURTRUNSRVRcIixcbiAqICAgXCJ0b2tlblwiOiBcIjEyMzQ1NlwiXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMgTG9naW4gUGF5bG9hZFxuICogYGBganNvblxuICoge1xuICogICBcInRva2VuXCI6IFwiMTIzNDU2XCJcbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1RpbWUtYmFzZWRfT25lLVRpbWVfUGFzc3dvcmRfYWxnb3JpdGhtIFRpbWUtYmFzZWQgT25lLVRpbWUgUGFzc3dvcmQgQWxnb3JpdGhtIChUT1RQKX1cbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2MjM4IFJGQyA2MjM4OiBUT1RQOiBUaW1lLUJhc2VkIE9uZS1UaW1lIFBhc3N3b3JkIEFsZ29yaXRobX1cbiAqL1xuXG5pbXBvcnQgeyBUT1RQLCBTZWNyZXQgfSBmcm9tICdvdHBhdXRoJztcbmltcG9ydCB7IHJhbmRvbVN0cmluZyB9IGZyb20gJy4uLy4uL2NyeXB0b1V0aWxzJztcbmltcG9ydCBBdXRoQWRhcHRlciBmcm9tICcuL0F1dGhBZGFwdGVyJztcbmNsYXNzIE1GQUFkYXB0ZXIgZXh0ZW5kcyBBdXRoQWRhcHRlciB7XG4gIHZhbGlkYXRlT3B0aW9ucyhvcHRzKSB7XG4gICAgY29uc3QgdmFsaWRPcHRpb25zID0gb3B0cy5vcHRpb25zO1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWxpZE9wdGlvbnMpKSB7XG4gICAgICB0aHJvdyAnbWZhLm9wdGlvbnMgbXVzdCBiZSBhbiBhcnJheSc7XG4gICAgfVxuICAgIHRoaXMuc21zID0gdmFsaWRPcHRpb25zLmluY2x1ZGVzKCdTTVMnKTtcbiAgICB0aGlzLnRvdHAgPSB2YWxpZE9wdGlvbnMuaW5jbHVkZXMoJ1RPVFAnKTtcbiAgICBpZiAoIXRoaXMuc21zICYmICF0aGlzLnRvdHApIHtcbiAgICAgIHRocm93ICdtZmEub3B0aW9ucyBtdXN0IGluY2x1ZGUgU01TIG9yIFRPVFAnO1xuICAgIH1cbiAgICBjb25zdCBkaWdpdHMgPSBvcHRzLmRpZ2l0cyB8fCA2O1xuICAgIGNvbnN0IHBlcmlvZCA9IG9wdHMucGVyaW9kIHx8IDMwO1xuICAgIGlmICh0eXBlb2YgZGlnaXRzICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgJ21mYS5kaWdpdHMgbXVzdCBiZSBhIG51bWJlcic7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGVyaW9kICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgJ21mYS5wZXJpb2QgbXVzdCBiZSBhIG51bWJlcic7XG4gICAgfVxuICAgIGlmIChkaWdpdHMgPCA0IHx8IGRpZ2l0cyA+IDEwKSB7XG4gICAgICB0aHJvdyAnbWZhLmRpZ2l0cyBtdXN0IGJlIGJldHdlZW4gNCBhbmQgMTAnO1xuICAgIH1cbiAgICBpZiAocGVyaW9kIDwgMTApIHtcbiAgICAgIHRocm93ICdtZmEucGVyaW9kIG11c3QgYmUgZ3JlYXRlciB0aGFuIDEwJztcbiAgICB9XG4gICAgY29uc3Qgc2VuZFNNUyA9IG9wdHMuc2VuZFNNUztcbiAgICBpZiAodGhpcy5zbXMgJiYgdHlwZW9mIHNlbmRTTVMgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93ICdtZmEuc2VuZFNNUyBjYWxsYmFjayBtdXN0IGJlIGRlZmluZWQgd2hlbiB1c2luZyBTTVMgT1RQcyc7XG4gICAgfVxuICAgIHRoaXMuc21zQ2FsbGJhY2sgPSBzZW5kU01TO1xuICAgIHRoaXMuZGlnaXRzID0gZGlnaXRzO1xuICAgIHRoaXMucGVyaW9kID0gcGVyaW9kO1xuICAgIHRoaXMuYWxnb3JpdGhtID0gb3B0cy5hbGdvcml0aG0gfHwgJ1NIQTEnO1xuICB9XG4gIHZhbGlkYXRlU2V0VXAobWZhRGF0YSkge1xuICAgIGlmIChtZmFEYXRhLm1vYmlsZSAmJiB0aGlzLnNtcykge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBNb2JpbGVPVFAobWZhRGF0YS5tb2JpbGUpO1xuICAgIH1cbiAgICBpZiAodGhpcy50b3RwKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXR1cFRPVFAobWZhRGF0YSk7XG4gICAgfVxuICAgIHRocm93ICdJbnZhbGlkIE1GQSBkYXRhJztcbiAgfVxuICBhc3luYyB2YWxpZGF0ZUxvZ2luKGxvZ2luRGF0YSwgXywgcmVxKSB7XG4gICAgY29uc3Qgc2F2ZVJlc3BvbnNlID0ge1xuICAgICAgZG9Ob3RTYXZlOiB0cnVlLFxuICAgIH07XG4gICAgY29uc3QgdG9rZW4gPSBsb2dpbkRhdGEudG9rZW47XG4gICAgY29uc3QgYXV0aCA9IHJlcS5vcmlnaW5hbC5nZXQoJ2F1dGhEYXRhJykgfHwge307XG4gICAgY29uc3QgeyBzZWNyZXQsIHJlY292ZXJ5LCBtb2JpbGUsIHRva2VuOiBzYXZlZCwgZXhwaXJ5IH0gPSBhdXRoLm1mYSB8fCB7fTtcbiAgICBpZiAodGhpcy5zbXMgJiYgbW9iaWxlKSB7XG4gICAgICBpZiAodG9rZW4gPT09ICdyZXF1ZXN0Jykge1xuICAgICAgICBjb25zdCB7IHRva2VuOiBzZW5kVG9rZW4sIGV4cGlyeSB9ID0gYXdhaXQgdGhpcy5zZW5kU01TKG1vYmlsZSk7XG4gICAgICAgIGF1dGgubWZhLnRva2VuID0gc2VuZFRva2VuO1xuICAgICAgICBhdXRoLm1mYS5leHBpcnkgPSBleHBpcnk7XG4gICAgICAgIHJlcS5vYmplY3Quc2V0KCdhdXRoRGF0YScsIGF1dGgpO1xuICAgICAgICBhd2FpdCByZXEub2JqZWN0LnNhdmUobnVsbCwgeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gICAgICAgIHRocm93ICdQbGVhc2UgZW50ZXIgdGhlIHRva2VuJztcbiAgICAgIH1cbiAgICAgIGlmICghc2F2ZWQgfHwgdG9rZW4gIT09IHNhdmVkKSB7XG4gICAgICAgIHRocm93ICdJbnZhbGlkIE1GQSB0b2tlbiAxJztcbiAgICAgIH1cbiAgICAgIGlmIChuZXcgRGF0ZSgpID4gZXhwaXJ5KSB7XG4gICAgICAgIHRocm93ICdJbnZhbGlkIE1GQSB0b2tlbiAyJztcbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBhdXRoLm1mYS50b2tlbjtcbiAgICAgIGRlbGV0ZSBhdXRoLm1mYS5leHBpcnk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzYXZlOiBhdXRoLm1mYSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh0aGlzLnRvdHApIHtcbiAgICAgIGlmICh0eXBlb2YgdG9rZW4gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93ICdJbnZhbGlkIE1GQSB0b2tlbic7XG4gICAgICB9XG4gICAgICBpZiAoIXNlY3JldCkge1xuICAgICAgICByZXR1cm4gc2F2ZVJlc3BvbnNlO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVjb3ZlcnlJbmRleCA9IHJlY292ZXJ5Py5pbmRleE9mKHRva2VuKSA/PyAtMTtcbiAgICAgIGlmIChyZWNvdmVyeUluZGV4ID49IDApIHtcbiAgICAgICAgY29uc3QgdXBkYXRlZFJlY292ZXJ5ID0gWy4uLnJlY292ZXJ5XTtcbiAgICAgICAgdXBkYXRlZFJlY292ZXJ5LnNwbGljZShyZWNvdmVyeUluZGV4LCAxKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzYXZlOiB7IC4uLmF1dGgubWZhLCByZWNvdmVyeTogdXBkYXRlZFJlY292ZXJ5IH0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBjb25zdCB0b3RwID0gbmV3IFRPVFAoe1xuICAgICAgICBhbGdvcml0aG06IHRoaXMuYWxnb3JpdGhtLFxuICAgICAgICBkaWdpdHM6IHRoaXMuZGlnaXRzLFxuICAgICAgICBwZXJpb2Q6IHRoaXMucGVyaW9kLFxuICAgICAgICBzZWNyZXQ6IFNlY3JldC5mcm9tQmFzZTMyKHNlY3JldCksXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHZhbGlkID0gdG90cC52YWxpZGF0ZSh7XG4gICAgICAgIHRva2VuLFxuICAgICAgfSk7XG4gICAgICBpZiAodmFsaWQgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgJ0ludmFsaWQgTUZBIHRva2VuJztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNhdmVSZXNwb25zZTtcbiAgfVxuICBhc3luYyB2YWxpZGF0ZVVwZGF0ZShhdXRoRGF0YSwgXywgcmVxKSB7XG4gICAgaWYgKHJlcS5tYXN0ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGF1dGhEYXRhLm1vYmlsZSAmJiB0aGlzLnNtcykge1xuICAgICAgaWYgKCFhdXRoRGF0YS50b2tlbikge1xuICAgICAgICB0aHJvdyAnTUZBIGlzIGFscmVhZHkgc2V0IHVwIG9uIHRoaXMgYWNjb3VudCc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5jb25maXJtU01TT1RQKGF1dGhEYXRhLCByZXEub3JpZ2luYWwuZ2V0KCdhdXRoRGF0YScpPy5tZmEgfHwge30pO1xuICAgIH1cbiAgICBpZiAodGhpcy50b3RwKSB7XG4gICAgICBhd2FpdCB0aGlzLnZhbGlkYXRlTG9naW4oeyB0b2tlbjogYXV0aERhdGEub2xkIH0sIG51bGwsIHJlcSk7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVNldFVwKGF1dGhEYXRhKTtcbiAgICB9XG4gICAgdGhyb3cgJ0ludmFsaWQgTUZBIGRhdGEnO1xuICB9XG4gIGFmdGVyRmluZChhdXRoRGF0YSwgb3B0aW9ucywgcmVxKSB7XG4gICAgaWYgKHJlcS5tYXN0ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMudG90cCAmJiBhdXRoRGF0YS5zZWNyZXQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN0YXR1czogJ2VuYWJsZWQnLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc21zICYmIGF1dGhEYXRhLm1vYmlsZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhdHVzOiAnZW5hYmxlZCcsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnZGlzYWJsZWQnLFxuICAgIH07XG4gIH1cblxuICBwb2xpY3kocmVxLCBhdXRoKSB7XG4gICAgaWYgKHRoaXMuc21zICYmIGF1dGg/LnBlbmRpbmcgJiYgT2JqZWN0LmtleXMoYXV0aCkubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gJ2RlZmF1bHQnO1xuICAgIH1cbiAgICByZXR1cm4gJ2FkZGl0aW9uYWwnO1xuICB9XG5cbiAgYXN5bmMgc2V0dXBNb2JpbGVPVFAobW9iaWxlKSB7XG4gICAgY29uc3QgeyB0b2tlbiwgZXhwaXJ5IH0gPSBhd2FpdCB0aGlzLnNlbmRTTVMobW9iaWxlKTtcbiAgICByZXR1cm4ge1xuICAgICAgc2F2ZToge1xuICAgICAgICBwZW5kaW5nOiB7XG4gICAgICAgICAgW21vYmlsZV06IHtcbiAgICAgICAgICAgIHRva2VuLFxuICAgICAgICAgICAgZXhwaXJ5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBhc3luYyBzZW5kU01TKG1vYmlsZSkge1xuICAgIGlmICghL15bK10qWyhdezAsMX1bMC05XXsxLDN9WyldezAsMX1bLVxcc1xcLi8wLTldKiQvZy50ZXN0KG1vYmlsZSkpIHtcbiAgICAgIHRocm93ICdJbnZhbGlkIG1vYmlsZSBudW1iZXIuJztcbiAgICB9XG4gICAgbGV0IHRva2VuID0gJyc7XG4gICAgd2hpbGUgKHRva2VuLmxlbmd0aCA8IHRoaXMuZGlnaXRzKSB7XG4gICAgICB0b2tlbiArPSByYW5kb21TdHJpbmcoMTApLnJlcGxhY2UoL1xcRC9nLCAnJyk7XG4gICAgfVxuICAgIHRva2VuID0gdG9rZW4uc3Vic3RyaW5nKDAsIHRoaXMuZGlnaXRzKTtcbiAgICBhd2FpdCBQcm9taXNlLnJlc29sdmUodGhpcy5zbXNDYWxsYmFjayh0b2tlbiwgbW9iaWxlKSk7XG4gICAgY29uc3QgZXhwaXJ5ID0gbmV3IERhdGUobmV3IERhdGUoKS5nZXRUaW1lKCkgKyB0aGlzLnBlcmlvZCAqIDEwMDApO1xuICAgIHJldHVybiB7IHRva2VuLCBleHBpcnkgfTtcbiAgfVxuXG4gIGFzeW5jIGNvbmZpcm1TTVNPVFAoaW5wdXREYXRhLCBhdXRoRGF0YSkge1xuICAgIGNvbnN0IHsgbW9iaWxlLCB0b2tlbiB9ID0gaW5wdXREYXRhO1xuICAgIGlmICghYXV0aERhdGEucGVuZGluZz8uW21vYmlsZV0pIHtcbiAgICAgIHRocm93ICdUaGlzIG51bWJlciBpcyBub3QgcGVuZGluZyc7XG4gICAgfVxuICAgIGNvbnN0IHBlbmRpbmdEYXRhID0gYXV0aERhdGEucGVuZGluZ1ttb2JpbGVdO1xuICAgIGlmICh0b2tlbiAhPT0gcGVuZGluZ0RhdGEudG9rZW4pIHtcbiAgICAgIHRocm93ICdJbnZhbGlkIE1GQSB0b2tlbic7XG4gICAgfVxuICAgIGlmIChuZXcgRGF0ZSgpID4gcGVuZGluZ0RhdGEuZXhwaXJ5KSB7XG4gICAgICB0aHJvdyAnSW52YWxpZCBNRkEgdG9rZW4nO1xuICAgIH1cbiAgICBkZWxldGUgYXV0aERhdGEucGVuZGluZ1ttb2JpbGVdO1xuICAgIGF1dGhEYXRhLm1vYmlsZSA9IG1vYmlsZTtcbiAgICByZXR1cm4ge1xuICAgICAgc2F2ZTogYXV0aERhdGEsXG4gICAgfTtcbiAgfVxuXG4gIHNldHVwVE9UUChtZmFEYXRhKSB7XG4gICAgY29uc3QgeyBzZWNyZXQsIHRva2VuIH0gPSBtZmFEYXRhO1xuICAgIGlmICghc2VjcmV0IHx8ICF0b2tlbiB8fCBzZWNyZXQubGVuZ3RoIDwgMjApIHtcbiAgICAgIHRocm93ICdJbnZhbGlkIE1GQSBkYXRhJztcbiAgICB9XG4gICAgY29uc3QgdG90cCA9IG5ldyBUT1RQKHtcbiAgICAgIGFsZ29yaXRobTogdGhpcy5hbGdvcml0aG0sXG4gICAgICBkaWdpdHM6IHRoaXMuZGlnaXRzLFxuICAgICAgcGVyaW9kOiB0aGlzLnBlcmlvZCxcbiAgICAgIHNlY3JldDogU2VjcmV0LmZyb21CYXNlMzIoc2VjcmV0KSxcbiAgICB9KTtcbiAgICBjb25zdCB2YWxpZCA9IHRvdHAudmFsaWRhdGUoe1xuICAgICAgdG9rZW4sXG4gICAgfSk7XG4gICAgaWYgKHZhbGlkID09PSBudWxsKSB7XG4gICAgICB0aHJvdyAnSW52YWxpZCBNRkEgdG9rZW4nO1xuICAgIH1cbiAgICBjb25zdCByZWNvdmVyeSA9IFtyYW5kb21TdHJpbmcoMzApLCByYW5kb21TdHJpbmcoMzApXTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IHsgcmVjb3Zlcnk6IHJlY292ZXJ5LmpvaW4oJywgJykgfSxcbiAgICAgIHNhdmU6IHsgc2VjcmV0LCByZWNvdmVyeSB9LFxuICAgIH07XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IG5ldyBNRkFBZGFwdGVyKCk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQWdGQSxJQUFBQSxRQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxZQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFBd0MsU0FBQUcsdUJBQUFDLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUFsRnhDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUtBLE1BQU1HLFVBQVUsU0FBU0Msb0JBQVcsQ0FBQztFQUNuQ0MsZUFBZUEsQ0FBQ0MsSUFBSSxFQUFFO0lBQ3BCLE1BQU1DLFlBQVksR0FBR0QsSUFBSSxDQUFDRSxPQUFPO0lBQ2pDLElBQUksQ0FBQ0MsS0FBSyxDQUFDQyxPQUFPLENBQUNILFlB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
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _BaseCodeAuthAdapter = _interopRequireDefault(require("./BaseCodeAuthAdapter"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /**
10
+ * Parse Server authentication adapter for Microsoft.
11
+ *
12
+ * @class MicrosoftAdapter
13
+ * @param {Object} options - The adapter configuration options.
14
+ * @param {string} options.clientId - Your Microsoft App Client ID. Required for secure authentication.
15
+ * @param {string} options.clientSecret - Your Microsoft App Client Secret. Required for secure authentication.
16
+ * @param {boolean} [options.enableInsecureAuth=false] - **[DEPRECATED]** Enable insecure authentication (not recommended).
17
+ *
18
+ * @description
19
+ * ## Parse Server Configuration
20
+ * To configure Parse Server for Microsoft authentication, use the following structure:
21
+ * ### Secure Configuration
22
+ * ```json
23
+ * {
24
+ * "auth": {
25
+ * "microsoft": {
26
+ * "clientId": "your-client-id",
27
+ * "clientSecret": "your-client-secret"
28
+ * }
29
+ * }
30
+ * }
31
+ * ```
32
+ * ### Insecure Configuration (Not Recommended)
33
+ * ```json
34
+ * {
35
+ * "auth": {
36
+ * "microsoft": {
37
+ * "enableInsecureAuth": true
38
+ * }
39
+ * }
40
+ * }
41
+ * ```
42
+ *
43
+ * The adapter requires the following `authData` fields:
44
+ * - **Secure Authentication**: `code`, `redirect_uri`.
45
+ * - **Insecure Authentication (Not Recommended)**: `id`, `access_token`.
46
+ *
47
+ * ## Auth Payloads
48
+ * ### Secure Authentication Payload
49
+ * ```json
50
+ * {
51
+ * "microsoft": {
52
+ * "code": "lmn789opq012rst345uvw",
53
+ * "redirect_uri": "https://your-redirect-uri.com/callback"
54
+ * }
55
+ * }
56
+ * ```
57
+ * ### Insecure Authentication Payload (Not Recommended)
58
+ * ```json
59
+ * {
60
+ * "microsoft": {
61
+ * "id": "7654321",
62
+ * "access_token": "AQXNnd2hIT6z9bHFzZz2Kp1ghiMz_RtyuvwXYZ123abc"
63
+ * }
64
+ * }
65
+ * ```
66
+ *
67
+ * ## Notes
68
+ * - Secure authentication exchanges the `code` and `redirect_uri` provided by the client for an access token using Microsoft's OAuth API.
69
+ * - **Insecure authentication** validates the user ID and access token directly, bypassing OAuth flows (not recommended). This method is deprecated and may be removed in future versions.
70
+ *
71
+ * @see {@link https://docs.microsoft.com/en-us/graph/auth/auth-concepts Microsoft Authentication Documentation}
72
+ */
73
+
74
+ class MicrosoftAdapter extends _BaseCodeAuthAdapter.default {
75
+ constructor() {
76
+ super('Microsoft');
77
+ }
78
+ async getUserFromAccessToken(access_token) {
79
+ const userResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
80
+ headers: {
81
+ Authorization: 'Bearer ' + access_token
82
+ }
83
+ });
84
+ if (!userResponse.ok) {
85
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Microsoft API request failed.');
86
+ }
87
+ return userResponse.json();
88
+ }
89
+ async getAccessTokenFromCode(authData) {
90
+ const response = await fetch('https://login.microsoftonline.com/common/oauth2/v2.0/token', {
91
+ method: 'POST',
92
+ headers: {
93
+ 'Content-Type': 'application/x-www-form-urlencoded'
94
+ },
95
+ body: new URLSearchParams({
96
+ client_id: this.clientId,
97
+ client_secret: this.clientSecret,
98
+ grant_type: 'authorization_code',
99
+ redirect_uri: authData.redirect_uri,
100
+ code: authData.code
101
+ })
102
+ });
103
+ if (!response.ok) {
104
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Microsoft API request failed.');
105
+ }
106
+ const json = await response.json();
107
+ return json.access_token;
108
+ }
109
+ }
110
+ var _default = exports.default = new MicrosoftAdapter();
111
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQmFzZUNvZGVBdXRoQWRhcHRlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiTWljcm9zb2Z0QWRhcHRlciIsIkJhc2VBdXRoQ29kZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsImdldFVzZXJGcm9tQWNjZXNzVG9rZW4iLCJhY2Nlc3NfdG9rZW4iLCJ1c2VyUmVzcG9uc2UiLCJmZXRjaCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwib2siLCJQYXJzZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsImpzb24iLCJnZXRBY2Nlc3NUb2tlbkZyb21Db2RlIiwiYXV0aERhdGEiLCJyZXNwb25zZSIsIm1ldGhvZCIsImJvZHkiLCJVUkxTZWFyY2hQYXJhbXMiLCJjbGllbnRfaWQiLCJjbGllbnRJZCIsImNsaWVudF9zZWNyZXQiLCJjbGllbnRTZWNyZXQiLCJncmFudF90eXBlIiwicmVkaXJlY3RfdXJpIiwiY29kZSIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21pY3Jvc29mdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlIFNlcnZlciBhdXRoZW50aWNhdGlvbiBhZGFwdGVyIGZvciBNaWNyb3NvZnQuXG4gKlxuICogQGNsYXNzIE1pY3Jvc29mdEFkYXB0ZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIGFkYXB0ZXIgY29uZmlndXJhdGlvbiBvcHRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMuY2xpZW50SWQgLSBZb3VyIE1pY3Jvc29mdCBBcHAgQ2xpZW50IElELiBSZXF1aXJlZCBmb3Igc2VjdXJlIGF1dGhlbnRpY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMuY2xpZW50U2VjcmV0IC0gWW91ciBNaWNyb3NvZnQgQXBwIENsaWVudCBTZWNyZXQuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUluc2VjdXJlQXV0aD1mYWxzZV0gLSAqKltERVBSRUNBVEVEXSoqIEVuYWJsZSBpbnNlY3VyZSBhdXRoZW50aWNhdGlvbiAobm90IHJlY29tbWVuZGVkKS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBNaWNyb3NvZnQgYXV0aGVudGljYXRpb24sIHVzZSB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAqICMjIyBTZWN1cmUgQ29uZmlndXJhdGlvblxuICogYGBganNvblxuICoge1xuICogICBcImF1dGhcIjoge1xuICogICAgIFwibWljcm9zb2Z0XCI6IHtcbiAqICAgICAgIFwiY2xpZW50SWRcIjogXCJ5b3VyLWNsaWVudC1pZFwiLFxuICogICAgICAgXCJjbGllbnRTZWNyZXRcIjogXCJ5b3VyLWNsaWVudC1zZWNyZXRcIlxuICogICAgIH1cbiAqICAgfVxuICogfVxuICogYGBgXG4gKiAjIyMgSW5zZWN1cmUgQ29uZmlndXJhdGlvbiAoTm90IFJlY29tbWVuZGVkKVxuICogYGBganNvblxuICoge1xuICogICBcImF1dGhcIjoge1xuICogICAgIFwibWljcm9zb2Z0XCI6IHtcbiAqICAgICAgIFwiZW5hYmxlSW5zZWN1cmVBdXRoXCI6IHRydWVcbiAqICAgICB9XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIFRoZSBhZGFwdGVyIHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgYGF1dGhEYXRhYCBmaWVsZHM6XG4gKiAtICoqU2VjdXJlIEF1dGhlbnRpY2F0aW9uKio6IGBjb2RlYCwgYHJlZGlyZWN0X3VyaWAuXG4gKiAtICoqSW5zZWN1cmUgQXV0aGVudGljYXRpb24gKE5vdCBSZWNvbW1lbmRlZCkqKjogYGlkYCwgYGFjY2Vzc190b2tlbmAuXG4gKlxuICogIyMgQXV0aCBQYXlsb2Fkc1xuICogIyMjIFNlY3VyZSBBdXRoZW50aWNhdGlvbiBQYXlsb2FkXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwibWljcm9zb2Z0XCI6IHtcbiAqICAgICBcImNvZGVcIjogXCJsbW43ODlvcHEwMTJyc3QzNDV1dndcIixcbiAqICAgICBcInJlZGlyZWN0X3VyaVwiOiBcImh0dHBzOi8veW91ci1yZWRpcmVjdC11cmkuY29tL2NhbGxiYWNrXCJcbiAqICAgfVxuICogfVxuICogYGBgXG4gKiAjIyMgSW5zZWN1cmUgQXV0aGVudGljYXRpb24gUGF5bG9hZCAoTm90IFJlY29tbWVuZGVkKVxuICogYGBganNvblxuICoge1xuICogICBcIm1pY3Jvc29mdFwiOiB7XG4gKiAgICAgXCJpZFwiOiBcIjc2NTQzMjFcIixcbiAqICAgICBcImFjY2Vzc190b2tlblwiOiBcIkFRWE5uZDJoSVQ2ejliSEZ6WnoyS3AxZ2hpTXpfUnR5dXZ3WFlaMTIzYWJjXCJcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogIyMgTm90ZXNcbiAqIC0gU2VjdXJlIGF1dGhlbnRpY2F0aW9uIGV4Y2hhbmdlcyB0aGUgYGNvZGVgIGFuZCBgcmVkaXJlY3RfdXJpYCBwcm92aWRlZCBieSB0aGUgY2xpZW50IGZvciBhbiBhY2Nlc3MgdG9rZW4gdXNpbmcgTWljcm9zb2Z0J3MgT0F1dGggQVBJLlxuICogLSAqKkluc2VjdXJlIGF1dGhlbnRpY2F0aW9uKiogdmFsaWRhdGVzIHRoZSB1c2VyIElEIGFuZCBhY2Nlc3MgdG9rZW4gZGlyZWN0bHksIGJ5cGFzc2luZyBPQXV0aCBmbG93cyAobm90IHJlY29tbWVuZGVkKS4gVGhpcyBtZXRob2QgaXMgZGVwcmVjYXRlZCBhbmQgbWF5IGJlIHJlbW92ZWQgaW4gZnV0dXJlIHZlcnNpb25zLlxuICpcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL2dyYXBoL2F1dGgvYXV0aC1jb25jZXB0cyBNaWNyb3NvZnQgQXV0aGVudGljYXRpb24gRG9jdW1lbnRhdGlvbn1cbiAqL1xuXG5pbXBvcnQgQmFzZUF1dGhDb2RlQWRhcHRlciBmcm9tICcuL0Jhc2VDb2RlQXV0aEFkYXB0ZXInO1xuY2xhc3MgTWljcm9zb2Z0QWRhcHRlciBleHRlbmRzIEJhc2VBdXRoQ29kZUFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignTWljcm9zb2Z0Jyk7XG4gIH1cbiAgYXN5bmMgZ2V0VXNlckZyb21BY2Nlc3NUb2tlbihhY2Nlc3NfdG9rZW4pIHtcbiAgICBjb25zdCB1c2VyUmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnaHR0cHM6Ly9ncmFwaC5taWNyb3NvZnQuY29tL3YxLjAvbWUnLCB7XG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoIXVzZXJSZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdNaWNyb3NvZnQgQVBJIHJlcXVlc3QgZmFpbGVkLicpO1xuICAgIH1cblxuICAgIHJldHVybiB1c2VyUmVzcG9uc2UuanNvbigpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QWNjZXNzVG9rZW5Gcm9tQ29kZShhdXRoRGF0YSkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vbG9naW4ubWljcm9zb2Z0b25saW5lLmNvbS9jb21tb24vb2F1dGgyL3YyLjAvdG9rZW4nLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY2xpZW50SWQsXG4gICAgICAgIGNsaWVudF9zZWNyZXQ6IHRoaXMuY2xpZW50U2VjcmV0LFxuICAgICAgICBncmFudF90eXBlOiAnYXV0aG9yaXphdGlvbl9jb2RlJyxcbiAgICAgICAgcmVkaXJlY3RfdXJpOiBhdXRoRGF0YS5yZWRpcmVjdF91cmksXG4gICAgICAgIGNvZGU6IGF1dGhEYXRhLmNvZGUsXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWljcm9zb2Z0IEFQSSByZXF1ZXN0IGZhaWxlZC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBqc29uID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgIHJldHVybiBqc29uLmFjY2Vzc190b2tlbjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgTWljcm9zb2Z0QWRhcHRlcigpO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFpRUEsSUFBQUEsb0JBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUF3RCxTQUFBRCx1QkFBQUUsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQWpFeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBR0EsTUFBTUcsZ0JBQWdCLFNBQVNDLDRCQUFtQixDQUFDO0VBQ2pEQyxXQUFXQSxDQUFBLEVBQUc7SUFDWixLQUFLLENBQUMsV0FBVyxDQUFDO0VBQ3BCO0VBQ0EsTUFBTUMsc0JBQXNCQSxDQUFDQyxZQUFZLEVBQUU7SUFDekMsTUFBTUMsWUFBWSxHQUFHLE1BQU1DLEtBQUssQ0FBQyxxQ0FBcUMsRUFBRTtNQUN0RUMsT0FBTyxFQUFFO1FBQ1BDLGFBQWEsRUFBRSxTQUFTLEdBQUdKO01BQzdCO0lBQ0YsQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDQyxZQUFZLENBQUNJLEVBQUUsRUFBRTtNQUNwQixNQUFNLElBQUlDLEtBQUssQ0FBQ0MsS0FBSyxDQUFDRCxLQUFLLENBQUNDLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQUUsK0JBQStCLENBQUM7SUFDdEY7SUFFQSxPQUFPUCxZQUFZLENBQUNRLElBQUksQ0FBQyxDQUFDO0VBQzVCO0VBRUEsTUFBTUMsc0JBQXNCQSxDQUFDQyxRQUFRLEVBQUU7SUFDckMsTUFBTUMsUUFBUSxHQUFHLE1BQU1WLEtBQUssQ0FBQyw0REFBNEQsRUFBRTtNQUN6RlcsTUFBTSxFQUFFLE1BQU07TUFDZFYsT0FBTyxFQUFFO1FBQ1AsY0FBYyxFQUFFO01BQ2xCLENBQUM7TUFDRFcsSUFBSSxFQUFFLElBQUlDLGVBQWUsQ0FBQztRQUN4QkMsU0FBUyxFQUFFLElBQUksQ0FBQ0MsUUFBUTtRQUN4QkMsYUFBYSxFQUFFLElBQUksQ0FBQ0MsWUFBWTtRQUNoQ0MsVUFBVSxFQUFFLG9CQUFvQjtRQUNoQ0MsWUFBWSxFQUFFVixRQUFRLENBQUNVLFlBQVk7UUFDbkNDLElBQUksRUFBRVgsUUFBUSxDQUFDVztNQUNqQixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDVixRQUFRLENBQUNQLEVBQUUsRUFBRTtNQUNoQixNQUFNLElBQUlDLEtBQUssQ0FBQ0MsS0FBSyxDQUFDRCxLQUFLLENBQUNDLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQUUsK0JBQStCLENBQUM7SUFDdEY7SUFFQSxNQUFNQyxJQUFJLEdBQUcsTUFBTUcsUUFBUSxDQUFDSCxJQUFJLENBQUMsQ0FBQztJQUNsQyxPQUFPQSxJQUFJLENBQUNULFlBQVk7RUFDMUI7QUFDRjtBQUFDLElBQUF1QixRQUFBLEdBQUFDLE9BQUEsQ0FBQTdCLE9BQUEsR0FFYyxJQUFJQyxnQkFBZ0IsQ0FBQyxDQUFDIiwiaWdub3JlTGlzdCI6W119
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _AuthAdapter = _interopRequireDefault(require("./AuthAdapter"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /**
10
+ * Parse Server authentication adapter for OAuth2 Token Introspection.
11
+ *
12
+ * @class OAuth2Adapter
13
+ * @param {Object} options - The adapter configuration options.
14
+ * @param {string} options.tokenIntrospectionEndpointUrl - The URL of the token introspection endpoint. Required.
15
+ * @param {boolean} options.oauth2 - Indicates that the request should be handled by the OAuth2 adapter. Required.
16
+ * @param {string} [options.useridField='sub'] - The field in the introspection response that contains the user ID. Defaults to `sub` per RFC 7662.
17
+ * @param {string} [options.appidField] - The field in the introspection response that contains the app ID. Optional.
18
+ * @param {string[]} [options.appIds] - List of allowed app IDs. Required if `appidField` is defined.
19
+ * @param {string} [options.authorizationHeader] - The Authorization header value for the introspection request. Optional.
20
+ *
21
+ * @description
22
+ * ## Parse Server Configuration
23
+ * To configure Parse Server for OAuth2 Token Introspection, use the following structure:
24
+ * ```json
25
+ * {
26
+ * "auth": {
27
+ * "oauth2Provider": {
28
+ * "tokenIntrospectionEndpointUrl": "https://provider.com/introspect",
29
+ * "useridField": "sub",
30
+ * "appidField": "aud",
31
+ * "appIds": ["my-app-id"],
32
+ * "authorizationHeader": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
33
+ * "oauth2": true
34
+ * }
35
+ * }
36
+ * }
37
+ * ```
38
+ *
39
+ * The adapter requires the following `authData` fields:
40
+ * - `id`: The user ID provided by the client.
41
+ * - `access_token`: The access token provided by the client.
42
+ *
43
+ * ## Auth Payload
44
+ * ### Example Auth Payload
45
+ * ```json
46
+ * {
47
+ * "oauth2": {
48
+ * "id": "user-id",
49
+ * "access_token": "access-token"
50
+ * }
51
+ * }
52
+ * ```
53
+ *
54
+ * ## Notes
55
+ * - `tokenIntrospectionEndpointUrl` is mandatory and should point to a valid OAuth2 provider's introspection endpoint.
56
+ * - If `appidField` is defined, `appIds` must also be specified to validate the app ID in the introspection response.
57
+ * - `authorizationHeader` can be used to authenticate requests to the token introspection endpoint.
58
+ *
59
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7662 OAuth 2.0 Token Introspection Specification}
60
+ */
61
+
62
+ class OAuth2Adapter extends _AuthAdapter.default {
63
+ validateOptions(options) {
64
+ super.validateOptions(options);
65
+ if (!options.tokenIntrospectionEndpointUrl) {
66
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'OAuth2 token introspection endpoint URL is missing.');
67
+ }
68
+ if (options.appidField && !options.appIds?.length) {
69
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'OAuth2 configuration is missing app IDs.');
70
+ }
71
+ this.tokenIntrospectionEndpointUrl = options.tokenIntrospectionEndpointUrl;
72
+ this.useridField = options.useridField || 'sub';
73
+ this.appidField = options.appidField;
74
+ this.appIds = options.appIds;
75
+ this.authorizationHeader = options.authorizationHeader;
76
+ }
77
+ async validateAppId(appIds, authData) {
78
+ if (!this.appidField) {
79
+ return;
80
+ }
81
+ const response = await this.requestTokenInfo(authData.access_token);
82
+ const appIdFieldValue = response[this.appidField];
83
+ const isValidAppId = Array.isArray(appIdFieldValue) ? appIdFieldValue.some(appId => this.appIds.includes(appId)) : this.appIds.includes(appIdFieldValue);
84
+ if (!isValidAppId) {
85
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'OAuth2: Invalid app ID.');
86
+ }
87
+ }
88
+ async validateAuthData(authData) {
89
+ const response = await this.requestTokenInfo(authData.access_token);
90
+ if (!response.active || this.useridField && authData.id !== response[this.useridField]) {
91
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'OAuth2 access token is invalid for this user.');
92
+ }
93
+ return {};
94
+ }
95
+ async requestTokenInfo(accessToken) {
96
+ const response = await fetch(this.tokenIntrospectionEndpointUrl, {
97
+ method: 'POST',
98
+ headers: {
99
+ 'Content-Type': 'application/x-www-form-urlencoded',
100
+ ...(this.authorizationHeader && {
101
+ Authorization: this.authorizationHeader
102
+ })
103
+ },
104
+ body: new URLSearchParams({
105
+ token: accessToken
106
+ })
107
+ });
108
+ if (!response.ok) {
109
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'OAuth2 token introspection request failed.');
110
+ }
111
+ return response.json();
112
+ }
113
+ }
114
+ var _default = exports.default = new OAuth2Adapter();
115
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQXV0aEFkYXB0ZXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsIk9BdXRoMkFkYXB0ZXIiLCJBdXRoQWRhcHRlciIsInZhbGlkYXRlT3B0aW9ucyIsIm9wdGlvbnMiLCJ0b2tlbkludHJvc3BlY3Rpb25FbmRwb2ludFVybCIsIlBhcnNlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiYXBwaWRGaWVsZCIsImFwcElkcyIsImxlbmd0aCIsInVzZXJpZEZpZWxkIiwiYXV0aG9yaXphdGlvbkhlYWRlciIsInZhbGlkYXRlQXBwSWQiLCJhdXRoRGF0YSIsInJlc3BvbnNlIiwicmVxdWVzdFRva2VuSW5mbyIsImFjY2Vzc190b2tlbiIsImFwcElkRmllbGRWYWx1ZSIsImlzVmFsaWRBcHBJZCIsIkFycmF5IiwiaXNBcnJheSIsInNvbWUiLCJhcHBJZCIsImluY2x1ZGVzIiwidmFsaWRhdGVBdXRoRGF0YSIsImFjdGl2ZSIsImlkIiwiYWNjZXNzVG9rZW4iLCJmZXRjaCIsIm1ldGhvZCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwiYm9keSIsIlVSTFNlYXJjaFBhcmFtcyIsInRva2VuIiwib2siLCJqc29uIiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvb2F1dGgyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGFyc2UgU2VydmVyIGF1dGhlbnRpY2F0aW9uIGFkYXB0ZXIgZm9yIE9BdXRoMiBUb2tlbiBJbnRyb3NwZWN0aW9uLlxuICpcbiAqIEBjbGFzcyBPQXV0aDJBZGFwdGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBhZGFwdGVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLnRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsIC0gVGhlIFVSTCBvZiB0aGUgdG9rZW4gaW50cm9zcGVjdGlvbiBlbmRwb2ludC4gUmVxdWlyZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMub2F1dGgyIC0gSW5kaWNhdGVzIHRoYXQgdGhlIHJlcXVlc3Qgc2hvdWxkIGJlIGhhbmRsZWQgYnkgdGhlIE9BdXRoMiBhZGFwdGVyLiBSZXF1aXJlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy51c2VyaWRGaWVsZD0nc3ViJ10gLSBUaGUgZmllbGQgaW4gdGhlIGludHJvc3BlY3Rpb24gcmVzcG9uc2UgdGhhdCBjb250YWlucyB0aGUgdXNlciBJRC4gRGVmYXVsdHMgdG8gYHN1YmAgcGVyIFJGQyA3NjYyLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmFwcGlkRmllbGRdIC0gVGhlIGZpZWxkIGluIHRoZSBpbnRyb3NwZWN0aW9uIHJlc3BvbnNlIHRoYXQgY29udGFpbnMgdGhlIGFwcCBJRC4gT3B0aW9uYWwuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbb3B0aW9ucy5hcHBJZHNdIC0gTGlzdCBvZiBhbGxvd2VkIGFwcCBJRHMuIFJlcXVpcmVkIGlmIGBhcHBpZEZpZWxkYCBpcyBkZWZpbmVkLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmF1dGhvcml6YXRpb25IZWFkZXJdIC0gVGhlIEF1dGhvcml6YXRpb24gaGVhZGVyIHZhbHVlIGZvciB0aGUgaW50cm9zcGVjdGlvbiByZXF1ZXN0LiBPcHRpb25hbC5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBPQXV0aDIgVG9rZW4gSW50cm9zcGVjdGlvbiwgdXNlIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxuICogYGBganNvblxuICoge1xuICogICBcImF1dGhcIjoge1xuICogICAgIFwib2F1dGgyUHJvdmlkZXJcIjoge1xuICogICAgICAgXCJ0b2tlbkludHJvc3BlY3Rpb25FbmRwb2ludFVybFwiOiBcImh0dHBzOi8vcHJvdmlkZXIuY29tL2ludHJvc3BlY3RcIixcbiAqICAgICAgIFwidXNlcmlkRmllbGRcIjogXCJzdWJcIixcbiAqICAgICAgIFwiYXBwaWRGaWVsZFwiOiBcImF1ZFwiLFxuICogICAgICAgXCJhcHBJZHNcIjogW1wibXktYXBwLWlkXCJdLFxuICogICAgICAgXCJhdXRob3JpemF0aW9uSGVhZGVyXCI6IFwiQmFzaWMgZFhObGNtNWhiV1U2Y0dGemMzZHZjbVE9XCIsXG4gKiAgICAgICBcIm9hdXRoMlwiOiB0cnVlXG4gKiAgICAgfVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgYWRhcHRlciByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGBhdXRoRGF0YWAgZmllbGRzOlxuICogLSBgaWRgOiBUaGUgdXNlciBJRCBwcm92aWRlZCBieSB0aGUgY2xpZW50LlxuICogLSBgYWNjZXNzX3Rva2VuYDogVGhlIGFjY2VzcyB0b2tlbiBwcm92aWRlZCBieSB0aGUgY2xpZW50LlxuICpcbiAqICMjIEF1dGggUGF5bG9hZFxuICogIyMjIEV4YW1wbGUgQXV0aCBQYXlsb2FkXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwib2F1dGgyXCI6IHtcbiAqICAgICBcImlkXCI6IFwidXNlci1pZFwiLFxuICogICAgIFwiYWNjZXNzX3Rva2VuXCI6IFwiYWNjZXNzLXRva2VuXCJcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogIyMgTm90ZXNcbiAqIC0gYHRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsYCBpcyBtYW5kYXRvcnkgYW5kIHNob3VsZCBwb2ludCB0byBhIHZhbGlkIE9BdXRoMiBwcm92aWRlcidzIGludHJvc3BlY3Rpb24gZW5kcG9pbnQuXG4gKiAtIElmIGBhcHBpZEZpZWxkYCBpcyBkZWZpbmVkLCBgYXBwSWRzYCBtdXN0IGFsc28gYmUgc3BlY2lmaWVkIHRvIHZhbGlkYXRlIHRoZSBhcHAgSUQgaW4gdGhlIGludHJvc3BlY3Rpb24gcmVzcG9uc2UuXG4gKiAtIGBhdXRob3JpemF0aW9uSGVhZGVyYCBjYW4gYmUgdXNlZCB0byBhdXRoZW50aWNhdGUgcmVxdWVzdHMgdG8gdGhlIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQuXG4gKlxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmM3NjYyIE9BdXRoIDIuMCBUb2tlbiBJbnRyb3NwZWN0aW9uIFNwZWNpZmljYXRpb259XG4gKi9cblxuXG5pbXBvcnQgQXV0aEFkYXB0ZXIgZnJvbSAnLi9BdXRoQWRhcHRlcic7XG5cbmNsYXNzIE9BdXRoMkFkYXB0ZXIgZXh0ZW5kcyBBdXRoQWRhcHRlciB7XG4gIHZhbGlkYXRlT3B0aW9ucyhvcHRpb25zKSB7XG4gICAgc3VwZXIudmFsaWRhdGVPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgaWYgKCFvcHRpb25zLnRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09BdXRoMiB0b2tlbiBpbnRyb3NwZWN0aW9uIGVuZHBvaW50IFVSTCBpcyBtaXNzaW5nLicpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5hcHBpZEZpZWxkICYmICFvcHRpb25zLmFwcElkcz8ubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09BdXRoMiBjb25maWd1cmF0aW9uIGlzIG1pc3NpbmcgYXBwIElEcy4nKTtcbiAgICB9XG5cbiAgICB0aGlzLnRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsID0gb3B0aW9ucy50b2tlbkludHJvc3BlY3Rpb25FbmRwb2ludFVybDtcbiAgICB0aGlzLnVzZXJpZEZpZWxkID0gb3B0aW9ucy51c2VyaWRGaWVsZCB8fCAnc3ViJztcbiAgICB0aGlzLmFwcGlkRmllbGQgPSBvcHRpb25zLmFwcGlkRmllbGQ7XG4gICAgdGhpcy5hcHBJZHMgPSBvcHRpb25zLmFwcElkcztcbiAgICB0aGlzLmF1dGhvcml6YXRpb25IZWFkZXIgPSBvcHRpb25zLmF1dGhvcml6YXRpb25IZWFkZXI7XG4gIH1cblxuICBhc3luYyB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEpIHtcbiAgICBpZiAoIXRoaXMuYXBwaWRGaWVsZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0VG9rZW5JbmZvKGF1dGhEYXRhLmFjY2Vzc190b2tlbik7XG5cbiAgICBjb25zdCBhcHBJZEZpZWxkVmFsdWUgPSByZXNwb25zZVt0aGlzLmFwcGlkRmllbGRdO1xuICAgIGNvbnN0IGlzVmFsaWRBcHBJZCA9IEFycmF5LmlzQXJyYXkoYXBwSWRGaWVsZFZhbHVlKVxuICAgICAgPyBhcHBJZEZpZWxkVmFsdWUuc29tZShhcHBJZCA9PiB0aGlzLmFwcElkcy5pbmNsdWRlcyhhcHBJZCkpXG4gICAgICA6IHRoaXMuYXBwSWRzLmluY2x1ZGVzKGFwcElkRmllbGRWYWx1ZSk7XG5cbiAgICBpZiAoIWlzVmFsaWRBcHBJZCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPQXV0aDI6IEludmFsaWQgYXBwIElELicpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdFRva2VuSW5mbyhhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5hY3RpdmUgfHwgKHRoaXMudXNlcmlkRmllbGQgJiYgYXV0aERhdGEuaWQgIT09IHJlc3BvbnNlW3RoaXMudXNlcmlkRmllbGRdKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPQXV0aDIgYWNjZXNzIHRva2VuIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge307XG4gIH1cblxuICBhc3luYyByZXF1ZXN0VG9rZW5JbmZvKGFjY2Vzc1Rva2VuKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLnRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgICAuLi4odGhpcy5hdXRob3JpemF0aW9uSGVhZGVyICYmIHsgQXV0aG9yaXphdGlvbjogdGhpcy5hdXRob3JpemF0aW9uSGVhZGVyIH0pXG4gICAgICB9LFxuICAgICAgYm9keTogbmV3IFVSTFNlYXJjaFBhcmFtcyh7IHRva2VuOiBhY2Nlc3NUb2tlbiB9KVxuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPQXV0aDIgdG9rZW4gaW50cm9zcGVjdGlvbiByZXF1ZXN0IGZhaWxlZC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBPQXV0aDJBZGFwdGVyKCk7XG5cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBc0RBLElBQUFBLFlBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUF3QyxTQUFBRCx1QkFBQUUsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQXREeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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