core-3nweb-client-lib 0.51.0 → 0.52.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/build/api-defs/asmail.d.ts +27 -4
- package/build/api-defs/files.d.ts +6 -3
- package/build/core/asmail/asmail-cap-ipc.js +22 -3
- package/build/core/asmail/delivery/common.d.ts +3 -0
- package/build/core/asmail/delivery/common.js +5 -0
- package/build/core/asmail/delivery/index.js +6 -6
- package/build/core/asmail/delivery/msg.js +1 -6
- package/build/core/asmail/delivery/per-recipient-wip.js +3 -5
- package/build/core/asmail/filtering.d.ts +11 -0
- package/build/core/asmail/filtering.js +219 -0
- package/build/core/asmail/inbox/inbox-events.d.ts +1 -0
- package/build/core/asmail/inbox/inbox-events.js +3 -0
- package/build/core/asmail/inbox/index.d.ts +1 -0
- package/build/core/asmail/inbox/index.js +8 -0
- package/build/core/asmail/index.d.ts +2 -0
- package/build/core/asmail/index.js +29 -4
- package/build/core/asmail/sending-params/index.d.ts +2 -0
- package/build/core/asmail/sending-params/index.js +11 -1
- package/build/core/asmail/sending-params/own-params.d.ts +2 -0
- package/build/core/asmail/sending-params/own-params.js +27 -5
- package/build/core/asmail/sending-params/params-from-others.d.ts +2 -0
- package/build/core/asmail/sending-params/params-from-others.js +28 -3
- package/build/core/keyring/index.d.ts +2 -0
- package/build/core/keyring/index.js +4 -2
- package/build/core/keyring/peer-keys/dataset/v2/logs.d.ts +13 -1
- package/build/core/keyring/peer-keys/dataset/v2/logs.js +17 -1
- package/build/core/keyring/peer-keys/dataset/v2/peer-keys-db.d.ts +2 -0
- package/build/core/keyring/peer-keys/dataset/v2/peer-keys-db.js +31 -1
- package/build/core/keyring/peer-keys/index.d.ts +2 -0
- package/build/core/keyring/peer-keys/index.js +11 -1
- package/build/core/storage/synced/remote-events.d.ts +1 -0
- package/build/core/storage/synced/remote-events.js +3 -0
- package/build/core/storage/synced/storage.d.ts +2 -0
- package/build/core/storage/synced/storage.js +13 -0
- package/build/core/storage/synced/upsyncer.js +2 -1
- package/build/lib-client/3nstorage/storage-owner.js +1 -2
- package/build/lib-client/asmail/sender.d.ts +0 -6
- package/build/lib-client/asmail/sender.js +20 -64
- package/build/lib-client/service-locator.d.ts +1 -2
- package/build/lib-client/service-locator.js +0 -1
- package/build/lib-common/awaitable-state.d.ts +1 -0
- package/build/lib-common/awaitable-state.js +3 -0
- package/build/lib-common/canonical-address.js +3 -0
- package/build/lib-common/periodic-trigger.d.ts +1 -0
- package/build/lib-common/periodic-trigger.js +44 -0
- package/build/tests/caps-api/asmail.js +34 -4
- package/package.json +1 -1
|
@@ -32,10 +32,20 @@ async function makeSendingParamsHolder(fs, anonInvitesOnServer, random) {
|
|
|
32
32
|
await thisSide.close();
|
|
33
33
|
await otherSides.close();
|
|
34
34
|
}
|
|
35
|
+
async function forgetCorrespondentAt(cAddr) {
|
|
36
|
+
await otherSides.forgetCorrespondentAt(cAddr);
|
|
37
|
+
await thisSide.forgetCorrespondentAt(cAddr);
|
|
38
|
+
}
|
|
39
|
+
async function forgetAllCorrespondentsAtDomain(domain) {
|
|
40
|
+
await otherSides.forgetAllCorrespondentsAtDomain(domain);
|
|
41
|
+
await thisSide.forgetAllCorrespondentsAtDomain(domain);
|
|
42
|
+
}
|
|
35
43
|
return {
|
|
36
44
|
thisSide,
|
|
37
45
|
otherSides,
|
|
38
|
-
close
|
|
46
|
+
close,
|
|
47
|
+
forgetCorrespondentAt,
|
|
48
|
+
forgetAllCorrespondentsAtDomain
|
|
39
49
|
};
|
|
40
50
|
}
|
|
41
51
|
Object.freeze(exports);
|
|
@@ -4,5 +4,7 @@ type WritableFS = web3n.files.WritableFS;
|
|
|
4
4
|
export type OwnSendingParams = Awaited<ReturnType<typeof makeOwnSendingParams>>;
|
|
5
5
|
export declare function makeOwnSendingParams(fs: WritableFS, fileName: string, anonInvites: AnonymousInvites): Promise<SendingParamsHolder['thisSide'] & {
|
|
6
6
|
close: () => Promise<void>;
|
|
7
|
+
forgetCorrespondentAt(cAddr: string): Promise<void>;
|
|
8
|
+
forgetAllCorrespondentsAtDomain(domain: string): Promise<void>;
|
|
7
9
|
}>;
|
|
8
10
|
export {};
|
|
@@ -49,7 +49,7 @@ async function makeOwnSendingParams(fs, fileName, anonInvites) {
|
|
|
49
49
|
invitation
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
await
|
|
52
|
+
await saveParamsAndTriggerUpload();
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
function currentToFileJSON() {
|
|
@@ -58,7 +58,7 @@ async function makeOwnSendingParams(fs, fileName, anonInvites) {
|
|
|
58
58
|
senderSpecific: Object.values(params)
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
async function
|
|
61
|
+
async function saveParamsAndTriggerUpload() {
|
|
62
62
|
await paramsFile.writeJSON(currentToFileJSON());
|
|
63
63
|
triggerUpload();
|
|
64
64
|
}
|
|
@@ -160,7 +160,7 @@ async function makeOwnSendingParams(fs, fileName, anonInvites) {
|
|
|
160
160
|
};
|
|
161
161
|
p.suggested.timestamp = Date.now();
|
|
162
162
|
params[p.address] = p;
|
|
163
|
-
await
|
|
163
|
+
await saveParamsAndTriggerUpload();
|
|
164
164
|
return p.suggested;
|
|
165
165
|
});
|
|
166
166
|
}
|
|
@@ -172,17 +172,39 @@ async function makeOwnSendingParams(fs, fileName, anonInvites) {
|
|
|
172
172
|
}
|
|
173
173
|
p.inUse = p.suggested;
|
|
174
174
|
p.suggested = undefined;
|
|
175
|
-
await
|
|
175
|
+
await saveParamsAndTriggerUpload();
|
|
176
176
|
});
|
|
177
177
|
}
|
|
178
178
|
async function close() {
|
|
179
179
|
anonInvites.close();
|
|
180
180
|
stopFileWatching();
|
|
181
181
|
}
|
|
182
|
+
async function forgetCorrespondentAt(cAddr) {
|
|
183
|
+
return changeProc.startOrChain(async () => {
|
|
184
|
+
if (params[cAddr]) {
|
|
185
|
+
delete params[cAddr];
|
|
186
|
+
await saveParamsAndTriggerUpload();
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async function forgetAllCorrespondentsAtDomain(domain) {
|
|
191
|
+
return changeProc.startOrChain(async () => {
|
|
192
|
+
const atDomain = `@${domain}`;
|
|
193
|
+
const addressesToRm = Object.keys(params).filter(addr => addr.endsWith(atDomain));
|
|
194
|
+
if (addressesToRm.length > 0) {
|
|
195
|
+
for (const addr of addressesToRm) {
|
|
196
|
+
delete params[addr];
|
|
197
|
+
}
|
|
198
|
+
await saveParamsAndTriggerUpload();
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
182
202
|
return {
|
|
183
203
|
close,
|
|
184
204
|
getUpdated,
|
|
185
|
-
setAsUsed
|
|
205
|
+
setAsUsed,
|
|
206
|
+
forgetCorrespondentAt,
|
|
207
|
+
forgetAllCorrespondentsAtDomain
|
|
186
208
|
};
|
|
187
209
|
}
|
|
188
210
|
Object.freeze(exports);
|
|
@@ -4,4 +4,6 @@ type WritableFS = web3n.files.WritableFS;
|
|
|
4
4
|
export type ParamsFromOthers = Awaited<ReturnType<typeof makeParamsFromOthers>>;
|
|
5
5
|
export declare function makeParamsFromOthers(fs: WritableFS, fileName: string): Promise<SendingParamsHolder['otherSides'] & {
|
|
6
6
|
close: () => Promise<void>;
|
|
7
|
+
forgetCorrespondentAt(cAddr: string): Promise<void>;
|
|
8
|
+
forgetAllCorrespondentsAtDomain(domain: string): Promise<void>;
|
|
7
9
|
}>;
|
|
@@ -103,17 +103,42 @@ async function makeParamsFromOthers(fs, fileName) {
|
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
105
|
params[address] = copyParams(params);
|
|
106
|
-
await
|
|
107
|
-
triggerUpload();
|
|
106
|
+
await saveParamsAndTriggerUpload();
|
|
108
107
|
});
|
|
109
108
|
}
|
|
109
|
+
async function saveParamsAndTriggerUpload() {
|
|
110
|
+
await paramsFile.writeJSON(params);
|
|
111
|
+
triggerUpload();
|
|
112
|
+
}
|
|
110
113
|
async function close() {
|
|
111
114
|
stopFileWatching();
|
|
112
115
|
}
|
|
116
|
+
async function forgetCorrespondentAt(cAddr) {
|
|
117
|
+
return changeProc.startOrChain(async () => {
|
|
118
|
+
if (params[cAddr]) {
|
|
119
|
+
delete params[cAddr];
|
|
120
|
+
await saveParamsAndTriggerUpload();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async function forgetAllCorrespondentsAtDomain(domain) {
|
|
125
|
+
return changeProc.startOrChain(async () => {
|
|
126
|
+
const atDomain = `@${domain}`;
|
|
127
|
+
const addressesToRm = Object.keys(params).filter(addr => addr.endsWith(atDomain));
|
|
128
|
+
if (addressesToRm.length > 0) {
|
|
129
|
+
for (const addr of addressesToRm) {
|
|
130
|
+
delete params[addr];
|
|
131
|
+
}
|
|
132
|
+
await saveParamsAndTriggerUpload();
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
113
136
|
return {
|
|
114
137
|
get,
|
|
115
138
|
set,
|
|
116
|
-
close
|
|
139
|
+
close,
|
|
140
|
+
forgetCorrespondentAt,
|
|
141
|
+
forgetAllCorrespondentsAtDomain
|
|
117
142
|
};
|
|
118
143
|
}
|
|
119
144
|
/**
|
|
@@ -31,6 +31,8 @@ export interface KeyringForASMail {
|
|
|
31
31
|
getEstablishedKeysToSendMsg: SendingResources['getEstablishedKeysToSendMsg'];
|
|
32
32
|
decrypt: ReceptionResources['msgDecryptor'];
|
|
33
33
|
close(): Promise<void>;
|
|
34
|
+
forgetCorrespondentAt(cAddr: string): Promise<void>;
|
|
35
|
+
forgetAllCorrespondentsAtDomain(domain: string): Promise<void>;
|
|
34
36
|
}
|
|
35
37
|
export declare function makeKeyrings(cryptor: AsyncSBoxCryptor, random: AsyncRNG, logger: Logger, fs: WritableFS, localFS: WritableFS, getSigner: GetSigner, pkeyOnServer: ParamOnServer<'init-pub-key'>): Promise<{
|
|
36
38
|
close: () => Promise<void>;
|
|
@@ -209,13 +209,15 @@ async function makeKeyrings(cryptor, random, logger, fs, localFS, getSigner, pke
|
|
|
209
209
|
decrypt,
|
|
210
210
|
generateIntroKeysToSendMsg,
|
|
211
211
|
getEstablishedKeysToSendMsg,
|
|
212
|
-
needIntroKeyFor: peerKeys.needIntroKeyFor
|
|
212
|
+
needIntroKeyFor: peerKeys.needIntroKeyFor,
|
|
213
|
+
forgetCorrespondentAt: peerKeys.forgetCorrespondentAt,
|
|
214
|
+
forgetAllCorrespondentsAtDomain: peerKeys.forgetAllCorrespondentsAtDomain
|
|
213
215
|
};
|
|
214
216
|
}
|
|
215
217
|
return {
|
|
216
218
|
close,
|
|
217
219
|
makeKeyringsCAP,
|
|
218
|
-
forASMail
|
|
220
|
+
forASMail,
|
|
219
221
|
};
|
|
220
222
|
}
|
|
221
223
|
Object.freeze(exports);
|
|
@@ -29,7 +29,17 @@ export interface PeerStartedUsingPair {
|
|
|
29
29
|
peerKId: string;
|
|
30
30
|
recipientKId: string;
|
|
31
31
|
}
|
|
32
|
-
export
|
|
32
|
+
export interface RemovePeerAtAddress {
|
|
33
|
+
opType: 'remove-peer-at-address';
|
|
34
|
+
eventTS: number;
|
|
35
|
+
peerCAddr: string;
|
|
36
|
+
}
|
|
37
|
+
export interface RemoveAllPeersAtDomain {
|
|
38
|
+
opType: 'remove-all-peers-at-domain';
|
|
39
|
+
eventTS: number;
|
|
40
|
+
domain: string;
|
|
41
|
+
}
|
|
42
|
+
export type PairEvent = PairFromPeerLog | PairSuggestedToPeerLog | PeerStartedUsingPair | RemovePeerAtAddress | RemoveAllPeersAtDomain;
|
|
33
43
|
export declare function sendingPairEntryFromJSON(json: PairFromPeerLog['sendingPairRecord']): SendingKeyPairDbEntry;
|
|
34
44
|
export declare function recipientPairEntryFromJSON(json: PairSuggestedToPeerLog['receivingPairRecord']): RecipientKeyPairDbEntry;
|
|
35
45
|
export declare function makePeerKeysChangeLogs(logsFS: WritableFS, localLogsFS: WritableFS, logError: LogError): Promise<{
|
|
@@ -39,5 +49,7 @@ export declare function makePeerKeysChangeLogs(logsFS: WritableFS, localLogsFS:
|
|
|
39
49
|
numOfLogs: () => number;
|
|
40
50
|
cutLogOnDatasetSyncAndUpload: (syncPointV: number, params?: any) => Promise<void> | undefined;
|
|
41
51
|
watchAndApplyOpsFromOtherDevices: (changeProc: SingleProc, sink: (ops: import("../../../../../lib-common/dataset-sync/per-device-json-array-logs").LogEntry<PairEvent>[]) => Promise<void>) => () => void;
|
|
52
|
+
recordRemovalOfPeerAtAddress: (peerCAddr: string) => Promise<void>;
|
|
53
|
+
recordRemovalOfAllPeersAtDomain: (domain: string) => Promise<void>;
|
|
42
54
|
}>;
|
|
43
55
|
export {};
|
|
@@ -104,13 +104,29 @@ async function makePeerKeysChangeLogs(logsFS, localLogsFS, logError) {
|
|
|
104
104
|
peerAddr
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
|
+
async function recordRemovalOfPeerAtAddress(peerCAddr) {
|
|
108
|
+
await appendLogsAndUpload({
|
|
109
|
+
opType: 'remove-peer-at-address',
|
|
110
|
+
eventTS: Date.now(),
|
|
111
|
+
peerCAddr
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async function recordRemovalOfAllPeersAtDomain(domain) {
|
|
115
|
+
await appendLogsAndUpload({
|
|
116
|
+
opType: 'remove-all-peers-at-domain',
|
|
117
|
+
eventTS: Date.now(),
|
|
118
|
+
domain
|
|
119
|
+
});
|
|
120
|
+
}
|
|
107
121
|
return {
|
|
108
122
|
recordSuggestingCryptoToPeer,
|
|
109
123
|
recordPeerStartedUsingPair,
|
|
110
124
|
recordGettingCryptoFromPeer,
|
|
111
125
|
numOfLogs,
|
|
112
126
|
cutLogOnDatasetSyncAndUpload,
|
|
113
|
-
watchAndApplyOpsFromOtherDevices
|
|
127
|
+
watchAndApplyOpsFromOtherDevices,
|
|
128
|
+
recordRemovalOfPeerAtAddress,
|
|
129
|
+
recordRemovalOfAllPeersAtDomain
|
|
114
130
|
};
|
|
115
131
|
}
|
|
116
132
|
Object.freeze(exports);
|
|
@@ -69,5 +69,7 @@ export declare function makePeerKeysDB(peerKeysFS: WritableFS, random: AsyncRNG)
|
|
|
69
69
|
watchAndApplyOpsFromOtherDevices: (changeProc: SingleProc, resetSyncInterval: () => void) => () => void;
|
|
70
70
|
saveAndSync: () => Promise<number>;
|
|
71
71
|
getPeerKeysInfo: (peerAddr: string) => CorrespondentKeysInfo | undefined;
|
|
72
|
+
forgetCorrespondentAt: (peerCAddr: string) => Promise<void>;
|
|
73
|
+
forgetAllCorrespondentsAtDomain: (domain: string) => Promise<void>;
|
|
72
74
|
}>;
|
|
73
75
|
export {};
|
|
@@ -399,6 +399,25 @@ async function makePeerKeysDB(peerKeysFS, random) {
|
|
|
399
399
|
entryToLog: dbEntry
|
|
400
400
|
};
|
|
401
401
|
}
|
|
402
|
+
async function forgetCorrespondentAt(peerCAddr) {
|
|
403
|
+
for (const table of [
|
|
404
|
+
'reception_key_pairs_pids', 'reception_key_pairs', 'sending_key_pairs', 'peers'
|
|
405
|
+
]) {
|
|
406
|
+
keys.db.exec(`--sql
|
|
407
|
+
DELETE FROM ${table} WHERE peerCAddr=$peerCAddr`, { $peerCAddr: peerCAddr });
|
|
408
|
+
noteDbMotificationForFileSaving();
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
async function forgetAllCorrespondentsAtDomain(domain) {
|
|
412
|
+
for (const table of [
|
|
413
|
+
'reception_key_pairs_pids', 'reception_key_pairs', 'sending_key_pairs', 'peers'
|
|
414
|
+
]) {
|
|
415
|
+
const atDomain = `@${domain}`;
|
|
416
|
+
keys.db.exec(`--sql
|
|
417
|
+
DELETE FROM ${table} WHERE substr(peerCAddr,-${atDomain.length})=$atDomain`, { $atDomain: atDomain });
|
|
418
|
+
noteDbMotificationForFileSaving();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
402
421
|
async function generateRegularSuggestedPairIfNeeded(peerCAddr) {
|
|
403
422
|
const pairsInUse = (0, for_sqlite_1.selectFromTable)(keys.db, 'reception_key_pairs', ['pairTS'], { peerCAddr, ratchetStage: 'in_use' }, receptionKeyPairsTabFields);
|
|
404
423
|
if (pairsInUse && ((pairsInUse[0].pairTS + common_1.MIN_PERIOD_FOR_PAIR) > Date.now())) {
|
|
@@ -484,6 +503,14 @@ async function makePeerKeysDB(peerKeysFS, random) {
|
|
|
484
503
|
const { peerCAddr, peerKId, recipientKId } = op.p;
|
|
485
504
|
markPairAsInUse(peerCAddr, peerKId, recipientKId);
|
|
486
505
|
}
|
|
506
|
+
else if (op.p.opType === 'remove-peer-at-address') {
|
|
507
|
+
const { peerCAddr } = op.p;
|
|
508
|
+
forgetCorrespondentAt(peerCAddr);
|
|
509
|
+
}
|
|
510
|
+
else if (op.p.opType === 'remove-all-peers-at-domain') {
|
|
511
|
+
const { domain } = op.p;
|
|
512
|
+
forgetAllCorrespondentsAtDomain(domain);
|
|
513
|
+
}
|
|
487
514
|
}
|
|
488
515
|
else if (op.syncPoint) {
|
|
489
516
|
// XXX
|
|
@@ -497,6 +524,7 @@ async function makePeerKeysDB(peerKeysFS, random) {
|
|
|
497
524
|
next: fsEvent => changeProc.startOrChain(async () => {
|
|
498
525
|
if (fsEvent.type === 'remote-change') {
|
|
499
526
|
// XXX get remote, compare,add to current what is missing, vs remote
|
|
527
|
+
console.log(`need implementation in peer-keys-db/watchAndApplyOpsFromOtherDevices()`);
|
|
500
528
|
resetSyncInterval();
|
|
501
529
|
}
|
|
502
530
|
})
|
|
@@ -522,7 +550,9 @@ async function makePeerKeysDB(peerKeysFS, random) {
|
|
|
522
550
|
absorbOpsFromOtherDevices,
|
|
523
551
|
watchAndApplyOpsFromOtherDevices,
|
|
524
552
|
saveAndSync,
|
|
525
|
-
getPeerKeysInfo
|
|
553
|
+
getPeerKeysInfo,
|
|
554
|
+
forgetCorrespondentAt,
|
|
555
|
+
forgetAllCorrespondentsAtDomain
|
|
526
556
|
};
|
|
527
557
|
}
|
|
528
558
|
function recipientKeyPairDbEntryIntoDisplayInfo(p) {
|
|
@@ -20,5 +20,7 @@ export declare function makePeersKeyring(keyringFS: WritableFS, localFS: Writabl
|
|
|
20
20
|
updateReceivedMsgCountIn: (peerCAddr: string, peerKId: string, recipientKId: string, msgCount: number, msgTS: number) => void;
|
|
21
21
|
close: () => Promise<void>;
|
|
22
22
|
getPeerKeysInfo: (peerAddr: string) => web3n.keys.CorrespondentKeysInfo | undefined;
|
|
23
|
+
forgetCorrespondentAt: (cAddr: string) => Promise<void>;
|
|
24
|
+
forgetAllCorrespondentsAtDomain: (domain: string) => Promise<void>;
|
|
23
25
|
}>;
|
|
24
26
|
export {};
|
|
@@ -190,6 +190,14 @@ async function makePeersKeyring(keyringFS, localFS, random, logger) {
|
|
|
190
190
|
async function close() {
|
|
191
191
|
stopSyncing();
|
|
192
192
|
}
|
|
193
|
+
async function forgetCorrespondentAt(cAddr) {
|
|
194
|
+
keysDB.forgetCorrespondentAt(cAddr);
|
|
195
|
+
await logs.recordRemovalOfPeerAtAddress(cAddr);
|
|
196
|
+
}
|
|
197
|
+
async function forgetAllCorrespondentsAtDomain(domain) {
|
|
198
|
+
keysDB.forgetAllCorrespondentsAtDomain(domain);
|
|
199
|
+
await logs.recordRemovalOfAllPeersAtDomain(domain);
|
|
200
|
+
}
|
|
193
201
|
return {
|
|
194
202
|
getPeerAddressForCanonical: keysDB.getPeerAddressForCanonical,
|
|
195
203
|
needIntroKeyFor,
|
|
@@ -200,7 +208,9 @@ async function makePeersKeyring(keyringFS, localFS, random, logger) {
|
|
|
200
208
|
markPairAsInUse: (0, synced_1.makeSyncedFunc)(changeProc, undefined, markPairAsInUse),
|
|
201
209
|
updateReceivedMsgCountIn: keysDB.updateReceivedMsgCountIn,
|
|
202
210
|
close,
|
|
203
|
-
getPeerKeysInfo: keysDB.getPeerKeysInfo
|
|
211
|
+
getPeerKeysInfo: keysDB.getPeerKeysInfo,
|
|
212
|
+
forgetCorrespondentAt,
|
|
213
|
+
forgetAllCorrespondentsAtDomain
|
|
204
214
|
};
|
|
205
215
|
}
|
|
206
216
|
function selectPid(pids) {
|
|
@@ -77,6 +77,9 @@ class RemoteEvents {
|
|
|
77
77
|
whenConnected() {
|
|
78
78
|
return this.remoteStorage.connectedState.whenStateIsSet();
|
|
79
79
|
}
|
|
80
|
+
isConnected() {
|
|
81
|
+
return this.remoteStorage.connectedState.isSet();
|
|
82
|
+
}
|
|
80
83
|
absorbObjChange(client) {
|
|
81
84
|
return (new rxjs_1.Observable(obs => client.subscribe(owner_1.events.objChanged.EVENT_NAME, obs)))
|
|
82
85
|
.pipe((0, operators_1.mergeMap)(async ({ newVer: newRemoteVersion, objId }) => {
|
|
@@ -25,6 +25,7 @@ export declare class SyncedStore implements SyncedStorage {
|
|
|
25
25
|
private readonly remoteEvents;
|
|
26
26
|
private readonly uploader;
|
|
27
27
|
private readonly events;
|
|
28
|
+
private stopConnectionCheckingProc;
|
|
28
29
|
private constructor();
|
|
29
30
|
static makeAndStart(path: string, user: string, getSigner: IGetMailerIdSigner, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, random: AsyncRNG, remoteServiceUrl: () => Promise<string>, net: NetClient, logError: LogError): Promise<{
|
|
30
31
|
syncedStore: SyncedStorage;
|
|
@@ -65,5 +66,6 @@ export declare class SyncedStore implements SyncedStorage {
|
|
|
65
66
|
resumeNetworkActivity(): void;
|
|
66
67
|
get connectionEvent$(): Observable<import("./remote-events").StorageConnectionStatus>;
|
|
67
68
|
whenConnected(): Promise<void>;
|
|
69
|
+
private startConnectionCheckingProc;
|
|
68
70
|
}
|
|
69
71
|
export {};
|
|
@@ -27,6 +27,8 @@ const remote_events_1 = require("./remote-events");
|
|
|
27
27
|
const upsyncer_1 = require("./upsyncer");
|
|
28
28
|
const rxjs_1 = require("rxjs");
|
|
29
29
|
const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
|
|
30
|
+
const periodic_trigger_1 = require("../../../lib-common/periodic-trigger");
|
|
31
|
+
const CONNECTION_CHECK_WAIT_SECS = 30;
|
|
30
32
|
class SyncedStore {
|
|
31
33
|
constructor(files, remoteStorage, getStorages, cryptor, random, logError) {
|
|
32
34
|
this.files = files;
|
|
@@ -39,6 +41,7 @@ class SyncedStore {
|
|
|
39
41
|
this.versioned = true;
|
|
40
42
|
this.nodes = new common_1.NodesContainer();
|
|
41
43
|
this.events = new utils_for_observables_1.Broadcast();
|
|
44
|
+
this.stopConnectionCheckingProc = undefined;
|
|
42
45
|
this.remoteEvents = new remote_events_1.RemoteEvents(this.remoteStorage, this.files, this.broadcastNodeEvent.bind(this), this.logError);
|
|
43
46
|
this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.logError);
|
|
44
47
|
Object.seal(this);
|
|
@@ -52,6 +55,7 @@ class SyncedStore {
|
|
|
52
55
|
syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
|
|
53
56
|
startObjProcs: () => {
|
|
54
57
|
s.remoteEvents.startListening();
|
|
58
|
+
s.startConnectionCheckingProc();
|
|
55
59
|
}
|
|
56
60
|
};
|
|
57
61
|
}
|
|
@@ -65,6 +69,7 @@ class SyncedStore {
|
|
|
65
69
|
setMid(getSigner);
|
|
66
70
|
s.uploader.start();
|
|
67
71
|
s.remoteEvents.startListening();
|
|
72
|
+
s.startConnectionCheckingProc();
|
|
68
73
|
}
|
|
69
74
|
};
|
|
70
75
|
}
|
|
@@ -229,7 +234,9 @@ class SyncedStore {
|
|
|
229
234
|
return obj.getNumOfBytesNeedingDownload(version);
|
|
230
235
|
}
|
|
231
236
|
async close() {
|
|
237
|
+
var _a;
|
|
232
238
|
try {
|
|
239
|
+
(_a = this.stopConnectionCheckingProc) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
233
240
|
await this.uploader.stop();
|
|
234
241
|
this.events.done();
|
|
235
242
|
await this.remoteEvents.close();
|
|
@@ -251,6 +258,12 @@ class SyncedStore {
|
|
|
251
258
|
whenConnected() {
|
|
252
259
|
return this.remoteStorage.connectedState.whenStateIsSet();
|
|
253
260
|
}
|
|
261
|
+
startConnectionCheckingProc() {
|
|
262
|
+
if (this.stopConnectionCheckingProc) {
|
|
263
|
+
this.stopConnectionCheckingProc();
|
|
264
|
+
}
|
|
265
|
+
this.stopConnectionCheckingProc = (0, periodic_trigger_1.startPeriodicConditionalTriggerProc)(() => !this.remoteStorage.connectedState.isSet(), () => this.remoteEvents.resumeNetworkActivity(), CONNECTION_CHECK_WAIT_SECS);
|
|
266
|
+
}
|
|
254
267
|
}
|
|
255
268
|
exports.SyncedStore = SyncedStore;
|
|
256
269
|
Object.freeze(SyncedStore.prototype);
|
|
@@ -242,7 +242,8 @@ class UploadTask {
|
|
|
242
242
|
this.info.needUpload = undefined;
|
|
243
243
|
this.uploadCompletion.reject((0, exceptions_1.makeFSSyncException)(`obj-upload`, {
|
|
244
244
|
message: `Fail to upload version ${this.info.uploadVersion} of local version ${this.info.localVersion}`,
|
|
245
|
-
localVersion: this.info.
|
|
245
|
+
localVersion: this.info.localVersion,
|
|
246
|
+
uploadVersion: this.info.uploadVersion,
|
|
246
247
|
cause: exc
|
|
247
248
|
}));
|
|
248
249
|
await this.objStatus.recordUploadCancellation(this.info);
|
|
@@ -262,8 +262,7 @@ class StorageOwner extends user_with_mid_session_1.ServiceUser {
|
|
|
262
262
|
throw (0, exceptions_1.makeUnknownTransactionExc)(objId);
|
|
263
263
|
}
|
|
264
264
|
else if (rep.status === api.currentObj.SC.mismatchedObjVer) {
|
|
265
|
-
const curVer = rep.current_version;
|
|
266
|
-
// XXX is undefined expected, or, was that an error from server? Is it is a header?
|
|
265
|
+
const curVer = rep.data.current_version;
|
|
267
266
|
if (!Number.isInteger(curVer)) {
|
|
268
267
|
throw new Error(`Got non-integer current object version value from a version mismatch reply ${curVer}`);
|
|
269
268
|
}
|
|
@@ -52,12 +52,6 @@ export declare class MailSender {
|
|
|
52
52
|
*/
|
|
53
53
|
static resume(net: NetClient, recipient: string, session: SessionInfo): Promise<MailSender>;
|
|
54
54
|
private setDeliveryUrl;
|
|
55
|
-
private badRedirectExc;
|
|
56
|
-
private unknownRecipientExc;
|
|
57
|
-
private senderNotAllowedExc;
|
|
58
|
-
private inboxIsFullExc;
|
|
59
|
-
private authFailedOnDeliveryExc;
|
|
60
|
-
private recipientHasNoPubKeyExc;
|
|
61
55
|
/**
|
|
62
56
|
* This method throws, if given message size is greater that a maximum
|
|
63
57
|
* message size that server is willing to take.
|
|
@@ -19,6 +19,7 @@ exports.MailSender = void 0;
|
|
|
19
19
|
const api = require("../../lib-common/service-api/asmail/delivery");
|
|
20
20
|
const service_locator_1 = require("../service-locator");
|
|
21
21
|
const http_1 = require("../../lib-common/exceptions/http");
|
|
22
|
+
const common_1 = require("../../core/asmail/delivery/common");
|
|
22
23
|
const LIMIT_ON_MAX_CHUNK = 1024 * 1024;
|
|
23
24
|
const TOO_EARLY_RESTART_PERIOD = 5 * 60 * 1000;
|
|
24
25
|
class MailSender {
|
|
@@ -86,54 +87,6 @@ class MailSender {
|
|
|
86
87
|
}
|
|
87
88
|
this.uri = info.delivery;
|
|
88
89
|
}
|
|
89
|
-
badRedirectExc() {
|
|
90
|
-
return {
|
|
91
|
-
runtimeException: true,
|
|
92
|
-
type: 'asmail-delivery',
|
|
93
|
-
address: this.recipient,
|
|
94
|
-
badRedirect: true
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
unknownRecipientExc() {
|
|
98
|
-
return {
|
|
99
|
-
runtimeException: true,
|
|
100
|
-
type: 'asmail-delivery',
|
|
101
|
-
address: this.recipient,
|
|
102
|
-
unknownRecipient: true
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
senderNotAllowedExc() {
|
|
106
|
-
return {
|
|
107
|
-
runtimeException: true,
|
|
108
|
-
type: 'asmail-delivery',
|
|
109
|
-
address: this.recipient,
|
|
110
|
-
senderNotAllowed: true
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
inboxIsFullExc() {
|
|
114
|
-
return {
|
|
115
|
-
runtimeException: true,
|
|
116
|
-
type: 'asmail-delivery',
|
|
117
|
-
address: this.recipient,
|
|
118
|
-
inboxIsFull: true
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
authFailedOnDeliveryExc() {
|
|
122
|
-
return {
|
|
123
|
-
runtimeException: true,
|
|
124
|
-
type: 'asmail-delivery',
|
|
125
|
-
address: this.recipient,
|
|
126
|
-
authFailedOnDelivery: true
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
recipientHasNoPubKeyExc() {
|
|
130
|
-
return {
|
|
131
|
-
runtimeException: true,
|
|
132
|
-
type: 'asmail-delivery',
|
|
133
|
-
address: this.recipient,
|
|
134
|
-
recipientHasNoPubKey: true
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
90
|
/**
|
|
138
91
|
* This method throws, if given message size is greater that a maximum
|
|
139
92
|
* message size that server is willing to take.
|
|
@@ -144,25 +97,28 @@ class MailSender {
|
|
|
144
97
|
throw new Error(`Premature call to ensure size fit: maximum message length isn't set.`);
|
|
145
98
|
}
|
|
146
99
|
if (msgSize > this.maxMsgLength) {
|
|
147
|
-
|
|
148
|
-
runtimeException: true,
|
|
149
|
-
type: 'asmail-delivery',
|
|
100
|
+
throw (0, common_1.makeDeliveryException)({
|
|
150
101
|
address: this.recipient,
|
|
151
102
|
msgTooBig: true,
|
|
152
103
|
allowedSize: this.maxMsgLength
|
|
153
|
-
};
|
|
154
|
-
throw exc;
|
|
104
|
+
});
|
|
155
105
|
}
|
|
156
106
|
}
|
|
157
107
|
prepareRedirectOrThrowUp(rep) {
|
|
158
108
|
if (("string" !== typeof rep.redirect)
|
|
159
109
|
|| (rep.redirect.length === 0)
|
|
160
110
|
|| ((new URL(rep.redirect)).protocol !== 'https:')) {
|
|
161
|
-
throw
|
|
111
|
+
throw (0, common_1.makeDeliveryException)({
|
|
112
|
+
address: this.recipient, badRedirect: true,
|
|
113
|
+
message: `Server returns invalid url for redirect`
|
|
114
|
+
});
|
|
162
115
|
}
|
|
163
116
|
// refuse second redirect
|
|
164
117
|
if (this.redirectedFrom !== undefined) {
|
|
165
|
-
throw
|
|
118
|
+
throw (0, common_1.makeDeliveryException)({
|
|
119
|
+
address: this.recipient, badRedirect: true,
|
|
120
|
+
message: `Recipient's server points to second redirect, which is one too many`
|
|
121
|
+
});
|
|
166
122
|
}
|
|
167
123
|
// set params
|
|
168
124
|
this.redirectedFrom = this.deliveryURI;
|
|
@@ -204,13 +160,13 @@ class MailSender {
|
|
|
204
160
|
return this.performPreFlight();
|
|
205
161
|
}
|
|
206
162
|
else if (rep.status == api.preFlight.SC.unknownRecipient) {
|
|
207
|
-
throw this.
|
|
163
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, unknownRecipient: true });
|
|
208
164
|
}
|
|
209
165
|
else if (rep.status == api.preFlight.SC.senderNotAllowed) {
|
|
210
|
-
throw this.
|
|
166
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, senderNotAllowed: true });
|
|
211
167
|
}
|
|
212
168
|
else if (rep.status == api.preFlight.SC.inboxFull) {
|
|
213
|
-
throw this.
|
|
169
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, inboxIsFull: true });
|
|
214
170
|
}
|
|
215
171
|
else {
|
|
216
172
|
throw (0, http_1.makeUnexpectedStatusHTTPException)(rep);
|
|
@@ -259,13 +215,13 @@ class MailSender {
|
|
|
259
215
|
return this.startSession();
|
|
260
216
|
}
|
|
261
217
|
else if (rep.status == api.sessionStart.SC.unknownRecipient) {
|
|
262
|
-
throw this.
|
|
218
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, unknownRecipient: true });
|
|
263
219
|
}
|
|
264
220
|
else if (rep.status == api.sessionStart.SC.senderNotAllowed) {
|
|
265
|
-
throw this.
|
|
221
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, senderNotAllowed: true });
|
|
266
222
|
}
|
|
267
223
|
else if (rep.status == api.sessionStart.SC.inboxFull) {
|
|
268
|
-
throw this.
|
|
224
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, inboxIsFull: true });
|
|
269
225
|
}
|
|
270
226
|
else {
|
|
271
227
|
throw (0, http_1.makeUnexpectedStatusHTTPException)(rep);
|
|
@@ -307,7 +263,7 @@ class MailSender {
|
|
|
307
263
|
return this.restartSession();
|
|
308
264
|
}
|
|
309
265
|
else if (rep.status == api.sessionRestart.SC.unknownRecipient) {
|
|
310
|
-
throw this.
|
|
266
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, unknownRecipient: true });
|
|
311
267
|
}
|
|
312
268
|
else {
|
|
313
269
|
throw (0, http_1.makeUnexpectedStatusHTTPException)(rep);
|
|
@@ -337,7 +293,7 @@ class MailSender {
|
|
|
337
293
|
}
|
|
338
294
|
this.sessionId = undefined;
|
|
339
295
|
if (rep.status === api.authSender.SC.authFailed) {
|
|
340
|
-
throw this.
|
|
296
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, authFailedOnDelivery: true });
|
|
341
297
|
}
|
|
342
298
|
else {
|
|
343
299
|
throw (0, http_1.makeUnexpectedStatusHTTPException)(rep);
|
|
@@ -362,7 +318,7 @@ class MailSender {
|
|
|
362
318
|
return this.recipientPubKeyCerts;
|
|
363
319
|
}
|
|
364
320
|
else if (rep.status === api.initPubKey.SC.pkeyNotRegistered) {
|
|
365
|
-
throw this.
|
|
321
|
+
throw (0, common_1.makeDeliveryException)({ address: this.recipient, recipientHasNoPubKey: true });
|
|
366
322
|
}
|
|
367
323
|
else {
|
|
368
324
|
throw (0, http_1.makeUnexpectedStatusHTTPException)(rep);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { NetClient } from './request-utils';
|
|
2
|
-
import type { promises as dnsPromises } from 'dns';
|
|
3
2
|
import { StorageRootRoute } from '../lib-common/service-api/3nstorage/root-route';
|
|
4
3
|
import { ASMailRootRoute } from '../lib-common/service-api/asmail/root-route';
|
|
5
4
|
import { LogError } from './logging/log-to-file';
|
|
@@ -31,7 +30,7 @@ export type ServiceTypeDNSLabel = 'mailerid' | 'asmail' | '3nstorage';
|
|
|
31
30
|
export type ServiceLocatorMaker = (serviceLabel: ServiceTypeDNSLabel | 'report', logError: LogError) => ServiceLocator;
|
|
32
31
|
export type ServiceLocator = (address: string) => Promise<string>;
|
|
33
32
|
export interface DnsResolver {
|
|
34
|
-
resolveTxt: (
|
|
33
|
+
resolveTxt: (hostname: string) => Promise<string[][]>;
|
|
35
34
|
}
|
|
36
35
|
export declare const NODATA = "ENODATA";
|
|
37
36
|
export declare const SERVFAIL = "ESERVFAIL";
|
|
@@ -23,7 +23,6 @@ exports.storageInfoAt = storageInfoAt;
|
|
|
23
23
|
exports.makeServiceLocator = makeServiceLocator;
|
|
24
24
|
exports.getMailerIdInfoFor = getMailerIdInfoFor;
|
|
25
25
|
const jwkeys_1 = require("../lib-common/jwkeys");
|
|
26
|
-
// import { CONNREFUSED, NODATA, NOTFOUND, SERVFAIL, TIMEOUT } from 'dns';
|
|
27
26
|
const runtime_1 = require("../lib-common/exceptions/runtime");
|
|
28
27
|
const http_1 = require("../lib-common/exceptions/http");
|
|
29
28
|
async function readJSONLocatedAt(client, url) {
|