From 8120a393f7f3c172721163446f010869d695d39a Mon Sep 17 00:00:00 2001 From: Ry Racherbaumer Date: Mon, 16 Dec 2024 12:07:50 -0600 Subject: [PATCH] Add support for custom permissions policy (Node + Browser SDK) (#752) * Add support for custom permissions policy (browser) * Add support for custom permissions policy (node) * Create long-ducks-smoke.md * Fix lint --- .changeset/long-ducks-smoke.md | 6 +++ sdks/browser-sdk/package.json | 2 +- sdks/browser-sdk/src/utils/conversions.ts | 60 ++++++++++++++++++--- sdks/browser-sdk/src/workers/client.ts | 5 ++ sdks/browser-sdk/test/Conversations.test.ts | 37 +++++++++++++ sdks/node-sdk/package.json | 2 +- sdks/node-sdk/test/Conversations.test.ts | 37 +++++++++++++ yarn.lock | 20 +++---- 8 files changed, 150 insertions(+), 19 deletions(-) create mode 100644 .changeset/long-ducks-smoke.md diff --git a/.changeset/long-ducks-smoke.md b/.changeset/long-ducks-smoke.md new file mode 100644 index 000000000..5ea587914 --- /dev/null +++ b/.changeset/long-ducks-smoke.md @@ -0,0 +1,6 @@ +--- +"@xmtp/browser-sdk": patch +"@xmtp/node-sdk": patch +--- + +Add support for custom permissions policy diff --git a/sdks/browser-sdk/package.json b/sdks/browser-sdk/package.json index ecf76edd5..9e923dc76 100644 --- a/sdks/browser-sdk/package.json +++ b/sdks/browser-sdk/package.json @@ -64,7 +64,7 @@ "@xmtp/content-type-primitives": "^2.0.0", "@xmtp/content-type-text": "^2.0.0", "@xmtp/proto": "^3.72.3", - "@xmtp/wasm-bindings": "^0.0.7", + "@xmtp/wasm-bindings": "^0.0.8", "uuid": "^11.0.3" }, "devDependencies": { diff --git a/sdks/browser-sdk/src/utils/conversions.ts b/sdks/browser-sdk/src/utils/conversions.ts index 1e9f32045..e0399777e 100644 --- a/sdks/browser-sdk/src/utils/conversions.ts +++ b/sdks/browser-sdk/src/utils/conversions.ts @@ -6,8 +6,10 @@ import { Consent, CreateGroupOptions, GroupMember, + GroupPermissionsOptions, ListConversationsOptions, ListMessagesOptions, + PermissionPolicySet, ContentTypeId as WasmContentTypeId, EncodedContent as WasmEncodedContent, type ConsentEntityType, @@ -16,7 +18,6 @@ import { type DeliveryStatus, type GroupMembershipState, type GroupMessageKind, - type GroupPermissionsOptions, type InboxState, type Installation, type Message, @@ -200,22 +201,62 @@ export const fromSafeListConversationsOptions = ( options.limit, ); +export type SafePermissionPolicySet = { + addAdminPolicy: PermissionPolicy; + addMemberPolicy: PermissionPolicy; + removeAdminPolicy: PermissionPolicy; + removeMemberPolicy: PermissionPolicy; + updateGroupDescriptionPolicy: PermissionPolicy; + updateGroupImageUrlSquarePolicy: PermissionPolicy; + updateGroupNamePolicy: PermissionPolicy; + updateGroupPinnedFrameUrlPolicy: PermissionPolicy; +}; + +export const toSafePermissionPolicySet = ( + policySet: PermissionPolicySet, +): SafePermissionPolicySet => ({ + addAdminPolicy: policySet.addAdminPolicy, + addMemberPolicy: policySet.addMemberPolicy, + removeAdminPolicy: policySet.removeAdminPolicy, + removeMemberPolicy: policySet.removeMemberPolicy, + updateGroupDescriptionPolicy: policySet.updateGroupDescriptionPolicy, + updateGroupImageUrlSquarePolicy: policySet.updateGroupImageUrlSquarePolicy, + updateGroupNamePolicy: policySet.updateGroupNamePolicy, + updateGroupPinnedFrameUrlPolicy: policySet.updateGroupPinnedFrameUrlPolicy, +}); + +export const fromSafePermissionPolicySet = ( + policySet: SafePermissionPolicySet, +): PermissionPolicySet => + new PermissionPolicySet( + policySet.addMemberPolicy, + policySet.removeMemberPolicy, + policySet.addAdminPolicy, + policySet.removeAdminPolicy, + policySet.updateGroupNamePolicy, + policySet.updateGroupDescriptionPolicy, + policySet.updateGroupImageUrlSquarePolicy, + policySet.updateGroupPinnedFrameUrlPolicy, + ); + export type SafeCreateGroupOptions = { - permissions?: GroupPermissionsOptions; - name?: string; - imageUrlSquare?: string; + customPermissionPolicySet?: SafePermissionPolicySet; description?: string; + imageUrlSquare?: string; + name?: string; + permissions?: GroupPermissionsOptions; pinnedFrameUrl?: string; }; export const toSafeCreateGroupOptions = ( options: CreateGroupOptions, ): SafeCreateGroupOptions => ({ - permissions: options.permissions, - name: options.groupName, - imageUrlSquare: options.groupImageUrlSquare, description: options.groupDescription, + imageUrlSquare: options.groupImageUrlSquare, + name: options.groupName, pinnedFrameUrl: options.groupPinnedFrameUrl, + permissions: options.permissions, + customPermissionPolicySet: options.customPermissionPolicySet, }); export const fromSafeCreateGroupOptions = ( @@ -227,6 +268,11 @@ export const fromSafeCreateGroupOptions = ( options.imageUrlSquare, options.description, options.pinnedFrameUrl, + // only include custom policy set if permissions are set to CustomPolicy + options.customPermissionPolicySet && + options.permissions === GroupPermissionsOptions.CustomPolicy + ? fromSafePermissionPolicySet(options.customPermissionPolicySet) + : undefined, ); export type SafeConversation = { diff --git a/sdks/browser-sdk/src/workers/client.ts b/sdks/browser-sdk/src/workers/client.ts index 61780b5ee..953f7b9d8 100644 --- a/sdks/browser-sdk/src/workers/client.ts +++ b/sdks/browser-sdk/src/workers/client.ts @@ -290,6 +290,11 @@ self.onmessage = async (event: MessageEvent) => { break; } case "newGroup": { + // console.log( + // "newGroup", + // fromSafeCreateGroupOptions(data.options!), + // data.options, + // ); const conversation = await client.conversations.newGroup( data.accountAddresses, data.options, diff --git a/sdks/browser-sdk/test/Conversations.test.ts b/sdks/browser-sdk/test/Conversations.test.ts index fcc15f322..224ffc13d 100644 --- a/sdks/browser-sdk/test/Conversations.test.ts +++ b/sdks/browser-sdk/test/Conversations.test.ts @@ -255,4 +255,41 @@ describe.concurrent("Conversations", () => { expect(groupWithPinnedFrameUrl.description).toBe(""); expect(groupWithPinnedFrameUrl.pinnedFrameUrl).toBe("https://foo/bar"); }); + + it("should create a group with custom permissions", async () => { + const user1 = createUser(); + const user2 = createUser(); + const client1 = await createRegisteredClient(user1); + await createRegisteredClient(user2); + const group = await client1.conversations.newGroup( + [user2.account.address], + { + permissions: GroupPermissionsOptions.CustomPolicy, + customPermissionPolicySet: { + addAdminPolicy: 1, + addMemberPolicy: 0, + removeAdminPolicy: 1, + removeMemberPolicy: 1, + updateGroupNamePolicy: 1, + updateGroupDescriptionPolicy: 1, + updateGroupImageUrlSquarePolicy: 1, + updateGroupPinnedFrameUrlPolicy: 1, + }, + }, + ); + expect(group).toBeDefined(); + expect(group.permissions?.policyType).toBe( + GroupPermissionsOptions.CustomPolicy, + ); + expect(group.permissions?.policySet).toEqual({ + addAdminPolicy: 1, + addMemberPolicy: 0, + removeAdminPolicy: 1, + removeMemberPolicy: 1, + updateGroupNamePolicy: 1, + updateGroupDescriptionPolicy: 1, + updateGroupImageUrlSquarePolicy: 1, + updateGroupPinnedFrameUrlPolicy: 1, + }); + }); }); diff --git a/sdks/node-sdk/package.json b/sdks/node-sdk/package.json index b83400d0f..9c0907d17 100644 --- a/sdks/node-sdk/package.json +++ b/sdks/node-sdk/package.json @@ -51,7 +51,7 @@ "@xmtp/content-type-group-updated": "^2.0.0", "@xmtp/content-type-primitives": "^2.0.0", "@xmtp/content-type-text": "^2.0.0", - "@xmtp/node-bindings": "^0.0.28", + "@xmtp/node-bindings": "^0.0.29", "@xmtp/proto": "^3.72.3" }, "devDependencies": { diff --git a/sdks/node-sdk/test/Conversations.test.ts b/sdks/node-sdk/test/Conversations.test.ts index 9c2e1a0d5..f28ddd7db 100644 --- a/sdks/node-sdk/test/Conversations.test.ts +++ b/sdks/node-sdk/test/Conversations.test.ts @@ -254,6 +254,43 @@ describe("Conversations", () => { expect(groupWithPinnedFrameUrl.pinnedFrameUrl).toBe("https://foo/bar"); }); + it("should create a group with custom permissions", async () => { + const user1 = createUser(); + const user2 = createUser(); + const client1 = await createRegisteredClient(user1); + await createRegisteredClient(user2); + const group = await client1.conversations.newGroup( + [user2.account.address], + { + permissions: GroupPermissionsOptions.CustomPolicy, + customPermissionPolicySet: { + addAdminPolicy: 1, + addMemberPolicy: 0, + removeAdminPolicy: 1, + removeMemberPolicy: 1, + updateGroupNamePolicy: 1, + updateGroupDescriptionPolicy: 1, + updateGroupImageUrlSquarePolicy: 1, + updateGroupPinnedFrameUrlPolicy: 1, + }, + }, + ); + expect(group).toBeDefined(); + expect(group.permissions.policyType).toBe( + GroupPermissionsOptions.CustomPolicy, + ); + expect(group.permissions.policySet).toEqual({ + addAdminPolicy: 1, + addMemberPolicy: 0, + removeAdminPolicy: 1, + removeMemberPolicy: 1, + updateGroupNamePolicy: 1, + updateGroupDescriptionPolicy: 1, + updateGroupImageUrlSquarePolicy: 1, + updateGroupPinnedFrameUrlPolicy: 1, + }); + }); + it("should stream new conversations", async () => { const user1 = createUser(); const user2 = createUser(); diff --git a/yarn.lock b/yarn.lock index 37f3dd5c2..a0dbed143 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4809,7 +4809,7 @@ __metadata: "@xmtp/content-type-primitives": "npm:^2.0.0" "@xmtp/content-type-text": "npm:^2.0.0" "@xmtp/proto": "npm:^3.72.3" - "@xmtp/wasm-bindings": "npm:^0.0.7" + "@xmtp/wasm-bindings": "npm:^0.0.8" playwright: "npm:^1.49.0" rollup: "npm:^4.27.3" rollup-plugin-dts: "npm:^6.1.1" @@ -5107,10 +5107,10 @@ __metadata: languageName: unknown linkType: soft -"@xmtp/node-bindings@npm:^0.0.28": - version: 0.0.28 - resolution: "@xmtp/node-bindings@npm:0.0.28" - checksum: 10/0ceea72582926dcce03c8e3839b7101d7ce4aef56a55b46421c2e46e96f65c90a224b1649ff765c1f3cb1e2e21a730d1891bb369260c94712066b85d358fb6f4 +"@xmtp/node-bindings@npm:^0.0.29": + version: 0.0.29 + resolution: "@xmtp/node-bindings@npm:0.0.29" + checksum: 10/d6abb86a58517bffff07bda59b387318a9d60b2ba0ca13376ef60fe79aa9afefb8e2b07b218064738b07c4e699eac967f8aff64942017f8872f4fe982ac475ae languageName: node linkType: hard @@ -5125,7 +5125,7 @@ __metadata: "@xmtp/content-type-group-updated": "npm:^2.0.0" "@xmtp/content-type-primitives": "npm:^2.0.0" "@xmtp/content-type-text": "npm:^2.0.0" - "@xmtp/node-bindings": "npm:^0.0.28" + "@xmtp/node-bindings": "npm:^0.0.29" "@xmtp/proto": "npm:^3.72.3" "@xmtp/xmtp-js": "workspace:^" fast-glob: "npm:^3.3.2" @@ -5236,10 +5236,10 @@ __metadata: languageName: node linkType: hard -"@xmtp/wasm-bindings@npm:^0.0.7": - version: 0.0.7 - resolution: "@xmtp/wasm-bindings@npm:0.0.7" - checksum: 10/4063d9cee51e4fd181d4d9f5840b861d8b99d6eb3d1bb6c3c09049105e126b958053c16ca29d729b62339d3d343b68e8955314d5a2c366b4d6e67d074228a94e +"@xmtp/wasm-bindings@npm:^0.0.8": + version: 0.0.8 + resolution: "@xmtp/wasm-bindings@npm:0.0.8" + checksum: 10/6020c15b56d3ac02fc76d86bb176c2504f1976aec7af2ae7f3aea7e159f2692db08c0d5501462f8ea4fb34530cacbd2568a3870d0a7b8189db33e7e7a49a9711 languageName: node linkType: hard