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.
Files changed (44) hide show
  1. package/README.md +16 -2
  2. package/build/asmail/asmail-app.js +5 -5
  3. package/build/asmail/config.d.ts +2 -2
  4. package/build/asmail/delivery.d.ts +2 -2
  5. package/build/asmail/delivery.js +1 -1
  6. package/build/asmail/resources/inbox.d.ts +5 -4
  7. package/build/asmail/resources/inbox.js +75 -65
  8. package/build/asmail/resources/recipients.d.ts +91 -104
  9. package/build/asmail/resources/recipients.js +37 -21
  10. package/build/asmail/retrieval.d.ts +2 -2
  11. package/build/asmail/retrieval.js +1 -1
  12. package/build/asmail/routes/config/param-getter.d.ts +3 -1
  13. package/build/asmail/routes/config/param-getter.js +1 -4
  14. package/build/asmail/routes/config/param-setter.d.ts +3 -1
  15. package/build/asmail/routes/config/param-setter.js +1 -5
  16. package/build/asmail/routes/delivery/finalize-delivery.d.ts +2 -2
  17. package/build/asmail/routes/delivery/finalize-delivery.js +1 -4
  18. package/build/asmail/routes/delivery/pre-flight.d.ts +2 -2
  19. package/build/asmail/routes/delivery/pre-flight.js +1 -7
  20. package/build/asmail/routes/delivery/provide-recipient-pubkey.d.ts +2 -2
  21. package/build/asmail/routes/delivery/provide-recipient-pubkey.js +1 -4
  22. package/build/asmail/routes/delivery/put-metadata.d.ts +2 -2
  23. package/build/asmail/routes/delivery/put-metadata.js +1 -5
  24. package/build/asmail/routes/delivery/put-obj.d.ts +2 -2
  25. package/build/asmail/routes/delivery/put-obj.js +1 -4
  26. package/build/asmail/routes/delivery/restart-session.d.ts +2 -2
  27. package/build/asmail/routes/delivery/restart-session.js +1 -13
  28. package/build/asmail/routes/delivery/sender-authorization.js +0 -3
  29. package/build/asmail/routes/delivery/start-session.d.ts +4 -3
  30. package/build/asmail/routes/delivery/start-session.js +3 -11
  31. package/build/asmail/routes/retrieval/get-message-meta.d.ts +2 -2
  32. package/build/asmail/routes/retrieval/get-message-meta.js +1 -4
  33. package/build/asmail/routes/retrieval/get-message-obj.d.ts +2 -2
  34. package/build/asmail/routes/retrieval/get-message-obj.js +3 -10
  35. package/build/asmail/routes/retrieval/list-messages.d.ts +2 -2
  36. package/build/asmail/routes/retrieval/list-messages.js +1 -4
  37. package/build/asmail/routes/retrieval/remove-message.d.ts +2 -2
  38. package/build/asmail/routes/retrieval/remove-message.js +0 -3
  39. package/build/lib-common/async-fs-node.d.ts +1 -0
  40. package/build/lib-common/buffer-utils.d.ts +1 -0
  41. package/build/lib-common/objs-on-disk/file-layout.d.ts +1 -0
  42. package/build/lib-common/objs-on-disk/v1-obj-file-format.d.ts +1 -0
  43. package/build/signup/signup-tokens.d.ts +1 -0
  44. 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
- ## Usage
10
+ ## Build & Test
11
11
 
12
- To use this repo, you need [Node.js](https://nodejs.org/) with [Typescript](http://www.typescriptlang.org/), installed globally to Node.js (with flag `-g`).
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.makeFactory)(rootFolder);
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
  }
@@ -1,5 +1,5 @@
1
1
  import * as express from 'express';
2
2
  import { SessionsFactory } from './resources/sessions';
