@wireapp/core 45.0.12 → 45.1.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.
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.d.ts +3 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.js +4 -4
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.test.js +9 -8
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +3 -1
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/MLSService/MLSService.js +20 -24
- package/lib/util/qualifiedIdUtil.d.ts +2 -1
- package/lib/util/qualifiedIdUtil.d.ts.map +1 -1
- package/package.json +6 -5
|
@@ -3,11 +3,13 @@ import { TypedEventEmitter } from '@wireapp/commons';
|
|
|
3
3
|
import { CoreCrypto, E2eiConversationState, WireIdentity, DeviceStatus } from '@wireapp/core-crypto';
|
|
4
4
|
import { ClientService } from '../../../client';
|
|
5
5
|
import { CoreDatabase } from '../../../storage/CoreDB';
|
|
6
|
+
import { StringifiedQualifiedId } from '../../../util/qualifiedIdUtil';
|
|
6
7
|
import { RecurringTaskScheduler } from '../../../util/RecurringTaskScheduler';
|
|
7
8
|
import { MLSService } from '../MLSService';
|
|
8
9
|
export type DeviceIdentity = Omit<WireIdentity, 'free' | 'status'> & {
|
|
9
10
|
status?: DeviceStatus;
|
|
10
11
|
deviceId: string;
|
|
12
|
+
qualifiedUserId: QualifiedId;
|
|
11
13
|
};
|
|
12
14
|
type Events = {
|
|
13
15
|
crlChanged: {
|
|
@@ -28,7 +30,7 @@ export declare class E2EIServiceExternal extends TypedEventEmitter<Events> {
|
|
|
28
30
|
getConversationState(conversationId: Uint8Array): Promise<E2eiConversationState>;
|
|
29
31
|
isE2EIEnabled(): Promise<boolean>;
|
|
30
32
|
getAllGroupUsersIdentities(groupId: string): Promise<Map<string, DeviceIdentity[]> | undefined>;
|
|
31
|
-
getUsersIdentities(groupId: string, userIds: QualifiedId[]): Promise<Map<
|
|
33
|
+
getUsersIdentities(groupId: string, userIds: QualifiedId[]): Promise<Map<StringifiedQualifiedId, DeviceIdentity[]> | undefined>;
|
|
32
34
|
getDevicesIdentities(groupId: string, userClientsMap: Record<string, QualifiedId>): Promise<DeviceIdentity[]>;
|
|
33
35
|
isFreshMLSSelfClient(): Promise<boolean>;
|
|
34
36
|
private registerLocalCertificateRoot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"E2EIServiceExternal.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAIzD,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAC,UAAU,EAAE,qBAAqB,EAAE,YAAY,EAAE,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAMnG,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAC,YAAY,EAAC,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"E2EIServiceExternal.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAIzD,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAC,UAAU,EAAE,qBAAqB,EAAE,YAAY,EAAE,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAMnG,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAC,YAAY,EAAC,MAAM,yBAAyB,CAAC;AAIrD,OAAO,EAAC,sBAAsB,EAAuB,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAC,sBAAsB,EAAC,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG;IACnE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,WAAW,CAAC;CAC9B,CAAC;AAEF,KAAK,MAAM,GAAG;IACZ,UAAU,EAAE;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,CAAC;CAC9B,CAAC;AAGF,qBAAa,mBAAoB,SAAQ,iBAAiB,CAAC,MAAM,CAAC;IAK9D,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR7B,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAiD;gBAGhE,gBAAgB,EAAE,UAAU,EAC5B,YAAY,EAAE,YAAY,EAC1B,sBAAsB,EAAE,sBAAsB,EAC9C,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU;IAU5B,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC;IAKhD,gBAAgB;IAIhB,oBAAoB,CAAC,cAAc,EAAE,UAAU,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAIhF,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAI3B,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,GAAG,SAAS,CAAC;IAsB/F,kBAAkB,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,WAAW,EAAE,GACrB,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,cAAc,EAAE,CAAC,GAAG,SAAS,CAAC;IAwDxD,oBAAoB,CAC/B,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAC1C,OAAO,CAAC,cAAc,EAAE,CAAC;IAgBf,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;YAQvC,4BAA4B;IAO1C;;;;;OAKG;IACU,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5D,OAAO,KAAK,WAAW,GAKtB;YAEa,+BAA+B;IAK7C;;;;;;;;;;;;OAYG;YACW,0BAA0B;IA6BxC,OAAO,CAAC,4BAA4B;YAStB,+BAA+B;YAQ/B,uBAAuB;YAKvB,0BAA0B;YAI1B,4BAA4B;YAO5B,WAAW;YAkBX,8BAA8B;CAK7C"}
|
|
@@ -84,14 +84,14 @@ class E2EIServiceExternal extends commons_1.TypedEventEmitter {
|
|
|
84
84
|
.map(fullyQualifiedId => (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(fullyQualifiedId));
|
|
85
85
|
const mappedUserIdentities = new Map();
|
|
86
86
|
for (const userId of userIds) {
|
|
87
|
-
const identities = (userIdentities.get(userId.id) || []).map(identity => (Object.assign(Object.assign({}, identity), { deviceId: (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(identity.clientId).client })));
|
|
87
|
+
const identities = (userIdentities.get(userId.id) || []).map(identity => (Object.assign(Object.assign({}, identity), { deviceId: (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(identity.clientId).client, qualifiedUserId: userId })));
|
|
88
88
|
const basicMLSDevices = allUsersMLSDevices
|
|
89
89
|
.filter(({ user }) => user === userId.id)
|
|
90
90
|
// filtering devices that have a valid identity
|
|
91
91
|
.filter(({ client }) => !identities.map(identity => identity.deviceId).includes(client))
|
|
92
92
|
// map basic MLS devices to "fake" identity object
|
|
93
|
-
.map(id => (Object.assign(Object.assign({}, id), { deviceId: id.client, thumbprint: '', user: '', certificate: '', displayName: '', handle: '', notAfter: BigInt(0), notBefore: BigInt(0), serialNumber: '', clientId: id.client })));
|
|
94
|
-
mappedUserIdentities.set(userId
|
|
93
|
+
.map(id => (Object.assign(Object.assign({}, id), { deviceId: id.client, thumbprint: '', user: '', certificate: '', displayName: '', handle: '', notAfter: BigInt(0), notBefore: BigInt(0), serialNumber: '', clientId: id.client, qualifiedUserId: userId })));
|
|
94
|
+
mappedUserIdentities.set((0, qualifiedIdUtil_1.stringifyQualifiedId)(userId), [...identities, ...basicMLSDevices]);
|
|
95
95
|
}
|
|
96
96
|
return mappedUserIdentities;
|
|
97
97
|
}
|
|
@@ -99,7 +99,7 @@ class E2EIServiceExternal extends commons_1.TypedEventEmitter {
|
|
|
99
99
|
async getDevicesIdentities(groupId, userClientsMap) {
|
|
100
100
|
const clientIds = Object.entries(userClientsMap).map(([clientId, userId]) => (0, Helper_1.getE2EIClientId)(clientId, userId.id, userId.domain).asBytes);
|
|
101
101
|
const deviceIdentities = await this.coreCryptoClient.getDeviceIdentities(bazinga64_1.Decoder.fromBase64(groupId).asBytes, clientIds);
|
|
102
|
-
return deviceIdentities.map(identity => (Object.assign(Object.assign({}, identity), { deviceId: (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(identity.clientId).client })));
|
|
102
|
+
return deviceIdentities.map(identity => (Object.assign(Object.assign({}, identity), { deviceId: (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(identity.clientId).client, qualifiedUserId: userClientsMap[identity.clientId] })));
|
|
103
103
|
}
|
|
104
104
|
async isFreshMLSSelfClient() {
|
|
105
105
|
const client = await this.clientService.loadClient();
|
|
@@ -21,6 +21,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
21
21
|
const E2EIServiceExternal_1 = require("./E2EIServiceExternal");
|
|
22
22
|
const CoreDB_1 = require("../../../storage/CoreDB");
|
|
23
23
|
const PayloadHelper_1 = require("../../../test/PayloadHelper");
|
|
24
|
+
const qualifiedIdUtil_1 = require("../../../util/qualifiedIdUtil");
|
|
24
25
|
const RecurringTaskScheduler_1 = require("../../../util/RecurringTaskScheduler");
|
|
25
26
|
async function buildE2EIService() {
|
|
26
27
|
const coreCrypto = {
|
|
@@ -67,8 +68,8 @@ describe('E2EIServiceExternal', () => {
|
|
|
67
68
|
const userIds = [user1, user2];
|
|
68
69
|
jest.spyOn(mlsService, 'conversationExists').mockResolvedValue(false);
|
|
69
70
|
const userIdentities = await service.getUsersIdentities(groupId, userIds);
|
|
70
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(
|
|
71
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(
|
|
71
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)(user1))).toEqual(undefined);
|
|
72
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)(user2))).toEqual(undefined);
|
|
72
73
|
});
|
|
73
74
|
it('returns the user identities', async () => {
|
|
74
75
|
const [service, { coreCrypto, mlsService }] = await buildE2EIService();
|
|
@@ -81,8 +82,8 @@ describe('E2EIServiceExternal', () => {
|
|
|
81
82
|
]));
|
|
82
83
|
jest.spyOn(mlsService, 'conversationExists').mockResolvedValue(true);
|
|
83
84
|
const userIdentities = await service.getUsersIdentities(groupId, userIds);
|
|
84
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(
|
|
85
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(
|
|
85
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)(user1))).toHaveLength(2);
|
|
86
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)(user2))).toHaveLength(1);
|
|
86
87
|
});
|
|
87
88
|
it('returns MLS basic devices with empty identity', async () => {
|
|
88
89
|
const [service, { coreCrypto, mlsService }] = await buildE2EIService();
|
|
@@ -103,8 +104,8 @@ describe('E2EIServiceExternal', () => {
|
|
|
103
104
|
coreCrypto.getClientIds.mockResolvedValue(allClients.map(clientId => encoder.encode(clientId)));
|
|
104
105
|
jest.spyOn(mlsService, 'conversationExists').mockResolvedValue(true);
|
|
105
106
|
const userIdentities = await service.getUsersIdentities(groupId, userIds);
|
|
106
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(
|
|
107
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(
|
|
107
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)(user1))).toHaveLength(3);
|
|
108
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)(user2))).toHaveLength(1);
|
|
108
109
|
});
|
|
109
110
|
});
|
|
110
111
|
describe('getAllGroupUsersIdentities', () => {
|
|
@@ -150,8 +151,8 @@ describe('E2EIServiceExternal', () => {
|
|
|
150
151
|
[user2.userId, [generateCoreCryptoIdentity({ userId: user2.userId })]],
|
|
151
152
|
]));
|
|
152
153
|
const userIdentities = await service.getAllGroupUsersIdentities(groupId);
|
|
153
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(user1.userId)).toHaveLength(2);
|
|
154
|
-
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get(user2.userId)).toHaveLength(1);
|
|
154
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)({ id: user1.userId, domain: user1.domain }))).toHaveLength(2);
|
|
155
|
+
expect(userIdentities === null || userIdentities === void 0 ? void 0 : userIdentities.get((0, qualifiedIdUtil_1.stringifyQualifiedId)({ id: user2.userId, domain: user2.domain }))).toHaveLength(1);
|
|
155
156
|
});
|
|
156
157
|
});
|
|
157
158
|
});
|
|
@@ -36,6 +36,7 @@ export declare class MLSService extends TypedEventEmitter<Events> {
|
|
|
36
36
|
config: LocalMLSServiceConfig;
|
|
37
37
|
private readonly textEncoder;
|
|
38
38
|
private readonly textDecoder;
|
|
39
|
+
private readonly conflictBackoffQueue;
|
|
39
40
|
constructor(apiClient: APIClient, coreCryptoClient: CoreCrypto, coreDatabase: CoreDatabase, recurringTaskScheduler: RecurringTaskScheduler, { keyingMaterialUpdateThreshold, nbKeyPackages, cipherSuite, }: Partial<MLSServiceConfig>);
|
|
40
41
|
/**
|
|
41
42
|
* Will initialize an MLS client
|
|
@@ -45,7 +46,8 @@ export declare class MLSService extends TypedEventEmitter<Events> {
|
|
|
45
46
|
*/
|
|
46
47
|
initClient(userId: QualifiedId, client: RegisteredClient, skipInitIdentity?: boolean): Promise<void>;
|
|
47
48
|
private getCredentialType;
|
|
48
|
-
private
|
|
49
|
+
private uploadCommitBundle;
|
|
50
|
+
private readonly _uploadCommitBundle;
|
|
49
51
|
/**
|
|
50
52
|
* Will add users to an existing MLS group and send a commit bundle to backend.
|
|
51
53
|
* Cannot be called with an empty array of keys.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAqB,gBAAgB,EAAC,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAC,sBAAsB,EAAE,kBAAkB,EAAC,MAAM,sCAAsC,CAAC;AAChG,OAAO,EAAC,8BAA8B,EAAE,2BAA2B,EAAC,MAAM,+BAA+B,CAAC;AAE1G,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,12 +34,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
35
|
exports.MLSService = exports.optionalToUint8Array = void 0;
|
|
36
36
|
const http_1 = require("@wireapp/api-client/lib/http");
|
|
37
|
-
const ExponentialBackoff_1 = require("@wireapp/commons/lib/util/ExponentialBackoff");
|
|
38
37
|
const TimeUtil_1 = require("@wireapp/commons/lib/util/TimeUtil");
|
|
39
38
|
const bazinga64_1 = require("bazinga64");
|
|
40
39
|
const logdown_1 = __importDefault(require("logdown"));
|
|
41
40
|
const commons_1 = require("@wireapp/commons");
|
|
42
41
|
const core_crypto_1 = require("@wireapp/core-crypto");
|
|
42
|
+
const priority_queue_1 = require("@wireapp/priority-queue");
|
|
43
43
|
const CoreCryptoMLSError_1 = require("./CoreCryptoMLSError");
|
|
44
44
|
const conversation_1 = require("../../../conversation");
|
|
45
45
|
const messageSender_1 = require("../../../conversation/message/messageSender");
|
|
@@ -72,17 +72,29 @@ class MLSService extends commons_1.TypedEventEmitter {
|
|
|
72
72
|
this.logger = (0, logdown_1.default)('@wireapp/core/MLSService');
|
|
73
73
|
this.textEncoder = new TextEncoder();
|
|
74
74
|
this.textDecoder = new TextDecoder();
|
|
75
|
-
this.
|
|
75
|
+
this.conflictBackoffQueue = new priority_queue_1.PriorityQueue({
|
|
76
|
+
maxRetries: 10,
|
|
77
|
+
retryDelay: 500,
|
|
78
|
+
maxRetryDelay: TimeUtil_1.TimeInMillis.SECOND * 32,
|
|
79
|
+
shouldRetry: error => error instanceof http_1.BackendError && error.code === http_1.StatusCode.CONFLICT,
|
|
80
|
+
});
|
|
81
|
+
this.uploadCommitBundle = async (groupId, commitBundle, { isExternalCommit = false, regenerateCommitBundle } = {}) => {
|
|
82
|
+
try {
|
|
83
|
+
return await this._uploadCommitBundle(groupId, async () => commitBundle, isExternalCommit);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error instanceof http_1.BackendError && error.code === http_1.StatusCode.CONFLICT && regenerateCommitBundle) {
|
|
87
|
+
return this.conflictBackoffQueue.add(async () => this._uploadCommitBundle(groupId, regenerateCommitBundle, isExternalCommit));
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
this._uploadCommitBundle = async (groupId, generateCommitBundle, isExternalCommit) => {
|
|
76
93
|
const groupIdStr = bazinga64_1.Encoder.toBase64(groupId).asString;
|
|
77
|
-
const backoffKey = `upload-commit-bundle-409-${groupIdStr}`;
|
|
78
|
-
const { backOff, resetBackOff } = (0, ExponentialBackoff_1.exponentialBackoff)(backoffKey, {
|
|
79
|
-
maxDelay: TimeUtil_1.TimeInMillis.SECOND * 32,
|
|
80
|
-
minDelay: TimeUtil_1.TimeInMillis.SECOND / 2,
|
|
81
|
-
});
|
|
82
94
|
// We need to lock the incoming mls messages queue while we are uploading the commit bundle
|
|
83
95
|
// it's possible that we will be sent some mls messages before we receive the response from backend and accept a commit locally.
|
|
84
96
|
return (0, messageAdd_1.withLockedMLSMessagesQueue)(groupIdStr, async () => {
|
|
85
|
-
const { commit, groupInfo, welcome } =
|
|
97
|
+
const { commit, groupInfo, welcome } = await generateCommitBundle();
|
|
86
98
|
const bundlePayload = new Uint8Array([...commit, ...groupInfo.payload, ...(welcome || [])]);
|
|
87
99
|
try {
|
|
88
100
|
const response = await this.apiClient.api.conversation.postMlsCommitBundle(bundlePayload);
|
|
@@ -94,8 +106,6 @@ class MLSService extends commons_1.TypedEventEmitter {
|
|
|
94
106
|
}
|
|
95
107
|
const newEpoch = await this.getEpoch(groupId);
|
|
96
108
|
this.emit('newEpoch', { epoch: newEpoch, groupId: groupIdStr });
|
|
97
|
-
// We need to reset the backoff after a successful request
|
|
98
|
-
resetBackOff();
|
|
99
109
|
return response;
|
|
100
110
|
}
|
|
101
111
|
catch (error) {
|
|
@@ -105,20 +115,6 @@ class MLSService extends commons_1.TypedEventEmitter {
|
|
|
105
115
|
else {
|
|
106
116
|
await this.coreCryptoClient.clearPendingCommit(groupId);
|
|
107
117
|
}
|
|
108
|
-
const shouldRetry = error instanceof http_1.BackendError && error.code === http_1.StatusCode.CONFLICT;
|
|
109
|
-
if (shouldRetry && regenerateCommitBundle) {
|
|
110
|
-
// in case of a 409, we want to retry to generate the commit and resend it
|
|
111
|
-
// could be that we are trying to upload a commit to a conversation that has a different epoch on backend
|
|
112
|
-
// in this case we will most likely receive a commit from backend that will increase our local epoch
|
|
113
|
-
this.logger.warn(`Uploading commitBundle failed. Will retry generating a new bundle`);
|
|
114
|
-
return backOff(async () => {
|
|
115
|
-
const updatedCommitBundle = await regenerateCommitBundle();
|
|
116
|
-
return this.uploadCommitBundle(groupId, updatedCommitBundle, { regenerateCommitBundle, isExternalCommit });
|
|
117
|
-
}, () => {
|
|
118
|
-
this.logger.error('Uploading commit bundle retry limit reached', error);
|
|
119
|
-
throw error;
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
118
|
throw error;
|
|
123
119
|
}
|
|
124
120
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { QualifiedId } from '@wireapp/api-client/lib/user';
|
|
2
|
-
export
|
|
2
|
+
export type StringifiedQualifiedId = `${string}@${string}`;
|
|
3
|
+
export declare const stringifyQualifiedId: (qualifiedId: QualifiedId) => StringifiedQualifiedId;
|
|
3
4
|
export declare const parseQualifiedId: (qualifiedId: string) => QualifiedId;
|
|
4
5
|
//# sourceMappingURL=qualifiedIdUtil.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qualifiedIdUtil.d.ts","sourceRoot":"","sources":["../../src/util/qualifiedIdUtil.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,
|
|
1
|
+
{"version":3,"file":"qualifiedIdUtil.d.ts","sourceRoot":"","sources":["../../src/util/qualifiedIdUtil.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,MAAM,MAAM,sBAAsB,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAC3D,eAAO,MAAM,oBAAoB,gBAAiB,WAAW,KAAG,sBACrB,CAAC;AAE5C,eAAO,MAAM,gBAAgB,gBAAiB,MAAM,KAAG,WAMtD,CAAC"}
|
package/package.json
CHANGED
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
"./lib/cryptography/AssetCryptography/crypto.node": "./lib/cryptography/AssetCryptography/crypto.browser.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@wireapp/api-client": "^26.10.
|
|
15
|
-
"@wireapp/commons": "^5.2.
|
|
14
|
+
"@wireapp/api-client": "^26.10.16",
|
|
15
|
+
"@wireapp/commons": "^5.2.7",
|
|
16
16
|
"@wireapp/core-crypto": "1.0.0-rc.46",
|
|
17
17
|
"@wireapp/cryptobox": "12.8.0",
|
|
18
|
-
"@wireapp/
|
|
18
|
+
"@wireapp/priority-queue": "^2.1.5",
|
|
19
|
+
"@wireapp/promise-queue": "^2.3.2",
|
|
19
20
|
"@wireapp/protocol-messaging": "1.44.0",
|
|
20
21
|
"@wireapp/store-engine": "5.1.5",
|
|
21
22
|
"axios": "1.6.7",
|
|
@@ -60,6 +61,6 @@
|
|
|
60
61
|
"test:coverage": "jest --coverage",
|
|
61
62
|
"watch": "tsc --watch"
|
|
62
63
|
},
|
|
63
|
-
"version": "45.0
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"version": "45.1.0",
|
|
65
|
+
"gitHead": "2d99401cd7f59fba88425d88f4cde8db12a72d7b"
|
|
65
66
|
}
|