@wireapp/core 46.40.8 → 46.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,33 +2,13 @@ import { AssetOptions, AssetResponse } from '@wireapp/api-client/lib/asset';
2
2
  import { ProgressCallback, RequestCancelable } from '@wireapp/api-client/lib/http';
3
3
  import { APIClient } from '@wireapp/api-client';
4
4
  import { EncryptedAsset, EncryptedAssetUploaded } from '../../cryptography';
5
- interface AssetDataV4 {
5
+ export { ProgressCallback };
6
+ export type AssetUrlData = {
6
7
  assetKey: string;
7
8
  assetToken: string;
8
9
  assetDomain: string;
9
10
  forceCaching: boolean;
10
- version: 4;
11
- }
12
- interface AssetDataV3 {
13
- assetKey: string;
14
- assetToken: string;
15
- forceCaching: boolean;
16
- version: 3;
17
- }
18
- interface AssetDataV2 {
19
- assetId: string;
20
- conversationId: string;
21
- forceCaching: boolean;
22
- version: 2;
23
- }
24
- interface AssetDataV1 {
25
- assetId: string;
26
- conversationId: string;
27
- forceCaching: boolean;
28
- version: 1;
29
- }
30
- export { ProgressCallback };
31
- export type AssetUrlData = AssetDataV1 | AssetDataV2 | AssetDataV3 | AssetDataV4;
11
+ };
32
12
  export declare class AssetService {
33
13
  private readonly apiClient;
34
14
  constructor(apiClient: APIClient);
@@ -40,10 +20,7 @@ export declare class AssetService {
40
20
  * @param progressCallback?
41
21
  * @return Resolves when the asset has been uploaded
42
22
  */
43
- downloadRawAsset(assetData: AssetUrlData, progressCallback?: ProgressCallback): {
44
- cancel: () => void;
45
- response: Promise<AssetResponse>;
46
- };
23
+ downloadRawAsset(assetData: AssetUrlData, progressCallback?: ProgressCallback): RequestCancelable<AssetResponse>;
47
24
  /**
48
25
  * Uploads a raw asset to the backend without encrypting it
49
26
  *
@@ -52,7 +29,12 @@ export declare class AssetService {
52
29
  * @param progressCallback?
53
30
  * @return cancellable request that resolves with the uploaded image
54
31
  */
55
- uploadRawAsset(asset: Buffer | Uint8Array, options?: AssetOptions, progressCallback?: ProgressCallback): RequestCancelable<import("@wireapp/api-client/lib/asset").AssetUploadData>;
32
+ uploadRawAsset(asset: Buffer | Uint8Array, options?: AssetOptions, progressCallback?: ProgressCallback): RequestCancelable<{
33
+ key: string;
34
+ token: string;
35
+ expires: string;
36
+ domain?: string | undefined;
37
+ }>;
56
38
  /**
57
39
  * Will encrypt and upload an asset to the backend
58
40
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AssetService.d.ts","sourceRoot":"","sources":["../../../src/conversation/AssetService/AssetService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,8BAA8B,CAAC;AAEjF,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAC,cAAc,EAAE,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAG1E,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC;CACZ;AACD,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,OAAO,EAAC,gBAAgB,EAAC,CAAC;AAC1B,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAEjF,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD;;;;;;;OAOG;IACI,gBAAgB,CAAC,SAAS,EAAE,YAAY,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;;;;IAoCpF;;;;;;;OAOG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAI7G;;;;;;;OAOG;IACU,WAAW,CACtB,SAAS,EAAE,MAAM,GAAG,UAAU,EAC9B,OAAO,CAAC,EAAE,YAAY,EACtB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,OAAO,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,CAAC;IAyB9C,YAAY,CAAC,KAAK,EAAE,cAAc;IAIzC;;;;;;OAMG;IACI,aAAa,CAClB,SAAS,EAAE,YAAY,EACvB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC;QAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAC;CAgB1D"}
1
+ {"version":3,"file":"AssetService.d.ts","sourceRoot":"","sources":["../../../src/conversation/AssetService/AssetService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,8BAA8B,CAAC;AAEjF,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAC,cAAc,EAAE,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAG1E,OAAO,EAAC,gBAAgB,EAAC,CAAC;AAC1B,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD;;;;;;;OAOG;IACI,gBAAgB,CAAC,SAAS,EAAE,YAAY,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAUpF;;;;;;;OAOG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;;;;;;IAI7G;;;;;;;OAOG;IACU,WAAW,CACtB,SAAS,EAAE,MAAM,GAAG,UAAU,EAC9B,OAAO,CAAC,EAAE,YAAY,EACtB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,OAAO,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,CAAC;IAyB9C,YAAY,CAAC,KAAK,EAAE,cAAc;IAIzC;;;;;;OAMG;IACI,aAAa,CAClB,SAAS,EAAE,YAAY,EACvB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC;QAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAC;CAgB1D"}
@@ -34,17 +34,7 @@ class AssetService {
34
34
  * @return Resolves when the asset has been uploaded
35
35
  */
36
36
  downloadRawAsset(assetData, progressCallback) {
37
- const { forceCaching } = assetData;
38
- switch (assetData.version) {
39
- case 1:
40
- return this.apiClient.api.asset.getAssetV1(assetData.assetId, assetData.conversationId, forceCaching, progressCallback);
41
- case 2:
42
- return this.apiClient.api.asset.getAssetV2(assetData.assetId, assetData.conversationId, forceCaching, progressCallback);
43
- case 3:
44
- return this.apiClient.api.asset.getAssetV3(assetData.assetKey, assetData.assetToken, forceCaching, progressCallback);
45
- case 4:
46
- return this.apiClient.api.asset.getAssetV4(assetData.assetKey, assetData.assetDomain, assetData.assetToken, forceCaching, progressCallback);
47
- }
37
+ return this.apiClient.api.asset.getAsset(assetData.assetKey, assetData.assetDomain, assetData.assetToken, assetData.forceCaching, progressCallback);
48
38
  }
49
39
  /**
50
40
  * Uploads a raw asset to the backend without encrypting it
@@ -31,6 +31,8 @@ export declare class ConversationService extends TypedEventEmitter<Events> {
31
31
  private readonly _mlsService?;
32
32
  readonly messageTimer: MessageTimer;
33
33
  private readonly logger;
34
+ private readonly recoveringKeyMaterialGroups;
35
+ private groupIdConversationMap;
34
36
  constructor(apiClient: APIClient, proteusService: ProteusService, coreDatabase: CoreDatabase, groupIdFromConversationId: (conversationId: QualifiedId, subconversationId?: SUBCONVERSATION_ID) => Promise<string | undefined>, subconversationService: SubconversationService, isMLSConversationRecoveryEnabled: () => Promise<boolean>, _mlsService?: MLSService | undefined);
35
37
  get mlsService(): MLSService;
36
38
  /**
@@ -123,6 +125,9 @@ export declare class ConversationService extends TypedEventEmitter<Events> {
123
125
  shouldRetry?: boolean;
124
126
  }): Promise<Conversation>;
125
127
  joinByExternalCommit(conversationId: QualifiedId, shouldRetry?: boolean): Promise<void>;
128
+ private refreshGroupIdConversationMap;
129
+ private getConversationByGroupId;
130
+ private reactToKeyMaterialUpdateFailure;
126
131
  private resetMLSConversation;
127
132
  /**
128
133
  * Will check if mls group exists locally.
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationService.d.ts","sourceRoot":"","sources":["../../../src/conversation/ConversationService/ConversationService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConversationService.d.ts","sourceRoot":"","sources":["../../../src/conversation/ConversationService/ConversationService.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,WAAW,EACX,eAAe,EACf,oBAAoB,EAEpB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAKnB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EACL,YAAY,EAIZ,4BAA4B,EAE7B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAGvD,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAa,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAY/D,OAAO,EACL,cAAc,EACd,8BAA8B,EAE9B,oBAAoB,EACpB,UAAU,EACX,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAC,YAAY,EAAuB,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAC,UAAU,EAAE,gBAAgB,EAAC,MAAM,8BAA8B,CAAC;AAS1E,OAAO,EAAkC,cAAc,EAAC,MAAM,kCAAkC,CAAC;AACjG,OAAO,EACL,mCAAmC,EACnC,wBAAwB,EACzB,MAAM,sEAAsE,CAAC;AAC9E,OAAO,EAAsB,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAIlD,OAAO,EAAC,sBAAsB,EAAC,MAAM,kDAAkD,CAAC;AAExF,KAAK,MAAM,GAAG;IACZ,wBAAwB,EAAE;QAAC,cAAc,EAAE,WAAW,CAAA;KAAC,CAAC;IACxD,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,EAAE;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;CACvE,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,iBAAiB,CAAC,MAAM,CAAC;IAQ9D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAI1C,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,gCAAgC;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAhB/B,SAAgB,YAAY,EAAE,YAAY,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6D;IAEpF,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAA0B;IACtE,OAAO,CAAC,sBAAsB,CAAwC;gBAGnD,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,YAAY,EAC1B,yBAAyB,EAAE,CAC1C,cAAc,EAAE,WAAW,EAC3B,iBAAiB,CAAC,EAAE,kBAAkB,KACnC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,EACf,sBAAsB,EAAE,sBAAsB,EAC9C,gCAAgC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EACxD,WAAW,CAAC,EAAE,UAAU,YAAA;IAgB3C,IAAI,UAAU,IAAI,UAAU,CAK3B;IAED;;;;;OAKG;IACU,2BAA2B,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkBpG;;;;;;;;;;OAUG;IACU,yBAAyB,CAAC,gBAAgB,EAAE,eAAe;IAI3D,eAAe,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAInE,sBAAsB,IAAI,OAAO,CAAC,eAAe,CAAC;IAIlD,gBAAgB,CAAC,eAAe,CAAC,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQ/E,6BAA6B,CAAC,MAAM,EAAE,mCAAmC;IAIzE,0BAA0B,CACrC,cAAc,EAAE,WAAW,EAC3B,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,4BAA4B,CAAC;IAIxC;;;OAGG;IACU,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAO5F,eAAe,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,cAAc,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE;;;;OAIG;IACH,SAAgB,qBAAqB,mBAA0B,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC,CAExF;IAEF;;;OAGG;IACH,SAAgB,+BAA+B,mBAA0B,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC,CAElG;IAEF;;OAEG;IACH,gBAAgB,IAAI,OAAO;IAIpB,0BAA0B,CAC/B,cAAc,EAAE,WAAW,EAC3B,MAAM,EAAE,WAAW,EACnB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,OAAO,CAAC,IAAI,CAAC;IAaT,yBAAyB,CAC9B,cAAc,EAAE,WAAW,EAC3B,QAAQ,EAAE,OAAO,EACjB,gBAAgB,GAAE,MAAM,GAAG,IAAiB,GAC3C,OAAO,CAAC,IAAI,CAAC;IAaT,yBAAyB,CAC9B,cAAc,EAAE,WAAW,EAC3B,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,2BAA2B,GAAG,MAAM,GACrD,OAAO,CAAC,IAAI,CAAC;IAMhB;;;;OAIG;IAEH;;;OAGG;IACU,qBAAqB,CAChC,gBAAgB,EAAE,eAAe,EACjC,UAAU,EAAE,WAAW,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,8BAA8B,CAAC;IAuB1C;;;;;;;;;OASG;YACW,2BAA2B;IA2BzC;;;OAGG;IACU,6BAA6B,CACxC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,WAAW,EAAE,EAC3B,UAAU,EAAE,WAAW,EACvB,YAAY,EAAE,MAAM,EACpB,uBAAuB,EAAE,WAAW,GACnC,OAAO,CAAC,8BAA8B,CAAC;YAiB5B,cAAc;IAyG5B;;;;;;OAMG;IACU,yBAAyB,CAAC,EACrC,cAAc,EACd,OAAO,EACP,cAAc,EACd,WAAkB,GACnB,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAC,GAAG,OAAO,CAAC,8BAA8B,CAAC;IA2DlF,8BAA8B,CAAC,EAC1C,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,WAAkB,GACnB,EAAE,iBAAiB,GAAG;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IAgEzD,oBAAoB,CAAC,cAAc,EAAE,WAAW,EAAE,WAAW,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAmBnF,6BAA6B;YAU7B,wBAAwB;IAOtC,OAAO,CAAC,+BAA+B,CA6CrC;YAEY,oBAAoB;IAiElC;;;OAGG;IACU,qBAAqB,CAAC,OAAO,EAAE,MAAM;IAIlD;;;;OAIG;IACU,4BAA4B,CAAC,OAAO,EAAE,MAAM;IAI5C,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAIlD,YAAY;IAYb,gCAAgC;IAe7C;;;OAGG;YACW,kCAAkC;IA2BhD;;;OAGG;YACW,+BAA+B;IAqB7C;;;;;;;OAOG;YACW,gBAAgB;IAc9B;;;OAGG;IACG,sBAAsB,CAAC,MAAM,EAAE,WAAW;IAShD;;;;;;;OAOG;IACH,SAAgB,4BAA4B,YACjC,MAAM,YACL;QAAC,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,eAChC,WAAW,4BAEvB,OAAO,CAAC,eAAe,CAAC,CAwDzB;IAEF;;;;;;;;OAQG;IACU,uBAAuB,CAAC,EACnC,OAAO,EACP,cAAc,EACd,UAAU,EACV,cAAc,GACf,EAAE;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,WAAW,CAAC;QAC5B,UAAU,EAAE,WAAW,CAAC;QACxB,cAAc,EAAE,WAAW,EAAE,CAAC;KAC/B,GAAG,OAAO,CAAC,IAAI,CAAC;YAkCH,wBAAwB;YAsBxB,gCAAgC;YA0BhC,4BAA4B;IA2B1C,OAAO,CAAC,2BAA2B;IAmBnC;;;OAGG;YACW,uCAAuC;YA4BvC,wBAAwB;YAIxB,yBAAyB;IAKvC;;;;OAIG;IACU,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAoB3E"}
@@ -44,6 +44,9 @@ class ConversationService extends commons_1.TypedEventEmitter {
44
44
  _mlsService;
45
45
  messageTimer;
46
46
  logger = commons_1.LogFactory.getLogger('@wireapp/core/ConversationService');
47
+ // Track groups currently undergoing recovery due to key material update failure to prevent duplicate work
48
+ recoveringKeyMaterialGroups = new Set();
49
+ groupIdConversationMap = new Map();
47
50
  constructor(apiClient, proteusService, coreDatabase, groupIdFromConversationId, subconversationService, isMLSConversationRecoveryEnabled, _mlsService) {
48
51
  super();
49
52
  this.apiClient = apiClient;
@@ -58,6 +61,10 @@ class ConversationService extends commons_1.TypedEventEmitter {
58
61
  this.mlsService.on(mls_1.MLSServiceEvents.MLS_EVENT_DISTRIBUTED, data => {
59
62
  this.emit(mls_1.MLSServiceEvents.MLS_EVENT_DISTRIBUTED, data);
60
63
  });
64
+ this.mlsService.on(mls_1.MLSServiceEvents.KEY_MATERIAL_UPDATE_FAILURE, ({ error, groupId }) => {
65
+ this.logger.warn(`Key material update failure for group ${groupId}`, { error });
66
+ return this.reactToKeyMaterialUpdateFailure({ error, groupId });
67
+ });
61
68
  }
62
69
  }
63
70
  get mlsService() {
@@ -274,7 +281,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
274
281
  /**
275
282
  * Only thrown by core-crypto when we call commitPendingProposals
276
283
  */
277
- if (mls_1.MLSService.isBrokenMLSConversationError(error)) {
284
+ if ((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(error)) {
278
285
  this.logger.info('Failed to send MLS message because broken MLS conversation, triggering a reset', {
279
286
  error,
280
287
  groupId,
@@ -286,22 +293,37 @@ class ConversationService extends commons_1.TypedEventEmitter {
286
293
  * core-crypto throws its own error class when we call commitPendingProposals
287
294
  * backend error mapper throws its own error class when we call postMlsMessage
288
295
  */
289
- if (mls_1.MLSService.isMLSStaleMessageError(error) || error instanceof conversation_1.MLSStaleMessageError) {
296
+ if ((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(error) || error instanceof conversation_1.MLSStaleMessageError) {
290
297
  this.logger.info('Failed to send MLS message because of stale message, recovering by joining with external commit', {
291
298
  error,
292
299
  groupId,
293
300
  });
294
301
  await this.recoverMLSGroupFromEpochMismatch(conversationId);
295
302
  }
296
- if (error instanceof conversation_1.MLSGroupOutOfSyncError) {
303
+ /**
304
+ * We may have the same error from core-crypto or from the backend error mapper
305
+ * core-crypto throws its own error class when we call commitPendingProposals
306
+ * backend error mapper throws its own error class when we call postMlsMessage
307
+ */
308
+ if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error) || error instanceof conversation_1.MLSGroupOutOfSyncError) {
297
309
  this.logger.info('Failed to send MLS message because of group out of sync, recovering by adding missing users', {
298
310
  error,
299
311
  groupId,
300
312
  });
313
+ /**
314
+ * We may get the missing users either from core-crypto error or from the backend error mapper
315
+ */
316
+ let missingUsers = [];
317
+ if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error)) {
318
+ missingUsers = (0, CoreCryptoMLSError_1.getMLSGroupOutOfSyncErrorMissingUsers)(error);
319
+ }
320
+ else {
321
+ missingUsers = error.missing_users;
322
+ }
301
323
  await this.addUsersToMLSConversation({
302
324
  groupId,
303
325
  conversationId,
304
- qualifiedUsers: error.missing_users,
326
+ qualifiedUsers: missingUsers,
305
327
  });
306
328
  }
307
329
  return this.sendMLSMessage(params, false);
@@ -333,14 +355,27 @@ class ConversationService extends commons_1.TypedEventEmitter {
333
355
  }
334
356
  catch (error) {
335
357
  this.logger.warn('Failed to add users to MLS conversation', { error, groupId, conversationId });
336
- if (mls_1.MLSService.isBrokenMLSConversationError(error)) {
337
- if (!shouldRetry) {
338
- this.logger.warn("Tried to add users to MLS conversation but it's still broken after reset", error);
339
- throw error;
340
- }
358
+ if (!shouldRetry) {
359
+ this.logger.warn("Tried to add users to MLS conversation but it's still broken after reset", error);
360
+ throw error;
361
+ }
362
+ if ((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(error)) {
341
363
  this.logger.warn("Tried to add users to MLS conversation but it's broken, resetting the conversation", error);
342
364
  return this.handleBrokenMLSConversation(conversationId, newGroupId => this.addUsersToMLSConversation({ qualifiedUsers, groupId: newGroupId, conversationId, shouldRetry: false }));
343
365
  }
366
+ if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error)) {
367
+ this.logger.info('Failed to send MLS message because of group out of sync, recovering by adding missing users', {
368
+ error,
369
+ groupId,
370
+ });
371
+ const missingUsers = (0, CoreCryptoMLSError_1.getMLSGroupOutOfSyncErrorMissingUsers)(error);
372
+ return this.addUsersToMLSConversation({
373
+ groupId,
374
+ conversationId,
375
+ qualifiedUsers: missingUsers,
376
+ shouldRetry: false,
377
+ });
378
+ }
344
379
  throw error;
345
380
  }
346
381
  }
@@ -354,11 +389,11 @@ class ConversationService extends commons_1.TypedEventEmitter {
354
389
  return await this.getConversation(conversationId);
355
390
  }
356
391
  catch (error) {
357
- if (mls_1.MLSService.isBrokenMLSConversationError(error)) {
358
- if (!shouldRetry) {
359
- this.logger.warn("Tried to remove users from MLS conversation but it's still broken after reset", error);
360
- throw error;
361
- }
392
+ if (!shouldRetry) {
393
+ this.logger.warn("Tried to remove users from MLS conversation but it's still broken", error);
394
+ throw error;
395
+ }
396
+ if ((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(error)) {
362
397
  this.logger.info("Tried to remove users from MLS conversation but it's broken, resetting the conversation", error);
363
398
  return this.handleBrokenMLSConversation(conversationId, newGroupId => this.removeUsersFromMLSConversation({
364
399
  groupId: newGroupId,
@@ -367,6 +402,24 @@ class ConversationService extends commons_1.TypedEventEmitter {
367
402
  shouldRetry: false,
368
403
  }));
369
404
  }
405
+ if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error)) {
406
+ this.logger.info('Failed to send MLS message because of group out of sync, recovering by adding missing users', {
407
+ error,
408
+ groupId,
409
+ });
410
+ const missingUsers = (0, CoreCryptoMLSError_1.getMLSGroupOutOfSyncErrorMissingUsers)(error);
411
+ await this.addUsersToMLSConversation({
412
+ groupId,
413
+ conversationId,
414
+ qualifiedUsers: missingUsers,
415
+ });
416
+ return this.removeUsersFromMLSConversation({
417
+ groupId,
418
+ conversationId,
419
+ qualifiedUserIds,
420
+ shouldRetry: false,
421
+ });
422
+ }
370
423
  throw error;
371
424
  }
372
425
  }
@@ -375,18 +428,71 @@ class ConversationService extends commons_1.TypedEventEmitter {
375
428
  await this.mlsService.joinByExternalCommit(() => this.apiClient.api.conversation.getGroupInfo(conversationId));
376
429
  }
377
430
  catch (error) {
431
+ if (!shouldRetry) {
432
+ this.logger.warn("Tried to join MLS conversation but it's still broken after reset", error);
433
+ throw error;
434
+ }
378
435
  this.logger.warn(`Failed to join MLS conversation ${conversationId.id} via external commit`, error);
379
- if (mls_1.MLSService.isBrokenMLSConversationError(error)) {
436
+ if ((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(error)) {
380
437
  this.logger.info('Resetting MLS conversation due to broken mls conversation error', error);
381
- if (!shouldRetry) {
382
- this.logger.warn("Tried to join MLS conversation but it's still broken after reset", error);
383
- throw error;
384
- }
385
438
  return this.handleBrokenMLSConversation(conversationId);
386
439
  }
387
440
  throw error;
388
441
  }
389
442
  }
443
+ async refreshGroupIdConversationMap() {
444
+ const conversations = await this.apiClient.api.conversation.getConversationList();
445
+ this.groupIdConversationMap.clear();
446
+ for (const conversation of conversations.found || []) {
447
+ if (conversation.group_id) {
448
+ this.groupIdConversationMap.set(conversation.group_id, conversation);
449
+ }
450
+ }
451
+ }
452
+ async getConversationByGroupId(groupId) {
453
+ if (!this.groupIdConversationMap.has(groupId)) {
454
+ await this.refreshGroupIdConversationMap();
455
+ }
456
+ return this.groupIdConversationMap.get(groupId);
457
+ }
458
+ reactToKeyMaterialUpdateFailure = async ({ error, groupId }) => {
459
+ // Deduplicate concurrent recoveries for the same group
460
+ if (this.recoveringKeyMaterialGroups.has(groupId)) {
461
+ this.logger.info(`Recovery already in progress for group ${groupId}, skipping duplicate trigger`);
462
+ return;
463
+ }
464
+ this.recoveringKeyMaterialGroups.add(groupId);
465
+ try {
466
+ this.logger.info(`Reacting to key material update failure for group ${groupId}`);
467
+ const conversation = await this.getConversationByGroupId(groupId);
468
+ if (!conversation) {
469
+ this.logger.warn(`No conversation found for group ${groupId}`);
470
+ throw error;
471
+ }
472
+ if ((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(error)) {
473
+ this.logger.info('Tried to update key material for a broken MLS conversation, initiating reset', error);
474
+ return this.handleBrokenMLSConversation(conversation.qualified_id);
475
+ }
476
+ if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error)) {
477
+ this.logger.info('Tried to update key material for an out of sync conversation, recovering by adding missing users', {
478
+ error,
479
+ groupId,
480
+ });
481
+ const missingUsers = (0, CoreCryptoMLSError_1.getMLSGroupOutOfSyncErrorMissingUsers)(error);
482
+ await this.addUsersToMLSConversation({
483
+ groupId,
484
+ conversationId: conversation.qualified_id,
485
+ qualifiedUsers: missingUsers,
486
+ });
487
+ }
488
+ }
489
+ catch (error) {
490
+ this.logger.error('Failed to react to key material update failure', { error, groupId });
491
+ }
492
+ finally {
493
+ this.recoveringKeyMaterialGroups.delete(groupId);
494
+ }
495
+ };
390
496
  async resetMLSConversation(conversationId) {
391
497
  this.logger.info(`Resetting MLS conversation with id ${conversationId.id}`);
392
498
  // STEP 1: Fetch the conversation to retrieve the group ID & epoch
@@ -50,6 +50,7 @@ const api_client_1 = require("@wireapp/api-client");
50
50
  const core_crypto_1 = require("@wireapp/core-crypto");
51
51
  const __1 = require("..");
52
52
  const CoreCryptoMLSError_1 = require("../../messagingProtocols/mls/MLSService/CoreCryptoMLSError");
53
+ const MLSService_1 = require("../../messagingProtocols/mls/MLSService/MLSService");
53
54
  const MessagingProtocols = __importStar(require("../../messagingProtocols/proteus"));
54
55
  const CoreDB_1 = require("../../storage/CoreDB");
55
56
  const PayloadHelper = __importStar(require("../../test/PayloadHelper"));
@@ -643,6 +644,154 @@ describe('ConversationService', () => {
643
644
  expect(conversationService.addUsersToMLSConversation).not.toHaveBeenCalled();
644
645
  });
645
646
  });
647
+ describe('reactToKeyMaterialUpdateFailure', () => {
648
+ function getKeyMaterialFailureHandler(mlsService) {
649
+ const onMock = mlsService.on;
650
+ const call = onMock.mock.calls.find(([event]) => event === MLSService_1.MLSServiceEvents.KEY_MATERIAL_UPDATE_FAILURE);
651
+ expect(call).toBeTruthy();
652
+ return call[1];
653
+ }
654
+ it('resets a broken MLS conversation', async () => {
655
+ const [conversationService, { apiClient, mlsService }] = await buildConversationService();
656
+ const groupId = 'group-1';
657
+ const qualified_id = { id: 'conv-1', domain: 'staging.zinfra.io' };
658
+ jest.spyOn(apiClient.api.conversation, 'getConversationList').mockResolvedValueOnce({
659
+ found: [{ group_id: groupId, qualified_id, protocol: conversation_1.ConversationProtocol.MLS, epoch: 1 }],
660
+ });
661
+ const resetSpy = jest
662
+ .spyOn(conversationService, 'handleBrokenMLSConversation')
663
+ .mockResolvedValue(undefined);
664
+ const addUsersSpy = jest.spyOn(conversationService, 'addUsersToMLSConversation');
665
+ const handler = getKeyMaterialFailureHandler(mlsService);
666
+ const brokenErr = {
667
+ type: core_crypto_1.ErrorType.Mls,
668
+ context: {
669
+ type: core_crypto_1.MlsErrorType.MessageRejected,
670
+ context: {
671
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION }),
672
+ },
673
+ },
674
+ };
675
+ await handler({ error: brokenErr, groupId });
676
+ expect(resetSpy).toHaveBeenCalledWith(qualified_id);
677
+ expect(addUsersSpy).not.toHaveBeenCalled();
678
+ });
679
+ it('adds missing users when group is out of sync', async () => {
680
+ const [conversationService, { apiClient, mlsService }] = await buildConversationService();
681
+ const groupId = 'group-2';
682
+ const qualified_id = { id: 'conv-2', domain: 'staging.zinfra.io' };
683
+ const missingUsers = [
684
+ { id: 'u1', domain: 'staging.zinfra.io' },
685
+ { id: 'u2', domain: 'staging.zinfra.io' },
686
+ ];
687
+ jest.spyOn(apiClient.api.conversation, 'getConversationList').mockResolvedValueOnce({
688
+ found: [{ group_id: groupId, qualified_id, protocol: conversation_1.ConversationProtocol.MLS, epoch: 1 }],
689
+ });
690
+ const addUsersSpy = jest
691
+ .spyOn(conversationService, 'addUsersToMLSConversation')
692
+ .mockResolvedValue({ conversation: {} });
693
+ const resetSpy = jest
694
+ .spyOn(conversationService, 'handleBrokenMLSConversation')
695
+ .mockResolvedValue(undefined);
696
+ const handler = getKeyMaterialFailureHandler(mlsService);
697
+ const outOfSyncErr = {
698
+ type: core_crypto_1.ErrorType.Mls,
699
+ context: {
700
+ type: core_crypto_1.MlsErrorType.MessageRejected,
701
+ context: {
702
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({
703
+ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_GROUP_OUT_OF_SYNC,
704
+ missing_users: missingUsers,
705
+ }),
706
+ },
707
+ },
708
+ };
709
+ await handler({ error: outOfSyncErr, groupId });
710
+ expect(addUsersSpy).toHaveBeenCalledWith({
711
+ groupId,
712
+ conversationId: qualified_id,
713
+ qualifiedUsers: missingUsers,
714
+ });
715
+ expect(resetSpy).not.toHaveBeenCalled();
716
+ });
717
+ it('deduplicates concurrent recoveries for the same group id', async () => {
718
+ const [conversationService, { apiClient, mlsService }] = await buildConversationService();
719
+ const groupId = 'group-dup';
720
+ const qualified_id = { id: 'conv-dup', domain: 'staging.zinfra.io' };
721
+ jest.spyOn(apiClient.api.conversation, 'getConversationList').mockResolvedValue({
722
+ found: [{ group_id: groupId, qualified_id, protocol: conversation_1.ConversationProtocol.MLS, epoch: 1 }],
723
+ });
724
+ // Make the recovery hang until we resolve it, to simulate overlapping calls
725
+ let resolveDeferred;
726
+ const deferred = new Promise(res => (resolveDeferred = res));
727
+ const resetSpy = jest
728
+ .spyOn(conversationService, 'handleBrokenMLSConversation')
729
+ .mockReturnValue(deferred);
730
+ const handler = getKeyMaterialFailureHandler(mlsService);
731
+ const brokenErr = {
732
+ type: core_crypto_1.ErrorType.Mls,
733
+ context: {
734
+ type: core_crypto_1.MlsErrorType.MessageRejected,
735
+ context: {
736
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION }),
737
+ },
738
+ },
739
+ };
740
+ const p1 = handler({ error: brokenErr, groupId });
741
+ const p2 = handler({ error: brokenErr, groupId });
742
+ // Complete the first recovery
743
+ if (resolveDeferred) {
744
+ resolveDeferred();
745
+ }
746
+ await Promise.allSettled([p1, p2]);
747
+ expect(resetSpy).toHaveBeenCalledTimes(1);
748
+ });
749
+ });
750
+ describe('groupIdConversationMap cache', () => {
751
+ function makeConversation(group_id, id) {
752
+ return {
753
+ group_id,
754
+ qualified_id: { id, domain: 'staging.zinfra.io' },
755
+ protocol: conversation_1.ConversationProtocol.MLS,
756
+ epoch: 1,
757
+ };
758
+ }
759
+ it('refreshGroupIdConversationMap builds the cache from backend list', async () => {
760
+ const [conversationService, { apiClient }] = await buildConversationService();
761
+ const conv1 = makeConversation('g-1', 'c-1');
762
+ const conv2 = makeConversation('g-2', 'c-2');
763
+ const getListSpy = jest
764
+ .spyOn(apiClient.api.conversation, 'getConversationList')
765
+ .mockResolvedValueOnce({ found: [conv1, conv2] });
766
+ await conversationService.refreshGroupIdConversationMap();
767
+ expect(getListSpy).toHaveBeenCalledTimes(1);
768
+ // Validate through the private cache map
769
+ const cache = conversationService.groupIdConversationMap;
770
+ expect(cache.get('g-1')?.qualified_id.id).toBe('c-1');
771
+ expect(cache.get('g-2')?.qualified_id.id).toBe('c-2');
772
+ });
773
+ it('getConversationByGroupId uses cache when available without backend call', async () => {
774
+ const [conversationService, { apiClient }] = await buildConversationService();
775
+ const conv = makeConversation('g-hit', 'c-hit');
776
+ // Pre-populate cache
777
+ conversationService.groupIdConversationMap.set('g-hit', conv);
778
+ const getListSpy = jest
779
+ .spyOn(apiClient.api.conversation, 'getConversationList')
780
+ .mockImplementation(() => Promise.reject(new Error('should not be called')));
781
+ const result = await conversationService.getConversationByGroupId('g-hit');
782
+ expect(result?.qualified_id.id).toBe('c-hit');
783
+ expect(getListSpy).not.toHaveBeenCalled();
784
+ });
785
+ it('getConversationByGroupId refreshes on cache miss and returns undefined if not found', async () => {
786
+ const [conversationService, { apiClient }] = await buildConversationService();
787
+ const getListSpy = jest
788
+ .spyOn(apiClient.api.conversation, 'getConversationList')
789
+ .mockResolvedValueOnce({ found: [makeConversation('g-else', 'c-else')] });
790
+ const result = await conversationService.getConversationByGroupId('g-missing');
791
+ expect(result).toBeUndefined();
792
+ expect(getListSpy).toHaveBeenCalledTimes(1);
793
+ });
794
+ });
646
795
  });
