Skip to content

Commit

Permalink
Merge pull request #2544 from kuzzleio/beta
Browse files Browse the repository at this point in the history
2.31.0
  • Loading branch information
rolljee authored Jul 22, 2024
2 parents ff00a44 + 782e2ca commit 3d214a0
Show file tree
Hide file tree
Showing 18 changed files with 165 additions and 178 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ lib/core/backend/backendSubscription.js
lib/core/backend/backendVault.js
lib/core/backend/index.js
lib/core/backend/internalLogger.js
lib/core/cache/cacheDbEnum.js
lib/core/debug/kuzzleDebugger.js
lib/core/plugin/pluginContext.js
lib/core/realtime/channel.js
Expand All @@ -135,10 +136,12 @@ lib/core/realtime/subscription.js
lib/core/security/profileRepository.js
lib/core/security/tokenRepository.js
lib/core/shared/KoncordeWrapper.js
lib/core/shared/repository.js
lib/core/shared/ObjectRepository.js
lib/core/shared/sdk/embeddedSdk.js
lib/core/shared/sdk/funnelProtocol.js
lib/core/shared/store.js
lib/core/storage/indexCache.js
lib/core/storage/storeScopeEnum.js
lib/kerror/errors/*.js
lib/kerror/errors/badRequestError.js
lib/kerror/errors/externalServiceError.js
Expand Down Expand Up @@ -208,6 +211,7 @@ lib/types/realtime/RoomList.js
lib/types/RequestPayload.js
lib/types/ResponsePayload.js
lib/types/RoleDefinition.js
lib/types/shared/StoreCollectionsDefinition.js
lib/types/StrategyDefinition.js
lib/types/Target.js
lib/types/Token.js
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# [2.31.0-beta.1](https://github.com/kuzzleio/kuzzle/compare/v2.30.1-beta.1...v2.31.0-beta.1) (2024-07-22)


### Features

* **doc:** add documentation in the event-system guide ([4913389](https://github.com/kuzzleio/kuzzle/commit/4913389e4be38f3cb23d85ca2bc769fc979dd64e))
* **funnel:** add optional parameter to request to trigger pipes ([508ac72](https://github.com/kuzzleio/kuzzle/commit/508ac72a25b690ac452ff32dbe80e0833c00290d))

## [2.30.1-beta.1](https://github.com/kuzzleio/kuzzle/compare/v2.30.0...v2.30.1-beta.1) (2024-06-03)


### Bug Fixes

* **doc:** fix a typo in documentation ([35256f0](https://github.com/kuzzleio/kuzzle/commit/35256f0299c01424af397707c02062128ebc98b2))
* hmset accepts value: 0 ([d973c4f](https://github.com/kuzzleio/kuzzle/commit/d973c4fe3f0b1d51d8389c606e5f3e1b31b47b86))
* mset accepts value: 0 ([d8168a8](https://github.com/kuzzleio/kuzzle/commit/d8168a8c5158c4ebcf7a51dddcaa9b2fa5fa1e65))

# [2.30.0](https://github.com/kuzzleio/kuzzle/compare/v2.29.1...v2.30.0) (2024-05-07)


Expand Down
2 changes: 1 addition & 1 deletion doc/2/api/controllers/document/delete-fields/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Returns an object containing updated document information, with the following pr
"index": "<index>",
"collection": "<collection>",
"controller": "document",
"action": "replace",
"action": "deleteFields",
"requestId": "<unique request identifier>",
"result": {
"_id": "<documentId>",
Expand Down
2 changes: 1 addition & 1 deletion doc/2/api/controllers/document/export/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Following arguments are available: `query`, `fields` and `fieldsName`.
"index": "<index>",
"collection": "<collection>",
"controller": "document",
"action": "search",
"action": "export",
"body": {
"query": {
// ...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ Body:
"action": "searchUsersByCredentials",
"strategy": "<strategy>",
"body": {
"bool": {
"must": [
{
"match": {
// example with the "local" authentication strategy
"username": "[email protected]"
"query":{
"bool": {
"must": [
{
"match": {
// example with the "local" authentication strategy
"username": "[email protected]"
}
}
}
]
]
}
}
},
}
Expand Down
2 changes: 1 addition & 1 deletion doc/2/framework/events/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The `before` event name is built using the following template:

#### Example

| API action | After event name |
| API action | Before event name |
| -------------------------------------------------------------------------------------------- | -------------------------------- |
| [auth:login](/core/2/api/controllers/auth/login) | auth:beforeLogin` |
| [document:createOrReplace](/core/2/api/controllers/document/create-or-replace) | `document:beforeCreateOrReplace` |
Expand Down
22 changes: 22 additions & 0 deletions doc/2/guides/develop-on-kuzzle/event-system/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,25 @@ await app.trigger('app-name/file-available', fileUrl);
::: warning
If an internal event is triggered, the payload must be the same as the original event.
:::

**Events are not triggered** with the embedded SDK and controllers actions.

::: warning
By default, actions executed through the embedded SDK or controllers won't trigger any events and thus no pipe or hooks will be called. On the contrary, controllers accessed by the external SDK through HTTP or Websocket requests will always fire events.
:::

This behaviour is set in order to prevent an infinite loop in which a pipe calls a controller generating an event calling this same pipe again and again.

It is nonetheless possible to pass the flag `triggerEvents` to the options parameters of the controller to fire events :

```ts
await this.sdk.document.create(
"index",
'collection',
{
contentOfDocument: 'CREATED VIA CONTROLLER',
},
_idOfDocument,
{ triggerEvents: true },
);
```
14 changes: 11 additions & 3 deletions lib/api/controllers/memoryStorageController.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,15 @@ function initMapping() {
kassert.assertBodyAttributeType(request, "entries", "array");

val.forEach((v) => {
if (typeof v !== "object" || !v.field || !v.value) {
if (
typeof v !== "object" ||
!v.field ||
(!v.value && v.value !== 0)
) {
throw kerror.get(
"invalid_argument",
"entries",
"<array of object>",
"<array of objects>",
);
}

Expand Down Expand Up @@ -348,7 +352,11 @@ function initMapping() {
kassert.assertBodyHasAttribute(request, "entries");
kassert.assertBodyAttributeType(request, "entries", "array");
val.forEach((entry) => {
if (typeof entry !== "object" || !entry.key || !entry.value) {
if (
typeof entry !== "object" ||
!entry.key ||
(!entry.value && entry.value !== 0)
) {
throw kerror.get(
"invalid_argument",
"entries",
Expand Down
3 changes: 3 additions & 0 deletions lib/api/funnel.js
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,9 @@ class Funnel {
*/
async executePluginRequest(request) {
try {
if (request.input.triggerEvents) {
return await this.processRequest(request);
}
return await doAction(this.getController(request), request);
} catch (e) {
this.handleErrorDump(e);
Expand Down
10 changes: 9 additions & 1 deletion lib/api/request/requestInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const _body = "body\u200b";
const _headers = "headers\u200b";
const _controller = "controller\u200b";
const _action = "action\u200b";
const _triggerEvents = "triggerEvents\u200b";

// any property not listed here will be copied into
// RequestInput.args
Expand Down Expand Up @@ -155,6 +156,7 @@ export class RequestInput {
this[_body] = null;
this[_controller] = null;
this[_action] = null;
this[_triggerEvents] = null;

// default value to null for former "resources" to avoid breaking
this.args = {};
Expand All @@ -181,6 +183,7 @@ export class RequestInput {
this.body = data.body;
this.controller = data.controller;
this.action = data.action;
this.triggerEvents = data.triggerEvents;
}

/**
Expand Down Expand Up @@ -263,7 +266,12 @@ export class RequestInput {
this[_action] = assert.assertString("action", str);
}
}

get triggerEvents(): boolean | undefined {
return this[_triggerEvents];
}
set triggerEvents(bool: boolean) {
this[_triggerEvents] = bool === true ? true : undefined;
}
/**
* Request body.
* In Http it's the request body parsed.
Expand Down
83 changes: 28 additions & 55 deletions lib/core/security/profileRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { JSONObject } from "kuzzle-sdk";
import { OptimizedPolicy, Policy } from "../../../index";
import * as kerror from "../../kerror";
import { Profile } from "../../model/security/profile";
import { cacheDbEnum } from "../cache/cacheDbEnum";
import { ObjectRepository } from "../shared/ObjectRepository";

/** @internal */
Expand Down Expand Up @@ -59,19 +58,14 @@ type UpdateOptions = {
*/
export class ProfileRepository extends ObjectRepository<Profile> {
private module: any;
private profiles: Map<string, Profile>;

/**
* @constructor
*/
constructor(securityModule) {
super({
cache: cacheDbEnum.NONE,
store: global.kuzzle.internalIndex,
});
super({ store: global.kuzzle.internalIndex });

this.module = securityModule;
this.profiles = new Map();

this.collection = "profiles";
this.ObjectConstructor = Profile;
Expand Down Expand Up @@ -129,7 +123,7 @@ export class ProfileRepository extends ObjectRepository<Profile> {
* @param {String} [id] - profile identifier
*/
global.kuzzle.onAsk("core:security:profile:invalidate", (id) =>
this.invalidate(id),
this.deleteFromCache(id),
);

/**
Expand Down Expand Up @@ -191,15 +185,29 @@ export class ProfileRepository extends ObjectRepository<Profile> {
* @returns {Promise.<Promise>}
* @throws {NotFoundError} If the corresponding profile doesn't exist
*/
async load(id: string): Promise<Profile> {
if (this.profiles.has(id)) {
return this.profiles.get(id);
}
override async load(
id: string,
options: { key?: string } = {},
): Promise<Profile> {
const profile = await this.loadFromCache(id, options);

if (profile === null) {
const profileFromDatabase = await this.loadOneFromDatabase(id);

if (profileFromDatabase !== null) {
await this.persistToCache(profileFromDatabase);

profileFromDatabase.optimizedPolicies = this.optimizePolicies(
profileFromDatabase.policies,
);
}

const profile = await super.load(id);
return profileFromDatabase;
}

profile.optimizedPolicies = this.optimizePolicies(profile.policies);
this.profiles.set(id, profile);

await this.refreshCacheTTL(profile);

return profile;
}
Expand Down Expand Up @@ -232,16 +240,7 @@ export class ProfileRepository extends ObjectRepository<Profile> {
}

for (const id of profileIds) {
let profile: Profile | Promise<Profile> = this.profiles.get(id);

if (!profile) {
profile = this.loadOneFromDatabase(id).then((p) => {
p.optimizedPolicies = this.optimizePolicies(p.policies);
this.profiles.set(id, p);
return p;
});
}

const profile: Profile | Promise<Profile> = this.load(id);
profiles.push(profile);
}

Expand Down Expand Up @@ -443,7 +442,7 @@ export class ProfileRepository extends ObjectRepository<Profile> {

await this.deleteFromDatabase(profile._id, { refresh });

this.profiles.delete(profile._id);
await this.deleteFromCache(profile._id);
}

/**
Expand Down Expand Up @@ -502,12 +501,12 @@ export class ProfileRepository extends ObjectRepository<Profile> {
});

const updatedProfile = await this.loadOneFromDatabase(profile._id);
await this.persistToCache(updatedProfile);

// Recompute optimized policies based on new policies
updatedProfile.optimizedPolicies = this.optimizePolicies(
updatedProfile.policies,
);

this.profiles.set(profile._id, updatedProfile);
return updatedProfile;
}

Expand Down Expand Up @@ -538,32 +537,6 @@ export class ProfileRepository extends ObjectRepository<Profile> {
return profile;
}

/**
* @override
*/
async truncate(opts: JSONObject) {
try {
await super.truncate(opts);
} finally {
// always clear the RAM cache: even if truncate fails in the middle of it,
// some of the cached profiles might not be valid anymore
this.invalidate();
}
}

/**
* Invalidate the cache entries for the given profile. If none is provided,
* the entire cache is emptied.
* @param {string} [profileId]
*/
invalidate(profileId?: string) {
if (!profileId) {
this.profiles.clear();
} else {
this.profiles.delete(profileId);
}
}

/**
* Optimize each policy to get a O(1) index access time
* and a O(log(n)) collection search time.
Expand Down Expand Up @@ -636,11 +609,11 @@ export class ProfileRepository extends ObjectRepository<Profile> {
// Otherwise we cannot stub them
// ============================================

async toDTO(dto: Profile): Promise<JSONObject> {
toDTO(dto: Profile): JSONObject {
return super.toDTO(dto);
}

async deleteFromDatabase(id: string, options: JSONObject) {
deleteFromDatabase(id: string, options: JSONObject) {
return super.deleteFromDatabase(id, options);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/core/security/roleRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class RoleRepository extends ObjectRepository {
*/
constructor(securityModule) {
super({
cache: cacheDbEnum.NONE,
cache: cacheDbEnum.INTERNAL,
store: global.kuzzle.internalIndex,
});

Expand Down
2 changes: 1 addition & 1 deletion lib/core/shared/ObjectRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class ObjectRepository<TObject extends { _id: string }> {
try {
response = await global.kuzzle.ask(`core:cache:${this.cacheDb}:get`, key);

if (response === null) {
if (response === null || response === undefined) {
return null;
}

Expand Down
Loading

0 comments on commit 3d214a0

Please sign in to comment.