@wireapp/core 46.46.6-beta.14.f6fd03fe6 → 46.46.6-beta.28.9d3034481

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 (195) hide show
  1. package/lib/Account.d.ts +168 -51
  2. package/lib/Account.d.ts.map +1 -1
  3. package/lib/Account.js +517 -127
  4. package/lib/Account.test.js +158 -147
  5. package/lib/broadcast/AvailabilityType.d.ts +1 -1
  6. package/lib/broadcast/AvailabilityType.d.ts.map +1 -1
  7. package/lib/broadcast/BroadcastService.d.ts +1 -1
  8. package/lib/broadcast/BroadcastService.d.ts.map +1 -1
  9. package/lib/broadcast/BroadcastService.js +1 -1
  10. package/lib/client/ClientService.d.ts +4 -3
  11. package/lib/client/ClientService.d.ts.map +1 -1
  12. package/lib/client/ClientService.js +19 -5
  13. package/lib/conversation/AbortReason.d.ts +1 -1
  14. package/lib/conversation/AbortReason.d.ts.map +1 -1
  15. package/lib/conversation/AssetService/AssetService.d.ts +12 -30
  16. package/lib/conversation/AssetService/AssetService.d.ts.map +1 -1
  17. package/lib/conversation/AssetService/AssetService.js +1 -10
  18. package/lib/conversation/AssetService/AssetService.test.js +8 -3
  19. package/lib/conversation/ClientActionType.d.ts +1 -1
  20. package/lib/conversation/ClientActionType.d.ts.map +1 -1
  21. package/lib/conversation/ClientActionType.js +1 -1
  22. package/lib/conversation/ConversationService/ConversationService.d.ts +98 -14
  23. package/lib/conversation/ConversationService/ConversationService.d.ts.map +1 -1
  24. package/lib/conversation/ConversationService/ConversationService.js +314 -101
  25. package/lib/conversation/ConversationService/ConversationService.test.js +441 -47
  26. package/lib/conversation/ConversationService/ConversationService.types.d.ts +5 -4
  27. package/lib/conversation/ConversationService/ConversationService.types.d.ts.map +1 -1
  28. package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts.map +1 -1
  29. package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.js +6 -3
  30. package/lib/conversation/SubconversationService/SubconversationService.d.ts.map +1 -1
  31. package/lib/conversation/SubconversationService/SubconversationService.js +158 -11
  32. package/lib/conversation/SubconversationService/SubconversationService.test.js +8 -2
  33. package/lib/conversation/content/AssetContent.d.ts +1 -1
  34. package/lib/conversation/content/AssetContent.d.ts.map +1 -1
  35. package/lib/conversation/content/ButtonActionConfirmationContent.d.ts +1 -1
  36. package/lib/conversation/content/ButtonActionConfirmationContent.d.ts.map +1 -1
  37. package/lib/conversation/content/ButtonActionContent.d.ts +1 -1
  38. package/lib/conversation/content/ButtonActionContent.d.ts.map +1 -1
  39. package/lib/conversation/content/ClearedContent.d.ts +1 -1
  40. package/lib/conversation/content/ClearedContent.d.ts.map +1 -1
  41. package/lib/conversation/content/ClientActionContent.d.ts +1 -1
  42. package/lib/conversation/content/ClientActionContent.d.ts.map +1 -1
  43. package/lib/conversation/content/CompositeContent.d.ts +1 -1
  44. package/lib/conversation/content/CompositeContent.d.ts.map +1 -1
  45. package/lib/conversation/content/ConfirmationContent.d.ts +1 -1
  46. package/lib/conversation/content/ConfirmationContent.d.ts.map +1 -1
  47. package/lib/conversation/content/DeletedContent.d.ts +1 -1
  48. package/lib/conversation/content/DeletedContent.d.ts.map +1 -1
  49. package/lib/conversation/content/HiddenContent.d.ts +1 -1
  50. package/lib/conversation/content/HiddenContent.d.ts.map +1 -1
  51. package/lib/conversation/content/KnockContent.d.ts +1 -1
  52. package/lib/conversation/content/KnockContent.d.ts.map +1 -1
  53. package/lib/conversation/content/LinkPreviewContent.d.ts +1 -1
  54. package/lib/conversation/content/LinkPreviewContent.d.ts.map +1 -1
  55. package/lib/conversation/content/MentionContent.d.ts +1 -1
  56. package/lib/conversation/content/MentionContent.d.ts.map +1 -1
  57. package/lib/conversation/content/MultipartContent.d.ts +1 -1
  58. package/lib/conversation/content/MultipartContent.d.ts.map +1 -1
  59. package/lib/conversation/content/QuoteContent.d.ts +1 -1
  60. package/lib/conversation/content/QuoteContent.d.ts.map +1 -1
  61. package/lib/conversation/content/TweetContent.d.ts +1 -1
  62. package/lib/conversation/content/TweetContent.d.ts.map +1 -1
  63. package/lib/conversation/content/index.d.ts +1 -1
  64. package/lib/conversation/content/index.d.ts.map +1 -1
  65. package/lib/conversation/content/index.js +1 -1
  66. package/lib/conversation/message/MessageBuilder.d.ts +1 -1
  67. package/lib/conversation/message/MessageBuilder.d.ts.map +1 -1
  68. package/lib/conversation/message/MessageBuilder.js +1 -1
  69. package/lib/conversation/message/MessageService.d.ts.map +1 -1
  70. package/lib/conversation/message/MessageService.js +1 -1
  71. package/lib/conversation/message/MessageService.test.js +7 -1
  72. package/lib/conversation/message/MessageToProtoMapper.d.ts +1 -1
  73. package/lib/conversation/message/MessageToProtoMapper.d.ts.map +1 -1
  74. package/lib/conversation/message/MessageToProtoMapper.js +1 -1
  75. package/lib/conversation/message/messageSender.js +2 -2
  76. package/lib/cryptography/AssetCryptography/EncryptedAsset.d.ts +2 -2
  77. package/lib/cryptography/AssetCryptography/EncryptedAsset.d.ts.map +1 -1
  78. package/lib/messagingProtocols/common.types.d.ts +9 -0
  79. package/lib/messagingProtocols/common.types.d.ts.map +1 -1
  80. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIService.types.d.ts +2 -2
  81. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIService.types.d.ts.map +1 -1
  82. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIService.types.js +2 -1
  83. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.d.ts +1 -1
  84. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.d.ts.map +1 -1
  85. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.js +13 -11
  86. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.test.js +21 -16
  87. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.d.ts +9 -3
  88. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.d.ts.map +1 -1
  89. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.js +31 -12
  90. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.d.ts +6 -0
  91. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.d.ts.map +1 -1
  92. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.js +19 -1
  93. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.d.ts +7 -0
  94. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.d.ts.map +1 -0
  95. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.js +48 -0
  96. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/index.d.ts +2 -0
  97. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/{IncomingMessagesQueue → IncomingProposalsQueue}/index.d.ts.map +1 -1
  98. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/{IncomingMessagesQueue → IncomingProposalsQueue}/index.js +1 -1
  99. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.d.ts +0 -1
  100. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.d.ts.map +1 -1
  101. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.js +0 -1
  102. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
  103. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +23 -14
  104. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map +1 -1
  105. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.js +5 -2
  106. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js +13 -3
  107. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.d.ts +38 -2
  108. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.d.ts.map +1 -1
  109. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.js +41 -6
  110. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.d.ts +2 -0
  111. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.d.ts.map +1 -0
  112. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.js +124 -0
  113. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +38 -34
  114. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
  115. package/lib/messagingProtocols/mls/MLSService/MLSService.js +267 -208
  116. package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +157 -160
  117. package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.js +3 -3
  118. package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.test.js +5 -5
  119. package/lib/messagingProtocols/mls/conversationRejoinQueue.js +2 -2
  120. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.d.ts +78 -0
  121. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.d.ts.map +1 -0
  122. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.js +173 -0
  123. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.d.ts +2 -0
  124. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.d.ts.map +1 -0
  125. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.js +117 -0
  126. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.d.ts +167 -0
  127. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.d.ts.map +1 -0
  128. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.js +317 -0
  129. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.d.ts +2 -0
  130. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.d.ts.map +1 -0
  131. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.js +248 -0
  132. package/lib/messagingProtocols/mls/recovery/index.d.ts +5 -0
  133. package/lib/messagingProtocols/mls/recovery/index.d.ts.map +1 -0
  134. package/lib/messagingProtocols/mls/recovery/index.js +28 -0
  135. package/lib/messagingProtocols/mls/types.d.ts +0 -8
  136. package/lib/messagingProtocols/mls/types.d.ts.map +1 -1
  137. package/lib/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.d.ts.map +1 -1
  138. package/lib/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.js +7 -1
  139. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts +8 -15
  140. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts.map +1 -1
  141. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.js +97 -62
  142. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts +0 -6
  143. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts.map +1 -1
  144. package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.d.ts +1 -6
  145. package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.d.ts.map +1 -1
  146. package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.js +19 -22
  147. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +5 -3
  148. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
  149. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +11 -24
  150. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts +1 -0
  151. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts.map +1 -1
  152. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.js +11 -2
  153. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +13 -9
  154. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts +3 -2
  155. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts.map +1 -1
  156. package/lib/messagingProtocols/proteus/ProteusService/WithMockedGenerics.test.js +11 -4
  157. package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.d.ts +0 -4
  158. package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.d.ts.map +1 -1
  159. package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.js +0 -5
  160. package/lib/messagingProtocols/proteus/ProteusService/identityClearer.d.ts +2 -1
  161. package/lib/messagingProtocols/proteus/ProteusService/identityClearer.d.ts.map +1 -1
  162. package/lib/messagingProtocols/proteus/ProteusService/identityClearer.js +8 -2
  163. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +4 -0
  164. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts +1 -1
  165. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts.map +1 -1
  166. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.js +1 -1
  167. package/lib/notification/NotificationService.d.ts +20 -6
  168. package/lib/notification/NotificationService.d.ts.map +1 -1
  169. package/lib/notification/NotificationService.js +23 -14
  170. package/lib/notification/NotificationService.test.js +8 -0
  171. package/lib/secretStore/secretKeyGenerator.d.ts +1 -0
  172. package/lib/secretStore/secretKeyGenerator.d.ts.map +1 -1
  173. package/lib/secretStore/secretKeyGenerator.js +3 -1
  174. package/lib/self/SelfService.d.ts +2 -2
  175. package/lib/self/SelfService.d.ts.map +1 -1
  176. package/lib/self/SelfService.test.js +5 -2
  177. package/lib/team/TeamService.d.ts +5 -2
  178. package/lib/team/TeamService.d.ts.map +1 -1
  179. package/lib/team/TeamService.js +12 -2
  180. package/lib/test/StoreHelper.d.ts +2 -0
  181. package/lib/test/StoreHelper.d.ts.map +1 -0
  182. package/lib/test/StoreHelper.js +27 -0
  183. package/lib/user/UserService.d.ts +2 -2
  184. package/lib/user/UserService.d.ts.map +1 -1
  185. package/lib/user/UserService.js +3 -3
  186. package/lib/util/TypePredicateUtil.d.ts.map +1 -1
  187. package/lib/util/TypePredicateUtil.js +2 -2
  188. package/package.json +5 -5
  189. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.d.ts +0 -4
  190. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.d.ts.map +0 -1
  191. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.js +0 -69
  192. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/index.d.ts +0 -2
  193. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.d.ts +0 -2
  194. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.d.ts.map +0 -1
  195. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.js +0 -98
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2025 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.minimalDefaultPolicies = exports.MlsRecoveryOrchestratorImpl = exports.OperationName = exports.RecoveryActionKind = void 0;
22
+ const commons_1 = require("@wireapp/commons");
23
+ /**
24
+ * Coordinates recovery actions for MLS operations.
25
+ *
26
+ * The orchestrator takes an arbitrary async "operation" (e.g. send, add users, handle welcome),
27
+ * executes it, and on failure maps the thrown error to a DomainMlsError via {@link MlsErrorMapper}.
28
+ * A recovery policy is then resolved and executed exactly-once per unique key, with optional
29
+ * re-run of the original operation after recovery.
30
+ *
31
+ * Key properties:
32
+ * - Single-flight: duplicate recoveries (same action+conversation+group+subconv) are deduplicated.
33
+ * - Per-operation policies: the same DomainMlsError can map to different actions depending on operation.
34
+ * - Non-invasive: the orchestrator has no MLS logic; it calls provided deps to perform actions.
35
+ */
36
+ /**
37
+ * Concrete recovery actions the orchestrator can trigger.
38
+ */
39
+ var RecoveryActionKind;
40
+ (function (RecoveryActionKind) {
41
+ /**
42
+ * Issue an external-commit join for the conversation.
43
+ */
44
+ RecoveryActionKind["JoinViaExternalCommit"] = "JoinViaExternalCommit";
45
+ /**
46
+ * Fetch missing epoch state and reconcile.
47
+ */
48
+ RecoveryActionKind["RecoverFromEpochMismatch"] = "RecoverFromEpochMismatch";
49
+ /**
50
+ * Tear down local MLS state and re-create the group.
51
+ */
52
+ RecoveryActionKind["ResetAndReestablish"] = "ResetAndReestablish";
53
+ /**
54
+ * Add users reported as missing to get the group back in sync.
55
+ */
56
+ RecoveryActionKind["AddMissingUsers"] = "AddMissingUsers";
57
+ /**
58
+ * Remove local MLS artifacts for the group and retry welcome handling.
59
+ */
60
+ RecoveryActionKind["WipeAndReprocessWelcome"] = "WipeAndReprocessWelcome";
61
+ /**
62
+ * No matching policy found; treated as no-op and the original error is re-thrown.
63
+ */
64
+ RecoveryActionKind["Unknown"] = "Unknown";
65
+ })(RecoveryActionKind || (exports.RecoveryActionKind = RecoveryActionKind = {}));
66
+ var OperationName;
67
+ (function (OperationName) {
68
+ OperationName["send"] = "send";
69
+ OperationName["addUsers"] = "addUsers";
70
+ OperationName["removeUsers"] = "removeUsers";
71
+ OperationName["joinExternalCommit"] = "joinExternalCommit";
72
+ OperationName["handleWelcome"] = "handleWelcome";
73
+ OperationName["handleMessageAdd"] = "handleMessageAdd";
74
+ OperationName["keyMaterialUpdate"] = "keyMaterialUpdate";
75
+ })(OperationName || (exports.OperationName = OperationName = {}));
76
+ function isRecoveryPolicy(entry) {
77
+ return 'action' in entry && typeof entry.action === 'string';
78
+ }
79
+ /**
80
+ * Default implementation with in-process deduplication keyed by action and context.
81
+ */
82
+ class MlsRecoveryOrchestratorImpl {
83
+ mapper;
84
+ policies;
85
+ deps;
86
+ inProgressRecoveries;
87
+ logger;
88
+ constructor(mapper, policies, deps, inProgressRecoveries = new Set(), logger = commons_1.LogFactory.getLogger('@wireapp/core/MlsRecoveryOrchestrator')) {
89
+ this.mapper = mapper;
90
+ this.policies = policies;
91
+ this.deps = deps;
92
+ this.inProgressRecoveries = inProgressRecoveries;
93
+ this.logger = logger;
94
+ }
95
+ async execute({ context, callBack, retry = true }) {
96
+ try {
97
+ this.logger.info('Executing MLS operation with recovery orchestration', { context });
98
+ return await callBack();
99
+ }
100
+ catch (rawError) {
101
+ this.logger.info('Operation failed, invoking MLS recovery orchestrator', { rawError });
102
+ const normalizedError = this.mapper.map(rawError, {
103
+ qualifiedConversationId: context.qualifiedConversationId,
104
+ groupId: context.groupId,
105
+ subconvId: context.subconvId,
106
+ });
107
+ this.logger.info(`Mapped error to domain MLS error of type ${normalizedError.type}`, { normalizedError });
108
+ const policy = this.getPolicyFor(normalizedError, context);
109
+ this.logger.info(`Resolved recovery policy: action=${policy.action}`, { policy });
110
+ if (policy.action === 'Unknown' || !retry) {
111
+ this.logger.info('No recovery action configured or retry disabled, re-throwing original error');
112
+ throw rawError;
113
+ }
114
+ const key = this.getRecoveryKey(context, policy.action);
115
+ await this.performRecovery(context, normalizedError, policy, key);
116
+ await this.maybeDelay(policy.retryConfig);
117
+ if (policy.retryConfig.reRunOriginalOperation) {
118
+ this.logger.info(`Re-running original operation after recovery for key ${key}`);
119
+ return this.execute({ context, callBack, retry: false });
120
+ }
121
+ }
122
+ }
123
+ /** Resolve the effective policy for the mapped error and operation. Supports per-operation policies. */
124
+ getPolicyFor = (err, ctx) => {
125
+ const entry = this.policies[err.type];
126
+ if (!entry) {
127
+ return { action: RecoveryActionKind.Unknown, retryConfig: { maxAttempts: 0 } };
128
+ }
129
+ if (isRecoveryPolicy(entry)) {
130
+ return entry;
131
+ }
132
+ const perOperationPolicy = entry;
133
+ return perOperationPolicy[ctx.operationName] ?? { action: RecoveryActionKind.Unknown, retryConfig: { maxAttempts: 0 } };
134
+ };
135
+ /**
136
+ * Execute the concrete recovery action once per unique recovery key. Throws if required context is missing.
137
+ * For WipeAndReprocessWelcome, attempts to derive groupId from either the operation context or error context.
138
+ */
139
+ async performRecovery(context, err, policy, recoveryKey) {
140
+ const id = context.qualifiedConversationId;
141
+ if (!id) {
142
+ const errorMessage = `Missing conversationId for recovery action ${policy.action}`;
143
+ this.logger.error(errorMessage);
144
+ throw new Error(errorMessage);
145
+ }
146
+ switch (policy.action) {
147
+ case 'RecoverFromEpochMismatch': {
148
+ await this.runOnceWithKey(recoveryKey, () => this.deps.recoverFromEpochMismatch(id, context.subconvId));
149
+ break;
150
+ }
151
+ case 'JoinViaExternalCommit': {
152
+ await this.runOnceWithKey(recoveryKey, () => this.deps.joinViaExternalCommit(id));
153
+ break;
154
+ }
155
+ case 'ResetAndReestablish': {
156
+ await this.runOnceWithKey(recoveryKey, () => this.deps.resetAndReestablish(id));
157
+ break;
158
+ }
159
+ case 'AddMissingUsers': {
160
+ const groupId = context.groupId;
161
+ const missing = err.context?.missingUsers;
162
+ if (!missing || missing.length === 0) {
163
+ throw new Error('No missing users reported in error context for AddMissingUsers');
164
+ }
165
+ if (!groupId) {
166
+ throw new Error('Missing groupId for AddMissingUsers');
167
+ }
168
+ await this.runOnceWithKey(recoveryKey, () => this.deps.addMissingUsers(id, groupId, missing));
169
+ break;
170
+ }
171
+ case 'WipeAndReprocessWelcome': {
172
+ // We rely on either the operation context groupId (preferred) or any mapped error context
173
+ const groupId = context.groupId ?? err.context?.groupId;
174
+ if (!groupId) {
175
+ this.logger.warn('Could not determine groupId for WipeAndReprocessWelcome; skipping wipe');
176
+ break;
177
+ }
178
+ await this.runOnceWithKey(recoveryKey, () => this.deps.wipeMLSConversation(groupId));
179
+ break;
180
+ }
181
+ default:
182
+ this.logger.info(`No recovery action taken for action ${policy.action}`);
183
+ break;
184
+ }
185
+ }
186
+ /**
187
+ * Build a stable deduplication key from action and operation context.
188
+ */
189
+ getRecoveryKey(context, action) {
190
+ const conv = context.qualifiedConversationId?.id ?? 'unknownConv';
191
+ const group = context.groupId ?? 'unknownGroup';
192
+ const sub = context.subconvId ?? 'none';
193
+ const key = `${action}:${conv}:${group}:${String(sub)}`;
194
+ this.logger.info(`Generated recovery key: ${key} for action ${action} with context`, { context });
195
+ return key;
196
+ }
197
+ /**
198
+ * Ensure the provided async task runs at most once for the given key at a time.
199
+ */
200
+ runOnceWithKey = async (key, task) => {
201
+ if (this.inProgressRecoveries.has(key)) {
202
+ this.logger.info(`Recovery already in progress for key ${key}, skipping duplicate recovery`);
203
+ return;
204
+ }
205
+ this.logger.info(`Starting recovery for key ${key}`);
206
+ this.inProgressRecoveries.add(key);
207
+ try {
208
+ await task();
209
+ }
210
+ catch (error) {
211
+ this.logger.warn(`Recovery failed for key ${key}`, { error });
212
+ throw error;
213
+ }
214
+ finally {
215
+ this.logger.info(`Completed recovery for key ${key}`);
216
+ this.inProgressRecoveries.delete(key);
217
+ }
218
+ };
219
+ /** Optionally wait before re-invoking the original operation. */
220
+ async maybeDelay(retry) {
221
+ if (retry.delayMs) {
222
+ this.logger.info(`Waiting for ${retry.delayMs}ms before retrying original operation`);
223
+ await this.sleep(retry.delayMs);
224
+ }
225
+ }
226
+ sleep(ms) {
227
+ return new Promise(resolve => setTimeout(resolve, ms));
228
+ }
229
+ }
230
+ exports.MlsRecoveryOrchestratorImpl = MlsRecoveryOrchestratorImpl;
231
+ /**
232
+ * Minimal default policies used by the initial integration. These can be extended over time.
233
+ *
234
+ * Highlights:
235
+ * - WrongEpoch: reconcile and retry for typed ops; do not re-run for join.
236
+ * - GroupNotEstablished: reset and re-establish; typed ops re-run once.
237
+ * - GroupOutOfSync: add missing users and retry for typed ops.
238
+ * - ConversationAlreadyExists (welcome): wipe local MLS state and re-run welcome once.
239
+ * - OrphanWelcome (welcome): attempt join via external commit; do not re-run.
240
+ */
241
+ exports.minimalDefaultPolicies = {
242
+ WrongEpoch: {
243
+ // For join operations, recover from epoch mismatch; do not re-run original op
244
+ joinExternalCommit: {
245
+ action: RecoveryActionKind.RecoverFromEpochMismatch,
246
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: false },
247
+ },
248
+ // For non-join operations, recover from epoch mismatch and retry original once
249
+ send: {
250
+ action: RecoveryActionKind.RecoverFromEpochMismatch,
251
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
252
+ },
253
+ addUsers: {
254
+ action: RecoveryActionKind.RecoverFromEpochMismatch,
255
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
256
+ },
257
+ removeUsers: {
258
+ action: RecoveryActionKind.RecoverFromEpochMismatch,
259
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
260
+ },
261
+ // For inbound message-add processing, fix epoch and allow normal flow to progress (no auto re-run)
262
+ handleMessageAdd: {
263
+ action: RecoveryActionKind.RecoverFromEpochMismatch,
264
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
265
+ },
266
+ keyMaterialUpdate: {
267
+ action: RecoveryActionKind.RecoverFromEpochMismatch,
268
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: false },
269
+ },
270
+ },
271
+ // Use per-operation semantics so typed operations re-run once post-recovery
272
+ GroupNotEstablished: {
273
+ joinExternalCommit: {
274
+ action: RecoveryActionKind.ResetAndReestablish,
275
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: false },
276
+ },
277
+ send: { action: RecoveryActionKind.ResetAndReestablish, retryConfig: { maxAttempts: 1, reRunOriginalOperation: true } },
278
+ addUsers: {
279
+ action: RecoveryActionKind.ResetAndReestablish,
280
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
281
+ },
282
+ removeUsers: {
283
+ action: RecoveryActionKind.ResetAndReestablish,
284
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
285
+ },
286
+ keyMaterialUpdate: {
287
+ action: RecoveryActionKind.ResetAndReestablish,
288
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: false },
289
+ },
290
+ },
291
+ GroupOutOfSync: {
292
+ send: { action: RecoveryActionKind.AddMissingUsers, retryConfig: { maxAttempts: 1, reRunOriginalOperation: true } },
293
+ addUsers: { action: RecoveryActionKind.AddMissingUsers, retryConfig: { maxAttempts: 1, reRunOriginalOperation: true } },
294
+ removeUsers: {
295
+ action: RecoveryActionKind.AddMissingUsers,
296
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
297
+ },
298
+ keyMaterialUpdate: {
299
+ action: RecoveryActionKind.AddMissingUsers,
300
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: false },
301
+ },
302
+ },
303
+ ConversationAlreadyExists: {
304
+ // For welcome handling, wipe local state; do not auto re-run the original callback
305
+ handleWelcome: {
306
+ action: RecoveryActionKind.WipeAndReprocessWelcome,
307
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
308
+ },
309
+ },
310
+ OrphanWelcome: {
311
+ // For orphan welcome, attempt an external commit join; no auto re-run
312
+ handleWelcome: {
313
+ action: RecoveryActionKind.JoinViaExternalCommit,
314
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: false },
315
+ },
316
+ },
317
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MlsRecoveryOrchestrator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MlsRecoveryOrchestrator.test.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2025 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 MlsRecoveryOrchestrator_1 = require("./MlsRecoveryOrchestrator");
23
+ function qid(id = 'conv-1') {
24
+ return { id, domain: 'wire.test' };
25
+ }
26
+ function makeMapperReturning(err) {
27
+ return { map: jest.fn().mockReturnValue(err) };
28
+ }
29
+ describe('MlsRecoveryOrchestrator', () => {
30
+ const baseDeps = () => ({
31
+ joinViaExternalCommit: jest.fn().mockResolvedValue(undefined),
32
+ resetAndReestablish: jest.fn().mockResolvedValue(undefined),
33
+ recoverFromEpochMismatch: jest.fn().mockResolvedValue(undefined),
34
+ addMissingUsers: jest.fn().mockResolvedValue(undefined),
35
+ wipeMLSConversation: jest.fn().mockResolvedValue(undefined),
36
+ });
37
+ it('does nothing when callback succeeds', async () => {
38
+ const deps = baseDeps();
39
+ const mapper = makeMapperReturning({ type: 'Unknown' });
40
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, MlsRecoveryOrchestrator_1.minimalDefaultPolicies, deps);
41
+ const cb = jest.fn().mockResolvedValue('ok');
42
+ const res = await orch.execute({
43
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.send, qualifiedConversationId: qid() },
44
+ callBack: cb,
45
+ });
46
+ expect(res).toBe('ok');
47
+ expect(cb).toHaveBeenCalledTimes(1);
48
+ expect(deps.joinViaExternalCommit).not.toHaveBeenCalled();
49
+ expect(deps.wipeMLSConversation).not.toHaveBeenCalled();
50
+ });
51
+ it('retries original when policy requests reRunOriginalOperation (WrongEpoch/send)', async () => {
52
+ const deps = baseDeps();
53
+ const mapper = makeMapperReturning({ type: 'WrongEpoch' });
54
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, MlsRecoveryOrchestrator_1.minimalDefaultPolicies, deps);
55
+ const cb = jest.fn().mockRejectedValueOnce(new Error('boom')).mockResolvedValueOnce('ok');
56
+ const res = await orch.execute({
57
+ context: {
58
+ operationName: MlsRecoveryOrchestrator_1.OperationName.send,
59
+ qualifiedConversationId: qid(),
60
+ subconvId: conversation_1.SUBCONVERSATION_ID.CONFERENCE,
61
+ },
62
+ callBack: cb,
63
+ });
64
+ expect(deps.recoverFromEpochMismatch).toHaveBeenCalledWith(qid(), conversation_1.SUBCONVERSATION_ID.CONFERENCE);
65
+ expect(cb).toHaveBeenCalledTimes(2);
66
+ expect(res).toBe('ok');
67
+ });
68
+ it('handles JoinViaExternalCommit without re-running original (OrphanWelcome/handleWelcome)', async () => {
69
+ const deps = baseDeps();
70
+ const mapper = makeMapperReturning({ type: 'OrphanWelcome' });
71
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, MlsRecoveryOrchestrator_1.minimalDefaultPolicies, deps);
72
+ const cb = jest.fn().mockRejectedValue(new Error('orphan'));
73
+ const res = await orch.execute({
74
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.handleWelcome, qualifiedConversationId: qid() },
75
+ callBack: cb,
76
+ });
77
+ expect(deps.joinViaExternalCommit).toHaveBeenCalledWith(qid());
78
+ expect(cb).toHaveBeenCalledTimes(1);
79
+ expect(res).toBeUndefined();
80
+ });
81
+ it('wipes group using context groupId when ConversationAlreadyExists and retries once', async () => {
82
+ const deps = baseDeps();
83
+ const mapper = makeMapperReturning({ type: 'ConversationAlreadyExists' });
84
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, MlsRecoveryOrchestrator_1.minimalDefaultPolicies, deps);
85
+ const cb = jest.fn().mockRejectedValueOnce('exists').mockResolvedValueOnce(undefined);
86
+ await orch.execute({
87
+ context: {
88
+ operationName: MlsRecoveryOrchestrator_1.OperationName.handleWelcome,
89
+ qualifiedConversationId: qid(),
90
+ groupId: 'gid-from-context',
91
+ },
92
+ callBack: cb,
93
+ });
94
+ expect(deps.wipeMLSConversation).toHaveBeenCalledTimes(1);
95
+ expect(deps.wipeMLSConversation).toHaveBeenCalledWith('gid-from-context');
96
+ expect(cb).toHaveBeenCalledTimes(2);
97
+ });
98
+ it('wipes group using mapped error groupId when missing in context', async () => {
99
+ const deps = baseDeps();
100
+ const mapper = makeMapperReturning({
101
+ type: 'ConversationAlreadyExists',
102
+ context: { groupId: 'gid-from-error' },
103
+ });
104
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, MlsRecoveryOrchestrator_1.minimalDefaultPolicies, deps);
105
+ const cb = jest.fn().mockRejectedValueOnce('exists').mockResolvedValueOnce(undefined);
106
+ await orch.execute({
107
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.handleWelcome, qualifiedConversationId: qid() },
108
+ callBack: cb,
109
+ });
110
+ expect(deps.wipeMLSConversation).toHaveBeenCalledWith('gid-from-error');
111
+ expect(cb).toHaveBeenCalledTimes(2);
112
+ });
113
+ it('throws if AddMissingUsers missing required inputs', async () => {
114
+ const deps = baseDeps();
115
+ const mapper = makeMapperReturning({ type: 'GroupOutOfSync', context: { missingUsers: [] } });
116
+ const policies = {
117
+ GroupOutOfSync: {
118
+ action: MlsRecoveryOrchestrator_1.RecoveryActionKind.AddMissingUsers,
119
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
120
+ },
121
+ };
122
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, policies, deps);
123
+ const cb = jest.fn().mockRejectedValueOnce('oops');
124
+ await expect(orch.execute({
125
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.send, qualifiedConversationId: qid(), groupId: 'gid' },
126
+ callBack: cb,
127
+ })).rejects.toThrow('No missing users reported in error context for AddMissingUsers');
128
+ });
129
+ it('calls AddMissingUsers with provided missing users and retries', async () => {
130
+ const deps = baseDeps();
131
+ const missing = [qid('u1'), qid('u2')];
132
+ const mapper = makeMapperReturning({ type: 'GroupOutOfSync', context: { missingUsers: missing } });
133
+ const policies = {
134
+ GroupOutOfSync: {
135
+ action: MlsRecoveryOrchestrator_1.RecoveryActionKind.AddMissingUsers,
136
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true },
137
+ },
138
+ };
139
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, policies, deps);
140
+ const cb = jest.fn().mockRejectedValueOnce('oops').mockResolvedValueOnce('ok');
141
+ const res = await orch.execute({
142
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.send, qualifiedConversationId: qid(), groupId: 'gid' },
143
+ callBack: cb,
144
+ });
145
+ expect(deps.addMissingUsers).toHaveBeenCalledWith(qid(), 'gid', missing);
146
+ expect(cb).toHaveBeenCalledTimes(2);
147
+ expect(res).toBe('ok');
148
+ });
149
+ it('rethrows when action is Unknown', async () => {
150
+ const deps = baseDeps();
151
+ const mapper = makeMapperReturning({ type: 'ConversationAlreadyExists' });
152
+ const policies = {
153
+ ConversationAlreadyExists: { action: MlsRecoveryOrchestrator_1.RecoveryActionKind.Unknown, retryConfig: { maxAttempts: 0 } },
154
+ };
155
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, policies, deps);
156
+ const cb = jest.fn().mockRejectedValue(new Error('problem'));
157
+ await expect(orch.execute({
158
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.handleWelcome, qualifiedConversationId: qid() },
159
+ callBack: cb,
160
+ })).rejects.toThrow('problem');
161
+ });
162
+ it('deduplicates concurrent recoveries for the same key', async () => {
163
+ const deps = baseDeps();
164
+ const mapper = makeMapperReturning({ type: 'OrphanWelcome' });
165
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, MlsRecoveryOrchestrator_1.minimalDefaultPolicies, deps);
166
+ // Simulate slow recovery function to keep the window open
167
+ let resolveJoin = () => { };
168
+ const joinPromise = new Promise(resolve => {
169
+ resolveJoin = resolve;
170
+ });
171
+ deps.joinViaExternalCommit.mockImplementation(() => joinPromise);
172
+ const ctx = {
173
+ operationName: MlsRecoveryOrchestrator_1.OperationName.handleWelcome,
174
+ qualifiedConversationId: qid('same'),
175
+ };
176
+ const callBack = () => Promise.reject(new Error('orphan'));
177
+ const p1 = orch.execute({ context: ctx, callBack });
178
+ const p2 = orch.execute({ context: ctx, callBack });
179
+ // Let both catch handlers run and start recovery
180
+ await new Promise(r => setImmediate(r));
181
+ // Release the recovery
182
+ resolveJoin();
183
+ await Promise.all([p1, p2]);
184
+ expect(deps.joinViaExternalCommit).toHaveBeenCalledTimes(1);
185
+ });
186
+ it('waits delayMs before re-running original operation', async () => {
187
+ jest.useFakeTimers({ advanceTimers: true });
188
+ const deps = baseDeps();
189
+ const mapper = makeMapperReturning({ type: 'WrongEpoch' });
190
+ const policies = {
191
+ WrongEpoch: {
192
+ send: {
193
+ action: 'RecoverFromEpochMismatch',
194
+ retryConfig: { maxAttempts: 1, reRunOriginalOperation: true, delayMs: 50 },
195
+ },
196
+ },
197
+ };
198
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, policies, deps);
199
+ const cb = jest.fn().mockRejectedValueOnce(new Error('boom')).mockResolvedValueOnce('ok');
200
+ const runPromise = orch.execute({
201
+ context: {
202
+ operationName: MlsRecoveryOrchestrator_1.OperationName.send,
203
+ qualifiedConversationId: qid(),
204
+ subconvId: conversation_1.SUBCONVERSATION_ID.CONFERENCE,
205
+ },
206
+ callBack: cb,
207
+ });
208
+ // Flush any microtasks from initial rejection handling
209
+ await Promise.resolve();
210
+ expect(cb).toHaveBeenCalledTimes(1);
211
+ expect(deps.recoverFromEpochMismatch).toHaveBeenCalledWith(qid(), conversation_1.SUBCONVERSATION_ID.CONFERENCE);
212
+ // The rerun should not happen until timers advance
213
+ jest.advanceTimersByTime(49);
214
+ await Promise.resolve();
215
+ expect(cb).toHaveBeenCalledTimes(1);
216
+ // Advance past delay and await completion
217
+ jest.advanceTimersByTime(1);
218
+ // Drain queued timers and microtasks
219
+ await Promise.resolve();
220
+ const res = await runPromise;
221
+ expect(cb).toHaveBeenCalledTimes(2);
222
+ expect(res).toBe('ok');
223
+ jest.useRealTimers();
224
+ });
225
+ it('ResetAndReestablish re-runs original for add/remove operations', async () => {
226
+ const deps = baseDeps();
227
+ const mapper = makeMapperReturning({ type: 'GroupNotEstablished' });
228
+ const orch = new MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl(mapper, MlsRecoveryOrchestrator_1.minimalDefaultPolicies, deps);
229
+ // addUsers path
230
+ const cbAdd = jest.fn().mockRejectedValueOnce(new Error('broken')).mockResolvedValueOnce('ok-add');
231
+ const resAdd = await orch.execute({
232
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.addUsers, qualifiedConversationId: qid() },
233
+ callBack: cbAdd,
234
+ });
235
+ expect(deps.resetAndReestablish).toHaveBeenCalledWith(qid());
236
+ expect(cbAdd).toHaveBeenCalledTimes(2);
237
+ expect(resAdd).toBe('ok-add');
238
+ // removeUsers path
239
+ const cbRemove = jest.fn().mockRejectedValueOnce(new Error('broken')).mockResolvedValueOnce('ok-remove');
240
+ const resRemove = await orch.execute({
241
+ context: { operationName: MlsRecoveryOrchestrator_1.OperationName.removeUsers, qualifiedConversationId: qid() },
242
+ callBack: cbRemove,
243
+ });
244
+ expect(deps.resetAndReestablish).toHaveBeenCalledWith(qid());
245
+ expect(cbRemove).toHaveBeenCalledTimes(2);
246
+ expect(resRemove).toBe('ok-remove');
247
+ });
248
+ });
@@ -0,0 +1,5 @@
1
+ export type { DomainMlsError, DomainMlsErrorType, ErrorContextInput, ErrorHandler, MlsErrorMapper, } from './MlsErrorMapper';
2
+ export { ChainedMlsErrorMapper, createDefaultMlsErrorMapper } from './MlsErrorMapper';
3
+ export type { RecoveryActionKind, RetryPolicy, RecoveryPolicy, PolicyTable, OperationContext, MlsRecoveryOrchestrator, OrchestratorDeps, } from './MlsRecoveryOrchestrator';
4
+ export { MlsRecoveryOrchestratorImpl, minimalDefaultPolicies, OperationName } from './MlsRecoveryOrchestrator';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/recovery/index.ts"],"names":[],"mappings":"AAmBA,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,qBAAqB,EAAE,2BAA2B,EAAC,MAAM,kBAAkB,CAAC;AACpF,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,2BAA2B,EAAE,sBAAsB,EAAE,aAAa,EAAC,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2025 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.OperationName = exports.minimalDefaultPolicies = exports.MlsRecoveryOrchestratorImpl = exports.createDefaultMlsErrorMapper = exports.ChainedMlsErrorMapper = void 0;
22
+ var MlsErrorMapper_1 = require("./MlsErrorMapper");
23
+ Object.defineProperty(exports, "ChainedMlsErrorMapper", { enumerable: true, get: function () { return MlsErrorMapper_1.ChainedMlsErrorMapper; } });
24
+ Object.defineProperty(exports, "createDefaultMlsErrorMapper", { enumerable: true, get: function () { return MlsErrorMapper_1.createDefaultMlsErrorMapper; } });
25
+ var MlsRecoveryOrchestrator_1 = require("./MlsRecoveryOrchestrator");
26
+ Object.defineProperty(exports, "MlsRecoveryOrchestratorImpl", { enumerable: true, get: function () { return MlsRecoveryOrchestrator_1.MlsRecoveryOrchestratorImpl; } });
27
+ Object.defineProperty(exports, "minimalDefaultPolicies", { enumerable: true, get: function () { return MlsRecoveryOrchestrator_1.minimalDefaultPolicies; } });
28
+ Object.defineProperty(exports, "OperationName", { enumerable: true, get: function () { return MlsRecoveryOrchestrator_1.OperationName; } });
@@ -20,12 +20,4 @@ export type HandlePendingProposalsParams = {
20
20
  delayInMs: number;
21
21
  eventTime: string;
22
22
  } & CommonMLS;
