@wireapp/core 40.5.3-draft-20-cc.3 → 40.5.3-draft-20-cc-1.3

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.
Files changed (143) hide show
  1. package/lib/Account.d.ts +9 -7
  2. package/lib/Account.d.ts.map +1 -1
  3. package/lib/Account.js +32 -35
  4. package/lib/CoreError.js +1 -1
  5. package/lib/broadcast/BroadcastService.d.ts +2 -11
  6. package/lib/broadcast/BroadcastService.d.ts.map +1 -1
  7. package/lib/broadcast/BroadcastService.js +5 -39
  8. package/lib/client/ClientDatabaseRepository.d.ts +5 -5
  9. package/lib/client/ClientDatabaseRepository.d.ts.map +1 -1
  10. package/lib/client/ClientDatabaseRepository.js +10 -17
  11. package/lib/client/ClientService.d.ts +5 -1
  12. package/lib/client/ClientService.d.ts.map +1 -1
  13. package/lib/client/ClientService.js +11 -9
  14. package/lib/connection/ConnectionService.d.ts +2 -2
  15. package/lib/connection/ConnectionService.d.ts.map +1 -1
  16. package/lib/connection/ConnectionService.js +2 -2
  17. package/lib/conversation/AssetTransferState.js +1 -1
  18. package/lib/conversation/ConversationService/ConversationService.d.ts +12 -5
  19. package/lib/conversation/ConversationService/ConversationService.d.ts.map +1 -1
  20. package/lib/conversation/ConversationService/ConversationService.js +26 -11
  21. package/lib/conversation/ConversationService/ConversationService.test.js +1 -1
  22. package/lib/conversation/ConversationService/ConversationService.types.d.ts +12 -11
  23. package/lib/conversation/ConversationService/ConversationService.types.d.ts.map +1 -1
  24. package/lib/conversation/ConversationService/ConversationService.types.js +1 -1
  25. package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts +1 -1
  26. package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts.map +1 -1
  27. package/lib/conversation/GenericMessageType.js +1 -1
  28. package/lib/conversation/ReactionType.d.ts +1 -4
  29. package/lib/conversation/ReactionType.d.ts.map +1 -1
  30. package/lib/conversation/ReactionType.js +0 -6
  31. package/lib/conversation/message/Message.types.js +1 -1
  32. package/lib/conversation/message/MessageBuilder.d.ts +1 -1
  33. package/lib/conversation/message/MessageBuilder.d.ts.map +1 -1
  34. package/lib/conversation/message/MessageBuilder.js +2 -2
  35. package/lib/conversation/message/MessageService.d.ts +6 -31
  36. package/lib/conversation/message/MessageService.d.ts.map +1 -1
  37. package/lib/conversation/message/MessageService.js +19 -162
  38. package/lib/conversation/message/MessageService.test.js +151 -141
  39. package/lib/conversation/message/PayloadBundle.js +1 -1
  40. package/lib/conversation/message/UserClientsUtil.d.ts +14 -10
  41. package/lib/conversation/message/UserClientsUtil.d.ts.map +1 -1
  42. package/lib/conversation/message/UserClientsUtil.js +21 -11
  43. package/lib/conversation/message/UserClientsUtils.test.js +5 -9
  44. package/lib/messagingProtocols/mls/EventHandler/EventHandler.d.ts +1 -1
  45. package/lib/messagingProtocols/mls/EventHandler/EventHandler.d.ts.map +1 -1
  46. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts +1 -1
  47. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
  48. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +7 -2
  49. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map +1 -1
  50. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.js +2 -0
  51. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js +3 -1
  52. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +20 -8
  53. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
  54. package/lib/messagingProtocols/mls/MLSService/MLSService.js +81 -40
  55. package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +9 -0
  56. package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.d.ts +1 -1
  57. package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.d.ts.map +1 -1
  58. package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.js +5 -5
  59. package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.test.js +3 -3
  60. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts +13 -0
  61. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts.map +1 -0
  62. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.js +67 -0
  63. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts +2 -0
  64. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts.map +1 -0
  65. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.js +72 -0
  66. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts +10 -5
  67. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts.map +1 -1
  68. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.js +33 -11
  69. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.d.ts +2 -3
  70. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.d.ts.map +1 -1
  71. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.js +8 -9
  72. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.d.ts +4 -9
  73. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.d.ts.map +1 -1
  74. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.js +10 -24
  75. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.test.js +2 -10
  76. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.d.ts +1 -2
  77. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.d.ts.map +1 -1
  78. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.js +3 -3
  79. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts +2 -2
  80. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts.map +1 -1
  81. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.d.ts +1 -1
  82. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.d.ts.map +1 -1
  83. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.js +2 -2
  84. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +14 -7
  85. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
  86. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +31 -35
  87. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts +1 -1
  88. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts.map +1 -1
  89. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.js +2 -3
  90. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +109 -89
  91. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts +6 -9
  92. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts.map +1 -1
  93. package/lib/messagingProtocols/proteus/Utility/Recipients.d.ts +4 -10
  94. package/lib/messagingProtocols/proteus/Utility/Recipients.d.ts.map +1 -1
  95. package/lib/messagingProtocols/proteus/Utility/Recipients.js +16 -16
  96. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts +15 -10
  97. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts.map +1 -1
  98. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.js +80 -92
  99. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +70 -54
  100. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts +5 -14
  101. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts.map +1 -1
  102. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.js +3 -35
  103. package/lib/messagingProtocols/proteus/Utility/isClearFromMismatch.d.ts +2 -2
  104. package/lib/messagingProtocols/proteus/Utility/isClearFromMismatch.d.ts.map +1 -1
  105. package/lib/notification/NotificationDatabaseRepository.js +1 -1
  106. package/lib/notification/Notifications.types.js +1 -1
  107. package/lib/user/UserService.d.ts +6 -17
  108. package/lib/user/UserService.d.ts.map +1 -1
  109. package/lib/user/UserService.js +2 -47
  110. package/lib/util/TaskScheduler/TaskScheduler.d.ts +4 -1
  111. package/lib/util/TaskScheduler/TaskScheduler.d.ts.map +1 -1
  112. package/lib/util/TaskScheduler/TaskScheduler.js +24 -3
  113. package/lib/util/TaskScheduler/TaskScheduler.store.d.ts +7 -0
  114. package/lib/util/TaskScheduler/TaskScheduler.store.d.ts.map +1 -0
  115. package/lib/util/TaskScheduler/TaskScheduler.store.js +34 -0
  116. package/lib/util/TypePredicateUtil.d.ts +0 -1
  117. package/lib/util/TypePredicateUtil.d.ts.map +1 -1
  118. package/lib/util/TypePredicateUtil.js +1 -2
  119. package/package.json +5 -5
  120. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.d.ts +0 -2
  121. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.d.ts.map +0 -1
  122. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.js +0 -35
  123. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.d.ts +0 -11
  124. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.d.ts.map +0 -1
  125. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.js +0 -50
  126. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.d.ts +0 -2
  127. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.d.ts.map +0 -1
  128. package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.js +0 -39
  129. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts +0 -4
  130. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts.map +0 -1
  131. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.js +0 -35
  132. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts +0 -2
  133. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts.map +0 -1
  134. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.js +0 -35
  135. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts +0 -25
  136. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts.map +0 -1
  137. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.js +0 -93
  138. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.d.ts +0 -2
  139. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.d.ts.map +0 -1
  140. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.js +0 -66
  141. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.d.ts +0 -2
  142. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.d.ts.map +0 -1
  143. package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.js +0 -35
