@wireapp/core 46.46.6-beta.10.d7a6c4c53 → 46.46.6-beta.14.f6fd03fe6

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 +51 -168
  2. package/lib/Account.d.ts.map +1 -1
  3. package/lib/Account.js +127 -517
  4. package/lib/Account.test.js +147 -158
  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 +3 -4
  11. package/lib/client/ClientService.d.ts.map +1 -1
  12. package/lib/client/ClientService.js +5 -19
  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 +30 -12
  16. package/lib/conversation/AssetService/AssetService.d.ts.map +1 -1
  17. package/lib/conversation/AssetService/AssetService.js +10 -1
  18. package/lib/conversation/AssetService/AssetService.test.js +3 -8
  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 +14 -98
  23. package/lib/conversation/ConversationService/ConversationService.d.ts.map +1 -1
  24. package/lib/conversation/ConversationService/ConversationService.js +101 -314
  25. package/lib/conversation/ConversationService/ConversationService.test.js +47 -441
  26. package/lib/conversation/ConversationService/ConversationService.types.d.ts +4 -5
  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 +3 -6
  30. package/lib/conversation/SubconversationService/SubconversationService.d.ts.map +1 -1
  31. package/lib/conversation/SubconversationService/SubconversationService.js +11 -158
  32. package/lib/conversation/SubconversationService/SubconversationService.test.js +2 -8
  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 +1 -7
  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 +0 -9
  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 +1 -2
  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 +11 -13
  86. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.test.js +16 -21
  87. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.d.ts +3 -9
  88. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.d.ts.map +1 -1
  89. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.js +12 -31
  90. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.d.ts +0 -6
  91. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.d.ts.map +1 -1
  92. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.js +1 -19
  93. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.d.ts +4 -0
  94. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.d.ts.map +1 -0
  95. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.js +69 -0
  96. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/index.d.ts +2 -0
  97. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/{IncomingProposalsQueue → IncomingMessagesQueue}/index.d.ts.map +1 -1
  98. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/{IncomingProposalsQueue → IncomingMessagesQueue}/index.js +1 -1
  99. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.d.ts +1 -0
  100. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.d.ts.map +1 -1
  101. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.js +1 -0
  102. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
  103. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +14 -23
  104. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.d.ts +2 -0
  105. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.d.ts.map +1 -0
  106. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.js +98 -0
  107. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map +1 -1
  108. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.js +2 -5
  109. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js +3 -13
  110. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.d.ts +2 -38
  111. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.d.ts.map +1 -1
  112. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.js +6 -41
  113. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +34 -38
  114. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
  115. package/lib/messagingProtocols/mls/MLSService/MLSService.js +208 -267
  116. package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +160 -157
  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/types.d.ts +8 -0
  121. package/lib/messagingProtocols/mls/types.d.ts.map +1 -1
  122. package/lib/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.d.ts.map +1 -1
  123. package/lib/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.js +1 -7
  124. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts +15 -8
  125. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts.map +1 -1
  126. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.js +62 -97
  127. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts +6 -0
  128. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts.map +1 -1
  129. package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.d.ts +6 -1
  130. package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.d.ts.map +1 -1
  131. package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.js +22 -19
  132. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +3 -5
  133. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
  134. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +24 -11
  135. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts +0 -1
  136. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts.map +1 -1
  137. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.js +2 -11
  138. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +9 -13
  139. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts +2 -3
  140. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts.map +1 -1
  141. package/lib/messagingProtocols/proteus/ProteusService/WithMockedGenerics.test.js +4 -11
  142. package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.d.ts +4 -0
  143. package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.d.ts.map +1 -1
  144. package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.js +5 -0
  145. package/lib/messagingProtocols/proteus/ProteusService/identityClearer.d.ts +1 -2
  146. package/lib/messagingProtocols/proteus/ProteusService/identityClearer.d.ts.map +1 -1
  147. package/lib/messagingProtocols/proteus/ProteusService/identityClearer.js +2 -8
  148. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +0 -4
  149. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts +1 -1
  150. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts.map +1 -1
  151. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.js +1 -1
  152. package/lib/notification/NotificationService.d.ts +6 -20
  153. package/lib/notification/NotificationService.d.ts.map +1 -1
  154. package/lib/notification/NotificationService.js +14 -23
  155. package/lib/notification/NotificationService.test.js +0 -8
  156. package/lib/secretStore/secretKeyGenerator.d.ts +0 -1
  157. package/lib/secretStore/secretKeyGenerator.d.ts.map +1 -1
  158. package/lib/secretStore/secretKeyGenerator.js +1 -3
  159. package/lib/self/SelfService.d.ts +2 -2
  160. package/lib/self/SelfService.d.ts.map +1 -1
  161. package/lib/self/SelfService.test.js +2 -5
  162. package/lib/team/TeamService.d.ts +2 -5
  163. package/lib/team/TeamService.d.ts.map +1 -1
  164. package/lib/team/TeamService.js +2 -12
  165. package/lib/user/UserService.d.ts +2 -2
  166. package/lib/user/UserService.d.ts.map +1 -1
  167. package/lib/user/UserService.js +3 -3
  168. package/lib/util/TypePredicateUtil.d.ts.map +1 -1
  169. package/lib/util/TypePredicateUtil.js +2 -2
  170. package/package.json +3 -3
  171. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.d.ts +0 -7
  172. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.d.ts.map +0 -1
  173. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.js +0 -48
  174. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/index.d.ts +0 -2
  175. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.d.ts +0 -2
  176. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.d.ts.map +0 -1
  177. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.js +0 -124
  178. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.d.ts +0 -78
  179. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.d.ts.map +0 -1
  180. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.js +0 -173
  181. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.d.ts +0 -2
  182. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.d.ts.map +0 -1
  183. package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.js +0 -117
  184. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.d.ts +0 -167
  185. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.d.ts.map +0 -1
  186. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.js +0 -317
  187. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.d.ts +0 -2
  188. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.d.ts.map +0 -1
  189. package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.js +0 -248
  190. package/lib/messagingProtocols/mls/recovery/index.d.ts +0 -5
  191. package/lib/messagingProtocols/mls/recovery/index.d.ts.map +0 -1
  192. package/lib/messagingProtocols/mls/recovery/index.js +0 -28
  193. package/lib/test/StoreHelper.d.ts +0 -2
  194. package/lib/test/StoreHelper.d.ts.map +0 -1
  195. package/lib/test/StoreHelper.js +0 -27
package/lib/Account.js CHANGED
@@ -41,18 +41,16 @@ var __importStar = (this && this.__importStar) || function (mod) {
41
41
  return result;
42
42
  };
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.Account = exports.AccountLocalStorageStore = exports.EVENTS = exports.ConnectionState = void 0;
44
+ exports.Account = exports.ConnectionState = exports.EVENTS = void 0;
45
45
  const auth_1 = require("@wireapp/api-client/lib/auth");
