kuzzle 2.19.2 → 2.19.3
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/lib/api/controllers/adminController.js +94 -80
- package/lib/api/controllers/authController.js +239 -212
- package/lib/api/controllers/baseController.js +89 -51
- package/lib/api/controllers/bulkController.js +62 -49
- package/lib/api/controllers/clusterController.js +6 -8
- package/lib/api/controllers/collectionController.js +140 -129
- package/lib/api/controllers/debugController.d.ts +2 -2
- package/lib/api/controllers/debugController.js +33 -31
- package/lib/api/controllers/documentController.js +365 -274
- package/lib/api/controllers/index.js +13 -13
- package/lib/api/controllers/indexController.js +46 -50
- package/lib/api/controllers/memoryStorageController.js +410 -360
- package/lib/api/controllers/realtimeController.js +37 -36
- package/lib/api/controllers/securityController.js +553 -412
- package/lib/api/controllers/serverController.js +111 -104
- package/lib/api/documentExtractor.js +75 -68
- package/lib/api/funnel.js +411 -312
- package/lib/api/httpRoutes.js +1493 -324
- package/lib/api/openapi/OpenApiManager.d.ts +1 -1
- package/lib/api/openapi/OpenApiManager.js +22 -22
- package/lib/api/openapi/components/document/count.yaml +1 -1
- package/lib/api/openapi/components/document/create.yaml +2 -2
- package/lib/api/openapi/components/document/delete.yaml +1 -1
- package/lib/api/openapi/components/document/deleteByQuery.yaml +1 -1
- package/lib/api/openapi/components/document/exists.yaml +1 -1
- package/lib/api/openapi/components/document/get.yaml +2 -2
- package/lib/api/openapi/components/document/index.js +12 -12
- package/lib/api/openapi/components/document/replace.yaml +1 -1
- package/lib/api/openapi/components/document/scroll.yaml +1 -1
- package/lib/api/openapi/components/document/validate.yaml +1 -1
- package/lib/api/openapi/components/index.d.ts +2 -2
- package/lib/api/openapi/components/index.js +1 -1
- package/lib/api/openapi/components/security/index.js +1 -1
- package/lib/api/openapi/components/security/upsertUser.yaml +2 -3
- package/lib/api/openapi/index.d.ts +1 -1
- package/lib/api/openapi/openApiGenerator.d.ts +1 -1
- package/lib/api/openapi/openApiGenerator.js +7 -7
- package/lib/api/rateLimiter.js +12 -13
- package/lib/api/request/index.d.ts +4 -4
- package/lib/api/request/kuzzleRequest.d.ts +9 -9
- package/lib/api/request/kuzzleRequest.js +89 -87
- package/lib/api/request/requestContext.d.ts +2 -2
- package/lib/api/request/requestContext.js +17 -17
- package/lib/api/request/requestInput.d.ts +1 -1
- package/lib/api/request/requestInput.js +19 -19
- package/lib/api/request/requestResponse.d.ts +4 -4
- package/lib/api/request/requestResponse.js +31 -33
- package/lib/cluster/command.js +48 -44
- package/lib/cluster/idCardHandler.d.ts +1 -1
- package/lib/cluster/idCardHandler.js +15 -15
- package/lib/cluster/index.js +2 -2
- package/lib/cluster/node.js +301 -269
- package/lib/cluster/publisher.js +45 -46
- package/lib/cluster/state.d.ts +5 -5
- package/lib/cluster/state.js +8 -8
- package/lib/cluster/subscriber.js +163 -113
- package/lib/cluster/workers/IDCardRenewer.js +33 -32
- package/lib/config/default.config.d.ts +1 -1
- package/lib/config/default.config.js +212 -171
- package/lib/config/documentEventAliases.js +6 -6
- package/lib/config/index.js +161 -98
- package/lib/config/sdkCompatibility.json +8 -8
- package/lib/core/auth/formatProcessing.js +7 -7
- package/lib/core/auth/passportResponse.js +7 -7
- package/lib/core/auth/passportWrapper.js +34 -30
- package/lib/core/auth/tokenManager.d.ts +2 -2
- package/lib/core/auth/tokenManager.js +11 -10
- package/lib/core/backend/applicationManager.d.ts +1 -1
- package/lib/core/backend/applicationManager.js +2 -2
- package/lib/core/backend/backend.d.ts +3 -3
- package/lib/core/backend/backend.js +34 -31
- package/lib/core/backend/backendCluster.d.ts +2 -2
- package/lib/core/backend/backendCluster.js +5 -5
- package/lib/core/backend/backendConfig.d.ts +2 -2
- package/lib/core/backend/backendConfig.js +3 -3
- package/lib/core/backend/backendController.d.ts +2 -2
- package/lib/core/backend/backendController.js +9 -10
- package/lib/core/backend/backendErrors.d.ts +3 -3
- package/lib/core/backend/backendErrors.js +2 -1
- package/lib/core/backend/backendHook.d.ts +2 -2
- package/lib/core/backend/backendHook.js +5 -5
- package/lib/core/backend/backendImport.d.ts +3 -3
- package/lib/core/backend/backendImport.js +23 -23
- package/lib/core/backend/backendOpenApi.d.ts +2 -2
- package/lib/core/backend/backendOpenApi.js +16 -16
- package/lib/core/backend/backendPipe.d.ts +2 -2
- package/lib/core/backend/backendPipe.js +6 -6
- package/lib/core/backend/backendPlugin.d.ts +4 -4
- package/lib/core/backend/backendPlugin.js +14 -14
- package/lib/core/backend/backendStorage.d.ts +2 -2
- package/lib/core/backend/backendStorage.js +1 -2
- package/lib/core/backend/backendVault.d.ts +2 -2
- package/lib/core/backend/backendVault.js +3 -3
- package/lib/core/backend/index.d.ts +14 -14
- package/lib/core/backend/internalLogger.d.ts +1 -1
- package/lib/core/backend/internalLogger.js +5 -5
- package/lib/core/cache/cacheDbEnum.js +4 -4
- package/lib/core/cache/cacheEngine.js +79 -85
- package/lib/core/network/accessLogger.js +126 -120
- package/lib/core/network/clientConnection.js +5 -5
- package/lib/core/network/context.js +8 -8
- package/lib/core/network/entryPoint.js +100 -85
- package/lib/core/network/httpRouter/index.js +63 -60
- package/lib/core/network/httpRouter/routeHandler.js +18 -19
- package/lib/core/network/httpRouter/routePart.js +23 -19
- package/lib/core/network/protocolManifest.js +3 -3
- package/lib/core/network/protocols/httpMessage.js +8 -10
- package/lib/core/network/protocols/httpwsProtocol.js +305 -250
- package/lib/core/network/protocols/internalProtocol.js +27 -24
- package/lib/core/network/protocols/mqttProtocol.js +106 -96
- package/lib/core/network/protocols/protocol.js +20 -17
- package/lib/core/network/router.js +56 -46
- package/lib/core/plugin/plugin.js +151 -120
- package/lib/core/plugin/pluginContext.d.ts +7 -7
- package/lib/core/plugin/pluginContext.js +48 -44
- package/lib/core/plugin/pluginManifest.js +13 -12
- package/lib/core/plugin/pluginRepository.js +26 -27
- package/lib/core/plugin/pluginsManager.js +425 -304
- package/lib/core/plugin/privilegedContext.js +3 -3
- package/lib/core/realtime/actionEnum.js +1 -1
- package/lib/core/realtime/channel.d.ts +1 -1
- package/lib/core/realtime/channel.js +22 -22
- package/lib/core/realtime/connectionRooms.d.ts +1 -1
- package/lib/core/realtime/hotelClerk.d.ts +2 -2
- package/lib/core/realtime/hotelClerk.js +53 -50
- package/lib/core/realtime/index.js +5 -5
- package/lib/core/realtime/notification/document.js +25 -25
- package/lib/core/realtime/notification/index.js +4 -4
- package/lib/core/realtime/notification/server.js +3 -3
- package/lib/core/realtime/notification/user.js +4 -4
- package/lib/core/realtime/notifier.js +113 -75
- package/lib/core/realtime/room.d.ts +1 -1
- package/lib/core/realtime/subscription.d.ts +1 -1
- package/lib/core/realtime/subscription.js +1 -1
- package/lib/core/security/index.js +8 -8
- package/lib/core/security/profileRepository.d.ts +6 -6
- package/lib/core/security/profileRepository.js +48 -45
- package/lib/core/security/roleRepository.js +127 -115
- package/lib/core/security/securityLoader.js +70 -63
- package/lib/core/security/tokenRepository.js +132 -118
- package/lib/core/security/userRepository.js +104 -88
- package/lib/core/shared/KoncordeWrapper.d.ts +1 -1
- package/lib/core/shared/KoncordeWrapper.js +3 -1
- package/lib/core/shared/abstractManifest.js +22 -23
- package/lib/core/shared/repository.js +69 -67
- package/lib/core/shared/sdk/embeddedSdk.d.ts +2 -2
- package/lib/core/shared/sdk/embeddedSdk.js +36 -32
- package/lib/core/shared/sdk/funnelProtocol.d.ts +1 -1
- package/lib/core/shared/sdk/funnelProtocol.js +11 -11
- package/lib/core/shared/sdk/impersonatedSdk.js +19 -18
- package/lib/core/shared/store.js +127 -32
- package/lib/core/statistics/index.js +2 -2
- package/lib/core/statistics/statistics.js +99 -85
- package/lib/core/storage/clientAdapter.js +219 -136
- package/lib/core/storage/indexCache.js +3 -3
- package/lib/core/storage/storageEngine.js +10 -13
- package/lib/core/storage/storeScopeEnum.js +3 -3
- package/lib/core/validation/baseType.js +12 -10
- package/lib/core/validation/index.js +2 -2
- package/lib/core/validation/types/anything.js +4 -4
- package/lib/core/validation/types/boolean.js +7 -7
- package/lib/core/validation/types/date.js +165 -131
- package/lib/core/validation/types/email.js +18 -21
- package/lib/core/validation/types/enum.js +34 -21
- package/lib/core/validation/types/geoPoint.js +7 -7
- package/lib/core/validation/types/geoShape.js +148 -125
- package/lib/core/validation/types/integer.js +9 -9
- package/lib/core/validation/types/ipAddress.js +17 -19
- package/lib/core/validation/types/numeric.js +36 -29
- package/lib/core/validation/types/object.js +19 -19
- package/lib/core/validation/types/string.js +36 -29
- package/lib/core/validation/types/url.js +17 -19
- package/lib/core/validation/validation.js +422 -378
- package/lib/kerror/codes/1-services.json +7 -1
- package/lib/kerror/codes/4-plugin.json +2 -2
- package/lib/kerror/codes/index.js +85 -63
- package/lib/kerror/errors/badRequestError.d.ts +1 -1
- package/lib/kerror/errors/externalServiceError.d.ts +1 -1
- package/lib/kerror/errors/forbiddenError.d.ts +1 -1
- package/lib/kerror/errors/gatewayTimeoutError.d.ts +1 -1
- package/lib/kerror/errors/index.d.ts +15 -15
- package/lib/kerror/errors/internalError.d.ts +1 -1
- package/lib/kerror/errors/kuzzleError.d.ts +1 -1
- package/lib/kerror/errors/multipleErrorsError.d.ts +1 -1
- package/lib/kerror/errors/multipleErrorsError.js +1 -1
- package/lib/kerror/errors/notFoundError.d.ts +1 -1
- package/lib/kerror/errors/partialError.d.ts +1 -1
- package/lib/kerror/errors/partialError.js +1 -1
- package/lib/kerror/errors/pluginImplementationError.d.ts +1 -1
- package/lib/kerror/errors/pluginImplementationError.js +2 -1
- package/lib/kerror/errors/preconditionError.d.ts +1 -1
- package/lib/kerror/errors/serviceUnavailableError.d.ts +1 -1
- package/lib/kerror/errors/sizeLimitError.d.ts +1 -1
- package/lib/kerror/errors/tooManyRequestsError.d.ts +1 -1
- package/lib/kerror/errors/unauthorizedError.d.ts +1 -1
- package/lib/kerror/index.d.ts +3 -3
- package/lib/kerror/index.js +17 -16
- package/lib/kuzzle/dumpGenerator.js +130 -114
- package/lib/kuzzle/event/kuzzleEventEmitter.js +96 -70
- package/lib/kuzzle/event/pipeRunner.js +25 -24
- package/lib/kuzzle/event/waterfall.js +13 -15
- package/lib/kuzzle/index.js +2 -2
- package/lib/kuzzle/internalIndexHandler.js +80 -59
- package/lib/kuzzle/kuzzle.js +99 -99
- package/lib/kuzzle/kuzzleStateEnum.js +1 -1
- package/lib/kuzzle/log.js +23 -18
- package/lib/kuzzle/vault.js +34 -19
- package/lib/model/security/profile.d.ts +3 -3
- package/lib/model/security/profile.js +38 -37
- package/lib/model/security/rights.js +5 -5
- package/lib/model/security/role.d.ts +3 -3
- package/lib/model/security/role.js +25 -26
- package/lib/model/security/token.d.ts +1 -1
- package/lib/model/security/token.js +4 -4
- package/lib/model/security/user.d.ts +2 -2
- package/lib/model/security/user.js +9 -9
- package/lib/model/storage/apiKey.js +43 -33
- package/lib/model/storage/baseModel.js +49 -45
- package/lib/service/cache/redis.js +60 -55
- package/lib/service/service.js +17 -17
- package/lib/service/storage/elasticsearch.js +839 -755
- package/lib/service/storage/esWrapper.js +103 -86
- package/lib/service/storage/queryTranslator.js +52 -59
- package/lib/types/Controller.d.ts +3 -3
- package/lib/types/ControllerDefinition.d.ts +3 -3
- package/lib/types/DebugModule.d.ts +2 -2
- package/lib/types/DebugModule.js +1 -1
- package/lib/types/Global.d.ts +1 -1
- package/lib/types/HttpStream.d.ts +2 -1
- package/lib/types/HttpStream.js +7 -5
- package/lib/types/Kuzzle.d.ts +1 -1
- package/lib/types/KuzzleDocument.d.ts +1 -1
- package/lib/types/OpenApiDefinition.d.ts +1 -1
- package/lib/types/PasswordPolicy.d.ts +1 -1
- package/lib/types/Plugin.d.ts +6 -6
- package/lib/types/Plugin.js +2 -2
- package/lib/types/Policy.d.ts +1 -1
- package/lib/types/RequestPayload.d.ts +1 -1
- package/lib/types/ResponsePayload.d.ts +1 -1
- package/lib/types/Token.d.ts +1 -1
- package/lib/types/User.d.ts +1 -1
- package/lib/types/config/DumpConfiguration.d.ts +8 -8
- package/lib/types/config/HttpConfiguration.d.ts +1 -1
- package/lib/types/config/KuzzleConfiguration.d.ts +1 -1
- package/lib/types/config/LimitsConfiguration.d.ts +8 -8
- package/lib/types/config/PluginsConfiguration.d.ts +4 -4
- package/lib/types/config/SecurityConfiguration.d.ts +62 -62
- package/lib/types/config/ServerConfiguration.d.ts +55 -55
- package/lib/types/config/ServicesConfiguration.d.ts +2 -2
- package/lib/types/config/internalCache/InternalCacheRedisConfiguration.d.ts +10 -10
- package/lib/types/config/publicCache/PublicCacheRedisConfiguration.d.ts +3 -3
- package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +194 -110
- package/lib/types/errors/ErrorDefinition.d.ts +1 -1
- package/lib/types/errors/ErrorDomains.d.ts +1 -1
- package/lib/types/index.d.ts +38 -38
- package/lib/types/realtime/RealtimeScope.d.ts +1 -1
- package/lib/types/realtime/RealtimeUsers.d.ts +1 -1
- package/lib/util/assertType.js +13 -11
- package/lib/util/async.d.ts +1 -0
- package/lib/util/async.js +61 -0
- package/lib/util/asyncStore.js +19 -21
- package/lib/util/bufferedPassThrough.d.ts +2 -2
- package/lib/util/bufferedPassThrough.js +4 -4
- package/lib/util/bytes.js +9 -13
- package/lib/util/crypto.js +1 -1
- package/lib/util/debug.js +5 -5
- package/lib/util/deprecate.js +24 -21
- package/lib/util/didYouMean.js +7 -7
- package/lib/util/dump-collection.d.ts +2 -2
- package/lib/util/dump-collection.js +26 -26
- package/lib/util/esRequest.d.ts +1 -0
- package/lib/util/esRequest.js +62 -0
- package/lib/util/extractFields.js +24 -25
- package/lib/util/inflector.js +5 -5
- package/lib/util/koncordeCompat.d.ts +2 -2
- package/lib/util/koncordeCompat.js +5 -5
- package/lib/util/memoize.js +3 -5
- package/lib/util/mutex.d.ts +19 -1
- package/lib/util/mutex.js +39 -12
- package/lib/util/name-generator.js +1331 -1331
- package/lib/util/promback.js +8 -10
- package/lib/util/readYamlFile.d.ts +1 -1
- package/lib/util/readYamlFile.js +1 -1
- package/lib/util/requestAssertions.js +34 -34
- package/lib/util/safeObject.js +5 -5
- package/lib/util/stackTrace.js +20 -22
- package/lib/util/wildcard.js +15 -15
- package/package.json +6 -6
- package/npm-shrinkwrap.json +0 -19422
|
@@ -52,7 +52,7 @@ const bluebird_1 = __importDefault(require("bluebird"));
|
|
|
52
52
|
const rights_1 = __importDefault(require("./rights"));
|
|
53
53
|
const kerror = __importStar(require("../../kerror"));
|
|
54
54
|
const safeObject_1 = require("../../util/safeObject");
|
|
55
|
-
const assertionError = kerror.wrap(
|
|
55
|
+
const assertionError = kerror.wrap("api", "assert");
|
|
56
56
|
/**
|
|
57
57
|
* @class Profile
|
|
58
58
|
*/
|
|
@@ -70,10 +70,10 @@ class Profile {
|
|
|
70
70
|
*/
|
|
71
71
|
async getPolicies() {
|
|
72
72
|
if (!global.kuzzle) {
|
|
73
|
-
throw kerror.get(
|
|
73
|
+
throw kerror.get("security", "profile", "uninitialized", this._id);
|
|
74
74
|
}
|
|
75
75
|
return bluebird_1.default.map(this.optimizedPolicies, async ({ restrictedTo, roleId }) => {
|
|
76
|
-
const role = await global.kuzzle.ask(
|
|
76
|
+
const role = await global.kuzzle.ask("core:security:role:get", roleId);
|
|
77
77
|
return { restrictedTo, role };
|
|
78
78
|
});
|
|
79
79
|
}
|
|
@@ -82,23 +82,24 @@ class Profile {
|
|
|
82
82
|
* @returns {Promise}
|
|
83
83
|
*/
|
|
84
84
|
async getAllowedPolicies(request) {
|
|
85
|
-
if (this.optimizedPolicies === undefined ||
|
|
85
|
+
if (this.optimizedPolicies === undefined ||
|
|
86
|
+
this.optimizedPolicies.length === 0) {
|
|
86
87
|
return [];
|
|
87
88
|
}
|
|
88
89
|
const policies = await this.getPolicies();
|
|
89
|
-
return policies.filter(policy => policy.role.isActionAllowed(request));
|
|
90
|
+
return policies.filter((policy) => policy.role.isActionAllowed(request));
|
|
90
91
|
}
|
|
91
92
|
/**
|
|
92
93
|
* @param {Request} request
|
|
93
94
|
* @returns {Promise<boolean>}
|
|
94
95
|
*/
|
|
95
96
|
async isActionAllowed(request) {
|
|
96
|
-
if (this.optimizedPolicies === undefined ||
|
|
97
|
+
if (this.optimizedPolicies === undefined ||
|
|
98
|
+
this.optimizedPolicies.length === 0) {
|
|
97
99
|
return false;
|
|
98
100
|
}
|
|
99
101
|
const allowedPolicies = await this.getAllowedPolicies(request);
|
|
100
|
-
return allowedPolicies
|
|
101
|
-
.some(policy => policy.role.checkRestrictions(request.input.args.index, request.input.args.collection, policy.restrictedTo));
|
|
102
|
+
return allowedPolicies.some((policy) => policy.role.checkRestrictions(request.input.args.index, request.input.args.collection, policy.restrictedTo));
|
|
102
103
|
}
|
|
103
104
|
/**
|
|
104
105
|
* Validates the Profile format
|
|
@@ -111,63 +112,63 @@ class Profile {
|
|
|
111
112
|
async validateDefinition({ strict = false } = {}) {
|
|
112
113
|
this.validateRateLimit();
|
|
113
114
|
if (!this.policies) {
|
|
114
|
-
throw assertionError.get(
|
|
115
|
+
throw assertionError.get("missing_argument", `${this._id}.policies`);
|
|
115
116
|
}
|
|
116
117
|
if (!Array.isArray(this.policies)) {
|
|
117
|
-
throw assertionError.get(
|
|
118
|
+
throw assertionError.get("invalid_type", `${this._id}.policies`, "object[]");
|
|
118
119
|
}
|
|
119
120
|
if (this.policies.length === 0) {
|
|
120
|
-
throw assertionError.get(
|
|
121
|
+
throw assertionError.get("empty_argument", `${this._id}.policies`);
|
|
121
122
|
}
|
|
122
123
|
let i = 0;
|
|
123
124
|
for (const policy of this.policies) {
|
|
124
125
|
if (!policy.roleId) {
|
|
125
|
-
throw assertionError.get(
|
|
126
|
+
throw assertionError.get("missing_argument", `${this._id}.policies[${i}].roleId`);
|
|
126
127
|
}
|
|
127
128
|
for (const member of Object.keys(policy)) {
|
|
128
|
-
if (member !==
|
|
129
|
-
throw assertionError.get(
|
|
129
|
+
if (member !== "roleId" && member !== "restrictedTo") {
|
|
130
|
+
throw assertionError.get("unexpected_argument", `${this._id}.policies[${i}].${member}`, '"roleId", "restrictedTo"');
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
133
|
if (policy.restrictedTo) {
|
|
133
134
|
if (!Array.isArray(policy.restrictedTo)) {
|
|
134
|
-
throw assertionError.get(
|
|
135
|
+
throw assertionError.get("invalid_type", `${this._id}.policies[${i}].restrictedTo`, "object[]");
|
|
135
136
|
}
|
|
136
137
|
let j = 0;
|
|
137
138
|
for (const restriction of policy.restrictedTo) {
|
|
138
139
|
if (!(0, safeObject_1.isPlainObject)(restriction)) {
|
|
139
|
-
throw assertionError.get(
|
|
140
|
+
throw assertionError.get("invalid_type", `${this._id}.policies[${i}].restrictedTo[${restriction}]`, "object");
|
|
140
141
|
}
|
|
141
142
|
if (restriction.index === null || restriction.index === undefined) {
|
|
142
|
-
throw assertionError.get(
|
|
143
|
+
throw assertionError.get("missing_argument", `${this._id}.policies[${i}].restrictedTo[${j}].index`);
|
|
143
144
|
}
|
|
144
145
|
if (strict) {
|
|
145
|
-
const indexExists = await global.kuzzle.ask(
|
|
146
|
+
const indexExists = await global.kuzzle.ask("core:storage:public:index:exist", restriction.index);
|
|
146
147
|
if (!indexExists) {
|
|
147
|
-
throw kerror.get(
|
|
148
|
+
throw kerror.get("services", "storage", "unknown_index", restriction.index);
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
|
-
if (restriction.collections !== undefined
|
|
151
|
-
|
|
151
|
+
if (restriction.collections !== undefined &&
|
|
152
|
+
restriction.collections !== null) {
|
|
152
153
|
if (!Array.isArray(restriction.collections)) {
|
|
153
|
-
throw assertionError.get(
|
|
154
|
+
throw assertionError.get("invalid_type", `${this._id}.policies[${i}].restrictedTo[${j}].collections`, "string[]");
|
|
154
155
|
}
|
|
155
156
|
if (strict) {
|
|
156
157
|
const invalidCollections = [];
|
|
157
158
|
for (const collection of restriction.collections) {
|
|
158
|
-
const isValid = await global.kuzzle.ask(
|
|
159
|
+
const isValid = await global.kuzzle.ask("core:storage:public:collection:exist", restriction.index, collection);
|
|
159
160
|
if (!isValid) {
|
|
160
161
|
invalidCollections.push(collection);
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
if (invalidCollections.length > 0) {
|
|
164
|
-
throw kerror.get(
|
|
165
|
+
throw kerror.get("services", "storage", "unknown_collection", restriction.index, invalidCollections);
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
for (const member of Object.keys(restriction)) {
|
|
169
|
-
if (member !==
|
|
170
|
-
throw assertionError.get(
|
|
170
|
+
if (member !== "index" && member !== "collections") {
|
|
171
|
+
throw assertionError.get("unexpected_argument", `${this._id}.policies[${i}].restrictedTo[${j}].${member}`, '"index", "collections"');
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
j++;
|
|
@@ -189,15 +190,15 @@ class Profile {
|
|
|
189
190
|
const role = policy.role;
|
|
190
191
|
let restrictedTo = lodash_1.default.cloneDeep(policy.restrictedTo);
|
|
191
192
|
if (restrictedTo === undefined || restrictedTo.size === 0) {
|
|
192
|
-
restrictedTo = new Map([[
|
|
193
|
+
restrictedTo = new Map([["*", ["*"]]]);
|
|
193
194
|
}
|
|
194
195
|
for (const [controller, rights] of Object.entries(role.controllers)) {
|
|
195
196
|
for (const [action, actionRights] of Object.entries(rights.actions)) {
|
|
196
|
-
for (const [restrictedIndex, restrictedCollections] of restrictedTo.entries()) {
|
|
197
|
+
for (const [restrictedIndex, restrictedCollections,] of restrictedTo.entries()) {
|
|
197
198
|
let collections = restrictedCollections;
|
|
198
|
-
if (restrictedCollections === undefined
|
|
199
|
-
|
|
200
|
-
collections = [
|
|
199
|
+
if (restrictedCollections === undefined ||
|
|
200
|
+
restrictedCollections.length === 0) {
|
|
201
|
+
collections = ["*"];
|
|
201
202
|
}
|
|
202
203
|
for (const collection of collections) {
|
|
203
204
|
const rightsItem = {
|
|
@@ -205,12 +206,12 @@ class Profile {
|
|
|
205
206
|
collection,
|
|
206
207
|
controller,
|
|
207
208
|
index: restrictedIndex,
|
|
208
|
-
value: actionRights
|
|
209
|
+
value: actionRights,
|
|
209
210
|
};
|
|
210
211
|
const rightsObject = {
|
|
211
212
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
212
213
|
// @ts-ignore
|
|
213
|
-
[this.constructor._hash(rightsItem)]: rightsItem
|
|
214
|
+
[this.constructor._hash(rightsItem)]: rightsItem,
|
|
214
215
|
};
|
|
215
216
|
lodash_1.default.assignWith(profileRights, rightsObject, rights_1.default.merge);
|
|
216
217
|
}
|
|
@@ -227,12 +228,12 @@ class Profile {
|
|
|
227
228
|
if (this.rateLimit === null || this.rateLimit === undefined) {
|
|
228
229
|
this.rateLimit = 0;
|
|
229
230
|
}
|
|
230
|
-
if (typeof this.rateLimit !==
|
|
231
|
-
|
|
232
|
-
throw assertionError.get(
|
|
231
|
+
if (typeof this.rateLimit !== "number" ||
|
|
232
|
+
!Number.isInteger(this.rateLimit)) {
|
|
233
|
+
throw assertionError.get("invalid_type", "rateLimit", "integer");
|
|
233
234
|
}
|
|
234
235
|
if (this.rateLimit < 0) {
|
|
235
|
-
throw assertionError.get(
|
|
236
|
+
throw assertionError.get("invalid_argument", "rateLimit", "positive integer, or zero");
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
}
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
* limitations under the License.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
"use strict";
|
|
23
23
|
|
|
24
|
-
function isAllowed
|
|
25
|
-
return obj && (obj.value ===
|
|
24
|
+
function isAllowed(obj) {
|
|
25
|
+
return obj && (obj.value === "allowed" || obj.value === true);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -32,8 +32,8 @@ function isAllowed (obj) {
|
|
|
32
32
|
*
|
|
33
33
|
* @returns {Object} the merged policies rights
|
|
34
34
|
*/
|
|
35
|
-
function merge
|
|
36
|
-
cur.value = isAllowed(cur) || isAllowed(prev) ?
|
|
35
|
+
function merge(prev, cur) {
|
|
36
|
+
cur.value = isAllowed(cur) || isAllowed(prev) ? "allowed" : "denied";
|
|
37
37
|
|
|
38
38
|
return cur;
|
|
39
39
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ControllerRight, ControllerRights } from
|
|
2
|
-
import { KuzzleRequest } from
|
|
3
|
-
import { OptimizedPolicyRestrictions } from
|
|
1
|
+
import { ControllerRight, ControllerRights } from "../../types/ControllerRights";
|
|
2
|
+
import { KuzzleRequest } from "../../../index";
|
|
3
|
+
import { OptimizedPolicyRestrictions } from "../../types/PolicyRestrictions";
|
|
4
4
|
/**
|
|
5
5
|
* @class Role
|
|
6
6
|
*/
|
|
@@ -47,7 +47,7 @@ exports.Role = void 0;
|
|
|
47
47
|
const kerror = __importStar(require("../../kerror"));
|
|
48
48
|
const safeObject_1 = require("../../util/safeObject");
|
|
49
49
|
const array_1 = require("../../util/array");
|
|
50
|
-
const assertionError = kerror.wrap(
|
|
50
|
+
const assertionError = kerror.wrap("api", "assert");
|
|
51
51
|
/**
|
|
52
52
|
* @class Role
|
|
53
53
|
*/
|
|
@@ -61,7 +61,7 @@ class Role {
|
|
|
61
61
|
*/
|
|
62
62
|
isActionAllowed(request) {
|
|
63
63
|
if (!global.kuzzle) {
|
|
64
|
-
throw kerror.get(
|
|
64
|
+
throw kerror.get("security", "role", "uninitialized", this._id);
|
|
65
65
|
}
|
|
66
66
|
if (this.controllers === undefined || this.controllers === null) {
|
|
67
67
|
return false;
|
|
@@ -70,15 +70,16 @@ class Role {
|
|
|
70
70
|
// @deprecated - the "memoryStorage" alias should be removed in the next
|
|
71
71
|
// major version
|
|
72
72
|
// Handles the memory storage controller aliases: ms, memoryStorage
|
|
73
|
-
if ((request.input.controller ===
|
|
74
|
-
|
|
73
|
+
if ((request.input.controller === "ms" ||
|
|
74
|
+
request.input.controller === "memoryStorage") &&
|
|
75
|
+
(this.controllers.ms || this.controllers.memoryStorage)) {
|
|
75
76
|
controllerRights = this.controllers.ms || this.controllers.memoryStorage;
|
|
76
77
|
}
|
|
77
78
|
else if ((0, safeObject_1.has)(this.controllers, request.input.controller)) {
|
|
78
79
|
controllerRights = this.controllers[request.input.controller];
|
|
79
80
|
}
|
|
80
|
-
else if (this.controllers[
|
|
81
|
-
controllerRights = this.controllers[
|
|
81
|
+
else if (this.controllers["*"] !== undefined) {
|
|
82
|
+
controllerRights = this.controllers["*"];
|
|
82
83
|
}
|
|
83
84
|
else {
|
|
84
85
|
return false;
|
|
@@ -90,13 +91,13 @@ class Role {
|
|
|
90
91
|
if ((0, safeObject_1.has)(controllerRights.actions, request.input.action)) {
|
|
91
92
|
actionRights = controllerRights.actions[request.input.action];
|
|
92
93
|
}
|
|
93
|
-
else if (controllerRights.actions[
|
|
94
|
-
actionRights = controllerRights.actions[
|
|
94
|
+
else if (controllerRights.actions["*"] !== undefined) {
|
|
95
|
+
actionRights = controllerRights.actions["*"];
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
97
98
|
return false;
|
|
98
99
|
}
|
|
99
|
-
if (typeof actionRights !==
|
|
100
|
+
if (typeof actionRights !== "boolean" || !actionRights) {
|
|
100
101
|
return false;
|
|
101
102
|
}
|
|
102
103
|
return true;
|
|
@@ -106,17 +107,15 @@ class Role {
|
|
|
106
107
|
*/
|
|
107
108
|
async validateDefinition() {
|
|
108
109
|
if (this.controllers === undefined || this.controllers === null) {
|
|
109
|
-
throw assertionError.get(
|
|
110
|
+
throw assertionError.get("missing_argument", `${this._id}.controllers`);
|
|
110
111
|
}
|
|
111
112
|
if (!(0, safeObject_1.isPlainObject)(this.controllers)) {
|
|
112
|
-
throw assertionError.get(
|
|
113
|
+
throw assertionError.get("invalid_type", `${this._id}.controllers`, "object");
|
|
113
114
|
}
|
|
114
115
|
if (Object.keys(this.controllers).length === 0) {
|
|
115
|
-
throw assertionError.get(
|
|
116
|
+
throw assertionError.get("empty_argument", `${this._id}.controllers`);
|
|
116
117
|
}
|
|
117
|
-
Object
|
|
118
|
-
.entries(this.controllers)
|
|
119
|
-
.forEach(entry => this.validateControllerRights(...entry));
|
|
118
|
+
Object.entries(this.controllers).forEach((entry) => this.validateControllerRights(...entry));
|
|
120
119
|
}
|
|
121
120
|
/**
|
|
122
121
|
* @param {String} index
|
|
@@ -163,23 +162,23 @@ class Role {
|
|
|
163
162
|
*/
|
|
164
163
|
validateControllerRights(name, controller) {
|
|
165
164
|
if (!(0, safeObject_1.isPlainObject)(controller)) {
|
|
166
|
-
throw assertionError.get(
|
|
165
|
+
throw assertionError.get("invalid_type", name, "object");
|
|
167
166
|
}
|
|
168
167
|
if (Object.keys(controller).length === 0) {
|
|
169
|
-
throw assertionError.get(
|
|
168
|
+
throw assertionError.get("empty_argument", name);
|
|
170
169
|
}
|
|
171
|
-
if (!(0, safeObject_1.has)(controller,
|
|
172
|
-
throw assertionError.get(
|
|
170
|
+
if (!(0, safeObject_1.has)(controller, "actions")) {
|
|
171
|
+
throw assertionError.get("missing_argument", name);
|
|
173
172
|
}
|
|
174
173
|
if (!(0, safeObject_1.isPlainObject)(controller.actions)) {
|
|
175
|
-
throw assertionError.get(
|
|
174
|
+
throw assertionError.get("invalid_type", `${name}.actions`, "object");
|
|
176
175
|
}
|
|
177
176
|
if (Object.keys(controller.actions).length === 0) {
|
|
178
|
-
throw assertionError.get(
|
|
177
|
+
throw assertionError.get("empty_argument", `${name}.actions`);
|
|
179
178
|
}
|
|
180
179
|
for (const [actionName, action] of Object.entries(controller.actions)) {
|
|
181
|
-
if (typeof action !==
|
|
182
|
-
throw assertionError.get(
|
|
180
|
+
if (typeof action !== "boolean") {
|
|
181
|
+
throw assertionError.get("invalid_type", `${name}.actions.${actionName}`, "boolean");
|
|
183
182
|
}
|
|
184
183
|
}
|
|
185
184
|
}
|
|
@@ -189,12 +188,12 @@ class Role {
|
|
|
189
188
|
* @returns {boolean}
|
|
190
189
|
*/
|
|
191
190
|
canLogIn() {
|
|
192
|
-
for (const controllerKey of [
|
|
191
|
+
for (const controllerKey of ["auth", "*"]) {
|
|
193
192
|
if (this.controllers[controllerKey]) {
|
|
194
193
|
const controller = this.controllers[controllerKey];
|
|
195
|
-
for (const actionKey of [
|
|
194
|
+
for (const actionKey of ["login", "*"]) {
|
|
196
195
|
const action = controller.actions[actionKey];
|
|
197
|
-
if (typeof action ===
|
|
196
|
+
if (typeof action === "boolean" && action) {
|
|
198
197
|
return true;
|
|
199
198
|
}
|
|
200
199
|
}
|
|
@@ -23,7 +23,7 @@ export declare class Token implements TokenContent {
|
|
|
23
23
|
jwt: string;
|
|
24
24
|
refreshed: boolean;
|
|
25
25
|
constructor(data?: TokenContent);
|
|
26
|
-
get type():
|
|
26
|
+
get type(): "apiKey" | "authToken";
|
|
27
27
|
static get AUTH_PREFIX(): string;
|
|
28
28
|
static get APIKEY_PREFIX(): string;
|
|
29
29
|
}
|
|
@@ -35,15 +35,15 @@ class Token {
|
|
|
35
35
|
}
|
|
36
36
|
get type() {
|
|
37
37
|
if (this.jwt && this.jwt.startsWith(Token.APIKEY_PREFIX)) {
|
|
38
|
-
return
|
|
38
|
+
return "apiKey";
|
|
39
39
|
}
|
|
40
|
-
return
|
|
40
|
+
return "authToken";
|
|
41
41
|
}
|
|
42
42
|
static get AUTH_PREFIX() {
|
|
43
|
-
return
|
|
43
|
+
return "kauth-";
|
|
44
44
|
}
|
|
45
45
|
static get APIKEY_PREFIX() {
|
|
46
|
-
return
|
|
46
|
+
return "kapikey-";
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
exports.Token = Token;
|
|
@@ -63,18 +63,18 @@ class User {
|
|
|
63
63
|
*/
|
|
64
64
|
getProfiles() {
|
|
65
65
|
if (!global.kuzzle) {
|
|
66
|
-
return kerror.reject(
|
|
66
|
+
return kerror.reject("security", "user", "uninitialized", this._id);
|
|
67
67
|
}
|
|
68
|
-
return global.kuzzle.ask(
|
|
68
|
+
return global.kuzzle.ask("core:security:profile:mGet", this.profileIds);
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
71
|
* @returns {Promise}
|
|
72
72
|
*/
|
|
73
73
|
async getRights() {
|
|
74
74
|
const profiles = await this.getProfiles();
|
|
75
|
-
const results = await Promise.all(profiles.map(p => p.getRights()));
|
|
75
|
+
const results = await Promise.all(profiles.map((p) => p.getRights()));
|
|
76
76
|
const rights = {};
|
|
77
|
-
results.forEach(right => lodash_1.default.assignWith(rights, right, rights_1.default.merge));
|
|
77
|
+
results.forEach((right) => lodash_1.default.assignWith(rights, right, rights_1.default.merge));
|
|
78
78
|
return rights;
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
@@ -85,7 +85,7 @@ class User {
|
|
|
85
85
|
if (this.profileIds === undefined || this.profileIds.length === 0) {
|
|
86
86
|
return false;
|
|
87
87
|
}
|
|
88
|
-
const targets = request.getArray(
|
|
88
|
+
const targets = request.getArray("targets", []);
|
|
89
89
|
const profiles = await this.getProfiles();
|
|
90
90
|
if (targets.length === 0) {
|
|
91
91
|
for (const profile of profiles) {
|
|
@@ -104,7 +104,7 @@ class User {
|
|
|
104
104
|
* later on, based on index and collections authorized for the given user.
|
|
105
105
|
*/
|
|
106
106
|
async areTargetsAllowed(request, profiles, targets) {
|
|
107
|
-
const profilesPolicies = await Promise.all(profiles.map(profile => profile.getAllowedPolicies(request)));
|
|
107
|
+
const profilesPolicies = await Promise.all(profiles.map((profile) => profile.getAllowedPolicies(request)));
|
|
108
108
|
// Every target must be allowed by at least one profile
|
|
109
109
|
for (const target of targets) {
|
|
110
110
|
// Skip targets with no Index or Collection
|
|
@@ -112,15 +112,15 @@ class User {
|
|
|
112
112
|
continue;
|
|
113
113
|
}
|
|
114
114
|
// TODO: Support Wildcard
|
|
115
|
-
if (target.index.includes(
|
|
115
|
+
if (target.index.includes("*")) {
|
|
116
116
|
return false;
|
|
117
117
|
}
|
|
118
118
|
for (const collection of target.collections) {
|
|
119
119
|
// TODO: Support Wildcard
|
|
120
|
-
if (collection.includes(
|
|
120
|
+
if (collection.includes("*")) {
|
|
121
121
|
return false;
|
|
122
122
|
}
|
|
123
|
-
const isTargetAllowed = profilesPolicies.some(policies => policies.some(policy => policy.role.checkRestrictions(target.index, collection, policy.restrictedTo)));
|
|
123
|
+
const isTargetAllowed = profilesPolicies.some((policies) => policies.some((policy) => policy.role.checkRestrictions(target.index, collection, policy.restrictedTo)));
|
|
124
124
|
if (!isTargetAllowed) {
|
|
125
125
|
return false;
|
|
126
126
|
}
|
|
@@ -19,36 +19,37 @@
|
|
|
19
19
|
* limitations under the License.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
"use strict";
|
|
23
23
|
|
|
24
|
-
const { sha256 } = require(
|
|
25
|
-
const debug = require(
|
|
26
|
-
const kerror = require(
|
|
27
|
-
const BaseModel = require(
|
|
24
|
+
const { sha256 } = require("../../util/crypto");
|
|
25
|
+
const debug = require("../../util/debug")("models:storage:apiKey");
|
|
26
|
+
const kerror = require("../../kerror");
|
|
27
|
+
const BaseModel = require("./baseModel");
|
|
28
28
|
|
|
29
29
|
class ApiKey extends BaseModel {
|
|
30
|
-
constructor
|
|
30
|
+
constructor(_source, _id = null) {
|
|
31
31
|
super(_source, _id);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* @override
|
|
36
36
|
*/
|
|
37
|
-
async _afterDelete
|
|
37
|
+
async _afterDelete() {
|
|
38
38
|
const token = await global.kuzzle.ask(
|
|
39
|
-
|
|
39
|
+
"core:security:token:get",
|
|
40
40
|
this.userId,
|
|
41
|
-
this.token
|
|
41
|
+
this.token
|
|
42
|
+
);
|
|
42
43
|
|
|
43
44
|
if (token) {
|
|
44
|
-
await global.kuzzle.ask(
|
|
45
|
+
await global.kuzzle.ask("core:security:token:delete", token);
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
serialize
|
|
49
|
+
serialize({ includeToken = false } = {}) {
|
|
49
50
|
const serialized = super.serialize();
|
|
50
51
|
|
|
51
|
-
if (!
|
|
52
|
+
if (!includeToken) {
|
|
52
53
|
delete serialized._source.token;
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -60,15 +61,22 @@ class ApiKey extends BaseModel {
|
|
|
60
61
|
/**
|
|
61
62
|
* @override
|
|
62
63
|
*/
|
|
63
|
-
static get collection
|
|
64
|
-
return
|
|
64
|
+
static get collection() {
|
|
65
|
+
return "api-keys";
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/**
|
|
68
69
|
* @override
|
|
69
70
|
*/
|
|
70
|
-
static get fields
|
|
71
|
-
return [
|
|
71
|
+
static get fields() {
|
|
72
|
+
return [
|
|
73
|
+
"userId",
|
|
74
|
+
"description",
|
|
75
|
+
"expiresAt",
|
|
76
|
+
"ttl",
|
|
77
|
+
"token",
|
|
78
|
+
"fingerprint",
|
|
79
|
+
];
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
/**
|
|
@@ -81,28 +89,30 @@ class ApiKey extends BaseModel {
|
|
|
81
89
|
*
|
|
82
90
|
* @returns {ApiKey}
|
|
83
91
|
*/
|
|
84
|
-
static async create
|
|
92
|
+
static async create(
|
|
85
93
|
user,
|
|
86
94
|
expiresIn,
|
|
87
95
|
description,
|
|
88
96
|
{ creatorId = null, apiKeyId = null, refresh, bypassMaxTTL = false } = {}
|
|
89
97
|
) {
|
|
90
|
-
const token = await global.kuzzle.ask(
|
|
98
|
+
const token = await global.kuzzle.ask("core:security:token:create", user, {
|
|
91
99
|
bypassMaxTTL,
|
|
92
100
|
expiresIn,
|
|
93
|
-
type:
|
|
101
|
+
type: "apiKey",
|
|
94
102
|
});
|
|
95
103
|
|
|
96
104
|
const fingerprint = sha256(token.jwt);
|
|
97
|
-
const apiKey = new ApiKey(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
const apiKey = new ApiKey(
|
|
106
|
+
{
|
|
107
|
+
description,
|
|
108
|
+
expiresAt: token.expiresAt,
|
|
109
|
+
fingerprint,
|
|
110
|
+
token: token.jwt,
|
|
111
|
+
ttl: token.ttl,
|
|
112
|
+
userId: user._id,
|
|
113
|
+
},
|
|
114
|
+
apiKeyId || fingerprint
|
|
115
|
+
);
|
|
106
116
|
|
|
107
117
|
await apiKey.save({ refresh, userId: creatorId });
|
|
108
118
|
|
|
@@ -117,12 +127,12 @@ class ApiKey extends BaseModel {
|
|
|
117
127
|
*
|
|
118
128
|
* @returns {ApiKey}
|
|
119
129
|
*/
|
|
120
|
-
static async load
|
|
130
|
+
static async load(userId, id) {
|
|
121
131
|
const apiKey = await super.load(id);
|
|
122
132
|
|
|
123
133
|
if (userId !== apiKey.userId) {
|
|
124
|
-
throw kerror.get(
|
|
125
|
-
message: `ApiKey "${id}" not found for user "${userId}"
|
|
134
|
+
throw kerror.get("services", "storage", "not_found", id, {
|
|
135
|
+
message: `ApiKey "${id}" not found for user "${userId}".`,
|
|
126
136
|
});
|
|
127
137
|
}
|
|
128
138
|
|
|
@@ -137,8 +147,8 @@ class ApiKey extends BaseModel {
|
|
|
137
147
|
*
|
|
138
148
|
* @returns {Promise}
|
|
139
149
|
*/
|
|
140
|
-
static deleteByUser
|
|
141
|
-
debug(
|
|
150
|
+
static deleteByUser(user, { refresh } = {}) {
|
|
151
|
+
debug("Delete ApiKeys for user %a", user);
|
|
142
152
|
return this.deleteByQuery({ term: { userId: user._id } }, { refresh });
|
|
143
153
|
}
|
|
144
154
|
}
|