3
- import { Factory as UsersFactory } from './resources/recipients';
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: UsersFactory, midAuthorizer: MidAuthorizer): express.Express;
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 { Factory as RecipFactory } from './resources/recipients';
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: RecipFactory, midAuthorizer: IMidAuthorizer): express.Express;
5
+ export declare function makeApp(domain: string, sessions: SessionsFactory, recipients: MsgDelivery, midAuthorizer: IMidAuthorizer): express.Express;
@@ -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
@@ -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": deliveryApi.initPubKey.Reply | null;
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: deliveryApi.initPubKey.Reply | null): Promise<boolean>;
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(list: Blacklist): Promise<boolean>;
118
- setAuthSenderWhitelist(list: Whitelist): Promise<boolean>;
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
- let isOK;
338
- if (initKeyCerts === null) {
339
- isOK = true;
337
+ if ((initKeyCerts === null) || isValidIntroPKeyCerts(initKeyCerts)) {
338
+ await this.setParam('pubkey', initKeyCerts);
339
+ return true;
340
340
  }
341
341
  else {
342
- isOK = ((typeof initKeyCerts === 'object') &&
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
- const isOK = (('object' === typeof policy) && !!policy &&
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
- const isOK = ('object' === typeof invites) && !!invites;
365
- if (!isOK) {
366
- return false;
355
+ if (isValidListWithMsgMaxSizes(invites)) {
356
+ await this.setParam('anonymous/invites', invites);
357
+ return true;
367
358
  }
368
- for (var invite in invites) {
369
- const msgMaxSize = invites[invite];
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
- const isOK = (('object' === typeof policy) && !!policy &&
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
- return isOK;
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 setAuthSenderWhitelist(list) {
398
- const isOK = ('object' === typeof list) && !!list;
399
- if (!isOK) {
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
- for (var addr in list) {
403
- const msgMaxSize = list[addr];
404
- const isOK = ('number' === typeof msgMaxSize) && (msgMaxSize > 500);
405
- if (!isOK) {
406
- return false;
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
- const isOK = ('object' === typeof invites) && !!invites;
414
- if (!isOK) {
415
- return false;
391
+ if (isValidListWithMsgMaxSizes(invites)) {
392
+ await this.setParam('authenticated/invites', invites);
393
+ return true;
416
394
  }
417
- for (var invite in invites) {
418
- const msgMaxSize = invites[invite];
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
- * This checks existence of a given user, returning a promise, resolvable
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 Factory {
88
- exists: UserExists;
89
- allowedMaxMsgSize: AllowedMaxMsgSize;
90
- setMsgStorage: SetMsgStorage;
91
- saveObj: SaveObj;
92
- finalizeDelivery: FinalizeDelivery;
93
- getMsgIds: GetMsgIds;
94
- getMsgMeta: GetMsgMeta;
95
- deleteMsg: DeleteMsg;
96
- getObj: GetObj;
97
- incompleteMsgDeliveryParams: IncompleteMsgDeliveryParams;
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 makeFactory(rootFolder: string, writeBufferSize?: string | number, readBufferSize?: string | number): Factory;
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.makeFactory = exports.BIN_TYPE = exports.SC = void 0;
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 (!policy.accept) {
90
- return 0;
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
- return 0;
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
- const invites = await inbox.getParam('anonymous/invites');
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 makeFactory(rootFolder, writeBufferSize, readBufferSize) {
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 recipients = {
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.makeFactory = makeFactory;
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 { Factory as RecipFactory } from './resources/recipients';
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: RecipFactory, midAuthorizer: MidAuthorizer): AppWithWSs;
5
+ export declare function makeApp(domain: string, sessions: SessionsFactory, recipients: MsgRetrieval, midAuthorizer: MidAuthorizer): AppWithWSs;
@@ -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
@@ -1,2 +1,4 @@
1
1
  import { RequestHandler } from 'express';
2
- export declare function getParam<T>(paramGetter: (userId: string) => Promise<T>): RequestHandler;
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
- export declare function setParam<T>(paramSetter: (userId: string, param: T) => Promise<boolean>): RequestHandler;
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 { FinalizeDelivery } from '../../resources/recipients';
3
- export declare function finalizeDelivery(finDelivFunc: FinalizeDelivery): RequestHandler;
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 { AllowedMaxMsgSize } from '../../resources/recipients';
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: AllowedMaxMsgSize, redirectFunc?: Redirect): RequestHandler;
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 { GetPubKey } from '../../resources/recipients';
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: GetPubKey): RequestHandler;
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 { SetMsgStorage } from '../../resources/recipients';
3
- export declare function saveMetadata(setMsgStorageFunc: SetMsgStorage, maxChunk: string | number): RequestHandler;
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 { SaveObj } from '../../resources/recipients';
3
- export declare function saveMsgObj(saveObjFunc: SaveObj, chunkLimit: string | number): RequestHandler;
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 { IncompleteMsgDeliveryParams } from '../../resources/recipients';
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: IncompleteMsgDeliveryParams, maxChunk: string | number, redirectFunc?: Redirect): RequestHandler;
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 { AllowedMaxMsgSize } from '../../resources/recipients';
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 may resolve to
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: AllowedMaxMsgSize, sessionGenFunc: GenerateSession, redirectFunc?: Redirect): RequestHandler;
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 may resolve to
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 { GetMsgMeta } from '../../resources/recipients';
3
- export declare function getMsgMeta(getMsgMetaFunc: GetMsgMeta): RequestHandler;
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 { GetObj } from '../../resources/recipients';
3
- export declare function getMsgObj(getMsgObjFunc: GetObj): RequestHandler;
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 { GetMsgIds } from '../../resources/recipients';
3
- export declare function listMsgIds(listMsgIdsFunc: GetMsgIds): RequestHandler;
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 { DeleteMsg } from '../../resources/recipients';
3
- export declare function deleteMsg(delMsgFunc: DeleteMsg): RequestHandler;
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;
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
3
  /// <reference types="node" />
4
+ /// <reference types="node" />
4
5
  import * as fs from 'fs';
5
6
  import { Readable, Writable } from 'stream';
6
7
  export { Stats } from 'fs';
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  export declare const EMPTY_BUFFER: Buffer;
3
4
  /**
4
5
  * Buffer and Uint8Array are intimately linked in Node, starting with some
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Layout } from "xsp-files";
3
4
  export interface HeaderChunkInfo {
4
5
  len: number;
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { HeaderChunkInfo, SegsChunk } from "./file-layout";
3
4
  export declare const V1_FILE_START: Buffer;
4
5
  /**
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  export type SignupContext = SingleUserSignupCtx | MultiDomainSignupCtx;
3
4
  export interface SingleUserSignupCtx {
4
5
  token: string;
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "spec-3nweb-server",
3
- "version": "1.7.8",
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": "pkg --config package.json build/main.js",
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
  }