46
46
  const client_1 = require("@wireapp/api-client/lib/client/");
47
47
  const event_1 = require("@wireapp/api-client/lib/event");
48
- const ConsumableNotification_1 = require("@wireapp/api-client/lib/notification/ConsumableNotification");
49
48
  const tcp_1 = require("@wireapp/api-client/lib/tcp/");
50
49
  const ReconnectingWebsocket_1 = require("@wireapp/api-client/lib/tcp/ReconnectingWebsocket");
51
50
  const team_1 = require("@wireapp/api-client/lib/team");
52
51
  const TimeUtil_1 = require("@wireapp/commons/lib/util/TimeUtil");
53
52
  const api_client_1 = require("@wireapp/api-client");
54
53
  const commons_1 = require("@wireapp/commons");
55
- const promise_queue_1 = require("@wireapp/promise-queue");
56
54
  const store_engine_1 = require("@wireapp/store-engine");
57
55
  const account_1 = require("./account/");
58
56
  const auth_2 = require("./auth/");
@@ -67,11 +65,8 @@ const linkPreview_1 = require("./linkPreview");
67
65
  const mls_1 = require("./messagingProtocols/mls");
68
66
  const conversationRejoinQueue_1 = require("./messagingProtocols/mls/conversationRejoinQueue");
69
67
  const E2EIdentityService_1 = require("./messagingProtocols/mls/E2EIdentityService");
70
- const IncomingProposalsQueue_1 = require("./messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue");
71
68
  const proteus_1 = require("./messagingProtocols/proteus");
72
69
  const CryptoClient_1 = require("./messagingProtocols/proteus/ProteusService/CryptoClient");
73
- const CoreCryptoWrapper_1 = require("./messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper");
74
- const identityClearer_1 = require("./messagingProtocols/proteus/ProteusService/identityClearer");
75
70
  const notification_1 = require("./notification/");
76
71
  const encryptedStore_1 = require("./secretStore/encryptedStore");
77
72
  const secretKeyGenerator_1 = require("./secretStore/secretKeyGenerator");
@@ -79,17 +74,24 @@ const self_1 = require("./self/");
79
74
  const CoreDB_1 = require("./storage/CoreDB");
80
75
  const team_2 = require("./team/");
81
76
  const user_1 = require("./user/");
82
- const LocalStorageStore_1 = require("./util/LocalStorageStore");
83
77
  const RecurringTaskScheduler_1 = require("./util/RecurringTaskScheduler");
78
+ var EVENTS;
79
+ (function (EVENTS) {
80
+ /**
81
+ * event triggered when a message from an unknown client is received.
82
+ * An unknown client is a client we don't yet have a session with
83
+ */
84
+ EVENTS["NEW_SESSION"] = "new_session";
85
+ })(EVENTS || (exports.EVENTS = EVENTS = {}));
84
86
  var ConnectionState;
85
87
  (function (ConnectionState) {
86
- /** The WebSocket is closed and no notifications are being processed */
88
+ /** The websocket is closed and notifications stream is not being processed */
87
89
  ConnectionState["CLOSED"] = "closed";
88
- /** The WebSocket is being opened or reconnected */
90
+ /** The websocket is being opened */
89
91
  ConnectionState["CONNECTING"] = "connecting";
90
92
  /** The websocket is open but locked and notifications stream is being processed */
91
93
  ConnectionState["PROCESSING_NOTIFICATIONS"] = "processing_notifications";
92
- /** The WebSocket is open and new messages are processed live in real time */
94
+ /** The websocket is open and message will go through and notifications stream is fully processed */
93
95
  ConnectionState["LIVE"] = "live";
94
96
  })(ConnectionState || (exports.ConnectionState = ConnectionState = {}));