@@ -1,11 +1,11 @@
1
- import { PostMlsMessageResponse } from '@wireapp/api-client/lib/conversation';
1
+ import { PostMlsMessageResponse, SUBCONVERSATION_ID } from '@wireapp/api-client/lib/conversation';
2
2
  import { Subconversation } from '@wireapp/api-client/lib/conversation/Subconversation';
3
3
  import { QualifiedId } from '@wireapp/api-client/lib/user';
4
4
  import logdown from 'logdown';
5
5
  import { APIClient } from '@wireapp/api-client';
6
- import { AddProposalArgs, ConversationId, CoreCrypto, DecryptedMessage, ExternalProposalArgs, ExternalProposalType, ExternalRemoveProposalArgs, Invitee, ProposalArgs, ProposalType, RemoveProposalArgs } from '@wireapp/core-crypto';
6
+ import { AddProposalArgs, ConversationId, CoreCrypto, DecryptedMessage, ExternalAddProposalArgs, ExternalProposalType, Invitee, ProposalArgs, ProposalType, RemoveProposalArgs } from '@wireapp/core-crypto';
7
7
  import { MLSServiceConfig } from './MLSService.types';
8
- import { QualifiedUsers } from '../../../conversation';
8
+ import { KeyPackageClaimUser } from '../../../conversation';
9
9
  import { TypedEventEmitter } from '../../../util/TypedEventEmitter';
10
10
  import { EventHandlerResult } from '../../common.types';
11
11
  import { EventHandlerParams } from '../EventHandler';
