@wireapp/core 17.20.1 → 17.21.1
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 +38 -0
- package/package.json +3 -3
- package/src/main/conversation/ConversationService.d.ts +43 -23
- package/src/main/conversation/ConversationService.js +106 -112
- package/src/main/conversation/ConversationService.js.map +1 -1
- package/src/main/conversation/ConversationService.ts +130 -388
- package/src/main/conversation/message/MessageService.d.ts +11 -2
- package/src/main/conversation/message/MessageService.js +46 -19
- package/src/main/conversation/message/MessageService.js.map +1 -1
- package/src/main/conversation/message/MessageService.test.node.d.ts +1 -0
- package/src/main/conversation/message/MessageService.test.node.js +80 -0
- package/src/main/conversation/message/MessageService.test.node.js.map +1 -0
- package/src/main/conversation/message/MessageService.test.node.ts +95 -0
- package/src/main/conversation/message/MessageService.ts +48 -28
- package/src/main/cryptography/CryptographyService.d.ts +3 -3
- package/src/main/cryptography/CryptographyService.js +14 -11
- package/src/main/cryptography/CryptographyService.js.map +1 -1
- package/src/main/cryptography/CryptographyService.ts +23 -16
- package/src/main/util/TypePredicateUtil.js +1 -1
- package/src/main/util/TypePredicateUtil.js.map +1 -1
- package/src/main/util/TypePredicateUtil.test.node.d.ts +1 -0
- package/src/main/util/TypePredicateUtil.test.node.js +42 -0
- package/src/main/util/TypePredicateUtil.test.node.js.map +1 -0
- package/src/main/util/TypePredicateUtil.test.node.ts +44 -0
- package/src/main/util/TypePredicateUtil.ts +1 -1
|
@@ -20,7 +20,13 @@
|
|
|
20
20
|
import type {APIClient} from '@wireapp/api-client';
|
|
21
21
|
import type {PreKey as SerializedPreKey} from '@wireapp/api-client/src/auth/';
|
|
22
22
|
import type {RegisteredClient} from '@wireapp/api-client/src/client/';
|
|
23
|
-
import type {
|
|
23
|
+
import type {
|
|
24
|
+
OTRClientMap,
|
|
25
|
+
OTRRecipients,
|
|
26
|
+
QualifiedOTRRecipients,
|
|
27
|
+
QualifiedUserClients,
|
|
28
|
+
UserClients,
|
|
29
|
+
} from '@wireapp/api-client/src/conversation/';
|
|
24
30
|
import type {ConversationOtrMessageAddEvent} from '@wireapp/api-client/src/event';
|
|
25
31
|
import type {QualifiedUserPreKeyBundleMap, UserPreKeyBundleMap} from '@wireapp/api-client/src/user/';
|
|
26
32
|
import {Cryptobox} from '@wireapp/cryptobox';
|
|
@@ -32,6 +38,7 @@ import logdown from 'logdown';
|
|
|
32
38
|
|
|
33
39
|
import {GenericMessageType, PayloadBundle, PayloadBundleSource} from '../conversation';
|
|
34
40
|
import type {SessionPayloadBundle} from '../cryptography/';
|
|
41
|
+
import {isUserClients} from '../util';
|
|
35
42
|
import {CryptographyDatabaseRepository} from './CryptographyDatabaseRepository';
|
|
36
43
|
import {GenericMessageMapper} from './GenericMessageMapper';
|
|
37
44
|
|
|
@@ -118,7 +125,7 @@ export class CryptographyService {
|
|
|
118
125
|
|
|
119
126
|
public async encryptQualified(
|
|
120
127
|
plainText: Uint8Array,
|
|
121
|
-
preKeyBundles: QualifiedUserPreKeyBundleMap,
|
|
128
|
+
preKeyBundles: QualifiedUserPreKeyBundleMap | QualifiedUserClients,
|
|
122
129
|
): Promise<QualifiedOTRRecipients> {
|
|
123
130
|
const qualifiedOTRRecipients: QualifiedOTRRecipients = {};
|
|
124
131
|
|
|
@@ -131,17 +138,15 @@ export class CryptographyService {
|
|
|
131
138
|
|
|
132
139
|
public async encrypt(
|
|
133
140
|
plainText: Uint8Array,
|
|
134
|
-
|
|
141
|
+
users: UserPreKeyBundleMap | UserClients,
|
|
135
142
|
domain?: string,
|
|
136
143
|
): Promise<OTRRecipients<Uint8Array>> {
|
|
137
|
-
const recipients: OTRRecipients<Uint8Array> = {};
|
|
138
144
|
const bundles: Promise<SessionPayloadBundle>[] = [];
|
|
139
145
|
|
|
140
|
-
for (const userId in
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const {key: base64PreKey} = preKeyBundles[userId][clientId];
|
|
146
|
+
for (const userId in users) {
|
|
147
|
+
const clientIds = isUserClients(users) ? users[userId] : Object.keys(users[userId]);
|
|
148
|
+
for (const clientId of clientIds) {
|
|
149
|
+
const base64PreKey = isUserClients(users) ? undefined : users[userId][clientId].key;
|
|
145
150
|
const sessionId = CryptographyService.constructSessionId(userId, clientId, domain || null);
|
|
146
151
|
bundles.push(this.encryptPayloadForSession(sessionId, plainText, base64PreKey));
|
|
147
152
|
}
|
|
@@ -149,27 +154,29 @@ export class CryptographyService {
|
|
|
149
154
|
|
|
150
155
|
const payloads = await Promise.all(bundles);
|
|
151
156
|
|
|
152
|
-
payloads.
|
|
157
|
+
return payloads.reduce((recipients, payload) => {
|
|
153
158
|
const {encryptedPayload, sessionId} = payload;
|
|
154
159
|
const {userId, clientId} = CryptographyService.dismantleSessionId(sessionId);
|
|
160
|
+
recipients[userId] ||= {};
|
|
155
161
|
recipients[userId][clientId] = encryptedPayload;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return recipients;
|
|
162
|
+
return recipients;
|
|
163
|
+
}, {} as OTRRecipients<Uint8Array>);
|
|
159
164
|
}
|
|
160
165
|
|
|
161
166
|
private async encryptPayloadForSession(
|
|
162
167
|
sessionId: string,
|
|
163
168
|
plainText: Uint8Array,
|
|
164
|
-
base64EncodedPreKey
|
|
169
|
+
base64EncodedPreKey?: string,
|
|
165
170
|
): Promise<SessionPayloadBundle> {
|
|
166
171
|
this.logger.log(`Encrypting payload for session ID "${sessionId}"`);
|
|
167
172
|
|
|
168
173
|
let encryptedPayload: Uint8Array;
|
|
169
174
|
|
|
170
175
|
try {
|
|
171
|
-
const decodedPreKeyBundle =
|
|
172
|
-
|
|
176
|
+
const decodedPreKeyBundle = base64EncodedPreKey
|
|
177
|
+
? Decoder.fromBase64(base64EncodedPreKey).asBytes.buffer
|
|
178
|
+
: undefined;
|
|
179
|
+
const payloadAsArrayBuffer = await this.cryptobox.encrypt(sessionId, plainText, decodedPreKeyBundle);
|
|
173
180
|
encryptedPayload = new Uint8Array(payloadAsArrayBuffer);
|
|
174
181
|
} catch (error) {
|
|
175
182
|
this.logger.error(`Could not encrypt payload: ${(error as Error).message}`);
|
|
@@ -35,7 +35,7 @@ function isQualifiedUserClients(obj) {
|
|
|
35
35
|
const firstClientIdArray = Object.values(firstUserClientObject)[0];
|
|
36
36
|
if (Array.isArray(firstClientIdArray)) {
|
|
37
37
|
const firstClientId = firstClientIdArray[0];
|
|
38
|
-
return typeof firstClientId === 'string';
|
|
38
|
+
return typeof firstClientId === 'string' || typeof firstClientId === 'undefined';
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypePredicateUtil.js","sourceRoot":"","sources":["TypePredicateUtil.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAKH,SAAgB,aAAa,CAAC,GAAQ;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC;AAC1D,CAAC;AAFD,sCAEC;AAED,SAAgB,kBAAkB,CAAC,GAAQ;IACzC,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC;AAClG,CAAC;AAFD,gDAEC;AAED,SAAgB,sBAAsB,CAAC,GAAQ;;IAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QAC3B,MAAM,qBAAqB,GAAG,MAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,0CAAG,CAAC,CAAC,CAAC;QACtD,IAAI,OAAO,qBAAqB,KAAK,QAAQ,EAAE;YAC7C,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,qBAA+B,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7E,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;gBACrC,MAAM,aAAa,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;gBAC5C,OAAO,OAAO,aAAa,KAAK,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"TypePredicateUtil.js","sourceRoot":"","sources":["TypePredicateUtil.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAKH,SAAgB,aAAa,CAAC,GAAQ;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC;AAC1D,CAAC;AAFD,sCAEC;AAED,SAAgB,kBAAkB,CAAC,GAAQ;IACzC,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC;AAClG,CAAC;AAFD,gDAEC;AAED,SAAgB,sBAAsB,CAAC,GAAQ;;IAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QAC3B,MAAM,qBAAqB,GAAG,MAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,0CAAG,CAAC,CAAC,CAAC;QACtD,IAAI,OAAO,qBAAqB,KAAK,QAAQ,EAAE;YAC7C,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,qBAA+B,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7E,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;gBACrC,MAAM,aAAa,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;gBAC5C,OAAO,OAAO,aAAa,KAAK,QAAQ,IAAI,OAAO,aAAa,KAAK,WAAW,CAAC;aAClF;SACF;KACF;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAZD,wDAYC;AAED,SAAgB,aAAa,CAAC,GAAQ;;IACpC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QAC3B,MAAM,oBAAoB,GAAG,MAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,0CAAG,CAAC,CAAC,CAAC;QACrD,IAAI,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;YACvC,MAAM,aAAa,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;YAC9C,OAAO,OAAO,aAAa,KAAK,QAAQ,CAAC;SAC1C;KACF;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AATD,sCASC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Wire
|
|
4
|
+
* Copyright (C) 2021 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 TypePredicateUtil_1 = require("./TypePredicateUtil");
|
|
22
|
+
describe('TypePredicatUtil', () => {
|
|
23
|
+
describe('isQualifiedUserClients', () => {
|
|
24
|
+
it('detects QualifiedUserClients', () => {
|
|
25
|
+
const validUserClients = [
|
|
26
|
+
{ domain1: { user1: ['client1'] } },
|
|
27
|
+
{ domain1: { user1: [] } }, // When a user has no clients
|
|
28
|
+
];
|
|
29
|
+
validUserClients.forEach(payload => expect((0, TypePredicateUtil_1.isQualifiedUserClients)(payload)).toBeTrue());
|
|
30
|
+
});
|
|
31
|
+
it('rejects non QualifiedUserClients', () => {
|
|
32
|
+
const invalidUserClients = [
|
|
33
|
+
{ domain1: { user1: '' } },
|
|
34
|
+
{ domain1: { user1: {} } },
|
|
35
|
+
{ domain1: [] },
|
|
36
|
+
{ domain1: { user1: [{}] } },
|
|
37
|
+
];
|
|
38
|
+
invalidUserClients.forEach(payload => expect((0, TypePredicateUtil_1.isQualifiedUserClients)(payload)).toBeFalse());
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=TypePredicateUtil.test.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TypePredicateUtil.test.node.js","sourceRoot":"","sources":["TypePredicateUtil.test.node.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;AAEH,2DAA2D;AAE3D,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,gBAAgB,GAAG;gBACvB,EAAC,OAAO,EAAE,EAAC,KAAK,EAAE,CAAC,SAAS,CAAC,EAAC,EAAC;gBAC/B,EAAC,OAAO,EAAE,EAAC,KAAK,EAAE,EAAE,EAAC,EAAC,EAAE,6BAA6B;aACtD,CAAC;YAEF,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAA,0CAAsB,EAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,kBAAkB,GAAG;gBACzB,EAAC,OAAO,EAAE,EAAC,KAAK,EAAE,EAAE,EAAC,EAAC;gBACtB,EAAC,OAAO,EAAE,EAAC,KAAK,EAAE,EAAE,EAAC,EAAC;gBACtB,EAAC,OAAO,EAAE,EAAE,EAAC;gBACb,EAAC,OAAO,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAC,EAAC;aACzB,CAAC;YAEF,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAA,0CAAsB,EAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC7F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Wire
|
|
3
|
+
* Copyright (C) 2021 Wire Swiss GmbH
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU General Public License
|
|
16
|
+
* along with this program. If not, see http://www.gnu.org/licenses/.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import {isQualifiedUserClients} from './TypePredicateUtil';
|
|
21
|
+
|
|
22
|
+
describe('TypePredicatUtil', () => {
|
|
23
|
+
describe('isQualifiedUserClients', () => {
|
|
24
|
+
it('detects QualifiedUserClients', () => {
|
|
25
|
+
const validUserClients = [
|
|
26
|
+
{domain1: {user1: ['client1']}},
|
|
27
|
+
{domain1: {user1: []}}, // When a user has no clients
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
validUserClients.forEach(payload => expect(isQualifiedUserClients(payload)).toBeTrue());
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('rejects non QualifiedUserClients', () => {
|
|
34
|
+
const invalidUserClients = [
|
|
35
|
+
{domain1: {user1: ''}},
|
|
36
|
+
{domain1: {user1: {}}},
|
|
37
|
+
{domain1: []},
|
|
38
|
+
{domain1: {user1: [{}]}},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
invalidUserClients.forEach(payload => expect(isQualifiedUserClients(payload)).toBeFalse());
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -35,7 +35,7 @@ export function isQualifiedUserClients(obj: any): obj is QualifiedUserClients {
|
|
|
35
35
|
const firstClientIdArray = Object.values(firstUserClientObject as object)[0];
|
|
36
36
|
if (Array.isArray(firstClientIdArray)) {
|
|
37
37
|
const firstClientId = firstClientIdArray[0];
|
|
38
|
-
return typeof firstClientId === 'string';
|
|
38
|
+
return typeof firstClientId === 'string' || typeof firstClientId === 'undefined';
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
}
|