95
97
  const coreDefaultClient = {
@@ -97,31 +99,17 @@ const coreDefaultClient = {
97
99
  cookieLabel: 'default',
98
100
  model: '@wireapp/core',
99
101
  };
100
- var EVENTS;
101
- (function (EVENTS) {
102
- /**
103
- * event triggered when a message from an unknown client is received.
104
- * An unknown client is a client we don't yet have a session with
105
- */
106
- EVENTS["NEW_SESSION"] = "new_session";
107
- })(EVENTS || (exports.EVENTS = EVENTS = {}));
108
- exports.AccountLocalStorageStore = (0, LocalStorageStore_1.LocalStorageStore)('core_account');
109
102
  class Account extends commons_1.TypedEventEmitter {
110
103
  options;
111
104
  apiClient;
112
105
  logger;
106
+ coreCryptoConfig;
113
107
  /** this is the client the consumer is currently using. Will be set as soon as `initClient` is called and will be rest upon logout */
114
108
  currentClient;
115
109
  storeEngine;
116
110
  db;
117
111
  encryptedDb;
118
112
  coreCallbacks;
119
- connectionState = ConnectionState.CLOSED;
120
- notificationProcessingQueue = new promise_queue_1.PromiseQueue({
121
- name: 'notification-processing-queue',
122
- paused: true,
123
- });
124
- setMaxCoreCryptoLogLevel = () => undefined;
125
113
  service;
126
114
  backendFeatures;
127
115
  recurringTaskScheduler;
@@ -129,14 +117,12 @@ class Account extends commons_1.TypedEventEmitter {
129
117
  * @param apiClient The apiClient instance to use in the core (will create a new new one if undefined)
130
118
  * @param accountOptions
131
119
  */
132
- constructor(apiClient = new api_client_1.APIClient(), options = {
133
- nbPrekeys: 100,
134
- coreCryptoConfig: { wasmFilePath: '', enabled: false },
135
- }) {
120
+ constructor(apiClient = new api_client_1.APIClient(), options = { nbPrekeys: 100 }) {
136
121
  super();
137
122
  this.options = options;
138
123
  this.apiClient = apiClient;
139
124
  this.backendFeatures = this.apiClient.backendFeatures;
125
+ this.coreCryptoConfig = options.coreCryptoConfig;
140
126
  this.recurringTaskScheduler = new RecurringTaskScheduler_1.RecurringTaskScheduler({
141
127
  get: async (key) => {
142
128
  const task = await this.db?.get('recurringTasks', key);
@@ -155,7 +141,7 @@ class Account extends commons_1.TypedEventEmitter {
155
141
  await this.persistCookie(this.storeEngine, cookie);
156
142
  }
157
143
  catch (error) {
158
- this.logger.error('Failed to save cookie:', error);
144
+ this.logger.error(`Failed to save cookie: ${error.message}`, error);
159
145
  }
160
146
  }
161
147
  });
@@ -173,16 +159,16 @@ class Account extends commons_1.TypedEventEmitter {
173
159
  * - useVersion(0, 1, true) > version 1 is used
174
160
  * @return The highest version that is both supported by client and backend
175
161
  */
176
- useAPIVersion = async (min, max, allowDev) => {
162
+ async useAPIVersion(min, max, allowDev) {
177
163
  const features = await this.apiClient.useVersion(min, max, allowDev);
178
164
  this.backendFeatures = features;
179
165
  return features;
180
- };
181
- persistCookie = (storeEngine, cookie) => {
166
+ }
167
+ persistCookie(storeEngine, cookie) {
182
168
  const entity = { expiration: cookie.expiration, zuid: cookie.zuid };
183
169
  return storeEngine.updateOrCreate(auth_1.AUTH_TABLE_NAME, auth_1.AUTH_COOKIE_KEY, entity);
184
- };
185
- enrollE2EI = async ({ displayName, handle, teamId, discoveryUrl, getOAuthToken, getAllConversations, certificateTtl = 90 * (TimeUtil_1.TimeInMillis.DAY / 1000), }) => {
170
+ }
171
+ async enrollE2EI({ displayName, handle, teamId, discoveryUrl, getOAuthToken, certificateTtl = 90 * (TimeUtil_1.TimeInMillis.DAY / 1000), }) {
186
172
  const context = this.apiClient.context;
187
173
  const domain = context?.domain ?? '';
188
174
  if (!this.currentClient) {
@@ -198,8 +184,8 @@ class Account extends commons_1.TypedEventEmitter {
198
184
  teamId,
199
185
  id: this.userId,
200
186
  };
201
- return this.service.mls.enrollE2EI(discoveryUrl, user, this.currentClient, this.options.nbPrekeys, certificateTtl, getOAuthToken, getAllConversations);
202
- };
187
+ return this.service.mls.enrollE2EI(discoveryUrl, user, this.currentClient, this.options.nbPrekeys, certificateTtl, getOAuthToken);
188
+ }
203
189
  get clientId() {
204
190
  return this.apiClient.validatedClientId;
205
191
  }
@@ -212,57 +198,52 @@ class Account extends commons_1.TypedEventEmitter {
212
198
  * @param registration The user's data
213
199
  * @param clientType Type of client to create (temporary or permanent)
214
200
  */
215
- register = async (registration, clientType) => {
201
+ async register(registration, clientType) {
216
202
  const context = await this.apiClient.register(registration, clientType);
217
203
  await this.initServices(context);
218
204
  return context;
219
- };
205
+ }
220
206
  /**
221
207
  * Will init the core with an already logged in user
222
208
  *
223
209
  * @param clientType The type of client the user is using (temporary or permanent)
224
210
  */
225
- init = async (clientType, { cookie } = {}) => {
211
+ async init(clientType, { cookie } = {}) {
226
212
  const context = await this.apiClient.init(clientType, cookie);
227
213
  await this.initServices(context);
228
214
  return context;
229
- };
215
+ }
230
216
  /**
231
217
  * Will log the user in with the given credential.
232
218
  *
233
219
  * @param loginData The credentials of the user
234
220
  * @param clientInfo Info about the client to create (name, type...)
235
221
  */
236
- login = async (loginData) => {
222
+ async login(loginData) {
237
223
  this.resetContext();
238
224
  auth_2.LoginSanitizer.removeNonPrintableCharacters(loginData);
239
225
  const context = await this.apiClient.login(loginData);
240
226
  await this.initServices(context);
241
227
  return context;
242
- };
228
+ }
243
229
  /**
244
230
  * Will register a new client for the current user
245
231
  */
246
- registerClient = async (loginData, useLegacyNotificationStream,
232
+ async registerClient(loginData, clientInfo = coreDefaultClient,
247
233
  /** will add extra manual entropy to the client's identity being created */
248
- entropyData, clientInfo = coreDefaultClient) => {
234
+ entropyData) {
249
235
  if (!this.service || !this.apiClient.context || !this.storeEngine) {
250
236
  throw new Error('Services are not set or context not initialized.');
251
237
  }
252
- if (typeof useLegacyNotificationStream !== 'boolean') {
253
- throw new Error('use of legacy notifications must be explicitly set to true or false');
254
- }
255
238
  // we reset the services to re-instantiate a new CryptoClient instance
256
239
  await this.initServices(this.apiClient.context);
257
240
  const initialPreKeys = await this.service.proteus.createClient(entropyData);
258
- const client = await this.service.client.register(loginData, clientInfo, initialPreKeys, useLegacyNotificationStream);
241
+ const client = await this.service.client.register(loginData, clientInfo, initialPreKeys);
259
242
  const clientId = client.id;
260
- if (useLegacyNotificationStream) {
261
- await this.service.notification.legacyInitializeNotificationStream(clientId);
262
- }
243
+ await this.service.notification.initializeNotificationStream(clientId);
263
244
  await this.service.client.synchronizeClients(clientId);
264
245
  return client;
265
- };
246
+ }
266
247
  getLocalClient() {
267
248
  return this.service?.client.loadClient();
268
249
  }
@@ -271,14 +252,14 @@ class Account extends commons_1.TypedEventEmitter {
271
252
  *
272
253
  * @returns The local existing client or undefined if the client does not exist or is not valid (non existing on backend)
273
254
  */
274
- initClient = async (client, mlsConfig) => {
255
+ async initClient(client, mlsConfig) {
275
256
  if (!this.service || !this.apiClient.context || !this.storeEngine) {
276
257
  throw new Error('Services are not set.');
277
258
  }
278
259
  this.apiClient.context.clientId = client.id;
279
260
  // Call /access endpoint with client_id after client initialisation
280
261
  await this.apiClient.transport.http.associateClientWithSession(client.id);
281
- await this.service.proteus.initClient(this.apiClient.context);
262
+ await this.service.proteus.initClient(this.storeEngine, this.apiClient.context);
282
263
  if ((await this.isMLSActiveForClient()) && this.service.mls && mlsConfig) {
283
264
  const { userId, domain = '' } = this.apiClient.context;
284
265
  await this.service.mls.initClient({ id: userId, domain }, client, mlsConfig);
@@ -291,8 +272,8 @@ class Account extends commons_1.TypedEventEmitter {
291
272
  }
292
273
  this.currentClient = client;
293
274
  return client;
294
- };
295
- buildCryptoClient = async (context, storeEngine, encryptedStore) => {
275
+ }
276
+ async buildCryptoClient(context, storeEngine, encryptedStore) {
296
277
  const baseConfig = {
297
278
  nbPrekeys: this.options.nbPrekeys,
298
279
  onNewPrekeys: async (prekeys) => {
@@ -301,19 +282,20 @@ class Account extends commons_1.TypedEventEmitter {
301
282
  this.logger.debug(`Successfully uploaded '${prekeys.length}' PreKeys.`);
302
283
  },
303
284
  };
304
- if (this.options.coreCryptoConfig?.enabled) {
285
+ const coreCryptoConfig = this.coreCryptoConfig;
286
+ if (coreCryptoConfig) {
305
287
  const { buildClient } = await Promise.resolve().then(() => __importStar(require('./messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper')));
306
288
  const client = await buildClient(storeEngine, {
307
289
  ...baseConfig,
308
- generateSecretKey: (keyId, keySize) => (0, secretKeyGenerator_1.generateSecretKey)({ keyId, keySize, secretsDb: encryptedStore }),
309
- }, this.options.coreCryptoConfig);
310
- this.setMaxCoreCryptoLogLevel = client.setMaxLogLevel;
290
+ ...coreCryptoConfig,
291
+ generateSecretKey: keyId => (0, secretKeyGenerator_1.generateSecretKey)({ keyId, keySize: 16, secretsDb: encryptedStore }),
292
+ });
311
293
  return [CryptoClient_1.CryptoClientType.CORE_CRYPTO, client];
312
294
  }
313
295
  const { buildClient } = await Promise.resolve().then(() => __importStar(require('./messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper')));
314
296
  const client = buildClient(storeEngine, baseConfig);
315
297
  return [CryptoClient_1.CryptoClientType.CRYPTOBOX, client];
316
- };
298
+ }
317
299
  /**
318
300
  * In order to be able to send MLS messages, the core needs a few information from the consumer.
319
301
  * Namely:
@@ -321,10 +303,10 @@ class Account extends commons_1.TypedEventEmitter {
321
303
  * - what is the groupId of a conversation
322
304
  * @param coreCallbacks
323
305
  */
324
- configureCoreCallbacks = (coreCallbacks) => {
306
+ configureCoreCallbacks(coreCallbacks) {
325
307
  this.coreCallbacks = coreCallbacks;
326
- };
327
- initServices = async (context) => {
308
+ }
309
+ async initServices(context) {
328
310
  const encryptedStoreName = this.generateEncryptedDbName(context);
329
311
  this.encryptedDb = this.options.systemCrypto
330
312
  ? await (0, encryptedStore_1.createCustomEncryptedStore)(encryptedStoreName, this.options.systemCrypto)
@@ -340,7 +322,7 @@ class Account extends commons_1.TypedEventEmitter {
340
322
  const proteusService = new proteus_1.ProteusService(this.apiClient, cryptoClient, {
341
323
  onNewClient: payload => this.emit(EVENTS.NEW_SESSION, payload),
342
324
  nbPrekeys: this.options.nbPrekeys,
343
- }, this.storeEngine);
325
+ });
344
326
  const clientService = new client_2.ClientService(this.apiClient, proteusService, this.storeEngine);
345
327
  if (clientType === CryptoClient_1.CryptoClientType.CORE_CRYPTO && (await this.apiClient.supportsMLS())) {
346
328
  mlsService = new mls_1.MLSService(this.apiClient, cryptoClient.getNativeClient(), this.db, this.recurringTaskScheduler);
@@ -350,7 +332,7 @@ class Account extends commons_1.TypedEventEmitter {
350
332
  const giphyService = new giphy_1.GiphyService(this.apiClient);
351
333
  const linkPreviewService = new linkPreview_1.LinkPreviewService(assetService);
352
334
  const subconversationService = new SubconversationService_1.SubconversationService(this.apiClient, this.db, mlsService);
353
- const conversationService = new conversation_1.ConversationService(this.apiClient, proteusService, this.db, this.groupIdFromConversationId, subconversationService, this.isMLSConversationRecoveryEnabled, mlsService);
335
+ const conversationService = new conversation_1.ConversationService(this.apiClient, proteusService, this.db, this.groupIdFromConversationId, subconversationService, mlsService);
354
336
  const notificationService = new notification_1.NotificationService(this.apiClient, this.storeEngine, conversationService);
355
337
  const selfService = new self_1.SelfService(this.apiClient);
356
338
  const teamService = new team_2.TeamService(this.apiClient);
@@ -374,88 +356,35 @@ class Account extends commons_1.TypedEventEmitter {
374
356
  team: teamService,
375
357
  user: userService,
376
358
  };
377
- };
378
- resetContext = () => {
359
+ }
360
+ resetContext() {
379
361
  this.currentClient = undefined;
380
362
  delete this.apiClient.context;
381
363
  delete this.service;
382
- };
364
+ }
383
365
  /**
384
366
  * Will logout the current user
385
367
  * @param clearData if set to `true` will completely wipe any database that was created by the Account
386
368
  */
387
- logout = async (data) => {
369
+ async logout(clearData = false) {
388
370
  this.db?.close();
389
371
  this.encryptedDb?.close();
390
- if (data?.clearAllData) {
391
- await this.wipeAllData();
392
- }
393
- else if (data?.clearCryptoData) {
394
- await this.wipeCryptoData();
372
+ if (clearData) {
373
+ await this.wipe();
395
374
  }
396
375
  await this.apiClient.logout();
397
376
  this.resetContext();
398
- };
399
- wipeCommonData = async () => {
400
- try {
401
- await this.service?.client.deleteLocalClient();
402
- }
403
- catch (error) {
404
- this.logger.error('Failed to delete local client during logout cleanup:', error);
405
- }
406
- try {
407
- if (this.storeEngine) {
408
- await (0, CoreCryptoWrapper_1.wipeCoreCryptoDb)(this.storeEngine);
409
- }
410
- }
411
- catch (error) {
412
- this.logger.error('Failed to wipe crypto database during logout cleanup:', error);
413
- }
414
- try {
415
- // needs to be wiped last
416
- await this.encryptedDb?.wipe();
417
- }
418
- catch (error) {
419
- this.logger.error('Failed to delete encrypted database during logout cleanup:', error);
420
- }
421
- };
422
- /**
423
- * Will delete the identity and history of the current user
424
- */
425
- wipeAllData = async () => {
426
- try {
427
- if (this.storeEngine) {
428
- await (0, identityClearer_1.deleteIdentity)(this.storeEngine, false);
429
- }
430
- }
431
- catch (error) {
432
- this.logger.error('Failed to delete identity during logout cleanup:', error);
433
- }
434
- try {
435
- if (this.db) {
436
- await (0, CoreDB_1.deleteDB)(this.db);
437
- }
438
- }
439
- catch (error) {
440
- this.logger.error('Failed to delete database during logout cleanup:', error);
441
- }
442
- await this.wipeCommonData();
443
- };
377
+ }
444
378
  /**
445
- * Will delete the cryptography and client of the current user
446
- * Will keep the history intact
379
+ * Will delete the identity of the current user
447
380
  */
448
- wipeCryptoData = async () => {
449
- try {
450
- if (this.storeEngine) {
451
- await (0, identityClearer_1.deleteIdentity)(this.storeEngine, true);
452
- }
453
- }
454
- catch (error) {
455
- this.logger.error('Failed to delete identity during logout cleanup:', error);
381
+ async wipe() {
382
+ await this.service?.proteus.wipe(this.storeEngine);
383
+ if (this.db) {
384
+ await (0, CoreDB_1.deleteDB)(this.db);
456
385
  }
457
- await this.wipeCommonData();
458
- };
386
+ await this.encryptedDb?.wipe();
387
+ }
459
388
  /**
460
389
  * return true if the current user has a MLS device that is initialized and ready to use
461
390
  */
@@ -469,105 +398,11 @@ class Account extends commons_1.TypedEventEmitter {
469
398
  * @param callbacks callbacks that will be called to handle different events
470
399
  * @returns close a function that will disconnect from the websocket
471
400
  */
472
- listen = async ({ useLegacy, onEvent = async () => { }, onConnectionStateChanged: onConnectionStateChangedCallBack = () => { }, onNotificationStreamProgress = () => { }, onMissedNotifications = () => { }, } = {}) => {
401
+ listen({ onEvent = () => { }, onConnectionStateChanged = () => { }, onNotificationStreamProgress = () => { }, onMissedNotifications = () => { }, dryRun = false, } = {}) {
473
402
  if (!this.currentClient) {
474
403
  throw new Error('Client has not been initialized - please login first');
475
404
  }
476
- if (typeof useLegacy !== 'boolean') {
477
- throw new Error('use of legacy notifications must be explicitly set to true or false');
478
- }
479
- const onConnectionStateChanged = this.createConnectionStateChangedHandler(onConnectionStateChangedCallBack);
480
- const handleEvent = this.createEventHandler(onEvent);
481
- const handleLegacyNotification = this.createLegacyNotificationHandler(handleEvent, onNotificationStreamProgress);
482
- const handleNotification = this.createNotificationHandler(handleEvent, onNotificationStreamProgress, onConnectionStateChanged);
483
- const handleMissedNotifications = this.createLegacyMissedNotificationsHandler(onMissedNotifications);
484
- const legacyProcessNotificationStream = this.createLegacyNotificationStreamProcessor({
485
- handleLegacyNotification,
486
- handleMissedNotifications,
487
- onConnectionStateChanged,
488
- });
489
- this.setupWebSocketListeners(onConnectionStateChanged, handleNotification, handleLegacyNotification, useLegacy);
490
- const isClientCapableOfConsumableNotifications = this.getClientCapabilities().includes(client_1.ClientCapability.CONSUMABLE_NOTIFICATIONS);
491
- const capabilities = [client_1.ClientCapability.LEGAL_HOLD_IMPLICIT_CONSENT];
492
- if (!useLegacy) {
493
- // let the backend now client is capable of consumable notifications
494
- capabilities.push(client_1.ClientCapability.CONSUMABLE_NOTIFICATIONS);
495
- this.apiClient.transport.ws.useAsyncNotificationsSocket();
496
- }
497
- this.logger.info(`Client is using the ${useLegacy ? 'legacy' : 'async'} notification stream`);
498
- await this.service?.client.putClientCapabilities(this.currentClient.id, { capabilities });
499
- /*
500
- * When enabling async notifications, be aware that the backend maintains a separate queue
501
- * for new async notifications (/events weboscket endpoint), which only starts populating *after* the client declares support
502
- * for async notifications.
503
- *
504
- * Therefore, after declaring support, it's necessary to perform one final fetch from the legacy
505
- * system to ensure no notifications are missed—since older notifications won't
506
- * appear in the new queue.
507
- *
508
- * These two systems are separate, and the transition timing
509
- * is important to avoid missing any messages during the switch.
510
- *
511
- * @todo This can be removed when all clients are capable of consumable notifications.
512
- */
513
- if (!isClientCapableOfConsumableNotifications && !useLegacy) {
514
- // do the last legacy sync without connecting to any websockets
515
- await legacyProcessNotificationStream();
516
- this.logger.info('Completed final legacy notification stream processing after enabling async notifications');
517
- }
518
- if (useLegacy) {
519
- /**
520
- * immediately lock the websocket to prevent any new messages from being received
521
- * before legacy notifications endpoint is fetched otherwise it'll update the last notification ID
522
- * and fetching legacy notifications will return an empty list
523
- */
524
- this.apiClient.transport.ws.lock();
525
- }
526
- this.apiClient.connect(async (abortController) => {
527
- // this call back is called every single time the websocket connection is (re)established
528
- this.logger.info('Connection established with websocket, starting notification stream processing');
529
- /**
530
- * This is to avoid passing proposals too early to core crypto
531
- * @See WPB-18995
532
- */
533
- (0, IncomingProposalsQueue_1.pauseProposalProcessing)();
534
- (0, messageSender_1.pauseMessageSending)(); // pause message sending while processing notifications, it will be resumed once the processing is done and we have the marker token
535
- (0, conversationRejoinQueue_1.pauseRejoiningMLSConversations)(); // We want to avoid triggering rejoins of out-of-sync MLS conversations while we are processing the notification stream
536
- /**
537
- * resume the notification processing queue
538
- * it will start processing notifications immediately and pause if web socket connection drops
539
- * we should start decryption and therefore acknowledging the notifications in order for the backend to
540
- * send us the next batch of notifications, currently total size of notifications coming from web socket is limited to 500
541
- * so we need to acknowledge the notifications to let the backend know we are ready for the next batch
542
- */
543
- this.notificationProcessingQueue.resume();
544
- if (useLegacy) {
545
- await legacyProcessNotificationStream(abortController);
546
- }
547
- });
548
- return () => {
549
- this.logger.info('Disconnecting from backend as requested by consumer');
550
- (0, IncomingProposalsQueue_1.flushProposalsQueue)();
551
- this.pauseAndFlushNotificationQueue();
552
- this.apiClient.disconnect();
553
- onConnectionStateChanged(ConnectionState.CLOSED);
554
- this.apiClient.transport.ws.removeAllListeners();
555
- };
556
- };
557
- createConnectionStateChangedHandler = (onConnectionStateChanged) => {
558
- return (state) => {
559
- this.connectionState = state;
560
- onConnectionStateChanged(state);
561
- this.logger.info(`Connection state changed to: ${state}`);
562
- };
563
- };
564
- /**
565
- * Creates the event handler that is invoked for each decrypted event from the backend.
566
- * Responsible for handling specific event types like `MESSAGE_TIMER_UPDATE`, and then
567
- * forwarding the event to the consumer via the `onEvent` callback.
568
- */
569
- createEventHandler = (onEvent) => {
570
- return async (payload, source) => {
405
+ const handleEvent = async (payload, source) => {
571
406
  const { event } = payload;
572
407
  switch (event?.type) {
573
408
  case event_1.CONVERSATION_EVENT.MESSAGE_TIMER_UPDATE: {
@@ -577,290 +412,80 @@ class Account extends commons_1.TypedEventEmitter {
577
412
  break;
578
413
  }
579
414
  }
580
- // Always forward the event to the consumer
581
415
  await onEvent(payload, source);
582
416
  };
583
- };
584
- /**
585
- * @deprecated This method is used to handle legacy notifications from the backend.
586
- * It processes notifications from the legacy system, decrypts them, and emits events.
587
- * It can be replaced with the new notification handling system using `ConsumableNotification`
588
- * when all clients are capable of handling consumable notifications.
589
- */
590
- createLegacyNotificationHandler = (handleEvent, onNotificationStreamProgress) => {
591
- return async (notification, source) => {
592
- void this.notificationProcessingQueue
593
- .push(async () => {
594
- try {
595
- const start = Date.now();
596
- const notificationTime = this.getNotificationEventTime(notification.payload[0]);
597
- this.logger.info(`Processing legacy notification "${notification.id}" at ${notificationTime}`, {
598
- notification,
599
- });
600
- this.logger.info(`Total notifications queue length: ${this.notificationProcessingQueue.getLength()}`);
601
- this.logger.info(`Total pending proposals queue length: ${(0, IncomingProposalsQueue_1.getProposalQueueLength)()}`);
602
- if (notificationTime) {
603
- onNotificationStreamProgress(notificationTime);
604
- }
605
- const messages = this.service.notification.handleNotification(notification, source);
606
- for await (const message of messages) {
607
- await handleEvent(message, source);
608
- }
609
- this.logger.info(`Finished processing legacy notification "${notification.id}" in ${Date.now() - start}ms`);
610
- }
611
- catch (error) {
612
- this.logger.error(`Failed to handle legacy notification "${notification.id}": ${error.message}`, error);
613
- }
614
- })
615
- .catch(this.handleNotificationQueueError);
616
- };
617
- };
618
- createNotificationHandler = (handleEvent, onNotificationStreamProgress, onConnectionStateChanged) => {
619
- return async (notification, source) => {
620
- this.logger.info(`Received consumable notification of type "${notification.type}"`, { notification });
417
+ const handleNotification = async (notification, source) => {
621
418
  try {
622
- if (notification.type === ConsumableNotification_1.ConsumableEvent.MISSED) {
623
- this.reactToMissedNotification();
624
- return;
625
- }
626
- if (notification.type === ConsumableNotification_1.ConsumableEvent.SYNCHRONIZATION) {
627
- this.notificationProcessingQueue
628
- .push(() => this.handleSynchronizationNotification(notification, onConnectionStateChanged))
629
- .catch(this.handleNotificationQueueError);
630
- return;
419
+ const messages = this.service.notification.handleNotification(notification, source, dryRun);
420
+ for await (const message of messages) {
421
+ await handleEvent(message, source);
631
422
  }
632
- this.notificationProcessingQueue
633
- .push(() => this.decryptAckEmitNotification(notification, handleEvent, source, onNotificationStreamProgress))
634
- .catch(this.handleNotificationQueueError);
635
423
  }
636
424
  catch (error) {
637
- this.logger.error(`Failed to handle notification "${notification.type}": ${error.message}`, error);
425
+ this.logger.error(`Failed to handle notification ID "${notification.id}": ${error.message}`, error);
638
426
  }
639
427
  };
640
- };
641
- handleNotificationQueueError = (error) => {
642
- if (!(error instanceof Error)) {
643
- throw error;
644
- }
645
- switch (error.cause) {
646
- case promise_queue_1.PromiseQueue.ERROR_CAUSES.TIMEOUT:
647
- this.logger.warn('Notification decryption task timed out', error);
648
- break;
649
- case promise_queue_1.PromiseQueue.ERROR_CAUSES.FLUSHED:
650
- this.logger.info('Notification processing queue was flushed, ignoring error', error);
651
- break;
652
- }
653
- };
654
- acknowledgeSynchronizationNotification = (notification) => {
655
- this.apiClient.transport.ws.acknowledgeConsumableNotificationSynchronization(notification);
656
- };
657
- handleSynchronizationNotification = async (notification, onConnectionStateChanged) => {
658
- this.logger.info('acknowledging synchronization notification', { notification });
659
- this.acknowledgeSynchronizationNotification(notification);
660
- const markerId = notification.data.marker_id;
661
- const currentMarkerId = this.apiClient.transport.http.accessTokenStore.markerToken;
662
- this.logger.info(`Handling synchronization notification with marker ID: ${markerId} current marker ID: ${currentMarkerId}`);
663
- /**
664
- * There is a chance that there might be multiple synchronization notifications (markers)
665
- * in the queue in case websocket connection drops a few times
666
- * Hence we only want to resume message sending and set the connection state to LIVE
667
- * if the marker ID matches the current marker ID.
668
- */
669
- if (markerId === currentMarkerId) {
670
- (0, IncomingProposalsQueue_1.resumeProposalProcessing)();
671
- (0, messageSender_1.resumeMessageSending)();
672
- (0, conversationRejoinQueue_1.resumeRejoiningMLSConversations)();
673
- onConnectionStateChanged(ConnectionState.LIVE);
674
- }
675
- };
676
- decryptAckEmitNotification = async (notification, handleEvent, source, onNotificationStreamProgress) => {
677
- try {
678
- this.logger.info(`Sending consumable notification for decryption`, notification.data.event.id);
679
- const payloads = this.service.notification.handleNotification(notification.data.event, source);
680
- const notificationTime = this.getNotificationEventTime(notification.data.event.payload[0]);
681
- if (this.connectionState !== ConnectionState.LIVE && notificationTime) {
682
- onNotificationStreamProgress(notificationTime);
683
- }
684
- for await (const payload of payloads ?? []) {
685
- await handleEvent(payload, source);
428
+ this.apiClient.transport.ws.removeAllListeners(tcp_1.WebSocketClient.TOPIC.ON_MESSAGE);
429
+ this.apiClient.transport.ws.on(tcp_1.WebSocketClient.TOPIC.ON_MESSAGE, notification => handleNotification(notification, notification_1.NotificationSource.WEBSOCKET));
430
+ this.apiClient.transport.ws.on(tcp_1.WebSocketClient.TOPIC.ON_STATE_CHANGE, wsState => {
431
+ const mapping = {
432
+ [ReconnectingWebsocket_1.WEBSOCKET_STATE.CLOSED]: ConnectionState.CLOSED,
433
+ [ReconnectingWebsocket_1.WEBSOCKET_STATE.CONNECTING]: ConnectionState.CONNECTING,
434
+ };
435
+ const connectionState = mapping[wsState];
436
+ if (connectionState) {
437
+ onConnectionStateChanged(connectionState);
686
438
  }
687
- this.logger.info(`Acknowledging consumable notification on the backend "${notification.data.delivery_tag}"`);
688
- this.apiClient.transport.ws.acknowledgeNotification(notification);
689
- }
690
- catch (err) {
691
- this.logger.error(`Failed to process notification ${notification.data.delivery_tag}`, err);
692
- }
693
- };
694
- getNotificationEventTime = (backendEvent) => {
695
- if ('time' in backendEvent && typeof backendEvent.time === 'string') {
696
- return backendEvent.time;
697
- }
698
- return null;
699
- };
700
- /**
701
- * Returns a function to handle missed notifications — i.e., when the backend indicates
702
- * that some notifications were lost due to age (typically >28 days).
703
- * Also handles MLS-specific epoch mismatch recovery by triggering a conversation rejoin.
704
- *
705
- * @deprecated This is used to handle legacy missed notifications.
706
- * It should be replaced with the new notification handling system using `ConsumableNotification`.
707
- * when all clients are capable of handling consumable notifications.
708
- */
709
- createLegacyMissedNotificationsHandler = (onMissedNotifications) => {
710
- return async (notificationId) => {
439
+ });
440
+ const handleMissedNotifications = async (notificationId) => {
711
441
  if (this.hasMLSDevice) {
712
- void (0, conversationRejoinQueue_1.queueConversationRejoin)('all-conversations', () => this.service.conversation.handleConversationsEpochMismatch());
442
+ (0, conversationRejoinQueue_1.queueConversationRejoin)('all-conversations', () => this.service.conversation.handleConversationsEpochMismatch());
713
443
  }
714
444
  return onMissedNotifications(notificationId);
715
445
  };
716
- };
717
- /**
718
- * Returns a processor function for the notification stream (legacy sync).
719
- * It pauses message sending and MLS rejoining during stream handling to prevent race conditions,
720
- * then resumes normal operations after sync is complete.
721
- *
722
- * @deprecated This is used to do a final sync of the legacy notification stream
723
- * before switching to the new notification handling system using `ConsumableNotification`.
724
- * It should be replaced with the new notification handling system when all clients are capable of handling consumable notifications.
725
- *
726
- * @param handlers Various logic handlers wired to notification callbacks
727
- */
728
- createLegacyNotificationStreamProcessor = ({ handleLegacyNotification, handleMissedNotifications, onConnectionStateChanged, }) => {
729
- return async (abortController) => {
446
+ const processNotificationStream = async (abortHandler) => {
447
+ // Lock websocket in order to buffer any message that arrives while we handle the notification stream
730
448
  this.apiClient.transport.ws.lock();
731
- (0, IncomingProposalsQueue_1.pauseProposalProcessing)();
732
449
  (0, messageSender_1.pauseMessageSending)();
450
+ // We want to avoid triggering rejoins of out-of-sync MLS conversations while we are processing the notification stream
733
451
  (0, conversationRejoinQueue_1.pauseRejoiningMLSConversations)();
734
452
  onConnectionStateChanged(ConnectionState.PROCESSING_NOTIFICATIONS);
735
- const results = await this.service.notification.legacyProcessNotificationStream(async (notification, source) => {
736
- await handleLegacyNotification(notification, source);
737
- }, handleMissedNotifications, abortController);
738
- this.logger.info('Finished inserting notifications for decryption from the legacy endpoint to the process queue', results);
453
+ const results = await this.service.notification.processNotificationStream(async (notification, source, progress) => {
454
+ await handleNotification(notification, source);
455
+ onNotificationStreamProgress(progress);
456
+ }, handleMissedNotifications, abortHandler);
457
+ this.logger.info('Finished processing notifications', results);
458
+ if (abortHandler.signal.aborted) {
459
+ this.logger.warn('Ending connection process as websocket was closed');
460
+ return;
461
+ }
462
+ onConnectionStateChanged(ConnectionState.LIVE);
463
+ // We can now unlock the websocket and let the new messages being handled and decrypted
464
+ this.apiClient.transport.ws.unlock();
739
465
  // We need to wait for the notification stream to be fully handled before releasing the message sending queue.
740
466
  // This is due to the nature of how message are encrypted, any change in mls epoch needs to happen before we start encrypting any kind of messages
741
- void this.notificationProcessingQueue
742
- .push(async () => {
743
- this.logger.info(`Resuming message sending. ${(0, messageSender_1.getQueueLength)()} messages to be sent`);
744
- (0, IncomingProposalsQueue_1.resumeProposalProcessing)();
745
- (0, messageSender_1.resumeMessageSending)();
746
- (0, conversationRejoinQueue_1.resumeRejoiningMLSConversations)();
747
- onConnectionStateChanged(ConnectionState.LIVE);
748
- this.apiClient.transport.ws.unlock();
749
- })
750
- .catch(this.handleNotificationQueueError);
467
+ this.logger.info(`Resuming message sending. ${(0, messageSender_1.getQueueLength)()} messages to be sent`);
468
+ (0, messageSender_1.resumeMessageSending)();
469
+ (0, conversationRejoinQueue_1.resumeRejoiningMLSConversations)();
751
470
  };
752
- };
753
- /**
754
- * In case of a closed connection, we flush the notification processing queue.
755
- * As we are not acknowledging them before decryption is done
756
- * they will be resent next time the connection is opened
757
- * this is to avoid duplicate decryption of notifications
758
- */
759
- pauseAndFlushNotificationQueue = () => {
760
- this.notificationProcessingQueue.pause();
761
- this.notificationProcessingQueue.flush();
762
- this.logger.info('Notification processing queue paused and flushed');
763
- };
764
- pauseNotificationQueue = () => {
765
- this.notificationProcessingQueue.pause();
766
- this.logger.info('Notification processing queue paused');
767
- };
768
- resumeNotificationQueue = () => {
769
- this.notificationProcessingQueue.resume();
770
- this.logger.info('Notification processing queue resumed');
771
- };
772
- /**
773
- * Sets up WebSocket event listeners for:
774
- * - Incoming backend messages
775
- * - WebSocket state changes
776
- * On each new backend message, we pass it to the notification handler.
777
- * On state changes, we map raw socket states to public connection states and emit them.
778
- */
779
- setupWebSocketListeners = (onConnectionStateChanged, handleNotification, handleLegacyNotification, useLegacy) => {
780
- this.logger.info('Setting up WebSocket listeners');
781
- this.apiClient.transport.ws.removeAllListeners(tcp_1.WebSocketClient.TOPIC.ON_MESSAGE);
782
- this.apiClient.transport.ws.on(tcp_1.WebSocketClient.TOPIC.ON_MESSAGE, notification => {
783
- this.logger.info('Received new notification from backend', { notification });
784
- if (Account.checkIsConsumable(notification)) {
785
- void handleNotification(notification, notification_1.NotificationSource.WEBSOCKET);
786
- return;
787
- }
788
- void handleLegacyNotification(notification, notification_1.NotificationSource.WEBSOCKET);
789
- });
790
- this.apiClient.transport.ws.on(tcp_1.WebSocketClient.TOPIC.ON_STATE_CHANGE, wsState => {
791
- const mapping = {
792
- [ReconnectingWebsocket_1.WEBSOCKET_STATE.CLOSED]: ConnectionState.CLOSED,
793
- [ReconnectingWebsocket_1.WEBSOCKET_STATE.CONNECTING]: ConnectionState.CONNECTING,
794
- };
795
- const connectionState = mapping[wsState];
796
- if (connectionState === ConnectionState.CLOSED) {
797
- (0, IncomingProposalsQueue_1.flushProposalsQueue)();
798
- this.pauseAndFlushNotificationQueue();
799
- if (useLegacy) {
800
- this.apiClient.transport.ws.lock();
801
- }
802
- }
803
- if (connectionState) {
804
- onConnectionStateChanged(connectionState);
805
- }
806
- });
807
- };
808
- /**
809
- * Handles logic for reacting to a missed notification event.
810
- *
811
- * The backend sends a special "missed notification" signal if it detects
812
- * that the client has missed one or more notifications. Once this signal is sent,
813
- * the backend will **stop sending all further notifications** until the client
814
- * acknowledges the missed state.
815
- *
816
- * Because our app currently lacks functionality to perform a full real-time sync
817
- * while running, we must reload the application to re-fetch the entire state.
818
- *
819
- * On first detection of the missed notification:
820
- * - We set a local storage flag (`has_missing_notification`) to mark that we've
821
- * entered this state.
822
- * - We reload the application so the state can be re-fetched from scratch.
823
- *
824
- * On the next load:
825
- * - If the flag is already present, we acknowledge the missed notification via
826
- * the WebSocket transport, unblocking the backend so it resumes sending updates
827
- * then we remove the flag.
828
- */
829
- reactToMissedNotification = () => {
830
- this.logger.info('Reacting to missed notification from consumable async websocket');
831
- const localStorageKey = 'has_missing_notification';
832
- // First-time handling: set flag and reload to trigger full re-fetch of state.
833
- if (!exports.AccountLocalStorageStore.has(localStorageKey)) {
834
- this.logger.info('First missed notification detected, reloading to recover state');
835
- exports.AccountLocalStorageStore.add(localStorageKey, 'true');
836
- window.location.reload();
837
- return;
838
- }
839
- this.logger.info('Missed notification previously detected, acknowledging to resume updates');
840
- // After reload: acknowledge the missed notification so backend resumes notifications.
841
- this.apiClient.transport.ws.acknowledgeMissedNotification();
842
- exports.AccountLocalStorageStore.remove(localStorageKey);
843
- };
844
- getClientCapabilities = () => {
845
- return this.currentClient?.capabilities || [];
846
- };
847
- static checkIsConsumable = (notification) => {
848
- return 'type' in notification;
849
- };
850
- static checkIsLegacyNotification = (notification) => {
851
- return !Account.checkIsConsumable(notification);
852
- };
853
- generateDbName = (context) => {
471
+ this.apiClient.connect(processNotificationStream);
472
+ return () => {
473
+ this.apiClient.disconnect();
474
+ onConnectionStateChanged(ConnectionState.CLOSED);
475
+ this.apiClient.transport.ws.removeAllListeners();
476
+ };
477
+ }
478
+ generateDbName(context) {
854
479
  const clientType = context.clientType === client_1.ClientType.NONE ? '' : `@${context.clientType}`;
855
480
  return `wire@${this.apiClient.config.urls.name}@${context.userId}${clientType}`;
856
- };
857
- generateCoreDbName = (context) => {
481
+ }
482
+ generateCoreDbName(context) {
858
483
  return `core-${this.generateDbName(context)}`;
859
- };
860
- generateEncryptedDbName = (context) => {
484
+ }
485
+ generateEncryptedDbName(context) {
861
486
  return `secrets-${this.generateDbName(context)}`;
862
- };
863
- initEngine = async (context, encryptedStore) => {
487
+ }
488
+ async initEngine(context, encryptedStore) {
864
489
  const dbName = this.generateDbName(context);
865
490
  this.logger.debug(`Initialising store with name "${dbName}"...`);
866
491
  const openDb = async () => {
@@ -881,43 +506,28 @@ class Account extends commons_1.TypedEventEmitter {
881
506
  await this.persistCookie(storeEngine, cookie);
882
507
  }
883
508
  return storeEngine;
884
- };
509
+ }
885
510
  groupIdFromConversationId = async (conversationId, subconversationId) => {
886
511
  if (!subconversationId) {
887
512
  return this.coreCallbacks?.groupIdFromConversationId(conversationId);
888
513
  }
889
514
  return this.service?.subconversation.getSubconversationGroupId(conversationId, subconversationId);
890
515
  };
891
- isMLSActiveForClient = async () => {
892
- // Check for CoreCrypto library, it is required for MLS
893
- if (!this.options.coreCryptoConfig?.enabled) {
516
+ async isMLSActiveForClient() {
517
+ // MLS service is initialized
518
+ const isMLSServiceInitialized = this.service?.mls !== undefined;
519
+ if (!isMLSServiceInitialized) {
894
520
  return false;
895
521
  }
896
- // Check if the backend supports MLS trough removal keys
897
- if (!(await this.apiClient.supportsMLS())) {
522
+ // Backend Supports MLS trough removal keys
523
+ const isMLSSupported = await this.apiClient.supportsMLS();
524
+ if (!isMLSSupported) {
898
525
  return false;
899
526
  }
900
- // Check if MLS is enabled for the public via backend feature flag
901
- const commonConfig = (await this.service?.team.getCommonFeatureConfig()) ?? {};
902
- return commonConfig[team_1.FEATURE_KEY.MLS]?.status === team_1.FEATURE_STATUS.ENABLED;
903
- };
904
- isMLSConversationRecoveryEnabled = async () => {
527
+ // MLS is enabled for the public via feature flag
905
528
  const commonConfig = (await this.service?.team.getCommonFeatureConfig()) ?? {};
906
- return commonConfig[team_1.FEATURE_KEY.ALLOWED_GLOBAL_OPERATIONS]?.config?.mlsConversationReset === true;
907
- };
908
- /**
909
- * Checks the health of the WebSocket connection by sending a ping and waiting for a pong response.
910
- * This is a non-disruptive check that does not close or reconnect the socket.
911
- * @returns A promise that resolves to true if the socket responds with a pong within the timeout, false otherwise.
912
- *
913
- * @example
914
- * const healthy = await account.isWebsocketHealthy();
915
- * if (!healthy) {
916
- * // handle unhealthy websocket
917
- * }
918
- */
919
- isWebsocketHealthy = async () => {
920
- return this.apiClient.transport.ws.checkHealth();
921
- };
529
+ const isMLSForTeamEnabled = commonConfig[team_1.FEATURE_KEY.MLS]?.status === team_1.FeatureStatus.ENABLED;
530
+ return isMLSSupported && isMLSForTeamEnabled && isMLSServiceInitialized;
531
+ }
922
532
  }
923
533
  exports.Account = Account;