@wireapp/core 29.3.0 → 30.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,49 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [30.0.0](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@29.3.0...@wireapp/core@30.0.0) (2022-08-25)
7
+
8
+
9
+ ### Features
10
+
11
+ * remove user from MLS conversation (#FS-561) ([#4366](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/issues/4366)) ([89da444](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/commit/89da4449fa3caa0cbe41fbd595326f157e7e4011)), closes [#FS-561](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/issues/FS-561) [#4367](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/issues/4367)
12
+
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ * renamed removeUser function to removeUserFromProteusConversation in @wireapp/core and
17
+ changed the types of conversation and user ids in @wireapp/bot-api MessageHandler from string to QualifiedId.
18
+
19
+ * chore: initial work on remove user from mls convo
20
+
21
+ * fix: use FQCI ids for client ids
22
+
23
+ * fix: use FQCI ids for client ids
24
+
25
+ * runfix: encode client id straight to byte array
26
+
27
+ * runfix: encode client id straight to byte array
28
+
29
+ * feat: send client-removal commit messages
30
+
31
+ * runfix: remove event from remove user from proteus convo func
32
+
33
+ * refactor: rename proteus remove func
34
+
35
+ * test: add test for fully qualified ids mapping function
36
+
37
+ * refactor: more precise name for remove from proteus convo
38
+
39
+ * refactor: apply CR suggestions
40
+
41
+ * runfix: don't convert messages twice to uint8arr
42
+
43
+ * runfix: wrapp commits into uint8arr
44
+
45
+
46
+
47
+
48
+
6
49
  # [29.3.0](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@29.2.4...@wireapp/core@29.3.0) (2022-08-25)
7
50
 
8
51
 
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "@otak/core-crypto": "0.3.0-es2017",
8
8
  "@types/long": "4.0.1",
9
9
  "@types/node": "~14",
10
- "@wireapp/api-client": "19.21.6",
10
+ "@wireapp/api-client": "20.0.0",
11
11
  "@wireapp/commons": "4.3.0",
12
12
  "@wireapp/cryptobox": "12.8.0",
13
13
  "@wireapp/store-engine-dexie": "1.6.10",
@@ -77,6 +77,6 @@
77
77
  "test:node": "nyc jasmine --config=jasmine.json",
78
78
  "watch": "tsc ---watch"
79
79
  },
80
- "version": "29.3.0",
81
- "gitHead": "e9707c97b3cfa69fa1e51c21d0d0ca6923f57d4d"
80
+ "version": "30.0.0",
81
+ "gitHead": "080d1139d0b9e8c3053d42dd42492a1a9b523191"
82
82
  }
@@ -3,7 +3,7 @@ import type { APIClient } from '@wireapp/api-client';
3
3
  import { MessageSendingStatus, Conversation, DefaultConversationRoleName, MutedStatus, NewConversation, QualifiedUserClients, UserClients, ClientMismatch } from '@wireapp/api-client/src/conversation';
4
4
  import type { ConversationMemberLeaveEvent } from '@wireapp/api-client/src/event';
5
5
  import type { QualifiedId, UserPreKeyBundleMap } from '@wireapp/api-client/src/user';
6
- import { MessageTimer } from '../../conversation/';
6
+ import { MessageTimer, RemoveUsersParams } from '../../conversation/';
7
7
  import type { RemoteData } from '../content';
8
8
  import type { CryptographyService } from '../../cryptography/';
9
9
  import type { ClearConversationMessage, DeleteMessage, HideMessage, OtrMessage } from '../message/OtrMessage';
