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,57 +1,184 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
- // Helper functions for accessing the Facebook Graph API.
4
- var https = require('https');
5
- var Parse = require('parse/node').Parse;
3
+ /**
4
+ * Parse Server authentication adapter for Facebook.
5
+ *
6
+ * @class FacebookAdapter
7
+ * @param {Object} options - The adapter configuration options.
8
+ * @param {string} options.appSecret - Your Facebook App Secret. Required for secure authentication.
9
+ * @param {string[]} options.appIds - An array of Facebook App IDs. Required for validating the app.
10
+ *
11
+ * @description
12
+ * ## Parse Server Configuration
13
+ * To configure Parse Server for Facebook authentication, use the following structure:
14
+ * ```json
15
+ * {
16
+ * "auth": {
17
+ * "facebook": {
18
+ * "appSecret": "your-app-secret",
19
+ * "appIds": ["your-app-id"]
20
+ * }
21
+ * }
22
+ * }
23
+ * ```
24
+ *
25
+ * The adapter supports the following authentication methods:
26
+ * - **Standard Login**: Requires `id` and `access_token`.
27
+ * - **Limited Login**: Requires `id` and `token`.
28
+ *
29
+ * ## Auth Payloads
30
+ * ### Standard Login Payload
31
+ * ```json
32
+ * {
33
+ * "facebook": {
34
+ * "id": "1234567",
35
+ * "access_token": "abc123def456ghi789"
36
+ * }
37
+ * }
38
+ * ```
39
+ *
40
+ * ### Limited Login Payload
41
+ * ```json
42
+ * {
43
+ * "facebook": {
44
+ * "id": "1234567",
45
+ * "token": "xxxxx.yyyyy.zzzzz"
46
+ * }
47
+ * }
48
+ * ```
49
+ *
50
+ * ## Notes
51
+ * - **Standard Login**: Use `id` and `access_token` for full functionality.
52
+ * - **Limited Login**: Use `id` and `token` (JWT) when tracking is opted out (e.g., via Apple's App Tracking Transparency).
53
+ * - Supported Parse Server versions:
54
+ * - `>= 6.5.6 < 7`
55
+ * - `>= 7.0.1`
56
+ *
57
+ * Secure authentication is recommended to ensure proper data protection and compliance with Facebook's guidelines.
58
+ *
59
+ * @see {@link https://developers.facebook.com/docs/facebook-login/limited-login/ Facebook Limited Login}
60
+ * @see {@link https://developers.facebook.com/docs/facebook-login/facebook-login-for-business/ Facebook Login for Business}
61
+ */
6
62
 
