diff --git a/packages/restapi/src/lib/chat/addAdmins.ts b/packages/restapi/src/lib/chat/addAdmins.ts index 0a15e31f5..450943621 100644 --- a/packages/restapi/src/lib/chat/addAdmins.ts +++ b/packages/restapi/src/lib/chat/addAdmins.ts @@ -33,6 +33,7 @@ export const addAdmins = async ( } const upsertPayload = { + members: [], admins: admins, }; diff --git a/packages/restapi/src/lib/chat/addMembers.ts b/packages/restapi/src/lib/chat/addMembers.ts index e43172706..535f7589b 100644 --- a/packages/restapi/src/lib/chat/addMembers.ts +++ b/packages/restapi/src/lib/chat/addMembers.ts @@ -7,7 +7,7 @@ export interface AddMembersToGroupType extends EnvOptionsType { members: Array; account?: string | null; signer?: SignerType | null; - pgpPrivateKey?: string | null; + pgpPrivateKey?: string | null; } /** @@ -35,6 +35,7 @@ export const addMembers = async ( const upsertPayload = { members: members, + admins: [], }; const groupMemberUpdateOptions: GroupMemberUpdateOptions = { diff --git a/packages/restapi/src/lib/chat/approveRequest.ts b/packages/restapi/src/lib/chat/approveRequest.ts index 8ad6388ac..4fe9958f5 100644 --- a/packages/restapi/src/lib/chat/approveRequest.ts +++ b/packages/restapi/src/lib/chat/approveRequest.ts @@ -79,7 +79,6 @@ export const approveCore = async ( ? await getUserDID(senderAddress, env) : await getUserDID(address, env); - let sessionKey: string | null = null; let encryptedSecret: string | null = null; /** * GENERATE VERIFICATION PROOF @@ -103,8 +102,6 @@ export const approveCore = async ( plainText: secretKey, keys: publicKeys, }); - - sessionKey = CryptoJS.SHA256(encryptedSecret).toString(); } } @@ -130,7 +127,6 @@ export const approveCore = async ( fromDID, toDID, status, - sessionKey: sessionKey, encryptedSecret: encryptedSecret, }; break; @@ -151,7 +147,6 @@ export const approveCore = async ( status, sigType, verificationProof, - sessionKey, encryptedSecret, }; diff --git a/packages/restapi/src/lib/chat/createGroupV2.ts b/packages/restapi/src/lib/chat/createGroupV2.ts new file mode 100644 index 000000000..07bb96041 --- /dev/null +++ b/packages/restapi/src/lib/chat/createGroupV2.ts @@ -0,0 +1,222 @@ +import axios from 'axios'; +import { getAPIBaseUrls, isValidETHAddress } from '../helpers'; +import Constants from '../constants'; +import { EnvOptionsType, GroupDTO, SignerType, Rules } from '../types'; +import { + getWallet, + getUserDID, + IPGPHelper, + PGPHelper, + validateScheduleDates, + getConnectedUserV2Core, +} from './helpers'; +import * as CryptoJS from 'crypto-js'; + +export interface ChatCreateGroupTypeV2 extends EnvOptionsType { + account?: string | null; + signer?: SignerType | null; + pgpPrivateKey?: string | null; + // Profile + groupName: string; + groupDescription: string | null; + groupImage: string | null; + rules: Rules | null; + isPublic: boolean; + groupType: 'default' | 'space'; + config: { + meta: string | null; + scheduleAt: Date | null; + scheduleEnd: Date | null; + status: 'PENDING' | null; + }; + members: Array; + admins: Array; +} + +export const createGroupV2 = async (options: ChatCreateGroupTypeV2) => { + return await createGroupCoreV2(options, PGPHelper); +}; + +export const createGroupCoreV2 = async ( + options: ChatCreateGroupTypeV2, + pgpHelper: IPGPHelper +): Promise => { + const { + account = null, + signer = null, + pgpPrivateKey = null, + env = Constants.ENV.PROD, + groupName, + groupDescription, + groupImage, + rules, + isPublic, + groupType, + config: { meta, scheduleAt, scheduleEnd, status }, + members, + admins, + } = options; + + try { + const wallet = getWallet({ account, signer }); + const connectedUser = await getConnectedUserV2Core( + wallet, + pgpPrivateKey, + env, + pgpHelper + ); + const convertedMembersPromise = members.map(async (each) => { + return getUserDID(each, env); + }); + const convertedAdminsPromise = admins.map(async (each) => { + return getUserDID(each, env); + }); + const convertedMembers = await Promise.all(convertedMembersPromise); + const convertedAdmins = await Promise.all(convertedAdminsPromise); + /** + * VALIDATIONS + */ + createGroupV2OptionsValidator(options); + /** + * PROFILE VERIFICATION PROOF + */ + const profileVerificationBody = { + groupName, + groupDescription, + groupImage, + rules, + isPublic, + groupType, + }; + const profileHash = CryptoJS.SHA256( + JSON.stringify(profileVerificationBody) + ).toString(); + const profileSignature: string = await pgpHelper.sign({ + message: profileHash, + signingKey: connectedUser.privateKey!, + }); + const profileVerificationProof = `pgpv2:${profileSignature}:${connectedUser.did}`; + /** + * CONFIG VERIFICATION PROOF + */ + const configVerificationBody = { + meta, + scheduleAt, + scheduleEnd, + status, + }; + const configHash = CryptoJS.SHA256( + JSON.stringify(configVerificationBody) + ).toString(); + const configSignature: string = await pgpHelper.sign({ + message: configHash, + signingKey: connectedUser.privateKey!, + }); + const configVerificationProof = `pgpv2:${configSignature}:${connectedUser.did}`; + /** + * IDEMPOTENT VERIFICATION PROOF + */ + const idempotentVerificationBody = { + members: convertedMembers, + admins: convertedAdmins, + }; + const idempotentHash = CryptoJS.SHA256( + JSON.stringify(idempotentVerificationBody) + ).toString(); + const idempotentSignature: string = await pgpHelper.sign({ + message: idempotentHash, + signingKey: connectedUser.privateKey!, + }); + const idempotentVerificationProof = `pgpv2:${idempotentSignature}:${connectedUser.did}`; + + const API_BASE_URL = getAPIBaseUrls(env); + const apiEndpoint = `${API_BASE_URL}/v2/chat/groups`; + const body = { + groupName, + groupDescription, + groupImage, + rules, + isPublic, + groupType, + profileVerificationProof, + config: { + meta, + scheduleAt, + scheduleEnd, + status, + configVerificationProof, + }, + members: convertedMembers, + admins: convertedAdmins, + idempotentVerificationProof, + }; + + return axios + .post(apiEndpoint, body) + .then((response) => { + return response.data; + }) + .catch((err) => { + if (err?.response?.data) + throw new Error(JSON.stringify(err?.response?.data)); + throw new Error(err); + }); + } catch (err) { + console.error( + `[Push SDK] - API - Error - API ${createGroupV2.name} -: `, + err + ); + throw Error( + `[Push SDK] - API - Error - API ${createGroupV2.name} -: ${err}` + ); + } +}; + +const createGroupV2OptionsValidator = ( + options: ChatCreateGroupTypeV2 +): void => { + const { + account = null, + signer = null, + pgpPrivateKey = null, + groupName, + groupDescription, + groupImage, + rules, + isPublic, + groupType, + config: { meta, scheduleAt, scheduleEnd, status }, + members, + admins, + } = options; + + if (!pgpPrivateKey && !signer) { + throw new Error(`At least one from pgpPrivateKey or signer is necessary!`); + } + + if (groupName == null || groupName.length == 0) { + throw new Error(`groupName cannot be null or empty`); + } + + if (groupName.length > 50) { + throw new Error(`groupName cannot be more than 50 characters`); + } + + if (groupDescription && groupDescription.length > 150) { + throw new Error(`groupDescription cannot be more than 150 characters`); + } + + for (let i = 0; i < members.length; i++) { + if (members[i] && !isValidETHAddress(members[i])) { + throw new Error(`Invalid member address!`); + } + } + + for (let i = 0; i < admins.length; i++) { + if (!isValidETHAddress(admins[i])) { + throw new Error(`Invalid admin address!`); + } + } + + validateScheduleDates(scheduleAt, scheduleEnd); +}; diff --git a/packages/restapi/src/lib/chat/helpers/payloadHelper.ts b/packages/restapi/src/lib/chat/helpers/payloadHelper.ts index 591ef58f0..c206c0a7b 100644 --- a/packages/restapi/src/lib/chat/helpers/payloadHelper.ts +++ b/packages/restapi/src/lib/chat/helpers/payloadHelper.ts @@ -74,7 +74,6 @@ export interface IUpdateGroupRequestPayload { admins: Array; address: string; verificationProof: string; - sessionKey: string | null; encryptedSecret: string | null; } @@ -365,7 +364,6 @@ export const updateGroupPayload = ( admins: Array, address: string, verificationProof: string, - sessionKey: string | null, encryptedSecret: string | null, groupDescription?: string | null, groupImage?: string | null, @@ -383,7 +381,6 @@ export const updateGroupPayload = ( admins: admins, address: address, verificationProof: verificationProof, - sessionKey: sessionKey, encryptedSecret: encryptedSecret, scheduleAt: scheduleAt, scheduleEnd: scheduleEnd, diff --git a/packages/restapi/src/lib/chat/helpers/validator.ts b/packages/restapi/src/lib/chat/helpers/validator.ts index 9c4797e8e..b49f1220a 100644 --- a/packages/restapi/src/lib/chat/helpers/validator.ts +++ b/packages/restapi/src/lib/chat/helpers/validator.ts @@ -213,7 +213,7 @@ export const updateGroupRequestValidator = ( export const validateGroupMemberUpdateOptions = ( options: GroupMemberUpdateOptions ): void => { - const { chatId, upsert, remove, } = options; + const { chatId, upsert, remove } = options; if (!chatId || chatId.trim().length === 0) { throw new Error('Chat ID cannot be null or empty.'); @@ -227,8 +227,8 @@ export const validateGroupMemberUpdateOptions = ( `Invalid role: ${role}. Allowed roles are ${allowedRoles.join(', ')}.` ); } - if (upsert[role] && upsert[role].length > 1000) { - throw new Error(`${role} array cannot have more than 1000 addresses.`); + if (upsert[role] && upsert[role].length > 100) { + throw new Error(`${role} array cannot have more than 100 addresses.`); } // Assuming you have a function `isValidETHAddress` to validate Ethereum addresses upsert[role].forEach((address) => { @@ -239,8 +239,8 @@ export const validateGroupMemberUpdateOptions = ( }); // Validating remove array - if (remove && remove.length > 1000) { - throw new Error('Remove array cannot have more than 1000 addresses.'); + if (remove && remove.length > 100) { + throw new Error('Remove array cannot have more than 100 addresses.'); } remove.forEach((address) => { if (!isValidETHAddress(address)) { diff --git a/packages/restapi/src/lib/chat/index.ts b/packages/restapi/src/lib/chat/index.ts index a8354d0a6..ab6a4580e 100644 --- a/packages/restapi/src/lib/chat/index.ts +++ b/packages/restapi/src/lib/chat/index.ts @@ -11,6 +11,7 @@ export { decryptPGPKey } from '../helpers/crypto'; export { decryptConversation } from './helpers'; export * from './helpers/payloadHelper'; export * from './createGroup'; +export * from './createGroupV2'; export * from './updateGroup'; export * from './getGroup'; export * from './getGroupByName'; @@ -25,4 +26,3 @@ export * from './getGroupMemberStatus'; export * from './getGroupMembers'; export * from './getGroupInfo'; export * from './getChatMemberCount'; -; \ No newline at end of file diff --git a/packages/restapi/src/lib/chat/removeAdmins.ts b/packages/restapi/src/lib/chat/removeAdmins.ts index 8b7a996e6..bf00cebc5 100644 --- a/packages/restapi/src/lib/chat/removeAdmins.ts +++ b/packages/restapi/src/lib/chat/removeAdmins.ts @@ -38,7 +38,10 @@ export const removeAdmins = async ( const groupMemberUpdateOptions: GroupMemberUpdateOptions = { chatId: chatId, - upsert: {}, + upsert: { + members: [], + admins: [], + }, remove: admins, account: account, signer: signer, diff --git a/packages/restapi/src/lib/chat/removeMembers.ts b/packages/restapi/src/lib/chat/removeMembers.ts index ee37bf9ce..ae8c61feb 100644 --- a/packages/restapi/src/lib/chat/removeMembers.ts +++ b/packages/restapi/src/lib/chat/removeMembers.ts @@ -34,7 +34,10 @@ export const removeMembers = async ( const groupMemberUpdateOptions: GroupMemberUpdateOptions = { chatId: chatId, - upsert: {}, + upsert: { + members: [], + admins: [], + }, remove: members, account: account, signer: signer, diff --git a/packages/restapi/src/lib/chat/updateGroup.ts b/packages/restapi/src/lib/chat/updateGroup.ts index 415a75032..48db488b5 100644 --- a/packages/restapi/src/lib/chat/updateGroup.ts +++ b/packages/restapi/src/lib/chat/updateGroup.ts @@ -125,7 +125,6 @@ export const updateGroupCore = async ( } }); - let sessionKey: string | null = null; let encryptedSecret: string | null = null; if ((!sameMembers || !participantStatus.isMember) && !groupChat.isPublic) { const secretKey = AES.generateRandomSecret(15); @@ -148,8 +147,6 @@ export const updateGroupCore = async ( plainText: secretKey, keys: publicKeys, }); - - sessionKey = CryptoJS.SHA256(encryptedSecret).toString(); } const bodyToBeHashed = { @@ -175,7 +172,6 @@ export const updateGroupCore = async ( convertedAdmins, connectedUser.did, verificationProof, - sessionKey, encryptedSecret, groupDescription, groupImage, @@ -192,7 +188,8 @@ export const updateGroupCore = async ( return response.data; }) .catch((err) => { - if (err?.response?.data) throw new Error(err?.response?.data); + if (err?.response?.data) + throw new Error(JSON.stringify(err.response.data)); throw new Error(err); }); } catch (err) { diff --git a/packages/restapi/src/lib/chat/updateGroupConfig.ts b/packages/restapi/src/lib/chat/updateGroupConfig.ts new file mode 100644 index 000000000..24fc9518c --- /dev/null +++ b/packages/restapi/src/lib/chat/updateGroupConfig.ts @@ -0,0 +1,95 @@ +import axios from 'axios'; +import { getAPIBaseUrls } from '../helpers'; +import Constants from '../constants'; +import { ChatStatus, EnvOptionsType, GroupInfoDTO, SignerType } from '../types'; +import { sign, getWallet, getConnectedUserV2 } from './helpers'; +import * as CryptoJS from 'crypto-js'; + +export interface ChatUpdateConfigProfileType extends EnvOptionsType { + account?: string | null; + signer?: SignerType | null; + chatId: string; + meta?: string | null; + scheduleAt?: Date | null; + scheduleEnd?: Date | null; + status?: ChatStatus | null; + pgpPrivateKey?: string | null; +} + +/** + * Update Group Config + */ +export const updateGroupConfig = async ( + options: ChatUpdateConfigProfileType +): Promise => { + const { + chatId, + meta, + scheduleAt, + scheduleEnd, + status, + account = null, + signer = null, + env = Constants.ENV.PROD, + pgpPrivateKey = null, + } = options || {}; + try { + /** + * VALIDATIONS + */ + if (account == null && signer == null) { + throw new Error(`At least one from account or signer is necessary!`); + } + + const wallet = getWallet({ account, signer }); + + /** + * CREATE PROFILE VERIFICATION PROOF + */ + const bodyToBeHashed = { + meta, + scheduleAt, + scheduleEnd, + status, + }; + + const hash = CryptoJS.SHA256(JSON.stringify(bodyToBeHashed)).toString(); + const connectedUser = await getConnectedUserV2(wallet, pgpPrivateKey, env); + const signature: string = await sign({ + message: hash, + signingKey: connectedUser.privateKey!, + }); + const sigType = 'pgpv2'; + // Account is need to verify the signature at any future point + const configVerificationProof: string = + sigType + ':' + signature + ':' + connectedUser.did; + + /** + * API CALL TO PUSH NODES + */ + const API_BASE_URL = getAPIBaseUrls(env); + const apiEndpoint = `${API_BASE_URL}/v1/chat/groups/${chatId}/config`; + + const body = bodyToBeHashed; + (body as any).configVerificationProof = configVerificationProof; + + return axios + .put(apiEndpoint, body) + .then((response) => { + return response.data; + }) + .catch((err) => { + if (err?.response?.data) + throw new Error(JSON.stringify(err?.response?.data)); + throw new Error(err); + }); + } catch (err) { + console.error( + `[Push SDK] - API - Error - API ${updateGroupConfig.name} -: `, + err + ); + throw Error( + `[Push SDK] - API - Error - API ${updateGroupConfig.name} -: ${err}` + ); + } +}; diff --git a/packages/restapi/src/lib/chat/updateGroupMembers.ts b/packages/restapi/src/lib/chat/updateGroupMembers.ts index 452748e4d..e1d97b31c 100644 --- a/packages/restapi/src/lib/chat/updateGroupMembers.ts +++ b/packages/restapi/src/lib/chat/updateGroupMembers.ts @@ -10,11 +10,7 @@ import { pgpEncrypt, } from './helpers'; import * as CryptoJS from 'crypto-js'; -import { - EnvOptionsType, - GroupInfoDTO, - SignerType, -} from '../types'; +import { EnvOptionsType, GroupInfoDTO, SignerType } from '../types'; import { getGroupInfo } from './getGroupInfo'; import { getGroupMemberStatus } from './getGroupMemberStatus'; import * as AES from '../chat/helpers/aes'; @@ -69,7 +65,6 @@ export const updateGroupMembers = async ( remove.map((userDID) => getUserDID(userDID, env)) ); - let sessionKey: string | null = null; let encryptedSecret: string | null = null; const group = await getGroupInfo({ chatId, env }); @@ -124,15 +119,12 @@ export const updateGroupMembers = async ( plainText: secretKey, keys: publicKeys, }); - - sessionKey = CryptoJS.SHA256(encryptedSecret).toString(); } } const bodyToBeHashed = { upsert: convertedUpsert, remove: convertedRemove, - sessionKey, encryptedSecret, }; @@ -142,24 +134,24 @@ export const updateGroupMembers = async ( signingKey: connectedUser.privateKey!, }); const sigType = 'pgpv2'; - const verificationProof = `${sigType}:${signature}:${connectedUser.did}`; + const deltaVerificationProof = `${sigType}:${signature}:${connectedUser.did}`; const API_BASE_URL = getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/chat/groups/${chatId}/members`; const body = { upsert: convertedUpsert, remove: convertedRemove, - sessionKey, encryptedSecret, - verificationProof, + deltaVerificationProof, }; return axios - .post(apiEndpoint, body) + .put(apiEndpoint, body) .then((response) => { return response.data; }) .catch((err) => { - if (err?.response?.data) throw new Error(err?.response?.data); + if (err?.response?.data) + throw new Error(JSON.stringify(err.response.data)); throw new Error(err); }); } catch (err) { diff --git a/packages/restapi/src/lib/chat/updateGroupProfile.ts b/packages/restapi/src/lib/chat/updateGroupProfile.ts index 189413c25..d33757c24 100644 --- a/packages/restapi/src/lib/chat/updateGroupProfile.ts +++ b/packages/restapi/src/lib/chat/updateGroupProfile.ts @@ -2,9 +2,9 @@ import axios from 'axios'; import { getAPIBaseUrls } from '../helpers'; import Constants from '../constants'; import { - ChatStatus, EnvOptionsType, GroupDTO, + GroupInfoDTO, Rules, SignerType, } from '../types'; @@ -16,43 +16,35 @@ import { updateGroupRequestValidator, } from './helpers'; import * as CryptoJS from 'crypto-js'; -import { getGroup } from './getGroup'; +import { getGroupInfo } from './getGroupInfo'; export interface ChatUpdateGroupProfileType extends EnvOptionsType { account?: string | null; signer?: SignerType | null; chatId: string; groupName: string; - groupImage?: string | null; - groupDescription?: string | null; - pgpPrivateKey?: string | null; - scheduleAt?: Date | null; - scheduleEnd?: Date | null; - status?: ChatStatus | null; - meta?: string | null; + groupDescription: string | null; + groupImage: string | null; rules?: Rules | null; + pgpPrivateKey?: string | null; } /** - * Update Group information + * Update Group Profile */ export const updateGroupProfile = async ( options: ChatUpdateGroupProfileType -): Promise => { +): Promise => { const { chatId, groupName, groupImage, groupDescription, + rules, account = null, signer = null, env = Constants.ENV.PROD, pgpPrivateKey = null, - scheduleAt, - scheduleEnd, - status, - meta, - rules, } = options || {}; try { /** @@ -73,7 +65,7 @@ export const updateGroupProfile = async ( groupDescription ); - const group = await getGroup({ + const group = await getGroupInfo({ chatId, env, }); @@ -82,15 +74,10 @@ export const updateGroupProfile = async ( * CREATE PROFILE VERIFICATION PROOF */ const bodyToBeHashed = { - chatId: chatId, groupName: groupName, groupDescription: groupDescription, groupImage: groupImage, - meta: meta, - scheduleAt: scheduleAt, - scheduleEnd: scheduleEnd, - rules: rules, - status: status, + rules: rules ?? {}, isPublic: group.isPublic, groupType: group.groupType, }; @@ -103,7 +90,7 @@ export const updateGroupProfile = async ( }); const sigType = 'pgpv2'; // Account is need to verify the signature at any future point - const verificationProof: string = + const profileVerificationProof: string = sigType + ':' + signature + ':' + connectedUser.did; /** @@ -113,12 +100,11 @@ export const updateGroupProfile = async ( const apiEndpoint = `${API_BASE_URL}/v1/chat/groups/${chatId}/profile`; const { - chatId: chat_id, isPublic: is_public, groupType: group_type, ...body } = bodyToBeHashed; - (body as any).verificationProof = verificationProof; + (body as any).profileVerificationProof = profileVerificationProof; return axios .put(apiEndpoint, body) diff --git a/packages/restapi/src/lib/pushapi/chat.ts b/packages/restapi/src/lib/pushapi/chat.ts index 7de852ebe..feaf5773c 100644 --- a/packages/restapi/src/lib/pushapi/chat.ts +++ b/packages/restapi/src/lib/pushapi/chat.ts @@ -27,6 +27,7 @@ import { updateGroupProfile, } from '../chat/updateGroupProfile'; import { User } from './user'; +import { updateGroupConfig } from '../chat/updateGroupConfig'; export class Chat { private userInstance: User; @@ -237,20 +238,30 @@ export class Chat { group = { create: async (name: string, options?: GroupCreationOptions) => { - const groupParams: PUSH_CHAT.ChatCreateGroupType = { - groupName: name, - groupDescription: options?.description, - members: options?.members ? options.members : [], - groupImage: options?.image, - admins: options?.admins ? options.admins : [], - rules: options?.rules, - isPublic: !options?.private, + const groupParams: PUSH_CHAT.ChatCreateGroupTypeV2 = { signer: this.signer, pgpPrivateKey: this.decryptedPgpPvtKey, env: this.env, + + groupName: name, + groupDescription: options?.description ?? null, + groupImage: options?.image ?? null, + rules: options?.rules ?? {}, + isPublic: !options?.private, + groupType: 'default', + + config: { + meta: null, + scheduleAt: null, + scheduleEnd: null, + status: null, + }, + + members: options?.members ? options.members : [], + admins: options?.admins ? options.admins : [], }; - return await PUSH_CHAT.createGroup(groupParams); + return await PUSH_CHAT.createGroupV2(groupParams); }, permissions: async (chatId: string): Promise => { @@ -271,7 +282,7 @@ export class Chat { update: async ( chatId: string, options: GroupUpdateOptions - ): Promise => { + ): Promise => { const group = await PUSH_CHAT.getGroup({ chatId: chatId, env: this.env, @@ -287,18 +298,25 @@ export class Chat { ? options.description : group.groupDescription, groupImage: options.image ? options.image : group.groupImage, + rules: options.rules ? options.rules : group.rules, + account: this.account, + pgpPrivateKey: this.decryptedPgpPvtKey, + env: this.env, + }; + const updateGroupConfigOptions = { + chatId: chatId, meta: options.meta ? options.meta : group.meta, scheduleAt: options.scheduleAt ? options.scheduleAt : group.scheduleAt, scheduleEnd: options.scheduleEnd ? options.scheduleEnd : group.scheduleEnd, - rules: options.rules ? options.rules : group.rules, status: options.status ? options.status : group.status, account: this.account, pgpPrivateKey: this.decryptedPgpPvtKey, env: this.env, }; - return await updateGroupProfile(updateGroupProfileOptions); + await updateGroupProfile(updateGroupProfileOptions); + return await updateGroupConfig(updateGroupConfigOptions); }, add: async (chatId: string, options: ManageGroupOptions) => { diff --git a/packages/restapi/tests/lib/chat/base.test.ts b/packages/restapi/tests/lib/chat/base.test.ts deleted file mode 100644 index efa0ff192..000000000 --- a/packages/restapi/tests/lib/chat/base.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -// import * as path from 'path'; -// import * as dotenv from 'dotenv'; -// dotenv.config({ path: path.resolve(__dirname, '../../.env') }); - -// import { PushAPI } from '../../../src/lib/pushapi/PushAPI'; // Ensure correct import path -// import { expect } from 'chai'; - -// describe.only('PushAPI class functionality', () => { -// let userAlice: PushAPI; - -// beforeEach(() => { -// userAlice = PushAPI.initialize(); -// }); - -// it('Should update user profile', () => { -// userAlice.profile.update(); -// // Add your assertions here -// expect(true).to.be.true; // Replace with actual assertion -// }); - -// it('Should list chats', () => { -// userAlice.chat.list(); -// // Add your assertions here -// expect(true).to.be.true; // Replace with actual assertion -// }); - -// // Similarly, write tests for other functions - -// it('Should fetch latest chat', () => { -// userAlice.chat.latest(); -// // Add your assertions here -// expect(true).to.be.true; // Replace with actual assertion -// }); - -// it('Should fetch chat history', () => { -// userAlice.chat.history(); -// // Add your assertions here -// expect(true).to.be.true; // Replace with actual assertion -// }); - -// //... continue for other methods -// }); diff --git a/packages/restapi/tests/lib/chat/chat.group.test.ts b/packages/restapi/tests/lib/chat/chat.group.test.ts new file mode 100644 index 000000000..1ea1c4c7c --- /dev/null +++ b/packages/restapi/tests/lib/chat/chat.group.test.ts @@ -0,0 +1,93 @@ +import * as chai from 'chai'; +import { expect } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { ethers } from 'ethers'; +import Constants from '../../../src/lib/constants'; +import { + adjectives, + animals, + colors, + uniqueNamesGenerator, +} from 'unique-names-generator'; +import { PushAPI } from '../../../src/lib/pushapi/PushAPI'; // Ensure correct import path + +const _env = Constants.ENV.DEV; +let groupName: string; +let groupDescription: string; +const groupImage = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg=='; +const meta = 'Random Group Meta'; +let userAlice: PushAPI; +let userBob: PushAPI; +let userJohn: PushAPI; + +describe('PushAPI.chat.group', () => { + let account1: string; + let account2: string; + let account3: string; + beforeEach(async () => { + groupName = uniqueNamesGenerator({ + dictionaries: [adjectives, colors, animals], + }); + groupDescription = uniqueNamesGenerator({ + dictionaries: [adjectives, colors, animals], + }); + + const WALLET1 = ethers.Wallet.createRandom(); + const signer1 = new ethers.Wallet(WALLET1.privateKey); + account1 = `eip155:${signer1.address}`; + userAlice = await PushAPI.initialize(signer1, { env: _env }); + + const WALLET2 = ethers.Wallet.createRandom(); + const signer2 = new ethers.Wallet(WALLET2.privateKey); + account2 = `eip155:${signer2.address}`; + userBob = await PushAPI.initialize(signer2, { env: _env }); + + const WALLET3 = ethers.Wallet.createRandom(); + const signer3 = new ethers.Wallet(WALLET3.privateKey); + account3 = `eip155:${signer3.address}`; + userJohn = await PushAPI.initialize(signer3, { env: _env }); + }); + describe('update', () => { + it('update Public Group', async () => { + const group = await userAlice.chat.group.create(groupName, { + description: groupDescription, + image: groupImage, + members: [], + admins: [], + private: false, + }); + const updatedGroup = await userAlice.chat.group.update(group.chatId, { + name: 'Updated Test Grp', + description: 'Updated Test Grp Description', + meta: 'Updated Meta', + }); + expect(updatedGroup.groupImage).to.equal(groupImage); + expect(updatedGroup.groupName).to.equal('Updated Test Grp'); + expect(updatedGroup.groupDescription).to.equal( + 'Updated Test Grp Description' + ); + expect(updatedGroup.meta).to.equal('Updated Meta'); + }); + it('update Public Group', async () => { + const group = await userAlice.chat.group.create(groupName, { + description: groupDescription, + image: groupImage, + members: [], + admins: [], + private: true, + }); + const updatedGroup = await userAlice.chat.group.update(group.chatId, { + name: 'Updated Test Grp', + description: 'Updated Test Grp Description', + meta: 'Updated Meta', + }); + expect(updatedGroup.groupImage).to.equal(groupImage); + expect(updatedGroup.groupName).to.equal('Updated Test Grp'); + expect(updatedGroup.groupDescription).to.equal( + 'Updated Test Grp Description' + ); + expect(updatedGroup.meta).to.equal('Updated Meta'); + }); + }); +}); diff --git a/packages/restapi/tests/lib/chat/group.test.ts b/packages/restapi/tests/lib/chat/group.test.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/restapi/tests/lib/pushapi/chat.group.test.ts b/packages/restapi/tests/lib/pushapi/chat.group.test.ts index 6b733faf0..e92ec30ee 100644 --- a/packages/restapi/tests/lib/pushapi/chat.group.test.ts +++ b/packages/restapi/tests/lib/pushapi/chat.group.test.ts @@ -44,7 +44,7 @@ describe('PushAPI.chat.group functionality', () => { userBob.chat.group.update(createdGroup.chatId, { description: 'Updated Test Grp Description', }) - ).to.be.rejectedWith(`Address eip155:${account2} is not a group admin`); + ).to.be.rejectedWith(`eip155:${account2} is not a group admin`); }); it('Should update Group By Admin', async () => {