core-3nweb-client-lib 0.49.6 → 0.49.8
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/build/api-defs/asmail.d.ts +1 -0
- package/build/api-defs/files.d.ts +11 -5
- package/build/core/asmail/delivery/common.d.ts +8 -28
- package/build/core/asmail/delivery/common.js +1 -47
- package/build/core/asmail/delivery/index.js +3 -3
- package/build/core/asmail/delivery/per-recipient-wip.js +3 -2
- package/build/core/asmail/inbox/index.d.ts +8 -32
- package/build/core/asmail/inbox/index.js +120 -170
- package/build/core/asmail/inbox/msg-indexing/dataset/v0/sql-db-v-none.d.ts +11 -0
- package/build/{lib-client/xsp-fs/util/for-arrays.js → core/asmail/inbox/msg-indexing/dataset/v0/sql-db-v-none.js} +7 -13
- package/build/core/asmail/inbox/msg-indexing/dataset/v1/logs.d.ts +33 -0
- package/build/core/asmail/inbox/msg-indexing/dataset/v1/logs.js +72 -0
- package/build/core/asmail/inbox/msg-indexing/dataset/v1/sql-db.d.ts +28 -0
- package/build/core/asmail/inbox/msg-indexing/dataset/v1/sql-db.js +477 -0
- package/build/core/asmail/inbox/msg-indexing/index.d.ts +12 -26
- package/build/core/asmail/inbox/msg-indexing/index.js +47 -68
- package/build/core/asmail/inbox/msg-on-disk.d.ts +0 -5
- package/build/core/asmail/inbox/msg-on-disk.js +2 -24
- package/build/core/asmail/index.js +8 -7
- package/build/core/asmail/msg/common.d.ts +0 -1
- package/build/core/asmail/msg/common.js +1 -1
- package/build/core/index.js +7 -4
- package/build/core/keyring/common.d.ts +1 -0
- package/build/core/keyring/common.js +2 -1
- package/build/core/keyring/index.d.ts +7 -44
- package/build/core/keyring/index.js +88 -222
- package/build/core/keyring/introductory-keys/published-intro-key.d.ts +17 -0
- package/build/core/keyring/introductory-keys/published-intro-key.js +190 -0
- package/build/core/keyring/peer-keys/dataset/v1/json-files.d.ts +105 -0
- package/build/core/keyring/peer-keys/dataset/v1/json-files.js +89 -0
- package/build/core/keyring/peer-keys/dataset/v2/logs.d.ts +43 -0
- package/build/core/keyring/peer-keys/dataset/v2/logs.js +116 -0
- package/build/core/keyring/peer-keys/dataset/v2/peer-keys-db.d.ts +73 -0
- package/build/core/keyring/peer-keys/dataset/v2/peer-keys-db.js +543 -0
- package/build/core/keyring/peer-keys/index.d.ts +24 -0
- package/build/core/keyring/peer-keys/index.js +208 -0
- package/build/core/storage/synced/obj-files.js +10 -3
- package/build/core/storage/synced/obj-status.d.ts +1 -1
- package/build/core/storage/synced/obj-status.js +8 -2
- package/build/core/storage/synced/storage.d.ts +4 -4
- package/build/core/storage/system-folders/apps-data.d.ts +0 -1
- package/build/core/storage/system-folders/apps-data.js +2 -6
- package/build/lib-client/asmail/recipient.d.ts +1 -0
- package/build/lib-client/asmail/recipient.js +11 -0
- package/build/lib-client/fs-utils/fs-sync-utils.d.ts +1 -1
- package/build/lib-client/fs-utils/fs-sync-utils.js +70 -13
- package/build/lib-client/xsp-fs/folder-node.js +13 -3
- package/build/lib-client/xsp-fs/fs.js +3 -1
- package/build/lib-client/xsp-fs/node-in-fs.d.ts +1 -0
- package/build/lib-client/xsp-fs/node-in-fs.js +7 -2
- package/build/lib-client/xsp-fs/node-persistence.js +1 -3
- package/build/lib-client/xsp-fs/xsp-payload-v2.js +1 -2
- package/build/lib-common/dataset-sync/per-device-json-array-logs.d.ts +58 -0
- package/build/lib-common/dataset-sync/per-device-json-array-logs.js +432 -0
- package/build/lib-common/dataset-sync/single-file.d.ts +10 -0
- package/build/lib-common/dataset-sync/single-file.js +77 -0
- package/build/lib-common/number-line.d.ts +10 -0
- package/build/lib-common/number-line.js +66 -0
- package/build/lib-common/objs-on-disk/obj-version-file.d.ts +1 -1
- package/build/lib-common/objs-on-disk/obj-version-file.js +3 -3
- package/build/lib-common/rng-def.d.ts +1 -0
- package/build/lib-common/rng-def.js +8 -0
- package/build/lib-sqlite-on-3nstorage/for-sqlite.d.ts +38 -0
- package/build/lib-sqlite-on-3nstorage/for-sqlite.js +162 -0
- package/build/lib-sqlite-on-3nstorage/index.d.ts +18 -5
- package/build/lib-sqlite-on-3nstorage/index.js +49 -26
- package/build/tests/caps-api/file-sink-checks/splice.js +72 -1
- package/build/tests/caps-api/fs-checks/sync-on-one-dev/upload.js +27 -1
- package/build/tests/caps-api/fs-checks/sync-with-two-devs/update-propagation.js +12 -3
- package/build/tests/computer.3nweb.core/inbox/msg-indexing.js +16 -12
- package/build/tests/computer.3nweb.core/keyrings.js +113 -28
- package/build/tests/jasmine.js +2 -2
- package/build/tests/units/number-line.js +9 -9
- package/package.json +2 -1
- package/build/core/asmail/inbox/msg-indexing/logs-n-entries.d.ts +0 -52
- package/build/core/asmail/inbox/msg-indexing/logs-n-entries.js +0 -333
- package/build/core/asmail/inbox/msg-indexing/sql-indexing.d.ts +0 -4
- package/build/core/asmail/inbox/msg-indexing/sql-indexing.js +0 -319
- package/build/core/keyring/correspondent-keys.d.ts +0 -149
- package/build/core/keyring/correspondent-keys.js +0 -403
- package/build/core/keyring/id-to-email-map.d.ts +0 -38
- package/build/core/keyring/id-to-email-map.js +0 -105
- package/build/core/keyring/keyring-storage.d.ts +0 -9
- package/build/core/keyring/keyring-storage.js +0 -54
- package/build/core/keyring/published-intro-key.d.ts +0 -45
- package/build/core/keyring/published-intro-key.js +0 -200
- package/build/lib-client/xsp-fs/util/for-arrays.d.ts +0 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { JWKeyPair } from '../../../common';
|
|
2
|
+
import type { RecipientKeyPairDbEntry, SendingKeyPairDbEntry } from '../v2/peer-keys-db';
|
|
3
|
+
type JsonKey = web3n.keys.JsonKey;
|
|
4
|
+
type JsonKeyShort = web3n.keys.JsonKeyShort;
|
|
5
|
+
type WritableFS = web3n.files.WritableFS;
|
|
6
|
+
export interface ReceptionPair {
|
|
7
|
+
pids: string[];
|
|
8
|
+
recipientKey: JWKeyPair;
|
|
9
|
+
isSenderIntroKey?: boolean;
|
|
10
|
+
senderPKey: JsonKeyShort;
|
|
11
|
+
msgMasterKey: string;
|
|
12
|
+
receivedMsgs?: {
|
|
13
|
+
counts: number[][];
|
|
14
|
+
lastTS: number;
|
|
15
|
+
};
|
|
16
|
+
timestamp: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Introductory pair appears when the first message is sent to a new
|
|
20
|
+
* correspondent. By nature it is an introductory message that uses recipient's
|
|
21
|
+
* published introductory key. Hence, recipient's key material in this pair
|
|
22
|
+
* comes from recipient's publishing.
|
|
23
|
+
*
|
|
24
|
+
* Structurally, introductory pair is just a sending pair with an addition of
|
|
25
|
+
* a flag that allows to distinguish it from ratcheted pair with a clean
|
|
26
|
+
* if-statement.
|
|
27
|
+
*/
|
|
28
|
+
export interface IntroductorySendingPair {
|
|
29
|
+
type: 'intro';
|
|
30
|
+
/**
|
|
31
|
+
* This is recipients' public key, to which encryption is done.
|
|
32
|
+
* If this is an introductory pair, this key is recipient's published intro
|
|
33
|
+
* public key.
|
|
34
|
+
* Else, if this is an ratcheted pair, this key comes from crypto material
|
|
35
|
+
* that recipients suggests from time to time for further use.
|
|
36
|
+
*/
|
|
37
|
+
recipientPKey: JsonKey;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Ratcheted sending pair is a sending pair with pair ids (pids), attached to
|
|
41
|
+
* it. These ids are used to identify correct key material.
|
|
42
|
+
*/
|
|
43
|
+
export interface RatchetedSendingPair {
|
|
44
|
+
type: 'ratcheted';
|
|
45
|
+
pids: string[];
|
|
46
|
+
timestamp: number;
|
|
47
|
+
/**
|
|
48
|
+
* This is sender's secret-public key pair, to which encryption is done.
|
|
49
|
+
* This sending side always generates this key.
|
|
50
|
+
* Key material of an introductory key is used right away.
|
|
51
|
+
* Key material of a ratcheted pair is first suggested to the other side,
|
|
52
|
+
* and is moved to the sending pair when it is used by the other side.
|
|
53
|
+
*/
|
|
54
|
+
senderKey: JWKeyPair;
|
|
55
|
+
/**
|
|
56
|
+
* This is recipients' public key, to which encryption is done.
|
|
57
|
+
* If this is an introductory pair, this key is recipient's published intro
|
|
58
|
+
* public key.
|
|
59
|
+
* Else, if this is an ratcheted pair, this key comes from crypto material
|
|
60
|
+
* that recipients suggests from time to time for further use.
|
|
61
|
+
*/
|
|
62
|
+
recipientPKey: JsonKeyShort;
|
|
63
|
+
/**
|
|
64
|
+
* This is a precomputed message master key that comes from a given pair.
|
|
65
|
+
* This exist only as a speedup measure, to save time of public key crypto
|
|
66
|
+
* calculation by using a bit of extra space.
|
|
67
|
+
*/
|
|
68
|
+
msgMasterKey: string;
|
|
69
|
+
sentMsgs?: {
|
|
70
|
+
count: number;
|
|
71
|
+
lastTS: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export type SendingPair = IntroductorySendingPair | RatchetedSendingPair;
|
|
75
|
+
export interface V1PeerKeysJSON {
|
|
76
|
+
/**
|
|
77
|
+
* This is correspondent's address.
|
|
78
|
+
*/
|
|
79
|
+
correspondent: string;
|
|
80
|
+
/**
|
|
81
|
+
* Sending pair is used for sending messages to this recipient.
|
|
82
|
+
* It is set from suggestions that correspondent sends in her messages.
|
|
83
|
+
* When initiating an exchange, while this pair has not been set, it is
|
|
84
|
+
* generated, which is indicated by the flag.
|
|
85
|
+
*/
|
|
86
|
+
sendingPair: SendingPair | null;
|
|
87
|
+
/**
|
|
88
|
+
* Reception key pairs are pairs which we suggest to this correspondent
|
|
89
|
+
* for sending messages to us.
|
|
90
|
+
* Suggested pair is the one that we have already suggested, or are
|
|
91
|
+
* suggesting now.
|
|
92
|
+
* When correspondent uses suggested pair, we move it to inUse, while
|
|
93
|
+
* previous inUse pair is moved to old.
|
|
94
|
+
*/
|
|
95
|
+
receptionPairs: {
|
|
96
|
+
suggested: ReceptionPair | null;
|
|
97
|
+
inUse: ReceptionPair | null;
|
|
98
|
+
old: ReceptionPair | null;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export declare function checkIfV1AndReadPeerKeys(krFS: WritableFS): Promise<V1PeerKeysJSON[] | undefined>;
|
|
102
|
+
export declare function removeV1FolderIn(krFS: WritableFS): Promise<void>;
|
|
103
|
+
export declare function v1ReceptionPairToV2RecipientKeyPairDbEntry(pairV1: ReceptionPair, ratchetStage: RecipientKeyPairDbEntry['ratchetStage'], peerCAddr: string): RecipientKeyPairDbEntry;
|
|
104
|
+
export declare function v1RatchetedSendingPairToV2SendingKeyPairDbEntry(pairV1: RatchetedSendingPair, peerCAddr: string): SendingKeyPairDbEntry;
|
|
105
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (C) 2026 3NSoft Inc.
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful, but
|
|
11
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
13
|
+
See the GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU General Public License along with
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.checkIfV1AndReadPeerKeys = checkIfV1AndReadPeerKeys;
|
|
20
|
+
exports.removeV1FolderIn = removeV1FolderIn;
|
|
21
|
+
exports.v1ReceptionPairToV2RecipientKeyPairDbEntry = v1ReceptionPairToV2RecipientKeyPairDbEntry;
|
|
22
|
+
exports.v1RatchetedSendingPairToV2SendingKeyPairDbEntry = v1RatchetedSendingPairToV2SendingKeyPairDbEntry;
|
|
23
|
+
const buffer_utils_1 = require("../../../../../lib-common/buffer-utils");
|
|
24
|
+
const ecma_nacl_1 = require("ecma-nacl");
|
|
25
|
+
const VERSION_1_FOLDER_NAME = 'v1';
|
|
26
|
+
const KEYRING_FNAME = 'keyring.json';
|
|
27
|
+
async function checkIfV1AndReadPeerKeys(krFS) {
|
|
28
|
+
if (!(await krFS.checkFolderPresence(VERSION_1_FOLDER_NAME))) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const peerKeys = [];
|
|
32
|
+
const ringJSON = await krFS.readJSONFile(`${VERSION_1_FOLDER_NAME}/${KEYRING_FNAME}`)
|
|
33
|
+
.catch(noop);
|
|
34
|
+
if (ringJSON) {
|
|
35
|
+
for (const peerKeysStr of ringJSON.corrKeys) {
|
|
36
|
+
try {
|
|
37
|
+
peerKeys.push(JSON.parse(peerKeysStr));
|
|
38
|
+
}
|
|
39
|
+
catch (_err) { }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return peerKeys;
|
|
43
|
+
}
|
|
44
|
+
async function removeV1FolderIn(krFS) {
|
|
45
|
+
await krFS.deleteFolder(VERSION_1_FOLDER_NAME, true).catch(noop);
|
|
46
|
+
}
|
|
47
|
+
function noop() { }
|
|
48
|
+
function v1ReceptionPairToV2RecipientKeyPairDbEntry(pairV1, ratchetStage, peerCAddr) {
|
|
49
|
+
const { pids, msgMasterKey, recipientKey, senderPKey, timestamp, isSenderIntroKey, receivedMsgs } = pairV1;
|
|
50
|
+
return {
|
|
51
|
+
ratchetStage,
|
|
52
|
+
pids,
|
|
53
|
+
msgMasterKey: buffer_utils_1.base64.open(msgMasterKey),
|
|
54
|
+
// at version 1 we only had NaCl' box shared key here
|
|
55
|
+
msgMasterKeyAlg: ecma_nacl_1.secret_box.JWK_ALG_NAME,
|
|
56
|
+
pairAlg: recipientKey.pkey.alg,
|
|
57
|
+
pairTS: timestamp,
|
|
58
|
+
peerCAddr,
|
|
59
|
+
peerKId: senderPKey.kid,
|
|
60
|
+
peerPKey: buffer_utils_1.base64.open(senderPKey.k),
|
|
61
|
+
isPeerIntroKey: !!isSenderIntroKey,
|
|
62
|
+
recipientKId: recipientKey.pkey.kid,
|
|
63
|
+
recipientPKey: recipientKey.pkey.k,
|
|
64
|
+
recipientSKey: buffer_utils_1.base64.open(recipientKey.skey.k),
|
|
65
|
+
receivedMsgLastTS: receivedMsgs === null || receivedMsgs === void 0 ? void 0 : receivedMsgs.lastTS,
|
|
66
|
+
receivedMsgsCounts: receivedMsgs === null || receivedMsgs === void 0 ? void 0 : receivedMsgs.counts
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function v1RatchetedSendingPairToV2SendingKeyPairDbEntry(pairV1, peerCAddr) {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
const { pids, msgMasterKey, recipientPKey, senderKey, timestamp, sentMsgs, type } = pairV1;
|
|
72
|
+
return {
|
|
73
|
+
pids,
|
|
74
|
+
msgMasterKey: buffer_utils_1.base64.open(msgMasterKey),
|
|
75
|
+
// at version 1 we only had NaCl' box shared key here
|
|
76
|
+
msgMasterKeyAlg: ecma_nacl_1.secret_box.JWK_ALG_NAME,
|
|
77
|
+
pairAlg: senderKey.pkey.alg,
|
|
78
|
+
pairTS: timestamp,
|
|
79
|
+
peerCAddr,
|
|
80
|
+
peerKId: recipientPKey.kid,
|
|
81
|
+
peerPKey: buffer_utils_1.base64.open(recipientPKey.k),
|
|
82
|
+
senderKId: senderKey.pkey.kid,
|
|
83
|
+
senderPKey: senderKey.pkey.k,
|
|
84
|
+
senderSKey: buffer_utils_1.base64.open(senderKey.skey.k),
|
|
85
|
+
sentMsgLastTS: (_a = sentMsgs === null || sentMsgs === void 0 ? void 0 : sentMsgs.lastTS) !== null && _a !== void 0 ? _a : 0,
|
|
86
|
+
sentMsgsCount: (_b = sentMsgs === null || sentMsgs === void 0 ? void 0 : sentMsgs.count) !== null && _b !== void 0 ? _b : 0
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
Object.freeze(exports);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LogError } from "../../../../../lib-client/logging/log-to-file";
|
|
2
|
+
import { SingleProc } from "../../../../../lib-common/processes/synced";
|
|
3
|
+
import { RecipientKeyPairDbEntry, SendingKeyPairDbEntry } from "./peer-keys-db";
|
|
4
|
+
type WritableFS = web3n.files.WritableFS;
|
|
5
|
+
export interface PairFromPeerLog {
|
|
6
|
+
opType: 'pair-from-peer';
|
|
7
|
+
eventTS: number;
|
|
8
|
+
sendingPairRecord: Omit<SendingKeyPairDbEntry, 'msgMasterKey' | 'senderSKey' | 'peerPKey'> & {
|
|
9
|
+
msgMasterKey: string;
|
|
10
|
+
senderSKey: string;
|
|
11
|
+
peerPKey: string;
|
|
12
|
+
};
|
|
13
|
+
peerAddr: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PairSuggestedToPeerLog {
|
|
16
|
+
opType: 'pair-suggested-to-peer';
|
|
17
|
+
eventTS: number;
|
|
18
|
+
receivingPairRecord: Omit<RecipientKeyPairDbEntry, 'msgMasterKey' | 'recipientSKey' | 'peerPKey'> & {
|
|
19
|
+
msgMasterKey: string;
|
|
20
|
+
recipientSKey: string;
|
|
21
|
+
peerPKey: string;
|
|
22
|
+
};
|
|
23
|
+
peerAddr: string;
|
|
24
|
+
}
|
|
25
|
+
export interface PeerStartedUsingPair {
|
|
26
|
+
opType: 'peer-started-using-pair';
|
|
27
|
+
eventTS: number;
|
|
28
|
+
peerCAddr: string;
|
|
29
|
+
peerKId: string;
|
|
30
|
+
recipientKId: string;
|
|
31
|
+
}
|
|
32
|
+
export type PairEvent = PairFromPeerLog | PairSuggestedToPeerLog | PeerStartedUsingPair;
|
|
33
|
+
export declare function sendingPairEntryFromJSON(json: PairFromPeerLog['sendingPairRecord']): SendingKeyPairDbEntry;
|
|
34
|
+
export declare function recipientPairEntryFromJSON(json: PairSuggestedToPeerLog['receivingPairRecord']): RecipientKeyPairDbEntry;
|
|
35
|
+
export declare function makePeerKeysChangeLogs(logsFS: WritableFS, localLogsFS: WritableFS, logError: LogError): Promise<{
|
|
36
|
+
recordSuggestingCryptoToPeer: (receivingPair: RecipientKeyPairDbEntry, peerAddr: string) => Promise<void>;
|
|
37
|
+
recordPeerStartedUsingPair: (peerCAddr: string, peerKId: string, recipientKId: string) => Promise<void>;
|
|
38
|
+
recordGettingCryptoFromPeer: (sendingPair: SendingKeyPairDbEntry, peerAddr: string) => Promise<void>;
|
|
39
|
+
numOfLogs: () => number;
|
|
40
|
+
cutLogOnDatasetSyncAndUpload: (syncPointV: number, params?: any) => Promise<void> | undefined;
|
|
41
|
+
watchAndApplyOpsFromOtherDevices: (changeProc: SingleProc, sink: (ops: import("../../../../../lib-common/dataset-sync/per-device-json-array-logs").LogEntry<PairEvent>[]) => Promise<void>) => () => void;
|
|
42
|
+
}>;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (C) 2026 3NSoft Inc.
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful, but
|
|
11
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
13
|
+
See the GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU General Public License along with
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.sendingPairEntryFromJSON = sendingPairEntryFromJSON;
|
|
20
|
+
exports.recipientPairEntryFromJSON = recipientPairEntryFromJSON;
|
|
21
|
+
exports.makePeerKeysChangeLogs = makePeerKeysChangeLogs;
|
|
22
|
+
const buffer_utils_1 = require("../../../../../lib-common/buffer-utils");
|
|
23
|
+
const per_device_json_array_logs_1 = require("../../../../../lib-common/dataset-sync/per-device-json-array-logs");
|
|
24
|
+
function sendingPairEntryFromJSON(json) {
|
|
25
|
+
return {
|
|
26
|
+
...json,
|
|
27
|
+
msgMasterKey: buffer_utils_1.base64.open(json.msgMasterKey),
|
|
28
|
+
senderSKey: buffer_utils_1.base64.open(json.senderSKey),
|
|
29
|
+
peerPKey: buffer_utils_1.base64.open(json.peerPKey),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function sendingPairEntryToJSON(entry) {
|
|
33
|
+
return {
|
|
34
|
+
...entry,
|
|
35
|
+
msgMasterKey: buffer_utils_1.base64.pack(entry.msgMasterKey),
|
|
36
|
+
senderSKey: buffer_utils_1.base64.pack(entry.senderSKey),
|
|
37
|
+
peerPKey: buffer_utils_1.base64.pack(entry.peerPKey),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function recipientPairEntryFromJSON(json) {
|
|
41
|
+
return {
|
|
42
|
+
...json,
|
|
43
|
+
msgMasterKey: buffer_utils_1.base64.open(json.msgMasterKey),
|
|
44
|
+
recipientSKey: buffer_utils_1.base64.open(json.recipientSKey),
|
|
45
|
+
peerPKey: buffer_utils_1.base64.open(json.peerPKey),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function recipientPairEntryToJSON(entry) {
|
|
49
|
+
return {
|
|
50
|
+
...entry,
|
|
51
|
+
msgMasterKey: buffer_utils_1.base64.pack(entry.msgMasterKey),
|
|
52
|
+
recipientSKey: buffer_utils_1.base64.pack(entry.recipientSKey),
|
|
53
|
+
peerPKey: buffer_utils_1.base64.pack(entry.peerPKey),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function areEventsEqual(a, b) {
|
|
57
|
+
if (b.opType !== a.opType) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
if (a.opType === 'pair-from-peer') {
|
|
61
|
+
const aSP = a.sendingPairRecord;
|
|
62
|
+
const { peerCAddr, peerKId, senderKId } = b.sendingPairRecord;
|
|
63
|
+
if ((aSP.peerCAddr === peerCAddr) && (aSP.peerKId === peerKId) && (aSP.senderKId === senderKId)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (a.opType === 'pair-suggested-to-peer') {
|
|
68
|
+
const aRP = a.receivingPairRecord;
|
|
69
|
+
const { receivingPairRecord: { peerCAddr, peerKId, recipientKId } } = b;
|
|
70
|
+
if ((aRP.peerCAddr === peerCAddr) && (aRP.peerKId === peerKId) && (aRP.recipientKId === recipientKId)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (a.opType === 'peer-started-using-pair') {
|
|
75
|
+
const { peerCAddr, peerKId, recipientKId } = b;
|
|
76
|
+
if ((a.peerCAddr === peerCAddr) && (a.peerKId === peerKId) && (a.recipientKId === recipientKId)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
async function makePeerKeysChangeLogs(logsFS, localLogsFS, logError) {
|
|
83
|
+
const { appendLogsAndUpload, watchAndApplyOpsFromOtherDevices, cutLogOnDatasetSyncAndUpload, numOfLogs } = await (0, per_device_json_array_logs_1.makeRecentChangesLogs)(logsFS, localLogsFS, areEventsEqual, logError);
|
|
84
|
+
async function recordSuggestingCryptoToPeer(receivingPair, peerAddr) {
|
|
85
|
+
await appendLogsAndUpload({
|
|
86
|
+
opType: 'pair-suggested-to-peer',
|
|
87
|
+
eventTS: Date.now(),
|
|
88
|
+
receivingPairRecord: recipientPairEntryToJSON(receivingPair),
|
|
89
|
+
peerAddr
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async function recordPeerStartedUsingPair(peerCAddr, peerKId, recipientKId) {
|
|
93
|
+
await appendLogsAndUpload({
|
|
94
|
+
opType: 'peer-started-using-pair',
|
|
95
|
+
eventTS: Date.now(),
|
|
96
|
+
peerCAddr, peerKId, recipientKId
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async function recordGettingCryptoFromPeer(sendingPair, peerAddr) {
|
|
100
|
+
await appendLogsAndUpload({
|
|
101
|
+
opType: 'pair-from-peer',
|
|
102
|
+
eventTS: Date.now(),
|
|
103
|
+
sendingPairRecord: sendingPairEntryToJSON(sendingPair),
|
|
104
|
+
peerAddr
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
recordSuggestingCryptoToPeer,
|
|
109
|
+
recordPeerStartedUsingPair,
|
|
110
|
+
recordGettingCryptoFromPeer,
|
|
111
|
+
numOfLogs,
|
|
112
|
+
cutLogOnDatasetSyncAndUpload,
|
|
113
|
+
watchAndApplyOpsFromOtherDevices
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
Object.freeze(exports);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { SuggestedNextKeyPair } from "../../../../asmail/msg/common";
|
|
2
|
+
import { AsyncRNG } from "../../../../../lib-common/rng-def";
|
|
3
|
+
import { PairEvent } from "./logs";
|
|
4
|
+
import { SingleProc } from "../../../../../lib-common/processes/synced";
|
|
5
|
+
import { LogEntry } from "../../../../../lib-common/dataset-sync/per-device-json-array-logs";
|
|
6
|
+
type WritableFS = web3n.files.WritableFS;
|
|
7
|
+
type JsonKey = web3n.keys.JsonKey;
|
|
8
|
+
type CorrespondentKeysInfo = web3n.keys.CorrespondentKeysInfo;
|
|
9
|
+
export interface SendingKeyPairDbEntry {
|
|
10
|
+
peerCAddr: string;
|
|
11
|
+
pids: string[];
|
|
12
|
+
pairAlg: string;
|
|
13
|
+
pairTS: number;
|
|
14
|
+
sentMsgsCount: number;
|
|
15
|
+
sentMsgLastTS: number;
|
|
16
|
+
peerPKey: Uint8Array;
|
|
17
|
+
peerKId: string;
|
|
18
|
+
senderSKey: Uint8Array;
|
|
19
|
+
senderPKey: string;
|
|
20
|
+
senderKId: string;
|
|
21
|
+
msgMasterKeyAlg: string;
|
|
22
|
+
msgMasterKey: Uint8Array;
|
|
23
|
+
}
|
|
24
|
+
export interface RecipientKeyPairDbEntry {
|
|
25
|
+
peerCAddr: string;
|
|
26
|
+
ratchetStage: 'suggested' | 'in_use' | 'old';
|
|
27
|
+
pids: string[];
|
|
28
|
+
pairTS: number;
|
|
29
|
+
pairAlg: string;
|
|
30
|
+
receivedMsgsCounts?: number[][];
|
|
31
|
+
receivedMsgLastTS?: number;
|
|
32
|
+
peerPKey: Uint8Array;
|
|
33
|
+
peerKId: string;
|
|
34
|
+
isPeerIntroKey: boolean;
|
|
35
|
+
recipientSKey: Uint8Array;
|
|
36
|
+
recipientPKey: string;
|
|
37
|
+
recipientKId: string;
|
|
38
|
+
msgMasterKeyAlg: string;
|
|
39
|
+
msgMasterKey: Uint8Array;
|
|
40
|
+
}
|
|
41
|
+
export declare function makePeerKeysDB(peerKeysFS: WritableFS, random: AsyncRNG): Promise<{
|
|
42
|
+
saveIfNeeded: () => Promise<void>;
|
|
43
|
+
generateSuggestedPairOnPeerIntroKey: (peerCAddr: string, peerIntroPKey: JsonKey) => Promise<{
|
|
44
|
+
nextCrypto: SuggestedNextKeyPair;
|
|
45
|
+
entryToLog: RecipientKeyPairDbEntry;
|
|
46
|
+
}>;
|
|
47
|
+
getPairSuggestedToPeer: (peerCAddr: string) => SuggestedNextKeyPair | undefined;
|
|
48
|
+
generateRegularSuggestedPairIfNeeded: (peerCAddr: string) => Promise<{
|
|
49
|
+
nextCrypto: SuggestedNextKeyPair;
|
|
50
|
+
entryToLog: RecipientKeyPairDbEntry;
|
|
51
|
+
} | undefined>;
|
|
52
|
+
addPeer: (peerAddr: string) => void;
|
|
53
|
+
getSendingPair: (peerCAddr: string) => SendingKeyPairDbEntry | undefined;
|
|
54
|
+
updateSentMsgCountInSendingPair: (peerCAddr: string, sentMsgsCount: number) => void;
|
|
55
|
+
addSendingPairFromSuggested: (peerCAddr: string, pair: SuggestedNextKeyPair, cryptoMaterial: Pick<SendingKeyPairDbEntry, "msgMasterKey" | "msgMasterKeyAlg" | "senderKId" | "senderPKey" | "senderSKey" | "peerPKey" | "pairAlg">) => void;
|
|
56
|
+
updateSendingPairFromSuggested: (peerCAddr: string, pair: SuggestedNextKeyPair, cryptoMaterial: Pick<SendingKeyPairDbEntry, "msgMasterKey" | "msgMasterKeyAlg" | "senderKId" | "senderPKey" | "senderSKey" | "peerPKey">) => void;
|
|
57
|
+
findKeyToMatchSuggestedForSendingPair: (peerCAddr: string, thisSideKid: string) => {
|
|
58
|
+
skey: Uint8Array;
|
|
59
|
+
pkey: string;
|
|
60
|
+
pairAlg: string;
|
|
61
|
+
} | undefined;
|
|
62
|
+
addReceptionPair: (pair: RecipientKeyPairDbEntry) => void;
|
|
63
|
+
markPairAsInUse: (peerCAddr: string, peerKId: string, recipientKId: string) => boolean;
|
|
64
|
+
findReceptionPairsForPId: (pid: string) => Pick<RecipientKeyPairDbEntry, "peerCAddr" | "peerKId" | "recipientKId" | "msgMasterKey" | "ratchetStage" | "pairAlg">[] | undefined;
|
|
65
|
+
absorbV1DataIfPresent: (keyringFS: WritableFS) => Promise<void>;
|
|
66
|
+
getPeerAddressForCanonical: (peerCAddr: string) => string | undefined;
|
|
67
|
+
updateReceivedMsgCountIn: (peerCAddr: string, peerKId: string, recipientKId: string, msgCount: number, msgTS: number) => void;
|
|
68
|
+
absorbOpsFromOtherDevices: (changeProc: SingleProc, ops: LogEntry<PairEvent>[]) => Promise<void>;
|
|
69
|
+
watchAndApplyOpsFromOtherDevices: (changeProc: SingleProc, resetSyncInterval: () => void) => () => void;
|
|
70
|
+
saveAndSync: () => Promise<number>;
|
|
71
|
+
getPeerKeysInfo: (peerAddr: string) => CorrespondentKeysInfo | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
export {};
|