kuzzle 2.16.11 → 2.17.0
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 +3 -3
- package/lib/api/controllers/authController.js +11 -11
- package/lib/api/controllers/baseController.js +60 -3
- package/lib/api/controllers/clusterController.js +1 -1
- package/lib/api/controllers/collectionController.js +7 -5
- package/lib/api/controllers/documentController.js +130 -17
- package/lib/api/controllers/indexController.js +1 -1
- package/lib/api/controllers/memoryStorageController.js +39 -38
- package/lib/api/controllers/realtimeController.js +1 -1
- package/lib/api/controllers/securityController.js +49 -49
- package/lib/api/controllers/serverController.js +73 -27
- package/lib/api/documentExtractor.js +3 -3
- package/lib/api/funnel.js +40 -21
- package/lib/api/httpRoutes.js +9 -4
- package/lib/api/openapi/OpenApiManager.d.ts +11 -0
- package/lib/api/openapi/OpenApiManager.js +96 -0
- package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
- package/lib/api/openapi/{document → components/document}/index.js +7 -2
- package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
- package/lib/api/openapi/components/document/validate.yaml +42 -0
- package/lib/api/openapi/components/index.d.ts +2 -0
- package/lib/api/openapi/components/index.js +18 -0
- package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
- package/lib/api/openapi/index.d.ts +1 -2
- package/lib/api/openapi/index.js +1 -5
- package/lib/api/openapi/openApiGenerator.d.ts +7 -0
- package/lib/api/openapi/openApiGenerator.js +133 -0
- package/lib/api/request/kuzzleRequest.js +4 -0
- package/lib/cluster/node.js +9 -9
- package/lib/cluster/publisher.js +1 -1
- package/lib/cluster/subscriber.js +1 -1
- package/lib/cluster/workers/IDCardRenewer.js +2 -2
- package/lib/config/default.config.js +1 -0
- package/lib/config/index.js +6 -6
- package/lib/core/auth/passportResponse.js +6 -6
- package/lib/core/auth/passportWrapper.js +5 -5
- package/lib/core/backend/backend.d.ts +5 -1
- package/lib/core/backend/backend.js +12 -8
- package/lib/core/backend/backendConfig.d.ts +5 -1
- package/lib/core/backend/backendConfig.js +4 -0
- package/lib/core/backend/backendOpenApi.d.ts +9 -0
- package/lib/core/backend/backendOpenApi.js +69 -0
- package/lib/core/backend/index.d.ts +1 -0
- package/lib/core/backend/index.js +1 -0
- package/lib/core/network/accessLogger.js +6 -6
- package/lib/core/network/clientConnection.js +1 -1
- package/lib/core/network/entryPoint.js +5 -5
- package/lib/core/network/httpRouter/index.js +5 -5
- package/lib/core/network/httpRouter/routeHandler.js +3 -3
- package/lib/core/network/httpRouter/routePart.js +5 -5
- package/lib/core/network/protocolManifest.js +1 -1
- package/lib/core/network/protocols/httpMessage.js +2 -2
- package/lib/core/network/protocols/httpwsProtocol.js +205 -48
- package/lib/core/network/protocols/mqttProtocol.js +3 -3
- package/lib/core/network/protocols/protocol.js +3 -3
- package/lib/core/network/router.js +7 -6
- package/lib/core/plugin/plugin.js +38 -64
- package/lib/core/plugin/pluginManifest.js +3 -3
- package/lib/core/plugin/pluginRepository.js +5 -5
- package/lib/core/plugin/pluginsManager.js +29 -28
- package/lib/core/realtime/notification/server.js +1 -1
- package/lib/core/realtime/notification/user.js +1 -1
- package/lib/core/realtime/notifier.js +5 -5
- package/lib/core/security/index.js +1 -1
- package/lib/core/security/profileRepository.d.ts +176 -0
- package/lib/core/security/profileRepository.js +426 -443
- package/lib/core/security/roleRepository.js +16 -16
- package/lib/core/security/securityLoader.js +2 -2
- package/lib/core/security/tokenRepository.js +11 -11
- package/lib/core/security/userRepository.js +8 -8
- package/lib/core/shared/abstractManifest.js +4 -4
- package/lib/core/shared/repository.js +5 -5
- package/lib/core/shared/sdk/funnelProtocol.js +1 -1
- package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
- package/lib/core/shared/store.js +30 -23
- package/lib/core/statistics/statistics.js +17 -17
- package/lib/core/storage/clientAdapter.js +45 -10
- package/lib/core/validation/baseType.js +5 -5
- package/lib/core/validation/types/anything.js +1 -1
- package/lib/core/validation/types/boolean.js +2 -2
- package/lib/core/validation/types/date.js +9 -9
- package/lib/core/validation/types/email.js +5 -5
- package/lib/core/validation/types/enum.js +6 -6
- package/lib/core/validation/types/geoPoint.js +2 -2
- package/lib/core/validation/types/geoShape.js +28 -25
- package/lib/core/validation/types/integer.js +4 -4
- package/lib/core/validation/types/ipAddress.js +7 -6
- package/lib/core/validation/types/numeric.js +4 -4
- package/lib/core/validation/types/object.js +5 -5
- package/lib/core/validation/types/string.js +5 -5
- package/lib/core/validation/types/url.js +7 -6
- package/lib/core/validation/validation.js +95 -84
- package/lib/kerror/codes/1-services.json +12 -0
- package/lib/kerror/codes/2-api.json +12 -0
- package/lib/kerror/codes/3-network.json +12 -0
- package/lib/kerror/codes/4-plugin.json +6 -0
- package/lib/kerror/codes/index.js +11 -11
- package/lib/kerror/index.js +1 -1
- package/lib/kuzzle/dumpGenerator.js +3 -3
- package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
- package/lib/kuzzle/event/pipeRunner.js +1 -1
- package/lib/kuzzle/event/waterfall.js +6 -6
- package/lib/kuzzle/kuzzle.js +36 -5
- package/lib/kuzzle/log.js +3 -3
- package/lib/kuzzle/vault.js +3 -3
- package/lib/model/security/profile.d.ts +54 -0
- package/lib/model/security/profile.js +174 -233
- package/lib/model/security/rights.js +1 -1
- package/lib/model/security/role.d.ts +40 -0
- package/lib/model/security/role.js +159 -191
- package/lib/model/security/user.d.ts +29 -0
- package/lib/model/security/user.js +84 -52
- package/lib/model/storage/apiKey.js +2 -2
- package/lib/model/storage/baseModel.js +3 -3
- package/lib/service/cache/redis.js +7 -7
- package/lib/service/storage/elasticsearch.js +152 -90
- package/lib/service/storage/esWrapper.js +2 -3
- package/lib/types/ControllerDefinition.d.ts +3 -3
- package/lib/types/ControllerRights.d.ts +22 -0
- package/lib/types/ControllerRights.js +23 -0
- package/lib/types/HttpStream.d.ts +32 -0
- package/lib/types/HttpStream.js +70 -0
- package/lib/types/OpenApiDefinition.d.ts +43 -0
- package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
- package/lib/types/Policy.d.ts +25 -0
- package/lib/types/{InternalLogger.js → Policy.js} +2 -2
- package/lib/types/PolicyRestrictions.d.ts +21 -0
- package/lib/types/PolicyRestrictions.js +23 -0
- package/lib/types/Target.d.ts +15 -0
- package/lib/types/Target.js +23 -0
- package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
- package/lib/types/config/ServicesConfiguration.d.ts +2 -2
- package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
- package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
- package/lib/types/index.d.ts +7 -1
- package/lib/types/index.js +7 -1
- package/lib/util/array.d.ts +11 -0
- package/lib/util/array.js +57 -0
- package/lib/util/assertType.js +6 -6
- package/lib/util/bufferedPassThrough.d.ts +76 -0
- package/lib/util/bufferedPassThrough.js +161 -0
- package/lib/util/deprecate.js +7 -5
- package/lib/util/didYouMean.js +1 -1
- package/lib/util/dump-collection.d.ts +3 -0
- package/lib/util/dump-collection.js +265 -0
- package/lib/util/extractFields.js +2 -2
- package/lib/util/inflector.d.ts +8 -0
- package/lib/util/inflector.js +16 -0
- package/lib/util/requestAssertions.js +7 -7
- package/lib/util/wildcard.js +55 -0
- package/package-lock.json +538 -78
- package/package.json +5 -3
- package/lib/api/openApiGenerator.d.ts +0 -7
- package/lib/api/openApiGenerator.js +0 -197
- package/lib/types/InternalLogger.d.ts +0 -25
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
4
|
* to power modern apps
|
|
@@ -18,487 +19,469 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.ProfileRepository = void 0;
|
|
27
|
+
const lodash_1 = require("lodash");
|
|
28
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
29
|
+
const profile_1 = require("../../model/security/profile");
|
|
30
|
+
const repository_1 = __importDefault(require("../shared/repository"));
|
|
31
|
+
const kerror_1 = __importDefault(require("../../kerror"));
|
|
32
|
+
const cacheDbEnum_1 = __importDefault(require("../cache/cacheDbEnum"));
|
|
32
33
|
/**
|
|
33
34
|
* @class ProfileRepository
|
|
34
35
|
* @extends Repository
|
|
35
36
|
*/
|
|
36
|
-
class ProfileRepository extends
|
|
37
|
-
/**
|
|
38
|
-
* @constructor
|
|
39
|
-
*/
|
|
40
|
-
constructor (securityModule) {
|
|
41
|
-
super({
|
|
42
|
-
cache: cacheDbEnum.NONE,
|
|
43
|
-
store: global.kuzzle.internalIndex,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
this.module = securityModule;
|
|
47
|
-
this.collection = 'profiles';
|
|
48
|
-
this.ObjectConstructor = Profile;
|
|
49
|
-
this.profiles = new Map();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
init () {
|
|
37
|
+
class ProfileRepository extends repository_1.default {
|
|
53
38
|
/**
|
|
54
|
-
*
|
|
55
|
-
* @param {String} id - profile identifier / name
|
|
56
|
-
* @param {Object} policies
|
|
57
|
-
* @param {Object} opts - refresh, userId (used for metadata)
|
|
58
|
-
* @returns {Profile}
|
|
59
|
-
* @throws If already exists or if the policies are invalid
|
|
39
|
+
* @constructor
|
|
60
40
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
41
|
+
constructor(securityModule) {
|
|
42
|
+
super({
|
|
43
|
+
cache: cacheDbEnum_1.default.NONE,
|
|
44
|
+
store: global.kuzzle.internalIndex,
|
|
45
|
+
});
|
|
46
|
+
this.module = securityModule;
|
|
47
|
+
this.profiles = new Map();
|
|
48
|
+
super.collection = 'profiles';
|
|
49
|
+
super.ObjectConstructor = profile_1.Profile;
|
|
50
|
+
}
|
|
51
|
+
init() {
|
|
52
|
+
/**
|
|
53
|
+
* Creates a new profile
|
|
54
|
+
* @param {String} id - profile identifier / name
|
|
55
|
+
* @param {Object} policies
|
|
56
|
+
* @param {Object} opts - refresh, userId (used for metadata)
|
|
57
|
+
* @returns {Profile}
|
|
58
|
+
* @throws If already exists or if the policies are invalid
|
|
59
|
+
*/
|
|
60
|
+
global.kuzzle.onAsk('core:security:profile:create', (id, policies, opts) => this.create(id, policies, opts));
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new profile, or replaces it if it already exists
|
|
63
|
+
* @param {String} id
|
|
64
|
+
* @param {Object} policies
|
|
65
|
+
* @param {Object} opts - refresh, userId (used for metadata)
|
|
66
|
+
* @returns {Profile}
|
|
67
|
+
* @throws If the profile policies are invalid
|
|
68
|
+
*/
|
|
69
|
+
global.kuzzle.onAsk('core:security:profile:createOrReplace', (id, policies, opts) => this.createOrReplace(id, policies, opts));
|
|
70
|
+
/**
|
|
71
|
+
* Deletes an existing profile
|
|
72
|
+
* @param {String} id
|
|
73
|
+
* @param {Object} opts - refresh
|
|
74
|
+
* @throws If the profile doesn't exist, if it is protected, or if it's
|
|
75
|
+
* still in use
|
|
76
|
+
*/
|
|
77
|
+
global.kuzzle.onAsk('core:security:profile:delete', (id, opts) => this.deleteById(id, opts));
|
|
78
|
+
/**
|
|
79
|
+
* Loads and returns an existing profile
|
|
80
|
+
* @param {String} id - profile identifier
|
|
81
|
+
* @returns {Profile}
|
|
82
|
+
* @throws {NotFoundError} If the profile doesn't exist
|
|
83
|
+
*/
|
|
84
|
+
global.kuzzle.onAsk('core:security:profile:get', id => this.load(id));
|
|
85
|
+
/**
|
|
86
|
+
* Invalidates the RAM cache from the given profile ID. If none is provided,
|
|
87
|
+
* the entire cache is emptied.
|
|
88
|
+
*
|
|
89
|
+
* @param {String} [id] - profile identifier
|
|
90
|
+
*/
|
|
91
|
+
global.kuzzle.onAsk('core:security:profile:invalidate', id => this.invalidate(id));
|
|
92
|
+
/**
|
|
93
|
+
* Gets multiple profiles
|
|
94
|
+
* @param {Array} ids
|
|
95
|
+
* @returns {Array.<Profile>}
|
|
96
|
+
* @throws If one or more profiles don't exist
|
|
97
|
+
*/
|
|
98
|
+
global.kuzzle.onAsk('core:security:profile:mGet', ids => this.loadProfiles(ids));
|
|
99
|
+
/**
|
|
100
|
+
* Fetches the next page of search results
|
|
101
|
+
* @param {String} id - scroll identifier
|
|
102
|
+
* @param {String} [ttl] - refresh the scroll results TTL
|
|
103
|
+
* @returns {Object} Search results
|
|
104
|
+
*/
|
|
105
|
+
global.kuzzle.onAsk('core:security:profile:scroll', (id, ttl) => this.scroll(id, ttl));
|
|
106
|
+
/**
|
|
107
|
+
* Searches profiles
|
|
108
|
+
*
|
|
109
|
+
* @param {Object} searchBody - Search query (ES format)
|
|
110
|
+
* @param {Object} opts (from, size, scroll)
|
|
111
|
+
*
|
|
112
|
+
* @returns {Object} Search results
|
|
113
|
+
*/
|
|
114
|
+
global.kuzzle.onAsk('core:security:profile:search', (searchBody, opts) => this.search(searchBody, opts));
|
|
115
|
+
/**
|
|
116
|
+
* Removes all existing profiles and invalidates the RAM cache
|
|
117
|
+
* @param {Object} opts (refresh)
|
|
118
|
+
*/
|
|
119
|
+
global.kuzzle.onAsk('core:security:profile:truncate', opts => this.truncate(opts));
|
|
120
|
+
/**
|
|
121
|
+
* Updates an existing profile using a partial content
|
|
122
|
+
* @param {String} id - profile identifier to update
|
|
123
|
+
* @param {Object} policies - partial policies to apply
|
|
124
|
+
* @param {Object} opts - refresh, retryOnConflict, userId (used for metadata)
|
|
125
|
+
* @returns {Profile} Updated profile
|
|
126
|
+
*/
|
|
127
|
+
global.kuzzle.onAsk('core:security:profile:update', (id, content, opts) => this.update(id, content, opts));
|
|
128
|
+
}
|
|
65
129
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @param
|
|
69
|
-
* @
|
|
70
|
-
* @
|
|
71
|
-
* @throws If the profile policies are invalid
|
|
130
|
+
* Loads a Profile
|
|
131
|
+
*
|
|
132
|
+
* @param {string} id
|
|
133
|
+
* @returns {Promise.<Promise>}
|
|
134
|
+
* @throws {NotFoundError} If the corresponding profile doesn't exist
|
|
72
135
|
*/
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
136
|
+
async load(id) {
|
|
137
|
+
if (this.profiles.has(id)) {
|
|
138
|
+
return this.profiles.get(id);
|
|
139
|
+
}
|
|
140
|
+
const profile = await super.load(id);
|
|
141
|
+
profile.optimizedPolicies = this.optimizePolicies(profile.policies);
|
|
142
|
+
this.profiles.set(id, profile);
|
|
143
|
+
return profile;
|
|
144
|
+
}
|
|
77
145
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
146
|
+
* Loads a Profile object given its id.
|
|
147
|
+
* Stores the promise of the profile being loaded in the memcache
|
|
148
|
+
* and then replaces it by the profile itself once it has been loaded
|
|
149
|
+
*
|
|
150
|
+
* This is to allow parallelisation while preventing sending requests
|
|
151
|
+
* to ES, which is slow
|
|
152
|
+
*
|
|
153
|
+
* @param {Array} profileIds - Array of profiles ids
|
|
154
|
+
* @param {Object} options - resetCache (false)
|
|
155
|
+
*
|
|
156
|
+
* @returns {Promise} Resolves to the matching Profile object if found, null
|
|
157
|
+
* if not.
|
|
158
|
+
*/
|
|
159
|
+
async loadProfiles(profileIds = []) {
|
|
160
|
+
const profiles = [];
|
|
161
|
+
if (profileIds.some(p => typeof p !== 'string')) {
|
|
162
|
+
throw kerror_1.default.get('api', 'assert', 'invalid_type', 'profileIds', 'string[]');
|
|
163
|
+
}
|
|
164
|
+
for (const id of profileIds) {
|
|
165
|
+
let profile = this.profiles.get(id);
|
|
166
|
+
if (!profile) {
|
|
167
|
+
profile = this.loadOneFromDatabase(id)
|
|
168
|
+
.then(p => {
|
|
169
|
+
p.optimizedPolicies = this.optimizePolicies(p.policies);
|
|
170
|
+
this.profiles.set(id, p);
|
|
171
|
+
return p;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
profiles.push(profile);
|
|
175
|
+
}
|
|
176
|
+
return bluebird_1.default.all(profiles);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* @override
|
|
83
180
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
181
|
+
async loadOneFromDatabase(id) {
|
|
182
|
+
try {
|
|
183
|
+
return await super.loadOneFromDatabase(id);
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
if (err.status === 404) {
|
|
187
|
+
throw kerror_1.default.get('security', 'profile', 'not_found', id);
|
|
188
|
+
}
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
88
192
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
193
|
+
* Creates a new profile, or create/replace a profile
|
|
194
|
+
*
|
|
195
|
+
* @param {String} id
|
|
196
|
+
* @param {Object} policies
|
|
197
|
+
* @param {Object} [opts]
|
|
91
198
|
* @returns {Profile}
|
|
92
|
-
* @throws {NotFoundError} If the profile doesn't exist
|
|
93
199
|
*/
|
|
94
|
-
|
|
95
|
-
|
|
200
|
+
async _createOrReplace(id, content, { method, refresh = 'false', strict, userId = null } = {}) {
|
|
201
|
+
const profile = await this.fromDTO({
|
|
202
|
+
// content should be first: ignores _id and _kuzzle_info in it
|
|
203
|
+
...content,
|
|
204
|
+
_id: id,
|
|
205
|
+
_kuzzle_info: {
|
|
206
|
+
author: userId,
|
|
207
|
+
createdAt: Date.now(),
|
|
208
|
+
updatedAt: null,
|
|
209
|
+
updater: null,
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
return this.validateAndSaveProfile(profile, { method, refresh, strict });
|
|
213
|
+
}
|
|
96
214
|
/**
|
|
97
|
-
*
|
|
98
|
-
* the entire cache is emptied.
|
|
215
|
+
* Creates a new profile
|
|
99
216
|
*
|
|
100
|
-
* @param
|
|
217
|
+
* @param {String} id
|
|
218
|
+
* @param {Object} content
|
|
219
|
+
* @param {Object} [opts]
|
|
220
|
+
* @returns {Profile}
|
|
101
221
|
*/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
222
|
+
async create(id, content, opts = {}) {
|
|
223
|
+
return this._createOrReplace(id, content, {
|
|
224
|
+
method: 'create',
|
|
225
|
+
...opts,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
106
228
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* @
|
|
110
|
-
* @
|
|
229
|
+
* Creates or replaces a profile
|
|
230
|
+
*
|
|
231
|
+
* @param {String} id
|
|
232
|
+
* @param {Object} content
|
|
233
|
+
* @param {Object} [opts]
|
|
234
|
+
* @returns {Profile}
|
|
111
235
|
*/
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
236
|
+
async createOrReplace(id, content, opts = {}) {
|
|
237
|
+
return this._createOrReplace(id, content, {
|
|
238
|
+
method: 'createOrReplace',
|
|
239
|
+
...opts,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
116
242
|
/**
|
|
117
|
-
*
|
|
118
|
-
* @param {String} id
|
|
119
|
-
* @param {
|
|
120
|
-
* @
|
|
243
|
+
* Updates a profile
|
|
244
|
+
* @param {String} id
|
|
245
|
+
* @param {Object} content
|
|
246
|
+
* @param {Object} [opts]
|
|
247
|
+
* @returns {Promise}
|
|
121
248
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
249
|
+
async update(id, content, { refresh, retryOnConflict, strict, userId } = {}) {
|
|
250
|
+
const profile = await this.load(id);
|
|
251
|
+
const pojo = super.toDTO(profile);
|
|
252
|
+
const updated = await this.fromDTO({
|
|
253
|
+
// /!\ order is important
|
|
254
|
+
...pojo,
|
|
255
|
+
...content,
|
|
256
|
+
// Always last, in case content contains these keys
|
|
257
|
+
_id: id,
|
|
258
|
+
_kuzzle_info: {
|
|
259
|
+
updatedAt: Date.now(),
|
|
260
|
+
updater: userId,
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
return this.validateAndSaveProfile(updated, {
|
|
264
|
+
method: 'update',
|
|
265
|
+
refresh,
|
|
266
|
+
retryOnConflict,
|
|
267
|
+
strict,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
126
270
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* @param {Object} searchBody - Search query (ES format)
|
|
130
|
-
* @param {Object} opts (from, size, scroll)
|
|
271
|
+
* Deletes a profile
|
|
131
272
|
*
|
|
132
|
-
* @
|
|
273
|
+
* @param {String} id
|
|
274
|
+
* @param {object} [options]
|
|
275
|
+
* @returns {Promise}
|
|
133
276
|
*/
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
277
|
+
async deleteById(id, options = {}) {
|
|
278
|
+
const profile = await this.load(id);
|
|
279
|
+
return this.delete(profile, options);
|
|
280
|
+
}
|
|
138
281
|
/**
|
|
139
|
-
*
|
|
140
|
-
* @param {Object} opts (refresh)
|
|
282
|
+
* @override
|
|
141
283
|
*/
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
284
|
+
async delete(profile, { refresh = 'false', onAssignedUsers = 'fail', userId = '-1', } = {}) {
|
|
285
|
+
if (['admin', 'default', 'anonymous'].includes(profile._id)) {
|
|
286
|
+
throw kerror_1.default.get('security', 'profile', 'cannot_delete');
|
|
287
|
+
}
|
|
288
|
+
const query = {
|
|
289
|
+
terms: {
|
|
290
|
+
'profileIds': [profile._id]
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
if (onAssignedUsers === 'remove') {
|
|
294
|
+
const batch = [];
|
|
295
|
+
let treated = 0;
|
|
296
|
+
let userPage = await this.module.user.search({ query }, { scroll: '1m', size: 100 });
|
|
297
|
+
while (treated < userPage.total) {
|
|
298
|
+
batch.length = 0;
|
|
299
|
+
for (const user of userPage.hits) {
|
|
300
|
+
user.profileIds = user.profileIds.filter(e => e !== profile._id);
|
|
301
|
+
if (user.profileIds.length === 0) {
|
|
302
|
+
user.profileIds.push('anonymous');
|
|
303
|
+
}
|
|
304
|
+
batch.push(this.module.user.update(user._id, user.profileIds, user, {
|
|
305
|
+
refresh,
|
|
306
|
+
userId
|
|
307
|
+
}));
|
|
308
|
+
}
|
|
309
|
+
await bluebird_1.default.all(batch);
|
|
310
|
+
treated += userPage.hits.length;
|
|
311
|
+
if (treated < userPage.total) {
|
|
312
|
+
userPage = await this.module.user.scroll(userPage.scrollId, '1m');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
const hits = await this.module.user.search({ query }, { from: 0, size: 1 });
|
|
318
|
+
if (hits.total > 0) {
|
|
319
|
+
throw kerror_1.default.get('security', 'profile', 'in_use');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
await this.deleteFromDatabase(profile._id, { refresh });
|
|
323
|
+
this.profiles.delete(profile._id);
|
|
324
|
+
}
|
|
146
325
|
/**
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* @param
|
|
151
|
-
* @returns {
|
|
326
|
+
* From a Profile object, returns a serialized object ready to be persisted
|
|
327
|
+
* to the database.
|
|
328
|
+
*
|
|
329
|
+
* @param {Profile} profile
|
|
330
|
+
* @returns {object}
|
|
152
331
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Loads a Profile
|
|
160
|
-
*
|
|
161
|
-
* @param {string} id
|
|
162
|
-
* @returns {Promise.<Promise>}
|
|
163
|
-
* @throws {NotFoundError} If the corresponding profile doesn't exist
|
|
164
|
-
*/
|
|
165
|
-
async load (id) {
|
|
166
|
-
if (this.profiles.has(id)) {
|
|
167
|
-
return this.profiles.get(id);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const profile = await super.load(id);
|
|
171
|
-
|
|
172
|
-
this.profiles.set(id, profile);
|
|
173
|
-
|
|
174
|
-
return profile;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Loads a Profile object given its id.
|
|
179
|
-
* Stores the promise of the profile being loaded in the memcache
|
|
180
|
-
* and then replaces it by the profile itself once it has been loaded
|
|
181
|
-
*
|
|
182
|
-
* This is to allow parallelisation while preventing sending requests
|
|
183
|
-
* to ES, which is slow
|
|
184
|
-
*
|
|
185
|
-
* @param {Array} profileIds - Array of profiles ids
|
|
186
|
-
* @param {Object} options - resetCache (false)
|
|
187
|
-
*
|
|
188
|
-
* @returns {Promise} Resolves to the matching Profile object if found, null
|
|
189
|
-
* if not.
|
|
190
|
-
*/
|
|
191
|
-
async loadProfiles (profileIds = []) {
|
|
192
|
-
const profiles = [];
|
|
193
|
-
|
|
194
|
-
if (profileIds.some(p => typeof p !== 'string')) {
|
|
195
|
-
throw kerror.get('api', 'assert', 'invalid_type', 'profileIds', 'string[]');
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
for (let i = 0; i < profileIds.length; i++) {
|
|
199
|
-
const id = profileIds[i];
|
|
200
|
-
let profile = this.profiles.get(id);
|
|
201
|
-
|
|
202
|
-
if (!profile) {
|
|
203
|
-
profile = this.loadOneFromDatabase(id)
|
|
204
|
-
.then(p => {
|
|
205
|
-
this.profiles.set(id, p);
|
|
206
|
-
return p;
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
this.profiles.set(id, profile);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
profiles.push(profile);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return Bluebird.all(profiles);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* @override
|
|
220
|
-
*/
|
|
221
|
-
async loadOneFromDatabase (id) {
|
|
222
|
-
try {
|
|
223
|
-
return await super.loadOneFromDatabase(id);
|
|
224
|
-
}
|
|
225
|
-
catch(err) {
|
|
226
|
-
if (err.status === 404) {
|
|
227
|
-
throw kerror.get('security', 'profile', 'not_found', id);
|
|
228
|
-
}
|
|
229
|
-
throw err;
|
|
332
|
+
serializeToDatabase(profile) {
|
|
333
|
+
// avoid the profile var mutation
|
|
334
|
+
return (0, lodash_1.omit)(profile, ['_id']);
|
|
230
335
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
{ method, refresh
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Creates a new profile
|
|
263
|
-
*
|
|
264
|
-
* @param {String} id
|
|
265
|
-
* @param {Object} content
|
|
266
|
-
* @param {Object} [opts]
|
|
267
|
-
* @returns {Profile}
|
|
268
|
-
*/
|
|
269
|
-
async create (id, content, opts) {
|
|
270
|
-
return this._createOrReplace(id, content, {
|
|
271
|
-
method: 'create',
|
|
272
|
-
...opts,
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Creates or replaces a profile
|
|
278
|
-
*
|
|
279
|
-
* @param {String} id
|
|
280
|
-
* @param {Object} content
|
|
281
|
-
* @param {Object} [opts]
|
|
282
|
-
* @returns {Profile}
|
|
283
|
-
*/
|
|
284
|
-
async createOrReplace (id, content, opts) {
|
|
285
|
-
return this._createOrReplace(id, content, {
|
|
286
|
-
method: 'createOrReplace',
|
|
287
|
-
...opts,
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Updates a profile
|
|
293
|
-
* @param {String} id
|
|
294
|
-
* @param {Object} content
|
|
295
|
-
* @param {Object} [opts]
|
|
296
|
-
* @returns {Promise}
|
|
297
|
-
*/
|
|
298
|
-
async update (id, content, {refresh, retryOnConflict, strict, userId} = {}) {
|
|
299
|
-
const profile = await this.load(id);
|
|
300
|
-
const pojo = this.toDTO(profile);
|
|
301
|
-
const updated = await this.fromDTO({
|
|
302
|
-
// /!\ order is important
|
|
303
|
-
...pojo,
|
|
304
|
-
...content,
|
|
305
|
-
// Always last, in case content contains these keys
|
|
306
|
-
_id: id,
|
|
307
|
-
_kuzzle_info: {
|
|
308
|
-
updatedAt: Date.now(),
|
|
309
|
-
updater: userId,
|
|
310
|
-
},
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
return this.validateAndSaveProfile(updated, {
|
|
314
|
-
method: 'update',
|
|
315
|
-
refresh,
|
|
316
|
-
retryOnConflict,
|
|
317
|
-
strict,
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Deletes a profile
|
|
323
|
-
*
|
|
324
|
-
* @param {String} id
|
|
325
|
-
* @param {object} [options]
|
|
326
|
-
* @returns {Promise}
|
|
327
|
-
*/
|
|
328
|
-
async deleteById (id, options) {
|
|
329
|
-
const profile = await this.load(id);
|
|
330
|
-
return this.delete(profile, options);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* @override
|
|
335
|
-
*/
|
|
336
|
-
async delete (profile, {
|
|
337
|
-
refresh = 'false',
|
|
338
|
-
onAssignedUsers = 'fail',
|
|
339
|
-
userId = '-1',
|
|
340
|
-
} = {}) {
|
|
341
|
-
if (['admin', 'default', 'anonymous'].includes(profile._id)) {
|
|
342
|
-
throw kerror.get('security', 'profile', 'cannot_delete');
|
|
336
|
+
/**
|
|
337
|
+
* Given a Profile object, validates its definition and if OK, persist it to the database.
|
|
338
|
+
*
|
|
339
|
+
* @param {Profile} profile
|
|
340
|
+
* @param {Object} [options]
|
|
341
|
+
* @param {string} [options.method] - Document persistence method
|
|
342
|
+
* @param {string} [options.refresh] - (Don't) wait for index refresh
|
|
343
|
+
* @param {number} [options.retryOnConflict] - Number of retries when an
|
|
344
|
+
* update fails due to a conflict
|
|
345
|
+
* @param {boolean} [options.strict] - if true, restrictions can only be
|
|
346
|
+
* applied on existing indexes/collections
|
|
347
|
+
* @returns {Promise<Profile>}
|
|
348
|
+
**/
|
|
349
|
+
async validateAndSaveProfile(profile, { method, refresh, retryOnConflict, strict } = {}) {
|
|
350
|
+
const policiesRoles = profile.policies.map(p => p.roleId);
|
|
351
|
+
// Assert: all roles must exist
|
|
352
|
+
await this.module.role.loadRoles(policiesRoles);
|
|
353
|
+
await profile.validateDefinition({ strict });
|
|
354
|
+
if (profile._id === 'anonymous'
|
|
355
|
+
&& policiesRoles.indexOf('anonymous') === -1) {
|
|
356
|
+
throw kerror_1.default.get('security', 'profile', 'missing_anonymous_role');
|
|
357
|
+
}
|
|
358
|
+
profile.optimizedPolicies = undefined; // Remove optimized policies
|
|
359
|
+
await super.persistToDatabase(profile, { method, refresh, retryOnConflict });
|
|
360
|
+
const updatedProfile = await this.loadOneFromDatabase(profile._id);
|
|
361
|
+
// Recompute optimized policies based on new policies
|
|
362
|
+
updatedProfile.optimizedPolicies = this.optimizePolicies(updatedProfile.policies);
|
|
363
|
+
this.profiles.set(profile._id, updatedProfile);
|
|
364
|
+
return updatedProfile;
|
|
343
365
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
let treated = 0;
|
|
354
|
-
let userPage = await this.module.user.search(
|
|
355
|
-
{ query },
|
|
356
|
-
{ scroll: '1m', size: 100 });
|
|
357
|
-
|
|
358
|
-
while (treated < userPage.total) {
|
|
359
|
-
batch.length = 0;
|
|
360
|
-
|
|
361
|
-
for (const user of userPage.hits) {
|
|
362
|
-
user.profileIds = user.profileIds.filter(e => e !== profile._id);
|
|
363
|
-
|
|
364
|
-
if (user.profileIds.length === 0) {
|
|
365
|
-
user.profileIds.push('anonymous');
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
batch.push(this.module.user.update(
|
|
369
|
-
user._id,
|
|
370
|
-
user.profileIds,
|
|
371
|
-
user,
|
|
372
|
-
{
|
|
373
|
-
refresh,
|
|
374
|
-
userId
|
|
375
|
-
}));
|
|
366
|
+
/**
|
|
367
|
+
* @param {object} dto
|
|
368
|
+
* @returns {Promise<Profile>}
|
|
369
|
+
*/
|
|
370
|
+
async fromDTO(dto) {
|
|
371
|
+
const profile = await super.fromDTO(dto);
|
|
372
|
+
// force "default" role/policy if the profile does not have any role in it
|
|
373
|
+
if (!profile.policies || profile.policies.length === 0) {
|
|
374
|
+
profile.policies = [{ roleId: 'default' }];
|
|
376
375
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
treated += userPage.hits.length;
|
|
381
|
-
|
|
382
|
-
if (treated < userPage.total) {
|
|
383
|
-
userPage = await this.module.user.scroll(userPage.scrollId, '1m');
|
|
376
|
+
if (profile.constructor._hash('') === false) {
|
|
377
|
+
profile.constructor._hash = obj => global.kuzzle.hash(obj);
|
|
384
378
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
379
|
+
const policiesRoles = profile.policies.map(p => p.roleId);
|
|
380
|
+
const roles = await this.module.role.loadRoles(policiesRoles);
|
|
381
|
+
// Fail if not all roles are found
|
|
382
|
+
if (roles.some(r => r === null)) {
|
|
383
|
+
throw kerror_1.default.get('security', 'profile', 'cannot_hydrate');
|
|
384
|
+
}
|
|
385
|
+
return profile;
|
|
393
386
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
*/
|
|
407
|
-
serializeToDatabase (profile) {
|
|
408
|
-
// avoid the profile var mutation
|
|
409
|
-
return omit(profile, ['_id']);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Given a Profile object, validates its definition and if OK, persist it to the database.
|
|
414
|
-
*
|
|
415
|
-
* @param {Profile} profile
|
|
416
|
-
* @param {Object} [options]
|
|
417
|
-
* @param {string} [options.method] - Document persistence method
|
|
418
|
-
* @param {string} [options.refresh] - (Don't) wait for index refresh
|
|
419
|
-
* @param {number} [options.retryOnConflict] - Number of retries when an
|
|
420
|
-
* update fails due to a conflict
|
|
421
|
-
* @param {boolean} [options.strict] - if true, restrictions can only be
|
|
422
|
-
* applied on existing indexes/collections
|
|
423
|
-
* @returns {Promise<Profile>}
|
|
424
|
-
**/
|
|
425
|
-
async validateAndSaveProfile (profile, { method, refresh, retryOnConflict, strict } = {}) {
|
|
426
|
-
const policiesRoles = profile.policies.map(p => p.roleId);
|
|
427
|
-
|
|
428
|
-
// Assert: all roles must exist
|
|
429
|
-
await this.module.role.loadRoles(policiesRoles);
|
|
430
|
-
|
|
431
|
-
await profile.validateDefinition({ strict });
|
|
432
|
-
|
|
433
|
-
if ( profile._id === 'anonymous'
|
|
434
|
-
&& policiesRoles.indexOf('anonymous') === -1
|
|
435
|
-
) {
|
|
436
|
-
throw kerror.get('security', 'profile', 'missing_anonymous_role');
|
|
387
|
+
/**
|
|
388
|
+
* @override
|
|
389
|
+
*/
|
|
390
|
+
async truncate(opts) {
|
|
391
|
+
try {
|
|
392
|
+
await super.truncate(opts);
|
|
393
|
+
}
|
|
394
|
+
finally {
|
|
395
|
+
// always clear the RAM cache: even if truncate fails in the middle of it,
|
|
396
|
+
// some of the cached profiles might not be valid anymore
|
|
397
|
+
this.invalidate();
|
|
398
|
+
}
|
|
437
399
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
*/
|
|
451
|
-
async fromDTO (dto) {
|
|
452
|
-
const profile = await super.fromDTO(dto);
|
|
453
|
-
|
|
454
|
-
// force "default" role/policy if the profile does not have any role in it
|
|
455
|
-
if (!profile.policies || profile.policies.length === 0) {
|
|
456
|
-
profile.policies = [ {roleId: 'default'} ];
|
|
400
|
+
/**
|
|
401
|
+
* Invalidate the cache entries for the given profile. If none is provided,
|
|
402
|
+
* the entire cache is emptied.
|
|
403
|
+
* @param {string} [profileId]
|
|
404
|
+
*/
|
|
405
|
+
invalidate(profileId) {
|
|
406
|
+
if (!profileId) {
|
|
407
|
+
this.profiles.clear();
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
this.profiles.delete(profileId);
|
|
411
|
+
}
|
|
457
412
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
413
|
+
/**
|
|
414
|
+
* Optimize each policy to get a O(1) index access time
|
|
415
|
+
* and a O(log(n)) collection search time.
|
|
416
|
+
*
|
|
417
|
+
* - Deduplicate indexes using a map
|
|
418
|
+
* - Sort collections per index
|
|
419
|
+
* @param {Object[]} policies
|
|
420
|
+
*/
|
|
421
|
+
optimizePolicies(policies) {
|
|
422
|
+
if (!policies) {
|
|
423
|
+
return [];
|
|
424
|
+
}
|
|
425
|
+
return policies.map(this.optimizePolicy);
|
|
461
426
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
427
|
+
/**
|
|
428
|
+
* Optimize a policy to get a O(1) index access time
|
|
429
|
+
* and a O(log(n)) collection search time.
|
|
430
|
+
*
|
|
431
|
+
* - Deduplicate indexes using a map
|
|
432
|
+
* - Sort collections per index
|
|
433
|
+
* @param policy
|
|
434
|
+
*/
|
|
435
|
+
optimizePolicy(policy) {
|
|
436
|
+
const indexes = new Map();
|
|
437
|
+
if (!policy.restrictedTo) {
|
|
438
|
+
return {
|
|
439
|
+
roleId: policy.roleId,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
for (const restriction of policy.restrictedTo) {
|
|
443
|
+
const index = restriction.index;
|
|
444
|
+
const collections = restriction.collections;
|
|
445
|
+
if (!index) {
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
if (!indexes.has(index)) {
|
|
449
|
+
indexes.set(index, new Set());
|
|
450
|
+
}
|
|
451
|
+
if (!collections) {
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
const collectionSet = indexes.get(index);
|
|
455
|
+
for (const collection of collections) {
|
|
456
|
+
collectionSet.add(collection); // Push unique values
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// Convert collections Set to arrays and sort them
|
|
460
|
+
for (const index of indexes.keys()) {
|
|
461
|
+
const collectionSet = indexes.get(index);
|
|
462
|
+
indexes.set(index, Array.from(collectionSet).sort());
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
restrictedTo: indexes,
|
|
466
|
+
roleId: policy.roleId,
|
|
467
|
+
};
|
|
469
468
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
*/
|
|
477
|
-
async truncate (opts) {
|
|
478
|
-
try {
|
|
479
|
-
await super.truncate(opts);
|
|
469
|
+
// ============================================
|
|
470
|
+
// Every method described after are for testing purpose only
|
|
471
|
+
// Otherwise we cannot stub them
|
|
472
|
+
// ============================================
|
|
473
|
+
async toDTO(dto) {
|
|
474
|
+
return super.toDTO(dto);
|
|
480
475
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
// some of the cached profiles might not be valid anymore
|
|
484
|
-
this.invalidate();
|
|
476
|
+
async deleteFromDatabase(id, options) {
|
|
477
|
+
return super.deleteFromDatabase(id, options);
|
|
485
478
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Invalidate the cache entries for the given profile. If none is provided,
|
|
490
|
-
* the entire cache is emptied.
|
|
491
|
-
* @param {string} [profileId]
|
|
492
|
-
*/
|
|
493
|
-
invalidate (profileId) {
|
|
494
|
-
if (!profileId) {
|
|
495
|
-
this.profiles.clear();
|
|
479
|
+
async search(searchBody, options) {
|
|
480
|
+
return super.search(searchBody, options);
|
|
496
481
|
}
|
|
497
|
-
|
|
498
|
-
|
|
482
|
+
async scroll(id, ttl) {
|
|
483
|
+
return super.scroll(id, ttl);
|
|
499
484
|
}
|
|
500
|
-
}
|
|
501
485
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
module.exports = ProfileRepository;
|
|
486
|
+
exports.ProfileRepository = ProfileRepository;
|
|
487
|
+
//# sourceMappingURL=profileRepository.js.map
|