diff --git a/lib/src/constants.ts b/lib/src/constants.ts index dce57f9..481d58c 100644 --- a/lib/src/constants.ts +++ b/lib/src/constants.ts @@ -1,3 +1,4 @@ export const MESSAGE_THREAD_ID_PREFIX = "PUBNUB_INTERNAL_THREAD" +export const INTERNAL_MODERATION_PREFIX = "PUBNUB_INTERNAL_MODERATION_" export const INTERNAL_ADMIN_CHANNEL = "PUBNUB_INTERNAL_ADMIN_CHANNEL" export const ERROR_LOGGER_KEY_PREFIX = "PUBNUB_INTERNAL_ERROR_LOGGER" diff --git a/lib/src/entities/channel.ts b/lib/src/entities/channel.ts index d62c610..22c6ca2 100644 --- a/lib/src/entities/channel.ts +++ b/lib/src/entities/channel.ts @@ -22,6 +22,7 @@ import { User } from "./user" import { MentionsUtils } from "../mentions-utils" import { MessageDraft } from "./message-draft" import { getErrorProxiedEntity } from "../error-logging" +import { INTERNAL_MODERATION_PREFIX } from "../constants" export type ChannelFields = Pick< Channel, @@ -644,4 +645,58 @@ export class Channel { async deleteFile(params: { id: string; name: string }) { return this.chat.sdk.deleteFile({ channel: this.id, ...params }) } + + /** + * Moderation restrictions + */ + + async setResctrictions(user: User, params: { ban?: boolean; mute?: boolean }) { + if (!(this.chat.sdk as any)._config.secretKey) + throw "Moderation restrictions can only be set by clients initialized with a Secret Key." + return this.chat.setResctrictions(user.id, this.id, params) + } + + /* @internal */ + private async getRestrictions( + user?: User, + params?: Pick + ) { + return await this.chat.sdk.objects.getChannelMembers({ + channel: `${INTERNAL_MODERATION_PREFIX}${this.id}`, + include: { + totalCount: true, + customFields: true, + }, + ...(user && { filter: `uuid.id == '${user.id}'` }), + ...params, + }) + } + + async getUserRestrictions(user: User) { + const response = await this.getRestrictions(user) + const restrictions = response && response.data[0]?.custom + return { + ban: !!restrictions?.ban, + mute: !!restrictions?.mute, + } + } + + async getUsersRestrictions( + params?: Pick + ) { + const response = await this.getRestrictions(undefined, params) + return { + page: { + next: response.next, + prev: response.prev, + }, + total: response.totalCount, + status: response.status, + restrictions: response.data.map(({ custom, uuid }) => ({ + ban: !!custom?.ban, + mute: !!custom?.mute, + userId: uuid.id, + })), + } + } } diff --git a/lib/src/entities/chat.ts b/lib/src/entities/chat.ts index 7cd4931..b5d1ea8 100644 --- a/lib/src/entities/chat.ts +++ b/lib/src/entities/chat.ts @@ -14,7 +14,7 @@ import { import { Message } from "./message" import { Event } from "./event" import { Membership } from "./membership" -import { MESSAGE_THREAD_ID_PREFIX } from "../constants" +import { MESSAGE_THREAD_ID_PREFIX, INTERNAL_MODERATION_PREFIX } from "../constants" import { ThreadChannel } from "./thread-channel" import { MentionsUtils } from "../mentions-utils" import { getErrorProxiedEntity, ErrorLogger } from "../error-logging" @@ -1067,4 +1067,19 @@ export class Chat { ), } } + + /** + * Moderation restrictions + */ + + async setResctrictions( + userId: string, + channelId: string, + params: { ban?: boolean; mute?: boolean } + ) { + await this.sdk.objects.setChannelMembers({ + channel: `${INTERNAL_MODERATION_PREFIX}${channelId}`, + uuids: [{ id: userId, custom: params }], + }) + } } diff --git a/lib/src/entities/user.ts b/lib/src/entities/user.ts index cc86409..cf2635d 100644 --- a/lib/src/entities/user.ts +++ b/lib/src/entities/user.ts @@ -1,8 +1,9 @@ import PubNub, { UUIDMetadataObject, ObjectCustom, GetMembershipsParametersv2 } from "pubnub" import { Chat } from "./chat" import { DeleteParameters, OptionalAllBut } from "../types" +import { Channel } from "./channel" import { Membership } from "./membership" -import { INTERNAL_ADMIN_CHANNEL } from "../constants" +import { INTERNAL_ADMIN_CHANNEL, INTERNAL_MODERATION_PREFIX } from "../constants" import { getErrorProxiedEntity } from "../error-logging" export type UserFields = Pick< @@ -122,6 +123,7 @@ export class User { channelFields: true, customChannelFields: true, }, + filter: `!(channel.id LIKE '${INTERNAL_MODERATION_PREFIX}*')`, }) return { @@ -137,6 +139,63 @@ export class User { } } + /** + * Moderation restrictions + */ + + async setResctrictions(channel: Channel, params: { ban?: boolean; mute?: boolean }) { + if (!(this.chat.sdk as any)._config.secretKey) + throw "Moderation restrictions can only be set by clients initialized with a Secret Key." + return this.chat.setResctrictions(this.id, channel.id, params) + } + + /* @internal */ + private async getRestrictions( + channel?: Channel, + params?: Pick + ) { + const filter = channel + ? `channel.id == '${INTERNAL_MODERATION_PREFIX}${channel.id}'` + : `channel.id LIKE '${INTERNAL_MODERATION_PREFIX}*'` + return await this.chat.sdk.objects.getMemberships({ + uuid: this.id, + include: { + totalCount: true, + customFields: true, + }, + filter, + ...params, + }) + } + + async getChannelRestrictions(channel: Channel) { + const response = await this.getRestrictions(channel) + const restrictions = response && response.data[0]?.custom + return { + ban: !!restrictions?.ban, + mute: !!restrictions?.mute, + } + } + + async getChannelsRestrictions( + params?: Pick + ) { + const response = await this.getRestrictions(undefined, params) + return { + page: { + next: response.next, + prev: response.prev, + }, + total: response.totalCount, + status: response.status, + restrictions: response.data.map(({ custom, channel }) => ({ + ban: !!custom?.ban, + mute: !!custom?.mute, + channelId: channel.id.replace(INTERNAL_MODERATION_PREFIX, ""), + })), + } + } + /* * Other */