@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.
- package/LICENSE +176 -0
- package/NOTICE +10 -0
- package/README.md +1311 -0
- package/bin/parse-live-query-server +3 -0
- package/bin/parse-server +3 -0
- package/lib/AccountLockout.js +149 -0
- package/lib/Adapters/AdapterLoader.js +60 -0
- package/lib/Adapters/Analytics/AnalyticsAdapter.js +32 -0
- package/lib/Adapters/Auth/AuthAdapter.js +132 -0
- package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +119 -0
- package/lib/Adapters/Auth/OAuth1Client.js +204 -0
- package/lib/Adapters/Auth/apple.js +125 -0
- package/lib/Adapters/Auth/facebook.js +187 -0
- package/lib/Adapters/Auth/gcenter.js +217 -0
- package/lib/Adapters/Auth/github.js +125 -0
- package/lib/Adapters/Auth/google.js +122 -0
- package/lib/Adapters/Auth/gpgames.js +125 -0
- package/lib/Adapters/Auth/httpsRequest.js +41 -0
- package/lib/Adapters/Auth/index.js +248 -0
- package/lib/Adapters/Auth/instagram.js +118 -0
- package/lib/Adapters/Auth/janraincapture.js +85 -0
- package/lib/Adapters/Auth/janrainengage.js +57 -0
- package/lib/Adapters/Auth/keycloak.js +168 -0
- package/lib/Adapters/Auth/ldap.js +193 -0
- package/lib/Adapters/Auth/line.js +125 -0
- package/lib/Adapters/Auth/linkedin.js +117 -0
- package/lib/Adapters/Auth/meetup.js +44 -0
- package/lib/Adapters/Auth/mfa.js +334 -0
- package/lib/Adapters/Auth/microsoft.js +111 -0
- package/lib/Adapters/Auth/oauth2.js +115 -0
- package/lib/Adapters/Auth/phantauth.js +53 -0
- package/lib/Adapters/Auth/qq.js +113 -0
- package/lib/Adapters/Auth/spotify.js +115 -0
- package/lib/Adapters/Auth/twitter.js +197 -0
- package/lib/Adapters/Auth/utils.js +28 -0
- package/lib/Adapters/Auth/vkontakte.js +55 -0
- package/lib/Adapters/Auth/wechat.js +110 -0
- package/lib/Adapters/Auth/weibo.js +141 -0
- package/lib/Adapters/Cache/CacheAdapter.js +40 -0
- package/lib/Adapters/Cache/InMemoryCache.js +61 -0
- package/lib/Adapters/Cache/InMemoryCacheAdapter.js +34 -0
- package/lib/Adapters/Cache/LRUCache.js +35 -0
- package/lib/Adapters/Cache/NullCacheAdapter.js +26 -0
- package/lib/Adapters/Cache/RedisCacheAdapter.js +109 -0
- package/lib/Adapters/Cache/SchemaCache.js +25 -0
- package/lib/Adapters/Email/MailAdapter.js +32 -0
- package/lib/Adapters/Files/FilesAdapter.js +129 -0
- package/lib/Adapters/Files/GridFSBucketAdapter.js +280 -0
- package/lib/Adapters/Files/GridStoreAdapter.js +5 -0
- package/lib/Adapters/Logger/LoggerAdapter.js +27 -0
- package/lib/Adapters/Logger/WinstonLogger.js +107 -0
- package/lib/Adapters/Logger/WinstonLoggerAdapter.js +63 -0
- package/lib/Adapters/MessageQueue/EventEmitterMQ.js +55 -0
- package/lib/Adapters/PubSub/EventEmitterPubSub.js +53 -0
- package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
- package/lib/Adapters/PubSub/RedisPubSub.js +49 -0
- package/lib/Adapters/Push/PushAdapter.js +40 -0
- package/lib/Adapters/Storage/Mongo/MongoCollection.js +212 -0
- package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +334 -0
- package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +1047 -0
- package/lib/Adapters/Storage/Mongo/MongoTransform.js +1397 -0
- package/lib/Adapters/Storage/Postgres/PostgresClient.js +38 -0
- package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +73 -0
- package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +2409 -0
- package/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/array/add.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql +14 -0
- package/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql +14 -0
- package/lib/Adapters/Storage/Postgres/sql/array/contains.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/array/remove.sql +11 -0
- package/lib/Adapters/Storage/Postgres/sql/index.js +32 -0
- package/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql +19 -0
- package/lib/Adapters/Storage/StorageAdapter.js +2 -0
- package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
- package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
- package/lib/Auth.js +687 -0
- package/lib/AuthDataLock.js +53 -0
- package/lib/ClientSDK.js +39 -0
- package/lib/Config.js +879 -0
- package/lib/Controllers/AdaptableController.js +72 -0
- package/lib/Controllers/AnalyticsController.js +43 -0
- package/lib/Controllers/CacheController.js +71 -0
- package/lib/Controllers/DatabaseController.js +1685 -0
- package/lib/Controllers/FilesController.js +122 -0
- package/lib/Controllers/HooksController.js +254 -0
- package/lib/Controllers/LiveQueryController.js +72 -0
- package/lib/Controllers/LoggerController.js +222 -0
- package/lib/Controllers/ParseGraphQLController.js +294 -0
- package/lib/Controllers/PushController.js +224 -0
- package/lib/Controllers/SchemaController.js +1563 -0
- package/lib/Controllers/UserController.js +364 -0
- package/lib/Controllers/index.js +251 -0
- package/lib/Controllers/types.js +2 -0
- package/lib/Deprecator/Deprecations.js +100 -0
- package/lib/Deprecator/Deprecator.js +140 -0
- package/lib/Error.js +50 -0
- package/lib/FileUrlValidator.js +69 -0
- package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
- package/lib/GraphQL/ParseGraphQLServer.js +241 -0
- package/lib/GraphQL/helpers/objectsMutations.js +30 -0
- package/lib/GraphQL/helpers/objectsQueries.js +246 -0
- package/lib/GraphQL/helpers/queryComplexity.js +138 -0
- package/lib/GraphQL/loaders/configMutations.js +87 -0
- package/lib/GraphQL/loaders/configQueries.js +79 -0
- package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
- package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
- package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1099 -0
- package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
- package/lib/GraphQL/loaders/filesMutations.js +107 -0
- package/lib/GraphQL/loaders/functionsMutations.js +77 -0
- package/lib/GraphQL/loaders/parseClassMutations.js +267 -0
- package/lib/GraphQL/loaders/parseClassQueries.js +126 -0
- package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
- package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
- package/lib/GraphQL/loaders/schemaMutations.js +161 -0
- package/lib/GraphQL/loaders/schemaQueries.js +80 -0
- package/lib/GraphQL/loaders/schemaTypes.js +341 -0
- package/lib/GraphQL/loaders/usersMutations.js +433 -0
- package/lib/GraphQL/loaders/usersQueries.js +90 -0
- package/lib/GraphQL/parseGraphQLUtils.js +71 -0
- package/lib/GraphQL/transformers/className.js +14 -0
- package/lib/GraphQL/transformers/constraintType.js +53 -0
- package/lib/GraphQL/transformers/inputType.js +51 -0
- package/lib/GraphQL/transformers/mutation.js +280 -0
- package/lib/GraphQL/transformers/outputType.js +51 -0
- package/lib/GraphQL/transformers/query.js +237 -0
- package/lib/GraphQL/transformers/schemaFields.js +99 -0
- package/lib/InstallationDedup.js +178 -0
- package/lib/KeyPromiseQueue.js +48 -0
- package/lib/LiveQuery/Client.js +90 -0
- package/lib/LiveQuery/Id.js +20 -0
- package/lib/LiveQuery/ParseCloudCodePublisher.js +54 -0
- package/lib/LiveQuery/ParseLiveQueryServer.js +1071 -0
- package/lib/LiveQuery/ParsePubSub.js +37 -0
- package/lib/LiveQuery/ParseWebSocketServer.js +66 -0
- package/lib/LiveQuery/QueryTools.js +443 -0
- package/lib/LiveQuery/RequestSchema.js +161 -0
- package/lib/LiveQuery/SessionTokenCache.js +51 -0
- package/lib/LiveQuery/Subscription.js +47 -0
- package/lib/LiveQuery/equalObjects.js +50 -0
- package/lib/Options/Definitions.js +1599 -0
- package/lib/Options/docs.js +389 -0
- package/lib/Options/index.js +12 -0
- package/lib/Options/parsers.js +89 -0
- package/lib/Page.js +44 -0
- package/lib/ParseMessageQueue.js +24 -0
- package/lib/ParseServer.js +632 -0
- package/lib/ParseServerRESTController.js +173 -0
- package/lib/PromiseRouter.js +208 -0
- package/lib/Push/PushQueue.js +67 -0
- package/lib/Push/PushWorker.js +101 -0
- package/lib/Push/utils.js +129 -0
- package/lib/RestQuery.js +1208 -0
- package/lib/RestWrite.js +1671 -0
- package/lib/Routers/AggregateRouter.js +150 -0
- package/lib/Routers/AnalyticsRouter.js +26 -0
- package/lib/Routers/AudiencesRouter.js +54 -0
- package/lib/Routers/ClassesRouter.js +191 -0
- package/lib/Routers/CloudCodeRouter.js +87 -0
- package/lib/Routers/FeaturesRouter.js +72 -0
- package/lib/Routers/FilesRouter.js +772 -0
- package/lib/Routers/FunctionsRouter.js +341 -0
- package/lib/Routers/GlobalConfigRouter.js +123 -0
- package/lib/Routers/GraphQLRouter.js +41 -0
- package/lib/Routers/HooksRouter.js +121 -0
- package/lib/Routers/IAPValidationRouter.js +113 -0
- package/lib/Routers/InstallationsRouter.js +46 -0
- package/lib/Routers/LogsRouter.js +57 -0
- package/lib/Routers/PagesRouter.js +676 -0
- package/lib/Routers/PurgeRouter.js +45 -0
- package/lib/Routers/PushRouter.js +75 -0
- package/lib/Routers/RolesRouter.js +33 -0
- package/lib/Routers/SchemasRouter.js +118 -0
- package/lib/Routers/SecurityRouter.js +34 -0
- package/lib/Routers/SessionsRouter.js +126 -0
- package/lib/Routers/UsersRouter.js +733 -0
- package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
- package/lib/SchemaMigrations/Migrations.js +30 -0
- package/lib/Security/Check.js +109 -0
- package/lib/Security/CheckGroup.js +44 -0
- package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
- package/lib/Security/CheckGroups/CheckGroupServerConfig.js +160 -0
- package/lib/Security/CheckGroups/CheckGroups.js +21 -0
- package/lib/Security/CheckRunner.js +213 -0
- package/lib/SharedRest.js +34 -0
- package/lib/StatusHandler.js +329 -0
- package/lib/TestUtils.js +87 -0
- package/lib/Utils.js +577 -0
- package/lib/batch.js +185 -0
- package/lib/cache.js +12 -0
- package/lib/cli/definitions/parse-live-query-server.js +9 -0
- package/lib/cli/definitions/parse-server.js +9 -0
- package/lib/cli/parse-live-query-server.js +14 -0
- package/lib/cli/parse-server.js +101 -0
- package/lib/cli/utils/commander.js +132 -0
- package/lib/cli/utils/runner.js +53 -0
- package/lib/cloud-code/Parse.Cloud.js +797 -0
- package/lib/cloud-code/Parse.Server.js +21 -0
- package/lib/cryptoUtils.js +54 -0
- package/lib/defaults.js +58 -0
- package/lib/deprecated.js +12 -0
- package/lib/index.js +89 -0
- package/lib/logger.js +40 -0
- package/lib/middlewares.js +810 -0
- package/lib/password.js +40 -0
- package/lib/request.js +175 -0
- package/lib/requiredParameter.js +11 -0
- package/lib/rest.js +264 -0
- package/lib/triggers.js +949 -0
- package/lib/vendor/README.md +8 -0
- package/lib/vendor/mongodbUrl.js +1012 -0
- package/package.json +172 -0
- package/postinstall.js +38 -0
- package/public/custom_json.html +17 -0
- package/public/custom_json.json +23 -0
- package/public/custom_page.html +15 -0
- package/public/de/email_verification_link_expired.html +24 -0
- package/public/de/email_verification_link_invalid.html +21 -0
- package/public/de/email_verification_send_fail.html +21 -0
- package/public/de/email_verification_send_success.html +19 -0
- package/public/de/email_verification_success.html +18 -0
- package/public/de/password_reset.html +65 -0
- package/public/de/password_reset_link_invalid.html +19 -0
- package/public/de/password_reset_success.html +18 -0
- package/public/de-AT/email_verification_link_expired.html +24 -0
- package/public/de-AT/email_verification_link_invalid.html +21 -0
- package/public/de-AT/email_verification_send_fail.html +21 -0
- package/public/de-AT/email_verification_send_success.html +19 -0
- package/public/de-AT/email_verification_success.html +18 -0
- package/public/de-AT/password_reset.html +65 -0
- package/public/de-AT/password_reset_link_invalid.html +19 -0
- package/public/de-AT/password_reset_success.html +18 -0
- package/public/email_verification_link_expired.html +24 -0
- package/public/email_verification_link_invalid.html +21 -0
- package/public/email_verification_send_fail.html +21 -0
- package/public/email_verification_send_success.html +19 -0
- package/public/email_verification_success.html +18 -0
- package/public/password_reset.html +65 -0
- package/public/password_reset_link_invalid.html +19 -0
- package/public/password_reset_success.html +18 -0
- package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
- package/types/@types/deepcopy/index.d.ts +5 -0
- package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
- package/types/Options/index.d.ts +320 -0
- package/types/ParseServer.d.ts +65 -0
- package/types/eslint.config.mjs +30 -0
- package/types/index.d.ts +21 -0
- package/types/logger.d.ts +2 -0
- package/types/tests.ts +44 -0
- package/types/tsconfig.json +24 -0
- package/views/choose_password +215 -0
package/lib/password.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Tools for encrypting and decrypting passwords.
|
|
4
|
+
// Basically promise-friendly wrappers for bcrypt.
|
|
5
|
+
var bcrypt = require('bcryptjs');
|
|
6
|
+
try {
|
|
7
|
+
const _bcrypt = require('@node-rs/bcrypt');
|
|
8
|
+
bcrypt = {
|
|
9
|
+
hash: _bcrypt.hash,
|
|
10
|
+
compare: _bcrypt.verify
|
|
11
|
+
};
|
|
12
|
+
} catch {
|
|
13
|
+
/* */
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Returns a promise for a hashed password string.
|
|
17
|
+
function hash(password) {
|
|
18
|
+
return bcrypt.hash(password, 10);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Returns a promise for whether this password compares to equal this
|
|
22
|
+
// hashed password.
|
|
23
|
+
function compare(password, hashedPassword) {
|
|
24
|
+
// Cannot bcrypt compare when one is undefined
|
|
25
|
+
if (!password || !hashedPassword) {
|
|
26
|
+
return Promise.resolve(false);
|
|
27
|
+
}
|
|
28
|
+
return bcrypt.compare(password, hashedPassword);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Pre-computed bcrypt hash (cost factor 10) used for timing normalization.
|
|
32
|
+
// The actual value is irrelevant; it ensures bcrypt.compare() runs with
|
|
33
|
+
// realistic cost even when no real password hash is available.
|
|
34
|
+
const dummyHash = '$2b$10$Wd1gvrMYPnQv5pHBbXCwCehxXmJSEzRqNON0ev98L6JJP5296S35i';
|
|
35
|
+
module.exports = {
|
|
36
|
+
hash: hash,
|
|
37
|
+
compare: compare,
|
|
38
|
+
dummyHash: dummyHash
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJiY3J5cHQiLCJyZXF1aXJlIiwiX2JjcnlwdCIsImhhc2giLCJjb21wYXJlIiwidmVyaWZ5IiwicGFzc3dvcmQiLCJoYXNoZWRQYXNzd29yZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiZHVtbXlIYXNoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXNzd29yZC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUb29scyBmb3IgZW5jcnlwdGluZyBhbmQgZGVjcnlwdGluZyBwYXNzd29yZHMuXG4vLyBCYXNpY2FsbHkgcHJvbWlzZS1mcmllbmRseSB3cmFwcGVycyBmb3IgYmNyeXB0LlxudmFyIGJjcnlwdCA9IHJlcXVpcmUoJ2JjcnlwdGpzJyk7XG5cbnRyeSB7XG4gIGNvbnN0IF9iY3J5cHQgPSByZXF1aXJlKCdAbm9kZS1ycy9iY3J5cHQnKTtcbiAgYmNyeXB0ID0ge1xuICAgIGhhc2g6IF9iY3J5cHQuaGFzaCxcbiAgICBjb21wYXJlOiBfYmNyeXB0LnZlcmlmeSxcbiAgfTtcbn0gY2F0Y2gge1xuICAvKiAqL1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSBoYXNoZWQgcGFzc3dvcmQgc3RyaW5nLlxuZnVuY3Rpb24gaGFzaChwYXNzd29yZCkge1xuICByZXR1cm4gYmNyeXB0Lmhhc2gocGFzc3dvcmQsIDEwKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgdGhpcyBwYXNzd29yZCBjb21wYXJlcyB0byBlcXVhbCB0aGlzXG4vLyBoYXNoZWQgcGFzc3dvcmQuXG5mdW5jdGlvbiBjb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCkge1xuICAvLyBDYW5ub3QgYmNyeXB0IGNvbXBhcmUgd2hlbiBvbmUgaXMgdW5kZWZpbmVkXG4gIGlmICghcGFzc3dvcmQgfHwgIWhhc2hlZFBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cbiAgcmV0dXJuIGJjcnlwdC5jb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG59XG5cbi8vIFByZS1jb21wdXRlZCBiY3J5cHQgaGFzaCAoY29zdCBmYWN0b3IgMTApIHVzZWQgZm9yIHRpbWluZyBub3JtYWxpemF0aW9uLlxuLy8gVGhlIGFjdHVhbCB2YWx1ZSBpcyBpcnJlbGV2YW50OyBpdCBlbnN1cmVzIGJjcnlwdC5jb21wYXJlKCkgcnVucyB3aXRoXG4vLyByZWFsaXN0aWMgY29zdCBldmVuIHdoZW4gbm8gcmVhbCBwYXNzd29yZCBoYXNoIGlzIGF2YWlsYWJsZS5cbmNvbnN0IGR1bW15SGFzaCA9ICckMmIkMTAkV2QxZ3ZyTVlQblF2NXBIQmJYQ3dDZWh4WG1KU0V6UnFOT04wZXY5OEw2SkpQNTI5NlMzNWknO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaGFzaDogaGFzaCxcbiAgY29tcGFyZTogY29tcGFyZSxcbiAgZHVtbXlIYXNoOiBkdW1teUhhc2gsXG59O1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQSxJQUFJQSxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxVQUFVLENBQUM7QUFFaEMsSUFBSTtFQUNGLE1BQU1DLE9BQU8sR0FBR0QsT0FBTyxDQUFDLGlCQUFpQixDQUFDO0VBQzFDRCxNQUFNLEdBQUc7SUFDUEcsSUFBSSxFQUFFRCxPQUFPLENBQUNDLElBQUk7SUFDbEJDLE9BQU8sRUFBRUYsT0FBTyxDQUFDRztFQUNuQixDQUFDO0FBQ0gsQ0FBQyxDQUFDLE1BQU07RUFDTjtBQUFBOztBQUdGO0FBQ0EsU0FBU0YsSUFBSUEsQ0FBQ0csUUFBUSxFQUFFO0VBQ3RCLE9BQU9OLE1BQU0sQ0FBQ0csSUFBSSxDQUFDRyxRQUFRLEVBQUUsRUFBRSxDQUFDO0FBQ2xDOztBQUVBO0FBQ0E7QUFDQSxTQUFTRixPQUFPQSxDQUFDRSxRQUFRLEVBQUVDLGNBQWMsRUFBRTtFQUN6QztFQUNBLElBQUksQ0FBQ0QsUUFBUSxJQUFJLENBQUNDLGNBQWMsRUFBRTtJQUNoQyxPQUFPQyxPQUFPLENBQUNDLE9BQU8sQ0FBQyxLQUFLLENBQUM7RUFDL0I7RUFDQSxPQUFPVCxNQUFNLENBQUNJLE9BQU8sQ0FBQ0UsUUFBUSxFQUFFQyxjQUFjLENBQUM7QUFDakQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTUcsU0FBUyxHQUFHLDhEQUE4RDtBQUVoRkMsTUFBTSxDQUFDQyxPQUFPLEdBQUc7RUFDZlQsSUFBSSxFQUFFQSxJQUFJO0VBQ1ZDLE9BQU8sRUFBRUEsT0FBTztFQUNoQk0sU0FBUyxFQUFFQTtBQUNiLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=
|
package/lib/request.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _querystring = _interopRequireDefault(require("querystring"));
|
|
4
|
+
var _logger = _interopRequireDefault(require("./logger"));
|
|
5
|
+
var _followRedirects = require("follow-redirects");
|
|
6
|
+
var _url = require("url");
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
class HTTPResponse {
|
|
9
|
+
constructor(response, body) {
|
|
10
|
+
let _text, _data;
|
|
11
|
+
this.status = response.statusCode;
|
|
12
|
+
this.headers = response.headers || {};
|
|
13
|
+
this.cookies = this.headers['set-cookie'];
|
|
14
|
+
if (typeof body == 'string') {
|
|
15
|
+
_text = body;
|
|
16
|
+
} else if (Buffer.isBuffer(body)) {
|
|
17
|
+
this.buffer = body;
|
|
18
|
+
} else if (typeof body == 'object') {
|
|
19
|
+
_data = body;
|
|
20
|
+
}
|
|
21
|
+
const getText = () => {
|
|
22
|
+
if (!_text && this.buffer) {
|
|
23
|
+
_text = this.buffer.toString('utf-8');
|
|
24
|
+
} else if (!_text && _data) {
|
|
25
|
+
_text = JSON.stringify(_data);
|
|
26
|
+
}
|
|
27
|
+
return _text;
|
|
28
|
+
};
|
|
29
|
+
const getData = () => {
|
|
30
|
+
if (!_data) {
|
|
31
|
+
try {
|
|
32
|
+
_data = JSON.parse(getText());
|
|
33
|
+
} catch {
|
|
34
|
+
/* */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return _data;
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(this, 'body', {
|
|
40
|
+
get: () => {
|
|
41
|
+
return body;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
Object.defineProperty(this, 'text', {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: getText
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(this, 'data', {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: getData
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const clients = {
|
|
55
|
+
'http:': _followRedirects.http,
|
|
56
|
+
'https:': _followRedirects.https
|
|
57
|
+
};
|
|
58
|
+
function makeCallback(resolve, reject) {
|
|
59
|
+
return function (response) {
|
|
60
|
+
const chunks = [];
|
|
61
|
+
response.on('data', chunk => {
|
|
62
|
+
chunks.push(chunk);
|
|
63
|
+
});
|
|
64
|
+
response.on('end', () => {
|
|
65
|
+
const body = Buffer.concat(chunks);
|
|
66
|
+
const httpResponse = new HTTPResponse(response, body);
|
|
67
|
+
|
|
68
|
+
// Consider <200 && >= 400 as errors
|
|
69
|
+
if (httpResponse.status < 200 || httpResponse.status >= 400) {
|
|
70
|
+
return reject(httpResponse);
|
|
71
|
+
} else {
|
|
72
|
+
return resolve(httpResponse);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
response.on('error', reject);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const encodeBody = function ({
|
|
79
|
+
body,
|
|
80
|
+
headers = {}
|
|
81
|
+
}) {
|
|
82
|
+
if (typeof body !== 'object') {
|
|
83
|
+
return {
|
|
84
|
+
body,
|
|
85
|
+
headers
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
var contentTypeKeys = Object.keys(headers).filter(key => {
|
|
89
|
+
return key.match(/content-type/i) != null;
|
|
90
|
+
});
|
|
91
|
+
if (contentTypeKeys.length == 0) {
|
|
92
|
+
// no content type
|
|
93
|
+
// As per https://parse.com/docs/cloudcode/guide#cloud-code-advanced-sending-a-post-request the default encoding is supposedly x-www-form-urlencoded
|
|
94
|
+
|
|
95
|
+
body = _querystring.default.stringify(body);
|
|
96
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
97
|
+
} else {
|
|
98
|
+
/* istanbul ignore next */
|
|
99
|
+
if (contentTypeKeys.length > 1) {
|
|
100
|
+
_logger.default.error('Parse.Cloud.httpRequest', 'multiple content-type headers are set.');
|
|
101
|
+
}
|
|
102
|
+
// There maybe many, we'll just take the 1st one
|
|
103
|
+
var contentType = contentTypeKeys[0];
|
|
104
|
+
if (headers[contentType].match(/application\/json/i)) {
|
|
105
|
+
body = JSON.stringify(body);
|
|
106
|
+
} else if (headers[contentType].match(/application\/x-www-form-urlencoded/i)) {
|
|
107
|
+
body = _querystring.default.stringify(body);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
body,
|
|
112
|
+
headers
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
function httpRequest(options) {
|
|
116
|
+
let url;
|
|
117
|
+
try {
|
|
118
|
+
url = (0, _url.parse)(options.url);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
return Promise.reject(e);
|
|
121
|
+
}
|
|
122
|
+
options = Object.assign(options, encodeBody(options));
|
|
123
|
+
// support params options
|
|
124
|
+
if (typeof options.params === 'object') {
|
|
125
|
+
options.qs = options.params;
|
|
126
|
+
} else if (typeof options.params === 'string') {
|
|
127
|
+
options.qs = _querystring.default.parse(options.params);
|
|
128
|
+
}
|
|
129
|
+
const client = clients[url.protocol];
|
|
130
|
+
if (!client) {
|
|
131
|
+
return Promise.reject(`Unsupported protocol ${url.protocol}`);
|
|
132
|
+
}
|
|
133
|
+
const requestOptions = {
|
|
134
|
+
method: options.method,
|
|
135
|
+
port: Number(url.port),
|
|
136
|
+
path: url.pathname,
|
|
137
|
+
hostname: url.hostname,
|
|
138
|
+
headers: options.headers,
|
|
139
|
+
encoding: null,
|
|
140
|
+
followRedirects: options.followRedirects === true
|
|
141
|
+
};
|
|
142
|
+
if (requestOptions.headers) {
|
|
143
|
+
Object.keys(requestOptions.headers).forEach(key => {
|
|
144
|
+
if (typeof requestOptions.headers[key] === 'undefined') {
|
|
145
|
+
delete requestOptions.headers[key];
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (url.search) {
|
|
150
|
+
options.qs = Object.assign({}, options.qs, _querystring.default.parse(url.query));
|
|
151
|
+
}
|
|
152
|
+
if (url.auth) {
|
|
153
|
+
requestOptions.auth = url.auth;
|
|
154
|
+
}
|
|
155
|
+
if (options.qs) {
|
|
156
|
+
requestOptions.path += `?${_querystring.default.stringify(options.qs)}`;
|
|
157
|
+
}
|
|
158
|
+
if (options.agent) {
|
|
159
|
+
requestOptions.agent = options.agent;
|
|
160
|
+
}
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
const req = client.request(requestOptions, makeCallback(resolve, reject, options));
|
|
163
|
+
if (options.body) {
|
|
164
|
+
req.write(options.body);
|
|
165
|
+
}
|
|
166
|
+
req.on('error', error => {
|
|
167
|
+
reject(error);
|
|
168
|
+
});
|
|
169
|
+
req.end();
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
module.exports = httpRequest;
|
|
173
|
+
module.exports.encodeBody = encodeBody;
|
|
174
|
+
module.exports.HTTPResponse = HTTPResponse;
|
|
175
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcXVlcnlzdHJpbmciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2dnZXIiLCJfZm9sbG93UmVkaXJlY3RzIiwiX3VybCIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsIkhUVFBSZXNwb25zZSIsImNvbnN0cnVjdG9yIiwicmVzcG9uc2UiLCJib2R5IiwiX3RleHQiLCJfZGF0YSIsInN0YXR1cyIsInN0YXR1c0NvZGUiLCJoZWFkZXJzIiwiY29va2llcyIsIkJ1ZmZlciIsImlzQnVmZmVyIiwiYnVmZmVyIiwiZ2V0VGV4dCIsInRvU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsImdldERhdGEiLCJwYXJzZSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0IiwiZW51bWVyYWJsZSIsImNsaWVudHMiLCJodHRwIiwiaHR0cHMiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0IiwiY2h1bmtzIiwib24iLCJjaHVuayIsInB1c2giLCJjb25jYXQiLCJodHRwUmVzcG9uc2UiLCJlbmNvZGVCb2R5IiwiY29udGVudFR5cGVLZXlzIiwia2V5cyIsImZpbHRlciIsImtleSIsIm1hdGNoIiwibGVuZ3RoIiwicXVlcnlzdHJpbmciLCJsb2ciLCJlcnJvciIsImNvbnRlbnRUeXBlIiwiaHR0cFJlcXVlc3QiLCJvcHRpb25zIiwidXJsIiwiUHJvbWlzZSIsImFzc2lnbiIsInBhcmFtcyIsInFzIiwiY2xpZW50IiwicHJvdG9jb2wiLCJyZXF1ZXN0T3B0aW9ucyIsIm1ldGhvZCIsInBvcnQiLCJOdW1iZXIiLCJwYXRoIiwicGF0aG5hbWUiLCJob3N0bmFtZSIsImVuY29kaW5nIiwiZm9sbG93UmVkaXJlY3RzIiwiZm9yRWFjaCIsInNlYXJjaCIsInF1ZXJ5IiwiYXV0aCIsImFnZW50IiwicmVxIiwicmVxdWVzdCIsIndyaXRlIiwiZW5kIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgbG9nIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCB7IGh0dHAsIGh0dHBzIH0gZnJvbSAnZm9sbG93LXJlZGlyZWN0cyc7XG5pbXBvcnQgeyBwYXJzZSB9IGZyb20gJ3VybCc7XG5cbmNsYXNzIEhUVFBSZXNwb25zZSB7XG4gIGNvbnN0cnVjdG9yKHJlc3BvbnNlLCBib2R5KSB7XG4gICAgbGV0IF90ZXh0LCBfZGF0YTtcbiAgICB0aGlzLnN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1c0NvZGU7XG4gICAgdGhpcy5oZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVycyB8fCB7fTtcbiAgICB0aGlzLmNvb2tpZXMgPSB0aGlzLmhlYWRlcnNbJ3NldC1jb29raWUnXTtcblxuICAgIGlmICh0eXBlb2YgYm9keSA9PSAnc3RyaW5nJykge1xuICAgICAgX3RleHQgPSBib2R5O1xuICAgIH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG4gICAgICB0aGlzLmJ1ZmZlciA9IGJvZHk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgYm9keSA9PSAnb2JqZWN0Jykge1xuICAgICAgX2RhdGEgPSBib2R5O1xuICAgIH1cblxuICAgIGNvbnN0IGdldFRleHQgPSAoKSA9PiB7XG4gICAgICBpZiAoIV90ZXh0ICYmIHRoaXMuYnVmZmVyKSB7XG4gICAgICAgIF90ZXh0ID0gdGhpcy5idWZmZXIudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICB9IGVsc2UgaWYgKCFfdGV4dCAmJiBfZGF0YSkge1xuICAgICAgICBfdGV4dCA9IEpTT04uc3RyaW5naWZ5KF9kYXRhKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBfdGV4dDtcbiAgICB9O1xuXG4gICAgY29uc3QgZ2V0RGF0YSA9ICgpID0+IHtcbiAgICAgIGlmICghX2RhdGEpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBfZGF0YSA9IEpTT04ucGFyc2UoZ2V0VGV4dCgpKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLyogKi9cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIF9kYXRhO1xuICAgIH07XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2JvZHknLCB7XG4gICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGJvZHk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0ZXh0Jywge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZ2V0VGV4dCxcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZGF0YScsIHtcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGdldERhdGEsXG4gICAgfSk7XG4gIH1cbn1cblxuY29uc3QgY2xpZW50cyA9IHtcbiAgJ2h0dHA6JzogaHR0cCxcbiAgJ2h0dHBzOic6IGh0dHBzLFxufTtcblxuZnVuY3Rpb24gbWFrZUNhbGxiYWNrKHJlc29sdmUsIHJlamVjdCkge1xuICByZXR1cm4gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgY29uc3QgY2h1bmtzID0gW107XG4gICAgcmVzcG9uc2Uub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICBjaHVua3MucHVzaChjaHVuayk7XG4gICAgfSk7XG4gICAgcmVzcG9uc2Uub24oJ2VuZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJvZHkgPSBCdWZmZXIuY29uY2F0KGNodW5rcyk7XG4gICAgICBjb25zdCBodHRwUmVzcG9uc2UgPSBuZXcgSFRUUFJlc3BvbnNlKHJlc3BvbnNlLCBib2R5KTtcblxuICAgICAgLy8gQ29uc2lkZXIgPDIwMCAmJiA+PSA0MDAgYXMgZXJyb3JzXG4gICAgICBpZiAoaHR0cFJlc3BvbnNlLnN0YXR1cyA8IDIwMCB8fCBodHRwUmVzcG9uc2Uuc3RhdHVzID49IDQwMCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KGh0dHBSZXNwb25zZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShodHRwUmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJlc3BvbnNlLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gIH07XG59XG5cbmNvbnN0IGVuY29kZUJvZHkgPSBmdW5jdGlvbiAoeyBib2R5LCBoZWFkZXJzID0ge30gfSkge1xuICBpZiAodHlwZW9mIGJvZHkgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHsgYm9keSwgaGVhZGVycyB9O1xuICB9XG4gIHZhciBjb250ZW50VHlwZUtleXMgPSBPYmplY3Qua2V5cyhoZWFkZXJzKS5maWx0ZXIoa2V5ID0+IHtcbiAgICByZXR1cm4ga2V5Lm1hdGNoKC9jb250ZW50LXR5cGUvaSkgIT0gbnVsbDtcbiAgfSk7XG5cbiAgaWYgKGNvbnRlbnRUeXBlS2V5cy5sZW5ndGggPT0gMCkge1xuICAgIC8vIG5vIGNvbnRlbnQgdHlwZVxuICAgIC8vICBBcyBwZXIgaHR0cHM6Ly9wYXJzZS5jb20vZG9jcy9jbG91ZGNvZGUvZ3VpZGUjY2xvdWQtY29kZS1hZHZhbmNlZC1zZW5kaW5nLWEtcG9zdC1yZXF1ZXN0IHRoZSBkZWZhdWx0IGVuY29kaW5nIGlzIHN1cHBvc2VkbHkgeC13d3ctZm9ybS11cmxlbmNvZGVkXG5cbiAgICBib2R5ID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KGJvZHkpO1xuICAgIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc7XG4gIH0gZWxzZSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoY29udGVudFR5cGVLZXlzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGxvZy5lcnJvcignUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3QnLCAnbXVsdGlwbGUgY29udGVudC10eXBlIGhlYWRlcnMgYXJlIHNldC4nKTtcbiAgICB9XG4gICAgLy8gVGhlcmUgbWF5YmUgbWFueSwgd2UnbGwganVzdCB0YWtlIHRoZSAxc3Qgb25lXG4gICAgdmFyIGNvbnRlbnRUeXBlID0gY29udGVudFR5cGVLZXlzWzBdO1xuICAgIGlmIChoZWFkZXJzW2NvbnRlbnRUeXBlXS5tYXRjaCgvYXBwbGljYXRpb25cXC9qc29uL2kpKSB7XG4gICAgICBib2R5ID0gSlNPTi5zdHJpbmdpZnkoYm9keSk7XG4gICAgfSBlbHNlIGlmIChoZWFkZXJzW2NvbnRlbnRUeXBlXS5tYXRjaCgvYXBwbGljYXRpb25cXC94LXd3dy1mb3JtLXVybGVuY29kZWQvaSkpIHtcbiAgICAgIGJvZHkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoYm9keSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IGJvZHksIGhlYWRlcnMgfTtcbn07XG5cbmZ1bmN0aW9uIGh0dHBSZXF1ZXN0KG9wdGlvbnMpIHtcbiAgbGV0IHVybDtcbiAgdHJ5IHtcbiAgICB1cmwgPSBwYXJzZShvcHRpb25zLnVybCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XG4gIH1cbiAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgZW5jb2RlQm9keShvcHRpb25zKSk7XG4gIC8vIHN1cHBvcnQgcGFyYW1zIG9wdGlvbnNcbiAgaWYgKHR5cGVvZiBvcHRpb25zLnBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zLnFzID0gb3B0aW9ucy5wYXJhbXM7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMucGFyYW1zID09PSAnc3RyaW5nJykge1xuICAgIG9wdGlvbnMucXMgPSBxdWVyeXN0cmluZy5wYXJzZShvcHRpb25zLnBhcmFtcyk7XG4gIH1cbiAgY29uc3QgY2xpZW50ID0gY2xpZW50c1t1cmwucHJvdG9jb2xdO1xuICBpZiAoIWNsaWVudCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJHt1cmwucHJvdG9jb2x9YCk7XG4gIH1cbiAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgbWV0aG9kOiBvcHRpb25zLm1ldGhvZCxcbiAgICBwb3J0OiBOdW1iZXIodXJsLnBvcnQpLFxuICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICBlbmNvZGluZzogbnVsbCxcbiAgICBmb2xsb3dSZWRpcmVjdHM6IG9wdGlvbnMuZm9sbG93UmVkaXJlY3RzID09PSB0cnVlLFxuICB9O1xuICBpZiAocmVxdWVzdE9wdGlvbnMuaGVhZGVycykge1xuICAgIE9iamVjdC5rZXlzKHJlcXVlc3RPcHRpb25zLmhlYWRlcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBkZWxldGUgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGlmICh1cmwuc2VhcmNoKSB7XG4gICAgb3B0aW9ucy5xcyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMucXMsIHF1ZXJ5c3RyaW5nLnBhcnNlKHVybC5xdWVyeSkpO1xuICB9XG4gIGlmICh1cmwuYXV0aCkge1xuICAgIHJlcXVlc3RPcHRpb25zLmF1dGggPSB1cmwuYXV0aDtcbiAgfVxuICBpZiAob3B0aW9ucy5xcykge1xuICAgIHJlcXVlc3RPcHRpb25zLnBhdGggKz0gYD8ke3F1ZXJ5c3RyaW5nLnN0cmluZ2lmeShvcHRpb25zLnFzKX1gO1xuICB9XG4gIGlmIChvcHRpb25zLmFnZW50KSB7XG4gICAgcmVxdWVzdE9wdGlvbnMuYWdlbnQgPSBvcHRpb25zLmFnZW50O1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gY2xpZW50LnJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG1ha2VDYWxsYmFjayhyZXNvbHZlLCByZWplY3QsIG9wdGlvbnMpKTtcbiAgICBpZiAob3B0aW9ucy5ib2R5KSB7XG4gICAgICByZXEud3JpdGUob3B0aW9ucy5ib2R5KTtcbiAgICB9XG4gICAgcmVxLm9uKCdlcnJvcicsIGVycm9yID0+IHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfSk7XG4gICAgcmVxLmVuZCgpO1xuICB9KTtcbn1cbm1vZHVsZS5leHBvcnRzID0gaHR0cFJlcXVlc3Q7XG5tb2R1bGUuZXhwb3J0cy5lbmNvZGVCb2R5ID0gZW5jb2RlQm9keTtcbm1vZHVsZS5leHBvcnRzLkhUVFBSZXNwb25zZSA9IEhUVFBSZXNwb25zZTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFBQSxZQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxnQkFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsSUFBQSxHQUFBSCxPQUFBO0FBQTRCLFNBQUFELHVCQUFBSyxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRTVCLE1BQU1HLFlBQVksQ0FBQztFQUNqQkMsV0FBV0EsQ0FBQ0MsUUFBUSxFQUFFQyxJQUFJLEVBQUU7SUFDMUIsSUFBSUMsS0FBSyxFQUFFQyxLQUFLO0lBQ2hCLElBQUksQ0FBQ0MsTUFBTSxHQUFHSixRQUFRLENBQUNLLFVBQVU7SUFDakMsSUFBSSxDQUFDQyxPQUFPLEdBQUdOLFFBQVEsQ0FBQ00sT0FBTyxJQUFJLENBQUMsQ0FBQztJQUNyQyxJQUFJLENBQUNDLE9BQU8sR0FBRyxJQUFJLENBQUNELE9BQU8sQ0FBQyxZQUFZLENBQUM7SUFFekMsSUFBSSxPQUFPTCxJQUFJLElBQUksUUFBUSxFQUFFO01BQzNCQyxLQUFLLEdBQUdELElBQUk7SUFD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
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _default = errorMessage => {
|
|
8
|
+
throw errorMessage;
|
|
9
|
+
};
|
|
10
|
+
exports.default = _default;
|
|
11
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJlcnJvck1lc3NhZ2UiLCJleHBvcnRzIiwiZGVmYXVsdCIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vc3JjL3JlcXVpcmVkUGFyYW1ldGVyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAZmxvdyAqL1xuZXhwb3J0IGRlZmF1bHQgKGVycm9yTWVzc2FnZTogc3RyaW5nKTogYW55ID0+IHtcbiAgdGhyb3cgZXJyb3JNZXNzYWdlO1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O2VBQ2dCQSxZQUFvQixJQUFVO0VBQzVDLE1BQU1BLFlBQVk7QUFDcEIsQ0FBQztBQUFBQyxPQUFBLENBQUFDLE9BQUEsR0FBQUMsUUFBQSIsImlnbm9yZUxpc3QiOltdfQ==
|
package/lib/rest.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// This file contains helpers for running operations in REST format.
|
|
4
|
+
// The goal is that handlers that explicitly handle an express route
|
|
5
|
+
// should just be shallow wrappers around things in this file, but
|
|
6
|
+
// these functions should not explicitly depend on the request
|
|
7
|
+
// object.
|
|
8
|
+
// This means that one of these handlers can support multiple
|
|
9
|
+
// routes. That's useful for the routes that do really similar
|
|
10
|
+
// things.
|
|
11
|
+
|
|
12
|
+
var Parse = require('parse/node').Parse;
|
|
13
|
+
var RestQuery = require('./RestQuery');
|
|
14
|
+
var RestWrite = require('./RestWrite');
|
|
15
|
+
var triggers = require('./triggers');
|
|
16
|
+
const Auth = require('./Auth');
|
|
17
|
+
const {
|
|
18
|
+
enforceRoleSecurity
|
|
19
|
+
} = require('./SharedRest');
|
|
20
|
+
const {
|
|
21
|
+
createSanitizedError
|
|
22
|
+
} = require('./Error');
|
|
23
|
+
function checkTriggers(className, config, types) {
|
|
24
|
+
return types.some(triggerType => {
|
|
25
|
+
return triggers.getTrigger(className, triggers.Types[triggerType], config.applicationId);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function checkLiveQuery(className, config) {
|
|
29
|
+
return config.liveQueryController && config.liveQueryController.hasLiveQuery(className);
|
|
30
|
+
}
|
|
31
|
+
async function runFindTriggers(config, auth, className, restWhere, restOptions, clientSDK, context, options = {}) {
|
|
32
|
+
const {
|
|
33
|
+
isGet
|
|
34
|
+
} = options;
|
|
35
|
+
if (restOptions && restOptions.explain && !auth.isMaster) {
|
|
36
|
+
const allowPublicExplain = config.databaseOptions?.allowPublicExplain ?? false;
|
|
37
|
+
if (!allowPublicExplain) {
|
|
38
|
+
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Using the explain query parameter requires the master key');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Run beforeFind trigger - may modify query or return objects directly
|
|
43
|
+
const result = await triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context, isGet);
|
|
44
|
+
restWhere = result.restWhere || restWhere;
|
|
45
|
+
restOptions = result.restOptions || restOptions;
|
|
46
|
+
|
|
47
|
+
// Short-circuit path: beforeFind returned objects directly
|
|
48
|
+
// Security risk: These objects may have been fetched with master privileges
|
|
49
|
+
if (result?.objects) {
|
|
50
|
+
const objectsFromBeforeFind = result.objects;
|
|
51
|
+
let objectsForAfterFind = objectsFromBeforeFind;
|
|
52
|
+
|
|
53
|
+
// Security check: Re-filter objects if not master to ensure ACL/CLP compliance
|
|
54
|
+
if (!auth?.isMaster && !auth?.isMaintenance) {
|
|
55
|
+
const ids = (Array.isArray(objectsFromBeforeFind) ? objectsFromBeforeFind : [objectsFromBeforeFind]).map(o => o && (o.id || o.objectId) || null).filter(Boolean);
|
|
56
|
+
|
|
57
|
+
// Objects without IDs are(normally) unsaved objects
|
|
58
|
+
// For unsaved objects, the ACL security does not apply, so no need to redo the query.
|
|
59
|
+
// For saved objects, we need to re-query to ensure proper ACL/CLP enforcement
|
|
60
|
+
if (ids.length > 0) {
|
|
61
|
+
const refilterWhere = isGet ? {
|
|
62
|
+
objectId: ids[0]
|
|
63
|
+
} : {
|
|
64
|
+
objectId: {
|
|
65
|
+
$in: ids
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Re-query with proper security: no triggers to avoid infinite loops
|
|
70
|
+
const refilterQuery = await RestQuery({
|
|
71
|
+
method: isGet ? RestQuery.Method.get : RestQuery.Method.find,
|
|
72
|
+
config,
|
|
73
|
+
auth,
|
|
74
|
+
className,
|
|
75
|
+
restWhere: refilterWhere,
|
|
76
|
+
restOptions,
|
|
77
|
+
clientSDK,
|
|
78
|
+
context,
|
|
79
|
+
runBeforeFind: false,
|
|
80
|
+
runAfterFind: false
|
|
81
|
+
});
|
|
82
|
+
const refiltered = await refilterQuery.execute();
|
|
83
|
+
objectsForAfterFind = refiltered && refiltered.results || [];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Run afterFind trigger on security-filtered objects
|
|
88
|
+
const afterFindProcessedObjects = await triggers.maybeRunAfterFindTrigger(triggers.Types.afterFind, auth, className, objectsForAfterFind, config, new Parse.Query(className).withJSON({
|
|
89
|
+
where: restWhere,
|
|
90
|
+
...restOptions
|
|
91
|
+
}), context, isGet);
|
|
92
|
+
return {
|
|
93
|
+
results: afterFindProcessedObjects
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Normal path: execute database query with modified conditions
|
|
98
|
+
const query = await RestQuery({
|
|
99
|
+
method: isGet ? RestQuery.Method.get : RestQuery.Method.find,
|
|
100
|
+
config,
|
|
101
|
+
auth,
|
|
102
|
+
className,
|
|
103
|
+
restWhere,
|
|
104
|
+
restOptions,
|
|
105
|
+
clientSDK,
|
|
106
|
+
context,
|
|
107
|
+
runBeforeFind: false
|
|
108
|
+
});
|
|
109
|
+
return query.execute();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Returns a promise for an object with optional keys 'results' and 'count'.
|
|
113
|
+
const find = async (config, auth, className, restWhere, restOptions, clientSDK, context) => {
|
|
114
|
+
enforceRoleSecurity('find', className, auth, config);
|
|
115
|
+
return runFindTriggers(config, auth, className, restWhere, restOptions, clientSDK, context, {
|
|
116
|
+
isGet: false
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// get is just like find but only queries an objectId.
|
|
121
|
+
const get = async (config, auth, className, objectId, restOptions, clientSDK, context) => {
|
|
122
|
+
enforceRoleSecurity('get', className, auth, config);
|
|
123
|
+
return runFindTriggers(config, auth, className, {
|
|
124
|
+
objectId
|
|
125
|
+
}, restOptions, clientSDK, context, {
|
|
126
|
+
isGet: true
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Returns a promise that doesn't resolve to any useful value.
|
|
131
|
+
function del(config, auth, className, objectId, context) {
|
|
132
|
+
if (typeof objectId !== 'string') {
|
|
133
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad objectId');
|
|
134
|
+
}
|
|
135
|
+
if (className === '_User' && auth.isUnauthenticated()) {
|
|
136
|
+
throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth to delete user');
|
|
137
|
+
}
|
|
138
|
+
enforceRoleSecurity('delete', className, auth, config);
|
|
139
|
+
let inflatedObject;
|
|
140
|
+
let schemaController;
|
|
141
|
+
return Promise.resolve().then(async () => {
|
|
142
|
+
const hasTriggers = checkTriggers(className, config, ['beforeDelete', 'afterDelete']);
|
|
143
|
+
const hasLiveQuery = checkLiveQuery(className, config);
|
|
144
|
+
if (hasTriggers || hasLiveQuery || className == '_Session') {
|
|
145
|
+
const query = await RestQuery({
|
|
146
|
+
method: RestQuery.Method.get,
|
|
147
|
+
config,
|
|
148
|
+
auth,
|
|
149
|
+
className,
|
|
150
|
+
restWhere: {
|
|
151
|
+
objectId
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return query.execute({
|
|
155
|
+
op: 'delete'
|
|
156
|
+
}).then(response => {
|
|
157
|
+
if (response && response.results && response.results.length) {
|
|
158
|
+
const firstResult = response.results[0];
|
|
159
|
+
firstResult.className = className;
|
|
160
|
+
if (className === '_Session' && !auth.isMaster && !auth.isMaintenance) {
|
|
161
|
+
if (!auth.user || firstResult.user.objectId !== auth.user.id) {
|
|
162
|
+
throw createSanitizedError(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token', config);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
var cacheAdapter = config.cacheController;
|
|
166
|
+
cacheAdapter.user.del(firstResult.sessionToken);
|
|
167
|
+
inflatedObject = Parse.Object.fromJSON(firstResult);
|
|
168
|
+
return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config, context);
|
|
169
|
+
}
|
|
170
|
+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for delete.');
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return Promise.resolve({});
|
|
174
|
+
}).then(() => {
|
|
175
|
+
if (!auth.isMaster && !auth.isMaintenance) {
|
|
176
|
+
return auth.getUserRoles();
|
|
177
|
+
} else {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}).then(() => config.database.loadSchema()).then(s => {
|
|
181
|
+
schemaController = s;
|
|
182
|
+
const options = {};
|
|
183
|
+
if (!auth.isMaster && !auth.isMaintenance) {
|
|
184
|
+
options.acl = ['*'];
|
|
185
|
+
if (auth.user) {
|
|
186
|
+
options.acl.push(auth.user.id);
|
|
187
|
+
options.acl = options.acl.concat(auth.userRoles);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return config.database.destroy(className, {
|
|
191
|
+
objectId: objectId
|
|
192
|
+
}, options, schemaController);
|
|
193
|
+
}).then(() => {
|
|
194
|
+
// Notify LiveQuery server if possible
|
|
195
|
+
const perms = schemaController.getClassLevelPermissions(className);
|
|
196
|
+
config.liveQueryController.onAfterDelete(className, inflatedObject, null, perms);
|
|
197
|
+
return triggers.maybeRunTrigger(triggers.Types.afterDelete, auth, inflatedObject, null, config, context);
|
|
198
|
+
}).catch(error => {
|
|
199
|
+
handleSessionMissingError(error, className, auth, config);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Returns a promise for a {response, status, location} object.
|
|
204
|
+
function create(config, auth, className, restObject, clientSDK, context) {
|
|
205
|
+
enforceRoleSecurity('create', className, auth, config);
|
|
206
|
+
var write = new RestWrite(config, auth, className, null, restObject, null, clientSDK, context);
|
|
207
|
+
return write.execute();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Returns a promise that contains the fields of the update that the
|
|
211
|
+
// REST API is supposed to return.
|
|
212
|
+
// Usually, this is just updatedAt.
|
|
213
|
+
function update(config, auth, className, restWhere, restObject, clientSDK, context) {
|
|
214
|
+
enforceRoleSecurity('update', className, auth, config);
|
|
215
|
+
return Promise.resolve().then(async () => {
|
|
216
|
+
const hasTriggers = checkTriggers(className, config, ['beforeSave', 'afterSave']);
|
|
217
|
+
const hasLiveQuery = checkLiveQuery(className, config);
|
|
218
|
+
if (hasTriggers || hasLiveQuery) {
|
|
219
|
+
// Do not use find, as it runs the before finds
|
|
220
|
+
// Use master auth when protectedFieldsTriggerExempt is true to bypass
|
|
221
|
+
// protectedFields filtering, so triggers see the full original object
|
|
222
|
+
const queryAuth = config.protectedFieldsTriggerExempt ? Auth.master(config) : auth;
|
|
223
|
+
const query = await RestQuery({
|
|
224
|
+
method: RestQuery.Method.get,
|
|
225
|
+
config,
|
|
226
|
+
auth: queryAuth,
|
|
227
|
+
className,
|
|
228
|
+
restWhere,
|
|
229
|
+
runAfterFind: false,
|
|
230
|
+
runBeforeFind: false,
|
|
231
|
+
context
|
|
232
|
+
});
|
|
233
|
+
return query.execute({
|
|
234
|
+
op: 'update'
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return Promise.resolve({});
|
|
238
|
+
}).then(({
|
|
239
|
+
results
|
|
240
|
+
}) => {
|
|
241
|
+
var originalRestObject;
|
|
242
|
+
if (results && results.length) {
|
|
243
|
+
originalRestObject = results[0];
|
|
244
|
+
}
|
|
245
|
+
return new RestWrite(config, auth, className, restWhere, restObject, originalRestObject, clientSDK, context, 'update').execute();
|
|
246
|
+
}).catch(error => {
|
|
247
|
+
handleSessionMissingError(error, className, auth, config);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function handleSessionMissingError(error, className, auth, config) {
|
|
251
|
+
// If we're trying to update a user without / with bad session token
|
|
252
|
+
if (className === '_User' && error.code === Parse.Error.OBJECT_NOT_FOUND && !auth.isMaster && !auth.isMaintenance) {
|
|
253
|
+
throw createSanitizedError(Parse.Error.SESSION_MISSING, 'Insufficient auth.', config);
|
|
254
|
+
}
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
module.exports = {
|
|
258
|
+
create,
|
|
259
|
+
del,
|
|
260
|
+
find,
|
|
261
|
+
get,
|
|
262
|
+
update
|
|
263
|
+
};
|
|
264
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJSZXN0UXVlcnkiLCJSZXN0V3JpdGUiLCJ0cmlnZ2VycyIsIkF1dGgiLCJlbmZvcmNlUm9sZVNlY3VyaXR5IiwiY3JlYXRlU2FuaXRpemVkRXJyb3IiLCJjaGVja1RyaWdnZXJzIiwiY2xhc3NOYW1lIiwiY29uZmlnIiwidHlwZXMiLCJzb21lIiwidHJpZ2dlclR5cGUiLCJnZXRUcmlnZ2VyIiwiVHlwZXMiLCJhcHBsaWNhdGlvbklkIiwiY2hlY2tMaXZlUXVlcnkiLCJsaXZlUXVlcnlDb250cm9sbGVyIiwiaGFzTGl2ZVF1ZXJ5IiwicnVuRmluZFRyaWdnZXJzIiwiYXV0aCIsInJlc3RXaGVyZSIsInJlc3RPcHRpb25zIiwiY2xpZW50U0RLIiwiY29udGV4dCIsIm9wdGlvbnMiLCJpc0dldCIsImV4cGxhaW4iLCJpc01hc3RlciIsImFsbG93UHVibGljRXhwbGFpbiIsImRhdGFiYXNlT3B0aW9ucyIsIkVycm9yIiwiSU5WQUxJRF9RVUVSWSIsInJlc3VsdCIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwiYmVmb3JlRmluZCIsIm9iamVjdHMiLCJvYmplY3RzRnJvbUJlZm9yZUZpbmQiLCJvYmplY3RzRm9yQWZ0ZXJGaW5kIiwiaXNNYWludGVuYW5jZSIsImlkcyIsIkFycmF5IiwiaXNBcnJheSIsIm1hcCIsIm8iLCJpZCIsIm9iamVjdElkIiwiZmlsdGVyIiwiQm9vbGVhbiIsImxlbmd0aCIsInJlZmlsdGVyV2hlcmUiLCIkaW4iLCJyZWZpbHRlclF1ZXJ5IiwibWV0aG9kIiwiTWV0aG9kIiwiZ2V0IiwiZmluZCIsInJ1bkJlZm9yZUZpbmQiLCJydW5BZnRlckZpbmQiLCJyZWZpbHRlcmVkIiwiZXhlY3V0ZSIsInJlc3VsdHMiLCJhZnRlckZpbmRQcm9jZXNzZWRPYmplY3RzIiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwiYWZ0ZXJGaW5kIiwiUXVlcnkiLCJ3aXRoSlNPTiIsIndoZXJlIiwicXVlcnkiLCJkZWwiLCJJTlZBTElEX0pTT04iLCJpc1VuYXV0aGVudGljYXRlZCIsIlNFU1NJT05fTUlTU0lORyIsImluZmxhdGVkT2JqZWN0Iiwic2NoZW1hQ29udHJvbGxlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImhhc1RyaWdnZXJzIiwib3AiLCJyZXNwb25zZSIsImZpcnN0UmVzdWx0IiwidXNlciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsInNlc3Npb25Ub2tlbiIsIk9iamVjdCIsImZyb21KU09OIiwibWF5YmVSdW5UcmlnZ2VyIiwiYmVmb3JlRGVsZXRlIiwiT0JKRUNUX05PVF9GT1VORCIsImdldFVzZXJSb2xlcyIsImRhdGFiYXNlIiwibG9hZFNjaGVtYSIsInMiLCJhY2wiLCJwdXNoIiwiY29uY2F0IiwidXNlclJvbGVzIiwiZGVzdHJveSIsInBlcm1zIiwiZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwib25BZnRlckRlbGV0ZSIsImFmdGVyRGVsZXRlIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IiLCJjcmVhdGUiLCJyZXN0T2JqZWN0Iiwid3JpdGUiLCJ1cGRhdGUiLCJxdWVyeUF1dGgiLCJwcm90ZWN0ZWRGaWVsZHNUcmlnZ2VyRXhlbXB0IiwibWFzdGVyIiwib3JpZ2luYWxSZXN0T2JqZWN0IiwiY29kZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi9zcmMvcmVzdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGlzIGZpbGUgY29udGFpbnMgaGVscGVycyBmb3IgcnVubmluZyBvcGVyYXRpb25zIGluIFJFU1QgZm9ybWF0LlxuLy8gVGhlIGdvYWwgaXMgdGhhdCBoYW5kbGVycyB0aGF0IGV4cGxpY2l0bHkgaGFuZGxlIGFuIGV4cHJlc3Mgcm91dGVcbi8vIHNob3VsZCBqdXN0IGJlIHNoYWxsb3cgd3JhcHBlcnMgYXJvdW5kIHRoaW5ncyBpbiB0aGlzIGZpbGUsIGJ1dFxuLy8gdGhlc2UgZnVuY3Rpb25zIHNob3VsZCBub3QgZXhwbGljaXRseSBkZXBlbmQgb24gdGhlIHJlcXVlc3Rcbi8vIG9iamVjdC5cbi8vIFRoaXMgbWVhbnMgdGhhdCBvbmUgb2YgdGhlc2UgaGFuZGxlcnMgY2FuIHN1cHBvcnQgbXVsdGlwbGVcbi8vIHJvdXRlcy4gVGhhdCdzIHVzZWZ1bCBmb3IgdGhlIHJvdXRlcyB0aGF0IGRvIHJlYWxseSBzaW1pbGFyXG4vLyB0aGluZ3MuXG5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxudmFyIFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4vUmVzdFF1ZXJ5Jyk7XG52YXIgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcbnZhciB0cmlnZ2VycyA9IHJlcXVpcmUoJy4vdHJpZ2dlcnMnKTtcbmNvbnN0IEF1dGggPSByZXF1aXJlKCcuL0F1dGgnKTtcbmNvbnN0IHsgZW5mb3JjZVJvbGVTZWN1cml0eSB9ID0gcmVxdWlyZSgnLi9TaGFyZWRSZXN0Jyk7XG5jb25zdCB7IGNyZWF0ZVNhbml0aXplZEVycm9yIH0gPSByZXF1aXJlKCcuL0Vycm9yJyk7XG5cbmZ1bmN0aW9uIGNoZWNrVHJpZ2dlcnMoY2xhc3NOYW1lLCBjb25maWcsIHR5cGVzKSB7XG4gIHJldHVybiB0eXBlcy5zb21lKHRyaWdnZXJUeXBlID0+IHtcbiAgICByZXR1cm4gdHJpZ2dlcnMuZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJzLlR5cGVzW3RyaWdnZXJUeXBlXSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY2hlY2tMaXZlUXVlcnkoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgcmV0dXJuIGNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyICYmIGNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLmhhc0xpdmVRdWVyeShjbGFzc05hbWUpO1xufVxuYXN5bmMgZnVuY3Rpb24gcnVuRmluZFRyaWdnZXJzKFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGNsYXNzTmFtZSxcbiAgcmVzdFdoZXJlLFxuICByZXN0T3B0aW9ucyxcbiAgY2xpZW50U0RLLFxuICBjb250ZXh0LFxuICBvcHRpb25zID0ge31cbikge1xuICBjb25zdCB7IGlzR2V0IH0gPSBvcHRpb25zO1xuXG4gIGlmIChyZXN0T3B0aW9ucyAmJiByZXN0T3B0aW9ucy5leHBsYWluICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgYWxsb3dQdWJsaWNFeHBsYWluID0gY29uZmlnLmRhdGFiYXNlT3B0aW9ucz8uYWxsb3dQdWJsaWNFeHBsYWluID8/IGZhbHNlO1xuXG4gICAgaWYgKCFhbGxvd1B1YmxpY0V4cGxhaW4pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgJ1VzaW5nIHRoZSBleHBsYWluIHF1ZXJ5IHBhcmFtZXRlciByZXF1aXJlcyB0aGUgbWFzdGVyIGtleSdcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gUnVuIGJlZm9yZUZpbmQgdHJpZ2dlciAtIG1heSBtb2RpZnkgcXVlcnkgb3IgcmV0dXJuIG9iamVjdHMgZGlyZWN0bHlcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5RdWVyeVRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRmluZCxcbiAgICBjbGFzc05hbWUsXG4gICAgcmVzdFdoZXJlLFxuICAgIHJlc3RPcHRpb25zLFxuICAgIGNvbmZpZyxcbiAgICBhdXRoLFxuICAgIGNvbnRleHQsXG4gICAgaXNHZXRcbiAgKTtcblxuICByZXN0V2hlcmUgPSByZXN1bHQucmVzdFdoZXJlIHx8IHJlc3RXaGVyZTtcbiAgcmVzdE9wdGlvbnMgPSByZXN1bHQucmVzdE9wdGlvbnMgfHwgcmVzdE9wdGlvbnM7XG5cbiAgLy8gU2hvcnQtY2lyY3VpdCBwYXRoOiBiZWZvcmVGaW5kIHJldHVybmVkIG9iamVjdHMgZGlyZWN0bHlcbiAgLy8gU2VjdXJpdHkgcmlzazogVGhlc2Ugb2JqZWN0cyBtYXkgaGF2ZSBiZWVuIGZldGNoZWQgd2l0aCBtYXN0ZXIgcHJpdmlsZWdlc1xuICBpZiAocmVzdWx0Py5vYmplY3RzKSB7XG4gICAgY29uc3Qgb2JqZWN0c0Zyb21CZWZvcmVGaW5kID0gcmVzdWx0Lm9iamVjdHM7XG5cbiAgICBsZXQgb2JqZWN0c0ZvckFmdGVyRmluZCA9IG9iamVjdHNGcm9tQmVmb3JlRmluZDtcblxuICAgIC8vIFNlY3VyaXR5IGNoZWNrOiBSZS1maWx0ZXIgb2JqZWN0cyBpZiBub3QgbWFzdGVyIHRvIGVuc3VyZSBBQ0wvQ0xQIGNvbXBsaWFuY2VcbiAgICBpZiAoIWF1dGg/LmlzTWFzdGVyICYmICFhdXRoPy5pc01haW50ZW5hbmNlKSB7XG4gICAgICBjb25zdCBpZHMgPSAoQXJyYXkuaXNBcnJheShvYmplY3RzRnJvbUJlZm9yZUZpbmQpID8gb2JqZWN0c0Zyb21CZWZvcmVGaW5kIDogW29iamVjdHNGcm9tQmVmb3JlRmluZF0pXG4gICAgICAgIC5tYXAobyA9PiAobyAmJiAoby5pZCB8fCBvLm9iamVjdElkKSkgfHwgbnVsbClcbiAgICAgICAgLmZpbHRlcihCb29sZWFuKTtcblxuICAgICAgLy8gT2JqZWN0cyB3aXRob3V0IElEcyBhcmUobm9ybWFsbHkpIHVuc2F2ZWQgb2JqZWN0c1xuICAgICAgLy8gRm9yIHVuc2F2ZWQgb2JqZWN0cywgdGhlIEFDTCBzZWN1cml0eSBkb2VzIG5vdCBhcHBseSwgc28gbm8gbmVlZCB0byByZWRvIHRoZSBxdWVyeS5cbiAgICAgIC8vIEZvciBzYXZlZCBvYmplY3RzLCB3ZSBuZWVkIHRvIHJlLXF1ZXJ5IHRvIGVuc3VyZSBwcm9wZXIgQUNML0NMUCBlbmZvcmNlbWVudFxuICAgICAgaWYgKGlkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHJlZmlsdGVyV2hlcmUgPSBpc0dldCA/IHsgb2JqZWN0SWQ6IGlkc1swXSB9IDogeyBvYmplY3RJZDogeyAkaW46IGlkcyB9IH07XG5cbiAgICAgICAgLy8gUmUtcXVlcnkgd2l0aCBwcm9wZXIgc2VjdXJpdHk6IG5vIHRyaWdnZXJzIHRvIGF2b2lkIGluZmluaXRlIGxvb3BzXG4gICAgICAgIGNvbnN0IHJlZmlsdGVyUXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgICAgICAgIG1ldGhvZDogaXNHZXQgPyBSZXN0UXVlcnkuTWV0aG9kLmdldCA6IFJlc3RRdWVyeS5NZXRob2QuZmluZCxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgcmVzdFdoZXJlOiByZWZpbHRlcldoZXJlLFxuICAgICAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgICAgIGNsaWVudFNESyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICAgICAgICAgIHJ1bkFmdGVyRmluZDogZmFsc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlZmlsdGVyZWQgPSBhd2FpdCByZWZpbHRlclF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICAgICAgb2JqZWN0c0ZvckFmdGVyRmluZCA9IChyZWZpbHRlcmVkICYmIHJlZmlsdGVyZWQucmVzdWx0cykgfHwgW107XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUnVuIGFmdGVyRmluZCB0cmlnZ2VyIG9uIHNlY3VyaXR5LWZpbHRlcmVkIG9iamVjdHNcbiAgICBjb25zdCBhZnRlckZpbmRQcm9jZXNzZWRPYmplY3RzID0gYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJGaW5kLFxuICAgICAgYXV0aCxcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIG9iamVjdHNGb3JBZnRlckZpbmQsXG4gICAgICBjb25maWcsXG4gICAgICBuZXcgUGFyc2UuUXVlcnkoY2xhc3NOYW1lKS53aXRoSlNPTih7IHdoZXJlOiByZXN0V2hlcmUsIC4uLnJlc3RPcHRpb25zIH0pLFxuICAgICAgY29udGV4dCxcbiAgICAgIGlzR2V0XG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZXN1bHRzOiBhZnRlckZpbmRQcm9jZXNzZWRPYmplY3RzLFxuICAgIH07XG4gIH1cblxuICAvLyBOb3JtYWwgcGF0aDogZXhlY3V0ZSBkYXRhYmFzZSBxdWVyeSB3aXRoIG1vZGlmaWVkIGNvbmRpdGlvbnNcbiAgY29uc3QgcXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgIG1ldGhvZDogaXNHZXQgPyBSZXN0UXVlcnkuTWV0aG9kLmdldCA6IFJlc3RRdWVyeS5NZXRob2QuZmluZCxcbiAgICBjb25maWcsXG4gICAgYXV0aCxcbiAgICBjbGFzc05hbWUsXG4gICAgcmVzdFdoZXJlLFxuICAgIHJlc3RPcHRpb25zLFxuICAgIGNsaWVudFNESyxcbiAgICBjb250ZXh0LFxuICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICB9KTtcblxuICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYW4gb2JqZWN0IHdpdGggb3B0aW9uYWwga2V5cyAncmVzdWx0cycgYW5kICdjb3VudCcuXG5jb25zdCBmaW5kID0gYXN5bmMgKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREssIGNvbnRleHQpID0+IHtcbiAgZW5mb3JjZVJvbGVTZWN1cml0eSgnZmluZCcsIGNsYXNzTmFtZSwgYXV0aCwgY29uZmlnKTtcbiAgcmV0dXJuIHJ1bkZpbmRUcmlnZ2VycyhcbiAgICBjb25maWcsXG4gICAgYXV0aCxcbiAgICBjbGFzc05hbWUsXG4gICAgcmVzdFdoZXJlLFxuICAgIHJlc3RPcHRpb25zLFxuICAgIGNsaWVudFNESyxcbiAgICBjb250ZXh0LFxuICAgIHsgaXNHZXQ6IGZhbHNlIH1cbiAgKTtcbn07XG5cbi8vIGdldCBpcyBqdXN0IGxpa2UgZmluZCBidXQgb25seSBxdWVyaWVzIGFuIG9iamVjdElkLlxuY29uc3QgZ2V0ID0gYXN5bmMgKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCBvYmplY3RJZCwgcmVzdE9wdGlvbnMsIGNsaWVudFNESywgY29udGV4dCkgPT4ge1xuICBlbmZvcmNlUm9sZVNlY3VyaXR5KCdnZXQnLCBjbGFzc05hbWUsIGF1dGgsIGNvbmZpZyk7XG4gIHJldHVybiBydW5GaW5kVHJpZ2dlcnMoXG4gICAgY29uZmlnLFxuICAgIGF1dGgsXG4gICAgY2xhc3NOYW1lLFxuICAgIHsgb2JqZWN0SWQgfSxcbiAgICByZXN0T3B0aW9ucyxcbiAgICBjbGllbnRTREssXG4gICAgY29udGV4dCxcbiAgICB7IGlzR2V0OiB0cnVlIH1cbiAgKTtcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZG9lc24ndCByZXNvbHZlIHRvIGFueSB1c2VmdWwgdmFsdWUuXG5mdW5jdGlvbiBkZWwoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdElkLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2Ygb2JqZWN0SWQgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCBvYmplY3RJZCcpO1xuICB9XG5cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJiBhdXRoLmlzVW5hdXRoZW50aWNhdGVkKCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuU0VTU0lPTl9NSVNTSU5HLCAnSW5zdWZmaWNpZW50IGF1dGggdG8gZGVsZXRlIHVzZXInKTtcbiAgfVxuXG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2RlbGV0ZScsIGNsYXNzTmFtZSwgYXV0aCwgY29uZmlnKTtcblxuICBsZXQgaW5mbGF0ZWRPYmplY3Q7XG4gIGxldCBzY2hlbWFDb250cm9sbGVyO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGhhc1RyaWdnZXJzID0gY2hlY2tUcmlnZ2VycyhjbGFzc05hbWUsIGNvbmZpZywgWydiZWZvcmVEZWxldGUnLCAnYWZ0ZXJEZWxldGUnXSk7XG4gICAgICBjb25zdCBoYXNMaXZlUXVlcnkgPSBjaGVja0xpdmVRdWVyeShjbGFzc05hbWUsIGNvbmZpZyk7XG4gICAgICBpZiAoaGFzVHJpZ2dlcnMgfHwgaGFzTGl2ZVF1ZXJ5IHx8IGNsYXNzTmFtZSA9PSAnX1Nlc3Npb24nKSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gYXdhaXQgUmVzdFF1ZXJ5KHtcbiAgICAgICAgICBtZXRob2Q6IFJlc3RRdWVyeS5NZXRob2QuZ2V0LFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICByZXN0V2hlcmU6IHsgb2JqZWN0SWQgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBxdWVyeS5leGVjdXRlKHsgb3A6ICdkZWxldGUnIH0pLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5yZXN1bHRzICYmIHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdFJlc3VsdCA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG4gICAgICAgICAgICBmaXJzdFJlc3VsdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09PSAnX1Nlc3Npb24nICYmICFhdXRoLmlzTWFzdGVyICYmICFhdXRoLmlzTWFpbnRlbmFuY2UpIHtcbiAgICAgICAgICAgICAgaWYgKCFhdXRoLnVzZXIgfHwgZmlyc3RSZXN1bHQudXNlci5vYmplY3RJZCAhPT0gYXV0aC51c2VyLmlkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlU2FuaXRpemVkRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJywgY29uZmlnKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNhY2hlQWRhcHRlciA9IGNvbmZpZy5jYWNoZUNvbnRyb2xsZXI7XG4gICAgICAgICAgICBjYWNoZUFkYXB0ZXIudXNlci5kZWwoZmlyc3RSZXN1bHQuc2Vzc2lvblRva2VuKTtcbiAgICAgICAgICAgIGluZmxhdGVkT2JqZWN0ID0gUGFyc2UuT2JqZWN0LmZyb21KU09OKGZpcnN0UmVzdWx0KTtcbiAgICAgICAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgICAgICAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZURlbGV0ZSxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbGF0ZWRPYmplY3QsXG4gICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgY29udGV4dFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kIGZvciBkZWxldGUuJyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICBpZiAoIWF1dGguaXNNYXN0ZXIgJiYgIWF1dGguaXNNYWludGVuYW5jZSkge1xuICAgICAgICByZXR1cm4gYXV0aC5nZXRVc2VyUm9sZXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9KVxuICAgIC50aGVuKCgpID0+IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKCkpXG4gICAgLnRoZW4ocyA9PiB7XG4gICAgICBzY2hlbWFDb250cm9sbGVyID0gcztcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICAgIGlmICghYXV0aC5pc01hc3RlciAmJiAhYXV0aC5pc01haW50ZW5hbmNlKSB7XG4gICAgICAgIG9wdGlvbnMuYWNsID0gWycqJ107XG4gICAgICAgIGlmIChhdXRoLnVzZXIpIHtcbiAgICAgICAgICBvcHRpb25zLmFjbC5wdXNoKGF1dGgudXNlci5pZCk7XG4gICAgICAgICAgb3B0aW9ucy5hY2wgPSBvcHRpb25zLmFjbC5jb25jYXQoYXV0aC51c2VyUm9sZXMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuZGVzdHJveShcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICB7XG4gICAgICAgICAgb2JqZWN0SWQ6IG9iamVjdElkLFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICBzY2hlbWFDb250cm9sbGVyXG4gICAgICApO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gTm90aWZ5IExpdmVRdWVyeSBzZXJ2ZXIgaWYgcG9zc2libGVcbiAgICAgIGNvbnN0IHBlcm1zID0gc2NoZW1hQ29udHJvbGxlci5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgICAgIGNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLm9uQWZ0ZXJEZWxldGUoY2xhc3NOYW1lLCBpbmZsYXRlZE9iamVjdCwgbnVsbCwgcGVybXMpO1xuICAgICAgcmV0dXJuIHRyaWdnZXJzLm1heWJlUnVuVHJpZ2dlcihcbiAgICAgICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJEZWxldGUsXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGluZmxhdGVkT2JqZWN0LFxuICAgICAgICBudWxsLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGNvbnRleHRcbiAgICAgICk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoLCBjb25maWcpO1xuICAgIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2UsIHN0YXR1cywgbG9jYXRpb259IG9iamVjdC5cbmZ1bmN0aW9uIGNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgcmVzdE9iamVjdCwgY2xpZW50U0RLLCBjb250ZXh0KSB7XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2NyZWF0ZScsIGNsYXNzTmFtZSwgYXV0aCwgY29uZmlnKTtcbiAgdmFyIHdyaXRlID0gbmV3IFJlc3RXcml0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgbnVsbCwgcmVzdE9iamVjdCwgbnVsbCwgY2xpZW50U0RLLCBjb250ZXh0KTtcbiAgcmV0dXJuIHdyaXRlLmV4ZWN1dGUoKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBjb250YWlucyB0aGUgZmllbGRzIG9mIHRoZSB1cGRhdGUgdGhhdCB0aGVcbi8vIFJFU1QgQVBJIGlzIHN1cHBvc2VkIHRvIHJldHVybi5cbi8vIFVzdWFsbHksIHRoaXMgaXMganVzdCB1cGRhdGVkQXQuXG5mdW5jdGlvbiB1cGRhdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9iamVjdCwgY2xpZW50U0RLLCBjb250ZXh0KSB7XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ3VwZGF0ZScsIGNsYXNzTmFtZSwgYXV0aCwgY29uZmlnKTtcblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBoYXNUcmlnZ2VycyA9IGNoZWNrVHJpZ2dlcnMoY2xhc3NOYW1lLCBjb25maWcsIFsnYmVmb3JlU2F2ZScsICdhZnRlclNhdmUnXSk7XG4gICAgICBjb25zdCBoYXNMaXZlUXVlcnkgPSBjaGVja0xpdmVRdWVyeShjbGFzc05hbWUsIGNvbmZpZyk7XG4gICAgICBpZiAoaGFzVHJpZ2dlcnMgfHwgaGFzTGl2ZVF1ZXJ5KSB7XG4gICAgICAgIC8vIERvIG5vdCB1c2UgZmluZCwgYXMgaXQgcnVucyB0aGUgYmVmb3JlIGZpbmRzXG4gICAgICAgIC8vIFVzZSBtYXN0ZXIgYXV0aCB3aGVuIHByb3RlY3RlZEZpZWxkc1RyaWdnZXJFeGVtcHQgaXMgdHJ1ZSB0byBieXBhc3NcbiAgICAgICAgLy8gcHJvdGVjdGVkRmllbGRzIGZpbHRlcmluZywgc28gdHJpZ2dlcnMgc2VlIHRoZSBmdWxsIG9yaWdpbmFsIG9iamVjdFxuICAgICAgICBjb25zdCBxdWVyeUF1dGggPSBjb25maWcucHJvdGVjdGVkRmllbGRzVHJpZ2dlckV4ZW1wdCA/IEF1dGgubWFzdGVyKGNvbmZpZykgOiBhdXRoO1xuICAgICAgICBjb25zdCBxdWVyeSA9IGF3YWl0IFJlc3RRdWVyeSh7XG4gICAgICAgICAgbWV0aG9kOiBSZXN0UXVlcnkuTWV0aG9kLmdldCxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aDogcXVlcnlBdXRoLFxuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgICAgcnVuQWZ0ZXJGaW5kOiBmYWxzZSxcbiAgICAgICAgICBydW5CZWZvcmVGaW5kOiBmYWxzZSxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoe1xuICAgICAgICAgIG9wOiAndXBkYXRlJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9KVxuICAgIC50aGVuKCh7IHJlc3VsdHMgfSkgPT4ge1xuICAgICAgdmFyIG9yaWdpbmFsUmVzdE9iamVjdDtcbiAgICAgIGlmIChyZXN1bHRzICYmIHJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgIG9yaWdpbmFsUmVzdE9iamVjdCA9IHJlc3VsdHNbMF07XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFJlc3RXcml0ZShcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBhdXRoLFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIHJlc3RXaGVyZSxcbiAgICAgICAgcmVzdE9iamVjdCxcbiAgICAgICAgb3JpZ2luYWxSZXN0T2JqZWN0LFxuICAgICAgICBjbGllbnRTREssXG4gICAgICAgIGNvbnRleHQsXG4gICAgICAgICd1cGRhdGUnXG4gICAgICApLmV4ZWN1dGUoKTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVTZXNzaW9uTWlzc2luZ0Vycm9yKGVycm9yLCBjbGFzc05hbWUsIGF1dGgsIGNvbmZpZyk7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IoZXJyb3IsIGNsYXNzTmFtZSwgYXV0aCwgY29uZmlnKSB7XG4gIC8vIElmIHdlJ3JlIHRyeWluZyB0byB1cGRhdGUgYSB1c2VyIHdpdGhvdXQgLyB3aXRoIGJhZCBzZXNzaW9uIHRva2VuXG4gIGlmIChcbiAgICBjbGFzc05hbWUgPT09ICdfVXNlcicgJiZcbiAgICBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EICYmXG4gICAgIWF1dGguaXNNYXN0ZXIgJiZcbiAgICAhYXV0aC5pc01haW50ZW5hbmNlXG4gICkge1xuICAgIHRocm93IGNyZWF0ZVNhbml0aXplZEVycm9yKFBhcnNlLkVycm9yLlNFU1NJT05fTUlTU0lORywgJ0luc3VmZmljaWVudCBhdXRoLicsIGNvbmZpZyk7XG4gIH1cbiAgdGhyb3cgZXJyb3I7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGUsXG4gIGRlbCxcbiAgZmluZCxcbiAgZ2V0LFxuICB1cGRhdGUsXG59O1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsSUFBSUEsS0FBSyxHQUFHQyxPQUFP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
|