7
- // Returns a promise that fulfills iff this user id is valid.
8
- function validateAuthData(authData) {
9
- return graphRequest('me?fields=id&access_token=' + authData.access_token).then(data => {
10
- if (data && data.id == authData.id) {
63
+ // Helper functions for accessing the Facebook Graph API.
64
+ const Parse = require('parse/node').Parse;
65
+ const crypto = require('crypto');
66
+ const jwksClient = require('jwks-rsa');
67
+ const jwt = require('jsonwebtoken');
68
+ const httpsRequest = require('./httpsRequest');
69
+ const authUtils = require('./utils');
70
+ const TOKEN_ISSUER = 'https://www.facebook.com';
71
+ function getAppSecretPath(authData, options = {}) {
72
+ const appSecret = options.appSecret;
73
+ if (!appSecret) {
74
+ return '';
75
+ }
76
+ const appsecret_proof = crypto.createHmac('sha256', appSecret).update(authData.access_token).digest('hex');
77
+ return `&appsecret_proof=${appsecret_proof}`;
78
+ }
79
+ function validateGraphToken(authData, options) {
80
+ return graphRequest('me?fields=id&access_token=' + authData.access_token + getAppSecretPath(authData, options)).then(data => {
81
+ if (data && data.id == authData.id || process.env.TESTING && authData.id === 'test') {
11
82
  return;
12
83
  }
13
84
  throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.');
14
85
  });
15
86
  }
16
-
17
- // Returns a promise that fulfills iff this app id is valid.
18
- function validateAppId(appIds, authData) {
87
+ async function validateGraphAppId(appIds, authData, options) {
19
88
  var access_token = authData.access_token;
89
+ if (process.env.TESTING && access_token === 'test') {
90
+ return;
91
+ }
92
+ if (!Array.isArray(appIds)) {
93
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'appIds must be an array.');
94
+ }
20
95
  if (!appIds.length) {
21
96
  throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is not configured.');
22
97
  }
23
- return graphRequest('app?access_token=' + access_token).then(data => {
24
- if (data && appIds.indexOf(data.id) != -1) {
25
- return;
26
- }
98
+ const data = await graphRequest(`app?access_token=${access_token}${getAppSecretPath(authData, options)}`);
99
+ if (!data || !appIds.includes(data.id)) {
27
100
  throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.');
101
+ }
102
+ }
103
+ const getFacebookKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => {
104
+ const client = jwksClient({
105
+ jwksUri: `${TOKEN_ISSUER}/.well-known/oauth/openid/jwks/`,
106
+ cache: true,
107
+ cacheMaxEntries,
108
+ cacheMaxAge
28
109
  });
110
+ let key;
111
+ try {
112
+ key = await authUtils.getSigningKey(client, keyId);
113
+ } catch {
114
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unable to find matching key for Key ID: ${keyId}`);
115
+ }
116
+ return key;
117
+ };
118
+ const verifyIdToken = async ({
119
+ token,
120
+ id
121
+ }, {
122
+ clientId,
123
+ cacheMaxEntries,
124
+ cacheMaxAge
125
+ }) => {
126
+ if (!token) {
127
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'id token is invalid for this user.');
128
+ }
129
+ const {
130
+ kid: keyId,
131
+ alg: algorithm
132
+ } = authUtils.getHeaderFromToken(token);
133
+ const ONE_HOUR_IN_MS = 3600000;
134
+ let jwtClaims;
135
+ cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS;
136
+ cacheMaxEntries = cacheMaxEntries || 5;
137
+ const facebookKey = await getFacebookKeyByKeyId(keyId, cacheMaxEntries, cacheMaxAge);
138
+ const signingKey = facebookKey.publicKey || facebookKey.rsaPublicKey;
139
+ try {
140
+ jwtClaims = jwt.verify(token, signingKey, {
141
+ algorithms: algorithm,
142
+ // the audience can be checked against a string, a regular expression or a list of strings and/or regular expressions.
143
+ audience: clientId
144
+ });
145
+ } catch (exception) {
146
+ const message = exception.message;
147
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`);
148
+ }
149
+ if (jwtClaims.iss !== TOKEN_ISSUER) {
150
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`);
151
+ }
152
+ if (jwtClaims.sub !== id) {
153
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'auth data is invalid for this user.');
154
+ }
155
+ return jwtClaims;
156
+ };
157
+
158
+ // Returns a promise that fulfills iff this user id is valid.
159
+ function validateAuthData(authData, options) {
160
+ if (authData.token) {
161
+ return verifyIdToken(authData, options);
162
+ } else {
163
+ return validateGraphToken(authData, options);
164
+ }
165
+ }
166
+
167
+ // Returns a promise that fulfills iff this app id is valid.
168
+ function validateAppId(appIds, authData, options) {
169
+ if (authData.token) {
170
+ return Promise.resolve();
171
+ } else {
172
+ return validateGraphAppId(appIds, authData, options);
173
+ }
29
174
  }
30
175
 
31
176
  // A promisey wrapper for FB graph requests.
32
177
  function graphRequest(path) {
33
- return new Promise(function (resolve, reject) {
34
- https.get('https://graph.facebook.com/' + path, function (res) {
35
- var data = '';
36
- res.on('data', function (chunk) {
37
- data += chunk;
38
- });
39
- res.on('end', function () {
40
- try {
41
- data = JSON.parse(data);
42
- } catch (e) {
43
- return reject(e);
44
- }
45
- resolve(data);
46
- });
47
- }).on('error', function () {
48
- reject('Failed to validate this access token with Facebook.');
49
- });
50
- });
178
+ return httpsRequest.get('https://graph.facebook.com/' + path);
51
179
  }
52
-
53
180
  module.exports = {
54
181
  validateAppId: validateAppId,
55
182
  validateAuthData: validateAuthData
56
183
  };
57
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2ZhY2Vib29rLmpzIl0sIm5hbWVzIjpbImh0dHBzIiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiZ3JhcGhSZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJhcHBJZHMiLCJsZW5ndGgiLCJpbmRleE9mIiwicGF0aCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwib24iLCJjaHVuayIsIkpTT04iLCJwYXJzZSIsImUiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsUUFBUUMsUUFBUSxPQUFSLENBQVo7QUFDQSxJQUFJQyxRQUFRRCxRQUFRLFlBQVIsRUFBc0JDLEtBQWxDOztBQUVBO0FBQ0EsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DO0FBQ2xDLFNBQU9DLGFBQWEsK0JBQStCRCxTQUFTRSxZQUFyRCxFQUNKQyxJQURJLENBQ0VDLElBQUQsSUFBVTtBQUNkLFFBQUlBLFFBQVFBLEtBQUtDLEVBQUwsSUFBV0wsU0FBU0ssRUFBaEMsRUFBb0M7QUFDbEM7QUFDRDtBQUNELFVBQU0sSUFBSVAsTUFBTVEsS0FBVixDQUNKUixNQUFNUSxLQUFOLENBQVlDLGdCQURSLEVBRUoseUNBRkksQ0FBTjtBQUdELEdBUkksQ0FBUDtBQVNEOztBQUVEO0FBQ0EsU0FBU0MsYUFBVCxDQUF1QkMsTUFBdkIsRUFBK0JULFFBQS9CLEVBQXlDO0FBQ3ZDLE1BQUlFLGVBQWVGLFNBQVNFLFlBQTVCO0FBQ0EsTUFBSSxDQUFDTyxPQUFPQyxNQUFaLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSVosTUFBTVEsS0FBVixDQUNKUixNQUFNUSxLQUFOLENBQVlDLGdCQURSLEVBRUosa0NBRkksQ0FBTjtBQUdEO0FBQ0QsU0FBT04sYUFBYSxzQkFBc0JDLFlBQW5DLEVBQ0pDLElBREksQ0FDRUMsSUFBRCxJQUFVO0FBQ2QsUUFBSUEsUUFBUUssT0FBT0UsT0FBUCxDQUFlUCxLQUFLQyxFQUFwQixLQUEyQixDQUFDLENBQXhDLEVBQTJDO0FBQ3pDO0FBQ0Q7QUFDRCxVQUFNLElBQUlQLE1BQU1RLEtBQVYsQ0FDSlIsTUFBTVEsS0FBTixDQUFZQyxnQkFEUixFQUVKLHlDQUZJLENBQU47QUFHRCxHQVJJLENBQVA7QUFTRDs7QUFFRDtBQUNBLFNBQVNOLFlBQVQsQ0FBc0JXLElBQXRCLEVBQTRCO0FBQzFCLFNBQU8sSUFBSUMsT0FBSixDQUFZLFVBQVNDLE9BQVQsRUFBa0JDLE1BQWxCLEVBQTBCO0FBQzNDbkIsVUFBTW9CLEdBQU4sQ0FBVSxnQ0FBZ0NKLElBQTFDLEVBQWdELFVBQVNLLEdBQVQsRUFBYztBQUM1RCxVQUFJYixPQUFPLEVBQVg7QUFDQWEsVUFBSUMsRUFBSixDQUFPLE1BQVAsRUFBZSxVQUFTQyxLQUFULEVBQWdCO0FBQzdCZixnQkFBUWUsS0FBUjtBQUNELE9BRkQ7QUFHQUYsVUFBSUMsRUFBSixDQUFPLEtBQVAsRUFBYyxZQUFXO0FBQ3ZCLFlBQUk7QUFDRmQsaUJBQU9nQixLQUFLQyxLQUFMLENBQVdqQixJQUFYLENBQVA7QUFDRCxTQUZELENBRUUsT0FBTWtCLENBQU4sRUFBUztBQUNULGlCQUFPUCxPQUFPTyxDQUFQLENBQVA7QUFDRDtBQUNEUixnQkFBUVYsSUFBUjtBQUNELE9BUEQ7QUFRRCxLQWJELEVBYUdjLEVBYkgsQ0FhTSxPQWJOLEVBYWUsWUFBVztBQUN4QkgsYUFBTyxxREFBUDtBQUNELEtBZkQ7QUFnQkQsR0FqQk0sQ0FBUDtBQWtCRDs7QUFFRFEsT0FBT0MsT0FBUCxHQUFpQjtBQUNmaEIsaUJBQWVBLGFBREE7QUFFZlQsb0JBQWtCQTtBQUZILENBQWpCIiwiZmlsZSI6ImZhY2Vib29rLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSBGYWNlYm9vayBHcmFwaCBBUEkuXG52YXIgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiBncmFwaFJlcXVlc3QoJ21lP2ZpZWxkcz1pZCZhY2Nlc3NfdG9rZW49JyArIGF1dGhEYXRhLmFjY2Vzc190b2tlbilcbiAgICAudGhlbigoZGF0YSkgPT4ge1xuICAgICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdGYWNlYm9vayBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEpIHtcbiAgdmFyIGFjY2Vzc190b2tlbiA9IGF1dGhEYXRhLmFjY2Vzc190b2tlbjtcbiAgaWYgKCFhcHBJZHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdGYWNlYm9vayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLicpO1xuICB9XG4gIHJldHVybiBncmFwaFJlcXVlc3QoJ2FwcD9hY2Nlc3NfdG9rZW49JyArIGFjY2Vzc190b2tlbilcbiAgICAudGhlbigoZGF0YSkgPT4ge1xuICAgICAgaWYgKGRhdGEgJiYgYXBwSWRzLmluZGV4T2YoZGF0YS5pZCkgIT0gLTEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAnRmFjZWJvb2sgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gICAgfSk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgRkIgZ3JhcGggcmVxdWVzdHMuXG5mdW5jdGlvbiBncmFwaFJlcXVlc3QocGF0aCkge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgaHR0cHMuZ2V0KCdodHRwczovL2dyYXBoLmZhY2Vib29rLmNvbS8nICsgcGF0aCwgZnVuY3Rpb24ocmVzKSB7XG4gICAgICB2YXIgZGF0YSA9ICcnO1xuICAgICAgcmVzLm9uKCdkYXRhJywgZnVuY3Rpb24oY2h1bmspIHtcbiAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgIH0pO1xuICAgICAgcmVzLm9uKCdlbmQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgfSk7XG4gICAgfSkub24oJ2Vycm9yJywgZnVuY3Rpb24oKSB7XG4gICAgICByZWplY3QoJ0ZhaWxlZCB0byB2YWxpZGF0ZSB0aGlzIGFjY2VzcyB0b2tlbiB3aXRoIEZhY2Vib29rLicpO1xuICAgIH0pO1xuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGFcbn07XG4iXX0=
184
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJjcnlwdG8iLCJqd2tzQ2xpZW50Iiwiand0IiwiaHR0cHNSZXF1ZXN0IiwiYXV0aFV0aWxzIiwiVE9LRU5fSVNTVUVSIiwiZ2V0QXBwU2VjcmV0UGF0aCIsImF1dGhEYXRhIiwib3B0aW9ucyIsImFwcFNlY3JldCIsImFwcHNlY3JldF9wcm9vZiIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJhY2Nlc3NfdG9rZW4iLCJkaWdlc3QiLCJ2YWxpZGF0ZUdyYXBoVG9rZW4iLCJncmFwaFJlcXVlc3QiLCJ0aGVuIiwiZGF0YSIsImlkIiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUdyYXBoQXBwSWQiLCJhcHBJZHMiLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJpbmNsdWRlcyIsImdldEZhY2Vib29rS2V5QnlLZXlJZCIsImtleUlkIiwiY2FjaGVNYXhFbnRyaWVzIiwiY2FjaGVNYXhBZ2UiLCJjbGllbnQiLCJqd2tzVXJpIiwiY2FjaGUiLCJrZXkiLCJnZXRTaWduaW5nS2V5IiwidmVyaWZ5SWRUb2tlbiIsInRva2VuIiwiY2xpZW50SWQiLCJraWQiLCJhbGciLCJhbGdvcml0aG0iLCJnZXRIZWFkZXJGcm9tVG9rZW4iLCJPTkVfSE9VUl9JTl9NUyIsImp3dENsYWltcyIsImZhY2Vib29rS2V5Iiwic2lnbmluZ0tleSIsInB1YmxpY0tleSIsInJzYVB1YmxpY0tleSIsInZlcmlmeSIsImFsZ29yaXRobXMiLCJhdWRpZW5jZSIsImV4Y2VwdGlvbiIsIm1lc3NhZ2UiLCJpc3MiLCJzdWIiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicGF0aCIsImdldCIsIm1vZHVsZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvQWRhcHRlcnMvQXV0aC9mYWNlYm9vay5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlIFNlcnZlciBhdXRoZW50aWNhdGlvbiBhZGFwdGVyIGZvciBGYWNlYm9vay5cbiAqXG4gKiBAY2xhc3MgRmFjZWJvb2tBZGFwdGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBhZGFwdGVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmFwcFNlY3JldCAtIFlvdXIgRmFjZWJvb2sgQXBwIFNlY3JldC4gUmVxdWlyZWQgZm9yIHNlY3VyZSBhdXRoZW50aWNhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nW119IG9wdGlvbnMuYXBwSWRzIC0gQW4gYXJyYXkgb2YgRmFjZWJvb2sgQXBwIElEcy4gUmVxdWlyZWQgZm9yIHZhbGlkYXRpbmcgdGhlIGFwcC5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBGYWNlYm9vayBhdXRoZW50aWNhdGlvbiwgdXNlIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxuICogYGBganNvblxuICoge1xuICogICBcImF1dGhcIjoge1xuICogICAgIFwiZmFjZWJvb2tcIjoge1xuICogICAgICAgXCJhcHBTZWNyZXRcIjogXCJ5b3VyLWFwcC1zZWNyZXRcIixcbiAqICAgICAgIFwiYXBwSWRzXCI6IFtcInlvdXItYXBwLWlkXCJdXG4gKiAgICAgfVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgYWRhcHRlciBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGF1dGhlbnRpY2F0aW9uIG1ldGhvZHM6XG4gKiAtICoqU3RhbmRhcmQgTG9naW4qKjogUmVxdWlyZXMgYGlkYCBhbmQgYGFjY2Vzc190b2tlbmAuXG4gKiAtICoqTGltaXRlZCBMb2dpbioqOiBSZXF1aXJlcyBgaWRgIGFuZCBgdG9rZW5gLlxuICpcbiAqICMjIEF1dGggUGF5bG9hZHNcbiAqICMjIyBTdGFuZGFyZCBMb2dpbiBQYXlsb2FkXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiZmFjZWJvb2tcIjoge1xuICogICAgIFwiaWRcIjogXCIxMjM0NTY3XCIsXG4gKiAgICAgXCJhY2Nlc3NfdG9rZW5cIjogXCJhYmMxMjNkZWY0NTZnaGk3ODlcIlxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMgTGltaXRlZCBMb2dpbiBQYXlsb2FkXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiZmFjZWJvb2tcIjoge1xuICogICAgIFwiaWRcIjogXCIxMjM0NTY3XCIsXG4gKiAgICAgXCJ0b2tlblwiOiBcInh4eHh4Lnl5eXl5Lnp6enp6XCJcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogIyMgTm90ZXNcbiAqIC0gKipTdGFuZGFyZCBMb2dpbioqOiBVc2UgYGlkYCBhbmQgYGFjY2Vzc190b2tlbmAgZm9yIGZ1bGwgZnVuY3Rpb25hbGl0eS5cbiAqIC0gKipMaW1pdGVkIExvZ2luKio6IFVzZSBgaWRgIGFuZCBgdG9rZW5gIChKV1QpIHdoZW4gdHJhY2tpbmcgaXMgb3B0ZWQgb3V0IChlLmcuLCB2aWEgQXBwbGUncyBBcHAgVHJhY2tpbmcgVHJhbnNwYXJlbmN5KS5cbiAqIC0gU3VwcG9ydGVkIFBhcnNlIFNlcnZlciB2ZXJzaW9uczpcbiAqICAgLSBgPj0gNi41LjYgPCA3YFxuICogICAtIGA+PSA3LjAuMWBcbiAqXG4gKiBTZWN1cmUgYXV0aGVudGljYXRpb24gaXMgcmVjb21tZW5kZWQgdG8gZW5zdXJlIHByb3BlciBkYXRhIHByb3RlY3Rpb24gYW5kIGNvbXBsaWFuY2Ugd2l0aCBGYWNlYm9vaydzIGd1aWRlbGluZXMuXG4gKlxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXJzLmZhY2Vib29rLmNvbS9kb2NzL2ZhY2Vib29rLWxvZ2luL2xpbWl0ZWQtbG9naW4vIEZhY2Vib29rIExpbWl0ZWQgTG9naW59XG4gKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3BlcnMuZmFjZWJvb2suY29tL2RvY3MvZmFjZWJvb2stbG9naW4vZmFjZWJvb2stbG9naW4tZm9yLWJ1c2luZXNzLyBGYWNlYm9vayBMb2dpbiBmb3IgQnVzaW5lc3N9XG4gKi9cblxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSBGYWNlYm9vayBHcmFwaCBBUEkuXG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuY29uc3Qgandrc0NsaWVudCA9IHJlcXVpcmUoJ2p3a3MtcnNhJyk7XG5jb25zdCBqd3QgPSByZXF1aXJlKCdqc29ud2VidG9rZW4nKTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5jb25zdCBhdXRoVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbmNvbnN0IFRPS0VOX0lTU1VFUiA9ICdodHRwczovL3d3dy5mYWNlYm9vay5jb20nO1xuXG5mdW5jdGlvbiBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3QgYXBwU2VjcmV0ID0gb3B0aW9ucy5hcHBTZWNyZXQ7XG4gIGlmICghYXBwU2VjcmV0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IGFwcHNlY3JldF9wcm9vZiA9IGNyeXB0b1xuICAgIC5jcmVhdGVIbWFjKCdzaGEyNTYnLCBhcHBTZWNyZXQpXG4gICAgLnVwZGF0ZShhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pXG4gICAgLmRpZ2VzdCgnaGV4Jyk7XG5cbiAgcmV0dXJuIGAmYXBwc2VjcmV0X3Byb29mPSR7YXBwc2VjcmV0X3Byb29mfWA7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlR3JhcGhUb2tlbihhdXRoRGF0YSwgb3B0aW9ucykge1xuICByZXR1cm4gZ3JhcGhSZXF1ZXN0KFxuICAgICdtZT9maWVsZHM9aWQmYWNjZXNzX3Rva2VuPScgKyBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4gKyBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zKVxuICApLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKChkYXRhICYmIGRhdGEuaWQgPT0gYXV0aERhdGEuaWQpIHx8IChwcm9jZXNzLmVudi5URVNUSU5HICYmIGF1dGhEYXRhLmlkID09PSAndGVzdCcpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnRmFjZWJvb2sgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUdyYXBoQXBwSWQoYXBwSWRzLCBhdXRoRGF0YSwgb3B0aW9ucykge1xuICB2YXIgYWNjZXNzX3Rva2VuID0gYXV0aERhdGEuYWNjZXNzX3Rva2VuO1xuICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyAmJiBhY2Nlc3NfdG9rZW4gPT09ICd0ZXN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIUFycmF5LmlzQXJyYXkoYXBwSWRzKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnYXBwSWRzIG11c3QgYmUgYW4gYXJyYXkuJyk7XG4gIH1cbiAgaWYgKCFhcHBJZHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdGYWNlYm9vayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLicpO1xuICB9XG4gIGNvbnN0IGRhdGEgPSBhd2FpdCBncmFwaFJlcXVlc3QoXG4gICAgYGFwcD9hY2Nlc3NfdG9rZW49JHthY2Nlc3NfdG9rZW59JHtnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zKX1gXG4gICk7XG4gIGlmICghZGF0YSB8fCAhYXBwSWRzLmluY2x1ZGVzKGRhdGEuaWQpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdGYWNlYm9vayBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfVxufVxuXG5jb25zdCBnZXRGYWNlYm9va0tleUJ5S2V5SWQgPSBhc3luYyAoa2V5SWQsIGNhY2hlTWF4RW50cmllcywgY2FjaGVNYXhBZ2UpID0+IHtcbiAgY29uc3QgY2xpZW50ID0gandrc0NsaWVudCh7XG4gICAgandrc1VyaTogYCR7VE9LRU5fSVNTVUVSfS8ud2VsbC1rbm93bi9vYXV0aC9vcGVuaWQvandrcy9gLFxuICAgIGNhY2hlOiB0cnVlLFxuICAgIGNhY2hlTWF4RW50cmllcyxcbiAgICBjYWNoZU1heEFnZSxcbiAgfSk7XG5cbiAgbGV0IGtleTtcbiAgdHJ5IHtcbiAgICBrZXkgPSBhd2FpdCBhdXRoVXRpbHMuZ2V0U2lnbmluZ0tleShjbGllbnQsIGtleUlkKTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBVbmFibGUgdG8gZmluZCBtYXRjaGluZyBrZXkgZm9yIEtleSBJRDogJHtrZXlJZH1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4ga2V5O1xufTtcblxuY29uc3QgdmVyaWZ5SWRUb2tlbiA9IGFzeW5jICh7IHRva2VuLCBpZCB9LCB7IGNsaWVudElkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlIH0pID0+IHtcbiAgaWYgKCF0b2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnaWQgdG9rZW4gaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9XG5cbiAgY29uc3QgeyBraWQ6IGtleUlkLCBhbGc6IGFsZ29yaXRobSB9ID0gYXV0aFV0aWxzLmdldEhlYWRlckZyb21Ub2tlbih0b2tlbik7XG4gIGNvbnN0IE9ORV9IT1VSX0lOX01TID0gMzYwMDAwMDtcbiAgbGV0IGp3dENsYWltcztcblxuICBjYWNoZU1heEFnZSA9IGNhY2hlTWF4QWdlIHx8IE9ORV9IT1VSX0lOX01TO1xuICBjYWNoZU1heEVudHJpZXMgPSBjYWNoZU1heEVudHJpZXMgfHwgNTtcblxuICBjb25zdCBmYWNlYm9va0tleSA9IGF3YWl0IGdldEZhY2Vib29rS2V5QnlLZXlJZChrZXlJZCwgY2FjaGVNYXhFbnRyaWVzLCBjYWNoZU1heEFnZSk7XG4gIGNvbnN0IHNpZ25pbmdLZXkgPSBmYWNlYm9va0tleS5wdWJsaWNLZXkgfHwgZmFjZWJvb2tLZXkucnNhUHVibGljS2V5O1xuXG4gIHRyeSB7XG4gICAgand0Q2xhaW1zID0gand0LnZlcmlmeSh0b2tlbiwgc2lnbmluZ0tleSwge1xuICAgICAgYWxnb3JpdGhtczogYWxnb3JpdGhtLFxuICAgICAgLy8gdGhlIGF1ZGllbmNlIGNhbiBiZSBjaGVja2VkIGFnYWluc3QgYSBzdHJpbmcsIGEgcmVndWxhciBleHByZXNzaW9uIG9yIGEgbGlzdCBvZiBzdHJpbmdzIGFuZC9vciByZWd1bGFyIGV4cHJlc3Npb25zLlxuICAgICAgYXVkaWVuY2U6IGNsaWVudElkLFxuICAgIH0pO1xuICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXhjZXB0aW9uLm1lc3NhZ2U7XG5cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYCR7bWVzc2FnZX1gKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuaXNzICE9PSBUT0tFTl9JU1NVRVIpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYGlkIHRva2VuIG5vdCBpc3N1ZWQgYnkgY29ycmVjdCBPcGVuSUQgcHJvdmlkZXIgLSBleHBlY3RlZDogJHtUT0tFTl9JU1NVRVJ9IHwgZnJvbTogJHtqd3RDbGFpbXMuaXNzfWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5zdWIgIT09IGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdhdXRoIGRhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9XG4gIHJldHVybiBqd3RDbGFpbXM7XG59O1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmIChhdXRoRGF0YS50b2tlbikge1xuICAgIHJldHVybiB2ZXJpZnlJZFRva2VuKGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdmFsaWRhdGVHcmFwaFRva2VuKGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoYXBwSWRzLCBhdXRoRGF0YSwgb3B0aW9ucykge1xuICBpZiAoYXV0aERhdGEudG9rZW4pIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHZhbGlkYXRlR3JhcGhBcHBJZChhcHBJZHMsIGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgfVxufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIEZCIGdyYXBoIHJlcXVlc3RzLlxuZnVuY3Rpb24gZ3JhcGhSZXF1ZXN0KHBhdGgpIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoJ2h0dHBzOi8vZ3JhcGguZmFjZWJvb2suY29tLycgKyBwYXRoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRl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
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _crypto = _interopRequireDefault(require("crypto"));
8
+ var _nodeForge = require("node-forge");
9
+ var _AuthAdapter = _interopRequireDefault(require("./AuthAdapter"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ /**
12
+ * Parse Server authentication adapter for Apple Game Center.
13
+ *
14
+ * @class AppleGameCenterAdapter
15
+ * @param {Object} options - Configuration options for the adapter.
16
+ * @param {string} options.bundleId - Your Apple Game Center bundle ID. Required for secure authentication.
17
+ * @param {boolean} [options.enableInsecureAuth=false] - **[DEPRECATED]** Enable insecure authentication (not recommended).
18
+ *
19
+ * @param {Object} authData - The authentication data provided by the client.
20
+ * @param {string} authData.id - The user ID obtained from Apple Game Center.
21
+ * @param {string} authData.publicKeyUrl - The public key URL obtained from Apple Game Center.
22
+ * @param {string} authData.timestamp - The timestamp obtained from Apple Game Center.
23
+ * @param {string} authData.signature - The signature obtained from Apple Game Center.
24
+ * @param {string} authData.salt - The salt obtained from Apple Game Center.
25
+ * @param {string} [authData.bundleId] - **[DEPRECATED]** The bundle ID obtained from Apple Game Center (required for insecure authentication).
26
+ *
27
+ * @description
28
+ * ## Parse Server Configuration
29
+ * The following `authData` fields are required:
30
+ * `id`, `publicKeyUrl`, `timestamp`, `signature`, and `salt`. These fields are validated against the configured `bundleId` for additional security.
31
+ *
32
+ * To configure Parse Server for Apple Game Center authentication, use the following structure:
33
+ * ```json
34
+ * {
35
+ * "auth": {
36
+ * "gcenter": {
37
+ * "bundleId": "com.valid.app"
38
+ * }
39
+ * }
40
+ * ```
41
+ *
42
+ * ## Insecure Authentication (Not Recommended)
43
+ * The following `authData` fields are required for insecure authentication:
44
+ * `id`, `publicKeyUrl`, `timestamp`, `signature`, `salt`, and `bundleId` (**[DEPRECATED]**). This flow is insecure and poses potential security risks.
45
+ *
46
+ * To configure Parse Server for insecure authentication, use the following structure:
47
+ * ```json
48
+ * {
49
+ * "auth": {
50
+ * "gcenter": {
51
+ * "enableInsecureAuth": true
52
+ * }
53
+ * }
54
+ * ```
55
+ *
56
+ * ### Deprecation Notice
57
+ * The `enableInsecureAuth` option and `authData.bundleId` parameter are deprecated and may be removed in future releases. Use secure authentication with the `bundleId` configured in the `options` object instead.
58
+ *
59
+ *
60
+ * @example <caption>Secure Authentication Example</caption>
61
+ * // Example authData for secure authentication:
62
+ * const authData = {
63
+ * gcenter: {
64
+ * id: "1234567",
65
+ * publicKeyUrl: "https://valid.apple.com/public/timeout.cer",
66
+ * timestamp: 1460981421303,
67
+ * salt: "saltST==",
68
+ * signature: "PoDwf39DCN464B49jJCU0d9Y0J"
69
+ * }
70
+ * };
71
+ *
72
+ * @example <caption>Insecure Authentication Example (Not Recommended)</caption>
73
+ * // Example authData for insecure authentication:
74
+ * const authData = {
75
+ * gcenter: {
76
+ * id: "1234567",
77
+ * publicKeyUrl: "https://valid.apple.com/public/timeout.cer",
78
+ * timestamp: 1460981421303,
79
+ * salt: "saltST==",
80
+ * signature: "PoDwf39DCN464B49jJCU0d9Y0J",
81
+ * bundleId: "com.valid.app" // Deprecated.
82
+ * }
83
+ * };
84
+ *
85
+ * @see {@link https://developer.apple.com/documentation/gamekit/gklocalplayer/3516283-fetchitems Apple Game Center Documentation}
86
+ */
87
+ /* global BigInt */
88
+
89
+ class GameCenterAuth extends _AuthAdapter.default {
90
+ constructor() {
91
+ super();
92
+ this.ca = {
93
+ cert: null,
94
+ url: null
95
+ };
96
+ this.cache = {};
97
+ this.bundleId = '';
98
+ }
99
+ validateOptions(options) {
100
+ if (!options) {
101
+ throw new Error('Game center auth options are required.');
102
+ }
103
+ if (!this.loadingPromise) {
104
+ this.loadingPromise = this.loadCertificate(options);
105
+ }
106
+ this.enableInsecureAuth = options.enableInsecureAuth;
107
+ this.bundleId = options.bundleId;
108
+ if (!this.enableInsecureAuth && !this.bundleId) {
109
+ throw new Error('bundleId is required for secure auth.');
110
+ }
111
+ }
112
+ async loadCertificate(options) {
113
+ const rootCertificateUrl = options.rootCertificateUrl || 'https://cacerts.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crt.pem';
114
+ if (this.ca.url === rootCertificateUrl) {
115
+ return rootCertificateUrl;
116
+ }
117
+ const {
118
+ certificate,
119
+ headers
120
+ } = await this.fetchCertificate(rootCertificateUrl);
121
+ if (headers.get('content-type') !== 'application/x-pem-file' || !headers.get('content-length') || parseInt(headers.get('content-length'), 10) > 10000) {
122
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid rootCertificateURL.');
123
+ }
124
+ this.ca.cert = _nodeForge.pki.certificateFromPem(certificate);
125
+ this.ca.url = rootCertificateUrl;
126
+ return rootCertificateUrl;
127
+ }
128
+ verifyPublicKeyUrl(publicKeyUrl) {
129
+ const regex = /^https:\/\/(?:[-_A-Za-z0-9]+\.){0,}apple\.com\/.*\.cer$/;
130
+ return regex.test(publicKeyUrl);
131
+ }
132
+ async fetchCertificate(url) {
133
+ const response = await fetch(url);
134
+ if (!response.ok) {
135
+ throw new Error(`Failed to fetch certificate: ${url}`);
136
+ }
137
+ const contentType = response.headers.get('content-type');
138
+ const isPem = contentType?.includes('application/x-pem-file');
139
+ if (isPem) {
140
+ const certificate = await response.text();
141
+ return {
142
+ certificate,
143
+ headers: response.headers
144
+ };
145
+ }
146
+ const data = await response.arrayBuffer();
147
+ const binaryData = Buffer.from(data);
148
+ const asn1Cert = _nodeForge.asn1.fromDer(binaryData.toString('binary'));
149
+ const forgeCert = _nodeForge.pki.certificateFromAsn1(asn1Cert);
150
+ const certificate = _nodeForge.pki.certificateToPem(forgeCert);
151
+ return {
152
+ certificate,
153
+ headers: response.headers
154
+ };
155
+ }
156
+ async getAppleCertificate(publicKeyUrl) {
157
+ if (!this.verifyPublicKeyUrl(publicKeyUrl)) {
158
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Invalid publicKeyUrl: ${publicKeyUrl}`);
159
+ }
160
+ if (this.cache[publicKeyUrl]) {
161
+ return this.cache[publicKeyUrl];
162
+ }
163
+ const {
164
+ certificate,
165
+ headers
166
+ } = await this.fetchCertificate(publicKeyUrl);
167
+ const cacheControl = headers.get('cache-control');
168
+ const expire = cacheControl?.match(/max-age=([0-9]+)/);
169
+ this.verifyPublicKeyIssuer(certificate, publicKeyUrl);
170
+ if (expire) {
171
+ this.cache[publicKeyUrl] = certificate;
172
+ setTimeout(() => delete this.cache[publicKeyUrl], parseInt(expire[1], 10) * 1000);
173
+ }
174
+ return certificate;
175
+ }
176
+ verifyPublicKeyIssuer(cert, publicKeyUrl) {
177
+ const publicKeyCert = _nodeForge.pki.certificateFromPem(cert);
178
+ if (!this.ca.cert) {
179
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Root certificate is invalid or missing.');
180
+ }
181
+ if (!this.ca.cert.verify(publicKeyCert)) {
182
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Invalid publicKeyUrl: ${publicKeyUrl}`);
183
+ }
184
+ }
185
+ verifySignature(publicKey, authData) {
186
+ const bundleId = this.bundleId || this.enableInsecureAuth && authData.bundleId;
187
+ const verifier = _crypto.default.createVerify('sha256');
188
+ verifier.update(Buffer.from(authData.id, 'utf8'));
189
+ verifier.update(Buffer.from(bundleId, 'utf8'));
190
+ verifier.update(this.convertTimestampToBigEndian(authData.timestamp));
191
+ verifier.update(Buffer.from(authData.salt, 'base64'));
192
+ if (!verifier.verify(publicKey, authData.signature, 'base64')) {
193
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid signature.');
194
+ }
195
+ }
196
+ async validateAuthData(authData) {
197
+ const requiredKeys = ['id', 'publicKeyUrl', 'timestamp', 'signature', 'salt'];
198
+ if (this.enableInsecureAuth) {
199
+ requiredKeys.push('bundleId');
200
+ }
201
+ for (const key of requiredKeys) {
202
+ if (!authData[key]) {
203
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `AuthData ${key} is missing.`);
204
+ }
205
+ }
206
+ await this.loadingPromise;
207
+ const publicKey = await this.getAppleCertificate(authData.publicKeyUrl);
208
+ this.verifySignature(publicKey, authData);
209
+ }
210
+ convertTimestampToBigEndian(timestamp) {
211
+ const buffer = Buffer.alloc(8);
212
+ buffer.writeBigUInt64BE(BigInt(timestamp));
213
+ return buffer;
214
+ }
215
+ }
216
+ var _default = exports.default = new GameCenterAuth();
217
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY3J5cHRvIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfbm9kZUZvcmdlIiwiX0F1dGhBZGFwdGVyIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiR2FtZUNlbnRlckF1dGgiLCJBdXRoQWRhcHRlciIsImNvbnN0cnVjdG9yIiwiY2EiLCJjZXJ0IiwidXJsIiwiY2FjaGUiLCJidW5kbGVJZCIsInZhbGlkYXRlT3B0aW9ucyIsIm9wdGlvbnMiLCJFcnJvciIsImxvYWRpbmdQcm9taXNlIiwibG9hZENlcnRpZmljYXRlIiwiZW5hYmxlSW5zZWN1cmVBdXRoIiwicm9vdENlcnRpZmljYXRlVXJsIiwiY2VydGlmaWNhdGUiLCJoZWFkZXJzIiwiZmV0Y2hDZXJ0aWZpY2F0ZSIsImdldCIsInBhcnNlSW50IiwiUGFyc2UiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwicGtpIiwiY2VydGlmaWNhdGVGcm9tUGVtIiwidmVyaWZ5UHVibGljS2V5VXJsIiwicHVibGljS2V5VXJsIiwicmVnZXgiLCJ0ZXN0IiwicmVzcG9uc2UiLCJmZXRjaCIsIm9rIiwiY29udGVudFR5cGUiLCJpc1BlbSIsImluY2x1ZGVzIiwidGV4dCIsImRhdGEiLCJhcnJheUJ1ZmZlciIsImJpbmFyeURhdGEiLCJCdWZmZXIiLCJmcm9tIiwiYXNuMUNlcnQiLCJhc24xIiwiZnJvbURlciIsInRvU3RyaW5nIiwiZm9yZ2VDZXJ0IiwiY2VydGlmaWNhdGVGcm9tQXNuMSIsImNlcnRpZmljYXRlVG9QZW0iLCJnZXRBcHBsZUNlcnRpZmljYXRlIiwiY2FjaGVDb250cm9sIiwiZXhwaXJlIiwibWF0Y2giLCJ2ZXJpZnlQdWJsaWNLZXlJc3N1ZXIiLCJzZXRUaW1lb3V0IiwicHVibGljS2V5Q2VydCIsInZlcmlmeSIsInZlcmlmeVNpZ25hdHVyZSIsInB1YmxpY0tleSIsImF1dGhEYXRhIiwidmVyaWZpZXIiLCJjcnlwdG8iLCJjcmVhdGVWZXJpZnkiLCJ1cGRhdGUiLCJpZCIsImNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbiIsInRpbWVzdGFtcCIsInNhbHQiLCJzaWduYXR1cmUiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwicmVxdWlyZWRLZXlzIiwicHVzaCIsImtleSIsImJ1ZmZlciIsImFsbG9jIiwid3JpdGVCaWdVSW50NjRCRSIsIkJpZ0ludCIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2djZW50ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJzZSBTZXJ2ZXIgYXV0aGVudGljYXRpb24gYWRhcHRlciBmb3IgQXBwbGUgR2FtZSBDZW50ZXIuXG4gKlxuICogQGNsYXNzIEFwcGxlR2FtZUNlbnRlckFkYXB0ZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgYWRhcHRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmJ1bmRsZUlkIC0gWW91ciBBcHBsZSBHYW1lIENlbnRlciBidW5kbGUgSUQuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUluc2VjdXJlQXV0aD1mYWxzZV0gLSAqKltERVBSRUNBVEVEXSoqIEVuYWJsZSBpbnNlY3VyZSBhdXRoZW50aWNhdGlvbiAobm90IHJlY29tbWVuZGVkKS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYXV0aERhdGEgLSBUaGUgYXV0aGVudGljYXRpb24gZGF0YSBwcm92aWRlZCBieSB0aGUgY2xpZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmlkIC0gVGhlIHVzZXIgSUQgb2J0YWluZWQgZnJvbSBBcHBsZSBHYW1lIENlbnRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhdXRoRGF0YS5wdWJsaWNLZXlVcmwgLSBUaGUgcHVibGljIGtleSBVUkwgb2J0YWluZWQgZnJvbSBBcHBsZSBHYW1lIENlbnRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhdXRoRGF0YS50aW1lc3RhbXAgLSBUaGUgdGltZXN0YW1wIG9idGFpbmVkIGZyb20gQXBwbGUgR2FtZSBDZW50ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gYXV0aERhdGEuc2lnbmF0dXJlIC0gVGhlIHNpZ25hdHVyZSBvYnRhaW5lZCBmcm9tIEFwcGxlIEdhbWUgQ2VudGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLnNhbHQgLSBUaGUgc2FsdCBvYnRhaW5lZCBmcm9tIEFwcGxlIEdhbWUgQ2VudGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IFthdXRoRGF0YS5idW5kbGVJZF0gLSAqKltERVBSRUNBVEVEXSoqIFRoZSBidW5kbGUgSUQgb2J0YWluZWQgZnJvbSBBcHBsZSBHYW1lIENlbnRlciAocmVxdWlyZWQgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uKS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUaGUgZm9sbG93aW5nIGBhdXRoRGF0YWAgZmllbGRzIGFyZSByZXF1aXJlZDpcbiAqIGBpZGAsIGBwdWJsaWNLZXlVcmxgLCBgdGltZXN0YW1wYCwgYHNpZ25hdHVyZWAsIGFuZCBgc2FsdGAuIFRoZXNlIGZpZWxkcyBhcmUgdmFsaWRhdGVkIGFnYWluc3QgdGhlIGNvbmZpZ3VyZWQgYGJ1bmRsZUlkYCBmb3IgYWRkaXRpb25hbCBzZWN1cml0eS5cbiAqXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBBcHBsZSBHYW1lIENlbnRlciBhdXRoZW50aWNhdGlvbiwgdXNlIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxuICogYGBganNvblxuICoge1xuICogIFwiYXV0aFwiOiB7XG4gKiAgICBcImdjZW50ZXJcIjoge1xuICogICAgIFwiYnVuZGxlSWRcIjogXCJjb20udmFsaWQuYXBwXCJcbiAqICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyBJbnNlY3VyZSBBdXRoZW50aWNhdGlvbiAoTm90IFJlY29tbWVuZGVkKVxuICogVGhlIGZvbGxvd2luZyBgYXV0aERhdGFgIGZpZWxkcyBhcmUgcmVxdWlyZWQgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uOlxuICogYGlkYCwgYHB1YmxpY0tleVVybGAsIGB0aW1lc3RhbXBgLCBgc2lnbmF0dXJlYCwgYHNhbHRgLCBhbmQgYGJ1bmRsZUlkYCAoKipbREVQUkVDQVRFRF0qKikuIFRoaXMgZmxvdyBpcyBpbnNlY3VyZSBhbmQgcG9zZXMgcG90ZW50aWFsIHNlY3VyaXR5IHJpc2tzLlxuICpcbiAqIFRvIGNvbmZpZ3VyZSBQYXJzZSBTZXJ2ZXIgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uLCB1c2UgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiYXV0aFwiOiB7XG4gKiAgICBcImdjZW50ZXJcIjoge1xuICogICAgICBcImVuYWJsZUluc2VjdXJlQXV0aFwiOiB0cnVlXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIyBEZXByZWNhdGlvbiBOb3RpY2VcbiAqIFRoZSBgZW5hYmxlSW5zZWN1cmVBdXRoYCBvcHRpb24gYW5kIGBhdXRoRGF0YS5idW5kbGVJZGAgcGFyYW1ldGVyIGFyZSBkZXByZWNhdGVkIGFuZCBtYXkgYmUgcmVtb3ZlZCBpbiBmdXR1cmUgcmVsZWFzZXMuIFVzZSBzZWN1cmUgYXV0aGVudGljYXRpb24gd2l0aCB0aGUgYGJ1bmRsZUlkYCBjb25maWd1cmVkIGluIHRoZSBgb3B0aW9uc2Agb2JqZWN0IGluc3RlYWQuXG4gKlxuICpcbiAqIEBleGFtcGxlIDxjYXB0aW9uPlNlY3VyZSBBdXRoZW50aWNhdGlvbiBFeGFtcGxlPC9jYXB0aW9uPlxuICogLy8gRXhhbXBsZSBhdXRoRGF0YSBmb3Igc2VjdXJlIGF1dGhlbnRpY2F0aW9uOlxuICogY29uc3QgYXV0aERhdGEgPSB7XG4gKiAgIGdjZW50ZXI6IHtcbiAqICAgICBpZDogXCIxMjM0NTY3XCIsXG4gKiAgICAgcHVibGljS2V5VXJsOiBcImh0dHBzOi8vdmFsaWQuYXBwbGUuY29tL3B1YmxpYy90aW1lb3V0LmNlclwiLFxuICogICAgIHRpbWVzdGFtcDogMTQ2MDk4MTQyMTMwMyxcbiAqICAgICBzYWx0OiBcInNhbHRTVD09XCIsXG4gKiAgICAgc2lnbmF0dXJlOiBcIlBvRHdmMzlEQ040NjRCNDlqSkNVMGQ5WTBKXCJcbiAqICAgfVxuICogfTtcbiAqXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj5JbnNlY3VyZSBBdXRoZW50aWNhdGlvbiBFeGFtcGxlIChOb3QgUmVjb21tZW5kZWQpPC9jYXB0aW9uPlxuICogLy8gRXhhbXBsZSBhdXRoRGF0YSBmb3IgaW5zZWN1cmUgYXV0aGVudGljYXRpb246XG4gKiBjb25zdCBhdXRoRGF0YSA9IHtcbiAqICAgZ2NlbnRlcjoge1xuICogICAgIGlkOiBcIjEyMzQ1NjdcIixcbiAqICAgICBwdWJsaWNLZXlVcmw6IFwiaHR0cHM6Ly92YWxpZC5hcHBsZS5jb20vcHVibGljL3RpbWVvdXQuY2VyXCIsXG4gKiAgICAgdGltZXN0YW1wOiAxNDYwOTgxNDIxMzAzLFxuICogICAgIHNhbHQ6IFwic2FsdFNUPT1cIixcbiAqICAgICBzaWduYXR1cmU6IFwiUG9Ed2YzOURDTjQ2NEI0OWpKQ1UwZDlZMEpcIixcbiAqICAgICBidW5kbGVJZDogXCJjb20udmFsaWQuYXBwXCIgLy8gRGVwcmVjYXRlZC5cbiAqICAgfVxuICogfTtcbiAqXG4gKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi9nYW1la2l0L2drbG9jYWxwbGF5ZXIvMzUxNjI4My1mZXRjaGl0ZW1zIEFwcGxlIEdhbWUgQ2VudGVyIERvY3VtZW50YXRpb259XG4gKi9cbi8qIGdsb2JhbCBCaWdJbnQgKi9cblxuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgYXNuMSwgcGtpIH0gZnJvbSAnbm9kZS1mb3JnZSc7XG5pbXBvcnQgQXV0aEFkYXB0ZXIgZnJvbSAnLi9BdXRoQWRhcHRlcic7XG5jbGFzcyBHYW1lQ2VudGVyQXV0aCBleHRlbmRzIEF1dGhBZGFwdGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmNhID0geyBjZXJ0OiBudWxsLCB1cmw6IG51bGwgfTtcbiAgICB0aGlzLmNhY2hlID0ge307XG4gICAgdGhpcy5idW5kbGVJZCA9ICcnO1xuICB9XG5cbiAgdmFsaWRhdGVPcHRpb25zKG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignR2FtZSBjZW50ZXIgYXV0aCBvcHRpb25zIGFyZSByZXF1aXJlZC4nKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubG9hZGluZ1Byb21pc2UpIHtcbiAgICAgIHRoaXMubG9hZGluZ1Byb21pc2UgPSB0aGlzLmxvYWRDZXJ0aWZpY2F0ZShvcHRpb25zKTtcbiAgICB9XG5cbiAgICB0aGlzLmVuYWJsZUluc2VjdXJlQXV0aCA9IG9wdGlvbnMuZW5hYmxlSW5zZWN1cmVBdXRoO1xuICAgIHRoaXMuYnVuZGxlSWQgPSBvcHRpb25zLmJ1bmRsZUlkO1xuXG4gICAgaWYgKCF0aGlzLmVuYWJsZUluc2VjdXJlQXV0aCAmJiAhdGhpcy5idW5kbGVJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdidW5kbGVJZCBpcyByZXF1aXJlZCBmb3Igc2VjdXJlIGF1dGguJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbG9hZENlcnRpZmljYXRlKG9wdGlvbnMpIHtcbiAgICBjb25zdCByb290Q2VydGlmaWNhdGVVcmwgPVxuICAgICAgb3B0aW9ucy5yb290Q2VydGlmaWNhdGVVcmwgfHxcbiAgICAgICdodHRwczovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQucGVtJztcblxuICAgIGlmICh0aGlzLmNhLnVybCA9PT0gcm9vdENlcnRpZmljYXRlVXJsKSB7XG4gICAgICByZXR1cm4gcm9vdENlcnRpZmljYXRlVXJsO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY2VydGlmaWNhdGUsIGhlYWRlcnMgfSA9IGF3YWl0IHRoaXMuZmV0Y2hDZXJ0aWZpY2F0ZShyb290Q2VydGlmaWNhdGVVcmwpO1xuXG4gICAgaWYgKFxuICAgICAgaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpICE9PSAnYXBwbGljYXRpb24veC1wZW0tZmlsZScgfHxcbiAgICAgICFoZWFkZXJzLmdldCgnY29udGVudC1sZW5ndGgnKSB8fFxuICAgICAgcGFyc2VJbnQoaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJyksIDEwKSA+IDEwMDAwXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgcm9vdENlcnRpZmljYXRlVVJMLicpO1xuICAgIH1cblxuICAgIHRoaXMuY2EuY2VydCA9IHBraS5jZXJ0aWZpY2F0ZUZyb21QZW0oY2VydGlmaWNhdGUpO1xuICAgIHRoaXMuY2EudXJsID0gcm9vdENlcnRpZmljYXRlVXJsO1xuXG4gICAgcmV0dXJuIHJvb3RDZXJ0aWZpY2F0ZVVybDtcbiAgfVxuXG4gIHZlcmlmeVB1YmxpY0tleVVybChwdWJsaWNLZXlVcmwpIHtcbiAgICBjb25zdCByZWdleCA9IC9eaHR0cHM6XFwvXFwvKD86Wy1fQS1aYS16MC05XStcXC4pezAsfWFwcGxlXFwuY29tXFwvLipcXC5jZXIkLztcbiAgICByZXR1cm4gcmVnZXgudGVzdChwdWJsaWNLZXlVcmwpO1xuICB9XG5cbiAgYXN5bmMgZmV0Y2hDZXJ0aWZpY2F0ZSh1cmwpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZmV0Y2ggY2VydGlmaWNhdGU6ICR7dXJsfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpO1xuICAgIGNvbnN0IGlzUGVtID0gY29udGVudFR5cGU/LmluY2x1ZGVzKCdhcHBsaWNhdGlvbi94LXBlbS1maWxlJyk7XG5cbiAgICBpZiAoaXNQZW0pIHtcbiAgICAgIGNvbnN0IGNlcnRpZmljYXRlID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgICAgcmV0dXJuIHsgY2VydGlmaWNhdGUsIGhlYWRlcnM6IHJlc3BvbnNlLmhlYWRlcnMgfTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcbiAgICBjb25zdCBiaW5hcnlEYXRhID0gQnVmZmVyLmZyb20oZGF0YSk7XG5cbiAgICBjb25zdCBhc24xQ2VydCA9IGFzbjEuZnJvbURlcihiaW5hcnlEYXRhLnRvU3RyaW5nKCdiaW5hcnknKSk7XG4gICAgY29uc3QgZm9yZ2VDZXJ0ID0gcGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoYXNuMUNlcnQpO1xuICAgIGNvbnN0IGNlcnRpZmljYXRlID0gcGtpLmNlcnRpZmljYXRlVG9QZW0oZm9yZ2VDZXJ0KTtcblxuICAgIHJldHVybiB7IGNlcnRpZmljYXRlLCBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzIH07XG4gIH1cblxuICBhc3luYyBnZXRBcHBsZUNlcnRpZmljYXRlKHB1YmxpY0tleVVybCkge1xuICAgIGlmICghdGhpcy52ZXJpZnlQdWJsaWNLZXlVcmwocHVibGljS2V5VXJsKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIGBJbnZhbGlkIHB1YmxpY0tleVVybDogJHtwdWJsaWNLZXlVcmx9YCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY2FjaGVbcHVibGljS2V5VXJsXSkge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVbcHVibGljS2V5VXJsXTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNlcnRpZmljYXRlLCBoZWFkZXJzIH0gPSBhd2FpdCB0aGlzLmZldGNoQ2VydGlmaWNhdGUocHVibGljS2V5VXJsKTtcbiAgICBjb25zdCBjYWNoZUNvbnRyb2wgPSBoZWFkZXJzLmdldCgnY2FjaGUtY29udHJvbCcpO1xuICAgIGNvbnN0IGV4cGlyZSA9IGNhY2hlQ29udHJvbD8ubWF0Y2goL21heC1hZ2U9KFswLTldKykvKTtcblxuICAgIHRoaXMudmVyaWZ5UHVibGljS2V5SXNzdWVyKGNlcnRpZmljYXRlLCBwdWJsaWNLZXlVcmwpO1xuXG4gICAgaWYgKGV4cGlyZSkge1xuICAgICAgdGhpcy5jYWNoZVtwdWJsaWNLZXlVcmxdID0gY2VydGlmaWNhdGU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IGRlbGV0ZSB0aGlzLmNhY2hlW3B1YmxpY0tleVVybF0sIHBhcnNlSW50KGV4cGlyZVsxXSwgMTApICogMTAwMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNlcnRpZmljYXRlO1xuICB9XG5cbiAgdmVyaWZ5UHVibGljS2V5SXNzdWVyKGNlcnQsIHB1YmxpY0tleVVybCkge1xuICAgIGNvbnN0IHB1YmxpY0tleUNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpO1xuXG4gICAgaWYgKCF0aGlzLmNhLmNlcnQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgJ1Jvb3QgY2VydGlmaWNhdGUgaXMgaW52YWxpZCBvciBtaXNzaW5nLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNhLmNlcnQudmVyaWZ5KHB1YmxpY0tleUNlcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYEludmFsaWQgcHVibGljS2V5VXJsOiAke3B1YmxpY0tleVVybH1gKTtcbiAgICB9XG4gIH1cblxuICB2ZXJpZnlTaWduYXR1cmUocHVibGljS2V5LCBhdXRoRGF0YSkge1xuICAgIGNvbnN0IGJ1bmRsZUlkID0gdGhpcy5idW5kbGVJZCB8fCAodGhpcy5lbmFibGVJbnNlY3VyZUF1dGggJiYgYXV0aERhdGEuYnVuZGxlSWQpO1xuXG4gICAgY29uc3QgdmVyaWZpZXIgPSBjcnlwdG8uY3JlYXRlVmVyaWZ5KCdzaGEyNTYnKTtcbiAgICB2ZXJpZmllci51cGRhdGUoQnVmZmVyLmZyb20oYXV0aERhdGEuaWQsICd1dGY4JykpO1xuICAgIHZlcmlmaWVyLnVwZGF0ZShCdWZmZXIuZnJvbShidW5kbGVJZCwgJ3V0ZjgnKSk7XG4gICAgdmVyaWZpZXIudXBkYXRlKHRoaXMuY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKGF1dGhEYXRhLnRpbWVzdGFtcCkpO1xuICAgIHZlcmlmaWVyLnVwZGF0ZShCdWZmZXIuZnJvbShhdXRoRGF0YS5zYWx0LCAnYmFzZTY0JykpO1xuXG4gICAgaWYgKCF2ZXJpZmllci52ZXJpZnkocHVibGljS2V5LCBhdXRoRGF0YS5zaWduYXR1cmUsICdiYXNlNjQnKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHNpZ25hdHVyZS4nKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG5cbiAgICBjb25zdCByZXF1aXJlZEtleXMgPSBbJ2lkJywgJ3B1YmxpY0tleVVybCcsICd0aW1lc3RhbXAnLCAnc2lnbmF0dXJlJywgJ3NhbHQnXTtcbiAgICBpZiAodGhpcy5lbmFibGVJbnNlY3VyZUF1dGgpIHtcbiAgICAgIHJlcXVpcmVkS2V5cy5wdXNoKCdidW5kbGVJZCcpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIHJlcXVpcmVkS2V5cykge1xuICAgICAgaWYgKCFhdXRoRGF0YVtrZXldKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgQXV0aERhdGEgJHtrZXl9IGlzIG1pc3NpbmcuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5sb2FkaW5nUHJvbWlzZTtcblxuICAgIGNvbnN0IHB1YmxpY0tleSA9IGF3YWl0IHRoaXMuZ2V0QXBwbGVDZXJ0aWZpY2F0ZShhdXRoRGF0YS5wdWJsaWNLZXlVcmwpO1xuICAgIHRoaXMudmVyaWZ5U2lnbmF0dXJlKHB1YmxpY0tleSwgYXV0aERhdGEpO1xuICB9XG5cbiAgY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKHRpbWVzdGFtcCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyg4KTtcbiAgICBidWZmZXIud3JpdGVCaWdVSW50NjRCRShCaWdJbnQodGltZXN0YW1wKSk7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgR2FtZUNlbnRlckF1dGgoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBOEVBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFVBQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLFlBQUEsR0FBQUgsc0JBQUEsQ0FBQUMsT0FBQTtBQUF3QyxTQUFBRCx1QkFBQUksQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQWhGeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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