23
- export interface CoreCryptoConfig {
24
- /**
25
- * path on the public server to the core crypto wasm file.
26
- * This file will be downloaded lazily when corecrypto is needed.
27
- * It, thus, needs to know where, on the server, the file can be found
28
- */
29
- wasmFilePath: string;
30
- }
31
23
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/messagingProtocols/mls/types.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACpD,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,yBAAyB,EAAE,CAAC,cAAc,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACzF;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,SAAS,CAAC;AAEd,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/messagingProtocols/mls/types.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACpD,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,yBAAyB,EAAE,CAAC,cAAc,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACzF;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"otrMessageAdd.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAC,8BAA8B,EAAC,MAAM,+BAA+B,CAAC;AAK7E,OAAO,EAAC,mBAAmB,EAAC,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAEvD,UAAU,yBAAyB;IACjC,KAAK,EAAE,8BAA8B,CAAC;IACtC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,eAAO,MAAM,mBAAmB,+BAG7B,yBAAyB,KAAG,OAAO,CAAC,mBAAmB,CA6BzD,CAAC"}
1
+ {"version":3,"file":"otrMessageAdd.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,8BAA8B,EAAC,MAAM,+BAA+B,CAAC;AAQ7E,OAAO,EAAC,mBAAmB,EAAC,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAEvD,UAAU,yBAAyB;IACjC,KAAK,EAAE,8BAA8B,CAAC;IACtC,cAAc,EAAE,cAAc,CAAC;CAChC;AAID,eAAO,MAAM,mBAAmB,+BAG7B,yBAAyB,KAAG,OAAO,CAAC,mBAAmB,CAgCzD,CAAC"}