From f4f45c47416fceddc5204ec922ebd6d97d850c76 Mon Sep 17 00:00:00 2001 From: cameronvoell Date: Tue, 2 Jul 2024 10:12:04 -0700 Subject: [PATCH] feat: added update permissions functions and updated tests --- .../modules/xmtpreactnativesdk/XMTPModule.kt | 16 ++ .../project.pbxproj | 10 +- .../ios/xmtpreactnativesdkexample/Info.plist | 158 +++++++++--------- example/src/tests/groupPermissionsTests.ts | 95 +++++++++-- example/src/tests/groupTests.ts | 4 +- ios/XMTPModule.swift | 118 ++++++++++++- src/index.ts | 117 +++++++++++-- src/lib/Group.ts | 125 +++++++++++++- 8 files changed, 523 insertions(+), 120 deletions(-) diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt index 4a8ec3b69..3055e5af9 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt @@ -25,6 +25,7 @@ import expo.modules.xmtpreactnativesdk.wrappers.DecryptedLocalAttachment import expo.modules.xmtpreactnativesdk.wrappers.EncryptedLocalAttachment import expo.modules.xmtpreactnativesdk.wrappers.GroupWrapper import expo.modules.xmtpreactnativesdk.wrappers.MemberWrapper +import expo.modules.xmtpreactnativesdk.wrappers.PermissionPolicySetWrapper import expo.modules.xmtpreactnativesdk.wrappers.PreparedLocalMessage import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope @@ -1165,6 +1166,21 @@ class XMTPModule : Module() { } } + AsyncFunction("permissionPolicySet") Coroutine { inboxId: String, id: String -> + withContext(Dispatchers.IO) { + logV("groupImageUrlSquare") + val client = clients[inboxId] ?: throw XMTPException("No client") + val group = findGroup(inboxId, id) + + val permissionPolicySet = group?.permissionPolicySet() + if (permissionPolicySet != null) { + PermissionPolicySetWrapper.encodeToJsonString(permissionPolicySet) + } else { + throw XMTPException("Permission policy set not found for group: $id") + } + } + } + AsyncFunction("processGroupMessage") Coroutine { inboxId: String, id: String, encryptedMessage: String -> withContext(Dispatchers.IO) { logV("processGroupMessage") diff --git a/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj b/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj index 311bc6e1e..b0d31c117 100644 --- a/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj +++ b/example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj @@ -221,7 +221,7 @@ LastUpgradeCheck = 1130; TargetAttributes = { 13B07F861A680F5B00A75B9A = { - DevelopmentTeam = FY4NZR34Z3; + DevelopmentTeam = 65GVVS9K6W; LastSwiftMigration = 1250; }; A6A5DB842A00551E001DF8C2 = { @@ -408,7 +408,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = xmtpreactnativesdkexample/xmtpreactnativesdkexample.entitlements; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = FY4NZR34Z3; + DEVELOPMENT_TEAM = 65GVVS9K6W; ENABLE_BITCODE = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", @@ -424,7 +424,7 @@ "-lc++", ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; - PRODUCT_BUNDLE_IDENTIFIER = expo.modules.xmtpreactnativesdk.example; + PRODUCT_BUNDLE_IDENTIFIER = cvoell.modules.xmtpreactnativesdk.example; PRODUCT_NAME = xmtpreactnativesdkexample; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -441,7 +441,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = xmtpreactnativesdkexample/xmtpreactnativesdkexample.entitlements; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = FY4NZR34Z3; + DEVELOPMENT_TEAM = 65GVVS9K6W; INFOPLIST_FILE = xmtpreactnativesdkexample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -452,7 +452,7 @@ "-lc++", ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; - PRODUCT_BUNDLE_IDENTIFIER = expo.modules.xmtpreactnativesdk.example; + PRODUCT_BUNDLE_IDENTIFIER = cvoell.modules.xmtpreactnativesdk.example; PRODUCT_NAME = xmtpreactnativesdkexample; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/example/ios/xmtpreactnativesdkexample/Info.plist b/example/ios/xmtpreactnativesdkexample/Info.plist index ce646d17c..bd85f227a 100644 --- a/example/ios/xmtpreactnativesdkexample/Info.plist +++ b/example/ios/xmtpreactnativesdkexample/Info.plist @@ -1,82 +1,82 @@ - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - xmtp-react-native-sdk-example - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0.0 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleURLSchemes - - expo.modules.xmtpreactnativesdk.example - - - - CFBundleVersion - 1 - LSRequiresIPhoneOS - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - NSExceptionDomains - - localhost - - NSExceptionAllowsInsecureHTTPLoads - - - - - NSCameraUsageDescription - The app accesses your camera to let you attach photos as messages. - NSMicrophoneUsageDescription - Allow $(PRODUCT_NAME) to access your microphone - NSPhotoLibraryUsageDescription - The app accesses your photos to let you attach them as messages. - UILaunchStoryboardName - SplashScreen - UIRequiredDeviceCapabilities - - armv7 - - UIRequiresFullScreen - - UIStatusBarStyle - UIStatusBarStyleDefault - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIUserInterfaceStyle - Light - UIViewControllerBasedStatusBarAppearance - - - \ No newline at end of file + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + xmtp-react-native-sdk-example + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleURLSchemes + + expo.modules.xmtpreactnativesdk.example + + + + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + NSCameraUsageDescription + The app accesses your camera to let you attach photos as messages. + NSMicrophoneUsageDescription + Allow $(PRODUCT_NAME) to access your microphone + NSPhotoLibraryUsageDescription + The app accesses your photos to let you attach them as messages. + UILaunchStoryboardName + SplashScreen + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresFullScreen + + UIStatusBarStyle + UIStatusBarStyleDefault + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIUserInterfaceStyle + Light + UIViewControllerBasedStatusBarAppearance + + + diff --git a/example/src/tests/groupPermissionsTests.ts b/example/src/tests/groupPermissionsTests.ts index 38abed82b..bd6ff470b 100644 --- a/example/src/tests/groupPermissionsTests.ts +++ b/example/src/tests/groupPermissionsTests.ts @@ -21,12 +21,8 @@ test('new group has expected admin list and super admin list', async () => { const superAdminList = await alixGroup.listSuperAdmins() assert( - adminList.length === 1, - `adminList.length should be 1 but was ${adminList.length}` - ) - assert( - adminList[0] === alix.inboxId, - `adminList[0] should be ${alix.address} but was ${adminList[0]}` + adminList.length === 0, + `adminList.length should be 0 but was ${adminList.length}` ) assert( superAdminList.length === 1, @@ -88,9 +84,9 @@ test('in admin only group, members can not update group name unless they are an { permissionLevel: 'admin_only' } ) - if (alixGroup.permissionLevel !== 'admin_only') { + if ((await alixGroup.permissionPolicySet()).addMemberPolicy !== 'admin') { throw Error( - `Group permission level should be admin_only but was ${alixGroup.permissionLevel}` + `Group add member policy should be admin but was ${(await alixGroup.permissionPolicySet()).addMemberPolicy}` ) } @@ -123,9 +119,11 @@ test('in admin only group, members can update group name once they are an admin' { permissionLevel: 'admin_only' } ) - if (alixGroup.permissionLevel !== 'admin_only') { + if ( + (await alixGroup.permissionPolicySet()).updateGroupNamePolicy !== 'admin' + ) { throw Error( - `Group permission level should be admin_only but was ${alixGroup.permissionLevel}` + `Group update name policy should be admin but was ${(await alixGroup.permissionPolicySet()).updateGroupNamePolicy}` ) } @@ -174,9 +172,11 @@ test('in admin only group, members can not update group name after admin status { permissionLevel: 'admin_only' } ) - if (alixGroup.permissionLevel !== 'admin_only') { + if ( + (await alixGroup.permissionPolicySet()).updateGroupNamePolicy !== 'admin' + ) { throw Error( - `Group permission level should be admin_only but was ${alixGroup.permissionLevel}` + `Group update name policy should be admin but was ${(await alixGroup.permissionPolicySet()).updateGroupNamePolicy}` ) } @@ -392,3 +392,74 @@ test('group with All Members policy has remove function that is admin only', asy return true }) + +test('can update group permissions', async () => { + // Create clients + const [alix, bo, caro] = await createClients(3) + + // Bo creates a group with Alix and Caro + const boGroup = await bo.conversations.newGroup( + [alix.address, caro.address], + { permissionLevel: 'admin_only' } + ) + + // Verify that bo is a super admin + assert( + (await boGroup.isSuperAdmin(bo.inboxId)) === true, + `bo should be a super admin` + ) + + // Verify that group has the expected group description permission + assert( + (await boGroup.permissionPolicySet()).updateGroupDescriptionPolicy === + 'admin', + `boGroup.permissionPolicySet.updateGroupDescriptionPolicy should be admin but was ${(await boGroup.permissionPolicySet()).updateGroupDescriptionPolicy}` + ) + + // Verify that Bo can update the group description + await boGroup.updateGroupDescription('new description') + await boGroup.sync() + assert( + (await boGroup.groupDescription()) === 'new description', + `boGroup.groupDescription should be "new description" but was ${boGroup.groupDescription}` + ) + + // Verify that alix can not update the group description + await alix.conversations.syncGroups() + const alixGroup = (await alix.conversations.listGroups())[0] + try { + await alixGroup.updateGroupDescription('new description') + assert(false, 'Alix should not be able to update the group description') + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (error) { + // expected + } + + // Verify that alix can not update permissions + try { + await alixGroup.updateGroupDescriptionPermission('allow') + assert(false, 'Alix should not be able to update the group name permission') + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (error) { + // expected + } + + // Verify that bo can update permissions + await boGroup.updateGroupDescriptionPermission('allow') + await boGroup.sync() + assert( + (await boGroup.permissionPolicySet()).updateGroupDescriptionPolicy === + 'allow', + `boGroup.permissionPolicySet.updateGroupDescriptionPolicy should be allow but was ${(await boGroup.permissionPolicySet()).updateGroupDescriptionPolicy}` + ) + + // Verify that alix can now update the group description + await alixGroup.updateGroupDescription('new description 2') + await alixGroup.sync() + assert( + (await alixGroup.groupDescription()) === 'new description 2', + `alixGroup.groupDescription should be "new description 2" but was ${alixGroup.groupDescription}` + ) + + return true +}) diff --git a/example/src/tests/groupTests.ts b/example/src/tests/groupTests.ts index 5aa2a2ad1..4a6dfbfa0 100644 --- a/example/src/tests/groupTests.ts +++ b/example/src/tests/groupTests.ts @@ -1137,9 +1137,9 @@ test('can make a group with admin permissions', async () => { { permissionLevel: 'admin_only' } ) - if (group.permissionPolicySet.addMemberPolicy !== 'admin') { + if ((await group.permissionPolicySet()).addMemberPolicy !== 'admin') { throw Error( - `Group permission level should be admin but was ${group.permissionPolicySet.addMemberPolicy}` + `Group permission level should be admin but was ${(await group.permissionPolicySet()).addMemberPolicy}` ) } diff --git a/ios/XMTPModule.swift b/ios/XMTPModule.swift index 28ee6b12d..18c367819 100644 --- a/ios/XMTPModule.swift +++ b/ios/XMTPModule.swift @@ -59,7 +59,7 @@ public class XMTPModule: Module { } enum Error: Swift.Error { - case noClient, conversationNotFound(String), noMessage, invalidKeyBundle, invalidDigest, badPreparation(String), mlsNotEnabled(String), invalidString + case noClient, conversationNotFound(String), noMessage, invalidKeyBundle, invalidDigest, badPreparation(String), mlsNotEnabled(String), invalidString, invalidPermissionOption } public func definition() -> ModuleDefinition { @@ -987,13 +987,100 @@ public class XMTPModule: Module { } try await group.removeSuperAdmin(inboxId: inboxId) } - - AsyncFunction("processGroupMessage") { (inboxId: String, id: String, encryptedMessage: String) -> String in - guard let client = await clientsManager.getClient(key: inboxId) else { - throw Error.noClient - } - - guard let group = try await findGroup(inboxId: inboxId, id: id) else { + + AsyncFunction("updateAddMemberPermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateAddMemberPermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } + + AsyncFunction("updateRemoveMemberPermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateRemoveMemberPermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } + + AsyncFunction("updateAddAdminPermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateAddAdminPermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } + + AsyncFunction("updateRemoveAdminPermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateRemoveAdminPermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } + + AsyncFunction("updateGroupNamePermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateGroupNamePermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } + + AsyncFunction("updateGroupImageUrlSquarePermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateGroupImageUrlSquarePermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } + + AsyncFunction("updateGroupDescriptionPermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateGroupDescriptionPermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } + + AsyncFunction("permissionPolicySet") { (inboxId: String, id: String) async throws -> String in + + guard let client = await clientsManager.getClient(key: inboxId) else { + throw Error.noClient + } + + guard let group = try await findGroup(inboxId: inboxId, id: id) else { + throw Error.conversationNotFound("Permission policy set not found for group: \(id)") + } + + let permissionPolicySet = try group.permissionPolicySet() + + return try PermissionPolicySetWrapper.encodeToJsonString(permissionPolicySet) + } + + + + AsyncFunction("processGroupMessage") { (inboxId: String, id: String, encryptedMessage: String) -> String in + guard let client = await clientsManager.getClient(key: inboxId) else { + throw Error.noClient + } + + guard let group = try await findGroup(inboxId: inboxId, id: id) else { throw Error.conversationNotFound("no group found for \(id)") } @@ -1275,6 +1362,21 @@ public class XMTPModule: Module { // // Helpers // + + private func getPermissionOption(permission: String) async throws -> PermissionOption { + switch permission { + case "allow": + return .allow + case "deny": + return .deny + case "admin": + return .admin + case "super_admin": + return .superAdmin + default: + throw Error.invalidPermissionOption + } + } func createClientConfig(env: String, appVersion: String?, preEnableIdentityCallback: PreEventCallback? = nil, preCreateIdentityCallback: PreEventCallback? = nil, enableV3: Bool = false, dbEncryptionKey: Data? = nil, dbDirectory: String? = nil, historySyncUrl: String? = nil) -> XMTP.ClientOptions { // Ensure that all codecs have been registered. diff --git a/src/index.ts b/src/index.ts index 2c1052d22..97f21dd15 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,11 +18,12 @@ import { ConversationVersion, } from './lib/ConversationContainer' import { DecodedMessage, MessageDeliveryStatus } from './lib/DecodedMessage' -import { Group } from './lib/Group' +import { Group, PermissionUpdateOption } from './lib/Group' import { Member } from './lib/Member' import type { Query } from './lib/Query' import { ConversationSendPayload } from './lib/types' import { DefaultContentTypes } from './lib/types/DefaultContentType' +import { PermissionPolicySet } from './lib/types/PermissionPolicySet' import { getAddress } from './utils/address' export * from './context' @@ -170,17 +171,19 @@ export async function createGroup< imageUrlSquare: string = '', description: string = '' ): Promise> { - const groupString = await XMTPModule.createGroup( - client.inboxId, - peerAddresses, - permissionLevel, - name, - imageUrlSquare, - description + return new Group( + client, + JSON.parse( + await XMTPModule.createGroup( + client.inboxId, + peerAddresses, + permissionLevel, + name, + imageUrlSquare, + description + ) + ) ) - const groupObj = JSON.parse(groupString) - groupObj.permissionPolicySet = JSON.parse(groupObj.permissionPolicySet) - return new Group(client, groupObj) } export async function listGroups< @@ -877,6 +880,98 @@ export async function removeSuperAdmin( return XMTPModule.removeSuperAdmin(clientInboxId, id, inboxId) } +export async function updateAddMemberPermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateAddMemberPermission( + clientInboxId, + id, + permissionOption + ) +} + +export async function updateRemoveMemberPermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateRemoveMemberPermission( + clientInboxId, + id, + permissionOption + ) +} + +export async function updateAddAdminPermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateAddAdminPermission( + clientInboxId, + id, + permissionOption + ) +} + +export async function updateRemoveAdminPermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateRemoveAdminPermission( + clientInboxId, + id, + permissionOption + ) +} + +export async function updateGroupNamePermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateGroupNamePermission( + clientInboxId, + id, + permissionOption + ) +} + +export async function updateGroupImageUrlSquarePermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateGroupImageUrlSquarePermission( + clientInboxId, + id, + permissionOption + ) +} + +export async function updateGroupDescriptionPermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateGroupDescriptionPermission( + clientInboxId, + id, + permissionOption + ) +} + +export async function permissionPolicySet( + clientInboxId: string, + id: string +): Promise { + const json = await XMTPModule.permissionPolicySet(clientInboxId, id) + return JSON.parse(json) +} + export async function allowGroups( inboxId: string, groupIds: string[] diff --git a/src/lib/Group.ts b/src/lib/Group.ts index c915e728a..8174e258a 100644 --- a/src/lib/Group.ts +++ b/src/lib/Group.ts @@ -13,6 +13,8 @@ import { PermissionPolicySet } from './types/PermissionPolicySet' import { SendOptions } from './types/SendOptions' import * as XMTP from '../index' +export type PermissionUpdateOption = 'allow' | 'deny' | 'admin' | 'super_admin' + export class Group< ContentTypes extends DefaultContentTypes = DefaultContentTypes, > implements ConversationContainer @@ -24,7 +26,6 @@ export class Group< version = ConversationVersion.GROUP topic: string creatorInboxId: InboxId - permissionPolicySet: PermissionPolicySet name: string isGroupActive: boolean imageUrlSquare: string @@ -36,7 +37,6 @@ export class Group< createdAt: number peerInboxIds: InboxId[] creatorInboxId: InboxId - permissionPolicySet: PermissionPolicySet topic: string name: string isGroupActive: boolean @@ -49,7 +49,6 @@ export class Group< this.peerInboxIds = params.peerInboxIds this.topic = params.topic this.creatorInboxId = params.creatorInboxId - this.permissionPolicySet = params.permissionPolicySet this.name = params.name this.isGroupActive = params.isGroupActive this.imageUrlSquare = params.imageUrlSquare @@ -384,6 +383,126 @@ export class Group< return XMTP.removeSuperAdmin(this.client.inboxId, this.id, inboxId) } + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the addMember permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateAddMemberPermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateAddMemberPermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the removeMember permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateRemoveMemberPermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateRemoveMemberPermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the addAdmin permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateAddAdminPermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateAddAdminPermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the removeAdmin permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateRemoveAdminPermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateRemoveAdminPermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the groupName permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateGroupNamePermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateGroupNamePermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the groupImageUrlSquare permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateGroupImageUrlSquarePermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateGroupImageUrlSquarePermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the groupDescription permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateGroupDescriptionPermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateGroupDescriptionPermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + + /** + * + * @returns {Promise} A {PermissionPolicySet} object representing the group's permission policy set. + */ + async permissionPolicySet(): Promise { + return XMTP.permissionPolicySet(this.client.inboxId, this.id) + } + async processMessage( encryptedMessage: string ): Promise> {