647
796
  function generateImage() {
648
797
  const image = {
@@ -1,3 +1,5 @@
1
+ import { QualifiedId } from '@wireapp/api-client/lib/user';
2
+ import { CoreCryptoError, ErrorContext, ErrorType, MlsErrorType } from '@wireapp/core-crypto';
1
3
  export declare const CORE_CRYPTO_ERROR_NAMES: {
2
4
  MlsErrorConversationAlreadyExists: string;
3
5
  MlsErrorDuplicateMessage: string;
@@ -15,4 +17,35 @@ export declare const CORE_CRYPTO_ERROR_NAMES: {
15
17
  export declare const isCoreCryptoMLSWrongEpochError: (error: unknown) => boolean;
16
18
  export declare const isCoreCryptoMLSConversationAlreadyExistsError: (error: unknown) => boolean;
17
19
  export declare const shouldMLSDecryptionErrorBeIgnored: (error: unknown) => error is Error;
20
+ export declare const UPLOAD_COMMIT_BUNDLE_ABORT_REASONS: {
21
+ BROKEN_MLS_CONVERSATION: string;
22
+ MLS_STALE_MESSAGE: string;
23
+ MLS_GROUP_OUT_OF_SYNC: string;
24
+ OTHER: string;
25
+ };
26
+ type MessageRejectedError = CoreCryptoError<ErrorType.Mls> & {
27
+ context: Extract<ErrorContext[ErrorType.Mls], {
28
+ type: MlsErrorType.MessageRejected;
29
+ }>;
30
+ };
31
+ export declare function isBrokenMLSConversationError(error: unknown): error is MessageRejectedError;
32
+ export declare function isMLSStaleMessageError(error: unknown): error is MessageRejectedError;
33
+ export declare function isMLSGroupOutOfSyncError(error: unknown): error is MessageRejectedError;
34
+ export declare function getMLSGroupOutOfSyncErrorMissingUsers(error: unknown): QualifiedId[];
35
+ type AbortReasonBrokenMLSConversation = {
36
+ message: typeof UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION;
37
+ };
38
+ type AbortReasonMLSStaleMessage = {
39
+ message: typeof UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE;
40
+ };
41
+ type AbortReasonMLSGroupOutOfSync = {
42
+ message: typeof UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_GROUP_OUT_OF_SYNC;
43
+ missing_users: QualifiedId[];
44
+ };
45
+ type AbortReasonOther = {
46
+ message: typeof UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.OTHER;
47
+ };
48
+ type AbortReasons = AbortReasonBrokenMLSConversation | AbortReasonMLSStaleMessage | AbortReasonMLSGroupOutOfSync | AbortReasonOther;
49
+ export declare function serializeAbortReason(reason: AbortReasons): string;
50
+ export {};
18
51
  //# sourceMappingURL=CoreCryptoMLSError.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CoreCryptoMLSError.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/CoreCryptoMLSError.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;CAanC,CAAC;AAEF,eAAO,MAAM,8BAA8B,UAAW,OAAO,KAAG,OAE/D,CAAC;AAEF,eAAO,MAAM,6CAA6C,UAAW,OAAO,KAAG,OAE9E,CAAC;AAoBF,eAAO,MAAM,iCAAiC,UAAW,OAAO,KAAG,KAAK,IAAI,KAI3E,CAAC"}
1
+ {"version":3,"file":"CoreCryptoMLSError.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/CoreCryptoMLSError.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAC,eAAe,EAAE,YAAY,EAAE,SAAS,EAA6B,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAEvH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;CAanC,CAAC;AAEF,eAAO,MAAM,8BAA8B,UAAW,OAAO,KAAG,OAE/D,CAAC;AAEF,eAAO,MAAM,6CAA6C,UAAW,OAAO,KAAG,OAE9E,CAAC;AAoBF,eAAO,MAAM,iCAAiC,UAAW,OAAO,KAAG,KAAK,IAAI,KAI3E,CAAC;AAEF,eAAO,MAAM,kCAAkC;;;;;CAK9C,CAAC;AAEF,KAAK,oBAAoB,GAAG,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG;IAC3D,OAAO,EAAE,OAAO,CACd,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,EAC3B;QACE,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC;KACpC,CACF,CAAC;CACH,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAM1F;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAMpF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAMtF;AAED,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,EAAE,CAOnF;AAED,KAAK,gCAAgC,GAAG;IACtC,OAAO,EAAE,OAAO,kCAAkC,CAAC,uBAAuB,CAAC;CAC5E,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,OAAO,EAAE,OAAO,kCAAkC,CAAC,iBAAiB,CAAC;CACtE,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC,OAAO,EAAE,OAAO,kCAAkC,CAAC,qBAAqB,CAAC;IACzE,aAAa,EAAE,WAAW,EAAE,CAAC;CAC9B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,OAAO,EAAE,OAAO,kCAAkC,CAAC,KAAK,CAAC;CAC1D,CAAC;AAEF,KAAK,YAAY,GACb,gCAAgC,GAChC,0BAA0B,GAC1B,4BAA4B,GAC5B,gBAAgB,CAAC;AAErB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEjE"}
@@ -18,7 +18,13 @@
18
18
  *
19
19
  */
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.shouldMLSDecryptionErrorBeIgnored = exports.isCoreCryptoMLSConversationAlreadyExistsError = exports.isCoreCryptoMLSWrongEpochError = exports.CORE_CRYPTO_ERROR_NAMES = void 0;
21
+ exports.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS = exports.shouldMLSDecryptionErrorBeIgnored = exports.isCoreCryptoMLSConversationAlreadyExistsError = exports.isCoreCryptoMLSWrongEpochError = exports.CORE_CRYPTO_ERROR_NAMES = void 0;
22
+ exports.isBrokenMLSConversationError = isBrokenMLSConversationError;
23
+ exports.isMLSStaleMessageError = isMLSStaleMessageError;
24
+ exports.isMLSGroupOutOfSyncError = isMLSGroupOutOfSyncError;
25
+ exports.getMLSGroupOutOfSyncErrorMissingUsers = getMLSGroupOutOfSyncErrorMissingUsers;
26
+ exports.serializeAbortReason = serializeAbortReason;
27
+ const core_crypto_1 = require("@wireapp/core-crypto");
22
28
  exports.CORE_CRYPTO_ERROR_NAMES = {
23
29
  MlsErrorConversationAlreadyExists: 'MlsErrorConversationAlreadyExists',
24
30
  MlsErrorDuplicateMessage: 'MlsErrorDuplicateMessage',
@@ -59,3 +65,37 @@ const shouldMLSDecryptionErrorBeIgnored = (error) => {
59
65
  return (error instanceof Error && (mlsDecryptionErrorNamesToIgnore.includes(error.name) || isOtherErrorToIgnore(error)));
60
66
  };
61
67
  exports.shouldMLSDecryptionErrorBeIgnored = shouldMLSDecryptionErrorBeIgnored;
68
+ exports.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS = {
69
+ BROKEN_MLS_CONVERSATION: 'BROKEN_MLS_CONVERSATION',
70
+ MLS_STALE_MESSAGE: 'MLS_STALE_MESSAGE',
71
+ MLS_GROUP_OUT_OF_SYNC: 'MLS_GROUP_OUT_OF_SYNC',
72
+ OTHER: 'OTHER',
73
+ };
74
+ function isBrokenMLSConversationError(error) {
75
+ return ((0, core_crypto_1.isMlsMessageRejectedError)(error) &&
76
+ deserializeAbortReason(error.context.context.reason).message ===
77
+ exports.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION);
78
+ }
79
+ function isMLSStaleMessageError(error) {
80
+ return ((0, core_crypto_1.isMlsMessageRejectedError)(error) &&
81
+ deserializeAbortReason(error.context.context.reason).message ===
82
+ exports.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE);
83
+ }
84
+ function isMLSGroupOutOfSyncError(error) {
85
+ return ((0, core_crypto_1.isMlsMessageRejectedError)(error) &&
86
+ deserializeAbortReason(error.context.context.reason).message ===
87
+ exports.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_GROUP_OUT_OF_SYNC);
88
+ }
89
+ function getMLSGroupOutOfSyncErrorMissingUsers(error) {
90
+ if (isMLSGroupOutOfSyncError(error)) {
91
+ const reason = deserializeAbortReason(error.context.context.reason);
92
+ return reason.missing_users;
93
+ }
94
+ throw new Error('Error is not MLSGroupOutOfSyncError');
95
+ }
96
+ function serializeAbortReason(reason) {
97
+ return JSON.stringify(reason);
98
+ }
99
+ function deserializeAbortReason(reasonString) {
100
+ return JSON.parse(reasonString);
101
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=CoreCryptoMLSError.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoreCryptoMLSError.test.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,124 @@
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 core_crypto_1 = require("@wireapp/core-crypto");
22
+ const CoreCryptoMLSError_1 = require("./CoreCryptoMLSError");
23
+ describe('CoreCryptoMLSError helpers', () => {
24
+ describe('epoch and conversation existence guards', () => {
25
+ it('detects MlsErrorWrongEpoch by name', () => {
26
+ const err = new Error('wrong epoch');
27
+ err.name = CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorWrongEpoch;
28
+ expect((0, CoreCryptoMLSError_1.isCoreCryptoMLSWrongEpochError)(err)).toBe(true);
29
+ const other = new Error('nope');
30
+ expect((0, CoreCryptoMLSError_1.isCoreCryptoMLSWrongEpochError)(other)).toBe(false);
31
+ expect((0, CoreCryptoMLSError_1.isCoreCryptoMLSWrongEpochError)('not-an-error')).toBe(false);
32
+ });
33
+ it('detects MlsErrorConversationAlreadyExists by name', () => {
34
+ const err = new Error('already exists');
35
+ err.name = CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorConversationAlreadyExists;
36
+ expect((0, CoreCryptoMLSError_1.isCoreCryptoMLSConversationAlreadyExistsError)(err)).toBe(true);
37
+ const other = new Error('nope');
38
+ expect((0, CoreCryptoMLSError_1.isCoreCryptoMLSConversationAlreadyExistsError)(other)).toBe(false);
39
+ expect((0, CoreCryptoMLSError_1.isCoreCryptoMLSConversationAlreadyExistsError)(42)).toBe(false);
40
+ });
41
+ });
42
+ describe('shouldMLSDecryptionErrorBeIgnored', () => {
43
+ const namesToIgnore = [
44
+ CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorStaleCommit,
45
+ CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorStaleProposal,
46
+ CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorDuplicateMessage,
47
+ CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorBufferedFutureMessage,
48
+ CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorUnmergedPendingGroup,
49
+ ];
50
+ it('returns true for known ignorable error names', () => {
51
+ for (const name of namesToIgnore) {
52
+ const err = new Error('ignore me');
53
+ err.name = name;
54
+ expect((0, CoreCryptoMLSError_1.shouldMLSDecryptionErrorBeIgnored)(err)).toBe(true);
55
+ }
56
+ });
57
+ it('returns true for generic MlsErrorOther with expected commit/proposals message', () => {
58
+ const err = new Error('Incoming message is a commit for which we have not yet received all the proposals: details...');
59
+ err.name = CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorOther;
60
+ expect((0, CoreCryptoMLSError_1.shouldMLSDecryptionErrorBeIgnored)(err)).toBe(true);
61
+ });
62
+ it('returns false for other errors or non-Error values', () => {
63
+ const err = new Error('some real failure');
64
+ err.name = 'RandomErrorName';
65
+ expect((0, CoreCryptoMLSError_1.shouldMLSDecryptionErrorBeIgnored)(err)).toBe(false);
66
+ expect((0, CoreCryptoMLSError_1.shouldMLSDecryptionErrorBeIgnored)('not-an-error')).toBe(false);
67
+ });
68
+ });
69
+ describe('abort reason based guards', () => {
70
+ function makeRejectedError(reason) {
71
+ return {
72
+ type: core_crypto_1.ErrorType.Mls,
73
+ context: {
74
+ type: core_crypto_1.MlsErrorType.MessageRejected,
75
+ context: {
76
+ reason,
77
+ },
78
+ },
79
+ };
80
+ }
81
+ it('detects broken MLS conversation errors', () => {
82
+ const err = makeRejectedError((0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION }));
83
+ expect((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(err)).toBe(true);
84
+ expect((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(err)).toBe(false);
85
+ expect((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(err)).toBe(false);
86
+ });
87
+ it('detects MLS stale message errors', () => {
88
+ const err = makeRejectedError((0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }));
89
+ expect((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(err)).toBe(true);
90
+ expect((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(err)).toBe(false);
91
+ expect((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(err)).toBe(false);
92
+ });
93
+ it('detects MLS group out-of-sync errors and exposes missing users', () => {
94
+ const missing = [
95
+ { id: 'u1', domain: 'example.com' },
96
+ { id: 'u2', domain: 'example.com' },
97
+ ];
98
+ const err = makeRejectedError((0, CoreCryptoMLSError_1.serializeAbortReason)({
99
+ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_GROUP_OUT_OF_SYNC,
100
+ missing_users: missing,
101
+ }));
102
+ expect((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(err)).toBe(true);
103
+ expect((0, CoreCryptoMLSError_1.getMLSGroupOutOfSyncErrorMissingUsers)(err)).toEqual(missing);
104
+ });
105
+ it('throws when getting missing users from non-MLSGroupOutOfSync error', () => {
106
+ const err = makeRejectedError((0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }));
107
+ expect(() => (0, CoreCryptoMLSError_1.getMLSGroupOutOfSyncErrorMissingUsers)(err)).toThrow('Error is not MLSGroupOutOfSyncError');
108
+ });
109
+ it('returns false for non-mls message rejected errors', () => {
110
+ const err = {
111
+ type: core_crypto_1.ErrorType.Mls,
112
+ context: {
113
+ type: core_crypto_1.MlsErrorType.Other,
114
+ context: {
115
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }),
116
+ },
117
+ },
118
+ };
119
+ expect((0, CoreCryptoMLSError_1.isBrokenMLSConversationError)(err)).toBe(false);
120
+ expect((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(err)).toBe(false);
121
+ expect((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(err)).toBe(false);
122
+ });
123
+ });
124
+ });
@@ -34,9 +34,14 @@ export declare enum MLSServiceEvents {
34
34
  NEW_EPOCH = "newEpoch",
35
35
  MLS_CLIENT_MISMATCH = "mlsClientMismatch",
36
36
  NEW_CRL_DISTRIBUTION_POINTS = "newCrlDistributionPoints",
37
- MLS_EVENT_DISTRIBUTED = "mlsEventDistributed"
37
+ MLS_EVENT_DISTRIBUTED = "mlsEventDistributed",
38
+ KEY_MATERIAL_UPDATE_FAILURE = "keyMaterialUpdateFailure"
38
39
  }
39
40
  type Events = {
41
+ [MLSServiceEvents.KEY_MATERIAL_UPDATE_FAILURE]: {
42
+ error: unknown;
43
+ groupId: string;
44
+ };
40
45
  [MLSServiceEvents.NEW_EPOCH]: {
41
46
  epoch: number;
42
47
  groupId: string;
@@ -57,13 +62,6 @@ export declare class MLSService extends TypedEventEmitter<Events> {
57
62
  private _config?;
58
63
  private readonly textEncoder;
59
64
  private readonly textDecoder;
60
- static UPLOAD_COMMIT_BUNDLE_ABORT_REASONS: {
61
- BROKEN_MLS_CONVERSATION: string;
62
- MLS_STALE_MESSAGE: string;
63
- OTHER: string;
64
- };
65
- static isBrokenMLSConversationError(error: unknown): boolean;
66
- static isMLSStaleMessageError(error: unknown): boolean;
67
65
  constructor(apiClient: APIClient, coreCryptoClient: CoreCrypto, coreDatabase: CoreDatabase, recurringTaskScheduler: RecurringTaskScheduler);
68
66
  /**
69
67
  * return true if the MLS service if configured and ready to be used
@@ -1 +1 @@
1
- {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,7 @@ var MLSServiceEvents;
49
49
  MLSServiceEvents["MLS_CLIENT_MISMATCH"] = "mlsClientMismatch";
50
50
  MLSServiceEvents["NEW_CRL_DISTRIBUTION_POINTS"] = "newCrlDistributionPoints";
51
51
  MLSServiceEvents["MLS_EVENT_DISTRIBUTED"] = "mlsEventDistributed";
52
+ MLSServiceEvents["KEY_MATERIAL_UPDATE_FAILURE"] = "keyMaterialUpdateFailure";
52
53
  })(MLSServiceEvents || (exports.MLSServiceEvents = MLSServiceEvents = {}));
53
54
  class MLSService extends commons_1.TypedEventEmitter {
54
55
  apiClient;
@@ -59,19 +60,6 @@ class MLSService extends commons_1.TypedEventEmitter {
59
60
  _config;
60
61
  textEncoder = new TextEncoder();
61
62
  textDecoder = new TextDecoder();
62
- static UPLOAD_COMMIT_BUNDLE_ABORT_REASONS = {
63
- BROKEN_MLS_CONVERSATION: 'BROKEN_MLS_CONVERSATION',
64
- MLS_STALE_MESSAGE: 'MLS_STALE_MESSAGE',
65
- OTHER: 'OTHER',
66
- };
67
- static isBrokenMLSConversationError(error) {
68
- return ((0, core_crypto_1.isMlsMessageRejectedError)(error) &&
69
- error.context.context.reason === MLSService.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION);
70
- }
71
- static isMLSStaleMessageError(error) {
72
- return ((0, core_crypto_1.isMlsMessageRejectedError)(error) &&
73
- error.context.context.reason === MLSService.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE);
74
- }
75
63
  constructor(apiClient, coreCryptoClient, coreDatabase, recurringTaskScheduler) {
76
64
  super();
77
65
  this.apiClient = apiClient;
@@ -192,18 +180,39 @@ class MLSService extends commons_1.TypedEventEmitter {
192
180
  if (error instanceof conversation_1.MLSInvalidLeafNodeSignatureError || error instanceof conversation_1.MLSInvalidLeafNodeIndexError) {
193
181
  this.logger.info('Aborting commit bundle upload due to broken MLS conversation');
194
182
  return {
195
- abort: { reason: MLSService.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION },
183
+ abort: {
184
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({
185
+ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.BROKEN_MLS_CONVERSATION,
186
+ }),
187
+ },
196
188
  };
197
189
  }
198
190
  if (error instanceof conversation_1.MLSStaleMessageError) {
199
191
  this.logger.info('Aborting commit bundle upload due to stale MLS message');
200
192
  return {
201
- abort: { reason: MLSService.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE },
193
+ abort: {
194
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }),
195
+ },
196
+ };
197
+ }
198
+ if (error instanceof conversation_1.MLSGroupOutOfSyncError) {
199
+ this.logger.info('Aborting commit bundle upload due to group out of sync');
200
+ return {
201
+ abort: {
202
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({
203
+ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_GROUP_OUT_OF_SYNC,
204
+ missing_users: error.missing_users,
205
+ }),
206
+ },
202
207
  };
203
208
  }
204
209
  this.logger.info('Aborting commit bundle upload due to unknown error');
205
210
  return {
206
- abort: { reason: error instanceof Error ? error.message : MLSService.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.OTHER },
211
+ abort: {
212
+ reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({
213
+ message: error instanceof Error ? error.message : CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.OTHER,
214
+ }),
215
+ },
207
216
  };
208
217
  }
209
218
  };
@@ -365,9 +374,33 @@ class MLSService extends commons_1.TypedEventEmitter {
365
374
  async encryptMessage(conversationId, message) {
366
375
  return this.coreCryptoClient.transaction(cx => cx.encryptMessage(conversationId, message));
367
376
  }
368
- async updateKeyingMaterial(groupId) {
369
- const groupIdBytes = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
370
- await this.coreCryptoClient.transaction(cx => cx.updateKeyingMaterial(new core_crypto_1.ConversationId(groupIdBytes)));
377
+ async updateKeyingMaterial(groupId, retry = true) {
378
+ try {
379
+ const groupIdBytes = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
380
+ await this.coreCryptoClient.transaction(cx => cx.updateKeyingMaterial(new core_crypto_1.ConversationId(groupIdBytes)));
381
+ }
382
+ catch (error) {
383
+ if (!retry) {
384
+ this.logger.error(`Failed to update keying material for group retrying did not fix the issue`, {
385
+ error,
386
+ groupId,
387
+ });
388
+ throw error;
389
+ }
390
+ this.logger.warn(`Failed to update keying material for group`, { error, groupId });
391
+ this.emit(MLSServiceEvents.KEY_MATERIAL_UPDATE_FAILURE, { error, groupId });
392
+ setTimeout(async () => {
393
+ try {
394
+ await this.updateKeyingMaterial(groupId, false);
395
+ }
396
+ catch (error) {
397
+ this.logger.error(`Failed to update keying material for group on retry`, {
398
+ error,
399
+ groupId,
400
+ });
401
+ }
402
+ }, commons_1.TimeUtil.TimeInMillis.SECOND * 10); // retry after 10 seconds
403
+ }
371
404
  }
372
405
  /**
373
406
  * Will create an empty conversation inside of coreCrypto.
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "./lib/cryptography/AssetCryptography/crypto.node": "./lib/cryptography/AssetCryptography/crypto.browser.js"
12
12
  },
13
13
  "dependencies": {
14
- "@wireapp/api-client": "^27.84.0",
14
+ "@wireapp/api-client": "^27.85.0",
15
15
  "@wireapp/commons": "^5.4.9",
16
16
  "@wireapp/core-crypto": "9.1.0",
17
17
  "@wireapp/cryptobox": "12.8.0",
@@ -61,6 +61,6 @@
61
61
  "test:coverage": "jest --coverage",
62
62
  "watch": "tsc --watch"
63
63
  },
64
- "version": "46.40.8",
65
- "gitHead": "0bfd815a30fb26b6fb514a550ae93cc6e285c77a"
64
+ "version": "46.42.0",
65
+ "gitHead": "90f056dc3490066658b4880b1d65093f8f1793f7"
66
66
  }