core-3nweb-client-lib 0.27.3 → 0.27.5
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/files.d.ts +92 -29
- package/build/core/asmail/config/index.d.ts +2 -2
- package/build/core/asmail/config/index.js +2 -2
- package/build/core/asmail/config/invitations-anon.d.ts +10 -24
- package/build/core/asmail/config/invitations-anon.js +43 -31
- package/build/core/asmail/config/published-intro-key.d.ts +11 -22
- package/build/core/asmail/config/published-intro-key.js +47 -38
- package/build/core/asmail/delivery/per-recipient-wip.js +2 -2
- package/build/core/asmail/inbox/inbox-events.js +10 -5
- package/build/core/asmail/inbox/index.d.ts +3 -2
- package/build/core/asmail/inbox/index.js +15 -11
- package/build/core/asmail/inbox/msg-indexing.d.ts +17 -64
- package/build/core/asmail/inbox/msg-indexing.js +440 -311
- package/build/core/asmail/inbox/msg-on-disk.js +2 -1
- package/build/core/asmail/index.d.ts +1 -1
- package/build/core/asmail/index.js +5 -4
- package/build/core/asmail/keyring/correspondent-keys.d.ts +2 -2
- package/build/core/asmail/keyring/correspondent-keys.js +4 -2
- package/build/core/asmail/keyring/index.d.ts +10 -33
- package/build/core/asmail/keyring/index.js +88 -75
- package/build/core/asmail/msg/opener.js +4 -3
- package/build/core/asmail/msg/packer.d.ts +1 -0
- package/build/core/asmail/msg/packer.js +8 -4
- package/build/core/index.js +3 -5
- package/build/core/sign-in.js +1 -1
- package/build/core/storage/local/obj-files.js +2 -1
- package/build/core/storage/synced/obj-files.d.ts +2 -0
- package/build/core/storage/synced/obj-files.js +18 -1
- package/build/core/storage/synced/obj-status.d.ts +1 -0
- package/build/core/storage/synced/obj-status.js +10 -0
- package/build/core/storage/synced/storage.js +7 -23
- package/build/core/storage/synced/upload-header-file.js +4 -2
- package/build/core/storage/synced/upsyncer.js +3 -5
- package/build/ipc-via-protobuf/asmail-cap.js +14 -15
- package/build/ipc-via-protobuf/bytes.js +42 -18
- package/build/ipc-via-protobuf/file.d.ts +7 -0
- package/build/ipc-via-protobuf/file.js +103 -66
- package/build/ipc-via-protobuf/fs.js +127 -105
- package/build/ipc-via-protobuf/mailerid.js +2 -2
- package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
- package/build/ipc-via-protobuf/protobuf-msg.js +5 -1
- package/build/ipc-via-protobuf/startup-cap.js +8 -8
- package/build/ipc-via-protobuf/storage-cap.js +4 -4
- package/build/lib-client/3nstorage/xsp-fs/common.js +2 -0
- package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +5 -10
- package/build/lib-client/3nstorage/xsp-fs/file-node.js +26 -45
- package/build/lib-client/3nstorage/xsp-fs/file.d.ts +8 -7
- package/build/lib-client/3nstorage/xsp-fs/file.js +12 -18
- package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +6 -1
- package/build/lib-client/3nstorage/xsp-fs/folder-node.js +20 -8
- package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +19 -18
- package/build/lib-client/3nstorage/xsp-fs/fs.js +18 -19
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +13 -4
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +63 -8
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -0
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +7 -5
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -4
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +20 -15
- package/build/lib-client/cryptor/cryptor-in-worker.js +37 -47
- package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
- package/build/lib-client/cryptor/cryptor.wasm +0 -0
- package/build/lib-client/cryptor/in-proc-js.js +15 -12
- package/build/lib-client/cryptor/in-proc-wasm.js +11 -8
- package/build/lib-client/cryptor/serialization-for-wasm.d.ts +36 -0
- package/build/lib-client/cryptor/serialization-for-wasm.js +58 -0
- package/build/lib-client/cryptor-work-labels.d.ts +26 -0
- package/build/lib-client/cryptor-work-labels.js +152 -0
- package/build/lib-client/fs-sync-utils.d.ts +7 -1
- package/build/lib-client/fs-sync-utils.js +18 -7
- package/build/lib-client/local-files/dev-file-src.d.ts +2 -1
- package/build/lib-client/local-files/dev-file-src.js +5 -1
- package/build/lib-client/local-files/device-fs.js +2 -1
- package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +5 -2
- package/build/lib-client/objs-on-disk/obj-on-disk.js +21 -2
- package/build/lib-client/request-utils.js +14 -14
- package/build/lib-common/async-cryptor-wrap.d.ts +9 -9
- package/build/lib-common/async-cryptor-wrap.js +13 -13
- package/build/lib-common/byte-streaming/pipe.d.ts +1 -1
- package/build/lib-common/byte-streaming/pipe.js +3 -3
- package/build/lib-common/byte-streaming/wrapping.js +4 -2
- package/build/lib-common/json-utils.js +0 -3
- package/build/lib-common/objs-on-disk/file-layout.js +1 -1
- package/build/lib-common/processes/synced.js +0 -184
- package/build/lib-sqlite-on-3nstorage/index.d.ts +32 -0
- package/build/lib-sqlite-on-3nstorage/index.js +117 -0
- package/build/lib-sqlite-on-3nstorage/sqljs.d.ts +279 -0
- package/build/lib-sqlite-on-3nstorage/sqljs.js +223 -0
- package/build/protos/asmail.proto.js +10145 -5923
- package/build/protos/bytes.proto.js +731 -204
- package/build/protos/common.proto.js +192 -44
- package/build/protos/cryptor.proto.js +184 -61
- package/build/protos/file.proto.js +2388 -502
- package/build/protos/fs.proto.js +9894 -6046
- package/build/protos/ipc.proto.js +244 -61
- package/build/protos/logger.proto.js +219 -53
- package/build/protos/mailerid.proto.js +230 -50
- package/build/protos/startup.proto.js +341 -77
- package/build/protos/storage.proto.js +276 -62
- package/package.json +8 -7
- package/protos/bytes.proto +13 -4
- package/protos/file.proto +27 -8
- package/protos/fs.proto +31 -14
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
See the GNU General Public License for more details.
|
|
14
14
|
|
|
15
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.MsgOnDisk = void 0;
|
|
19
20
|
const fs = require("../../../lib-common/async-fs-node");
|
|
@@ -10,6 +10,7 @@ declare type Service = web3n.asmail.Service;
|
|
|
10
10
|
export declare type MailCAPMaker = () => Service;
|
|
11
11
|
export declare class ASMail {
|
|
12
12
|
private readonly cryptor;
|
|
13
|
+
private readonly makeNet;
|
|
13
14
|
private readonly inboxPathForUser;
|
|
14
15
|
private readonly logger;
|
|
15
16
|
private keyring;
|
|
@@ -18,7 +19,6 @@ export declare class ASMail {
|
|
|
18
19
|
private delivery;
|
|
19
20
|
private config;
|
|
20
21
|
private sendingParams;
|
|
21
|
-
private readonly makeNet;
|
|
22
22
|
constructor(cryptor: AsyncSBoxCryptor, makeNet: MakeNet, inboxPathForUser: InboxPathForUser, logger: Logger);
|
|
23
23
|
init(address: string, getSigner: GetSigner, syncedFS: WritableFS, localFS: WritableFS, getStorages: StorageGetter, makeResolver: ServiceLocatorMaker): Promise<void>;
|
|
24
24
|
private setupConfig;
|
|
@@ -32,6 +32,7 @@ const SEND_PARAMS_DATA_FOLDER = 'sending-params';
|
|
|
32
32
|
class ASMail {
|
|
33
33
|
constructor(cryptor, makeNet, inboxPathForUser, logger) {
|
|
34
34
|
this.cryptor = cryptor;
|
|
35
|
+
this.makeNet = makeNet;
|
|
35
36
|
this.inboxPathForUser = inboxPathForUser;
|
|
36
37
|
this.logger = logger;
|
|
37
38
|
this.keyring = undefined;
|
|
@@ -40,7 +41,6 @@ class ASMail {
|
|
|
40
41
|
this.delivery = undefined;
|
|
41
42
|
this.config = undefined;
|
|
42
43
|
this.sendingParams = undefined;
|
|
43
|
-
this.makeNet = () => makeNet();
|
|
44
44
|
Object.seal(this);
|
|
45
45
|
}
|
|
46
46
|
async init(address, getSigner, syncedFS, localFS, getStorages, makeResolver) {
|
|
@@ -70,7 +70,7 @@ class ASMail {
|
|
|
70
70
|
}
|
|
71
71
|
async setupKeyring(syncedFS) {
|
|
72
72
|
const fs = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, KEYRING_DATA_FOLDER);
|
|
73
|
-
this.keyring = await keyring_1.
|
|
73
|
+
this.keyring = await (0, keyring_1.makeAndKeyRing)(this.cryptor, fs, this.config.publishedKeys);
|
|
74
74
|
}
|
|
75
75
|
async setupSendingParams(syncedFS) {
|
|
76
76
|
const fs = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, SEND_PARAMS_DATA_FOLDER);
|
|
@@ -99,8 +99,8 @@ class ASMail {
|
|
|
99
99
|
}
|
|
100
100
|
async setupInbox(syncedFS, getSigner, getStorages, makeResolver) {
|
|
101
101
|
const cachePath = this.inboxPathForUser(this.address);
|
|
102
|
-
const
|
|
103
|
-
this.inbox = await inbox_1.InboxOnServer.makeAndStart(cachePath,
|
|
102
|
+
const inboxSyncedFS = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, INBOX_DATA_FOLDER);
|
|
103
|
+
this.inbox = await inbox_1.InboxOnServer.makeAndStart(cachePath, inboxSyncedFS, {
|
|
104
104
|
address: this.address,
|
|
105
105
|
cryptor: this.cryptor,
|
|
106
106
|
getSigner,
|
|
@@ -126,6 +126,7 @@ class ASMail {
|
|
|
126
126
|
}
|
|
127
127
|
;
|
|
128
128
|
async close() {
|
|
129
|
+
await this.inbox.close();
|
|
129
130
|
await this.keyring.close();
|
|
130
131
|
}
|
|
131
132
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { JWKeyPair, MsgKeyRole, ASMailKeyPair } from './common';
|
|
5
5
|
import { JsonKey, JsonKeyShort } from '../../../lib-common/jwkeys';
|
|
6
6
|
import { SuggestedNextKeyPair } from '../msg/opener';
|
|
7
|
-
import {
|
|
7
|
+
import { KeyPairsStorage } from './index';
|
|
8
8
|
import { Decryptor } from '../../../lib-common/async-cryptor-wrap';
|
|
9
9
|
import { AsyncSBoxCryptor } from 'xsp-files';
|
|
10
10
|
export interface ReceptionPair {
|
|
@@ -89,7 +89,7 @@ export declare class CorrespondentKeys {
|
|
|
89
89
|
* @param serialData from which this object should be reconstructed.
|
|
90
90
|
* Either serialData, or an address should be defined, not both.
|
|
91
91
|
*/
|
|
92
|
-
constructor(keyring:
|
|
92
|
+
constructor(keyring: KeyPairsStorage, address: string | undefined, serialData?: string);
|
|
93
93
|
/**
|
|
94
94
|
* This attaches all keys into ring's maps.
|
|
95
95
|
* Theis method should be called only once, and only on a deserialized
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2018 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2018, 2022 3NSoft Inc.
|
|
4
4
|
|
|
5
5
|
This program is free software: you can redistribute it and/or modify it under
|
|
6
6
|
the terms of the GNU General Public License as published by the Free Software
|
|
@@ -26,6 +26,7 @@ const ecma_nacl_1 = require("ecma-nacl");
|
|
|
26
26
|
const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
27
27
|
const error_1 = require("../../../lib-common/exceptions/error");
|
|
28
28
|
const async_cryptor_wrap_1 = require("../../../lib-common/async-cryptor-wrap");
|
|
29
|
+
const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
|
|
29
30
|
function generatePids() {
|
|
30
31
|
const pids = [];
|
|
31
32
|
for (let i = 0; i < 5; i += 1) {
|
|
@@ -35,7 +36,8 @@ function generatePids() {
|
|
|
35
36
|
}
|
|
36
37
|
function msgMasterDecryptor(cryptor, skey, pkey) {
|
|
37
38
|
const msgMasterKey = calcMsgMasterKey(skey, pkey);
|
|
38
|
-
const
|
|
39
|
+
const workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeRandom('asmail');
|
|
40
|
+
const masterDecr = (0, async_cryptor_wrap_1.makeDecryptor)(cryptor, workLabel, msgMasterKey);
|
|
39
41
|
msgMasterKey.fill(0);
|
|
40
42
|
return masterDecr;
|
|
41
43
|
}
|
|
@@ -7,10 +7,7 @@ import { ResourcesForReceiving } from '../inbox';
|
|
|
7
7
|
export { KEY_USE, MsgKeyRole } from './common';
|
|
8
8
|
export interface MsgKeyInfo {
|
|
9
9
|
correspondent: string;
|
|
10
|
-
|
|
11
|
-
* This is a base64 form of key's byte array.
|
|
12
|
-
*/
|
|
13
|
-
key?: string;
|
|
10
|
+
key?: Uint8Array;
|
|
14
11
|
/**
|
|
15
12
|
* This is a current status of the key in this keyring.
|
|
16
13
|
*/
|
|
@@ -25,35 +22,15 @@ export interface MsgKeyInfo {
|
|
|
25
22
|
declare type WritableFS = web3n.files.WritableFS;
|
|
26
23
|
declare type SendingResources = ResourcesForSending['correspondents'];
|
|
27
24
|
declare type ReceptionResources = ResourcesForReceiving['correspondents'];
|
|
28
|
-
export
|
|
29
|
-
private readonly cryptor;
|
|
30
|
-
private readonly publishedKeys;
|
|
31
|
-
/**
|
|
32
|
-
* This is a map from correspondents' canonical addresses to key objects.
|
|
33
|
-
*/
|
|
34
|
-
private readonly corrKeys;
|
|
35
|
-
readonly pairIdToEmailMap: IdToEmailMap;
|
|
36
|
-
private storage;
|
|
37
|
-
constructor(cryptor: AsyncSBoxCryptor, publishedKeys: ConfigOfASMailServer['publishedKeys']);
|
|
38
|
-
private addCorrespondent;
|
|
39
|
-
private init;
|
|
40
|
-
static makeAndStart(cryptor: AsyncSBoxCryptor, fs: WritableFS, publishedKeys: ConfigOfASMailServer['publishedKeys']): Promise<KeyRing>;
|
|
41
|
-
saveChanges(): void;
|
|
25
|
+
export interface KeyRing {
|
|
42
26
|
needIntroKeyFor: SendingResources['needIntroKeyFor'];
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
private findEstablishedReceptionPairs;
|
|
47
|
-
private decryptMsgKeyWithEstablishedPair;
|
|
48
|
-
/**
|
|
49
|
-
* This method updates message counts and a timestamp in a given reception
|
|
50
|
-
* pair.
|
|
51
|
-
* @param rp is a sending pair, in which changes should be done. Note this
|
|
52
|
-
* must be a shared structure at this point, not a copy of a pair.
|
|
53
|
-
* @param msgCount is a message count that should be added to the pair.
|
|
54
|
-
*/
|
|
55
|
-
private updateReceivedMsgCountIn;
|
|
56
|
-
private absorbSuggestedNextKeyPair;
|
|
57
|
-
readonly decrypt: ReceptionResources['msgDecryptor'];
|
|
27
|
+
generateKeysToSend: SendingResources['generateKeysToSend'];
|
|
28
|
+
nextCrypto: SendingResources['nextCrypto'];
|
|
29
|
+
decrypt: ReceptionResources['msgDecryptor'];
|
|
58
30
|
close(): Promise<void>;
|
|
59
31
|
}
|
|
32
|
+
export declare function makeAndKeyRing(cryptor: AsyncSBoxCryptor, fs: WritableFS, publishedKeys: ConfigOfASMailServer['publishedKeys']): Promise<KeyRing>;
|
|
33
|
+
export interface KeyPairsStorage {
|
|
34
|
+
pairIdToEmailMap: IdToEmailMap;
|
|
35
|
+
saveChanges: () => void;
|
|
36
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2018 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2018, 2022 3NSoft Inc.
|
|
4
4
|
|
|
5
5
|
This program is free software: you can redistribute it and/or modify it under
|
|
6
6
|
the terms of the GNU General Public License as published by the Free Software
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.
|
|
19
|
+
exports.makeAndKeyRing = exports.KEY_USE = void 0;
|
|
20
20
|
const correspondent_keys_1 = require("./correspondent-keys");
|
|
21
21
|
const id_to_email_map_1 = require("./id-to-email-map");
|
|
22
22
|
const common_1 = require("./common");
|
|
@@ -27,9 +27,15 @@ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
|
27
27
|
const canonical_address_1 = require("../../../lib-common/canonical-address");
|
|
28
28
|
const common_2 = require("../delivery/common");
|
|
29
29
|
const keyring_storage_1 = require("./keyring-storage");
|
|
30
|
+
const assert_1 = require("../../../lib-common/assert");
|
|
31
|
+
const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
|
|
30
32
|
var common_3 = require("./common");
|
|
31
33
|
Object.defineProperty(exports, "KEY_USE", { enumerable: true, get: function () { return common_3.KEY_USE; } });
|
|
32
|
-
|
|
34
|
+
function makeAndKeyRing(cryptor, fs, publishedKeys) {
|
|
35
|
+
return KRing.makeAndStart(cryptor, fs, publishedKeys);
|
|
36
|
+
}
|
|
37
|
+
exports.makeAndKeyRing = makeAndKeyRing;
|
|
38
|
+
class KRing {
|
|
33
39
|
constructor(cryptor, publishedKeys) {
|
|
34
40
|
this.cryptor = cryptor;
|
|
35
41
|
this.publishedKeys = publishedKeys;
|
|
@@ -38,8 +44,13 @@ class KeyRing {
|
|
|
38
44
|
*/
|
|
39
45
|
this.corrKeys = new Map();
|
|
40
46
|
this.pairIdToEmailMap = new id_to_email_map_1.IdToEmailMap();
|
|
47
|
+
this.workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeRandom('asmail');
|
|
41
48
|
this.storage = undefined;
|
|
42
|
-
this.
|
|
49
|
+
this.asKeyPairsStorage = {
|
|
50
|
+
pairIdToEmailMap: this.pairIdToEmailMap,
|
|
51
|
+
saveChanges: this.saveChanges.bind(this)
|
|
52
|
+
};
|
|
53
|
+
this.needIntroKeyFor = address => {
|
|
43
54
|
address = (0, canonical_address_1.toCanonicalAddress)(address);
|
|
44
55
|
return !this.corrKeys.has(address);
|
|
45
56
|
};
|
|
@@ -55,7 +66,7 @@ class KeyRing {
|
|
|
55
66
|
const { msgMasterKey, currentPair, msgCount } = await ck.getSendingPair(introPKeyFromServer);
|
|
56
67
|
// prepare message encryptor
|
|
57
68
|
const nextNonce = await random.bytes(xsp_files_1.NONCE_LENGTH);
|
|
58
|
-
const encryptor = (0, async_cryptor_wrap_1.makeEncryptor)(this.cryptor, msgMasterKey, nextNonce);
|
|
69
|
+
const encryptor = (0, async_cryptor_wrap_1.makeEncryptor)(this.cryptor, this.workLabel, msgMasterKey, nextNonce);
|
|
59
70
|
msgMasterKey.fill(0);
|
|
60
71
|
return { encryptor, currentPair, msgCount };
|
|
61
72
|
};
|
|
@@ -68,65 +79,14 @@ class KeyRing {
|
|
|
68
79
|
const suggestPair = await ck.suggestPair();
|
|
69
80
|
return suggestPair;
|
|
70
81
|
};
|
|
71
|
-
this.decrypt = async (msgMeta, getMainObjHeader, getOpenedMsg, checkMidKeyCerts) => {
|
|
72
|
-
let decrInfo;
|
|
73
|
-
let incrMsgCount;
|
|
74
|
-
let openedMsg;
|
|
75
|
-
if (msgMeta.pid) {
|
|
76
|
-
const r = await this.decryptMsgKeyWithEstablishedPair(msgMeta.pid, getMainObjHeader);
|
|
77
|
-
if (!r) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
decrInfo = r.keyInfo;
|
|
81
|
-
incrMsgCount = r.incrMsgCount;
|
|
82
|
-
openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
decrInfo = await this.decryptMsgKeyWithIntroPair(msgMeta.recipientKid, msgMeta.senderPKey, getMainObjHeader);
|
|
86
|
-
if (!decrInfo) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
|
|
90
|
-
const certs = openedMsg.introCryptoCerts;
|
|
91
|
-
const { address, pkey } = await checkMidKeyCerts(certs);
|
|
92
|
-
if (pkey.k !== msgMeta.senderPKey) {
|
|
93
|
-
throw new Error(`Key certificates in the message are not for a key that encrypted this message.`);
|
|
94
|
-
}
|
|
95
|
-
decrInfo.correspondent = (0, canonical_address_1.toCanonicalAddress)(address);
|
|
96
|
-
}
|
|
97
|
-
// check that sender is the same as the trusted correspondent
|
|
98
|
-
const sender = openedMsg.sender;
|
|
99
|
-
if (!sender || !(0, canonical_address_1.areAddressesEqual)(sender, decrInfo.correspondent)) {
|
|
100
|
-
throw new Error(`Mismatch between message sender field '${sender}', and address '${decrInfo.correspondent}', associated with decrypting key.`);
|
|
101
|
-
}
|
|
102
|
-
// update received msg counts and a time stamp
|
|
103
|
-
if (incrMsgCount) {
|
|
104
|
-
incrMsgCount(openedMsg.msgCount);
|
|
105
|
-
}
|
|
106
|
-
// absorb next crypto
|
|
107
|
-
const pair = openedMsg.nextCrypto;
|
|
108
|
-
if (pair) {
|
|
109
|
-
if (msgMeta.recipientKid) {
|
|
110
|
-
if (!pair.isSenderIntroKey) {
|
|
111
|
-
throw new Error(`Introductory message is not referencing used intro key in the next crypto`);
|
|
112
|
-
}
|
|
113
|
-
if (msgMeta.recipientKid !== pair.senderKid) {
|
|
114
|
-
throw new Error(`Introductory message is referencing wrong key in the next crypto`);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
this.absorbSuggestedNextKeyPair(decrInfo.correspondent, pair);
|
|
118
|
-
}
|
|
119
|
-
return { decrInfo, openedMsg };
|
|
120
|
-
};
|
|
121
82
|
Object.seal(this);
|
|
122
83
|
}
|
|
123
84
|
addCorrespondent(address, serialForm) {
|
|
124
85
|
const ck = (serialForm ?
|
|
125
|
-
new correspondent_keys_1.CorrespondentKeys(this, undefined, serialForm) :
|
|
126
|
-
new correspondent_keys_1.CorrespondentKeys(this, address));
|
|
86
|
+
new correspondent_keys_1.CorrespondentKeys(this.asKeyPairsStorage, undefined, serialForm) :
|
|
87
|
+
new correspondent_keys_1.CorrespondentKeys(this.asKeyPairsStorage, address));
|
|
127
88
|
if (this.corrKeys.has(ck.correspondent)) {
|
|
128
|
-
throw new Error(
|
|
129
|
-
" is already present.");
|
|
89
|
+
throw new Error(`Correspondent with address ${ck.correspondent} is already present.`);
|
|
130
90
|
}
|
|
131
91
|
this.corrKeys.set(ck.correspondent, ck);
|
|
132
92
|
if (serialForm) {
|
|
@@ -135,9 +95,7 @@ class KeyRing {
|
|
|
135
95
|
return ck;
|
|
136
96
|
}
|
|
137
97
|
async init(fs) {
|
|
138
|
-
|
|
139
|
-
throw new Error("Keyring has already been initialized.");
|
|
140
|
-
}
|
|
98
|
+
(0, assert_1.assert)(!this.storage);
|
|
141
99
|
this.storage = (0, keyring_storage_1.makeKeyringStorage)(fs);
|
|
142
100
|
await this.storage.start();
|
|
143
101
|
const serialForm = await this.storage.load();
|
|
@@ -155,9 +113,15 @@ class KeyRing {
|
|
|
155
113
|
}
|
|
156
114
|
}
|
|
157
115
|
static async makeAndStart(cryptor, fs, publishedKeys) {
|
|
158
|
-
const kr = new
|
|
116
|
+
const kr = new KRing(cryptor, publishedKeys);
|
|
159
117
|
await kr.init(fs);
|
|
160
|
-
return
|
|
118
|
+
return {
|
|
119
|
+
close: kr.close.bind(kr),
|
|
120
|
+
decrypt: kr.decrypt.bind(kr),
|
|
121
|
+
generateKeysToSend: kr.generateKeysToSend.bind(kr),
|
|
122
|
+
needIntroKeyFor: kr.needIntroKeyFor.bind(kr),
|
|
123
|
+
nextCrypto: kr.nextCrypto.bind(kr)
|
|
124
|
+
};
|
|
161
125
|
}
|
|
162
126
|
saveChanges() {
|
|
163
127
|
// pack bytes that need to be encrypted and saved
|
|
@@ -186,10 +150,9 @@ class KeyRing {
|
|
|
186
150
|
const info = {
|
|
187
151
|
correspondent: undefined,
|
|
188
152
|
keyStatus: recipKey.role,
|
|
189
|
-
key:
|
|
153
|
+
key: mainObjFileKey,
|
|
190
154
|
msgKeyPackLen
|
|
191
155
|
};
|
|
192
|
-
mainObjFileKey.fill(0);
|
|
193
156
|
return info;
|
|
194
157
|
}
|
|
195
158
|
catch (err) {
|
|
@@ -233,7 +196,7 @@ class KeyRing {
|
|
|
233
196
|
const h = await getMainObjHeader();
|
|
234
197
|
for (const { correspondent, pair, role } of pairs) {
|
|
235
198
|
const masterKey = buffer_utils_1.base64.open(pair.msgMasterKey);
|
|
236
|
-
const masterDecr = (0, async_cryptor_wrap_1.makeDecryptor)(this.cryptor, masterKey);
|
|
199
|
+
const masterDecr = (0, async_cryptor_wrap_1.makeDecryptor)(this.cryptor, this.workLabel, masterKey);
|
|
237
200
|
masterKey.fill(0);
|
|
238
201
|
try {
|
|
239
202
|
const msgKeyPackLen = msgKeyPackLenForPair(pair);
|
|
@@ -244,18 +207,18 @@ class KeyRing {
|
|
|
244
207
|
const keyInfo = {
|
|
245
208
|
correspondent: correspondent,
|
|
246
209
|
keyStatus: role,
|
|
247
|
-
key:
|
|
210
|
+
key: mainObjFileKey,
|
|
248
211
|
msgKeyPackLen
|
|
249
212
|
};
|
|
250
|
-
mainObjFileKey.fill(0);
|
|
251
213
|
// set pair as in use
|
|
252
214
|
if (keyInfo.keyStatus === 'suggested') {
|
|
253
215
|
const corrKeys = this.corrKeys.get(keyInfo.correspondent);
|
|
254
216
|
corrKeys.markPairAsInUse(pair);
|
|
255
217
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
218
|
+
return {
|
|
219
|
+
keyInfo,
|
|
220
|
+
incrMsgCount: msgCount => this.updateReceivedMsgCountIn(pair, msgCount)
|
|
221
|
+
};
|
|
259
222
|
}
|
|
260
223
|
catch (err) {
|
|
261
224
|
if (!err.failedCipherVerification) {
|
|
@@ -301,13 +264,63 @@ class KeyRing {
|
|
|
301
264
|
}
|
|
302
265
|
this.saveChanges();
|
|
303
266
|
}
|
|
267
|
+
async decrypt(msgMeta, getMainObjHeader, getOpenedMsg, checkMidKeyCerts) {
|
|
268
|
+
let decrInfo;
|
|
269
|
+
let incrMsgCount;
|
|
270
|
+
let openedMsg;
|
|
271
|
+
if (msgMeta.pid) {
|
|
272
|
+
const r = await this.decryptMsgKeyWithEstablishedPair(msgMeta.pid, getMainObjHeader);
|
|
273
|
+
if (!r) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
decrInfo = r.keyInfo;
|
|
277
|
+
incrMsgCount = r.incrMsgCount;
|
|
278
|
+
openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
decrInfo = await this.decryptMsgKeyWithIntroPair(msgMeta.recipientKid, msgMeta.senderPKey, getMainObjHeader);
|
|
282
|
+
if (!decrInfo) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
|
|
286
|
+
const certs = openedMsg.introCryptoCerts;
|
|
287
|
+
const { address, pkey } = await checkMidKeyCerts(certs);
|
|
288
|
+
if (pkey.k !== msgMeta.senderPKey) {
|
|
289
|
+
throw new Error(`Key certificates in the message are not for a key that encrypted this message.`);
|
|
290
|
+
}
|
|
291
|
+
decrInfo.correspondent = (0, canonical_address_1.toCanonicalAddress)(address);
|
|
292
|
+
}
|
|
293
|
+
// check that sender is the same as the trusted correspondent
|
|
294
|
+
const sender = openedMsg.sender;
|
|
295
|
+
if (!sender || !(0, canonical_address_1.areAddressesEqual)(sender, decrInfo.correspondent)) {
|
|
296
|
+
throw new Error(`Mismatch between message sender field '${sender}', and address '${decrInfo.correspondent}', associated with decrypting key.`);
|
|
297
|
+
}
|
|
298
|
+
// update received msg counts and a time stamp
|
|
299
|
+
if (incrMsgCount) {
|
|
300
|
+
incrMsgCount(openedMsg.msgCount);
|
|
301
|
+
}
|
|
302
|
+
// absorb next crypto
|
|
303
|
+
const pair = openedMsg.nextCrypto;
|
|
304
|
+
if (pair) {
|
|
305
|
+
if (msgMeta.recipientKid) {
|
|
306
|
+
if (!pair.isSenderIntroKey) {
|
|
307
|
+
throw new Error(`Introductory message is not referencing used intro key in the next crypto`);
|
|
308
|
+
}
|
|
309
|
+
if (msgMeta.recipientKid !== pair.senderKid) {
|
|
310
|
+
throw new Error(`Introductory message is referencing wrong key in the next crypto`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
this.absorbSuggestedNextKeyPair(decrInfo.correspondent, pair);
|
|
314
|
+
}
|
|
315
|
+
return { decrInfo, openedMsg };
|
|
316
|
+
}
|
|
317
|
+
;
|
|
304
318
|
close() {
|
|
305
319
|
return this.storage.close();
|
|
306
320
|
}
|
|
307
321
|
}
|
|
308
|
-
|
|
309
|
-
Object.freeze(
|
|
310
|
-
Object.freeze(KeyRing);
|
|
322
|
+
Object.freeze(KRing.prototype);
|
|
323
|
+
Object.freeze(KRing);
|
|
311
324
|
function msgKeyPackLenForPair(p) {
|
|
312
325
|
return (0, common_1.msgKeyPackSizeFor)(p.recipientKey.skey.alg);
|
|
313
326
|
}
|
|
@@ -20,6 +20,7 @@ exports.openMsg = exports.OpenedMsg = void 0;
|
|
|
20
20
|
const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
21
21
|
const error_1 = require("../../../lib-common/exceptions/error");
|
|
22
22
|
const xsp_files_1 = require("xsp-files");
|
|
23
|
+
const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
|
|
23
24
|
class OpenedMsg {
|
|
24
25
|
constructor(msgId, main) {
|
|
25
26
|
this.msgId = msgId;
|
|
@@ -77,9 +78,9 @@ Object.freeze(OpenedMsg);
|
|
|
77
78
|
async function openMsg(msgId, mainObjId, mainObj, headerOfs, fKey, cryptor) {
|
|
78
79
|
try {
|
|
79
80
|
const header = await mainObj.readHeader();
|
|
80
|
-
const segReader = await (0, xsp_files_1.makeSegmentsReader)(fKey, (0, xsp_files_1.idToHeaderNonce)(mainObjId), 0, header.subarray(headerOfs), cryptor);
|
|
81
|
-
const byteSrc =
|
|
82
|
-
const bytes = await byteSrc.
|
|
81
|
+
const segReader = await (0, xsp_files_1.makeSegmentsReader)(fKey, (0, xsp_files_1.idToHeaderNonce)(mainObjId), 0, header.subarray(headerOfs), cryptor, cryptor_work_labels_1.cryptoWorkLabels.makeFor('asmail', msgId));
|
|
82
|
+
const byteSrc = (0, xsp_files_1.makeDecryptedByteSource)(mainObj.segSrc, segReader);
|
|
83
|
+
const bytes = await byteSrc.readNext(undefined);
|
|
83
84
|
if (!bytes) {
|
|
84
85
|
throw new Error(`End of bytes is reached too soon`);
|
|
85
86
|
}
|
|
@@ -52,6 +52,7 @@ export declare class MsgPacker {
|
|
|
52
52
|
private hasAttachments;
|
|
53
53
|
private attachmentsFS;
|
|
54
54
|
private attachmentsCont;
|
|
55
|
+
private workLabel;
|
|
55
56
|
private constructor();
|
|
56
57
|
static empty(segSizeIn256bs: number): MsgPacker;
|
|
57
58
|
static fromPack(p: PackJSON, segSizeIn256bs: number, att: undefined | {
|
|
@@ -24,6 +24,7 @@ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
|
24
24
|
const folder_node_serialization_1 = require("../../../lib-client/3nstorage/xsp-fs/folder-node-serialization");
|
|
25
25
|
const json_utils_1 = require("../../../lib-common/json-utils");
|
|
26
26
|
const attachments_container_1 = require("./attachments-container");
|
|
27
|
+
const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
|
|
27
28
|
function turnKeysToB64(obj) {
|
|
28
29
|
obj.key = buffer_utils_1.base64.pack(obj.key);
|
|
29
30
|
if (!obj.folder) {
|
|
@@ -88,6 +89,7 @@ class MsgPacker {
|
|
|
88
89
|
'From': undefined
|
|
89
90
|
};
|
|
90
91
|
this.mainObjId = this.addJsonObj(this.main);
|
|
92
|
+
this.workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeFor('asmail', this.mainObjId);
|
|
91
93
|
Object.seal(this);
|
|
92
94
|
}
|
|
93
95
|
static empty(segSizeIn256bs) {
|
|
@@ -97,6 +99,7 @@ class MsgPacker {
|
|
|
97
99
|
const packer = new MsgPacker(segSizeIn256bs);
|
|
98
100
|
packer.readyPack = p;
|
|
99
101
|
packer.mainObjId = p.meta.objIds[0];
|
|
102
|
+
packer.workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeFor('asmail', packer.mainObjId);
|
|
100
103
|
Object.values((0, json_utils_1.copy)(p.objs))
|
|
101
104
|
.forEach(obj => {
|
|
102
105
|
packer.allObjs.set(obj.id, obj);
|
|
@@ -347,7 +350,7 @@ class MsgPacker {
|
|
|
347
350
|
}
|
|
348
351
|
const msgKeyPack = await msgKeyEnc.pack(obj.key);
|
|
349
352
|
const bytes = buffer_utils_1.utf8.pack(JSON.stringify(obj.json));
|
|
350
|
-
const segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor);
|
|
353
|
+
const segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor, this.workLabel);
|
|
351
354
|
// make source that inserts message key pack into header
|
|
352
355
|
return makeMainObjSrc(msgKeyPack, bytes, segWriter);
|
|
353
356
|
}
|
|
@@ -410,10 +413,10 @@ class MsgPacker {
|
|
|
410
413
|
// make object segments writer
|
|
411
414
|
let segWriter;
|
|
412
415
|
if (header) {
|
|
413
|
-
segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'restart', header }, random.bytes, cryptor);
|
|
416
|
+
segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'restart', header }, random.bytes, cryptor, this.workLabel);
|
|
414
417
|
}
|
|
415
418
|
else {
|
|
416
|
-
segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor);
|
|
419
|
+
segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor, this.workLabel);
|
|
417
420
|
}
|
|
418
421
|
// make object source
|
|
419
422
|
let src;
|
|
@@ -492,7 +495,8 @@ function fileSrcToByteSrc(fileSrc) {
|
|
|
492
495
|
size: await fileSrc.getSize()
|
|
493
496
|
};
|
|
494
497
|
},
|
|
495
|
-
|
|
498
|
+
readNext: fileSrc.readNext,
|
|
499
|
+
readAt: fileSrc.readAt,
|
|
496
500
|
seek: fileSrc.seek
|
|
497
501
|
};
|
|
498
502
|
}
|
package/build/core/index.js
CHANGED
|
@@ -120,9 +120,8 @@ class Core {
|
|
|
120
120
|
const initFromSignUp$ = signUp.newUser$
|
|
121
121
|
.pipe((0, operators_1.mergeMap)(this.initForNewUser, 1));
|
|
122
122
|
const initFromSignIn$ = signIn.existingUser$;
|
|
123
|
-
const coreInit = (0, rxjs_1.merge)(initFromSignIn$, initFromSignUp$)
|
|
124
|
-
.pipe((0, operators_1.take)(1), (0, operators_1.mergeMap)(idManager => this.initCore(idManager), 1))
|
|
125
|
-
.toPromise();
|
|
123
|
+
const coreInit = (0, rxjs_1.lastValueFrom)((0, rxjs_1.merge)(initFromSignIn$, initFromSignUp$)
|
|
124
|
+
.pipe((0, operators_1.take)(1), (0, operators_1.mergeMap)(idManager => this.initCore(idManager), 1)));
|
|
126
125
|
return { coreInit, capsForStartup };
|
|
127
126
|
}
|
|
128
127
|
;
|
|
@@ -225,8 +224,7 @@ function makeStoragePolicy(appDomain, requestedCAPs) {
|
|
|
225
224
|
}
|
|
226
225
|
else if (Array.isArray(capReq.appFS)) {
|
|
227
226
|
const okDomains = capReq.appFS
|
|
228
|
-
.filter(fsInfo => (fsInfo.domain === appDomain) ||
|
|
229
|
-
fsInfo.domain.endsWith('.' + appDomain))
|
|
227
|
+
.filter(fsInfo => (fsInfo.domain === appDomain) || fsInfo.domain.endsWith('.' + appDomain))
|
|
230
228
|
.map(fsInfo => (0, json_utils_1.copy)(fsInfo));
|
|
231
229
|
policy = {
|
|
232
230
|
canOpenAppFS: severalDomainsAppFSChecker(okDomains)
|
package/build/core/sign-in.js
CHANGED
|
@@ -45,7 +45,7 @@ class SignIn {
|
|
|
45
45
|
const midKeyProgressCB = makeKeyGenProgressCB(0, 50, progressCB);
|
|
46
46
|
const midKeyGen = async (params) => (await (0, key_derivation_1.deriveMidKeyPair)(this.cryptor, pass, params, midKeyProgressCB)).skey;
|
|
47
47
|
const storeKeyProgressCB = makeKeyGenProgressCB(51, 100, progressCB);
|
|
48
|
-
const storeKeyGen =
|
|
48
|
+
const storeKeyGen = params => (0, key_derivation_1.deriveStorageSKey)(this.cryptor, pass, params, storeKeyProgressCB);
|
|
49
49
|
const idManager = await this.completeInitWithoutCache(midKeyGen, storeKeyGen);
|
|
50
50
|
if (!idManager) {
|
|
51
51
|
return false;
|
|
@@ -24,6 +24,7 @@ const path_1 = require("path");
|
|
|
24
24
|
const obj_files_gc_1 = require("./obj-files-gc");
|
|
25
25
|
const obj_status_1 = require("./obj-status");
|
|
26
26
|
const timed_cache_1 = require("../../../lib-common/timed-cache");
|
|
27
|
+
const rxjs_1 = require("rxjs");
|
|
27
28
|
class ObjFiles {
|
|
28
29
|
constructor(folders, logError) {
|
|
29
30
|
this.folders = folders;
|
|
@@ -140,7 +141,7 @@ class LocalObj {
|
|
|
140
141
|
const fPath = this.path(version);
|
|
141
142
|
const { obj, write$ } = await obj_on_disk_1.ObjOnDisk.createFileForWriteOfNewVersion(this.objId, version, fPath, encSub, undefined, this.objSegsGetterFromDisk);
|
|
142
143
|
try {
|
|
143
|
-
await
|
|
144
|
+
await (0, rxjs_1.lastValueFrom)(write$);
|
|
144
145
|
}
|
|
145
146
|
catch (err) {
|
|
146
147
|
if (this.verObjs.get(version) === obj) {
|
|
@@ -89,4 +89,6 @@ export declare class SyncedObj {
|
|
|
89
89
|
syncStatus(): SyncedObjStatus;
|
|
90
90
|
statusObj(): ObjStatus;
|
|
91
91
|
recordRemovalUploadAndGC(): Promise<void>;
|
|
92
|
+
isRemoteVersionOnDisk(version: number): Promise<'complete' | 'partial' | 'none'>;
|
|
93
|
+
downloadRemoteVersion(version: number): Promise<void>;
|
|
92
94
|
}
|
|
@@ -32,6 +32,7 @@ const obj_status_1 = require("./obj-status");
|
|
|
32
32
|
const timed_cache_1 = require("../../../lib-common/timed-cache");
|
|
33
33
|
const upload_header_file_1 = require("./upload-header-file");
|
|
34
34
|
const utils_1 = require("../common/utils");
|
|
35
|
+
const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
|
|
35
36
|
exports.UNSYNCED_FILE_NAME_EXT = 'unsynced';
|
|
36
37
|
exports.REMOTE_FILE_NAME_EXT = 'v';
|
|
37
38
|
/**
|
|
@@ -338,7 +339,8 @@ class SyncedObj {
|
|
|
338
339
|
this.remoteVers.set(uploadVersion, syncedVerObj);
|
|
339
340
|
}
|
|
340
341
|
else {
|
|
341
|
-
|
|
342
|
+
const localPath = this.localVerPath(localVersion);
|
|
343
|
+
await fs.rename(localPath, remotePath);
|
|
342
344
|
}
|
|
343
345
|
await this.status.recordUploadCompletion(localVersion, uploadVersion);
|
|
344
346
|
this.scheduleSelfGC();
|
|
@@ -395,6 +397,21 @@ class SyncedObj {
|
|
|
395
397
|
await this.status.recordRemoteRemovalCompletion();
|
|
396
398
|
this.scheduleSelfGC();
|
|
397
399
|
}
|
|
400
|
+
async isRemoteVersionOnDisk(version) {
|
|
401
|
+
if (!this.status.isAmongRemote(version)) {
|
|
402
|
+
throw (0, exceptions_1.makeObjVersionNotFoundExc)(this.objId, version);
|
|
403
|
+
}
|
|
404
|
+
const verPath = this.remoteVerPath(version);
|
|
405
|
+
if (!(await isOnDisk(verPath))) {
|
|
406
|
+
return 'none';
|
|
407
|
+
}
|
|
408
|
+
const objVer = await this.instanceOfRemoteObjVer(version);
|
|
409
|
+
return (objVer.doesFileNeedDownload() ? 'complete' : 'partial');
|
|
410
|
+
}
|
|
411
|
+
async downloadRemoteVersion(version) {
|
|
412
|
+
const objVer = await this.instanceOfRemoteObjVer(version);
|
|
413
|
+
await objVer.downloadMissingSections();
|
|
414
|
+
}
|
|
398
415
|
}
|
|
399
416
|
exports.SyncedObj = SyncedObj;
|
|
400
417
|
Object.freeze(SyncedObj.prototype);
|
|
@@ -125,6 +125,7 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
|
|
|
125
125
|
neverUploaded(): boolean;
|
|
126
126
|
versionBeforeUnsyncedRemoval(): number | undefined;
|
|
127
127
|
adoptRemoteVersion(version?: number, dropLocalVer?: boolean): Promise<void>;
|
|
128
|
+
isAmongRemote(version: number): boolean;
|
|
128
129
|
}
|
|
129
130
|
export declare function readAndCheckStatus(objFolder: string, objId: ObjId): Promise<ObjStatusInfo>;
|
|
130
131
|
export {};
|
|
@@ -551,6 +551,16 @@ class ObjStatus {
|
|
|
551
551
|
this.updateStateIndicator();
|
|
552
552
|
await this.triggerSaveProc();
|
|
553
553
|
}
|
|
554
|
+
isAmongRemote(version) {
|
|
555
|
+
var _a;
|
|
556
|
+
if (this.status.remote.current === version) {
|
|
557
|
+
return true;
|
|
558
|
+
}
|
|
559
|
+
if ((_a = this.status.remote.archived) === null || _a === void 0 ? void 0 : _a.includes(version)) {
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
554
564
|
}
|
|
555
565
|
exports.ObjStatus = ObjStatus;
|
|
556
566
|
Object.freeze(ObjStatus.prototype);
|