@@ -30,19 +30,26 @@ export declare class MLSService extends TypedEventEmitter<Events> {
30
30
  groupIdFromConversationId?: MLSCallbacks['groupIdFromConversationId'];
31
31
  private readonly textEncoder;
32
32
  private readonly textDecoder;
33
+ private readonly defaultCiphersuite;
33
34
  constructor(apiClient: APIClient, coreCryptoClient: CoreCrypto, { keyingMaterialUpdateThreshold, nbKeyPackages, }: Partial<MLSServiceConfig>);
34
35
  initClient(userId: QualifiedId, clientId: string): Promise<void>;
35
36
  createClient(userId: QualifiedId, clientId: string): Promise<void>;
36
37
  private uploadCommitBundle;
37
- addUsersToExistingConversation(groupId: Uint8Array, invitee: Invitee[]): Promise<PostMlsMessageResponse | null>;
38
+ addUsersToExistingConversation(groupId: Uint8Array, invitee: Invitee[]): Promise<PostMlsMessageResponse | null> | null;
38
39
  configureMLSCallbacks({ groupIdFromConversationId, ...coreCryptoCallbacks }: MLSCallbacks): void;
39
- getKeyPackagesPayload(qualifiedUsers: QualifiedUsers[]): Promise<Invitee[]>;
40
+ getKeyPackagesPayload(qualifiedUsers: KeyPackageClaimUser[]): Promise<Invitee[]>;
40
41
  getEpoch(groupId: string | Uint8Array): Promise<number>;
41
42
  newProposal(proposalType: ProposalType, args: ProposalArgs | AddProposalArgs | RemoveProposalArgs): Promise<import("@wireapp/core-crypto").ProposalBundle>;
42
43
  joinByExternalCommit(getGroupInfo: () => Promise<Uint8Array>): Promise<PostMlsMessageResponse | null>;
43
44
  getConferenceSubconversation(conversationId: QualifiedId): Promise<Subconversation>;
44
45
  private deleteConferenceSubconversation;
46
+ /**
47
+ * Will leave conference subconversation if it's known by client and established.
48
+ *
49
+ * @param conversationId Id of the parent conversation which subconversation we want to leave
50
+ */
45
51
  leaveConferenceSubconversation(conversationId: QualifiedId): Promise<void>;
52
+ leaveStaleConferenceSubconversations(): Promise<void>;
46
53
  /**
47
54
  * Will join or register an mls subconversation for conference calls.
48
55
  * Will return the secret key derived from the subconversation
@@ -54,7 +61,7 @@ export declare class MLSService extends TypedEventEmitter<Events> {
54
61
  epoch: number;
55
62
  }>;
56
63
  exportSecretKey(groupId: string, keyLength: number): Promise<string>;
57
- newExternalProposal(externalProposalType: ExternalProposalType, args: ExternalProposalArgs | ExternalRemoveProposalArgs): Promise<Uint8Array>;
64
+ newExternalProposal(externalProposalType: ExternalProposalType, args: ExternalAddProposalArgs): Promise<Uint8Array>;
58
65
  processWelcomeMessage(welcomeMessage: Uint8Array): Promise<ConversationId>;
59
66
  decryptMessage(conversationId: ConversationId, payload: Uint8Array): Promise<DecryptedMessage>;
60
67
  encryptMessage(conversationId: ConversationId, message: Uint8Array): Promise<Uint8Array>;
@@ -102,6 +109,11 @@ export declare class MLSService extends TypedEventEmitter<Events> {
102
109
  * @param groupId The group that should have its key material updated
103
110
  */
104
111
  resetKeyMaterialRenewal(groupId: string): void;
112
+ /**
113
+ * Will cancel the renewal of the key material for a given groupId
114
+ * @param groupId The group that should stop having its key material updated
115
+ */
116
+ cancelKeyMaterialRenewal(groupId: string): void;
105
117
  /**
106
118
  * Will schedule a task to update the key material of the conversation according to the threshold given as config
107
119
  * @param groupId
@@ -111,7 +123,7 @@ export declare class MLSService extends TypedEventEmitter<Events> {
111
123
  * Get all keying material last update dates and schedule tasks for renewal
112
124
  * Function must only be called once, after application start
113
125
  */
114
- checkForKeyMaterialsUpdate(): void;
126
+ schedulePeriodicKeyMaterialRenewals(groupIds: string[]): void;
115
127
  /**
116
128
  * Get date of last key packages count query and schedule a task to sync it with backend
117
129
  * Function must only be called once, after application start
@@ -134,7 +146,7 @@ export declare class MLSService extends TypedEventEmitter<Events> {
134
146
  *
135
147
  * @param conversationQualifiedId
136
148
  */
137
- getGroupIdFromConversationId(conversationQualifiedId: QualifiedId, subconversationId?: string): Promise<string>;
149
+ getGroupIdFromConversationId(conversationQualifiedId: QualifiedId, subconversationId?: SUBCONVERSATION_ID): Promise<string | undefined>;
138
150
  /**
139
151
  * If there are pending proposals, we need to either process them,
140
152
  * or save them in the database for later processing
@@ -1 +1 @@
1
- {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
@@ -39,10 +39,9 @@ const axios_1 = __importDefault(require("axios"));
39
39
  const bazinga64_1 = require("bazinga64");
40
40
  const logdown_1 = __importDefault(require("logdown"));
41
41
  const commons_1 = require("@wireapp/commons");
42
- const commitBundleUtil_1 = require("./commitBundleUtil");
43
- const keyMaterialUpdatesStore_1 = require("./stores/keyMaterialUpdatesStore");
42
+ const core_crypto_1 = require("@wireapp/core-crypto");
44
43
  const pendingProposalsStore_1 = require("./stores/pendingProposalsStore");
45
- const subconversationGroupIdMapper_1 = require("./subconversationGroupIdMapper");
44
+ const subconversationGroupIdStore_1 = require("./stores/subconversationGroupIdStore/subconversationGroupIdStore");
46
45
  const messageSender_1 = require("../../../conversation/message/messageSender");
47
46
  const fullyQualifiedClientIdUtils_1 = require("../../../util/fullyQualifiedClientIdUtils");
48
47
  const RecurringTaskScheduler_1 = require("../../../util/RecurringTaskScheduler");
@@ -67,6 +66,7 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
67
66
  this.logger = (0, logdown_1.default)('@wireapp/core/MLSService');
68
67
  this.textEncoder = new TextEncoder();
69
68
  this.textDecoder = new TextDecoder();
69
+ this.defaultCiphersuite = core_crypto_1.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519;
70
70
  this.config = {
71
71
  keyingMaterialUpdateThreshold,
72
72
  nbKeyPackages,
@@ -74,20 +74,21 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
74
74
  }
75
75
  async initClient(userId, clientId) {
76
76
  const qualifiedClientId = (0, fullyQualifiedClientIdUtils_1.constructFullyQualifiedClientId)(userId.id, clientId, userId.domain);
77
- await this.coreCryptoClient.mlsInit(this.textEncoder.encode(qualifiedClientId));
77
+ await this.coreCryptoClient.mlsInit(this.textEncoder.encode(qualifiedClientId), [this.defaultCiphersuite]);
78
78
  }
79
79
  async createClient(userId, clientId) {
80
80
  await this.initClient(userId, clientId);
81
81
  // If the device is new, we need to upload keypackages and public key to the backend
82
- const publicKey = await this.coreCryptoClient.clientPublicKey();
83
- const keyPackages = await this.coreCryptoClient.clientKeypackages(this.config.nbKeyPackages);
82
+ const publicKey = await this.coreCryptoClient.clientPublicKey(this.defaultCiphersuite);
83
+ const keyPackages = await this.coreCryptoClient.clientKeypackages(this.defaultCiphersuite, this.config.nbKeyPackages);
84
84
  await this.uploadMLSPublicKeys(publicKey, clientId);
85
85
  await this.uploadMLSKeyPackages(keyPackages, clientId);
86
86
  }
87
87
  async uploadCommitBundle(groupId, commitBundle, { regenerateCommitBundle, isExternalCommit } = {}) {
88
- const bundlePayload = (0, commitBundleUtil_1.toProtobufCommitBundle)(commitBundle);
88
+ const { commit, groupInfo, welcome } = commitBundle;
89
+ const bundlePayload = new Uint8Array([...commit, ...groupInfo.payload, ...(welcome || [])]);
89
90
  try {
90
- const response = await this.apiClient.api.conversation.postMlsCommitBundle(bundlePayload.slice());
91
+ const response = await this.apiClient.api.conversation.postMlsCommitBundle(bundlePayload);
91
92
  if (isExternalCommit) {
92
93
  await this.coreCryptoClient.mergePendingGroupFromExternalCommit(groupId);
93
94
  }
@@ -119,16 +120,18 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
119
120
  return null;
120
121
  }
121
122
  addUsersToExistingConversation(groupId, invitee) {
123
+ if (invitee.length < 1) {
124
+ // providing an empty invitee list to addClientsToConversation method would make core-crypto throw an error
125
+ // we want to skip adding clinets in this case
126
+ return null;
127
+ }
122
128
  return this.processCommitAction(groupId, () => this.coreCryptoClient.addClientsToConversation(groupId, invitee));
123
129
  }
124
130
  configureMLSCallbacks(_a) {
125
131
  var { groupIdFromConversationId } = _a, coreCryptoCallbacks = __rest(_a, ["groupIdFromConversationId"]);
126
- void this.coreCryptoClient.registerCallbacks(Object.assign(Object.assign({}, coreCryptoCallbacks), { clientIsExistingGroupUser: (_groupId, client, otherClients) => {
127
- const { user } = (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(this.textDecoder.decode(client));
128
- return Promise.resolve(otherClients.some(client => {
129
- const { user: otherUser } = (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(this.textDecoder.decode(client));
130
- return otherUser.toLowerCase() === user.toLowerCase();
131
- }));
132
+ void this.coreCryptoClient.registerCallbacks(Object.assign(Object.assign({}, coreCryptoCallbacks), { clientIsExistingGroupUser: (_groupId, _client, _otherClients) => {
133
+ // All authorization/membership rules are enforced on backend
134
+ return Promise.resolve(true);
132
135
  } }));
133
136
  this.groupIdFromConversationId = groupIdFromConversationId;
134
137
  }
@@ -138,9 +141,7 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
138
141
  * we want to add to the new MLS conversations,
139
142
  * includes self user too.
140
143
  */
141
- const keyPackages = await Promise.all([
142
- ...qualifiedUsers.map(({ id, domain, skipOwn }) => this.apiClient.api.client.claimMLSKeyPackages(id, domain, skipOwn)),
143
- ]);
144
+ const keyPackages = await Promise.all(qualifiedUsers.map(({ id, domain, skipOwnClientId }) => this.apiClient.api.client.claimMLSKeyPackages(id, domain, skipOwnClientId)));
144
145
  const coreCryptoKeyPackagesPayload = keyPackages.reduce((previousValue, currentValue) => {
145
146
  // skip users that have not uploaded their MLS key packages
146
147
  if (currentValue.key_packages.length > 0) {
@@ -166,14 +167,20 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
166
167
  async joinByExternalCommit(getGroupInfo) {
167
168
  const generateCommit = async () => {
168
169
  const groupInfo = await getGroupInfo();
169
- const _a = await this.coreCryptoClient.joinByExternalCommit(groupInfo), { conversationId } = _a, commitBundle = __rest(_a, ["conversationId"]);
170
+ const _a = await this.coreCryptoClient.joinByExternalCommit(groupInfo, core_crypto_1.CredentialType.Basic), { conversationId } = _a, commitBundle = __rest(_a, ["conversationId"]);
170
171
  return { groupId: conversationId, commitBundle };
171
172
  };
172
173
  const { commitBundle, groupId } = await generateCommit();
173
- return this.uploadCommitBundle(groupId, commitBundle, {
174
+ const mlsResponse = await this.uploadCommitBundle(groupId, commitBundle, {
174
175
  isExternalCommit: true,
175
176
  regenerateCommitBundle: async () => (await generateCommit()).commitBundle,
176
177
  });
178
+ if (mlsResponse) {
179
+ //after we've successfully joined via external commit, we schedule periodic key material renewal
180
+ const groupIdStr = bazinga64_1.Encoder.toBase64(groupId).asString;
181
+ this.scheduleKeyMaterialRenewal(groupIdStr);
182
+ }
183
+ return mlsResponse;
177
184
  }
178
185
  async getConferenceSubconversation(conversationId) {
179
186
  return this.apiClient.api.conversation.getSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
@@ -181,14 +188,36 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
181
188
  async deleteConferenceSubconversation(conversationId, data) {
182
189
  return this.apiClient.api.conversation.deleteSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE, data);
183
190
  }
191
+ /**
192
+ * Will leave conference subconversation if it's known by client and established.
193
+ *
194
+ * @param conversationId Id of the parent conversation which subconversation we want to leave
195
+ */
184
196
  async leaveConferenceSubconversation(conversationId) {
185
- const subconversationGroupId = await this.getGroupIdFromConversationId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
197
+ const subconversationGroupId = subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
198
+ if (!subconversationGroupId) {
199
+ return;
200
+ }
186
201
  const isSubconversationEstablished = await this.conversationExists(subconversationGroupId);
187
202
  if (!isSubconversationEstablished) {
188
- return;
203
+ // if the subconversation was known by a client but is not established anymore, we can remove it from the store
204
+ return subconversationGroupIdStore_1.subconversationGroupIdStore.removeGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
205
+ }
206
+ try {
207
+ await this.apiClient.api.conversation.deleteSubconversationSelf(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
208
+ }
209
+ catch (error) {
210
+ this.logger.error(`Failed to leave conference subconversation:`, error);
211
+ }
212
+ await this.wipeConversation(subconversationGroupId);
213
+ // once we've left the subconversation, we can remove it from the store
214
+ subconversationGroupIdStore_1.subconversationGroupIdStore.removeGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
215
+ }
216
+ async leaveStaleConferenceSubconversations() {
217
+ const conversationIds = subconversationGroupIdStore_1.subconversationGroupIdStore.getAllGroupIdsBySubconversationId(conversation_1.SUBCONVERSATION_ID.CONFERENCE);
218
+ for (const { parentConversationId } of conversationIds) {
219
+ await this.leaveConferenceSubconversation(parentConversationId);
189
220
  }
190
- await this.apiClient.api.conversation.deleteSubconversationSelf(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
191
- return this.wipeConversation(subconversationGroupId);
192
221
  }
193
222
  /**
194
223
  * Will join or register an mls subconversation for conference calls.
@@ -218,7 +247,7 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
218
247
  }
219
248
  const epoch = Number(await this.getEpoch(subconversation.group_id));
220
249
  // We store the mapping between the subconversation and the parent conversation
221
- (0, subconversationGroupIdMapper_1.storeSubconversationGroupId)(conversationId, subconversation.subconv_id, subconversation.group_id);
250
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation.subconv_id, subconversation.group_id);
222
251
  return { groupId: subconversation.group_id, epoch };
223
252
  }
224
253
  async exportSecretKey(groupId, keyLength) {
@@ -270,16 +299,16 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
270
299
  const mlsKeyBytes = Object.values(mlsKeys).map((key) => bazinga64_1.Decoder.fromBase64(key).asBytes);
271
300
  const configuration = {
272
301
  externalSenders: mlsKeyBytes,
273
- ciphersuite: 1, // TODO: Use the correct ciphersuite enum.
302
+ ciphersuite: this.defaultCiphersuite,
274
303
  };
275
- await this.coreCryptoClient.createConversation(groupIdBytes, configuration);
304
+ await this.coreCryptoClient.createConversation(groupIdBytes, core_crypto_1.CredentialType.Basic, configuration);
276
305
  const keyPackages = await this.getKeyPackagesPayload(users.map(user => {
277
306
  if (user.id === (creator === null || creator === void 0 ? void 0 : creator.user.id)) {
278
307
  /**
279
308
  * we should skip fetching key packages for current self client,
280
309
  * it's already added by the backend on the group creation time
281
310
  */
282
- return Object.assign(Object.assign({}, creator.user), { skipOwn: creator.client });
311
+ return Object.assign(Object.assign({}, creator.user), { skipOwnClientId: creator.client });
283
312
  }
284
313
  return user;
285
314
  }));
@@ -287,7 +316,7 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
287
316
  ? await this.addUsersToExistingConversation(groupIdBytes, keyPackages)
288
317
  : // If there are no clients to add, just update the keying material
289
318
  await this.processCommitAction(groupIdBytes, () => this.coreCryptoClient.updateKeyingMaterial(groupIdBytes));
290
- // We schedule a key material renewal
319
+ // We schedule a periodic key material renewal
291
320
  this.scheduleKeyMaterialRenewal(groupId);
292
321
  return response;
293
322
  }
@@ -309,10 +338,10 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
309
338
  return this.coreCryptoClient.conversationExists(groupIdBytes);
310
339
  }
311
340
  async clientValidKeypackagesCount() {
312
- return this.coreCryptoClient.clientValidKeypackagesCount();
341
+ return this.coreCryptoClient.clientValidKeypackagesCount(this.defaultCiphersuite);
313
342
  }
314
343
  async clientKeypackages(amountRequested) {
315
- return this.coreCryptoClient.clientKeypackages(amountRequested);
344
+ return this.coreCryptoClient.clientKeypackages(this.defaultCiphersuite, amountRequested);
316
345
  }
317
346
  /**
318
347
  * Renew key material for a given groupId
@@ -323,7 +352,7 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
323
352
  try {
324
353
  const groupConversationExists = await this.conversationExists(groupId);
325
354
  if (!groupConversationExists) {
326
- keyMaterialUpdatesStore_1.keyMaterialUpdatesStore.deleteLastKeyMaterialUpdateDate({ groupId });
355
+ this.cancelKeyMaterialRenewal(groupId);
327
356
  return;
328
357
  }
329
358
  const groupIdDecodedFromBase64 = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
@@ -341,9 +370,16 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
341
370
  * @param groupId The group that should have its key material updated
342
371
  */
343
372
  resetKeyMaterialRenewal(groupId) {
344
- (0, RecurringTaskScheduler_1.cancelRecurringTask)(this.createKeyMaterialUpdateTaskSchedulerId(groupId));
373
+ this.cancelKeyMaterialRenewal(groupId);
345
374
  this.scheduleKeyMaterialRenewal(groupId);
346
375
  }
376
+ /**
377
+ * Will cancel the renewal of the key material for a given groupId
378
+ * @param groupId The group that should stop having its key material updated
379
+ */
380
+ cancelKeyMaterialRenewal(groupId) {
381
+ return (0, RecurringTaskScheduler_1.cancelRecurringTask)(this.createKeyMaterialUpdateTaskSchedulerId(groupId));
382
+ }
347
383
  /**
348
384
  * Will schedule a task to update the key material of the conversation according to the threshold given as config
349
385
  * @param groupId
@@ -360,10 +396,9 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
360
396
  * Get all keying material last update dates and schedule tasks for renewal
361
397
  * Function must only be called once, after application start
362
398
  */
363
- checkForKeyMaterialsUpdate() {
399
+ schedulePeriodicKeyMaterialRenewals(groupIds) {
364
400
  try {
365
- const keyMaterialUpdateDates = keyMaterialUpdatesStore_1.keyMaterialUpdatesStore.getAllUpdateDates();
366
- keyMaterialUpdateDates.forEach(({ groupId }) => this.scheduleKeyMaterialRenewal(groupId));
401
+ groupIds.forEach(groupId => this.scheduleKeyMaterialRenewal(groupId));
367
402
  }
368
403
  catch (error) {
369
404
  this.logger.error('Could not get last key material update dates', error);
@@ -409,11 +444,21 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
409
444
  return this.apiClient.api.client.uploadMLSKeyPackages(clientId, keypackages.map(keypackage => btoa(bazinga64_1.Converter.arrayBufferViewToBaselineString(keypackage))));
410
445
  }
411
446
  async wipeConversation(groupId) {
447
+ const isMLSConversationEstablished = await this.conversationExists(groupId);
448
+ if (!isMLSConversationEstablished) {
449
+ //if the mls group does not exist, we don't need to wipe it
450
+ return;
451
+ }
452
+ this.cancelKeyMaterialRenewal(groupId);
412
453
  const groupIdBytes = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
413
454
  return this.coreCryptoClient.wipeConversation(groupIdBytes);
414
455
  }
415
456
  async handleEvent(params) {
416
457
  return (0, EventHandler_1.handleBackendEvent)(Object.assign(Object.assign({}, params), { mlsService: this }), async (groupId) => {
458
+ const conversationExists = await this.conversationExists(groupId);
459
+ if (!conversationExists) {
460
+ return;
461
+ }
417
462
  const newEpoch = await this.getEpoch(groupId);
418
463
  this.emit('newEpoch', { groupId, epoch: newEpoch });
419
464
  });
@@ -426,13 +471,9 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
426
471
  */
427
472
  async getGroupIdFromConversationId(conversationQualifiedId, subconversationId) {
428
473
  var _a;
429
- const { id: conversationId, domain: conversationDomain } = conversationQualifiedId;
430
474
  const groupId = subconversationId
431
- ? (0, subconversationGroupIdMapper_1.getGroupId)(conversationQualifiedId, subconversationId)
475
+ ? subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationQualifiedId, subconversationId)
432
476
  : await ((_a = this.groupIdFromConversationId) === null || _a === void 0 ? void 0 : _a.call(this, conversationQualifiedId));
433
- if (!groupId) {
434
- throw new Error(`Could not find a group_id for conversation ${conversationId}@${conversationDomain}`);
435
- }
436
477
  return groupId;
437
478
  }
438
479
  /**
@@ -29,6 +29,8 @@ describe('MLSService', () => {
29
29
  const apiClient = new api_client_1.APIClient();
30
30
  const mockCoreCrypto = {
31
31
  createConversation: jest.fn(),
32
+ conversationExists: jest.fn(),
33
+ wipeConversation: jest.fn(),
32
34
  };
33
35
  describe('registerConversation', () => {
34
36
  let mlsService;
@@ -40,6 +42,7 @@ describe('MLSService', () => {
40
42
  jest.spyOn(apiClient.api.client, 'claimMLSKeyPackages').mockResolvedValue({ key_packages: [] });
41
43
  jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation();
42
44
  jest.spyOn(mlsService, 'processCommitAction').mockImplementation();
45
+ jest.spyOn(mlsService, 'cancelKeyMaterialRenewal').mockImplementation();
43
46
  });
44
47
  it('creates a new mls conversation and avoid adding the selfUser', async () => {
45
48
  const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
@@ -56,5 +59,11 @@ describe('MLSService', () => {
56
59
  await mlsService.registerConversation(groupId, [createUserId(), createUserId()]);
57
60
  expect(mlsService.scheduleKeyMaterialRenewal).toHaveBeenCalledWith(groupId);
58
61
  });
62
+ it('cancels key material timers after group is wiped', async () => {
63
+ const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm4OQFc=';
64
+ jest.spyOn(mockCoreCrypto, 'conversationExists').mockResolvedValueOnce(true);
65
+ await mlsService.wipeConversation(groupId);
66
+ expect(mlsService.cancelKeyMaterialRenewal).toHaveBeenCalledWith(groupId);
67
+ });
59
68
  });
60
69
  });
@@ -4,5 +4,5 @@ import { CommitBundle } from '@wireapp/core-crypto';
4
4
  * @param commitBundle a commit bundle generated by coreCrypto
5
5
  * @returns
6
6
  */
7
- export declare function toProtobufCommitBundle({ commit, welcome, publicGroupState }: CommitBundle): Uint8Array;
7
+ export declare function toProtobufCommitBundle({ commit, welcome, groupInfo }: CommitBundle): Uint8Array;
8
8
  //# sourceMappingURL=commitBundleUtil.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commitBundleUtil.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/commitBundleUtil.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,YAAY,EAAkD,MAAM,sBAAsB,CAAC;AAYnG;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAC,EAAE,YAAY,GAAG,UAAU,CAWpG"}
1
+ {"version":3,"file":"commitBundleUtil.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/commitBundleUtil.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,YAAY,EAA2C,MAAM,sBAAsB,CAAC;AAY5F;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAC,EAAE,YAAY,GAAG,UAAU,CAW7F"}
@@ -27,20 +27,20 @@ const ratchetTreeMapping = {
27
27
  [core_crypto_1.RatchetTreeType.Delta]: mls_1.mls.RatchetTreeType.DELTA,
28
28
  };
29
29
  const groupInfoType = {
30
- [core_crypto_1.PublicGroupStateEncryptionType.Plaintext]: mls_1.mls.GroupInfoType.PUBLIC_GROUP_STATE,
31
- [core_crypto_1.PublicGroupStateEncryptionType.JweEncrypted]: mls_1.mls.GroupInfoType.GROUP_INFO_JWE,
30
+ [core_crypto_1.GroupInfoEncryptionType.Plaintext]: mls_1.mls.GroupInfoType.PUBLIC_GROUP_STATE,
31
+ [core_crypto_1.GroupInfoEncryptionType.JweEncrypted]: mls_1.mls.GroupInfoType.GROUP_INFO_JWE,
32
32
  };
33
33
  /**
34
34
  * Will convert a coreCrypto commit bundle into a Uint8Array representing a protobuf object
35
35
  * @param commitBundle a commit bundle generated by coreCrypto
36
36
  * @returns
37
37
  */
38
- function toProtobufCommitBundle({ commit, welcome, publicGroupState }) {
39
- const { ratchetTreeType, encryptionType } = publicGroupState;
38
+ function toProtobufCommitBundle({ commit, welcome, groupInfo }) {
39
+ const { ratchetTreeType, encryptionType } = groupInfo;
40
40
  return mls_1.mls.CommitBundle.encode({
41
41
  groupInfoBundle: {
42
42
  ratchetTreeType: ratchetTreeMapping[ratchetTreeType],
43
- groupInfo: publicGroupState.payload,
43
+ groupInfo: groupInfo.payload,
44
44
  groupInfoType: groupInfoType[encryptionType],
45
45
  },
46
46
  commit,
@@ -27,17 +27,17 @@ describe('toProtobufCommitBundle', () => {
27
27
  const payload = {
28
28
  commit: Uint8Array.from([0]),
29
29
  welcome: Uint8Array.from([1]),
30
- publicGroupState: {
30
+ groupInfo: {
31
31
  ratchetTreeType: core_crypto_1.RatchetTreeType.Full,
32
32
  payload: Uint8Array.from([2]),
33
- encryptionType: core_crypto_1.PublicGroupStateEncryptionType.Plaintext,
33
+ encryptionType: core_crypto_1.GroupInfoEncryptionType.Plaintext,
34
34
  },
35
35
  };
36
36
  const result = (0, commitBundleUtil_1.toProtobufCommitBundle)(payload);
37
37
  const { commit, welcome, groupInfoBundle } = mls_1.mls.CommitBundle.decode(result);
38
38
  expect(bazinga64_1.Encoder.toBase64(commit)).toEqual(bazinga64_1.Encoder.toBase64(payload.commit));
39
39
  expect(bazinga64_1.Encoder.toBase64(welcome)).toEqual(bazinga64_1.Encoder.toBase64(payload.welcome));
40
- expect(bazinga64_1.Encoder.toBase64(groupInfoBundle.groupInfo)).toEqual(bazinga64_1.Encoder.toBase64(payload.publicGroupState.payload));
40
+ expect(bazinga64_1.Encoder.toBase64(groupInfoBundle.groupInfo)).toEqual(bazinga64_1.Encoder.toBase64(payload.groupInfo.payload));
41
41
  expect(groupInfoBundle.ratchetTreeType).toEqual(mls_1.mls.RatchetTreeType.FULL);
42
42
  expect(groupInfoBundle.groupInfoType).toEqual(mls_1.mls.GroupInfoType.PUBLIC_GROUP_STATE);
43
43
  });
@@ -0,0 +1,13 @@
1
+ import { SUBCONVERSATION_ID } from '@wireapp/api-client/lib/conversation';
2
+ import { QualifiedId } from '@wireapp/api-client/lib/user';
3
+ export declare const subconversationGroupIdStore: {
4
+ storeGroupId: (parentConversationId: QualifiedId, subconversationId: SUBCONVERSATION_ID, subconversationGroupId: string) => void;
5
+ getGroupId: (parentConversationId: QualifiedId, subconversationId: SUBCONVERSATION_ID) => string | undefined;
6
+ removeGroupId: (parentConversationId: QualifiedId, subconversationId: SUBCONVERSATION_ID) => void;
7
+ getAllGroupIdsBySubconversationId: (subconversationIdQuery: SUBCONVERSATION_ID) => {
8
+ subconversationGroupId: string;
9
+ parentConversationId: QualifiedId;
10
+ subconversationId: SUBCONVERSATION_ID;
11
+ }[];
12
+ };
13
+ //# sourceMappingURL=subconversationGroupIdStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subconversationGroupIdStore.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sCAAsC,CAAC;AACxE,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAgEzD,eAAO,MAAM,2BAA2B;yCA3BhB,WAAW,qBACd,kBAAkB,0BACb,MAAM;uCAMU,WAAW,qBAAqB,kBAAkB;0CAc/C,WAAW,qBAAqB,kBAAkB;gEAT5B,kBAAkB;;8BArC3D,WAAW;2BAAqB,kBAAkB;;CAwD3E,CAAC"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2023 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.subconversationGroupIdStore = void 0;
22
+ const storageKey = 'subconversationGroupIdStore';
23
+ const generateSubconversationStoreKey = (parentConversationId, subconversationId) => {
24
+ return `${parentConversationId.id}@${parentConversationId.domain}:${subconversationId}`;
25
+ };
26
+ const parseSubconversationStoreKey = (subconversationStoreKey) => {
27
+ const [parentConversationId, subconversationId] = subconversationStoreKey.split(':');
28
+ const [id, domain] = parentConversationId.split('@');
29
+ return { parentConversationId: { domain, id }, subconversationId };
30
+ };
31
+ const getCurrentMap = () => {
32
+ const storedEntry = localStorage.getItem(storageKey);
33
+ return storedEntry ? new Map(JSON.parse(storedEntry)) : new Map();
34
+ };
35
+ const addItemToMap = (subconversationId, subgroupId) => {
36
+ const currentMap = getCurrentMap();
37
+ currentMap.set(subconversationId, subgroupId);
38
+ localStorage.setItem(storageKey, JSON.stringify(Array.from(currentMap.entries())));
39
+ };
40
+ const removeItemFromMap = (subconversationId) => {
41
+ const currentMap = getCurrentMap();
42
+ currentMap.delete(subconversationId);
43
+ localStorage.setItem(storageKey, JSON.stringify(Array.from(currentMap.entries())));
44
+ };
45
+ const storeGroupId = (parentConversationId, subconversationId, subconversationGroupId) => {
46
+ const subconversationStoreKey = generateSubconversationStoreKey(parentConversationId, subconversationId);
47
+ addItemToMap(subconversationStoreKey, subconversationGroupId);
48
+ };
49
+ const getGroupId = (parentConversationId, subconversationId) => {
50
+ const subconversationStoreKey = generateSubconversationStoreKey(parentConversationId, subconversationId);
51
+ return getCurrentMap().get(subconversationStoreKey);
52
+ };
53
+ const getAllGroupIdsBySubconversationId = (subconversationIdQuery) => {
54
+ return Array.from(getCurrentMap().entries())
55
+ .map(([subconversationId, subconversationGroupId]) => (Object.assign(Object.assign({}, parseSubconversationStoreKey(subconversationId)), { subconversationGroupId })))
56
+ .filter(({ subconversationId }) => subconversationId === subconversationIdQuery);
57
+ };
58
+ const removeGroupId = (parentConversationId, subconversationId) => {
59
+ const subconversationStoreKey = generateSubconversationStoreKey(parentConversationId, subconversationId);
60
+ return removeItemFromMap(subconversationStoreKey);
61
+ };
62
+ exports.subconversationGroupIdStore = {
63
+ storeGroupId,
64
+ getGroupId,
65
+ removeGroupId,
66
+ getAllGroupIdsBySubconversationId,
67
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=subconversationGroupIdStore.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subconversationGroupIdStore.test.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2018 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
+ const conversation_1 = require("@wireapp/api-client/lib/conversation");
22
+ const subconversationGroupIdStore_1 = require("./subconversationGroupIdStore");
23
+ describe('subconversationGroupIdMapper', () => {
24
+ it('returns empty groupId if conversation is not known', () => {
25
+ const groupId = subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId({ domain: 'example.com', id: '123' }, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
26
+ expect(groupId).toBeUndefined();
27
+ });
28
+ it('returns the stored groupId', () => {
29
+ const conversationId = { domain: 'example.com', id: '123' };
30
+ const subconversation = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
31
+ const groupId = 'groupID';
32
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation, groupId);
33
+ const result = subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationId, subconversation);
34
+ expect(result).toBe(groupId);
35
+ });
36
+ it('removes groupId from the store', () => {
37
+ const conversationId = { domain: 'example.com', id: '123' };
38
+ const subconversation = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
39
+ const groupId = 'groupID';
40
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation, groupId);
41
+ expect(subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationId, subconversation)).toEqual(groupId);
42
+ subconversationGroupIdStore_1.subconversationGroupIdStore.removeGroupId(conversationId, subconversation);
43
+ expect(subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationId, subconversation)).toBeUndefined();
44
+ });
45
+ it('retrieves all entries from the store by subconversation id', () => {
46
+ const conversationId = { domain: 'example.com', id: '123' };
47
+ const subconversation = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
48
+ const groupId = 'groupID';
49
+ const conversationId2 = { domain: 'example2.com', id: '1234' };
50
+ const subconversation2 = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
51
+ const groupId2 = 'groupID2';
52
+ const conversationId3 = { domain: 'example3.com', id: '12345' };
53
+ const subconversation3 = 'none';
54
+ const groupId3 = 'groupID3';
55
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation, groupId);
56
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId2, subconversation2, groupId2);
57
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId3, subconversation3, groupId3);
58
+ const result = subconversationGroupIdStore_1.subconversationGroupIdStore.getAllGroupIdsBySubconversationId(conversation_1.SUBCONVERSATION_ID.CONFERENCE);
59
+ expect(result).toEqual([
60
+ {
61
+ parentConversationId: conversationId,
62
+ subconversationId: subconversation,
63
+ subconversationGroupId: groupId,
64
+ },
65
+ {
66
+ parentConversationId: conversationId2,
67
+ subconversationId: subconversation2,
68
+ subconversationGroupId: groupId2,
69
+ },
70
+ ]);
71
+ });
72
+ });