diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..a6c7e4c2d --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "tabWidth": 4, + "useTabs": false, + "singleQuote": true, + "trailingComma": "all", + "printWidth": 160 +} diff --git a/src/definition/accessors/IModifyUpdater.ts b/src/definition/accessors/IModifyUpdater.ts index 6142e184f..7923ac393 100644 --- a/src/definition/accessors/IModifyUpdater.ts +++ b/src/definition/accessors/IModifyUpdater.ts @@ -2,6 +2,7 @@ import { IUser } from '../users'; import { ILivechatUpdater } from './ILivechatUpdater'; import { IMessageBuilder } from './IMessageBuilder'; import { IRoomBuilder } from './IRoomBuilder'; +import { IRoomUpdater } from './IRoomUpdater'; import { IUserUpdater } from './IUserUpdater'; export interface IModifyUpdater { @@ -17,6 +18,12 @@ export interface IModifyUpdater { */ getUserUpdater(): IUserUpdater; + /** + * Get the object responsible for + * the methods that let you edit a room + */ + getRoomUpdater(): IRoomUpdater; + /** * Modifies an existing message. * Raises an exception if a non-existent messageId is supplied diff --git a/src/definition/accessors/IRoomUpdater.ts b/src/definition/accessors/IRoomUpdater.ts new file mode 100644 index 000000000..aa4603912 --- /dev/null +++ b/src/definition/accessors/IRoomUpdater.ts @@ -0,0 +1,6 @@ +import { IRoom } from '../rooms'; + +export interface IRoomUpdater { + archiveRoom(room: IRoom): Promise; + unarchiveRoom(room: IRoom): Promise; +} diff --git a/src/definition/rooms/IRoom.ts b/src/definition/rooms/IRoom.ts index da106db08..6f837d611 100644 --- a/src/definition/rooms/IRoom.ts +++ b/src/definition/rooms/IRoom.ts @@ -6,6 +6,7 @@ export interface IRoom { displayName?: string; slugifiedName: string; type: RoomType; + isArchived: boolean; creator: IUser; /** * @deprecated usernames will be removed on version 2.0.0 diff --git a/src/server/accessors/ModifyUpdater.ts b/src/server/accessors/ModifyUpdater.ts index a564398c1..b92f17199 100644 --- a/src/server/accessors/ModifyUpdater.ts +++ b/src/server/accessors/ModifyUpdater.ts @@ -1,4 +1,5 @@ import { ILivechatUpdater, IMessageBuilder, IModifyUpdater, IRoomBuilder } from '../../definition/accessors'; +import { IRoomUpdater } from '../../definition/accessors/IRoomUpdater'; import { IUserUpdater } from '../../definition/accessors/IUserUpdater'; import { RocketChatAssociationModel } from '../../definition/metadata'; import { RoomType } from '../../definition/rooms'; @@ -7,15 +8,18 @@ import { AppBridges } from '../bridges'; import { LivechatUpdater } from './LivechatUpdater'; import { MessageBuilder } from './MessageBuilder'; import { RoomBuilder } from './RoomBuilder'; +import { RoomUpdater } from './RoomUpdater'; import { UserUpdater } from './UserUpdater'; export class ModifyUpdater implements IModifyUpdater { private livechatUpdater: ILivechatUpdater; private userUpdater: IUserUpdater; + private roomUpdater: IRoomUpdater; constructor(private readonly bridges: AppBridges, private readonly appId: string) { this.livechatUpdater = new LivechatUpdater(this.bridges, this.appId); this.userUpdater = new UserUpdater(this.bridges, this.appId); + this.roomUpdater = new RoomUpdater(this.bridges, this.appId); } public getLivechatUpdater(): ILivechatUpdater { @@ -26,6 +30,10 @@ export class ModifyUpdater implements IModifyUpdater { return this.userUpdater; } + public getRoomUpdater(): IRoomUpdater { + return this.roomUpdater; + } + public async message(messageId: string, updater: IUser): Promise { const msg = await this.bridges.getMessageBridge().doGetById(messageId, this.appId); @@ -53,7 +61,7 @@ export class ModifyUpdater implements IModifyUpdater { const result = builder.getMessage(); if (!result.id) { - throw new Error('Invalid message, can\'t update a message without an id.'); + throw new Error(`Invalid message, can't update a message without an id.`); } if (!result.sender || !result.sender.id) { diff --git a/src/server/accessors/RoomBuilder.ts b/src/server/accessors/RoomBuilder.ts index 7c3de167d..ef175b1ac 100644 --- a/src/server/accessors/RoomBuilder.ts +++ b/src/server/accessors/RoomBuilder.ts @@ -5,6 +5,7 @@ import { IUser } from '../../definition/users'; export class RoomBuilder implements IRoomBuilder { public kind: RocketChatAssociationModel.ROOM | RocketChatAssociationModel.DISCUSSION; + protected room: IRoom; private members: Array; @@ -140,11 +141,11 @@ export class RoomBuilder implements IRoomBuilder { } public getCustomFields(): { [key: string]: object } { - return this.room.customFields; + return this.room.customFields; } public getUserIds(): Array { - return this.room.userIds; + return this.room.userIds; } public getRoom(): IRoom { diff --git a/src/server/accessors/RoomUpdater.ts b/src/server/accessors/RoomUpdater.ts new file mode 100644 index 000000000..ee56edfb7 --- /dev/null +++ b/src/server/accessors/RoomUpdater.ts @@ -0,0 +1,13 @@ +import { IRoomUpdater } from '../../definition/accessors/IRoomUpdater'; +import { IRoom } from '../../definition/rooms'; +import { AppBridges } from '../bridges'; + +export class RoomUpdater implements IRoomUpdater { + constructor(private readonly bridges: AppBridges, private readonly appId: string) {} + public async archiveRoom(room: IRoom): Promise { + return this.bridges.getRoomBridge().doArchiveRoom(room, this.appId); + } + public async unarchiveRoom(room: IRoom): Promise { + return this.bridges.getRoomBridge().doUnarchiveRoom(room, this.appId); + } +} diff --git a/src/server/bridges/RoomBridge.ts b/src/server/bridges/RoomBridge.ts index e81d4935f..bb692aa2e 100644 --- a/src/server/bridges/RoomBridge.ts +++ b/src/server/bridges/RoomBridge.ts @@ -55,8 +55,25 @@ export abstract class RoomBridge extends BaseBridge { } } - public async doCreateDiscussion(room: IRoom, parentMessage: IMessage | undefined, - reply: string | undefined, members: Array, appId: string): Promise { + public async doArchiveRoom(room: IRoom, appId: string): Promise { + if (this.hasWritePermission(appId)) { + return this.archiveRoom(room, appId); + } + } + + public async doUnarchiveRoom(room: IRoom, appId: string): Promise { + if (this.hasWritePermission(appId)) { + return this.unarchiveRoom(room, appId); + } + } + + public async doCreateDiscussion( + room: IRoom, + parentMessage: IMessage | undefined, + reply: string | undefined, + members: Array, + appId: string, + ): Promise { if (this.hasWritePermission(appId)) { return this.createDiscussion(room, parentMessage, reply, members, appId); } @@ -76,19 +93,28 @@ export abstract class RoomBridge extends BaseBridge { protected abstract getDirectByUsernames(usernames: Array, appId: string): Promise; protected abstract getMembers(roomId: string, appId: string): Promise>; protected abstract update(room: IRoom, members: Array, appId: string): Promise; - protected abstract createDiscussion(room: IRoom, parentMessage: IMessage | undefined, - reply: string | undefined, members: Array, appId: string): Promise; + protected abstract createDiscussion( + room: IRoom, + parentMessage: IMessage | undefined, + reply: string | undefined, + members: Array, + appId: string, + ): Promise; protected abstract delete(room: string, appId: string): Promise; + protected abstract archiveRoom(room: IRoom, appId: string): Promise; + protected abstract unarchiveRoom(room: IRoom, appId: string): Promise; private hasWritePermission(appId: string): boolean { if (AppPermissionManager.hasPermission(appId, AppPermissions.room.write)) { return true; } - AppPermissionManager.notifyAboutError(new PermissionDeniedError({ - appId, - missingPermissions: [AppPermissions.room.write], - })); + AppPermissionManager.notifyAboutError( + new PermissionDeniedError({ + appId, + missingPermissions: [AppPermissions.room.write], + }), + ); return false; } @@ -98,10 +124,12 @@ export abstract class RoomBridge extends BaseBridge { return true; } - AppPermissionManager.notifyAboutError(new PermissionDeniedError({ - appId, - missingPermissions: [AppPermissions.room.read], - })); + AppPermissionManager.notifyAboutError( + new PermissionDeniedError({ + appId, + missingPermissions: [AppPermissions.room.read], + }), + ); return false; } diff --git a/src/server/rooms/Room.ts b/src/server/rooms/Room.ts index 34ae7c3b4..4efdeb7d4 100644 --- a/src/server/rooms/Room.ts +++ b/src/server/rooms/Room.ts @@ -9,6 +9,7 @@ export class Room implements IRoom { public displayName?: string; public slugifiedName: string; public type: RoomType; + public isArchived: boolean; public creator: IUser; public isDefault?: boolean; public isReadOnly?: boolean; diff --git a/tests/test-data/bridges/roomBridge.ts b/tests/test-data/bridges/roomBridge.ts index b28103a22..09488eb64 100644 --- a/tests/test-data/bridges/roomBridge.ts +++ b/tests/test-data/bridges/roomBridge.ts @@ -43,4 +43,12 @@ export class TestsRoomBridge extends RoomBridge { public delete(roomId: string, appId: string): Promise { throw new Error('Method not implemented.'); } + + protected archiveRoom(room: IRoom, appId: string): Promise { + throw new Error('Method not implemented.'); + } + + protected unarchiveRoom(room: IRoom, appId: string): Promise { + throw new Error('Method not implemented.'); + } } diff --git a/tests/test-data/utilities.ts b/tests/test-data/utilities.ts index 19b8aab01..a3613dfbd 100644 --- a/tests/test-data/utilities.ts +++ b/tests/test-data/utilities.ts @@ -96,6 +96,7 @@ export class TestData { slugifiedName: slugifiedName ? slugifiedName : 'testing-room', displayName: 'Testing Room', type: RoomType.CHANNEL, + isArchived: false, creator: TestData.getUser(), usernames: [TestData.getUser().username], isDefault: true, @@ -121,39 +122,41 @@ export class TestData { emoji: ':see_no_evil:', avatarUrl: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4', alias: 'Testing Bot', - attachments: [{ - collapsed: false, - color: '#00b2b2', - text: 'Just an attachment that is used for testing', - timestamp: new Date(), - timestampLink: 'https://google.com/', - thumbnailUrl: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4', - author: { - name: 'Author Name', - link: 'https://github.com/graywolf336', - icon: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4', - }, - title: { - value: 'Attachment Title', - link: 'https://github.com/RocketChat', - displayDownloadLink: false, - }, - imageUrl: 'https://rocket.chat/images/default/logo.svg', - audioUrl: 'http://www.w3schools.com/tags/horse.mp3', - videoUrl: 'http://www.w3schools.com/tags/movie.mp4', - fields: [ - { - short: true, - title: 'Test', - value: 'Testing out something or other', + attachments: [ + { + collapsed: false, + color: '#00b2b2', + text: 'Just an attachment that is used for testing', + timestamp: new Date(), + timestampLink: 'https://google.com/', + thumbnailUrl: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4', + author: { + name: 'Author Name', + link: 'https://github.com/graywolf336', + icon: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4', }, - { - short: true, - title: 'Another Test', - value: '[Link](https://google.com/) something and this and that.', + title: { + value: 'Attachment Title', + link: 'https://github.com/RocketChat', + displayDownloadLink: false, }, - ], - }], + imageUrl: 'https://rocket.chat/images/default/logo.svg', + audioUrl: 'http://www.w3schools.com/tags/horse.mp3', + videoUrl: 'http://www.w3schools.com/tags/movie.mp4', + fields: [ + { + short: true, + title: 'Test', + value: 'Testing out something or other', + }, + { + short: true, + title: 'Another Test', + value: '[Link](https://google.com/) something and this and that.', + }, + ], + }, + ], }; } @@ -173,7 +176,14 @@ export class TestData { items: new Array(), } as ISlashCommandPreview); }, - executePreviewItem: (item: ISlashCommandPreviewItem, context: SlashCommandContext, read: IRead, modify: IModify, http: IHttp, persis: IPersistence): Promise => { + executePreviewItem: ( + item: ISlashCommandPreviewItem, + context: SlashCommandContext, + read: IRead, + modify: IModify, + http: IHttp, + persis: IPersistence, + ): Promise => { return Promise.resolve(); }, }; @@ -183,14 +193,23 @@ export class TestData { return { visibility, security, - endpoints: [{ - path, - get(request: IApiRequest, endpoint: IApiEndpointInfo, read: IRead, modify: IModify, http: IHttp, persis: IPersistence): Promise { - return Promise.resolve({ - status: HttpStatusCode.OK, - }); + endpoints: [ + { + path, + get( + request: IApiRequest, + endpoint: IApiEndpointInfo, + read: IRead, + modify: IModify, + http: IHttp, + persis: IPersistence, + ): Promise { + return Promise.resolve({ + status: HttpStatusCode.OK, + }); + }, }, - }], + ], }; } @@ -322,10 +341,19 @@ export class TestData { } public static getMockApp(id: string, name: string): ProxiedApp { - return new ProxiedApp({} as AppManager, { status: AppStatus.UNKNOWN } as IAppStorageItem, { - getName() { return 'testing'; }, - getID() { return 'testing'; }, - } as App, (mod: string) => mod); + return new ProxiedApp( + {} as AppManager, + { status: AppStatus.UNKNOWN } as IAppStorageItem, + { + getName() { + return 'testing'; + }, + getID() { + return 'testing'; + }, + } as App, + (mod: string) => mod, + ); } }