@wireapp/core 27.3.2 → 27.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,36 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [27.3.5](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@27.3.4...@wireapp/core@27.3.5) (2022-06-09)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Do not process outdated events ([#4289](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/issues/4289)) ([e817f8f](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/commit/e817f8f3351d8b9c016bf94a2668278d9dc14514))
12
+
13
+
14
+
15
+
16
+
17
+ ## [27.3.4](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@27.3.3...@wireapp/core@27.3.4) (2022-06-08)
18
+
19
+ **Note:** Version bump only for package @wireapp/core
20
+
21
+
22
+
23
+
24
+
25
+ ## [27.3.3](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@27.3.2...@wireapp/core@27.3.3) (2022-06-08)
26
+
27
+
28
+ ### Bug Fixes
29
+
30
+ * **core:** Abort notification stream handling when websocket is disconnected ([#4285](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/issues/4285)) ([e674a38](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/commit/e674a3827f4e107f9d6ef39e26fa8d94c58986d7))
31
+
32
+
33
+
34
+
35
+
6
36
  ## [27.3.2](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@27.3.1...@wireapp/core@27.3.2) (2022-06-07)
7
37
 
8
38
  **Note:** Version bump only for package @wireapp/core
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "dependencies": {
6
6
  "@types/long": "4.0.1",
7
7
  "@types/node": "~14",
8
- "@wireapp/api-client": "19.5.0",
8
+ "@wireapp/api-client": "19.6.0",
9
9
  "@wireapp/cryptobox": "12.8.0",
10
10
  "bazinga64": "5.10.0",
11
11
  "hash.js": "1.1.7",
@@ -69,6 +69,6 @@
69
69
  "test:project": "yarn dist && yarn test",
70
70
  "test:node": "nyc jasmine --config=jasmine.json"
71
71
  },
72
- "version": "27.3.2",
73
- "gitHead": "f0a342f7757e65293a7fb1e5bfba1ccab646030d"
72
+ "version": "27.3.5",
73
+ "gitHead": "2ef677ae91a6350051dc3c2c24bd1b20f60a9f2e"
74
74
  }
@@ -306,7 +306,7 @@ class Account extends events_1.EventEmitter {
306
306
  const handleNotification = async (notification, source) => {
307
307
  var e_1, _a;
308
308
  try {
309
- const messages = this.service.notification.handleNotification(notification, conversation_1.PayloadBundleSource.WEBSOCKET, dryRun);
309
+ const messages = this.service.notification.handleNotification(notification, source, dryRun);
310
310
  try {
311
311
  for (var messages_1 = __asyncValues(messages), messages_1_1; messages_1_1 = await messages_1.next(), !messages_1_1.done;) {
312
312
  const message = messages_1_1.value;
@@ -328,13 +328,13 @@ class Account extends events_1.EventEmitter {
328
328
  this.apiClient.transport.ws.removeAllListeners(tcp_1.WebSocketClient.TOPIC.ON_MESSAGE);
329
329
  this.apiClient.transport.ws.on(tcp_1.WebSocketClient.TOPIC.ON_MESSAGE, notification => handleNotification(notification, conversation_1.PayloadBundleSource.WEBSOCKET));
330
330
  this.apiClient.transport.ws.on(tcp_1.WebSocketClient.TOPIC.ON_STATE_CHANGE, onConnectionStateChanged);
331
- const onBeforeConnect = async () => {
331
+ const onBeforeConnect = async (abortHandler) => {
332
332
  // Lock websocket in order to buffer any message that arrives while we handle the notification stream
333
333
  this.apiClient.transport.ws.lock();
334
334
  await this.service.notification.handleNotificationStream(async (notification, source, progress) => {
335
335
  await handleNotification(notification, source);
336
336
  onNotificationStreamProgress(progress);
337
- }, onMissedNotifications);
337
+ }, onMissedNotifications, abortHandler);
338
338
  // We can now unlock the websocket and let the new messages being handled and decrypted
339
339
  this.apiClient.transport.ws.unlock();
340
340
  onConnected();
@@ -342,6 +342,8 @@ class Account extends events_1.EventEmitter {
342
342
  await this.apiClient.connect(onBeforeConnect);
343
343
  return () => {
344
344
  this.apiClient.disconnect();
345
+ this.apiClient.transport.ws.removeAllListeners(tcp_1.WebSocketClient.TOPIC.ON_MESSAGE);
346
+ this.apiClient.transport.ws.removeListener(tcp_1.WebSocketClient.TOPIC.ON_STATE_CHANGE, onConnectionStateChanged);
345
347
  };
346
348
  }
347
349
  async initEngine(context) {
@@ -8,6 +8,7 @@ import { PayloadBundle, PayloadBundleSource } from '../conversation';
8
8
  import { NotificationError } from '../CoreError';
9
9
  import type { CryptographyService } from '../cryptography';
10
10
  import { GenericMessage } from '@wireapp/protocol-messaging';
11
+ import { AbortHandler } from '@wireapp/api-client/src/tcp';
11
12
  export declare type HandledEventPayload = {
12
13
  event: Events.BackendEvent;
13
14
  mappedEvent?: PayloadBundle;
@@ -42,7 +43,16 @@ export declare class NotificationService extends EventEmitter {
42
43
  getNotificationEventList(): Promise<Events.BackendEvent[]>;
43
44
  setLastEventDate(eventDate: Date): Promise<Date>;
44
45
  setLastNotificationId(lastNotification: Notification): Promise<string>;
45
- handleNotificationStream(notificationHandler: NotificationHandler, onMissedNotifications: (notificationId: string) => void): Promise<void>;
46
+ handleNotificationStream(notificationHandler: NotificationHandler, onMissedNotifications: (notificationId: string) => void, abortHandler: AbortHandler): Promise<void>;
47
+ /**
48
+ * Checks if an event should be ignored.
49
+ * An event that has a date prior to that last event that we have parsed should be ignored
50
+ *
51
+ * @param event
52
+ * @param source
53
+ * @param lastEventDate?
54
+ */
55
+ private isOutdatedEvent;
46
56
  handleNotification(notification: Notification, source: PayloadBundleSource, dryRun?: boolean): AsyncGenerator<HandledEventPayload>;
47
57
  private cleanupPayloadBundle;
48
58
  private handleEvent;
@@ -118,22 +118,55 @@ class NotificationService extends events_1.EventEmitter {
118
118
  async setLastNotificationId(lastNotification) {
119
119
  return this.database.updateLastNotificationId(lastNotification);
120
120
  }
121
- async handleNotificationStream(notificationHandler, onMissedNotifications) {
121
+ async handleNotificationStream(notificationHandler, onMissedNotifications, abortHandler) {
122
122
  const { notifications, missedNotification } = await this.getAllNotifications();
123
123
  if (missedNotification) {
124
124
  onMissedNotifications(missedNotification);
125
125
  }
126
126
  for (const [index, notification] of notifications.entries()) {
127
+ if (abortHandler.isAborted()) {
128
+ /* Stop handling notifications if the websocket has been disconnected.
129
+ * Upon reconnecting we are going to restart handling the notification stream for where we left of
130
+ */
131
+ return;
132
+ }
127
133
  await notificationHandler(notification, conversation_1.PayloadBundleSource.NOTIFICATION_STREAM, {
128
134
  done: index + 1,
129
135
  total: notifications.length,
130
136
  }).catch(error => this.logger.error(error));
131
137
  }
132
138
  }
139
+ /**
140
+ * Checks if an event should be ignored.
141
+ * An event that has a date prior to that last event that we have parsed should be ignored
142
+ *
143
+ * @param event
144
+ * @param source
145
+ * @param lastEventDate?
146
+ */
147
+ isOutdatedEvent(event, source, lastEventDate) {
148
+ const isFromNotificationStream = source === conversation_1.PayloadBundleSource.NOTIFICATION_STREAM;
149
+ const shouldCheckEventDate = !!event.time && isFromNotificationStream && lastEventDate;
150
+ if (shouldCheckEventDate) {
151
+ /** This check prevents duplicated "You joined" system messages. */
152
+ const isOutdated = lastEventDate.getTime() >= new Date(event.time).getTime();
153
+ return isOutdated;
154
+ }
155
+ return false;
156
+ }
133
157
  handleNotification(notification, source, dryRun = false) {
134
158
  return __asyncGenerator(this, arguments, function* handleNotification_1() {
135
159
  for (const event of notification.payload) {
136
160
  this.logger.log(`Handling event of type "${event.type}" for notification with ID "${notification.id}"`, event);
161
+ let lastEventDate = undefined;
162
+ try {
163
+ lastEventDate = yield __await(this.database.getLastEventDate());
164
+ }
165
+ catch (_a) { }
166
+ if ('time' in event && this.isOutdatedEvent(event, source, lastEventDate)) {
167
+ this.logger.info(`Ignored outdated event type: '${event.type}'`);
168
+ continue;
169
+ }
137
170
  try {
138
171
  const data = yield __await(this.handleEvent(event, source, dryRun));
139
172
  yield yield __await(Object.assign(Object.assign({}, data), { mappedEvent: data.mappedEvent ? this.cleanupPayloadBundle(data.mappedEvent) : undefined }));