Skip to content

Commit

Permalink
feat(lib): add CryptoModule support for Chat SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-suwala committed Dec 4, 2023
1 parent f53b705 commit 9b99560
Show file tree
Hide file tree
Showing 17 changed files with 1,143 additions and 2,874 deletions.
4 changes: 2 additions & 2 deletions lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
},
"homepage": "https://github.com/pubnub/js-chat#readme",
"dependencies": {
"pubnub": "7.4.3"
"pubnub": "7.4.5"
},
"devDependencies": {
"@babel/core": "7.22.15",
Expand All @@ -34,7 +34,7 @@
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-terser": "^0.4.3",
"@types/jest": "29.5.0",
"@types/pubnub": "7.2.0",
"@types/pubnub": "7.4.0",
"babel-jest": "29.5.0",
"dotenv": "16.0.3",
"jest": "29.5.0",
Expand Down
29 changes: 29 additions & 0 deletions lib/src/crypto-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Message } from "./entities/message"
import PubNub from "pubnub"
import { TextMessageContent } from "./types"
import { Chat } from "./entities/chat"
// pubNubCryptoModule: typeof PubNub.CryptoModule

export class CryptoUtils {
static decrypt({
chat,
message,
decryptor,
}: {
chat: Chat
message: Message
decryptor: (encryptedContent: string) => TextMessageContent
}) {
const decryptedContent = decryptor(message.content.text)

return Message.fromDTO(chat, {
timetoken: message.timetoken,
message: decryptedContent,
channel: message.channelId,
publisher: message.userId,
actions: message.actions || {},
meta: message.meta,
error: undefined,
})
}
}
25 changes: 21 additions & 4 deletions lib/src/entities/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PubNub, {
ObjectCustom,
GetChannelMembersParameters,
SetMembershipsParameters,
ChannelMetadataObject,
} from "pubnub"
import { Chat } from "./chat"
import { Message } from "./message"
Expand All @@ -29,6 +30,22 @@ export type ChannelFields = Pick<
"id" | "name" | "custom" | "description" | "updated" | "status" | "type"
>

function normalizeChannelParams(params: ChannelDTOParams | ChannelMetadataObject<ObjectCustom>) {
return {
...params,
id: params.id,
name: params.name || undefined,
custom: params.custom || undefined,
description: params.description || undefined,
updated: params.updated || undefined,
status: params.status || undefined,
type:
params.type && ["direct", "group", "public"].includes(params.type)
? (params.type as ChannelType)
: "unknown",
}
}

export class Channel {
protected chat: Chat
readonly id: string
Expand Down Expand Up @@ -75,7 +92,7 @@ export class Channel {
type: params.type || undefined,
}

return getErrorProxiedEntity(new Channel(chat, data), chat.errorLogger)
return getErrorProxiedEntity(new Channel(chat, normalizeChannelParams(data)), chat.errorLogger)
}

