parse-server 4.10.2 → 5.0.0-alpha.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 (132) hide show
  1. package/README.md +450 -153
  2. package/lib/AccountLockout.js +23 -2
  3. package/lib/Adapters/AdapterLoader.js +1 -1
  4. package/lib/Adapters/Analytics/AnalyticsAdapter.js +1 -1
  5. package/lib/Adapters/Auth/AuthAdapter.js +1 -1
  6. package/lib/Adapters/Auth/OAuth1Client.js +1 -1
  7. package/lib/Adapters/Auth/facebook.js +110 -10
  8. package/lib/Adapters/Auth/gcenter.js +1 -1
  9. package/lib/Adapters/Auth/gpgames.js +1 -1
  10. package/lib/Adapters/Auth/instagram.js +4 -2
  11. package/lib/Adapters/Auth/keycloak.js +1 -1
  12. package/lib/Adapters/Auth/ldap.js +3 -1
  13. package/lib/Adapters/Auth/oauth2.js +1 -1
  14. package/lib/Adapters/Auth/phantauth.js +1 -1
  15. package/lib/Adapters/Cache/CacheAdapter.js +1 -1
  16. package/lib/Adapters/Cache/RedisCacheAdapter.js +143 -0
  17. package/lib/Adapters/Cache/SchemaCache.js +31 -0
  18. package/lib/Adapters/Email/MailAdapter.js +1 -1
  19. package/lib/Adapters/Files/FilesAdapter.js +1 -1
  20. package/lib/Adapters/Files/GridFSBucketAdapter.js +1 -1
  21. package/lib/Adapters/Files/GridStoreAdapter.js +1 -1
  22. package/lib/Adapters/Logger/LoggerAdapter.js +1 -1
  23. package/lib/Adapters/Logger/WinstonLogger.js +4 -4
  24. package/lib/Adapters/PubSub/EventEmitterPubSub.js +5 -1
  25. package/lib/Adapters/PubSub/PubSubAdapter.js +1 -1
  26. package/lib/Adapters/Push/PushAdapter.js +1 -1
  27. package/lib/Adapters/Storage/Mongo/MongoCollection.js +1 -1
  28. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +1 -1
  29. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +51 -11
  30. package/lib/Adapters/Storage/Mongo/MongoTransform.js +9 -6
  31. package/lib/Adapters/Storage/Postgres/PostgresClient.js +11 -1
  32. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +91 -57
  33. package/lib/Adapters/WebSocketServer/WSAdapter.js +1 -1
  34. package/lib/Adapters/WebSocketServer/WSSAdapter.js +1 -1
  35. package/lib/Auth.js +2 -39
  36. package/lib/Config.js +149 -8
  37. package/lib/Controllers/AdaptableController.js +1 -9
  38. package/lib/Controllers/CacheController.js +1 -1
  39. package/lib/Controllers/DatabaseController.js +148 -44
  40. package/lib/Controllers/FilesController.js +1 -1
  41. package/lib/Controllers/HooksController.js +2 -2
  42. package/lib/Controllers/LiveQueryController.js +16 -3
  43. package/lib/Controllers/LoggerController.js +1 -1
  44. package/lib/Controllers/ParseGraphQLController.js +2 -2
  45. package/lib/Controllers/PushController.js +1 -1
  46. package/lib/Controllers/SchemaController.js +101 -88
  47. package/lib/Controllers/UserController.js +16 -5
  48. package/lib/Controllers/index.js +10 -11
  49. package/lib/Deprecator/Deprecations.js +28 -0
  50. package/lib/Deprecator/Deprecator.js +135 -0
  51. package/lib/GraphQL/ParseGraphQLSchema.js +71 -39
  52. package/lib/GraphQL/ParseGraphQLServer.js +3 -3
  53. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +2 -2
  54. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +2 -2
  55. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +4 -7
  56. package/lib/GraphQL/loaders/defaultRelaySchema.js +3 -3
  57. package/lib/GraphQL/loaders/filesMutations.js +2 -2
  58. package/lib/GraphQL/loaders/functionsMutations.js +9 -5
  59. package/lib/GraphQL/loaders/parseClassMutations.js +21 -9
  60. package/lib/GraphQL/loaders/parseClassQueries.js +9 -6
  61. package/lib/GraphQL/loaders/parseClassTypes.js +5 -5
  62. package/lib/GraphQL/loaders/schemaDirectives.js +1 -1
  63. package/lib/GraphQL/loaders/schemaMutations.js +8 -6
  64. package/lib/GraphQL/loaders/schemaQueries.js +6 -4
  65. package/lib/GraphQL/loaders/usersMutations.js +65 -7
  66. package/lib/GraphQL/transformers/constraintType.js +2 -2
  67. package/lib/GraphQL/transformers/inputType.js +2 -2
  68. package/lib/GraphQL/transformers/mutation.js +45 -10
  69. package/lib/GraphQL/transformers/outputType.js +2 -2
  70. package/lib/GraphQL/transformers/query.js +2 -2
  71. package/lib/GraphQL/transformers/schemaFields.js +1 -1
  72. package/lib/KeyPromiseQueue.js +59 -0
  73. package/lib/LiveQuery/Client.js +1 -1
  74. package/lib/LiveQuery/Id.js +1 -1
  75. package/lib/LiveQuery/ParseLiveQueryServer.js +158 -38
  76. package/lib/LiveQuery/ParseWebSocketServer.js +2 -2
  77. package/lib/LiveQuery/QueryTools.js +50 -1
  78. package/lib/LiveQuery/equalObjects.js +1 -1
  79. package/lib/Options/Definitions.js +220 -33
  80. package/lib/Options/docs.js +79 -21
  81. package/lib/Options/index.js +3 -1
  82. package/lib/Page.js +53 -0
  83. package/lib/ParseServer.js +37 -16
  84. package/lib/ParseServerRESTController.js +55 -45
  85. package/lib/PromiseRouter.js +7 -20
  86. package/lib/Push/PushQueue.js +1 -1
  87. package/lib/Push/PushWorker.js +2 -2
  88. package/lib/Push/utils.js +1 -1
  89. package/lib/RestQuery.js +45 -9
  90. package/lib/RestWrite.js +60 -10
  91. package/lib/Routers/AggregateRouter.js +23 -18
  92. package/lib/Routers/AudiencesRouter.js +2 -2
  93. package/lib/Routers/ClassesRouter.js +11 -11
  94. package/lib/Routers/CloudCodeRouter.js +1 -1
  95. package/lib/Routers/FeaturesRouter.js +2 -2
  96. package/lib/Routers/FilesRouter.js +34 -7
  97. package/lib/Routers/FunctionsRouter.js +2 -2
  98. package/lib/Routers/GlobalConfigRouter.js +2 -2
  99. package/lib/Routers/GraphQLRouter.js +3 -3
  100. package/lib/Routers/HooksRouter.js +2 -2
  101. package/lib/Routers/LogsRouter.js +2 -2
  102. package/lib/Routers/PagesRouter.js +722 -0
  103. package/lib/Routers/PurgeRouter.js +2 -2
  104. package/lib/Routers/PushRouter.js +3 -3
  105. package/lib/Routers/SchemasRouter.js +2 -2
  106. package/lib/Routers/SecurityRouter.js +47 -0
  107. package/lib/Routers/SessionsRouter.js +4 -2
  108. package/lib/Routers/UsersRouter.js +88 -17
  109. package/lib/Security/Check.js +118 -0
  110. package/lib/Security/CheckGroup.js +54 -0
  111. package/lib/Security/CheckGroups/CheckGroupDatabase.js +57 -0
  112. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +82 -0
  113. package/lib/Security/CheckGroups/CheckGroups.js +24 -0
  114. package/lib/Security/CheckRunner.js +236 -0
  115. package/lib/StatusHandler.js +27 -36
  116. package/lib/TestUtils.js +1 -1
  117. package/lib/Utils.js +226 -0
  118. package/lib/batch.js +55 -44
  119. package/lib/cli/utils/commander.js +8 -3
  120. package/lib/cloud-code/HTTPResponse.js +1 -1
  121. package/lib/cloud-code/Parse.Cloud.js +155 -19
  122. package/lib/cloud-code/httpRequest.js +1 -1
  123. package/lib/index.js +6 -12
  124. package/lib/middlewares.js +39 -4
  125. package/lib/rest.js +4 -4
  126. package/lib/triggers.js +134 -121
  127. package/lib/vendor/mongodbUrl.js +8 -10
  128. package/package.json +54 -29
  129. package/CHANGELOG.md +0 -1769
  130. package/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js +0 -59
  131. package/lib/Adapters/Cache/RedisCacheAdapter/index.js +0 -130
  132. package/lib/Controllers/SchemaCache.js +0 -75
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _Utils = _interopRequireDefault(require("../Utils"));
9
+
10
+ var _lodash = require("lodash");
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ /**
15
+ * @module SecurityCheck
16
+ */
17
+
18
+ /**
19
+ * A security check.
20
+ * @class Check
21
+ */
22
+ class Check {
23
+ /**
24
+ * Constructs a new security check.
25
+ * @param {Object} params The parameters.
26
+ * @param {String} params.title The title.
27
+ * @param {String} params.warning The warning message if the check fails.
28
+ * @param {String} params.solution The solution to fix the check.
29
+ * @param {Promise} params.check The check as synchronous or asynchronous function.
30
+ */
31
+ constructor(params) {
32
+ this._validateParams(params);
33
+
34
+ const {
35
+ title,
36
+ warning,
37
+ solution,
38
+ check
39
+ } = params;
40
+ this.title = title;
41
+ this.warning = warning;
42
+ this.solution = solution;
43
+ this.check = check; // Set default properties
44
+
45
+ this._checkState = CheckState.none;
46
+ this.error;
47
+ }
48
+ /**
49
+ * Returns the current check state.
50
+ * @return {CheckState} The check state.
51
+ */
52
+
53
+
54
+ checkState() {
55
+ return this._checkState;
56
+ }
57
+
58
+ async run() {
59
+ // Get check as synchronous or asynchronous function
60
+ const check = this.check instanceof Promise ? await this.check : this.check; // Run check
61
+
62
+ try {
63
+ check();
64
+ this._checkState = CheckState.success;
65
+ } catch (e) {
66
+ this.stateFailError = e;
67
+ this._checkState = CheckState.fail;
68
+ }
69
+ }
70
+ /**
71
+ * Validates the constructor parameters.
72
+ * @param {Object} params The parameters to validate.
73
+ */
74
+
75
+
76
+ _validateParams(params) {
77
+ _Utils.default.validateParams(params, {
78
+ group: {
79
+ t: 'string',
80
+ v: _lodash.isString
81
+ },
82
+ title: {
83
+ t: 'string',
84
+ v: _lodash.isString
85
+ },
86
+ warning: {
87
+ t: 'string',
88
+ v: _lodash.isString
89
+ },
90
+ solution: {
91
+ t: 'string',
92
+ v: _lodash.isString
93
+ },
94
+ check: {
95
+ t: 'function',
96
+ v: _lodash.isFunction
97
+ }
98
+ });
99
+ }
100
+
101
+ }
102
+ /**
103
+ * The check state.
104
+ */
105
+
106
+
107
+ const CheckState = Object.freeze({
108
+ none: 'none',
109
+ fail: 'fail',
110
+ success: 'success'
111
+ });
112
+ var _default = Check;
113
+ exports.default = _default;
114
+ module.exports = {
115
+ Check,
116
+ CheckState
117
+ };
118
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TZWN1cml0eS9DaGVjay5qcyJdLCJuYW1lcyI6WyJDaGVjayIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwiX3ZhbGlkYXRlUGFyYW1zIiwidGl0bGUiLCJ3YXJuaW5nIiwic29sdXRpb24iLCJjaGVjayIsIl9jaGVja1N0YXRlIiwiQ2hlY2tTdGF0ZSIsIm5vbmUiLCJlcnJvciIsImNoZWNrU3RhdGUiLCJydW4iLCJQcm9taXNlIiwic3VjY2VzcyIsImUiLCJzdGF0ZUZhaWxFcnJvciIsImZhaWwiLCJVdGlscyIsInZhbGlkYXRlUGFyYW1zIiwiZ3JvdXAiLCJ0IiwidiIsImlzU3RyaW5nIiwiaXNGdW5jdGlvbiIsIk9iamVjdCIsImZyZWV6ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFJQTs7QUFDQTs7OztBQUxBO0FBQ0E7QUFDQTs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1BLEtBQU4sQ0FBWTtBQUNWO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsV0FBVyxDQUFDQyxNQUFELEVBQVM7QUFDbEIsU0FBS0MsZUFBTCxDQUFxQkQsTUFBckI7O0FBQ0EsVUFBTTtBQUFFRSxNQUFBQSxLQUFGO0FBQVNDLE1BQUFBLE9BQVQ7QUFBa0JDLE1BQUFBLFFBQWxCO0FBQTRCQyxNQUFBQTtBQUE1QixRQUFzQ0wsTUFBNUM7QUFFQSxTQUFLRSxLQUFMLEdBQWFBLEtBQWI7QUFDQSxTQUFLQyxPQUFMLEdBQWVBLE9BQWY7QUFDQSxTQUFLQyxRQUFMLEdBQWdCQSxRQUFoQjtBQUNBLFNBQUtDLEtBQUwsR0FBYUEsS0FBYixDQVBrQixDQVNsQjs7QUFDQSxTQUFLQyxXQUFMLEdBQW1CQyxVQUFVLENBQUNDLElBQTlCO0FBQ0EsU0FBS0MsS0FBTDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7OztBQUNFQyxFQUFBQSxVQUFVLEdBQUc7QUFDWCxXQUFPLEtBQUtKLFdBQVo7QUFDRDs7QUFFUSxRQUFISyxHQUFHLEdBQUc7QUFDVjtBQUNBLFVBQU1OLEtBQUssR0FBRyxLQUFLQSxLQUFMLFlBQXNCTyxPQUF0QixHQUFnQyxNQUFNLEtBQUtQLEtBQTNDLEdBQW1ELEtBQUtBLEtBQXRFLENBRlUsQ0FJVjs7QUFDQSxRQUFJO0FBQ0ZBLE1BQUFBLEtBQUs7QUFDTCxXQUFLQyxXQUFMLEdBQW1CQyxVQUFVLENBQUNNLE9BQTlCO0FBQ0QsS0FIRCxDQUdFLE9BQU9DLENBQVAsRUFBVTtBQUNWLFdBQUtDLGNBQUwsR0FBc0JELENBQXRCO0FBQ0EsV0FBS1IsV0FBTCxHQUFtQkMsVUFBVSxDQUFDUyxJQUE5QjtBQUNEO0FBQ0Y7QUFFRDtBQUNGO0FBQ0E7QUFDQTs7O0FBQ0VmLEVBQUFBLGVBQWUsQ0FBQ0QsTUFBRCxFQUFTO0FBQ3RCaUIsbUJBQU1DLGNBQU4sQ0FBcUJsQixNQUFyQixFQUE2QjtBQUMzQm1CLE1BQUFBLEtBQUssRUFBRTtBQUFFQyxRQUFBQSxDQUFDLEVBQUUsUUFBTDtBQUFlQyxRQUFBQSxDQUFDLEVBQUVDO0FBQWxCLE9BRG9CO0FBRTNCcEIsTUFBQUEsS0FBSyxFQUFFO0FBQUVrQixRQUFBQSxDQUFDLEVBQUUsUUFBTDtBQUFlQyxRQUFBQSxDQUFDLEVBQUVDO0FBQWxCLE9BRm9CO0FBRzNCbkIsTUFBQUEsT0FBTyxFQUFFO0FBQUVpQixRQUFBQSxDQUFDLEVBQUUsUUFBTDtBQUFlQyxRQUFBQSxDQUFDLEVBQUVDO0FBQWxCLE9BSGtCO0FBSTNCbEIsTUFBQUEsUUFBUSxFQUFFO0FBQUVnQixRQUFBQSxDQUFDLEVBQUUsUUFBTDtBQUFlQyxRQUFBQSxDQUFDLEVBQUVDO0FBQWxCLE9BSmlCO0FBSzNCakIsTUFBQUEsS0FBSyxFQUFFO0FBQUVlLFFBQUFBLENBQUMsRUFBRSxVQUFMO0FBQWlCQyxRQUFBQSxDQUFDLEVBQUVFO0FBQXBCO0FBTG9CLEtBQTdCO0FBT0Q7O0FBekRTO0FBNERaO0FBQ0E7QUFDQTs7O0FBQ0EsTUFBTWhCLFVBQVUsR0FBR2lCLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjO0FBQy9CakIsRUFBQUEsSUFBSSxFQUFFLE1BRHlCO0FBRS9CUSxFQUFBQSxJQUFJLEVBQUUsTUFGeUI7QUFHL0JILEVBQUFBLE9BQU8sRUFBRTtBQUhzQixDQUFkLENBQW5CO2VBTWVmLEs7O0FBQ2Y0QixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZjdCLEVBQUFBLEtBRGU7QUFFZlMsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG1vZHVsZSBTZWN1cml0eUNoZWNrXG4gKi9cblxuaW1wb3J0IFV0aWxzIGZyb20gJy4uL1V0aWxzJztcbmltcG9ydCB7IGlzRnVuY3Rpb24sIGlzU3RyaW5nIH0gZnJvbSAnbG9kYXNoJztcblxuLyoqXG4gKiBBIHNlY3VyaXR5IGNoZWNrLlxuICogQGNsYXNzIENoZWNrXG4gKi9cbmNsYXNzIENoZWNrIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgYSBuZXcgc2VjdXJpdHkgY2hlY2suXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXJhbXMudGl0bGUgVGhlIHRpdGxlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFyYW1zLndhcm5pbmcgVGhlIHdhcm5pbmcgbWVzc2FnZSBpZiB0aGUgY2hlY2sgZmFpbHMuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXJhbXMuc29sdXRpb24gVGhlIHNvbHV0aW9uIHRvIGZpeCB0aGUgY2hlY2suXG4gICAqIEBwYXJhbSB7UHJvbWlzZX0gcGFyYW1zLmNoZWNrIFRoZSBjaGVjayBhcyBzeW5jaHJvbm91cyBvciBhc3luY2hyb25vdXMgZnVuY3Rpb24uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcbiAgICB0aGlzLl92YWxpZGF0ZVBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IHsgdGl0bGUsIHdhcm5pbmcsIHNvbHV0aW9uLCBjaGVjayB9ID0gcGFyYW1zO1xuXG4gICAgdGhpcy50aXRsZSA9IHRpdGxlO1xuICAgIHRoaXMud2FybmluZyA9IHdhcm5pbmc7XG4gICAgdGhpcy5zb2x1dGlvbiA9IHNvbHV0aW9uO1xuICAgIHRoaXMuY2hlY2sgPSBjaGVjaztcblxuICAgIC8vIFNldCBkZWZhdWx0IHByb3BlcnRpZXNcbiAgICB0aGlzLl9jaGVja1N0YXRlID0gQ2hlY2tTdGF0ZS5ub25lO1xuICAgIHRoaXMuZXJyb3I7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCBjaGVjayBzdGF0ZS5cbiAgICogQHJldHVybiB7Q2hlY2tTdGF0ZX0gVGhlIGNoZWNrIHN0YXRlLlxuICAgKi9cbiAgY2hlY2tTdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fY2hlY2tTdGF0ZTtcbiAgfVxuXG4gIGFzeW5jIHJ1bigpIHtcbiAgICAvLyBHZXQgY2hlY2sgYXMgc3luY2hyb25vdXMgb3IgYXN5bmNocm9ub3VzIGZ1bmN0aW9uXG4gICAgY29uc3QgY2hlY2sgPSB0aGlzLmNoZWNrIGluc3RhbmNlb2YgUHJvbWlzZSA/IGF3YWl0IHRoaXMuY2hlY2sgOiB0aGlzLmNoZWNrO1xuXG4gICAgLy8gUnVuIGNoZWNrXG4gICAgdHJ5IHtcbiAgICAgIGNoZWNrKCk7XG4gICAgICB0aGlzLl9jaGVja1N0YXRlID0gQ2hlY2tTdGF0ZS5zdWNjZXNzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuc3RhdGVGYWlsRXJyb3IgPSBlO1xuICAgICAgdGhpcy5fY2hlY2tTdGF0ZSA9IENoZWNrU3RhdGUuZmFpbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIFRoZSBwYXJhbWV0ZXJzIHRvIHZhbGlkYXRlLlxuICAgKi9cbiAgX3ZhbGlkYXRlUGFyYW1zKHBhcmFtcykge1xuICAgIFV0aWxzLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywge1xuICAgICAgZ3JvdXA6IHsgdDogJ3N0cmluZycsIHY6IGlzU3RyaW5nIH0sXG4gICAgICB0aXRsZTogeyB0OiAnc3RyaW5nJywgdjogaXNTdHJpbmcgfSxcbiAgICAgIHdhcm5pbmc6IHsgdDogJ3N0cmluZycsIHY6IGlzU3RyaW5nIH0sXG4gICAgICBzb2x1dGlvbjogeyB0OiAnc3RyaW5nJywgdjogaXNTdHJpbmcgfSxcbiAgICAgIGNoZWNrOiB7IHQ6ICdmdW5jdGlvbicsIHY6IGlzRnVuY3Rpb24gfSxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSBjaGVjayBzdGF0ZS5cbiAqL1xuY29uc3QgQ2hlY2tTdGF0ZSA9IE9iamVjdC5mcmVlemUoe1xuICBub25lOiAnbm9uZScsXG4gIGZhaWw6ICdmYWlsJyxcbiAgc3VjY2VzczogJ3N1Y2Nlc3MnLFxufSk7XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrO1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIENoZWNrLFxuICBDaGVja1N0YXRlLFxufTtcbiJdfQ==
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * @module SecurityCheck
5
+ */
6
+
7
+ /**
8
+ * A group of security checks.
9
+ * @interface CheckGroup
10
+ */
11
+ class CheckGroup {
12
+ constructor() {
13
+ this._name = this.setName();
14
+ this._checks = this.setChecks();
15
+ }
16
+ /**
17
+ * The security check group name; to be overridden by child class.
18
+ */
19
+
20
+
21
+ setName() {
22
+ throw `Check group has no name.`;
23
+ }
24
+
25
+ name() {
26
+ return this._name;
27
+ }
28
+ /**
29
+ * The security checks; to be overridden by child class.
30
+ */
31
+
32
+
33
+ setChecks() {
34
+ throw `Check group has no checks.`;
35
+ }
36
+
37
+ checks() {
38
+ return this._checks;
39
+ }
40
+ /**
41
+ * Runs all checks.
42
+ */
43
+
44
+
45
+ async run() {
46
+ for (const check of this._checks) {
47
+ check.run();
48
+ }
49
+ }
50
+
51
+ }
52
+
53
+ module.exports = CheckGroup;
54
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TZWN1cml0eS9DaGVja0dyb3VwLmpzIl0sIm5hbWVzIjpbIkNoZWNrR3JvdXAiLCJjb25zdHJ1Y3RvciIsIl9uYW1lIiwic2V0TmFtZSIsIl9jaGVja3MiLCJzZXRDaGVja3MiLCJuYW1lIiwiY2hlY2tzIiwicnVuIiwiY2hlY2siLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1BLFVBQU4sQ0FBaUI7QUFDZkMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxHQUFhLEtBQUtDLE9BQUwsRUFBYjtBQUNBLFNBQUtDLE9BQUwsR0FBZSxLQUFLQyxTQUFMLEVBQWY7QUFDRDtBQUVEO0FBQ0Y7QUFDQTs7O0FBQ0VGLEVBQUFBLE9BQU8sR0FBRztBQUNSLFVBQU8sMEJBQVA7QUFDRDs7QUFDREcsRUFBQUEsSUFBSSxHQUFHO0FBQ0wsV0FBTyxLQUFLSixLQUFaO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7OztBQUNFRyxFQUFBQSxTQUFTLEdBQUc7QUFDVixVQUFPLDRCQUFQO0FBQ0Q7O0FBQ0RFLEVBQUFBLE1BQU0sR0FBRztBQUNQLFdBQU8sS0FBS0gsT0FBWjtBQUNEO0FBRUQ7QUFDRjtBQUNBOzs7QUFDVyxRQUFISSxHQUFHLEdBQUc7QUFDVixTQUFLLE1BQU1DLEtBQVgsSUFBb0IsS0FBS0wsT0FBekIsRUFBa0M7QUFDaENLLE1BQUFBLEtBQUssQ0FBQ0QsR0FBTjtBQUNEO0FBQ0Y7O0FBakNjOztBQW9DakJFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQlgsVUFBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBtb2R1bGUgU2VjdXJpdHlDaGVja1xuICovXG5cbi8qKlxuICogQSBncm91cCBvZiBzZWN1cml0eSBjaGVja3MuXG4gKiBAaW50ZXJmYWNlIENoZWNrR3JvdXBcbiAqL1xuY2xhc3MgQ2hlY2tHcm91cCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX25hbWUgPSB0aGlzLnNldE5hbWUoKTtcbiAgICB0aGlzLl9jaGVja3MgPSB0aGlzLnNldENoZWNrcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBzZWN1cml0eSBjaGVjayBncm91cCBuYW1lOyB0byBiZSBvdmVycmlkZGVuIGJ5IGNoaWxkIGNsYXNzLlxuICAgKi9cbiAgc2V0TmFtZSgpIHtcbiAgICB0aHJvdyBgQ2hlY2sgZ3JvdXAgaGFzIG5vIG5hbWUuYDtcbiAgfVxuICBuYW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9uYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBzZWN1cml0eSBjaGVja3M7IHRvIGJlIG92ZXJyaWRkZW4gYnkgY2hpbGQgY2xhc3MuXG4gICAqL1xuICBzZXRDaGVja3MoKSB7XG4gICAgdGhyb3cgYENoZWNrIGdyb3VwIGhhcyBubyBjaGVja3MuYDtcbiAgfVxuICBjaGVja3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NoZWNrcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFsbCBjaGVja3MuXG4gICAqL1xuICBhc3luYyBydW4oKSB7XG4gICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9jaGVja3MpIHtcbiAgICAgIGNoZWNrLnJ1bigpO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IENoZWNrR3JvdXA7XG4iXX0=
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ var _Check = require("../Check");
4
+
5
+ var _CheckGroup = _interopRequireDefault(require("../CheckGroup"));
6
+
7
+ var _Config = _interopRequireDefault(require("../../Config"));
8
+
9
+ var _node = _interopRequireDefault(require("parse/node"));
10
+
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+
13
+ /**
14
+ * @module SecurityCheck
15
+ */
16
+
17
+ /**
18
+ * The security checks group for Parse Server configuration.
19
+ * Checks common Parse Server parameters such as access keys.
20
+ */
21
+ class CheckGroupDatabase extends _CheckGroup.default {
22
+ setName() {
23
+ return 'Database';
24
+ }
25
+
26
+ setChecks() {
27
+ const config = _Config.default.get(_node.default.applicationId);
28
+
29
+ const databaseAdapter = config.database.adapter;
30
+ const databaseUrl = databaseAdapter._uri;
31
+ return [new _Check.Check({
32
+ title: 'Secure database password',
33
+ warning: 'The database password is insecure and vulnerable to brute force attacks.',
34
+ solution: 'Choose a longer and/or more complex password with a combination of upper- and lowercase characters, numbers and special characters.',
35
+ check: () => {
36
+ const password = databaseUrl.match(/\/\/\S+:(\S+)@/)[1];
37
+ const hasUpperCase = /[A-Z]/.test(password);
38
+ const hasLowerCase = /[a-z]/.test(password);
39
+ const hasNumbers = /\d/.test(password);
40
+ const hasNonAlphasNumerics = /\W/.test(password); // Ensure length
41
+
42
+ if (password.length < 14) {
43
+ throw 1;
44
+ } // Ensure at least 3 out of 4 requirements passed
45
+
46
+
47
+ if (hasUpperCase + hasLowerCase + hasNumbers + hasNonAlphasNumerics < 3) {
48
+ throw 1;
49
+ }
50
+ }
51
+ })];
52
+ }
53
+
54
+ }
55
+
56
+ module.exports = CheckGroupDatabase;
57
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9TZWN1cml0eS9DaGVja0dyb3Vwcy9DaGVja0dyb3VwRGF0YWJhc2UuanMiXSwibmFtZXMiOlsiQ2hlY2tHcm91cERhdGFiYXNlIiwiQ2hlY2tHcm91cCIsInNldE5hbWUiLCJzZXRDaGVja3MiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJQYXJzZSIsImFwcGxpY2F0aW9uSWQiLCJkYXRhYmFzZUFkYXB0ZXIiLCJkYXRhYmFzZSIsImFkYXB0ZXIiLCJkYXRhYmFzZVVybCIsIl91cmkiLCJDaGVjayIsInRpdGxlIiwid2FybmluZyIsInNvbHV0aW9uIiwiY2hlY2siLCJwYXNzd29yZCIsIm1hdGNoIiwiaGFzVXBwZXJDYXNlIiwidGVzdCIsImhhc0xvd2VyQ2FzZSIsImhhc051bWJlcnMiLCJoYXNOb25BbHBoYXNOdW1lcmljcyIsImxlbmd0aCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBSUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFQQTtBQUNBO0FBQ0E7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNQSxrQkFBTixTQUFpQ0MsbUJBQWpDLENBQTRDO0FBQzFDQyxFQUFBQSxPQUFPLEdBQUc7QUFDUixXQUFPLFVBQVA7QUFDRDs7QUFDREMsRUFBQUEsU0FBUyxHQUFHO0FBQ1YsVUFBTUMsTUFBTSxHQUFHQyxnQkFBT0MsR0FBUCxDQUFXQyxjQUFNQyxhQUFqQixDQUFmOztBQUNBLFVBQU1DLGVBQWUsR0FBR0wsTUFBTSxDQUFDTSxRQUFQLENBQWdCQyxPQUF4QztBQUNBLFVBQU1DLFdBQVcsR0FBR0gsZUFBZSxDQUFDSSxJQUFwQztBQUNBLFdBQU8sQ0FDTCxJQUFJQyxZQUFKLENBQVU7QUFDUkMsTUFBQUEsS0FBSyxFQUFFLDBCQURDO0FBRVJDLE1BQUFBLE9BQU8sRUFBRSwwRUFGRDtBQUdSQyxNQUFBQSxRQUFRLEVBQUUscUlBSEY7QUFJUkMsTUFBQUEsS0FBSyxFQUFFLE1BQU07QUFDWCxjQUFNQyxRQUFRLEdBQUdQLFdBQVcsQ0FBQ1EsS0FBWixDQUFrQixnQkFBbEIsRUFBb0MsQ0FBcEMsQ0FBakI7QUFDQSxjQUFNQyxZQUFZLEdBQUcsUUFBUUMsSUFBUixDQUFhSCxRQUFiLENBQXJCO0FBQ0EsY0FBTUksWUFBWSxHQUFHLFFBQVFELElBQVIsQ0FBYUgsUUFBYixDQUFyQjtBQUNBLGNBQU1LLFVBQVUsR0FBRyxLQUFLRixJQUFMLENBQVVILFFBQVYsQ0FBbkI7QUFDQSxjQUFNTSxvQkFBb0IsR0FBRyxLQUFLSCxJQUFMLENBQVVILFFBQVYsQ0FBN0IsQ0FMVyxDQU1YOztBQUNBLFlBQUlBLFFBQVEsQ0FBQ08sTUFBVCxHQUFrQixFQUF0QixFQUEwQjtBQUN4QixnQkFBTSxDQUFOO0FBQ0QsU0FUVSxDQVVYOzs7QUFDQSxZQUFJTCxZQUFZLEdBQUdFLFlBQWYsR0FBOEJDLFVBQTlCLEdBQTJDQyxvQkFBM0MsR0FBa0UsQ0FBdEUsRUFBeUU7QUFDdkUsZ0JBQU0sQ0FBTjtBQUNEO0FBQ0Y7QUFsQk8sS0FBVixDQURLLENBQVA7QUFzQkQ7O0FBOUJ5Qzs7QUFpQzVDRSxNQUFNLENBQUNDLE9BQVAsR0FBaUI1QixrQkFBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBtb2R1bGUgU2VjdXJpdHlDaGVja1xuICovXG5cbmltcG9ydCB7IENoZWNrIH0gZnJvbSAnLi4vQ2hlY2snO1xuaW1wb3J0IENoZWNrR3JvdXAgZnJvbSAnLi4vQ2hlY2tHcm91cCc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uLy4uL0NvbmZpZyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbi8qKlxuKiBUaGUgc2VjdXJpdHkgY2hlY2tzIGdyb3VwIGZvciBQYXJzZSBTZXJ2ZXIgY29uZmlndXJhdGlvbi5cbiogQ2hlY2tzIGNvbW1vbiBQYXJzZSBTZXJ2ZXIgcGFyYW1ldGVycyBzdWNoIGFzIGFjY2VzcyBrZXlzLlxuKi9cbmNsYXNzIENoZWNrR3JvdXBEYXRhYmFzZSBleHRlbmRzIENoZWNrR3JvdXAge1xuICBzZXROYW1lKCkge1xuICAgIHJldHVybiAnRGF0YWJhc2UnO1xuICB9XG4gIHNldENoZWNrcygpIHtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICAgIGNvbnN0IGRhdGFiYXNlQWRhcHRlciA9IGNvbmZpZy5kYXRhYmFzZS5hZGFwdGVyO1xuICAgIGNvbnN0IGRhdGFiYXNlVXJsID0gZGF0YWJhc2VBZGFwdGVyLl91cmk7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBDaGVjayh7XG4gICAgICAgIHRpdGxlOiAnU2VjdXJlIGRhdGFiYXNlIHBhc3N3b3JkJyxcbiAgICAgICAgd2FybmluZzogJ1RoZSBkYXRhYmFzZSBwYXNzd29yZCBpcyBpbnNlY3VyZSBhbmQgdnVsbmVyYWJsZSB0byBicnV0ZSBmb3JjZSBhdHRhY2tzLicsXG4gICAgICAgIHNvbHV0aW9uOiAnQ2hvb3NlIGEgbG9uZ2VyIGFuZC9vciBtb3JlIGNvbXBsZXggcGFzc3dvcmQgd2l0aCBhIGNvbWJpbmF0aW9uIG9mIHVwcGVyLSBhbmQgbG93ZXJjYXNlIGNoYXJhY3RlcnMsIG51bWJlcnMgYW5kIHNwZWNpYWwgY2hhcmFjdGVycy4nLFxuICAgICAgICBjaGVjazogKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhc3N3b3JkID0gZGF0YWJhc2VVcmwubWF0Y2goL1xcL1xcL1xcUys6KFxcUyspQC8pWzFdO1xuICAgICAgICAgIGNvbnN0IGhhc1VwcGVyQ2FzZSA9IC9bQS1aXS8udGVzdChwYXNzd29yZCk7XG4gICAgICAgICAgY29uc3QgaGFzTG93ZXJDYXNlID0gL1thLXpdLy50ZXN0KHBhc3N3b3JkKTtcbiAgICAgICAgICBjb25zdCBoYXNOdW1iZXJzID0gL1xcZC8udGVzdChwYXNzd29yZCk7XG4gICAgICAgICAgY29uc3QgaGFzTm9uQWxwaGFzTnVtZXJpY3MgPSAvXFxXLy50ZXN0KHBhc3N3b3JkKTtcbiAgICAgICAgICAvLyBFbnN1cmUgbGVuZ3RoXG4gICAgICAgICAgaWYgKHBhc3N3b3JkLmxlbmd0aCA8IDE0KSB7XG4gICAgICAgICAgICB0aHJvdyAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBFbnN1cmUgYXQgbGVhc3QgMyBvdXQgb2YgNCByZXF1aXJlbWVudHMgcGFzc2VkXG4gICAgICAgICAgaWYgKGhhc1VwcGVyQ2FzZSArIGhhc0xvd2VyQ2FzZSArIGhhc051bWJlcnMgKyBoYXNOb25BbHBoYXNOdW1lcmljcyA8IDMpIHtcbiAgICAgICAgICAgIHRocm93IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IENoZWNrR3JvdXBEYXRhYmFzZTtcbiJdfQ==
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ var _Check = require("../Check");
4
+
5
+ var _CheckGroup = _interopRequireDefault(require("../CheckGroup"));
6
+
7
+ var _Config = _interopRequireDefault(require("../../Config"));
8
+
9
+ var _node = _interopRequireDefault(require("parse/node"));
10
+
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+
13
+ /**
14
+ * @module SecurityCheck
15
+ */
16
+
17
+ /**
18
+ * The security checks group for Parse Server configuration.
19
+ * Checks common Parse Server parameters such as access keys.
20
+ */
21
+ class CheckGroupServerConfig extends _CheckGroup.default {
22
+ setName() {
23
+ return 'Parse Server Configuration';
24
+ }
25
+
26
+ setChecks() {
27
+ const config = _Config.default.get(_node.default.applicationId);
28
+
29
+ return [new _Check.Check({
30
+ title: 'Secure master key',
31
+ warning: 'The Parse Server master key is insecure and vulnerable to brute force attacks.',
32
+ solution: 'Choose a longer and/or more complex master key with a combination of upper- and lowercase characters, numbers and special characters.',
33
+ check: () => {
34
+ const masterKey = config.masterKey;
35
+ const hasUpperCase = /[A-Z]/.test(masterKey);
36
+ const hasLowerCase = /[a-z]/.test(masterKey);
37
+ const hasNumbers = /\d/.test(masterKey);
38
+ const hasNonAlphasNumerics = /\W/.test(masterKey); // Ensure length
39
+
40
+ if (masterKey.length < 14) {
41
+ throw 1;
42
+ } // Ensure at least 3 out of 4 requirements passed
43
+
44
+
45
+ if (hasUpperCase + hasLowerCase + hasNumbers + hasNonAlphasNumerics < 3) {
46
+ throw 1;
47
+ }
48
+ }
49
+ }), new _Check.Check({
50
+ title: 'Security log disabled',
51
+ warning: 'Security checks in logs may expose vulnerabilities to anyone with access to logs.',
52
+ solution: "Change Parse Server configuration to 'security.enableCheckLog: false'.",
53
+ check: () => {
54
+ if (config.security && config.security.enableCheckLog) {
55
+ throw 1;
56
+ }
57
+ }
58
+ }), new _Check.Check({
59
+ title: 'Client class creation disabled',
60
+ warning: 'Attackers are allowed to create new classes without restriction and flood the database.',
61
+ solution: "Change Parse Server configuration to 'allowClientClassCreation: false'.",
62
+ check: () => {
63
+ if (config.allowClientClassCreation || config.allowClientClassCreation == null) {
64
+ throw 1;
65
+ }
66
+ }
67
+ }), new _Check.Check({
68
+ title: 'Users are created without public access',
69
+ warning: 'Users with public read access are exposed to anyone who knows their object IDs, or to anyone who can query the Parse.User class.',
70
+ solution: "Change Parse Server configuration to 'enforcePrivateUsers: true'.",
71
+ check: () => {
72
+ if (!config.enforcePrivateUsers) {
73
+ throw 1;
74
+ }
75
+ }
76
+ })];
77
+ }
78
+
79
+ }
80
+
81
+ module.exports = CheckGroupServerConfig;
82
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9TZWN1cml0eS9DaGVja0dyb3Vwcy9DaGVja0dyb3VwU2VydmVyQ29uZmlnLmpzIl0sIm5hbWVzIjpbIkNoZWNrR3JvdXBTZXJ2ZXJDb25maWciLCJDaGVja0dyb3VwIiwic2V0TmFtZSIsInNldENoZWNrcyIsImNvbmZpZyIsIkNvbmZpZyIsImdldCIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsIkNoZWNrIiwidGl0bGUiLCJ3YXJuaW5nIiwic29sdXRpb24iLCJjaGVjayIsIm1hc3RlcktleSIsImhhc1VwcGVyQ2FzZSIsInRlc3QiLCJoYXNMb3dlckNhc2UiLCJoYXNOdW1iZXJzIiwiaGFzTm9uQWxwaGFzTnVtZXJpY3MiLCJsZW5ndGgiLCJzZWN1cml0eSIsImVuYWJsZUNoZWNrTG9nIiwiYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIiwiZW5mb3JjZVByaXZhdGVVc2VycyIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBSUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFQQTtBQUNBO0FBQ0E7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNQSxzQkFBTixTQUFxQ0MsbUJBQXJDLENBQWdEO0FBQzlDQyxFQUFBQSxPQUFPLEdBQUc7QUFDUixXQUFPLDRCQUFQO0FBQ0Q7O0FBQ0RDLEVBQUFBLFNBQVMsR0FBRztBQUNWLFVBQU1DLE1BQU0sR0FBR0MsZ0JBQU9DLEdBQVAsQ0FBV0MsY0FBTUMsYUFBakIsQ0FBZjs7QUFDQSxXQUFPLENBQ0wsSUFBSUMsWUFBSixDQUFVO0FBQ1JDLE1BQUFBLEtBQUssRUFBRSxtQkFEQztBQUVSQyxNQUFBQSxPQUFPLEVBQUUsZ0ZBRkQ7QUFHUkMsTUFBQUEsUUFBUSxFQUNOLHVJQUpNO0FBS1JDLE1BQUFBLEtBQUssRUFBRSxNQUFNO0FBQ1gsY0FBTUMsU0FBUyxHQUFHVixNQUFNLENBQUNVLFNBQXpCO0FBQ0EsY0FBTUMsWUFBWSxHQUFHLFFBQVFDLElBQVIsQ0FBYUYsU0FBYixDQUFyQjtBQUNBLGNBQU1HLFlBQVksR0FBRyxRQUFRRCxJQUFSLENBQWFGLFNBQWIsQ0FBckI7QUFDQSxjQUFNSSxVQUFVLEdBQUcsS0FBS0YsSUFBTCxDQUFVRixTQUFWLENBQW5CO0FBQ0EsY0FBTUssb0JBQW9CLEdBQUcsS0FBS0gsSUFBTCxDQUFVRixTQUFWLENBQTdCLENBTFcsQ0FNWDs7QUFDQSxZQUFJQSxTQUFTLENBQUNNLE1BQVYsR0FBbUIsRUFBdkIsRUFBMkI7QUFDekIsZ0JBQU0sQ0FBTjtBQUNELFNBVFUsQ0FVWDs7O0FBQ0EsWUFBSUwsWUFBWSxHQUFHRSxZQUFmLEdBQThCQyxVQUE5QixHQUEyQ0Msb0JBQTNDLEdBQWtFLENBQXRFLEVBQXlFO0FBQ3ZFLGdCQUFNLENBQU47QUFDRDtBQUNGO0FBbkJPLEtBQVYsQ0FESyxFQXNCTCxJQUFJVixZQUFKLENBQVU7QUFDUkMsTUFBQUEsS0FBSyxFQUFFLHVCQURDO0FBRVJDLE1BQUFBLE9BQU8sRUFDTCxtRkFITTtBQUlSQyxNQUFBQSxRQUFRLEVBQUUsd0VBSkY7QUFLUkMsTUFBQUEsS0FBSyxFQUFFLE1BQU07QUFDWCxZQUFJVCxNQUFNLENBQUNpQixRQUFQLElBQW1CakIsTUFBTSxDQUFDaUIsUUFBUCxDQUFnQkMsY0FBdkMsRUFBdUQ7QUFDckQsZ0JBQU0sQ0FBTjtBQUNEO0FBQ0Y7QUFUTyxLQUFWLENBdEJLLEVBaUNMLElBQUliLFlBQUosQ0FBVTtBQUNSQyxNQUFBQSxLQUFLLEVBQUUsZ0NBREM7QUFFUkMsTUFBQUEsT0FBTyxFQUNMLHlGQUhNO0FBSVJDLE1BQUFBLFFBQVEsRUFBRSx5RUFKRjtBQUtSQyxNQUFBQSxLQUFLLEVBQUUsTUFBTTtBQUNYLFlBQUlULE1BQU0sQ0FBQ21CLHdCQUFQLElBQW1DbkIsTUFBTSxDQUFDbUIsd0JBQVAsSUFBbUMsSUFBMUUsRUFBZ0Y7QUFDOUUsZ0JBQU0sQ0FBTjtBQUNEO0FBQ0Y7QUFUTyxLQUFWLENBakNLLEVBNENMLElBQUlkLFlBQUosQ0FBVTtBQUNSQyxNQUFBQSxLQUFLLEVBQUUseUNBREM7QUFFUkMsTUFBQUEsT0FBTyxFQUNMLGtJQUhNO0FBSVJDLE1BQUFBLFFBQVEsRUFBRSxtRUFKRjtBQUtSQyxNQUFBQSxLQUFLLEVBQUUsTUFBTTtBQUNYLFlBQUksQ0FBQ1QsTUFBTSxDQUFDb0IsbUJBQVosRUFBaUM7QUFDL0IsZ0JBQU0sQ0FBTjtBQUNEO0FBQ0Y7QUFUTyxLQUFWLENBNUNLLENBQVA7QUF3REQ7O0FBOUQ2Qzs7QUFpRWhEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUIxQixzQkFBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBtb2R1bGUgU2VjdXJpdHlDaGVja1xuICovXG5cbmltcG9ydCB7IENoZWNrIH0gZnJvbSAnLi4vQ2hlY2snO1xuaW1wb3J0IENoZWNrR3JvdXAgZnJvbSAnLi4vQ2hlY2tHcm91cCc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uLy4uL0NvbmZpZyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbi8qKlxuICogVGhlIHNlY3VyaXR5IGNoZWNrcyBncm91cCBmb3IgUGFyc2UgU2VydmVyIGNvbmZpZ3VyYXRpb24uXG4gKiBDaGVja3MgY29tbW9uIFBhcnNlIFNlcnZlciBwYXJhbWV0ZXJzIHN1Y2ggYXMgYWNjZXNzIGtleXMuXG4gKi9cbmNsYXNzIENoZWNrR3JvdXBTZXJ2ZXJDb25maWcgZXh0ZW5kcyBDaGVja0dyb3VwIHtcbiAgc2V0TmFtZSgpIHtcbiAgICByZXR1cm4gJ1BhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uJztcbiAgfVxuICBzZXRDaGVja3MoKSB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IENoZWNrKHtcbiAgICAgICAgdGl0bGU6ICdTZWN1cmUgbWFzdGVyIGtleScsXG4gICAgICAgIHdhcm5pbmc6ICdUaGUgUGFyc2UgU2VydmVyIG1hc3RlciBrZXkgaXMgaW5zZWN1cmUgYW5kIHZ1bG5lcmFibGUgdG8gYnJ1dGUgZm9yY2UgYXR0YWNrcy4nLFxuICAgICAgICBzb2x1dGlvbjpcbiAgICAgICAgICAnQ2hvb3NlIGEgbG9uZ2VyIGFuZC9vciBtb3JlIGNvbXBsZXggbWFzdGVyIGtleSB3aXRoIGEgY29tYmluYXRpb24gb2YgdXBwZXItIGFuZCBsb3dlcmNhc2UgY2hhcmFjdGVycywgbnVtYmVycyBhbmQgc3BlY2lhbCBjaGFyYWN0ZXJzLicsXG4gICAgICAgIGNoZWNrOiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgbWFzdGVyS2V5ID0gY29uZmlnLm1hc3RlcktleTtcbiAgICAgICAgICBjb25zdCBoYXNVcHBlckNhc2UgPSAvW0EtWl0vLnRlc3QobWFzdGVyS2V5KTtcbiAgICAgICAgICBjb25zdCBoYXNMb3dlckNhc2UgPSAvW2Etel0vLnRlc3QobWFzdGVyS2V5KTtcbiAgICAgICAgICBjb25zdCBoYXNOdW1iZXJzID0gL1xcZC8udGVzdChtYXN0ZXJLZXkpO1xuICAgICAgICAgIGNvbnN0IGhhc05vbkFscGhhc051bWVyaWNzID0gL1xcVy8udGVzdChtYXN0ZXJLZXkpO1xuICAgICAgICAgIC8vIEVuc3VyZSBsZW5ndGhcbiAgICAgICAgICBpZiAobWFzdGVyS2V5Lmxlbmd0aCA8IDE0KSB7XG4gICAgICAgICAgICB0aHJvdyAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBFbnN1cmUgYXQgbGVhc3QgMyBvdXQgb2YgNCByZXF1aXJlbWVudHMgcGFzc2VkXG4gICAgICAgICAgaWYgKGhhc1VwcGVyQ2FzZSArIGhhc0xvd2VyQ2FzZSArIGhhc051bWJlcnMgKyBoYXNOb25BbHBoYXNOdW1lcmljcyA8IDMpIHtcbiAgICAgICAgICAgIHRocm93IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgICBuZXcgQ2hlY2soe1xuICAgICAgICB0aXRsZTogJ1NlY3VyaXR5IGxvZyBkaXNhYmxlZCcsXG4gICAgICAgIHdhcm5pbmc6XG4gICAgICAgICAgJ1NlY3VyaXR5IGNoZWNrcyBpbiBsb2dzIG1heSBleHBvc2UgdnVsbmVyYWJpbGl0aWVzIHRvIGFueW9uZSB3aXRoIGFjY2VzcyB0byBsb2dzLicsXG4gICAgICAgIHNvbHV0aW9uOiBcIkNoYW5nZSBQYXJzZSBTZXJ2ZXIgY29uZmlndXJhdGlvbiB0byAnc2VjdXJpdHkuZW5hYmxlQ2hlY2tMb2c6IGZhbHNlJy5cIixcbiAgICAgICAgY2hlY2s6ICgpID0+IHtcbiAgICAgICAgICBpZiAoY29uZmlnLnNlY3VyaXR5ICYmIGNvbmZpZy5zZWN1cml0eS5lbmFibGVDaGVja0xvZykge1xuICAgICAgICAgICAgdGhyb3cgMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIG5ldyBDaGVjayh7XG4gICAgICAgIHRpdGxlOiAnQ2xpZW50IGNsYXNzIGNyZWF0aW9uIGRpc2FibGVkJyxcbiAgICAgICAgd2FybmluZzpcbiAgICAgICAgICAnQXR0YWNrZXJzIGFyZSBhbGxvd2VkIHRvIGNyZWF0ZSBuZXcgY2xhc3NlcyB3aXRob3V0IHJlc3RyaWN0aW9uIGFuZCBmbG9vZCB0aGUgZGF0YWJhc2UuJyxcbiAgICAgICAgc29sdXRpb246IFwiQ2hhbmdlIFBhcnNlIFNlcnZlciBjb25maWd1cmF0aW9uIHRvICdhbGxvd0NsaWVudENsYXNzQ3JlYXRpb246IGZhbHNlJy5cIixcbiAgICAgICAgY2hlY2s6ICgpID0+IHtcbiAgICAgICAgICBpZiAoY29uZmlnLmFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiB8fCBjb25maWcuYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgICBuZXcgQ2hlY2soe1xuICAgICAgICB0aXRsZTogJ1VzZXJzIGFyZSBjcmVhdGVkIHdpdGhvdXQgcHVibGljIGFjY2VzcycsXG4gICAgICAgIHdhcm5pbmc6XG4gICAgICAgICAgJ1VzZXJzIHdpdGggcHVibGljIHJlYWQgYWNjZXNzIGFyZSBleHBvc2VkIHRvIGFueW9uZSB3aG8ga25vd3MgdGhlaXIgb2JqZWN0IElEcywgb3IgdG8gYW55b25lIHdobyBjYW4gcXVlcnkgdGhlIFBhcnNlLlVzZXIgY2xhc3MuJyxcbiAgICAgICAgc29sdXRpb246IFwiQ2hhbmdlIFBhcnNlIFNlcnZlciBjb25maWd1cmF0aW9uIHRvICdlbmZvcmNlUHJpdmF0ZVVzZXJzOiB0cnVlJy5cIixcbiAgICAgICAgY2hlY2s6ICgpID0+IHtcbiAgICAgICAgICBpZiAoIWNvbmZpZy5lbmZvcmNlUHJpdmF0ZVVzZXJzKSB7XG4gICAgICAgICAgICB0aHJvdyAxO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF07XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDaGVja0dyb3VwU2VydmVyQ29uZmlnO1xuIl19
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "CheckGroupDatabase", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _CheckGroupDatabase.default;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "CheckGroupServerConfig", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _CheckGroupServerConfig.default;
16
+ }
17
+ });
18
+
19
+ var _CheckGroupDatabase = _interopRequireDefault(require("./CheckGroupDatabase"));
20
+
21
+ var _CheckGroupServerConfig = _interopRequireDefault(require("./CheckGroupServerConfig"));
22
+
23
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9TZWN1cml0eS9DaGVja0dyb3Vwcy9DaGVja0dyb3Vwcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPQTs7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG1vZHVsZSBTZWN1cml0eUNoZWNrXG4gKi9cblxuLyoqXG4gKiBUaGUgbGlzdCBvZiBzZWN1cml0eSBjaGVjayBncm91cHMuXG4gKi9cbmV4cG9ydCB7IGRlZmF1bHQgYXMgQ2hlY2tHcm91cERhdGFiYXNlIH0gZnJvbSAnLi9DaGVja0dyb3VwRGF0YWJhc2UnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBDaGVja0dyb3VwU2VydmVyQ29uZmlnIH0gZnJvbSAnLi9DaGVja0dyb3VwU2VydmVyQ29uZmlnJztcbiJdfQ==
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+
3
+ var _Utils = _interopRequireDefault(require("../Utils"));
4
+
5
+ var _Check = require("./Check");
6
+
7
+ var CheckGroups = _interopRequireWildcard(require("./CheckGroups/CheckGroups"));
8
+
9
+ var _logger = _interopRequireDefault(require("../logger"));
10
+
11
+ var _lodash = require("lodash");
12
+
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
+
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
+
17
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
+
19
+ /**
20
+ * @module SecurityCheck
21
+ */
22
+
23
+ /**
24
+ * The security check runner.
25
+ */
26
+ class CheckRunner {
27
+ /**
28
+ * The security check runner.
29
+ * @param {Object} [config] The configuration options.
30
+ * @param {Boolean} [config.enableCheck=false] Is true if Parse Server should report weak security settings.
31
+ * @param {Boolean} [config.enableCheckLog=false] Is true if the security check report should be written to logs.
32
+ * @param {Object} [config.checkGroups] The check groups to run. Default are the groups defined in `./CheckGroups/CheckGroups.js`.
33
+ */
34
+ constructor(config = {}) {
35
+ this._validateParams(config);
36
+
37
+ const {
38
+ enableCheck = false,
39
+ enableCheckLog = false,
40
+ checkGroups = CheckGroups
41
+ } = config;
42
+ this.enableCheck = enableCheck;
43
+ this.enableCheckLog = enableCheckLog;
44
+ this.checkGroups = checkGroups;
45
+ }
46
+ /**
47
+ * Runs all security checks and returns the results.
48
+ * @params
49
+ * @returns {Object} The security check report.
50
+ */
51
+
52
+
53
+ async run({
54
+ version = '1.0.0'
55
+ } = {}) {
56
+ // Instantiate check groups
57
+ const groups = Object.values(this.checkGroups).filter(c => typeof c === 'function').map(CheckGroup => new CheckGroup()); // Run checks
58
+
59
+ groups.forEach(group => group.run()); // Generate JSON report
60
+
61
+ const report = this._generateReport({
62
+ groups,
63
+ version
64
+ }); // If report should be written to logs
65
+
66
+
67
+ if (this.enableCheckLog) {
68
+ this._logReport(report);
69
+ }
70
+
71
+ return report;
72
+ }
73
+ /**
74
+ * Generates a security check report in JSON format with schema:
75
+ * ```
76
+ * {
77
+ * report: {
78
+ * version: "1.0.0", // The report version, defines the schema
79
+ * state: "fail" // The disjunctive indicator of failed checks in all groups.
80
+ * groups: [ // The check groups
81
+ * {
82
+ * name: "House", // The group name
83
+ * state: "fail" // The disjunctive indicator of failed checks in this group.
84
+ * checks: [ // The checks
85
+ * title: "Door locked", // The check title
86
+ * state: "fail" // The check state
87
+ * warning: "Anyone can enter your house." // The warning.
88
+ * solution: "Lock your door." // The solution.
89
+ * ]
90
+ * },
91
+ * ...
92
+ * ]
93
+ * }
94
+ * }
95
+ * ```
96
+ * @param {Object} params The parameters.
97
+ * @param {Array<CheckGroup>} params.groups The check groups.
98
+ * @param {String} params.version: The report schema version.
99
+ * @returns {Object} The report.
100
+ */
101
+
102
+
103
+ _generateReport({
104
+ groups,
105
+ version
106
+ }) {
107
+ // Create report template
108
+ const report = {
109
+ report: {
110
+ version,
111
+ state: _Check.CheckState.success,
112
+ groups: []
113
+ }
114
+ }; // Identify report version
115
+
116
+ switch (version) {
117
+ case '1.0.0':
118
+ default:
119
+ // For each check group
120
+ for (const group of groups) {
121
+ // Create group report
122
+ const groupReport = {
123
+ name: group.name(),
124
+ state: _Check.CheckState.success,
125
+ checks: []
126
+ }; // Create check reports
127
+
128
+ groupReport.checks = group.checks().map(check => {
129
+ const checkReport = {
130
+ title: check.title,
131
+ state: check.checkState()
132
+ };
133
+
134
+ if (check.checkState() == _Check.CheckState.fail) {
135
+ checkReport.warning = check.warning;
136
+ checkReport.solution = check.solution;
137
+ report.report.state = _Check.CheckState.fail;
138
+ groupReport.state = _Check.CheckState.fail;
139
+ }
140
+
141
+ return checkReport;
142
+ });
143
+ report.report.groups.push(groupReport);
144
+ }
145
+
146
+ }
147
+
148
+ return report;
149
+ }
150
+ /**
151
+ * Logs the security check report.
152
+ * @param {Object} report The report to log.
153
+ */
154
+
155
+
156
+ _logReport(report) {
157
+ // Determine log level depending on whether any check failed
158
+ const log = report.report.state == _Check.CheckState.success ? s => _logger.default.info(s) : s => _logger.default.warn(s); // Declare output
159
+
160
+ const indent = ' ';
161
+ let output = '';
162
+ let checksCount = 0;
163
+ let failedChecksCount = 0;
164
+ let skippedCheckCount = 0; // Traverse all groups and checks for compose output
165
+
166
+ for (const group of report.report.groups) {
167
+ output += `\n- ${group.name}`;
168
+
169
+ for (const check of group.checks) {
170
+ checksCount++;
171
+ output += `\n${indent}${this._getLogIconForState(check.state)} ${check.title}`;
172
+
173
+ if (check.state == _Check.CheckState.fail) {
174
+ failedChecksCount++;
175
+ output += `\n${indent}${indent}Warning: ${check.warning}`;
176
+ output += ` ${check.solution}`;
177
+ } else if (check.state == _Check.CheckState.none) {
178
+ skippedCheckCount++;
179
+ output += `\n${indent}${indent}Test did not execute, this is likely an internal server issue, please report.`;
180
+ }
181
+ }
182
+ }
183
+
184
+ output = `\n###################################` + `\n# #` + `\n# Parse Server Security Check #` + `\n# #` + `\n###################################` + `\n` + `\n${failedChecksCount > 0 ? 'Warning: ' : ''}${failedChecksCount} weak security setting(s) found${failedChecksCount > 0 ? '!' : ''}` + `\n${checksCount} check(s) executed` + `\n${skippedCheckCount} check(s) skipped` + `\n` + `${output}`; // Write log
185
+
186
+ log(output);
187
+ }
188
+ /**
189
+ * Returns an icon for use in the report log output.
190
+ * @param {CheckState} state The check state.
191
+ * @returns {String} The icon.
192
+ */
193
+
194
+
195
+ _getLogIconForState(state) {
196
+ switch (state) {
197
+ case _Check.CheckState.success:
198
+ return '✅';
199
+
200
+ case _Check.CheckState.fail:
201
+ return '❌';
202
+
203
+ default:
204
+ return 'ℹ️';
205
+ }
206
+ }
207
+ /**
208
+ * Validates the constructor parameters.
209
+ * @param {Object} params The parameters to validate.
210
+ */
211
+
212
+
213
+ _validateParams(params) {
214
+ _Utils.default.validateParams(params, {
215
+ enableCheck: {
216
+ t: 'boolean',
217
+ v: _lodash.isBoolean,
218
+ o: true
219
+ },
220
+ enableCheckLog: {
221
+ t: 'boolean',
222
+ v: _lodash.isBoolean,
223
+ o: true
224
+ },
225
+ checkGroups: {
226
+ t: 'array',
227
+ v: _lodash.isArray,
228
+ o: true
229
+ }
230
+ });
231
+ }
232
+
233
+ }
234
+
235
+ module.exports = CheckRunner;
236
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TZWN1cml0eS9DaGVja1J1bm5lci5qcyJdLCJuYW1lcyI6WyJDaGVja1J1bm5lciIsImNvbnN0cnVjdG9yIiwiY29uZmlnIiwiX3ZhbGlkYXRlUGFyYW1zIiwiZW5hYmxlQ2hlY2siLCJlbmFibGVDaGVja0xvZyIsImNoZWNrR3JvdXBzIiwiQ2hlY2tHcm91cHMiLCJydW4iLCJ2ZXJzaW9uIiwiZ3JvdXBzIiwiT2JqZWN0IiwidmFsdWVzIiwiZmlsdGVyIiwiYyIsIm1hcCIsIkNoZWNrR3JvdXAiLCJmb3JFYWNoIiwiZ3JvdXAiLCJyZXBvcnQiLCJfZ2VuZXJhdGVSZXBvcnQiLCJfbG9nUmVwb3J0Iiwic3RhdGUiLCJDaGVja1N0YXRlIiwic3VjY2VzcyIsImdyb3VwUmVwb3J0IiwibmFtZSIsImNoZWNrcyIsImNoZWNrIiwiY2hlY2tSZXBvcnQiLCJ0aXRsZSIsImNoZWNrU3RhdGUiLCJmYWlsIiwid2FybmluZyIsInNvbHV0aW9uIiwicHVzaCIsImxvZyIsInMiLCJsb2dnZXIiLCJpbmZvIiwid2FybiIsImluZGVudCIsIm91dHB1dCIsImNoZWNrc0NvdW50IiwiZmFpbGVkQ2hlY2tzQ291bnQiLCJza2lwcGVkQ2hlY2tDb3VudCIsIl9nZXRMb2dJY29uRm9yU3RhdGUiLCJub25lIiwicGFyYW1zIiwiVXRpbHMiLCJ2YWxpZGF0ZVBhcmFtcyIsInQiLCJ2IiwiaXNCb29sZWFuIiwibyIsImlzQXJyYXkiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUlBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQVJBO0FBQ0E7QUFDQTs7QUFRQTtBQUNBO0FBQ0E7QUFDQSxNQUFNQSxXQUFOLENBQWtCO0FBQ2hCO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0VDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBTSxHQUFHLEVBQVYsRUFBYztBQUN2QixTQUFLQyxlQUFMLENBQXFCRCxNQUFyQjs7QUFDQSxVQUFN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QUFBQSxDQUFDLEVBQUUsU0FBTDtBQUFnQkMsUUFBQUEsQ0FBQyxFQUFFQyxpQkFBbkI7QUFBOEJDLFFBQUFBLENBQUMsRUFBRTtBQUFqQyxPQURjO0FBRTNCakQsTUFBQUEsY0FBYyxFQUFFO0FBQUU4QyxRQUFBQSxDQUFDLEVBQUUsU0FBTDtBQUFnQkMsUUFBQUEsQ0FBQyxFQUFFQyxpQkFBbkI7QUFBOEJDLFFBQUFBLENBQUMsRUFBRTtBQUFqQyxPQUZXO0FBRzNCaEQsTUFBQUEsV0FBVyxFQUFFO0FBQUU2QyxRQUFBQSxDQUFDLEVBQUUsT0FBTDtBQUFjQyxRQUFBQSxDQUFDLEVBQUVHLGVBQWpCO0FBQTBCRCxRQUFBQSxDQUFDLEVBQUU7QUFBN0I7QUFIYyxLQUE3QjtBQUtEOztBQWhNZTs7QUFtTWxCRSxNQUFNLENBQUNDLE9BQVAsR0FBaUJ6RCxXQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG1vZHVsZSBTZWN1cml0eUNoZWNrXG4gKi9cblxuaW1wb3J0IFV0aWxzIGZyb20gJy4uL1V0aWxzJztcbmltcG9ydCB7IENoZWNrU3RhdGUgfSBmcm9tICcuL0NoZWNrJztcbmltcG9ydCAqIGFzIENoZWNrR3JvdXBzIGZyb20gJy4vQ2hlY2tHcm91cHMvQ2hlY2tHcm91cHMnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNCb29sZWFuIH0gZnJvbSAnbG9kYXNoJztcblxuLyoqXG4gKiBUaGUgc2VjdXJpdHkgY2hlY2sgcnVubmVyLlxuICovXG5jbGFzcyBDaGVja1J1bm5lciB7XG4gIC8qKlxuICAgKiBUaGUgc2VjdXJpdHkgY2hlY2sgcnVubmVyLlxuICAgKiBAcGFyYW0ge09iamVjdH0gW2NvbmZpZ10gVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAgICogQHBhcmFtIHtCb29sZWFufSBbY29uZmlnLmVuYWJsZUNoZWNrPWZhbHNlXSBJcyB0cnVlIGlmIFBhcnNlIFNlcnZlciBzaG91bGQgcmVwb3J0IHdlYWsgc2VjdXJpdHkgc2V0dGluZ3MuXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW2NvbmZpZy5lbmFibGVDaGVja0xvZz1mYWxzZV0gSXMgdHJ1ZSBpZiB0aGUgc2VjdXJpdHkgY2hlY2sgcmVwb3J0IHNob3VsZCBiZSB3cml0dGVuIHRvIGxvZ3MuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnLmNoZWNrR3JvdXBzXSBUaGUgY2hlY2sgZ3JvdXBzIHRvIHJ1bi4gRGVmYXVsdCBhcmUgdGhlIGdyb3VwcyBkZWZpbmVkIGluIGAuL0NoZWNrR3JvdXBzL0NoZWNrR3JvdXBzLmpzYC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZyA9IHt9KSB7XG4gICAgdGhpcy5fdmFsaWRhdGVQYXJhbXMoY29uZmlnKTtcbiAgICBjb25zdCB7IGVuYWJsZUNoZWNrID0gZmFsc2UsIGVuYWJsZUNoZWNrTG9nID0gZmFsc2UsIGNoZWNrR3JvdXBzID0gQ2hlY2tHcm91cHMgfSA9IGNvbmZpZztcbiAgICB0aGlzLmVuYWJsZUNoZWNrID0gZW5hYmxlQ2hlY2s7XG4gICAgdGhpcy5lbmFibGVDaGVja0xvZyA9IGVuYWJsZUNoZWNrTG9nO1xuICAgIHRoaXMuY2hlY2tHcm91cHMgPSBjaGVja0dyb3VwcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFsbCBzZWN1cml0eSBjaGVja3MgYW5kIHJldHVybnMgdGhlIHJlc3VsdHMuXG4gICAqIEBwYXJhbXNcbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIHNlY3VyaXR5IGNoZWNrIHJlcG9ydC5cbiAgICovXG4gIGFzeW5jIHJ1bih7IHZlcnNpb24gPSAnMS4wLjAnIH0gPSB7fSkge1xuICAgIC8vIEluc3RhbnRpYXRlIGNoZWNrIGdyb3Vwc1xuICAgIGNvbnN0IGdyb3VwcyA9IE9iamVjdC52YWx1ZXModGhpcy5jaGVja0dyb3VwcylcbiAgICAgIC5maWx0ZXIoYyA9PiB0eXBlb2YgYyA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIC5tYXAoQ2hlY2tHcm91cCA9PiBuZXcgQ2hlY2tHcm91cCgpKTtcblxuICAgIC8vIFJ1biBjaGVja3NcbiAgICBncm91cHMuZm9yRWFjaChncm91cCA9PiBncm91cC5ydW4oKSk7XG5cbiAgICAvLyBHZW5lcmF0ZSBKU09OIHJlcG9ydFxuICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuX2dlbmVyYXRlUmVwb3J0KHsgZ3JvdXBzLCB2ZXJzaW9uIH0pO1xuXG4gICAgLy8gSWYgcmVwb3J0IHNob3VsZCBiZSB3cml0dGVuIHRvIGxvZ3NcbiAgICBpZiAodGhpcy5lbmFibGVDaGVja0xvZykge1xuICAgICAgdGhpcy5fbG9nUmVwb3J0KHJlcG9ydCk7XG4gICAgfVxuICAgIHJldHVybiByZXBvcnQ7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGEgc2VjdXJpdHkgY2hlY2sgcmVwb3J0IGluIEpTT04gZm9ybWF0IHdpdGggc2NoZW1hOlxuICAgKiBgYGBcbiAgICoge1xuICAgKiAgICByZXBvcnQ6IHtcbiAgICogICAgICB2ZXJzaW9uOiBcIjEuMC4wXCIsIC8vIFRoZSByZXBvcnQgdmVyc2lvbiwgZGVmaW5lcyB0aGUgc2NoZW1hXG4gICAqICAgICAgc3RhdGU6IFwiZmFpbFwiICAgICAvLyBUaGUgZGlzanVuY3RpdmUgaW5kaWNhdG9yIG9mIGZhaWxlZCBjaGVja3MgaW4gYWxsIGdyb3Vwcy5cbiAgICogICAgICBncm91cHM6IFsgICAgICAgICAvLyBUaGUgY2hlY2sgZ3JvdXBzXG4gICAqICAgICAgICB7XG4gICAqICAgICAgICAgIG5hbWU6IFwiSG91c2VcIiwgICAgICAgICAgICAvLyBUaGUgZ3JvdXAgbmFtZVxuICAgKiAgICAgICAgICBzdGF0ZTogXCJmYWlsXCIgICAgICAgICAgICAgLy8gVGhlIGRpc2p1bmN0aXZlIGluZGljYXRvciBvZiBmYWlsZWQgY2hlY2tzIGluIHRoaXMgZ3JvdXAuXG4gICAqICAgICAgICAgIGNoZWNrczogWyAgICAgICAgICAgICAgICAgLy8gVGhlIGNoZWNrc1xuICAgKiAgICAgICAgICAgIHRpdGxlOiBcIkRvb3IgbG9ja2VkXCIsICAgLy8gVGhlIGNoZWNrIHRpdGxlXG4gICAqICAgICAgICAgICAgc3RhdGU6IFwiZmFpbFwiICAgICAgICAgICAvLyBUaGUgY2hlY2sgc3RhdGVcbiAgICogICAgICAgICAgICB3YXJuaW5nOiBcIkFueW9uZSBjYW4gZW50ZXIgeW91ciBob3VzZS5cIiAgIC8vIFRoZSB3YXJuaW5nLlxuICAgKiAgICAgICAgICAgIHNvbHV0aW9uOiBcIkxvY2sgeW91ciBkb29yLlwiICAgICAgICAgICAgICAgLy8gVGhlIHNvbHV0aW9uLlxuICAgKiAgICAgICAgICBdXG4gICAqICAgICAgICB9LFxuICAgKiAgICAgICAgLi4uXG4gICAqICAgICAgXVxuICAgKiAgICB9XG4gICAqIH1cbiAgICogYGBgXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSB7QXJyYXk8Q2hlY2tHcm91cD59IHBhcmFtcy5ncm91cHMgVGhlIGNoZWNrIGdyb3Vwcy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhcmFtcy52ZXJzaW9uOiBUaGUgcmVwb3J0IHNjaGVtYSB2ZXJzaW9uLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgcmVwb3J0LlxuICAgKi9cbiAgX2dlbmVyYXRlUmVwb3J0KHsgZ3JvdXBzLCB2ZXJzaW9uIH0pIHtcbiAgICAvLyBDcmVhdGUgcmVwb3J0IHRlbXBsYXRlXG4gICAgY29uc3QgcmVwb3J0ID0ge1xuICAgICAgcmVwb3J0OiB7XG4gICAgICAgIHZlcnNpb24sXG4gICAgICAgIHN0YXRlOiBDaGVja1N0YXRlLnN1Y2Nlc3MsXG4gICAgICAgIGdyb3VwczogW10sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICAvLyBJZGVudGlmeSByZXBvcnQgdmVyc2lvblxuICAgIHN3aXRjaCAodmVyc2lvbikge1xuICAgICAgY2FzZSAnMS4wLjAnOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gRm9yIGVhY2ggY2hlY2sgZ3JvdXBcbiAgICAgICAgZm9yIChjb25zdCBncm91cCBvZiBncm91cHMpIHtcbiAgICAgICAgICAvLyBDcmVhdGUgZ3JvdXAgcmVwb3J0XG4gICAgICAgICAgY29uc3QgZ3JvdXBSZXBvcnQgPSB7XG4gICAgICAgICAgICBuYW1lOiBncm91cC5uYW1lKCksXG4gICAgICAgICAgICBzdGF0ZTogQ2hlY2tTdGF0ZS5zdWNjZXNzLFxuICAgICAgICAgICAgY2hlY2tzOiBbXSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLy8gQ3JlYXRlIGNoZWNrIHJlcG9ydHNcbiAgICAgICAgICBncm91cFJlcG9ydC5jaGVja3MgPSBncm91cC5jaGVja3MoKS5tYXAoY2hlY2sgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hlY2tSZXBvcnQgPSB7XG4gICAgICAgICAgICAgIHRpdGxlOiBjaGVjay50aXRsZSxcbiAgICAgICAgICAgICAgc3RhdGU6IGNoZWNrLmNoZWNrU3RhdGUoKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoY2hlY2suY2hlY2tTdGF0ZSgpID09IENoZWNrU3RhdGUuZmFpbCkge1xuICAgICAgICAgICAgICBjaGVja1JlcG9ydC53YXJuaW5nID0gY2hlY2sud2FybmluZztcbiAgICAgICAgICAgICAgY2hlY2tSZXBvcnQuc29sdXRpb24gPSBjaGVjay5zb2x1dGlvbjtcbiAgICAgICAgICAgICAgcmVwb3J0LnJlcG9ydC5zdGF0ZSA9IENoZWNrU3RhdGUuZmFpbDtcbiAgICAgICAgICAgICAgZ3JvdXBSZXBvcnQuc3RhdGUgPSBDaGVja1N0YXRlLmZhaWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY2hlY2tSZXBvcnQ7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXBvcnQucmVwb3J0Lmdyb3Vwcy5wdXNoKGdyb3VwUmVwb3J0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVwb3J0O1xuICB9XG5cbiAgLyoqXG4gICAqIExvZ3MgdGhlIHNlY3VyaXR5IGNoZWNrIHJlcG9ydC5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcG9ydCBUaGUgcmVwb3J0IHRvIGxvZy5cbiAgICovXG4gIF9sb2dSZXBvcnQocmVwb3J0KSB7XG4gICAgLy8gRGV0ZXJtaW5lIGxvZyBsZXZlbCBkZXBlbmRpbmcgb24gd2hldGhlciBhbnkgY2hlY2sgZmFpbGVkXG4gICAgY29uc3QgbG9nID1cbiAgICAgIHJlcG9ydC5yZXBvcnQuc3RhdGUgPT0gQ2hlY2tTdGF0ZS5zdWNjZXNzID8gcyA9PiBsb2dnZXIuaW5mbyhzKSA6IHMgPT4gbG9nZ2VyLndhcm4ocyk7XG5cbiAgICAvLyBEZWNsYXJlIG91dHB1dFxuICAgIGNvbnN0IGluZGVudCA9ICcgICAnO1xuICAgIGxldCBvdXRwdXQgPSAnJztcbiAgICBsZXQgY2hlY2tzQ291bnQgPSAwO1xuICAgIGxldCBmYWlsZWRDaGVja3NDb3VudCA9IDA7XG4gICAgbGV0IHNraXBwZWRDaGVja0NvdW50ID0gMDtcblxuICAgIC8vIFRyYXZlcnNlIGFsbCBncm91cHMgYW5kIGNoZWNrcyBmb3IgY29tcG9zZSBvdXRwdXRcbiAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHJlcG9ydC5yZXBvcnQuZ3JvdXBzKSB7XG4gICAgICBvdXRwdXQgKz0gYFxcbi0gJHtncm91cC5uYW1lfWA7XG5cbiAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgZ3JvdXAuY2hlY2tzKSB7XG4gICAgICAgIGNoZWNrc0NvdW50Kys7XG4gICAgICAgIG91dHB1dCArPSBgXFxuJHtpbmRlbnR9JHt0aGlzLl9nZXRMb2dJY29uRm9yU3RhdGUoY2hlY2suc3RhdGUpfSAke2NoZWNrLnRpdGxlfWA7XG5cbiAgICAgICAgaWYgKGNoZWNrLnN0YXRlID09IENoZWNrU3RhdGUuZmFpbCkge1xuICAgICAgICAgIGZhaWxlZENoZWNrc0NvdW50Kys7XG4gICAgICAgICAgb3V0cHV0ICs9IGBcXG4ke2luZGVudH0ke2luZGVudH1XYXJuaW5nOiAke2NoZWNrLndhcm5pbmd9YDtcbiAgICAgICAgICBvdXRwdXQgKz0gYCAke2NoZWNrLnNvbHV0aW9ufWA7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hlY2suc3RhdGUgPT0gQ2hlY2tTdGF0ZS5ub25lKSB7XG4gICAgICAgICAgc2tpcHBlZENoZWNrQ291bnQrKztcbiAgICAgICAgICBvdXRwdXQgKz0gYFxcbiR7aW5kZW50fSR7aW5kZW50fVRlc3QgZGlkIG5vdCBleGVjdXRlLCB0aGlzIGlzIGxpa2VseSBhbiBpbnRlcm5hbCBzZXJ2ZXIgaXNzdWUsIHBsZWFzZSByZXBvcnQuYDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dCA9XG4gICAgICBgXFxuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNgICtcbiAgICAgIGBcXG4jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2AgK1xuICAgICAgYFxcbiMgICBQYXJzZSBTZXJ2ZXIgU2VjdXJpdHkgQ2hlY2sgICAjYCArXG4gICAgICBgXFxuIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNgICtcbiAgICAgIGBcXG4jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI2AgK1xuICAgICAgYFxcbmAgK1xuICAgICAgYFxcbiR7XG4gICAgICAgIGZhaWxlZENoZWNrc0NvdW50ID4gMCA/ICdXYXJuaW5nOiAnIDogJydcbiAgICAgIH0ke2ZhaWxlZENoZWNrc0NvdW50fSB3ZWFrIHNlY3VyaXR5IHNldHRpbmcocykgZm91bmQke2ZhaWxlZENoZWNrc0NvdW50ID4gMCA/ICchJyA6ICcnfWAgK1xuICAgICAgYFxcbiR7Y2hlY2tzQ291bnR9IGNoZWNrKHMpIGV4ZWN1dGVkYCArXG4gICAgICBgXFxuJHtza2lwcGVkQ2hlY2tDb3VudH0gY2hlY2socykgc2tpcHBlZGAgK1xuICAgICAgYFxcbmAgK1xuICAgICAgYCR7b3V0cHV0fWA7XG5cbiAgICAvLyBXcml0ZSBsb2dcbiAgICBsb2cob3V0cHV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGljb24gZm9yIHVzZSBpbiB0aGUgcmVwb3J0IGxvZyBvdXRwdXQuXG4gICAqIEBwYXJhbSB7Q2hlY2tTdGF0ZX0gc3RhdGUgVGhlIGNoZWNrIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgaWNvbi5cbiAgICovXG4gIF9nZXRMb2dJY29uRm9yU3RhdGUoc3RhdGUpIHtcbiAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICBjYXNlIENoZWNrU3RhdGUuc3VjY2VzczpcbiAgICAgICAgcmV0dXJuICfinIUnO1xuICAgICAgY2FzZSBDaGVja1N0YXRlLmZhaWw6XG4gICAgICAgIHJldHVybiAn4p2MJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAn4oS577iPJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIFRoZSBwYXJhbWV0ZXJzIHRvIHZhbGlkYXRlLlxuICAgKi9cbiAgX3ZhbGlkYXRlUGFyYW1zKHBhcmFtcykge1xuICAgIFV0aWxzLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywge1xuICAgICAgZW5hYmxlQ2hlY2s6IHsgdDogJ2Jvb2xlYW4nLCB2OiBpc0Jvb2xlYW4sIG86IHRydWUgfSxcbiAgICAgIGVuYWJsZUNoZWNrTG9nOiB7IHQ6ICdib29sZWFuJywgdjogaXNCb29sZWFuLCBvOiB0cnVlIH0sXG4gICAgICBjaGVja0dyb3VwczogeyB0OiAnYXJyYXknLCB2OiBpc0FycmF5LCBvOiB0cnVlIH0sXG4gICAgfSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDaGVja1J1bm5lcjtcbiJdfQ==