@wireapp/core 30.12.0 → 30.13.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/CHANGELOG.md +11 -0
- package/package.json +2 -2
- package/src/main/Account.d.ts +9 -1
- package/src/main/Account.js +11 -0
- package/src/main/conversation/ConversationService/ConversationService.js +2 -3
- package/src/main/mls/MLSService/MLSService.d.ts +5 -3
- package/src/main/mls/MLSService/MLSService.js +35 -10
- package/src/main/mls/types.d.ts +11 -0
- package/src/main/notification/NotificationDatabaseRepository.d.ts +1 -4
- package/src/main/notification/NotificationDatabaseRepository.js +0 -10
- package/src/main/notification/NotificationService.d.ts +2 -13
- package/src/main/notification/NotificationService.js +15 -27
- package/src/main/notification/types.d.ts +0 -4
- package/src/main/util/{mapQualifiedUserClientIdsToFullyQualifiedClientIds.d.ts → fullyQualifiedClientIdUtils.d.ts} +5 -0
- package/src/main/util/{mapQualifiedUserClientIdsToFullyQualifiedClientIds.js → fullyQualifiedClientIdUtils.js} +12 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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
|
+
# [30.13.0](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@30.12.0...@wireapp/core@30.13.0) (2022-09-20)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Handle external proposals ([#4397](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/issues/4397)) ([54c5f97](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/commit/54c5f979eb5e5bd4e864dad1b9acb3c330ddac75))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [30.12.0](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@30.11.2...@wireapp/core@30.12.0) (2022-09-20)
|
|
7
18
|
|
|
8
19
|
|
package/package.json
CHANGED
package/src/main/Account.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ import { AccountService } from './account/';
|
|
|
23
23
|
import { LinkPreviewService } from './linkPreview';
|
|
24
24
|
import { WEBSOCKET_STATE } from '@wireapp/api-client/src/tcp/ReconnectingWebsocket';
|
|
25
25
|
import { MLSService } from './mls';
|
|
26
|
-
import type { MLSConfig } from './mls/types';
|
|
26
|
+
import type { MLSCallbacks, MLSConfig } from './mls/types';
|
|
27
27
|
export declare type ProcessedEventPayload = HandledEventPayload;
|
|
28
28
|
declare enum TOPIC {
|
|
29
29
|
ERROR = "Account.TOPIC.ERROR"
|
|
@@ -147,6 +147,14 @@ export declare class Account<T = any> extends EventEmitter {
|
|
|
147
147
|
isNewClient: boolean;
|
|
148
148
|
localClient: RegisteredClient;
|
|
149
149
|
}>;
|
|
150
|
+
/**
|
|
151
|
+
* In order to be able to send MLS messages, the core needs a few information from the consumer.
|
|
152
|
+
* Namely:
|
|
153
|
+
* - is the current user allowed to administrate a specific conversation
|
|
154
|
+
* - what is the groupId of a conversation
|
|
155
|
+
* @param mlsCallbacks
|
|
156
|
+
*/
|
|
157
|
+
configureMLSCallbacks(mlsCallbacks: MLSCallbacks): void;
|
|
150
158
|
initServices(context: Context): Promise<void>;
|
|
151
159
|
loadAndValidateLocalClient(entropyData?: Uint8Array): Promise<RegisteredClient>;
|
|
152
160
|
private createMLSClient;
|
package/src/main/Account.js
CHANGED
|
@@ -232,6 +232,17 @@ class Account extends events_1.EventEmitter {
|
|
|
232
232
|
throw error;
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* In order to be able to send MLS messages, the core needs a few information from the consumer.
|
|
237
|
+
* Namely:
|
|
238
|
+
* - is the current user allowed to administrate a specific conversation
|
|
239
|
+
* - what is the groupId of a conversation
|
|
240
|
+
* @param mlsCallbacks
|
|
241
|
+
*/
|
|
242
|
+
configureMLSCallbacks(mlsCallbacks) {
|
|
243
|
+
var _a;
|
|
244
|
+
(_a = this.service) === null || _a === void 0 ? void 0 : _a.mls.configureMLSCallbacks(mlsCallbacks);
|
|
245
|
+
}
|
|
235
246
|
async initServices(context) {
|
|
236
247
|
this.storeEngine = await this.initEngine(context);
|
|
237
248
|
const accountService = new account_1.AccountService(this.apiClient);
|
|
@@ -31,7 +31,7 @@ const MessageService_1 = require("../message/MessageService");
|
|
|
31
31
|
const MessageToProtoMapper_1 = require("../message/MessageToProtoMapper");
|
|
32
32
|
const ConversationService_types_1 = require("./ConversationService.types");
|
|
33
33
|
const bazinga64_1 = require("bazinga64");
|
|
34
|
-
const
|
|
34
|
+
const fullyQualifiedClientIdUtils_1 = require("../../util/fullyQualifiedClientIdUtils");
|
|
35
35
|
const mls_1 = require("../../mls");
|
|
36
36
|
const messageSender_1 = require("../message/messageSender");
|
|
37
37
|
class ConversationService {
|
|
@@ -830,7 +830,6 @@ class ConversationService {
|
|
|
830
830
|
...qualifiedUsers,
|
|
831
831
|
]);
|
|
832
832
|
const response = await this.mlsService.addUsersToExistingConversation(groupIdDecodedFromBase64, coreCryptoKeyPackagesPayload);
|
|
833
|
-
await this.notificationService.saveConversationGroupId(newConversation);
|
|
834
833
|
//We store the info when conversation (along with key material) was created, so we will know when to renew it
|
|
835
834
|
const groupCreationTimeStamp = new Date().getTime();
|
|
836
835
|
await this.notificationService.storeLastKeyMaterialUpdateDate({
|
|
@@ -877,7 +876,7 @@ class ConversationService {
|
|
|
877
876
|
async removeUsersFromMLSConversation({ groupId, conversationId, qualifiedUserIds, }) {
|
|
878
877
|
const groupIdDecodedFromBase64 = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
|
|
879
878
|
const clientsToRemove = await this.apiClient.api.user.postListClients({ qualified_users: qualifiedUserIds });
|
|
880
|
-
const fullyQualifiedClientIds = (0,
|
|
879
|
+
const fullyQualifiedClientIds = (0, fullyQualifiedClientIdUtils_1.mapQualifiedUserClientIdsToFullyQualifiedClientIds)(clientsToRemove.qualified_user_map);
|
|
881
880
|
const messageResponse = await this.mlsService.removeClientsFromConversation(groupIdDecodedFromBase64, fullyQualifiedClientIds);
|
|
882
881
|
//key material gets updated after removing a user from the group, so we can reset last key update time value in the store
|
|
883
882
|
await this.storeLastKeyMaterialUpdateDateWithCurrentTime(groupId);
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { AddProposalArgs,
|
|
1
|
+
import { AddProposalArgs, ConversationConfiguration, ConversationId, CoreCrypto, DecryptedMessage, ExternalProposalArgs, ExternalProposalType, ExternalRemoveProposalArgs, Invitee, ProposalArgs, ProposalType, RemoveProposalArgs } from '@wireapp/core-crypto';
|
|
2
2
|
import { APIClient } from '@wireapp/api-client';
|
|
3
3
|
import { QualifiedUsers } from '../../conversation';
|
|
4
|
-
import type { MLSConfig } from '../types';
|
|
4
|
+
import type { MLSCallbacks, MLSConfig } from '../types';
|
|
5
5
|
import { PostMlsMessageResponse } from '@wireapp/api-client/src/conversation';
|
|
6
6
|
export declare const optionalToUint8Array: (array: Uint8Array | []) => Uint8Array;
|
|
7
7
|
export declare class MLSService {
|
|
8
8
|
readonly config: MLSConfig | undefined;
|
|
9
9
|
private readonly apiClient;
|
|
10
10
|
private readonly coreCryptoClientProvider;
|
|
11
|
+
groupIdFromConversationId?: MLSCallbacks['groupIdFromConversationId'];
|
|
11
12
|
constructor(config: MLSConfig | undefined, apiClient: APIClient, coreCryptoClientProvider: () => CoreCrypto | undefined);
|
|
12
13
|
private getCoreCryptoClient;
|
|
13
14
|
private uploadCommitBundle;
|
|
14
15
|
addUsersToExistingConversation(groupId: Uint8Array, invitee: Invitee[]): Promise<PostMlsMessageResponse | null>;
|
|
16
|
+
configureMLSCallbacks({ groupIdFromConversationId, ...coreCryptoCallbacks }: MLSCallbacks): void;
|
|
15
17
|
getKeyPackagesPayload(qualifiedUsers: QualifiedUsers[]): Promise<Invitee[]>;
|
|
16
18
|
newProposal(proposalType: ProposalType, args: ProposalArgs | AddProposalArgs | RemoveProposalArgs): Promise<import("@wireapp/core-crypto").ProposalBundle>;
|
|
17
19
|
newExternalProposal(externalProposalType: ExternalProposalType, args: ExternalProposalArgs | ExternalRemoveProposalArgs): Promise<Uint8Array>;
|
|
@@ -21,7 +23,7 @@ export declare class MLSService {
|
|
|
21
23
|
updateKeyingMaterial(conversationId: ConversationId): Promise<PostMlsMessageResponse | null>;
|
|
22
24
|
createConversation(conversationId: ConversationId, configuration?: ConversationConfiguration): Promise<any>;
|
|
23
25
|
removeClientsFromConversation(conversationId: ConversationId, clientIds: Uint8Array[]): Promise<PostMlsMessageResponse | null>;
|
|
24
|
-
commitPendingProposals(
|
|
26
|
+
commitPendingProposals(groupId: ConversationId): Promise<void>;
|
|
25
27
|
conversationExists(conversationId: ConversationId): Promise<boolean>;
|
|
26
28
|
clientValidKeypackagesCount(): Promise<number>;
|
|
27
29
|
clientKeypackages(amountRequested: number): Promise<Uint8Array[]>;
|
|
@@ -17,10 +17,22 @@
|
|
|
17
17
|
* along with this program. If not, see http://www.gnu.org/licenses/.
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
21
|
+
var t = {};
|
|
22
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
23
|
+
t[p] = s[p];
|
|
24
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
25
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
26
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
27
|
+
t[p[i]] = s[p[i]];
|
|
28
|
+
}
|
|
29
|
+
return t;
|
|
30
|
+
};
|
|
20
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
32
|
exports.MLSService = exports.optionalToUint8Array = void 0;
|
|
22
33
|
const bazinga64_1 = require("bazinga64");
|
|
23
34
|
const messageSender_1 = require("../../conversation/message/messageSender");
|
|
35
|
+
const fullyQualifiedClientIdUtils_1 = require("../../util/fullyQualifiedClientIdUtils");
|
|
24
36
|
//@todo: this function is temporary, we wait for the update from core-crypto side
|
|
25
37
|
//they are returning regular array instead of Uint8Array for commit and welcome messages
|
|
26
38
|
const optionalToUint8Array = (array) => {
|
|
@@ -40,23 +52,23 @@ class MLSService {
|
|
|
40
52
|
}
|
|
41
53
|
return client;
|
|
42
54
|
}
|
|
43
|
-
async uploadCommitBundle(groupId,
|
|
55
|
+
async uploadCommitBundle(groupId, { commit, welcome }) {
|
|
44
56
|
const coreCryptoClient = this.getCoreCryptoClient();
|
|
45
|
-
if (
|
|
46
|
-
//@todo: it's temporary - we wait for core-crypto fix to return the actual Uint8Array instead of regular array
|
|
47
|
-
await this.apiClient.api.conversation.postMlsWelcomeMessage((0, exports.optionalToUint8Array)(commitBundle.welcome));
|
|
48
|
-
}
|
|
49
|
-
if (commitBundle.commit) {
|
|
57
|
+
if (commit) {
|
|
50
58
|
try {
|
|
51
59
|
const messageResponse = await this.apiClient.api.conversation.postMlsMessage(
|
|
52
60
|
//@todo: it's temporary - we wait for core-crypto fix to return the actual Uint8Array instead of regular array
|
|
53
|
-
(0, exports.optionalToUint8Array)(
|
|
61
|
+
(0, exports.optionalToUint8Array)(commit));
|
|
54
62
|
await coreCryptoClient.commitAccepted(groupId);
|
|
63
|
+
if (welcome) {
|
|
64
|
+
// If the commit went well, we can send the Welcome
|
|
65
|
+
//@todo: it's temporary - we wait for core-crypto fix to return the actual Uint8Array instead of regular array
|
|
66
|
+
await this.apiClient.api.conversation.postMlsWelcomeMessage((0, exports.optionalToUint8Array)(welcome));
|
|
67
|
+
}
|
|
55
68
|
return messageResponse;
|
|
56
69
|
}
|
|
57
70
|
catch (error) {
|
|
58
71
|
await coreCryptoClient.clearPendingCommit(groupId);
|
|
59
|
-
return null;
|
|
60
72
|
}
|
|
61
73
|
}
|
|
62
74
|
return null;
|
|
@@ -68,6 +80,18 @@ class MLSService {
|
|
|
68
80
|
return this.uploadCommitBundle(groupId, memberAddedMessages);
|
|
69
81
|
});
|
|
70
82
|
}
|
|
83
|
+
configureMLSCallbacks(_a) {
|
|
84
|
+
var { groupIdFromConversationId } = _a, coreCryptoCallbacks = __rest(_a, ["groupIdFromConversationId"]);
|
|
85
|
+
this.getCoreCryptoClient().registerCallbacks(Object.assign(Object.assign({}, coreCryptoCallbacks), { clientIdBelongsToOneOf: (client, otherClients) => {
|
|
86
|
+
const decoder = new TextDecoder();
|
|
87
|
+
const { user } = (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(decoder.decode(client));
|
|
88
|
+
return otherClients.some(client => {
|
|
89
|
+
const { user: otherUser } = (0, fullyQualifiedClientIdUtils_1.parseFullQualifiedClientId)(decoder.decode(client));
|
|
90
|
+
return otherUser === user;
|
|
91
|
+
});
|
|
92
|
+
} }));
|
|
93
|
+
this.groupIdFromConversationId = groupIdFromConversationId;
|
|
94
|
+
}
|
|
71
95
|
async getKeyPackagesPayload(qualifiedUsers) {
|
|
72
96
|
/**
|
|
73
97
|
* @note We need to fetch key packages for all the users
|
|
@@ -122,8 +146,9 @@ class MLSService {
|
|
|
122
146
|
return this.uploadCommitBundle(conversationId, commitBundle);
|
|
123
147
|
});
|
|
124
148
|
}
|
|
125
|
-
async commitPendingProposals(
|
|
126
|
-
|
|
149
|
+
async commitPendingProposals(groupId) {
|
|
150
|
+
const commitBundle = await this.getCoreCryptoClient().commitPendingProposals(groupId);
|
|
151
|
+
return commitBundle ? void this.uploadCommitBundle(groupId, commitBundle) : undefined;
|
|
127
152
|
}
|
|
128
153
|
async conversationExists(conversationId) {
|
|
129
154
|
return this.getCoreCryptoClient().conversationExists(conversationId);
|
package/src/main/mls/types.d.ts
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
import { QualifiedId } from '@wireapp/api-client/src/user';
|
|
2
|
+
import { CoreCryptoCallbacks } from '@wireapp/core-crypto';
|
|
1
3
|
declare type SecretCrypto<T> = {
|
|
2
4
|
encrypt: (value: Uint8Array) => Promise<T>;
|
|
3
5
|
decrypt: (payload: T) => Promise<Uint8Array>;
|
|
4
6
|
};
|
|
7
|
+
export interface MLSCallbacks extends Pick<CoreCryptoCallbacks, 'authorize'> {
|
|
8
|
+
/**
|
|
9
|
+
* Should return a groupId corresponding to the conversation ID given
|
|
10
|
+
* Used for the core to know what core-crypto conversation we are dealing with when receiving events
|
|
11
|
+
* @param conversationId
|
|
12
|
+
* @returns the bytes of the groupId corresponding to the conversation ID
|
|
13
|
+
*/
|
|
14
|
+
groupIdFromConversationId: (conversationId: QualifiedId) => Promise<string | undefined>;
|
|
15
|
+
}
|
|
5
16
|
export interface MLSConfig<T = any> {
|
|
6
17
|
/**
|
|
7
18
|
* encrypt/decrypt function pair that will be called before storing/fetching secrets in the secrets database.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BackendEvent } from '@wireapp/api-client/src/event';
|
|
2
2
|
import type { Notification } from '@wireapp/api-client/src/notification/';
|
|
3
3
|
import type { CRUDEngine } from '@wireapp/store-engine';
|
|
4
|
-
import { CommonMLS,
|
|
4
|
+
import { CommonMLS, StorePendingProposalsParams } from './types';
|
|
5
5
|
export declare enum DatabaseStores {
|
|
6
6
|
EVENTS = "events"
|
|
7
7
|
}
|
|
@@ -18,9 +18,6 @@ export declare class NotificationDatabaseRepository {
|
|
|
18
18
|
createLastEventDate(eventDate: Date): Promise<Date>;
|
|
19
19
|
getLastNotificationId(): Promise<string>;
|
|
20
20
|
updateLastNotificationId(lastNotification: Notification): Promise<string>;
|
|
21
|
-
private generateCompoundGroupIdPrimaryKey;
|
|
22
|
-
addCompoundGroupId(params: CompoundGroupIdParams): Promise<CompoundGroupIdParams>;
|
|
23
|
-
getCompoundGroupId(params: Omit<CompoundGroupIdParams, 'groupId'>): Promise<string>;
|
|
24
21
|
/**
|
|
25
22
|
* ## MLS only ##
|
|
26
23
|
* Store groupIds with pending proposals and a delay in the DB until the proposals get committed.
|
|
@@ -63,16 +63,6 @@ class NotificationDatabaseRepository {
|
|
|
63
63
|
});
|
|
64
64
|
return lastNotification.id;
|
|
65
65
|
}
|
|
66
|
-
generateCompoundGroupIdPrimaryKey({ conversationId, conversationDomain, }) {
|
|
67
|
-
return `${conversationId}@${conversationDomain}`;
|
|
68
|
-
}
|
|
69
|
-
async addCompoundGroupId(params) {
|
|
70
|
-
await this.storeEngine.updateOrCreate(STORES.GROUP_IDS, this.generateCompoundGroupIdPrimaryKey(params), params.groupId);
|
|
71
|
-
return params;
|
|
72
|
-
}
|
|
73
|
-
async getCompoundGroupId(params) {
|
|
74
|
-
return this.storeEngine.read(STORES.GROUP_IDS, this.generateCompoundGroupIdPrimaryKey(params));
|
|
75
|
-
}
|
|
76
66
|
/**
|
|
77
67
|
* ## MLS only ##
|
|
78
68
|
* Store groupIds with pending proposals and a delay in the DB until the proposals get committed.
|
|
@@ -9,8 +9,6 @@ import { NotificationError } from '../CoreError';
|
|
|
9
9
|
import type { CryptographyService } from '../cryptography';
|
|
10
10
|
import { GenericMessage } from '@wireapp/protocol-messaging';
|
|
11
11
|
import { AbortHandler } from '@wireapp/api-client/src/tcp';
|
|
12
|
-
import { QualifiedId } from '@wireapp/api-client/src/user';
|
|
13
|
-
import { Conversation } from '@wireapp/api-client/src/conversation';
|
|
14
12
|
import { CommitPendingProposalsParams, LastKeyMaterialUpdateParams } from './types';
|
|
15
13
|
import type { MLSService } from '../mls';
|
|
16
14
|
export declare type HandledEventPayload = {
|
|
@@ -61,23 +59,14 @@ export declare class NotificationService extends EventEmitter {
|
|
|
61
59
|
handleNotification(notification: Notification, source: PayloadBundleSource, dryRun?: boolean): AsyncGenerator<HandledEventPayload>;
|
|
62
60
|
private cleanupPayloadBundle;
|
|
63
61
|
private handleEvent;
|
|
64
|
-
/**
|
|
65
|
-
* ## MLS only ##
|
|
66
|
-
* If there is a groupId in the conversation, we need to store the conversationId => groupId pair
|
|
67
|
-
* in order to find the groupId when decrypting messages
|
|
68
|
-
* This is a bit hacky but since mls messages do not embed the groupId we need to keep a mapping of those
|
|
69
|
-
*
|
|
70
|
-
* @param conversation conversation with group_id
|
|
71
|
-
*/
|
|
72
|
-
saveConversationGroupId(conversation: Conversation): Promise<void>;
|
|
73
62
|
/**
|
|
74
63
|
* ## MLS only ##
|
|
75
64
|
* If there is a matching conversationId => groupId pair in the database,
|
|
76
|
-
* we can find the groupId and return it as a
|
|
65
|
+
* we can find the groupId and return it as a string
|
|
77
66
|
*
|
|
78
67
|
* @param conversationQualifiedId
|
|
79
68
|
*/
|
|
80
|
-
|
|
69
|
+
private getGroupIdFromConversationId;
|
|
81
70
|
/**
|
|
82
71
|
* ## MLS only ##
|
|
83
72
|
* If there are pending proposals, we need to either process them,
|
|
@@ -229,20 +229,25 @@ class NotificationService extends events_1.EventEmitter {
|
|
|
229
229
|
const groupIdStr = bazinga64_1.Encoder.toBase64(newGroupId).asString;
|
|
230
230
|
// The groupId can then be sent back to the consumer
|
|
231
231
|
return {
|
|
232
|
-
event,
|
|
232
|
+
event: Object.assign(Object.assign({}, event), { data: groupIdStr }),
|
|
233
233
|
mappedEvent: ConversationMapper_1.ConversationMapper.mapConversationEvent(Object.assign(Object.assign({}, event), { data: groupIdStr }), source),
|
|
234
234
|
};
|
|
235
235
|
case Events.CONVERSATION_EVENT.MLS_MESSAGE_ADD:
|
|
236
236
|
const encryptedData = bazinga64_1.Decoder.fromBase64(event.data).asBytes;
|
|
237
|
-
const groupId = await this.
|
|
237
|
+
const groupId = await this.getGroupIdFromConversationId((_a = event.qualified_conversation) !== null && _a !== void 0 ? _a : { id: event.conversation, domain: '' });
|
|
238
|
+
const groupIdBytes = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
|
|
238
239
|
// Check if the message includes proposals
|
|
239
|
-
const { proposals, commitDelay, message } = await this.mlsService.decryptMessage(
|
|
240
|
-
if (proposals.length > 0) {
|
|
240
|
+
const { proposals, commitDelay, message } = await this.mlsService.decryptMessage(groupIdBytes, encryptedData);
|
|
241
|
+
if (typeof commitDelay === 'number' || proposals.length > 0) {
|
|
242
|
+
// we are dealing with a proposal, add a task to process this proposal later on
|
|
243
|
+
// Those proposals are stored inside of coreCrypto and will be handled after a timeout
|
|
241
244
|
await this.handlePendingProposals({
|
|
242
|
-
groupId
|
|
245
|
+
groupId,
|
|
243
246
|
delayInMs: commitDelay !== null && commitDelay !== void 0 ? commitDelay : 0,
|
|
244
247
|
eventTime: event.time,
|
|
245
248
|
});
|
|
249
|
+
// This is not a text message, there is nothing more to do
|
|
250
|
+
return { event };
|
|
246
251
|
}
|
|
247
252
|
if (!message) {
|
|
248
253
|
throw new Error(`MLS message received from ${source} was empty`);
|
|
@@ -280,7 +285,6 @@ class NotificationService extends events_1.EventEmitter {
|
|
|
280
285
|
if (!conversation) {
|
|
281
286
|
throw new Error('no conv');
|
|
282
287
|
}
|
|
283
|
-
await this.saveConversationGroupId(conversation);
|
|
284
288
|
case Events.CONVERSATION_EVENT.MESSAGE_TIMER_UPDATE:
|
|
285
289
|
case Events.CONVERSATION_EVENT.RENAME:
|
|
286
290
|
case Events.CONVERSATION_EVENT.TYPING: {
|
|
@@ -298,37 +302,21 @@ class NotificationService extends events_1.EventEmitter {
|
|
|
298
302
|
}
|
|
299
303
|
return { event };
|
|
300
304
|
}
|
|
301
|
-
/**
|
|
302
|
-
* ## MLS only ##
|
|
303
|
-
* If there is a groupId in the conversation, we need to store the conversationId => groupId pair
|
|
304
|
-
* in order to find the groupId when decrypting messages
|
|
305
|
-
* This is a bit hacky but since mls messages do not embed the groupId we need to keep a mapping of those
|
|
306
|
-
*
|
|
307
|
-
* @param conversation conversation with group_id
|
|
308
|
-
*/
|
|
309
|
-
async saveConversationGroupId(conversation) {
|
|
310
|
-
if (conversation.group_id) {
|
|
311
|
-
const { group_id: groupId, qualified_id: { id: conversationId, domain: conversationDomain }, } = conversation;
|
|
312
|
-
await this.database.addCompoundGroupId({ conversationDomain, conversationId, groupId });
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
305
|
/**
|
|
316
306
|
* ## MLS only ##
|
|
317
307
|
* If there is a matching conversationId => groupId pair in the database,
|
|
318
|
-
* we can find the groupId and return it as a
|
|
308
|
+
* we can find the groupId and return it as a string
|
|
319
309
|
*
|
|
320
310
|
* @param conversationQualifiedId
|
|
321
311
|
*/
|
|
322
|
-
async
|
|
312
|
+
async getGroupIdFromConversationId(conversationQualifiedId) {
|
|
313
|
+
var _a, _b;
|
|
323
314
|
const { id: conversationId, domain: conversationDomain } = conversationQualifiedId;
|
|
324
|
-
const groupId = await this.
|
|
325
|
-
conversationId,
|
|
326
|
-
conversationDomain,
|
|
327
|
-
});
|
|
315
|
+
const groupId = await ((_b = (_a = this.mlsService).groupIdFromConversationId) === null || _b === void 0 ? void 0 : _b.call(_a, conversationQualifiedId));
|
|
328
316
|
if (!groupId) {
|
|
329
317
|
throw new Error(`Could not find a group_id for conversation ${conversationId}@${conversationDomain}`);
|
|
330
318
|
}
|
|
331
|
-
return
|
|
319
|
+
return groupId;
|
|
332
320
|
}
|
|
333
321
|
/**
|
|
334
322
|
* ## MLS only ##
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
export declare type CommonMLS = {
|
|
2
2
|
groupId: string;
|
|
3
3
|
};
|
|
4
|
-
export declare type CompoundGroupIdParams = {
|
|
5
|
-
conversationId: string;
|
|
6
|
-
conversationDomain: string;
|
|
7
|
-
} & CommonMLS;
|
|
8
4
|
export declare type HandlePendingProposalsParams = {
|
|
9
5
|
delayInMs: number;
|
|
10
6
|
eventTime: string;
|
|
@@ -4,5 +4,10 @@ declare type ClientId = string;
|
|
|
4
4
|
declare type Domain = string;
|
|
5
5
|
export declare type ClientIdStringType = `${UserId}:${ClientId}@${Domain}`;
|
|
6
6
|
export declare const constructFullyQualifiedClientId: (userId: UserId, clientId: ClientId, domain: Domain) => ClientIdStringType;
|
|
7
|
+
export declare const parseFullQualifiedClientId: (qualifiedId: string) => {
|
|
8
|
+
user: UserId;
|
|
9
|
+
client: ClientId;
|
|
10
|
+
domain: Domain;
|
|
11
|
+
};
|
|
7
12
|
export declare const mapQualifiedUserClientIdsToFullyQualifiedClientIds: (qualifiedUserMap: QualifiedUserClientMap) => Uint8Array[];
|
|
8
13
|
export {};
|
|
@@ -18,9 +18,19 @@
|
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.mapQualifiedUserClientIdsToFullyQualifiedClientIds = exports.constructFullyQualifiedClientId = void 0;
|
|
21
|
+
exports.mapQualifiedUserClientIdsToFullyQualifiedClientIds = exports.parseFullQualifiedClientId = exports.constructFullyQualifiedClientId = void 0;
|
|
22
22
|
const constructFullyQualifiedClientId = (userId, clientId, domain) => `${userId}:${clientId}@${domain}`;
|
|
23
23
|
exports.constructFullyQualifiedClientId = constructFullyQualifiedClientId;
|
|
24
|
+
const parseFullQualifiedClientId = (qualifiedId) => {
|
|
25
|
+
var _a;
|
|
26
|
+
const regexp = /([a-zA-Z0-9\-]+):([a-zA-Z0-9\-]+)@([a-zA-Z0-9\-.]+)/;
|
|
27
|
+
const [, user, client, domain] = (_a = qualifiedId.match(regexp)) !== null && _a !== void 0 ? _a : [];
|
|
28
|
+
if (!user || !client || !domain) {
|
|
29
|
+
throw new Error(`given client fully qualified ID is corrupted (${qualifiedId})`);
|
|
30
|
+
}
|
|
31
|
+
return { user, client, domain };
|
|
32
|
+
};
|
|
33
|
+
exports.parseFullQualifiedClientId = parseFullQualifiedClientId;
|
|
24
34
|
const mapQualifiedUserClientIdsToFullyQualifiedClientIds = (qualifiedUserMap) => {
|
|
25
35
|
const encoder = new TextEncoder();
|
|
26
36
|
return Object.entries(qualifiedUserMap).flatMap(([domain, users]) => {
|
|
@@ -29,4 +39,4 @@ const mapQualifiedUserClientIdsToFullyQualifiedClientIds = (qualifiedUserMap) =>
|
|
|
29
39
|
});
|
|
30
40
|
};
|
|
31
41
|
exports.mapQualifiedUserClientIdsToFullyQualifiedClientIds = mapQualifiedUserClientIdsToFullyQualifiedClientIds;
|
|
32
|
-
//# sourceMappingURL=
|
|
42
|
+
//# sourceMappingURL=fullyQualifiedClientIdUtils.js.map
|