@@ -102,7 +102,11 @@ export declare class ConversationService {
102
102
  getAllParticipantsClients(conversationId: string, conversationDomain?: string): Promise<UserClients | QualifiedUserClients>;
103
103
  deleteMessageLocal(conversationId: string, messageIdToHide: string, sendAsProtobuf?: boolean, conversationDomain?: string): Promise<HideMessage>;
104
104
  deleteMessageEveryone(conversationId: string, messageIdToDelete: string, userIds?: string[] | QualifiedId[] | UserClients | QualifiedUserClients, sendAsProtobuf?: boolean, conversationDomain?: string, callbacks?: MessageSendingCallbacks): Promise<DeleteMessage>;
105
- leaveConversation(conversationId: string): Promise<ConversationMemberLeaveEvent>;
105
+ leaveConversation(conversationId: QualifiedId): Promise<ConversationMemberLeaveEvent>;
106
+ leaveMLSConversation(conversationId: QualifiedId): Promise<ConversationMemberLeaveEvent>;
107
+ /**
108
+ * @depricated seems not to be used and is outdated. use leaveConversation instead
109
+ */
106
110
  leaveConversations(conversationIds?: string[]): Promise<ConversationMemberLeaveEvent[]>;
107
111
  /**
108
112
  * Create a group conversation.
@@ -127,7 +131,7 @@ export declare class ConversationService {
127
131
  getAsset({ assetId, assetToken, otrKey, sha256 }: RemoteData): Promise<Uint8Array>;
128
132
  getUnencryptedAsset(assetId: string, assetToken?: string): Promise<ArrayBuffer>;
129
133
  addUsersToProteusConversation({ conversationId, qualifiedUserIds }: Omit<AddUsersParams, 'groupId'>): Promise<import("@wireapp/api-client/src/event").ConversationMemberJoinEvent>;
130
- removeUser(conversationId: string, userId: string): Promise<string>;
134
+ removeUserFromProteusConversation(conversationId: QualifiedId, userId: QualifiedId): Promise<ConversationMemberLeaveEvent>;
131
135
  private sendProteusMessage;
132
136
  /**
133
137
  * Sends a message to a conversation
@@ -151,4 +155,6 @@ export declare class ConversationService {
151
155
  createMLSConversation(conversationData: NewConversation): Promise<MLSReturnType>;
152
156
  private sendMLSMessage;
153
157
  addUsersToMLSConversation({ qualifiedUserIds, groupId, conversationId, }: Required<AddUsersParams>): Promise<MLSReturnType>;
158
+ private sendCommitBundleRemovalMessages;
159
+ removeUsersFromMLSConversation({ groupId, conversationId, qualifiedUserIds, }: RemoveUsersParams): Promise<MLSReturnType>;
154
160
  }
@@ -30,6 +30,12 @@ const MessageService_1 = require("../message/MessageService");
30
30
  const MessageToProtoMapper_1 = require("../message/MessageToProtoMapper");
31
31
  const ConversationService_types_1 = require("./ConversationService.types");
32
32
  const bazinga64_1 = require("bazinga64");
33
+ const mapQualifiedUserClientIdsToFullyQualifiedClientIds_1 = require("../../util/mapQualifiedUserClientIdsToFullyQualifiedClientIds");
34
+ //@todo: this function is temporary, we wait for the update from core-crypto side
35
+ //they are returning regular array instead of Uint8Array for commit and welcome messages
36
+ const optionalToUint8Array = (array) => {
37
+ return Array.isArray(array) ? Uint8Array.from(array) : array;
38
+ };
33
39
  class ConversationService {
34
40
  constructor(apiClient, cryptographyService, config, coreCryptoClientProvider, notificationService) {
35
41
  this.apiClient = apiClient;
@@ -598,8 +604,20 @@ class ConversationService {
598
604
  };
599
605
  }
600
606
  leaveConversation(conversationId) {
601
- return this.apiClient.api.conversation.deleteMember(conversationId, this.apiClient.context.userId);
607
+ if (!this.apiClient.context || !this.apiClient.context.userId || !this.apiClient.context.domain) {
608
+ throw new Error('Cannot leave conversation without a userId and domain');
609
+ }
610
+ return this.apiClient.api.conversation.deleteMember(conversationId, {
611
+ domain: this.apiClient.context.domain,
612
+ id: this.apiClient.context.userId,
613
+ });
614
+ }
615
+ leaveMLSConversation(conversationId) {
616
+ return this.leaveConversation(conversationId);
602
617
  }
618
+ /**
619
+ * @depricated seems not to be used and is outdated. use leaveConversation instead
620
+ */
603
621
  async leaveConversations(conversationIds) {
604
622
  if (!conversationIds) {
605
623
  const conversation = await this.getConversations();
@@ -607,7 +625,7 @@ class ConversationService {
607
625
  .filter(conversation => conversation.type === conversation_1.CONVERSATION_TYPE.REGULAR)
608
626
  .map(conversation => conversation.id);
609
627
  }
610
- return Promise.all(conversationIds.map(conversationId => this.leaveConversation(conversationId)));
628
+ return Promise.all(conversationIds.map(conversationId => { var _a, _b; return this.leaveConversation({ id: conversationId, domain: (_b = (_a = this.apiClient.context) === null || _a === void 0 ? void 0 : _a.domain) !== null && _b !== void 0 ? _b : '' }); }));
611
629
  }
612
630
  createProteusConversation(conversationData, otherUserIds) {
613
631
  let payload;
@@ -647,12 +665,10 @@ class ConversationService {
647
665
  return (await request.response).buffer;
648
666
  }
649
667
  async addUsersToProteusConversation({ conversationId, qualifiedUserIds }) {
650
- const response = await this.apiClient.api.conversation.postMembers(conversationId, qualifiedUserIds);
651
- return response;
668
+ return this.apiClient.api.conversation.postMembers(conversationId, qualifiedUserIds);
652
669
  }
653
- async removeUser(conversationId, userId) {
654
- await this.apiClient.api.conversation.deleteMember(conversationId, userId);
655
- return userId;
670
+ async removeUserFromProteusConversation(conversationId, userId) {
671
+ return this.apiClient.api.conversation.deleteMember(conversationId, userId);
656
672
  }
657
673
  async sendProteusMessage(params, genericMessage, content) {
658
674
  var _a;
@@ -822,10 +838,13 @@ class ConversationService {
822
838
  const coreCryptoClient = this.coreCryptoClientProvider();
823
839
  const memberAddedMessages = await coreCryptoClient.addClientsToConversation(groupIdDecodedFromBase64, invitee);
824
840
  if (memberAddedMessages === null || memberAddedMessages === void 0 ? void 0 : memberAddedMessages.welcome) {
825
- await this.apiClient.api.conversation.postMlsWelcomeMessage(Uint8Array.from(memberAddedMessages.welcome));
841
+ //@todo: it's temporary - we wait for core-crypto fix to return the actual Uint8Array instead of regular array
842
+ await this.apiClient.api.conversation.postMlsWelcomeMessage(optionalToUint8Array(memberAddedMessages.welcome));
826
843
  }
827
844
  if (memberAddedMessages === null || memberAddedMessages === void 0 ? void 0 : memberAddedMessages.commit) {
828
- const messageResponse = await this.apiClient.api.conversation.postMlsMessage(Uint8Array.from(memberAddedMessages.commit));
845
+ const messageResponse = await this.apiClient.api.conversation.postMlsMessage(
846
+ //@todo: it's temporary - we wait for core-crypto fix to return the actual Uint8Array instead of regular array
847
+ optionalToUint8Array(memberAddedMessages.commit));
829
848
  await coreCryptoClient.commitAccepted(groupIdDecodedFromBase64);
830
849
  return messageResponse;
831
850
  }
@@ -897,6 +916,34 @@ class ConversationService {
897
916
  conversation,
898
917
  };
899
918
  }
919
+ async sendCommitBundleRemovalMessages(groupIdDecodedFromBase64, commitBundle) {
920
+ const coreCryptoClient = this.coreCryptoClientProvider();
921
+ if (commitBundle === null || commitBundle === void 0 ? void 0 : commitBundle.welcome) {
922
+ //@todo: it's temporary - we wait for core-crypto fix to return the actual Uint8Array instead of regular array
923
+ await this.apiClient.api.conversation.postMlsWelcomeMessage(optionalToUint8Array(commitBundle.welcome));
924
+ }
925
+ if (commitBundle === null || commitBundle === void 0 ? void 0 : commitBundle.commit) {
926
+ const messageResponse = await this.apiClient.api.conversation.postMlsMessage(
927
+ //@todo: it's temporary - we wait for core-crypto fix to return the actual Uint8Array instead of regular array
928
+ optionalToUint8Array(commitBundle.commit));
929
+ await coreCryptoClient.commitAccepted(groupIdDecodedFromBase64);
930
+ return messageResponse;
931
+ }
932
+ return null;
933
+ }
934
+ async removeUsersFromMLSConversation({ groupId, conversationId, qualifiedUserIds, }) {
935
+ const coreCryptoClient = this.coreCryptoClientProvider();
936
+ const groupIdDecodedFromBase64 = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
937
+ const clientsToRemove = await this.apiClient.api.user.postListClients({ qualified_users: qualifiedUserIds });
938
+ const fullyQualifiedClientIds = (0, mapQualifiedUserClientIdsToFullyQualifiedClientIds_1.mapQualifiedUserClientIdsToFullyQualifiedClientIds)(clientsToRemove.qualified_user_map);
939
+ const commitBundle = await coreCryptoClient.removeClientsFromConversation(groupIdDecodedFromBase64, fullyQualifiedClientIds);
940
+ const messageResponse = await this.sendCommitBundleRemovalMessages(groupIdDecodedFromBase64, commitBundle);
941
+ const conversation = await this.getConversations(conversationId.id);
942
+ return {
943
+ events: (messageResponse === null || messageResponse === void 0 ? void 0 : messageResponse.events) || [],
944
+ conversation,
945
+ };
946
+ }
900
947
  }
901
948
  exports.ConversationService = ConversationService;
902
949
  //# sourceMappingURL=ConversationService.js.map
@@ -97,6 +97,11 @@ export declare type AddUsersParams = {
97
97
  qualifiedUserIds: QualifiedId[];
98
98
  groupId?: string;
99
99
  };
100
+ export declare type RemoveUsersParams = {
101
+ conversationId: QualifiedId;
102
+ qualifiedUserIds: QualifiedId[];
103
+ groupId: string;
104
+ };
100
105
  export declare type MLSReturnType = {
101
106
  events: MlsEvent[];
102
107
  conversation: Conversation;
@@ -0,0 +1,8 @@
1
+ import { QualifiedUserClientMap } from '@wireapp/api-client/src/client';
2
+ declare type UserId = string;
3
+ declare type ClientId = string;
4
+ declare type Domain = string;
5
+ export declare type ClientIdStringType = `${UserId}:${ClientId}@${Domain}`;
6
+ export declare const constructFullyQualifiedClientId: (userId: UserId, clientId: ClientId, domain: Domain) => ClientIdStringType;
7
+ export declare const mapQualifiedUserClientIdsToFullyQualifiedClientIds: (qualifiedUserMap: QualifiedUserClientMap) => Uint8Array[];
8
+ export {};
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2022 Wire Swiss GmbH
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program. If not, see http://www.gnu.org/licenses/.
18
+ *
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.mapQualifiedUserClientIdsToFullyQualifiedClientIds = exports.constructFullyQualifiedClientId = void 0;
22
+ const constructFullyQualifiedClientId = (userId, clientId, domain) => `${userId}:${clientId}@${domain}`;
23
+ exports.constructFullyQualifiedClientId = constructFullyQualifiedClientId;
24
+ const mapQualifiedUserClientIdsToFullyQualifiedClientIds = (qualifiedUserMap) => {
25
+ const encoder = new TextEncoder();
26
+ return Object.entries(qualifiedUserMap).flatMap(([domain, users]) => {
27
+ const clients = Object.entries(users);
28
+ return clients.flatMap(([userId, clients]) => clients.map(client => encoder.encode((0, exports.constructFullyQualifiedClientId)(userId, client.id, domain))));
29
+ });
30
+ };
31
+ exports.mapQualifiedUserClientIdsToFullyQualifiedClientIds = mapQualifiedUserClientIdsToFullyQualifiedClientIds;
32
+ //# sourceMappingURL=mapQualifiedUserClientIdsToFullyQualifiedClientIds.js.map