spec-3nweb-server 1.7.8 → 1.7.11
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/README.md +16 -2
- package/build/asmail/asmail-app.js +5 -5
- package/build/asmail/config.d.ts +2 -2
- package/build/asmail/delivery.d.ts +2 -2
- package/build/asmail/delivery.js +1 -1
- package/build/asmail/resources/inbox.d.ts +5 -4
- package/build/asmail/resources/inbox.js +75 -65
- package/build/asmail/resources/recipients.d.ts +91 -104
- package/build/asmail/resources/recipients.js +37 -21
- package/build/asmail/retrieval.d.ts +2 -2
- package/build/asmail/retrieval.js +1 -1
- package/build/asmail/routes/config/param-getter.d.ts +3 -1
- package/build/asmail/routes/config/param-getter.js +1 -4
- package/build/asmail/routes/config/param-setter.d.ts +3 -1
- package/build/asmail/routes/config/param-setter.js +1 -5
- package/build/asmail/routes/delivery/finalize-delivery.d.ts +2 -2
- package/build/asmail/routes/delivery/finalize-delivery.js +1 -4
- package/build/asmail/routes/delivery/pre-flight.d.ts +2 -2
- package/build/asmail/routes/delivery/pre-flight.js +1 -7
- package/build/asmail/routes/delivery/provide-recipient-pubkey.d.ts +2 -2
- package/build/asmail/routes/delivery/provide-recipient-pubkey.js +1 -4
- package/build/asmail/routes/delivery/put-metadata.d.ts +2 -2
- package/build/asmail/routes/delivery/put-metadata.js +1 -5
- package/build/asmail/routes/delivery/put-obj.d.ts +2 -2
- package/build/asmail/routes/delivery/put-obj.js +1 -4
- package/build/asmail/routes/delivery/restart-session.d.ts +2 -2
- package/build/asmail/routes/delivery/restart-session.js +1 -13
- package/build/asmail/routes/delivery/sender-authorization.js +0 -3
- package/build/asmail/routes/delivery/start-session.d.ts +4 -3
- package/build/asmail/routes/delivery/start-session.js +3 -11
- package/build/asmail/routes/retrieval/get-message-meta.d.ts +2 -2
- package/build/asmail/routes/retrieval/get-message-meta.js +1 -4
- package/build/asmail/routes/retrieval/get-message-obj.d.ts +2 -2
- package/build/asmail/routes/retrieval/get-message-obj.js +3 -10
- package/build/asmail/routes/retrieval/list-messages.d.ts +2 -2
- package/build/asmail/routes/retrieval/list-messages.js +1 -4
- package/build/asmail/routes/retrieval/remove-message.d.ts +2 -2
- package/build/asmail/routes/retrieval/remove-message.js +0 -3
- package/build/lib-common/async-fs-node.d.ts +1 -0
- package/build/lib-common/buffer-utils.d.ts +1 -0
- package/build/lib-common/objs-on-disk/file-layout.d.ts +1 -0
- package/build/lib-common/objs-on-disk/v1-obj-file-format.d.ts +1 -0
- package/build/signup/signup-tokens.d.ts +1 -0
- package/package.json +6 -9
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@ Thus, we call it a spec server.
|
|
|
7
7
|
Main purpose of this server is to ensure that 3NWeb protocols are implementable, and to be a testbed for possible new features.
|
|
8
8
|
Secondary purpose of this server is to be packagable into a home-class server, i.e. server that can be run from a single machine.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Build & Test
|
|
11
11
|
|
|
12
|
-
To use this repo, you need [Node.js](https://nodejs.org/)
|
|
12
|
+
To use this repo, you need [Node.js](https://nodejs.org/).
|
|
13
13
|
|
|
14
14
|
When in the project's folder, run
|
|
15
15
|
```
|
|
@@ -32,6 +32,20 @@ Config file is `src/tests/jasmine.ts`.
|
|
|
32
32
|
|
|
33
33
|
Please note, that support for running server on windows hasn't been introduced, yet.
|
|
34
34
|
|
|
35
|
+
## ASMail (Authenticated Secure Mail) protocol overview
|
|
36
|
+
|
|
37
|
+
```mermaid
|
|
38
|
+
flowchart LR
|
|
39
|
+
C@{ shape: hex, label: "customer#64;x.y.z" } -- anonymous <br> connection --> VS@{ shape: lin-cyl, label: "ASMail service for a.b.c" }
|
|
40
|
+
V@{ shape: hex, label: "vendor#64;a.b.c" } -- anonymous <br> connection --> CS@{ shape: lin-cyl, label: "ASMail service for x.y.z" }
|
|
41
|
+
subgraph cg[" "]
|
|
42
|
+
CS -- owner <br> connection --> C
|
|
43
|
+
end
|
|
44
|
+
subgraph vg[" "]
|
|
45
|
+
VS -- owner <br> connection --> V
|
|
46
|
+
end
|
|
47
|
+
```
|
|
48
|
+
|
|
35
49
|
# License
|
|
36
50
|
|
|
37
51
|
Code is provided here under GNU General Public License, version 3.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2017, 2020 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2017, 2020, 2025 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
|
|
@@ -51,11 +51,11 @@ function makeASMailApp(rootFolder, domain, midAuthorizer, errLogger) {
|
|
|
51
51
|
const mailDeliverySessions = delivery_sessions_1.DeliverySessions.make(5 * 60);
|
|
52
52
|
const recipientsSessions = (0, sessions_1.makeSessionFactory)(10 * 60);
|
|
53
53
|
const userSettingSessions = (0, sessions_1.makeSessionFactory)(10 * 60);
|
|
54
|
-
const recipients = (0, recipients_1.
|
|
54
|
+
const recipients = (0, recipients_1.makeRecipients)(rootFolder);
|
|
55
55
|
setupStaticEntryRoute(app.http);
|
|
56
|
-
app.http.use(PATHS.delivery, (0, delivery_1.makeApp)(domain, mailDeliverySessions, recipients, midAuthorizer));
|
|
57
|
-
app.use(PATHS.retrieval, (0, retrieval_1.makeApp)(domain, recipientsSessions, recipients, midAuthorizer));
|
|
58
|
-
app.http.use(PATHS.config, (0, config_1.makeApp)(domain, userSettingSessions, recipients, midAuthorizer));
|
|
56
|
+
app.http.use(PATHS.delivery, (0, delivery_1.makeApp)(domain, mailDeliverySessions, recipients.delivery, midAuthorizer));
|
|
57
|
+
app.use(PATHS.retrieval, (0, retrieval_1.makeApp)(domain, recipientsSessions, recipients.retrieval, midAuthorizer));
|
|
58
|
+
app.http.use(PATHS.config, (0, config_1.makeApp)(domain, userSettingSessions, recipients.config, midAuthorizer));
|
|
59
59
|
app.http.use((0, error_handler_1.makeErrHandler)(errLogger));
|
|
60
60
|
return app;
|
|
61
61
|
}
|
package/build/asmail/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as express from 'express';
|
|
2
2
|
import { SessionsFactory } from './resources/sessions';
|
|
3
|
-
import {
|
|
3
|
+
import { ASMailServiceConfig } from './resources/recipients';
|
|
4
4
|
import { MidAuthorizer } from '../lib-server/routes/sessions/mid-auth';
|
|
5
|
-
export declare function makeApp(domain: string, sessions: SessionsFactory, recipients:
|
|
5
|
+
export declare function makeApp(domain: string, sessions: SessionsFactory, recipients: ASMailServiceConfig, midAuthorizer: MidAuthorizer): express.Express;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as express from 'express';
|
|
2
2
|
import { SessionsFactory } from './resources/delivery-sessions';
|
|
3
|
-
import {
|
|
3
|
+
import { MsgDelivery } from './resources/recipients';
|
|
4
4
|
import { IMidAuthorizer } from './routes/delivery/sender-authorization';
|
|
5
|
-
export declare function makeApp(domain: string, sessions: SessionsFactory, recipients:
|
|
5
|
+
export declare function makeApp(domain: string, sessions: SessionsFactory, recipients: MsgDelivery, midAuthorizer: IMidAuthorizer): express.Express;
|
package/build/asmail/delivery.js
CHANGED
|
@@ -5,6 +5,7 @@ import * as configApi from '../../lib-common/service-api/asmail/config';
|
|
|
5
5
|
import * as retrievalApi from '../../lib-common/service-api/asmail/retrieval';
|
|
6
6
|
import { UserFiles, ObjReader } from '../../lib-server/resources/user-files';
|
|
7
7
|
export { ObjPipe, ObjReader } from '../../lib-server/resources/user-files';
|
|
8
|
+
type InitPubKey = configApi.p.initPubKey.Certs;
|
|
8
9
|
type AnonSenderPolicy = configApi.p.anonSenderPolicy.Policy;
|
|
9
10
|
export type AuthSenderPolicy = configApi.p.authSenderPolicy.Policy;
|
|
10
11
|
type Whitelist = configApi.p.authSenderWhitelist.List;
|
|
@@ -23,7 +24,7 @@ export declare const SC: {
|
|
|
23
24
|
OBJ_FILE_INCOMPLETE: string;
|
|
24
25
|
};
|
|
25
26
|
export interface InboxParams {
|
|
26
|
-
"pubkey":
|
|
27
|
+
"pubkey": InitPubKey | null;
|
|
27
28
|
"anonymous/policy": AnonSenderPolicy;
|
|
28
29
|
"anonymous/invites": AnonSenderInvites;
|
|
29
30
|
"authenticated/policy": AuthSenderPolicy;
|
|
@@ -110,11 +111,11 @@ export declare class Inbox extends UserFiles<InboxParams> {
|
|
|
110
111
|
* @return a promise, resolvable to true, when certs are set, or
|
|
111
112
|
* resolvable to false, when given certs do not pass sanitization.
|
|
112
113
|
*/
|
|
113
|
-
setPubKey(initKeyCerts:
|
|
114
|
+
setPubKey(initKeyCerts: InitPubKey | null): Promise<boolean>;
|
|
114
115
|
setAnonSenderPolicy(policy: AnonSenderPolicy): Promise<boolean>;
|
|
115
116
|
setAnonSenderInvites(invites: AnonSenderInvites): Promise<boolean>;
|
|
116
117
|
setAuthSenderPolicy(policy: AuthSenderPolicy): Promise<boolean>;
|
|
117
|
-
setAuthSenderBlacklist(
|
|
118
|
-
setAuthSenderWhitelist(
|
|
118
|
+
setAuthSenderBlacklist(lst: Blacklist): Promise<boolean>;
|
|
119
|
+
setAuthSenderWhitelist(lst: Whitelist): Promise<boolean>;
|
|
119
120
|
setAuthSenderInvites(invites: AuthSenderInvites): Promise<boolean>;
|
|
120
121
|
}
|
|
@@ -334,100 +334,110 @@ class Inbox extends user_files_1.UserFiles {
|
|
|
334
334
|
* resolvable to false, when given certs do not pass sanitization.
|
|
335
335
|
*/
|
|
336
336
|
async setPubKey(initKeyCerts) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
337
|
+
if ((initKeyCerts === null) || isValidIntroPKeyCerts(initKeyCerts)) {
|
|
338
|
+
await this.setParam('pubkey', initKeyCerts);
|
|
339
|
+
return true;
|
|
340
340
|
}
|
|
341
341
|
else {
|
|
342
|
-
|
|
343
|
-
(0, jwkeys_1.isLikeSignedKeyCert)(initKeyCerts.pkeyCert) &&
|
|
344
|
-
(0, jwkeys_1.isLikeSignedKeyCert)(initKeyCerts.userCert) &&
|
|
345
|
-
(0, jwkeys_1.isLikeSignedKeyCert)(initKeyCerts.provCert));
|
|
346
|
-
}
|
|
347
|
-
if (isOK) {
|
|
348
|
-
await this.setParam('pubkey', initKeyCerts);
|
|
342
|
+
return false;
|
|
349
343
|
}
|
|
350
|
-
return isOK;
|
|
351
344
|
}
|
|
352
345
|
async setAnonSenderPolicy(policy) {
|
|
353
|
-
|
|
354
|
-
('boolean' === typeof policy.accept) &&
|
|
355
|
-
('boolean' === typeof policy.acceptWithInvitesOnly) &&
|
|
356
|
-
('number' === typeof policy.defaultMsgSize) &&
|
|
357
|
-
(policy.defaultMsgSize > 500));
|
|
358
|
-
if (isOK) {
|
|
346
|
+
if (isValidAnonSenderPolicy(policy)) {
|
|
359
347
|
await this.setParam('anonymous/policy', policy);
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
return false;
|
|
360
352
|
}
|
|
361
|
-
return isOK;
|
|
362
353
|
}
|
|
363
354
|
async setAnonSenderInvites(invites) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
return
|
|
355
|
+
if (isValidListWithMsgMaxSizes(invites)) {
|
|
356
|
+
await this.setParam('anonymous/invites', invites);
|
|
357
|
+
return true;
|
|
367
358
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const isOK = ('number' === typeof msgMaxSize) && (msgMaxSize > 500);
|
|
371
|
-
if (!isOK) {
|
|
372
|
-
return false;
|
|
373
|
-
}
|
|
359
|
+
else {
|
|
360
|
+
return false;
|
|
374
361
|
}
|
|
375
|
-
await this.setParam('anonymous/invites', invites);
|
|
376
|
-
return true;
|
|
377
362
|
}
|
|
378
363
|
async setAuthSenderPolicy(policy) {
|
|
379
|
-
|
|
380
|
-
('boolean' === typeof policy.applyBlackList) &&
|
|
381
|
-
('boolean' === typeof policy.acceptFromWhiteListOnly) &&
|
|
382
|
-
('boolean' === typeof policy.acceptWithInvitesOnly) &&
|
|
383
|
-
('number' === typeof policy.defaultMsgSize) &&
|
|
384
|
-
(policy.defaultMsgSize > 500));
|
|
385
|
-
if (!isOK) {
|
|
364
|
+
if (isValidAuthSenderPolicy(policy)) {
|
|
386
365
|
await this.setParam('authenticated/policy', policy);
|
|
366
|
+
return true;
|
|
387
367
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
async setAuthSenderBlacklist(list) {
|
|
391
|
-
const isOK = ('object' === typeof list) && !!list;
|
|
392
|
-
if (isOK) {
|
|
393
|
-
await this.setParam('authenticated/blacklist', list);
|
|
368
|
+
else {
|
|
369
|
+
return false;
|
|
394
370
|
}
|
|
395
|
-
return isOK;
|
|
396
371
|
}
|
|
397
|
-
async
|
|
398
|
-
|
|
399
|
-
|
|
372
|
+
async setAuthSenderBlacklist(lst) {
|
|
373
|
+
if (isValidBlacklist(lst)) {
|
|
374
|
+
await this.setParam('authenticated/blacklist', lst);
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
400
378
|
return false;
|
|
401
379
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
380
|
+
}
|
|
381
|
+
async setAuthSenderWhitelist(lst) {
|
|
382
|
+
if (isValidListWithMsgMaxSizes(lst)) {
|
|
383
|
+
await this.setParam('authenticated/whitelist', lst);
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
return false;
|
|
408
388
|
}
|
|
409
|
-
await this.setParam('authenticated/whitelist', list);
|
|
410
|
-
return true;
|
|
411
389
|
}
|
|
412
390
|
async setAuthSenderInvites(invites) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
return
|
|
391
|
+
if (isValidListWithMsgMaxSizes(invites)) {
|
|
392
|
+
await this.setParam('authenticated/invites', invites);
|
|
393
|
+
return true;
|
|
416
394
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
const isOK = ('number' === typeof msgMaxSize) && (msgMaxSize > 500);
|
|
420
|
-
if (!isOK) {
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
395
|
+
else {
|
|
396
|
+
return false;
|
|
423
397
|
}
|
|
424
|
-
await this.setParam('authenticated/invites', invites);
|
|
425
|
-
return true;
|
|
426
398
|
}
|
|
427
399
|
}
|
|
428
400
|
exports.Inbox = Inbox;
|
|
429
401
|
Object.freeze(Inbox.prototype);
|
|
430
402
|
Object.freeze(Inbox);
|
|
403
|
+
function isValidIntroPKeyCerts(pkeyCerts) {
|
|
404
|
+
return ((typeof pkeyCerts === 'object') && !!pkeyCerts &&
|
|
405
|
+
(0, jwkeys_1.isLikeSignedKeyCert)(pkeyCerts.pkeyCert) &&
|
|
406
|
+
(0, jwkeys_1.isLikeSignedKeyCert)(pkeyCerts.userCert) &&
|
|
407
|
+
(0, jwkeys_1.isLikeSignedKeyCert)(pkeyCerts.provCert));
|
|
408
|
+
}
|
|
409
|
+
function isValidAnonSenderPolicy(policy) {
|
|
410
|
+
return (('object' === typeof policy) && !!policy &&
|
|
411
|
+
('boolean' === typeof policy.accept) &&
|
|
412
|
+
('boolean' === typeof policy.acceptWithInvitesOnly) &&
|
|
413
|
+
('number' === typeof policy.defaultMsgSize) &&
|
|
414
|
+
(policy.defaultMsgSize > 500));
|
|
415
|
+
}
|
|
416
|
+
function isValidAuthSenderPolicy(policy) {
|
|
417
|
+
return (('object' === typeof policy) && !!policy &&
|
|
418
|
+
('boolean' === typeof policy.applyBlackList) &&
|
|
419
|
+
('boolean' === typeof policy.acceptFromWhiteListOnly) &&
|
|
420
|
+
('boolean' === typeof policy.acceptWithInvitesOnly) &&
|
|
421
|
+
('number' === typeof policy.defaultMsgSize) &&
|
|
422
|
+
(policy.defaultMsgSize > 500));
|
|
423
|
+
}
|
|
424
|
+
function isValidListWithMsgMaxSizes(lst) {
|
|
425
|
+
const isOK = ('object' === typeof lst) && !!lst;
|
|
426
|
+
if (!isOK) {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
for (const inviteOrAddr in lst) {
|
|
430
|
+
const msgMaxSize = lst[inviteOrAddr];
|
|
431
|
+
const isOK = ('number' === typeof msgMaxSize) && (msgMaxSize > 500);
|
|
432
|
+
if (!isOK) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
function isValidBlacklist(lst) {
|
|
439
|
+
return ('object' === typeof lst) && !!lst;
|
|
440
|
+
}
|
|
431
441
|
class ObjFiles {
|
|
432
442
|
constructor(cachePeriodMillis, deliveryFolder, readyMsgsFolder) {
|
|
433
443
|
this.deliveryFolder = deliveryFolder;
|
|
@@ -5,110 +5,97 @@ import * as deliveryApi from '../../lib-common/service-api/asmail/delivery';
|
|
|
5
5
|
import * as retrievalApi from '../../lib-common/service-api/asmail/retrieval';
|
|
6
6
|
export { SC } from './inbox';
|
|
7
7
|
export declare const BIN_TYPE = "application/octet-stream";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* either to true, when given user id is known, or to false, when it is not.
|
|
11
|
-
*/
|
|
12
|
-
export type UserExists = (userId: string) => Promise<boolean>;
|
|
13
|
-
/**
|
|
14
|
-
* This tells what is an allowable maximum message size for a given recipient,
|
|
15
|
-
* for a given sender and/or under a given invitation token.
|
|
16
|
-
* Function returns a promise, resolvable to
|
|
17
|
-
* (1) zero (0), if leaving mail is forbidden,
|
|
18
|
-
* (2) greater than zero maximum message length, and
|
|
19
|
-
* (3) -1 (less than zero), if mail cannot be accepted due to full mail
|
|
20
|
-
* box.
|
|
21
|
-
*/
|
|
22
|
-
export type AllowedMaxMsgSize = (recipient: string, sender: string | undefined, invitation: string | undefined) => Promise<number>;
|
|
23
|
-
/**
|
|
24
|
-
* This allocates storage for a message returning a promise, resolvable to
|
|
25
|
-
* (1) message id, when a folder for new message has been created,
|
|
26
|
-
* (2) undefined, if recipient is unknown.
|
|
27
|
-
*/
|
|
28
|
-
export type SetMsgStorage = (recipient: string, msgMeta: deliveryApi.msgMeta.Request, authSender: string | undefined, invite: string | undefined, maxMsgLength: number) => Promise<string>;
|
|
29
|
-
/**
|
|
30
|
-
* This saves object's bytes, returning a promise, resolvable when saving
|
|
31
|
-
* is OK, otherwise, promise rejects with string error code from SC.
|
|
32
|
-
*/
|
|
33
|
-
export type SaveObj = (recipient: string, msgId: string, objId: string, fstReq: deliveryApi.PutObjFirstQueryOpts | undefined, sndReq: deliveryApi.PutObjSecondQueryOpts | undefined, bytesLen: number, bytes: Readable) => Promise<void>;
|
|
34
|
-
/**
|
|
35
|
-
* This finalizes delivery of a message, returning a promise.
|
|
36
|
-
* Rejected promise may have a string error code from SC.
|
|
37
|
-
*/
|
|
38
|
-
export type FinalizeDelivery = (recipient: string, msgId: string) => Promise<void>;
|
|
39
|
-
/**
|
|
40
|
-
* This returns a promise, resolvable to array with ids of available messages.
|
|
41
|
-
* Rejected promise may have a string error code from SC.
|
|
42
|
-
*/
|
|
43
|
-
export type GetMsgIds = (userId: string) => Promise<retrievalApi.listMsgs.Reply>;
|
|
44
|
-
/**
|
|
45
|
-
* This returns a promise, resolvable to message meta.
|
|
46
|
-
* Rejected promise may have a string error code from SC.
|
|
47
|
-
*/
|
|
48
|
-
export type GetMsgMeta = (userId: string, msgId: string) => Promise<retrievalApi.MsgMeta>;
|
|
49
|
-
/**
|
|
50
|
-
* This deletes a message returning a promise, resolvable when message is
|
|
51
|
-
* removed.
|
|
52
|
-
* Rejected promise may have a string error code from SC.
|
|
53
|
-
*/
|
|
54
|
-
export type DeleteMsg = (userId: string, msgId: string) => Promise<void>;
|
|
55
|
-
/**
|
|
56
|
-
* This returns parameter of a message that is still in delivery, identified
|
|
57
|
-
* by given recipient and message id. If message is unknown, or if it has
|
|
58
|
-
* already been delivered, error code is thrown.
|
|
59
|
-
* Rejected promise may have a string error code from SC.
|
|
60
|
-
*/
|
|
61
|
-
export type IncompleteMsgDeliveryParams = (recipient: string, msgId: string) => Promise<{
|
|
62
|
-
maxMsgLength: number;
|
|
63
|
-
currentMsgLength: number;
|
|
64
|
-
}>;
|
|
65
|
-
/**
|
|
66
|
-
* This returns a promise, resolvable to readable stream of object bytes.
|
|
67
|
-
* Rejected promise may be passing string error code from SC.
|
|
68
|
-
*/
|
|
69
|
-
export type GetObj = (userId: string, msgId: string, objId: string, header: boolean, segsOffset: number, segsLimit: number | undefined) => Promise<ObjReader>;
|
|
70
|
-
type GetParam<P extends keyof InboxParams> = (userId: string) => Promise<InboxParams[P]>;
|
|
71
|
-
type SetParam<P extends keyof InboxParams> = (userId: string, param: InboxParams[P]) => Promise<boolean>;
|
|
72
|
-
export type GetPubKey = GetParam<'pubkey'>;
|
|
73
|
-
export type SetPubKey = SetParam<'pubkey'>;
|
|
74
|
-
export type GetAnonSenderPolicy = GetParam<'anonymous/policy'>;
|
|
75
|
-
export type SetAnonSenderPolicy = SetParam<'anonymous/policy'>;
|
|
76
|
-
export type GetAnonSenderInvites = GetParam<'anonymous/invites'>;
|
|
77
|
-
export type SetAnonSenderInvites = SetParam<'anonymous/invites'>;
|
|
78
|
-
export type GetAuthSenderPolicy = GetParam<'authenticated/policy'>;
|
|
79
|
-
export type SetAuthSenderPolicy = SetParam<'authenticated/policy'>;
|
|
80
|
-
export type GetAuthSenderInvites = GetParam<'authenticated/invites'>;
|
|
81
|
-
export type SetAuthSenderInvites = SetParam<'authenticated/invites'>;
|
|
82
|
-
export type GetAuthSenderBlacklist = GetParam<'authenticated/blacklist'>;
|
|
83
|
-
export type SetAuthSenderBlacklist = SetParam<'authenticated/blacklist'>;
|
|
84
|
-
export type GetAuthSenderWhitelist = GetParam<'authenticated/whitelist'>;
|
|
85
|
-
export type SetAuthSenderWhitelist = SetParam<'authenticated/whitelist'>;
|
|
8
|
+
export type GetParam<P extends keyof InboxParams> = (userId: string) => Promise<InboxParams[P]>;
|
|
9
|
+
export type SetParam<P extends keyof InboxParams> = (userId: string, param: InboxParams[P]) => Promise<boolean>;
|
|
86
10
|
export type EventsSink = MailEventsSink;
|
|
87
|
-
export interface
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
11
|
+
export interface Recipients {
|
|
12
|
+
config: ASMailServiceConfig;
|
|
13
|
+
delivery: MsgDelivery;
|
|
14
|
+
retrieval: MsgRetrieval;
|
|
15
|
+
}
|
|
16
|
+
export interface ASMailServiceConfig {
|
|
17
|
+
/**
|
|
18
|
+
* This checks existence of a given user, returning a promise, resolvable
|
|
19
|
+
* either to true, when given user id is known, or to false, when it is not.
|
|
20
|
+
*/
|
|
21
|
+
exists: (userId: string) => Promise<boolean>;
|
|
22
|
+
getPubKey: GetParam<'pubkey'>;
|
|
23
|
+
setPubKey: SetParam<'pubkey'>;
|
|
24
|
+
getAnonSenderPolicy: GetParam<'anonymous/policy'>;
|
|
25
|
+
setAnonSenderPolicy: SetParam<'anonymous/policy'>;
|
|
26
|
+
getAnonSenderInvites: GetParam<'anonymous/invites'>;
|
|
27
|
+
setAnonSenderInvites: SetParam<'anonymous/invites'>;
|
|
28
|
+
getAuthSenderPolicy: GetParam<'authenticated/policy'>;
|
|
29
|
+
setAuthSenderPolicy: SetParam<'authenticated/policy'>;
|
|
30
|
+
getAuthSenderInvites: GetParam<'authenticated/invites'>;
|
|
31
|
+
setAuthSenderInvites: SetParam<'authenticated/invites'>;
|
|
32
|
+
getAuthSenderBlacklist: GetParam<'authenticated/blacklist'>;
|
|
33
|
+
setAuthSenderBlacklist: SetParam<'authenticated/blacklist'>;
|
|
34
|
+
getAuthSenderWhitelist: GetParam<'authenticated/whitelist'>;
|
|
35
|
+
setAuthSenderWhitelist: SetParam<'authenticated/whitelist'>;
|
|
36
|
+
}
|
|
37
|
+
export interface MsgDelivery {
|
|
38
|
+
getPubKey: ASMailServiceConfig['getPubKey'];
|
|
39
|
+
/**
|
|
40
|
+
* This tells what is an allowable maximum message size for a given
|
|
41
|
+
* recipient, for a given sender and/or under a given invitation token.
|
|
42
|
+
* Function returns a promise, resolvable to
|
|
43
|
+
* (1) zero (0), if leaving mail is forbidden,
|
|
44
|
+
* (2) greater than zero maximum message length, and
|
|
45
|
+
* (3) -1 (less than zero), if mail cannot be accepted due to full mail
|
|
46
|
+
* box.
|
|
47
|
+
*/
|
|
48
|
+
allowedMaxMsgSize: (recipient: string, sender: string | undefined, invitation: string | undefined) => Promise<number>;
|
|
49
|
+
/**
|
|
50
|
+
* This allocates storage for a message returning a promise, resolvable to
|
|
51
|
+
* (1) message id, when a folder for new message has been created,
|
|
52
|
+
* (2) undefined, if recipient is unknown.
|
|
53
|
+
*/
|
|
54
|
+
setMsgStorage: (recipient: string, msgMeta: deliveryApi.msgMeta.Request, authSender: string | undefined, invite: string | undefined, maxMsgLength: number) => Promise<string>;
|
|
55
|
+
/**
|
|
56
|
+
* This saves object's bytes, returning a promise, resolvable when saving
|
|
57
|
+
* is OK, otherwise, promise rejects with string error code from SC.
|
|
58
|
+
*/
|
|
59
|
+
saveObj: (recipient: string, msgId: string, objId: string, fstReq: deliveryApi.PutObjFirstQueryOpts | undefined, sndReq: deliveryApi.PutObjSecondQueryOpts | undefined, bytesLen: number, bytes: Readable) => Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* This returns parameter of a message that is still in delivery, identified
|
|
62
|
+
* by given recipient and message id. If message is unknown, or if it has
|
|
63
|
+
* already been delivered, error code is thrown.
|
|
64
|
+
* Rejected promise may have a string error code from SC.
|
|
65
|
+
*/
|
|
66
|
+
incompleteMsgDeliveryParams: (recipient: string, msgId: string) => Promise<{
|
|
67
|
+
maxMsgLength: number;
|
|
68
|
+
currentMsgLength: number;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* This finalizes delivery of a message, returning a promise.
|
|
72
|
+
* Rejected promise may have a string error code from SC.
|
|
73
|
+
*/
|
|
74
|
+
finalizeDelivery: (recipient: string, msgId: string) => Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
export interface MsgRetrieval {
|
|
77
|
+
exists: ASMailServiceConfig['exists'];
|
|
78
|
+
/**
|
|
79
|
+
* This returns a promise, resolvable to array with ids of available
|
|
80
|
+
* messages. Rejected promise may have a string error code from SC.
|
|
81
|
+
*/
|
|
82
|
+
getMsgIds: (userId: string) => Promise<retrievalApi.listMsgs.Reply>;
|
|
83
|
+
/**
|
|
84
|
+
* This returns a promise, resolvable to message meta.
|
|
85
|
+
* Rejected promise may have a string error code from SC.
|
|
86
|
+
*/
|
|
87
|
+
getMsgMeta: (userId: string, msgId: string) => Promise<retrievalApi.MsgMeta>;
|
|
88
|
+
/**
|
|
89
|
+
* This deletes a message returning a promise, resolvable when message is
|
|
90
|
+
* removed.
|
|
91
|
+
* Rejected promise may have a string error code from SC.
|
|
92
|
+
*/
|
|
93
|
+
deleteMsg: (userId: string, msgId: string) => Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* This returns a promise, resolvable to readable stream of object bytes.
|
|
96
|
+
* Rejected promise may be passing string error code from SC.
|
|
97
|
+
*/
|
|
98
|
+
getObj: (userId: string, msgId: string, objId: string, header: boolean, segsOffset: number, segsLimit: number | undefined) => Promise<ObjReader>;
|
|
98
99
|
setMailEventsSink(sink: EventsSink): void;
|
|
99
|
-
getPubKey: GetPubKey;
|
|
100
|
-
setPubKey: SetPubKey;
|
|
101
|
-
getAnonSenderPolicy: GetAnonSenderPolicy;
|
|
102
|
-
setAnonSenderPolicy: SetAnonSenderPolicy;
|
|
103
|
-
getAnonSenderInvites: GetAnonSenderInvites;
|
|
104
|
-
setAnonSenderInvites: SetAnonSenderInvites;
|
|
105
|
-
getAuthSenderPolicy: GetAuthSenderPolicy;
|
|
106
|
-
setAuthSenderPolicy: SetAuthSenderPolicy;
|
|
107
|
-
getAuthSenderInvites: GetAuthSenderInvites;
|
|
108
|
-
setAuthSenderInvites: SetAuthSenderInvites;
|
|
109
|
-
getAuthSenderBlacklist: GetAuthSenderBlacklist;
|
|
110
|
-
setAuthSenderBlacklist: SetAuthSenderBlacklist;
|
|
111
|
-
getAuthSenderWhitelist: GetAuthSenderWhitelist;
|
|
112
|
-
setAuthSenderWhitelist: SetAuthSenderWhitelist;
|
|
113
100
|
}
|
|
114
|
-
export declare function
|
|
101
|
+
export declare function makeRecipients(rootFolder: string, writeBufferSize?: string | number, readBufferSize?: string | number): Recipients;
|
|
@@ -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.makeRecipients = exports.BIN_TYPE = exports.SC = void 0;
|
|
20
20
|
const inbox_1 = require("./inbox");
|
|
21
21
|
const server_data_folders_1 = require("../../lib-server/resources/server-data-folders");
|
|
22
22
|
var inbox_2 = require("./inbox");
|
|
@@ -86,22 +86,26 @@ async function adaptToFreeSpaceLeft(inbox, msgSize) {
|
|
|
86
86
|
*/
|
|
87
87
|
async function allowedMsgSizeForAnonSender(inbox, invitation) {
|
|
88
88
|
const policy = await inbox.getParam('anonymous/policy');
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!invitation) {
|
|
89
|
+
if (policy.accept) {
|
|
90
|
+
// XXX this misses case when invite allows for bigger messages,
|
|
91
|
+
// while without invite messages are also allowed.
|
|
93
92
|
if (policy.acceptWithInvitesOnly) {
|
|
94
|
-
|
|
93
|
+
if (invitation) {
|
|
94
|
+
const invites = await inbox.getParam('anonymous/invites');
|
|
95
|
+
const sizeForInvite = invites[invitation];
|
|
96
|
+
return ((typeof sizeForInvite === 'number') ?
|
|
97
|
+
adaptToFreeSpaceLeft(inbox, sizeForInvite) : 0);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return await adaptToFreeSpaceLeft(inbox, policy.defaultMsgSize);
|
|
95
105
|
}
|
|
96
|
-
return await adaptToFreeSpaceLeft(inbox, policy.defaultMsgSize);
|
|
97
106
|
}
|
|
98
107
|
else {
|
|
99
|
-
|
|
100
|
-
const sizeForInvite = invites[invitation];
|
|
101
|
-
if (typeof sizeForInvite !== 'number') {
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
return adaptToFreeSpaceLeft(inbox, sizeForInvite);
|
|
108
|
+
return 0;
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
/**
|
|
@@ -144,7 +148,7 @@ async function allowedMsgSizeForAuthSender(inbox, sender, invitation) {
|
|
|
144
148
|
}
|
|
145
149
|
return adaptToFreeSpaceLeft(inbox, policy.defaultMsgSize);
|
|
146
150
|
}
|
|
147
|
-
function
|
|
151
|
+
function makeRecipients(rootFolder, writeBufferSize, readBufferSize) {
|
|
148
152
|
const boxes = new Map();
|
|
149
153
|
let mailEventsSink = undefined;
|
|
150
154
|
async function getInbox(userId) {
|
|
@@ -169,7 +173,7 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
|
|
|
169
173
|
return inbox;
|
|
170
174
|
}
|
|
171
175
|
}
|
|
172
|
-
const
|
|
176
|
+
const config = {
|
|
173
177
|
exists: async (userId) => {
|
|
174
178
|
try {
|
|
175
179
|
await getInbox(userId);
|
|
@@ -237,7 +241,11 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
|
|
|
237
241
|
setAuthSenderWhitelist: async (userId, list) => {
|
|
238
242
|
const inbox = await getInbox(userId);
|
|
239
243
|
return inbox.setAuthSenderWhitelist(list);
|
|
240
|
-
}
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
Object.freeze(config);
|
|
247
|
+
const delivery = {
|
|
248
|
+
getPubKey: config.getPubKey,
|
|
241
249
|
allowedMaxMsgSize: async (recipient, sender, invitation) => {
|
|
242
250
|
const inbox = await getInbox(recipient);
|
|
243
251
|
// XXX move these two functions into inbox
|
|
@@ -268,6 +276,14 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
|
|
|
268
276
|
const inbox = await getInbox(recipient);
|
|
269
277
|
return inbox.completeMsgDelivery(msgId);
|
|
270
278
|
},
|
|
279
|
+
incompleteMsgDeliveryParams: async (recipient, msgId) => {
|
|
280
|
+
const inbox = await getInbox(recipient);
|
|
281
|
+
return inbox.getIncompleteMsgParams(msgId);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
Object.freeze(delivery);
|
|
285
|
+
const retrieval = {
|
|
286
|
+
exists: config.exists,
|
|
271
287
|
getMsgIds: async (userId) => {
|
|
272
288
|
const inbox = await getInbox(userId);
|
|
273
289
|
return inbox.getMsgIds();
|
|
@@ -280,10 +296,6 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
|
|
|
280
296
|
const inbox = await getInbox(userId);
|
|
281
297
|
return inbox.rmMsg(msgId);
|
|
282
298
|
},
|
|
283
|
-
incompleteMsgDeliveryParams: async (recipient, msgId) => {
|
|
284
|
-
const inbox = await getInbox(recipient);
|
|
285
|
-
return inbox.getIncompleteMsgParams(msgId);
|
|
286
|
-
},
|
|
287
299
|
getObj: async (userId, msgId, objId, header, segsOffset, segsLimit) => {
|
|
288
300
|
const inbox = await getInbox(userId);
|
|
289
301
|
return inbox.getObj(msgId, objId, header, segsOffset, segsLimit);
|
|
@@ -295,8 +307,12 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
|
|
|
295
307
|
mailEventsSink = sink;
|
|
296
308
|
}
|
|
297
309
|
};
|
|
310
|
+
Object.freeze(retrieval);
|
|
311
|
+
const recipients = {
|
|
312
|
+
config, delivery, retrieval
|
|
313
|
+
};
|
|
298
314
|
Object.freeze(recipients);
|
|
299
315
|
return recipients;
|
|
300
316
|
}
|
|
301
|
-
exports.
|
|
317
|
+
exports.makeRecipients = makeRecipients;
|
|
302
318
|
Object.freeze(exports);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppWithWSs } from '../lib-server/web-sockets/app';
|
|
2
2
|
import { SessionsFactory } from './resources/sessions';
|
|
3
|
-
import {
|
|
3
|
+
import { MsgRetrieval } from './resources/recipients';
|
|
4
4
|
import { MidAuthorizer } from '../lib-server/routes/sessions/mid-auth';
|
|
5
|
-
export declare function makeApp(domain: string, sessions: SessionsFactory, recipients:
|
|
5
|
+
export declare function makeApp(domain: string, sessions: SessionsFactory, recipients: MsgRetrieval, midAuthorizer: MidAuthorizer): AppWithWSs;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
|
|
2
|
+
import { GetParam } from '../../resources/recipients';
|
|
3
|
+
import { InboxParams } from '../../resources/inbox';
|
|
4
|
+
export declare function getParam<P extends keyof InboxParams>(paramGetter: GetParam<P>): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -20,9 +20,6 @@ exports.getParam = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const config_1 = require("../../../lib-common/service-api/asmail/config");
|
|
22
22
|
function getParam(paramGetter) {
|
|
23
|
-
if ('function' !== typeof paramGetter) {
|
|
24
|
-
throw new TypeError("Given argument 'paramGetter' must be function, but is not.");
|
|
25
|
-
}
|
|
26
23
|
return async (req, res, next) => {
|
|
27
24
|
const session = req.session;
|
|
28
25
|
const userId = session.params.userId;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
|
|
2
|
+
import { SetParam } from '../../resources/recipients';
|
|
3
|
+
import { InboxParams } from '../../resources/inbox';
|
|
4
|
+
export declare function setParam<P extends keyof InboxParams>(paramSetter: SetParam<P>): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -20,9 +20,6 @@ exports.setParam = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const config_1 = require("../../../lib-common/service-api/asmail/config");
|
|
22
22
|
function setParam(paramSetter) {
|
|
23
|
-
if ('function' !== typeof paramSetter) {
|
|
24
|
-
throw new TypeError("Given argument 'paramSetter' must be function, but is not.");
|
|
25
|
-
}
|
|
26
23
|
return async (req, res, next) => {
|
|
27
24
|
const session = req.session;
|
|
28
25
|
const userId = session.params.userId;
|
|
@@ -48,4 +45,3 @@ function setParam(paramSetter) {
|
|
|
48
45
|
};
|
|
49
46
|
}
|
|
50
47
|
exports.setParam = setParam;
|
|
51
|
-
;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
3
|
-
export declare function finalizeDelivery(finDelivFunc:
|
|
2
|
+
import { MsgDelivery } from '../../resources/recipients';
|
|
3
|
+
export declare function finalizeDelivery(finDelivFunc: MsgDelivery['finalizeDelivery']): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -20,9 +20,6 @@ exports.finalizeDelivery = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
22
22
|
function finalizeDelivery(finDelivFunc) {
|
|
23
|
-
if ('function' !== typeof finDelivFunc) {
|
|
24
|
-
throw new TypeError("Given argument 'finDelivFunc' must be function, but is not.");
|
|
25
|
-
}
|
|
26
23
|
return async (req, res, next) => {
|
|
27
24
|
const session = req.session;
|
|
28
25
|
const recipient = session.params.recipient;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import { MsgDelivery } from '../../resources/recipients';
|
|
3
3
|
import { Redirect } from './start-session';
|
|
4
4
|
/**
|
|
5
5
|
* This creates a pre-flight route handler.
|
|
@@ -13,4 +13,4 @@ import { Redirect } from './start-session';
|
|
|
13
13
|
* (1) string with URI for ASMail service, which is serving given recipient,
|
|
14
14
|
* (2) undefined, if it is this server should service given recipient.
|
|
15
15
|
*/
|
|
16
|
-
export declare function preFlight(allowedMsgSizeFunc:
|
|
16
|
+
export declare function preFlight(allowedMsgSizeFunc: MsgDelivery['allowedMaxMsgSize'], redirectFunc?: Redirect): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2017 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2017, 2025 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
|
|
@@ -33,12 +33,6 @@ const canonical_address_1 = require("../../../lib-common/canonical-address");
|
|
|
33
33
|
* (2) undefined, if it is this server should service given recipient.
|
|
34
34
|
*/
|
|
35
35
|
function preFlight(allowedMsgSizeFunc, redirectFunc) {
|
|
36
|
-
if (typeof allowedMsgSizeFunc !== 'function') {
|
|
37
|
-
throw new TypeError(`Given argument 'allowedMsgSizeFunc' must be function, but is not.`);
|
|
38
|
-
}
|
|
39
|
-
if ((redirectFunc !== undefined) && (typeof redirectFunc !== 'function')) {
|
|
40
|
-
throw new TypeError(`Given argument 'redirectFunc' must either be function, or be undefined, but it is neither.`);
|
|
41
|
-
}
|
|
42
36
|
async function serveRequestHere(recipient, sender, invitation, res) {
|
|
43
37
|
const msgSize = await allowedMsgSizeFunc(recipient, sender, invitation);
|
|
44
38
|
if (msgSize > 0) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import { MsgDelivery } from '../../resources/recipients';
|
|
3
3
|
/**
|
|
4
4
|
* This creates a get-init-pub-key route handler.
|
|
5
5
|
* @param pkeyProvidingFunc is a function that provides recipient's public key
|
|
6
6
|
* for use in this communication.
|
|
7
7
|
*/
|
|
8
|
-
export declare function getRecipientPubKey(pkeyProvidingFunc:
|
|
8
|
+
export declare function getRecipientPubKey(pkeyProvidingFunc: MsgDelivery['getPubKey']): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -25,9 +25,6 @@ const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
|
25
25
|
* for use in this communication.
|
|
26
26
|
*/
|
|
27
27
|
function getRecipientPubKey(pkeyProvidingFunc) {
|
|
28
|
-
if ('function' !== typeof pkeyProvidingFunc) {
|
|
29
|
-
throw new TypeError("Given argument 'pkeyProvidingFunc' must be function, but is not.");
|
|
30
|
-
}
|
|
31
28
|
return async (req, res, next) => {
|
|
32
29
|
const session = req.session;
|
|
33
30
|
try {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
3
|
-
export declare function saveMetadata(setMsgStorageFunc:
|
|
2
|
+
import { MsgDelivery } from '../../resources/recipients';
|
|
3
|
+
export declare function saveMetadata(setMsgStorageFunc: MsgDelivery['setMsgStorage'], maxChunk: string | number): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -44,10 +44,6 @@ function findProblemWithObjIds(ids) {
|
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
function saveMetadata(setMsgStorageFunc, maxChunk) {
|
|
47
|
-
if ('function' !== typeof setMsgStorageFunc) {
|
|
48
|
-
throw new TypeError("Given argument 'setMsgStorageFunc' must " +
|
|
49
|
-
"be function, but is not.");
|
|
50
|
-
}
|
|
51
47
|
const maxChunkSize = confUtil.stringToNumOfBytes(maxChunk);
|
|
52
48
|
return async (req, res, next) => {
|
|
53
49
|
const session = req.session;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
3
|
-
export declare function saveMsgObj(saveObjFunc:
|
|
2
|
+
import { MsgDelivery } from '../../resources/recipients';
|
|
3
|
+
export declare function saveMsgObj(saveObjFunc: MsgDelivery['saveObj'], chunkLimit: string | number): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2017, 2019 - 2020 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2017, 2019 - 2020, 2025 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
|
|
@@ -22,9 +22,6 @@ const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
|
22
22
|
const confUtil = require("../../../lib-server/conf-util");
|
|
23
23
|
const body_parsers_1 = require("../../../lib-server/middleware/body-parsers");
|
|
24
24
|
function saveMsgObj(saveObjFunc, chunkLimit) {
|
|
25
|
-
if ('function' !== typeof saveObjFunc) {
|
|
26
|
-
throw new TypeError("Given argument 'saveObjFunc' must be function, but is not.");
|
|
27
|
-
}
|
|
28
25
|
const maxChunkSize = confUtil.stringToNumOfBytes(chunkLimit);
|
|
29
26
|
return async (req, res, next) => {
|
|
30
27
|
if (!req.is(recipients_1.BIN_TYPE)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import { MsgDelivery } from '../../resources/recipients';
|
|
3
3
|
import { GenerateSession, GetSessionForMsg } from '../../resources/delivery-sessions';
|
|
4
4
|
import { Redirect } from './start-session';
|
|
5
5
|
/**
|
|
@@ -15,4 +15,4 @@ import { Redirect } from './start-session';
|
|
|
15
15
|
* (1) string with URI for ASMail service, which is serving given recipient,
|
|
16
16
|
* (2) undefined, if it is this server should service given recipient.
|
|
17
17
|
*/
|
|
18
|
-
export declare function restartSession(sessionGenFunc: GenerateSession, sessionForMsgFunc: GetSessionForMsg, incompleteMsgFunc:
|
|
18
|
+
export declare function restartSession(sessionGenFunc: GenerateSession, sessionForMsgFunc: GetSessionForMsg, incompleteMsgFunc: MsgDelivery['incompleteMsgDeliveryParams'], maxChunk: string | number, redirectFunc?: Redirect): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2017 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2017, 2025 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
|
|
@@ -35,18 +35,6 @@ const confUtil = require("../../../lib-server/conf-util");
|
|
|
35
35
|
* (2) undefined, if it is this server should service given recipient.
|
|
36
36
|
*/
|
|
37
37
|
function restartSession(sessionGenFunc, sessionForMsgFunc, incompleteMsgFunc, maxChunk, redirectFunc) {
|
|
38
|
-
if (typeof sessionGenFunc !== 'function') {
|
|
39
|
-
throw new TypeError(`Given argument 'sessionGenFunc' must be function, but is not.`);
|
|
40
|
-
}
|
|
41
|
-
if (typeof sessionForMsgFunc !== 'function') {
|
|
42
|
-
throw new TypeError(`Given argument 'sessionForMsgFunc' must be function, but is not.`);
|
|
43
|
-
}
|
|
44
|
-
if (typeof incompleteMsgFunc !== 'function') {
|
|
45
|
-
throw new TypeError(`Given argument 'incompleteMsgFunc' must be function, but is not.`);
|
|
46
|
-
}
|
|
47
|
-
if ((redirectFunc !== undefined) && (typeof redirectFunc !== 'function')) {
|
|
48
|
-
throw new TypeError(`Given argument 'redirectFunc' must either be function, or be undefined, but it is neither.`);
|
|
49
|
-
}
|
|
50
38
|
const maxChunkSize = confUtil.stringToNumOfBytes(maxChunk);
|
|
51
39
|
async function serveRequestHere(recipient, msgId, res) {
|
|
52
40
|
let session = await sessionForMsgFunc(recipient, msgId);
|
|
@@ -26,9 +26,6 @@ const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
|
26
26
|
* and false for failed authorization.
|
|
27
27
|
*/
|
|
28
28
|
function authorize(relyingPartyDomain, midAuthorizingFunc) {
|
|
29
|
-
if ('function' !== typeof midAuthorizingFunc) {
|
|
30
|
-
throw new TypeError("Given argument 'midAuthorizingFunc' must be function, but is not.");
|
|
31
|
-
}
|
|
32
29
|
return async (req, res, next) => {
|
|
33
30
|
if (req.session.isAuthorized) {
|
|
34
31
|
res.status(delivery_1.ERR_SC.duplicateReq).send("This protocol request has already been served.");
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
2
|
import { GenerateSession } from '../../resources/delivery-sessions';
|
|
3
|
-
import {
|
|
3
|
+
import { MsgDelivery } from '../../resources/recipients';
|
|
4
4
|
export type Redirect = (userId: string) => Promise<string>;
|
|
5
5
|
/**
|
|
6
6
|
* This creates a start-session route handler.
|
|
7
|
-
* @param allowedMsgSizeFunc is a function returning promises, that
|
|
7
|
+
* @param allowedMsgSizeFunc is a function returning promises, that
|
|
8
|
+
* may resolve to
|
|
8
9
|
* (1) undefined, if recipient is unknown,
|
|
9
10
|
* (2) zero (0), if leaving mail is forbidden,
|
|
10
11
|
* (3) greater than zero maximum message length, and
|
|
@@ -16,4 +17,4 @@ export type Redirect = (userId: string) => Promise<string>;
|
|
|
16
17
|
* (1) string with URI for ASMail service, which is serving given recipient,
|
|
17
18
|
* (2) undefined, if it is this server should service given recipient.
|
|
18
19
|
*/
|
|
19
|
-
export declare function startSession(allowedMsgSizeFunc:
|
|
20
|
+
export declare function startSession(allowedMsgSizeFunc: MsgDelivery['allowedMaxMsgSize'], sessionGenFunc: GenerateSession, redirectFunc?: Redirect): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -22,7 +22,8 @@ const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
|
22
22
|
const canonical_address_1 = require("../../../lib-common/canonical-address");
|
|
23
23
|
/**
|
|
24
24
|
* This creates a start-session route handler.
|
|
25
|
-
* @param allowedMsgSizeFunc is a function returning promises, that
|
|
25
|
+
* @param allowedMsgSizeFunc is a function returning promises, that
|
|
26
|
+
* may resolve to
|
|
26
27
|
* (1) undefined, if recipient is unknown,
|
|
27
28
|
* (2) zero (0), if leaving mail is forbidden,
|
|
28
29
|
* (3) greater than zero maximum message length, and
|
|
@@ -35,15 +36,6 @@ const canonical_address_1 = require("../../../lib-common/canonical-address");
|
|
|
35
36
|
* (2) undefined, if it is this server should service given recipient.
|
|
36
37
|
*/
|
|
37
38
|
function startSession(allowedMsgSizeFunc, sessionGenFunc, redirectFunc) {
|
|
38
|
-
if (typeof allowedMsgSizeFunc !== 'function') {
|
|
39
|
-
throw new TypeError(`Given argument 'allowedMsgSizeFunc' must be function, but is not.`);
|
|
40
|
-
}
|
|
41
|
-
if (typeof sessionGenFunc !== 'function') {
|
|
42
|
-
throw new TypeError(`Given argument 'sessionGenFunc' must be function, but is not.`);
|
|
43
|
-
}
|
|
44
|
-
if ((redirectFunc !== undefined) && (typeof redirectFunc !== 'function')) {
|
|
45
|
-
throw new TypeError(`Given argument 'redirectFunc' must either be function, or be undefined, but it is neither.`);
|
|
46
|
-
}
|
|
47
39
|
async function serveRequestHere(recipient, sender, invitation, res) {
|
|
48
40
|
const msgSize = await allowedMsgSizeFunc(recipient, sender, invitation);
|
|
49
41
|
if (msgSize > 0) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
3
|
-
export declare function getMsgMeta(getMsgMetaFunc:
|
|
2
|
+
import { MsgRetrieval } from '../../resources/recipients';
|
|
3
|
+
export declare function getMsgMeta(getMsgMetaFunc: MsgRetrieval['getMsgMeta']): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -20,9 +20,6 @@ exports.getMsgMeta = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const retrieval_1 = require("../../../lib-common/service-api/asmail/retrieval");
|
|
22
22
|
function getMsgMeta(getMsgMetaFunc) {
|
|
23
|
-
if ('function' !== typeof getMsgMetaFunc) {
|
|
24
|
-
throw new TypeError("Given argument 'getMsgMetaFunc' must be function, but is not.");
|
|
25
|
-
}
|
|
26
23
|
return async (req, res, next) => {
|
|
27
24
|
const userId = req.session.params.userId;
|
|
28
25
|
const msgId = req.params.msgId;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
3
|
-
export declare function getMsgObj(getMsgObjFunc:
|
|
2
|
+
import { MsgRetrieval } from '../../resources/recipients';
|
|
3
|
+
export declare function getMsgObj(getMsgObjFunc: MsgRetrieval['getObj']): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2017 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2017, 2025 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,25 +26,18 @@ function extractQueryOptions(req) {
|
|
|
26
26
|
const query = req.query;
|
|
27
27
|
const header = (query.header === 'true');
|
|
28
28
|
const ofs = (query.ofs ? parseInt(query.ofs) : 0);
|
|
29
|
-
if (isNaN(ofs) ||
|
|
30
|
-
(ofs < 0) ||
|
|
31
|
-
(header && (ofs > 0))) {
|
|
29
|
+
if (isNaN(ofs) || (ofs < 0) || (header && (ofs > 0))) {
|
|
32
30
|
return;
|
|
33
31
|
}
|
|
34
32
|
const limit = (query.limit ? parseInt(query.limit) : undefined);
|
|
35
33
|
if (limit !== undefined) {
|
|
36
|
-
if (isNaN(limit) ||
|
|
37
|
-
(limit < 0) ||
|
|
38
|
-
(!header && (limit === 0))) {
|
|
34
|
+
if (isNaN(limit) || (limit < 0) || (!header && (limit === 0))) {
|
|
39
35
|
return;
|
|
40
36
|
}
|
|
41
37
|
}
|
|
42
38
|
return { header, limit, ofs };
|
|
43
39
|
}
|
|
44
40
|
function getMsgObj(getMsgObjFunc) {
|
|
45
|
-
if ('function' !== typeof getMsgObjFunc) {
|
|
46
|
-
throw new TypeError("Given argument 'getMsgObjFunc' must be function, but is not.");
|
|
47
|
-
}
|
|
48
41
|
return async (req, res, next) => {
|
|
49
42
|
const userId = req.session.params.userId;
|
|
50
43
|
const msgId = req.params.msgId;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
3
|
-
export declare function listMsgIds(listMsgIdsFunc:
|
|
2
|
+
import { MsgRetrieval } from '../../resources/recipients';
|
|
3
|
+
export declare function listMsgIds(listMsgIdsFunc: MsgRetrieval['getMsgIds']): RequestHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 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
|
|
@@ -20,9 +20,6 @@ exports.listMsgIds = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const retrieval_1 = require("../../../lib-common/service-api/asmail/retrieval");
|
|
22
22
|
function listMsgIds(listMsgIdsFunc) {
|
|
23
|
-
if ('function' !== typeof listMsgIdsFunc) {
|
|
24
|
-
throw new TypeError("Given argument 'listMsgIdsFunc' must be function, but is not.");
|
|
25
|
-
}
|
|
26
23
|
return async (req, res, next) => {
|
|
27
24
|
const userId = req.session.params.userId;
|
|
28
25
|
try {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import {
|
|
3
|
-
export declare function deleteMsg(delMsgFunc:
|
|
2
|
+
import { MsgRetrieval } from '../../resources/recipients';
|
|
3
|
+
export declare function deleteMsg(delMsgFunc: MsgRetrieval['deleteMsg']): RequestHandler;
|
|
@@ -20,9 +20,6 @@ exports.deleteMsg = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const retrieval_1 = require("../../../lib-common/service-api/asmail/retrieval");
|
|
22
22
|
function deleteMsg(delMsgFunc) {
|
|
23
|
-
if ('function' !== typeof delMsgFunc) {
|
|
24
|
-
throw new TypeError("Given argument 'delMsgFunc' must be function, but is not.");
|
|
25
|
-
}
|
|
26
23
|
return async (req, res, next) => {
|
|
27
24
|
const userId = req.session.params.userId;
|
|
28
25
|
const msgId = req.params.msgId;
|
package/package.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spec-3nweb-server",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.11",
|
|
4
4
|
"description": "3NWeb spec server.",
|
|
5
5
|
"main": "build/lib.js",
|
|
6
6
|
"types": "build/lib.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"3nweb": "node build/main.js"
|
|
9
|
+
},
|
|
7
10
|
"scripts": {
|
|
8
11
|
"build": "tsc -p ts-code",
|
|
12
|
+
"server": "node build/main.js",
|
|
9
13
|
"test": "node build/tests/jasmine.js",
|
|
10
14
|
"clear-for-packing": "npm prune --production && bash -c \"rm -rf build/mock build/tests 'node_modules/ecma-nacl/c sources'\"",
|
|
11
15
|
"clear-for-packing-mock": "npm prune --production && bash -c \"rm -rf build/tests 'node_modules/ecma-nacl/c sources'\"",
|
|
12
|
-
"pack": "
|
|
16
|
+
"pack": "echo unimplemented",
|
|
13
17
|
"pack-deb": "npm run pack && bash packing/create-deb.sh",
|
|
14
18
|
"postinstall": "node -e \"try{require('./postinstall')}catch(e){}\""
|
|
15
19
|
},
|
|
@@ -47,16 +51,9 @@
|
|
|
47
51
|
"@types/node": "^16.11.7",
|
|
48
52
|
"@types/ws": "^4.0.0",
|
|
49
53
|
"jasmine": "^3.9.0",
|
|
50
|
-
"pkg": "^5.8.1",
|
|
51
54
|
"rxjs": "^5.3.0",
|
|
52
55
|
"typescript": "^4.7.4",
|
|
53
56
|
"xhr2": "^0.1.3"
|
|
54
57
|
},
|
|
55
|
-
"pkg": {
|
|
56
|
-
"targets": [
|
|
57
|
-
"node18-linux-x64"
|
|
58
|
-
],
|
|
59
|
-
"outputPath": "dist"
|
|
60
|
-
},
|
|
61
58
|
"readmeFilename": "README.md"
|
|
62
59
|
}
|