/*
Expand All @@ -99,7 +116,7 @@ export class Channel {
if (event.message.type !== "channel") return
const channel = channels.find((c) => c.id === event.channel)
if (!channel) return
const newChannel = Channel.fromDTO(channel.chat, event.message.data)
const newChannel = Channel.fromDTO(channel.chat, normalizeChannelParams(event.message.data))
const newChannels = channels.map((channel) =>
channel.id === newChannel.id ? newChannel : channel
)
Expand Down Expand Up @@ -557,12 +574,12 @@ export class Channel {

async pinMessage(message: Message) {
const response = await this.chat.pinMessageToChannel(message, this)
return Channel.fromDTO(this.chat, response.data)
return Channel.fromDTO(this.chat, normalizeChannelParams(response.data))
}

async unpinMessage() {
const response = await this.chat.pinMessageToChannel(null, this)
return Channel.fromDTO(this.chat, response.data)
return Channel.fromDTO(this.chat, normalizeChannelParams(response.data))
}

async getPinnedMessage() {
Expand Down
3 changes: 2 additions & 1 deletion lib/src/entities/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { getErrorProxiedEntity, ErrorLogger } from "../error-logging"
import { cyrb53a } from "../hash"
import { uuidv4 } from "../uuidv4"

type ChatConfig = {
export type ChatConfig = {
saveDebugLog: boolean
typingTimeout: number
storeUserActivityInterval: number
Expand Down Expand Up @@ -114,6 +114,7 @@ export class Chat {
direct: 0,
group: 0,
public: 0,
unknown: 0,
},
}
}
Expand Down
11 changes: 10 additions & 1 deletion lib/src/entities/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class Message {
readonly meta?: {
[key: string]: any
}
readonly error?: string

get hasThread() {
if (!this.actions?.["threadRootId"]) {
Expand Down Expand Up @@ -90,12 +91,20 @@ export class Message {
static fromDTO(chat: Chat, params: MessageDTOParams) {
const data = {
timetoken: String(params.timetoken),
content: params.message,
content:
typeof params.message === "string"
? {
type: "text",
text: params.message,
files: [],
}
: params.message,
channelId: params.channel,
userId: "publisher" in params ? params.publisher : params.uuid || "unknown-user",
actions: "actions" in params ? params.actions : undefined,
meta:
"meta" in params ? params.meta : "userMetadata" in params ? params.userMetadata : undefined,
error: params.error || undefined,
}

return getErrorProxiedEntity(new Message(chat, data), chat.errorLogger)
Expand Down
8 changes: 5 additions & 3 deletions lib/src/entities/thread-channel.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { ObjectCustom, SetChannelMetadataResponse } from "pubnub"
import { Channel, ChannelFields } from "./channel"
import { Chat } from "./chat"
import { DeleteParameters, ThreadChannelDTOParams } from "../types"
import { ChannelType, DeleteParameters, ThreadChannelDTOParams } from "../types"
import { ThreadMessage } from "./thread-message"
import { getErrorProxiedEntity } from "../error-logging"
import { MESSAGE_THREAD_ID_PREFIX } from "../constants"
import { Message } from "./message"

export class ThreadChannel extends Channel {
Expand Down Expand Up @@ -33,7 +32,10 @@ export class ThreadChannel extends Channel {
description: params.description || undefined,
updated: params.updated || undefined,
status: params.status || undefined,
type: params.type || undefined,
type:
params.type && ["direct", "group", "public"].includes(params.type)
? (params.type as ChannelType)
: "unknown",
}

return getErrorProxiedEntity(new ThreadChannel(chat, data), chat.errorLogger)
Expand Down
26 changes: 16 additions & 10 deletions lib/src/entities/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ export class User {
/** @internal */
static fromDTO(
chat: Chat,
params: OptionalAllBut<UUIDMetadataObject<ObjectCustom>, "id"> & {
status?: string
type?: string
}
params:
| (OptionalAllBut<UUIDMetadataObject<ObjectCustom>, "id"> & {
status?: string
type?: string | null
})
| UUIDMetadataObject<ObjectCustom>
) {
const data = {
id: params.id,
Expand Down Expand Up @@ -115,14 +117,18 @@ export class User {
* Memberships
*/
async getMemberships(params: Omit<GetMembershipsParametersv2, "include"> = {}) {
const include = {
totalCount: true,
customFields: true,
channelFields: true,
customChannelFields: true,
channelTypeField: true,
statusField: true,
}

const membershipsResponse = await this.chat.sdk.objects.getMemberships({
...params,
include: {
totalCount: true,
customFields: true,
channelFields: true,
customChannelFields: true,
},
include,
filter: `!(channel.id LIKE '${INTERNAL_MODERATION_PREFIX}*')`,
})

Expand Down
5 changes: 5 additions & 0 deletions lib/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import PubNub from "pubnub"

export * from "./entities/chat"
export * from "./entities/channel"
export * from "./entities/user"
Expand All @@ -9,4 +11,7 @@ export * from "./entities/message-draft"
export * from "./entities/event"
export * from "./types"
export * from "./timetoken-utils"
export * from "./crypto-utils"
export * from "./constants"

export const PubNubCryptoModule = PubNub.CryptoModule
6 changes: 3 additions & 3 deletions lib/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { User } from "./entities/user"
import { Message } from "./entities/message"
import { Event } from "./entities/event"

export type ChannelType = "direct" | "group" | "public"
export type ChannelType = "direct" | "group" | "public" | "unknown"

export enum MessageType {
TEXT = "text",
Expand Down Expand Up @@ -158,8 +158,8 @@ export type MembershipResponse = Awaited<ReturnType<User["getMemberships"]>>
export type OptionalAllBut<T, K extends keyof T> = Partial<T> & Pick<T, K>

export type ChannelDTOParams = OptionalAllBut<ChannelMetadataObject<ObjectCustom>, "id"> & {
status?: string
type?: ChannelType
status?: string | null
type?: ChannelType | null | string
}

export type ThreadChannelDTOParams = ChannelDTOParams & {
Expand Down
Loading

0 comments on commit 9b99560

Please sign in to comment.