From 4971781a835070e33d5939f77663d2b683e152cc Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 20 Mar 2020 22:37:00 -0300 Subject: [PATCH 1/3] modal close response --- src/definition/uikit/UIKitInteractionResponder.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/definition/uikit/UIKitInteractionResponder.ts b/src/definition/uikit/UIKitInteractionResponder.ts index 7e2ef14b2..c8a4f1de5 100644 --- a/src/definition/uikit/UIKitInteractionResponder.ts +++ b/src/definition/uikit/UIKitInteractionResponder.ts @@ -39,6 +39,15 @@ export class UIKitInteractionResponder { }; } + public closeModalViewResponse(viewData: IUIKitModalViewParam): IUIKitModalResponse { + const { appId, triggerId } = this.baseContext; + + return { + success: true, + ...formatModalInteraction(viewData, { appId, triggerId, type: UIKitInteractionType.MODAL_CLOSE }), + }; + } + public viewErrorResponse(errorInteraction: IUIKitErrorInteractionParam): IUIKitErrorResponse { const { appId, triggerId } = this.baseContext; From 36dd58b2be4476be5c3f61ec61fec0579a9b3de6 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 20 Mar 2020 23:34:32 -0300 Subject: [PATCH 2/3] add user join event --- src/definition/metadata/AppMethod.ts | 7 ++ src/definition/users/IPostUserJoinRoom.ts | 31 ++++++++ .../users/IPreUserJoinRoomPrevent.ts | 31 ++++++++ src/definition/users/index.ts | 3 + src/server/compiler/AppImplements.ts | 4 ++ src/server/managers/AppListenerManager.ts | 72 ++++++++++++++++++- src/server/users/User.ts | 24 +++++++ 7 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 src/definition/users/IPostUserJoinRoom.ts create mode 100644 src/definition/users/IPreUserJoinRoomPrevent.ts create mode 100644 src/server/users/User.ts diff --git a/src/definition/metadata/AppMethod.ts b/src/definition/metadata/AppMethod.ts index b0ca31ad4..c5d2f32bf 100644 --- a/src/definition/metadata/AppMethod.ts +++ b/src/definition/metadata/AppMethod.ts @@ -49,4 +49,11 @@ export enum AppMethod { UIKIT_VIEW_CLOSE = 'executeViewClosedHandler', // Livechat EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER = 'executeLivechatRoomClosedHandler', + + // User + CHECK_PRE_USER_JOIN_PREVENT = 'checkPreUserJoinPrevent', + EXECUTE_PRE_USER_JOIN_PREVENT = 'executePreUserJoinPrevent', + + CHECK_POST_USER_JOIN = 'checkPostUserJoin', + EXECUTE_POST_USER_JOIN = 'executePostUserJoin', } diff --git a/src/definition/users/IPostUserJoinRoom.ts b/src/definition/users/IPostUserJoinRoom.ts new file mode 100644 index 000000000..8c38ba214 --- /dev/null +++ b/src/definition/users/IPostUserJoinRoom.ts @@ -0,0 +1,31 @@ +import { IHttp, IPersistence, IRead } from '../accessors'; +import { IUser } from '.'; +import { IRoom } from '../rooms'; + +/** Handler which is called to determine whether a user is allowed to send a message or not. */ +export interface IPostUserJoinRoom { + /** + * Enables the handler to signal to the Apps framework whether + * this handler should actually be executed for the message + * about to be sent. + * + * @param user The user which is being joined + * @param room The room the room + * @param read An accessor to the environment + * @param http An accessor to the outside world + * @returns whether to run the prevent or not + */ + checkPostUserJoin?(user: IUser, room: IRoom ,read: IRead, http: IHttp): Promise; + + /** + * Method which is to be used to prevent a message from being sent. + * + * @param user The user which is being joined + * @param room The room the room + * @param read An accessor to the environment + * @param http An accessor to the outside world + * @param persistence An accessor to the App's persistence storage + * @returns whether to prevent the message from being sent + */ + executePostUserJoin(user: IUser, room: IRoom, read: IRead, http: IHttp, persistence: IPersistence): Promise; +} diff --git a/src/definition/users/IPreUserJoinRoomPrevent.ts b/src/definition/users/IPreUserJoinRoomPrevent.ts new file mode 100644 index 000000000..0f2f3bb8f --- /dev/null +++ b/src/definition/users/IPreUserJoinRoomPrevent.ts @@ -0,0 +1,31 @@ +import { IHttp, IPersistence, IRead } from '../accessors'; +import { IUser } from '.'; +import { IRoom } from '../rooms'; + +/** Handler which is called to determine whether a user is allowed to send a message or not. */ +export interface IPreUserJoinRoomPrevent { + /** + * Enables the handler to signal to the Apps framework whether + * this handler should actually be executed for the message + * about to be sent. + * + * @param user The user which is being joined + * @param room The room the room + * @param read An accessor to the environment + * @param http An accessor to the outside world + * @returns whether to run the prevent or not + */ + checkPreUserJoinPrevent?(user: IUser, room: IRoom ,read: IRead, http: IHttp): Promise; + + /** + * Method which is to be used to prevent a message from being sent. + * + * @param user The user which is being joined + * @param room The room the room + * @param read An accessor to the environment + * @param http An accessor to the outside world + * @param persistence An accessor to the App's persistence storage + * @returns whether to prevent the message from being sent + */ + executePreUserJoinPrevent(user: IUser, room: IRoom, read: IRead, http: IHttp, persistence: IPersistence): Promise; +} diff --git a/src/definition/users/index.ts b/src/definition/users/index.ts index 008dd2b87..006affcf8 100644 --- a/src/definition/users/index.ts +++ b/src/definition/users/index.ts @@ -5,3 +5,6 @@ import { UserStatusConnection } from './UserStatusConnection'; import { UserType } from './UserType'; export { IUser, IUserEmail, IUserCreationOptions, UserStatusConnection, UserType }; + +export * from './IPreUserJoinRoomPrevent'; +export * from './IPostUserJoinRoom'; diff --git a/src/server/compiler/AppImplements.ts b/src/server/compiler/AppImplements.ts index 3a8e84ebe..3401d7b74 100644 --- a/src/server/compiler/AppImplements.ts +++ b/src/server/compiler/AppImplements.ts @@ -23,6 +23,10 @@ export enum AppInterface { IUIKitInteractionHandler = 'IUIKitInteractionHandler', // Livechat ILivechatRoomClosedHandler = 'ILivechatRoomClosedHandler', + // Users + + IPreUserJoinRoomPrevent= 'IPreUserJoinRoomPrevent', + IPostUserJoinRoom = 'IPostUserJoinRoom', } export class AppImplements { diff --git a/src/server/managers/AppListenerManager.ts b/src/server/managers/AppListenerManager.ts index 944d8f2e4..a218722be 100644 --- a/src/server/managers/AppListenerManager.ts +++ b/src/server/managers/AppListenerManager.ts @@ -20,6 +20,7 @@ import { Message } from '../messages/Message'; import { Utilities } from '../misc/Utilities'; import { ProxiedApp } from '../ProxiedApp'; import { Room } from '../rooms/Room'; +import { User } from '../users/User'; import { AppAccessorManager } from './AppAccessorManager'; export class AppListenerManager { @@ -108,14 +109,83 @@ export class AppListenerManager { return this.executeUIKitInteraction(data as IUIKitIncomingInteraction); // Livechat case AppInterface.ILivechatRoomClosedHandler: - this.executeLivechatRoomClosed(data as ILivechatRoom); + return this.executeLivechatRoomClosed(data as ILivechatRoom); return; + // User + case AppInterface.IPreUserJoinRoomPrevent: + return this.executePreUserJoinPrevent(data); + + case AppInterface.IPostUserJoinRoom: + return this.executePostUserJoin(data); default: console.warn('Unimplemented (or invalid) AppInterface was just tried to execute.'); return; } } + private async executePreUserJoinPrevent(data: any) { + let prevented = false; + const cfUser = new User(Utilities.deepCloneAndFreeze(data.user), this.manager); + const cfRoom = new User(Utilities.deepCloneAndFreeze(data.room), this.manager); + + for (const appId of this.listeners.get(AppInterface.IPreMessageSentPrevent)) { + const app = this.manager.getOneById(appId); + + let continueOn = true; + if (app.hasMethod(AppMethod.CHECK_PRE_USER_JOIN_PREVENT)) { + continueOn = await app.call(AppMethod.CHECK_PRE_USER_JOIN_PREVENT, + cfUser, + cfRoom, + this.am.getReader(appId), + this.am.getHttp(appId), + ) as boolean; + } + + if (continueOn && app.hasMethod(AppMethod.EXECUTE_PRE_USER_JOIN_PREVENT)) { + prevented = await app.call(AppMethod.EXECUTE_PRE_USER_JOIN_PREVENT, + cfUser, + cfRoom, + this.am.getReader(appId), + this.am.getHttp(appId), + this.am.getPersistence(appId), + ) as boolean; + + if (prevented) { + return prevented; + } + } + } + return prevented; + } + + private async executePostUserJoin(data: any) { + const cfUser = new User(Utilities.deepCloneAndFreeze(data.user), this.manager); + const cfRoom = new Room(Utilities.deepCloneAndFreeze(data.room), this.manager); + + for (const appId of this.listeners.get(AppInterface.IPostRoomDeleted)) { + const app = this.manager.getOneById(appId); + + let continueOn = true; + if (app.hasMethod(AppMethod.CHECK_POST_USER_JOIN)) { + continueOn = await app.call(AppMethod.CHECK_POST_USER_JOIN, + cfUser, + cfRoom, + this.am.getReader(appId), + this.am.getHttp(appId), + ) as boolean; + } + + if (continueOn && app.hasMethod(AppMethod.EXECUTE_POST_USER_JOIN)) { + await app.call(AppMethod.EXECUTE_POST_USER_JOIN, + cfUser, + cfRoom, + this.am.getReader(appId), + this.am.getHttp(appId), + this.am.getPersistence(appId), + ); + } + } + } // Messages private async executePreMessageSentPrevent(data: IMessage): Promise { let prevented = false; diff --git a/src/server/users/User.ts b/src/server/users/User.ts new file mode 100644 index 000000000..995133edc --- /dev/null +++ b/src/server/users/User.ts @@ -0,0 +1,24 @@ + +import { IUser, UserType, IUserEmail, UserStatusConnection } from "../../definition/users"; +import { AppManager } from '../AppManager'; +export class User implements IUser { + + id: string; + username: string; + emails: Array; + type: UserType; + isEnabled: boolean; + name: string; + roles: Array; + status: string; + statusConnection: UserStatusConnection; + utcOffset: number; + createdAt: Date; + updatedAt: Date; + lastLoginAt: Date; + appId?: string; + + public constructor(user: IUser, private manager: AppManager) { + Object.assign(this, user); + } +} From 5148e041a4e8929d2bc08d6b6d94bbf37547517e Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 20 Mar 2020 23:47:40 -0300 Subject: [PATCH 3/3] user join event --- .../uikit/UIKitInteractionResponder.ts | 5 ++- src/definition/users/IPostUserJoinRoom.ts | 4 +-- .../users/IPreUserJoinRoomPrevent.ts | 4 +-- src/server/managers/AppListenerManager.ts | 9 ++--- src/server/users/User.ts | 35 +++++++++---------- 5 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/definition/uikit/UIKitInteractionResponder.ts b/src/definition/uikit/UIKitInteractionResponder.ts index c8a4f1de5..89fd9c3cd 100644 --- a/src/definition/uikit/UIKitInteractionResponder.ts +++ b/src/definition/uikit/UIKitInteractionResponder.ts @@ -41,13 +41,12 @@ export class UIKitInteractionResponder { public closeModalViewResponse(viewData: IUIKitModalViewParam): IUIKitModalResponse { const { appId, triggerId } = this.baseContext; - return { success: true, ...formatModalInteraction(viewData, { appId, triggerId, type: UIKitInteractionType.MODAL_CLOSE }), }; - } - + } + public viewErrorResponse(errorInteraction: IUIKitErrorInteractionParam): IUIKitErrorResponse { const { appId, triggerId } = this.baseContext; diff --git a/src/definition/users/IPostUserJoinRoom.ts b/src/definition/users/IPostUserJoinRoom.ts index 8c38ba214..7b500ff3b 100644 --- a/src/definition/users/IPostUserJoinRoom.ts +++ b/src/definition/users/IPostUserJoinRoom.ts @@ -1,5 +1,5 @@ -import { IHttp, IPersistence, IRead } from '../accessors'; import { IUser } from '.'; +import { IHttp, IPersistence, IRead } from '../accessors'; import { IRoom } from '../rooms'; /** Handler which is called to determine whether a user is allowed to send a message or not. */ @@ -15,7 +15,7 @@ export interface IPostUserJoinRoom { * @param http An accessor to the outside world * @returns whether to run the prevent or not */ - checkPostUserJoin?(user: IUser, room: IRoom ,read: IRead, http: IHttp): Promise; + checkPostUserJoin?(user: IUser, room: IRoom, read: IRead, http: IHttp): Promise; /** * Method which is to be used to prevent a message from being sent. diff --git a/src/definition/users/IPreUserJoinRoomPrevent.ts b/src/definition/users/IPreUserJoinRoomPrevent.ts index 0f2f3bb8f..8a83ac4b0 100644 --- a/src/definition/users/IPreUserJoinRoomPrevent.ts +++ b/src/definition/users/IPreUserJoinRoomPrevent.ts @@ -1,5 +1,5 @@ -import { IHttp, IPersistence, IRead } from '../accessors'; import { IUser } from '.'; +import { IHttp, IPersistence, IRead } from '../accessors'; import { IRoom } from '../rooms'; /** Handler which is called to determine whether a user is allowed to send a message or not. */ @@ -15,7 +15,7 @@ export interface IPreUserJoinRoomPrevent { * @param http An accessor to the outside world * @returns whether to run the prevent or not */ - checkPreUserJoinPrevent?(user: IUser, room: IRoom ,read: IRead, http: IHttp): Promise; + checkPreUserJoinPrevent?(user: IUser, room: IRoom, read: IRead, http: IHttp): Promise; /** * Method which is to be used to prevent a message from being sent. diff --git a/src/server/managers/AppListenerManager.ts b/src/server/managers/AppListenerManager.ts index a218722be..e569e59d6 100644 --- a/src/server/managers/AppListenerManager.ts +++ b/src/server/managers/AppListenerManager.ts @@ -110,11 +110,9 @@ export class AppListenerManager { // Livechat case AppInterface.ILivechatRoomClosedHandler: return this.executeLivechatRoomClosed(data as ILivechatRoom); - return; // User case AppInterface.IPreUserJoinRoomPrevent: return this.executePreUserJoinPrevent(data); - case AppInterface.IPostUserJoinRoom: return this.executePostUserJoin(data); default: @@ -124,8 +122,8 @@ export class AppListenerManager { } private async executePreUserJoinPrevent(data: any) { let prevented = false; - const cfUser = new User(Utilities.deepCloneAndFreeze(data.user), this.manager); - const cfRoom = new User(Utilities.deepCloneAndFreeze(data.room), this.manager); + const cfUser = new User(Utilities.deepCloneAndFreeze(data.user)); + const cfRoom = new User(Utilities.deepCloneAndFreeze(data.room)); for (const appId of this.listeners.get(AppInterface.IPreMessageSentPrevent)) { const app = this.manager.getOneById(appId); @@ -159,7 +157,7 @@ export class AppListenerManager { } private async executePostUserJoin(data: any) { - const cfUser = new User(Utilities.deepCloneAndFreeze(data.user), this.manager); + const cfUser = new User(Utilities.deepCloneAndFreeze(data.user)); const cfRoom = new Room(Utilities.deepCloneAndFreeze(data.room), this.manager); for (const appId of this.listeners.get(AppInterface.IPostRoomDeleted)) { @@ -174,7 +172,6 @@ export class AppListenerManager { this.am.getHttp(appId), ) as boolean; } - if (continueOn && app.hasMethod(AppMethod.EXECUTE_POST_USER_JOIN)) { await app.call(AppMethod.EXECUTE_POST_USER_JOIN, cfUser, diff --git a/src/server/users/User.ts b/src/server/users/User.ts index 995133edc..13477f21d 100644 --- a/src/server/users/User.ts +++ b/src/server/users/User.ts @@ -1,24 +1,21 @@ - -import { IUser, UserType, IUserEmail, UserStatusConnection } from "../../definition/users"; -import { AppManager } from '../AppManager'; +import { IUser, IUserEmail, UserStatusConnection, UserType } from '../../definition/users'; export class User implements IUser { + public id: string; + public username: string; + public emails: Array; + public type: UserType; + public isEnabled: boolean; + public name: string; + public roles: Array; + public status: string; + public statusConnection: UserStatusConnection; + public utcOffset: number; + public createdAt: Date; + public updatedAt: Date; + public lastLoginAt: Date; + public appId?: string; - id: string; - username: string; - emails: Array; - type: UserType; - isEnabled: boolean; - name: string; - roles: Array; - status: string; - statusConnection: UserStatusConnection; - utcOffset: number; - createdAt: Date; - updatedAt: Date; - lastLoginAt: Date; - appId?: string; - - public constructor(user: IUser, private manager: AppManager) { + public constructor(user: IUser) { Object.assign(this, user); } }