spec-3nweb-server 1.8.6 → 1.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/3nstorage/resources/store.d.ts +2 -2
- package/build/3nstorage/resources/store.js +1 -1
- package/build/3nstorage/resources/users.d.ts +3 -3
- package/build/3nstorage/resources/users.js +1 -1
- package/build/3nstorage/resources/utils.d.ts +6 -0
- package/build/3nstorage/resources/utils.js +41 -0
- package/build/3nstorage/routes/owner/archive-obj-version.js +8 -10
- package/build/3nstorage/routes/owner/cancel-trans.js +5 -4
- package/build/3nstorage/routes/owner/delete-obj.js +7 -8
- package/build/3nstorage/routes/owner/get-archived-obj-ver.js +11 -13
- package/build/3nstorage/routes/owner/get-current-obj.js +7 -6
- package/build/3nstorage/routes/owner/get-obj-status.js +8 -8
- package/build/3nstorage/routes/owner/put-current-obj.js +25 -55
- package/build/3nstorage/routes/owner/session-params.js +2 -0
- package/build/asmail/resources/utils.d.ts +6 -0
- package/build/asmail/resources/utils.js +36 -0
- package/build/asmail/routes/delivery/finalize-delivery.js +3 -2
- package/build/asmail/routes/delivery/pre-flight.js +9 -26
- package/build/asmail/routes/delivery/provide-recipient-pubkey.js +4 -3
- package/build/asmail/routes/delivery/put-metadata.js +13 -21
- package/build/asmail/routes/delivery/put-obj.js +19 -25
- package/build/asmail/routes/delivery/restart-session.d.ts +4 -8
- package/build/asmail/routes/delivery/restart-session.js +10 -23
- package/build/asmail/routes/delivery/sender-authorization.js +5 -5
- package/build/asmail/routes/delivery/start-session.js +9 -24
- package/build/asmail/routes/retrieval/get-message-meta.js +4 -7
- package/build/asmail/routes/retrieval/get-message-obj.js +10 -7
- package/build/asmail/routes/retrieval/list-messages.js +4 -4
- package/build/asmail/routes/retrieval/remove-message.js +3 -2
- package/package.json +4 -4
- package/ts-code/3nstorage/resources/store.ts +3 -3
- package/ts-code/3nstorage/resources/users.ts +5 -5
- package/ts-code/3nstorage/resources/utils.ts +45 -0
- package/ts-code/3nstorage/routes/owner/archive-obj-version.ts +8 -10
- package/ts-code/3nstorage/routes/owner/cancel-trans.ts +5 -3
- package/ts-code/3nstorage/routes/owner/delete-obj.ts +9 -13
- package/ts-code/3nstorage/routes/owner/get-archived-obj-ver.ts +13 -15
- package/ts-code/3nstorage/routes/owner/get-current-obj.ts +7 -5
- package/ts-code/3nstorage/routes/owner/get-obj-status.ts +8 -8
- package/ts-code/3nstorage/routes/owner/put-current-obj.ts +33 -60
- package/ts-code/3nstorage/routes/owner/session-params.ts +4 -3
- package/ts-code/asmail/resources/utils.ts +41 -0
- package/ts-code/asmail/routes/delivery/finalize-delivery.ts +3 -2
- package/ts-code/asmail/routes/delivery/pre-flight.ts +15 -29
- package/ts-code/asmail/routes/delivery/provide-recipient-pubkey.ts +4 -4
- package/ts-code/asmail/routes/delivery/put-metadata.ts +21 -30
- package/ts-code/asmail/routes/delivery/put-obj.ts +20 -34
- package/ts-code/asmail/routes/delivery/restart-session.ts +11 -24
- package/ts-code/asmail/routes/delivery/sender-authorization.ts +5 -5
- package/ts-code/asmail/routes/delivery/start-session.ts +17 -32
- package/ts-code/asmail/routes/retrieval/get-message-meta.ts +5 -8
- package/ts-code/asmail/routes/retrieval/get-message-obj.ts +12 -15
- package/ts-code/asmail/routes/retrieval/list-messages.ts +4 -6
- package/ts-code/asmail/routes/retrieval/remove-message.ts +3 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2017, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2017, 2025 - 2026 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,6 +20,7 @@ exports.preFlight = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
22
22
|
const canonical_address_1 = require("../../../lib-common/canonical-address");
|
|
23
|
+
const utils_1 = require("../../resources/utils");
|
|
23
24
|
/**
|
|
24
25
|
* This creates a pre-flight route handler.
|
|
25
26
|
* @param allowedMsgSizeFunc is a function returning promises, that may resolve to
|
|
@@ -41,14 +42,10 @@ function preFlight(allowedMsgSizeFunc, redirectFunc) {
|
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
else if (msgSize === 0) {
|
|
44
|
-
|
|
45
|
-
error: `${sender ? sender : "Anonymous sender "} is not allowed to leave mail for ${recipient}`
|
|
46
|
-
});
|
|
45
|
+
(0, utils_1.replyWithErr)(delivery_1.preFlight.SC.senderNotAllowed, `${sender ? sender : "Anonymous sender "} is not allowed to leave mail for ${recipient}`, res);
|
|
47
46
|
}
|
|
48
47
|
else if (msgSize === -1) {
|
|
49
|
-
|
|
50
|
-
error: `Mail box for ${recipient} is full.`
|
|
51
|
-
});
|
|
48
|
+
(0, utils_1.replyWithErr)(delivery_1.preFlight.SC.inboxFull, `Mail box for ${recipient} is full.`, res);
|
|
52
49
|
}
|
|
53
50
|
else {
|
|
54
51
|
throw new Error(`Unrecognized code ${msgSize} for message size limits.`);
|
|
@@ -62,34 +59,22 @@ function preFlight(allowedMsgSizeFunc, redirectFunc) {
|
|
|
62
59
|
const session = req.session;
|
|
63
60
|
// already existing session indicates repeated call, which should be bounced off
|
|
64
61
|
if (session) {
|
|
65
|
-
|
|
66
|
-
error: "This protocol request has already been served."
|
|
67
|
-
});
|
|
68
|
-
return;
|
|
62
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.duplicateReq, "This protocol request has already been served.", res);
|
|
69
63
|
}
|
|
70
64
|
// missing recipient makes a bad request
|
|
71
65
|
if (!recipient) {
|
|
72
|
-
|
|
73
|
-
error: "Recipient is either missing in the request, or is malformed"
|
|
74
|
-
});
|
|
75
|
-
return;
|
|
66
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Recipient is either missing in the request, or is malformed", res);
|
|
76
67
|
}
|
|
77
68
|
// if sender is given, we canonicalize the address
|
|
78
69
|
if (sender) {
|
|
79
70
|
sender = (0, canonical_address_1.checkAndTransformAddress)(sender);
|
|
80
71
|
if (!sender) {
|
|
81
|
-
|
|
82
|
-
error: "Sender field is malformed"
|
|
83
|
-
});
|
|
84
|
-
return;
|
|
72
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Sender field is malformed", res);
|
|
85
73
|
}
|
|
86
74
|
}
|
|
87
75
|
// check invitation field
|
|
88
76
|
if ((invitation !== undefined) && (typeof invitation !== 'string')) {
|
|
89
|
-
|
|
90
|
-
error: "Inviation field is malformed"
|
|
91
|
-
});
|
|
92
|
-
return;
|
|
77
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Inviation field is malformed", res);
|
|
93
78
|
}
|
|
94
79
|
try {
|
|
95
80
|
if (redirectFunc) {
|
|
@@ -109,9 +94,7 @@ function preFlight(allowedMsgSizeFunc, redirectFunc) {
|
|
|
109
94
|
}
|
|
110
95
|
catch (err) {
|
|
111
96
|
if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
112
|
-
|
|
113
|
-
error: `Recipient ${recipient} is unknown.`
|
|
114
|
-
});
|
|
97
|
+
(0, utils_1.replyWithErr)(delivery_1.preFlight.SC.unknownRecipient, `Recipient ${recipient} is unknown.`, res);
|
|
115
98
|
}
|
|
116
99
|
else {
|
|
117
100
|
next(err);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 - 2026 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
|
|
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
exports.getRecipientPubKey = void 0;
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
22
|
+
const utils_1 = require("../../resources/utils");
|
|
22
23
|
/**
|
|
23
24
|
* This creates a get-init-pub-key route handler.
|
|
24
25
|
* @param pkeyProvidingFunc is a function that provides recipient's public key
|
|
@@ -33,7 +34,7 @@ function getRecipientPubKey(pkeyProvidingFunc) {
|
|
|
33
34
|
res.status(delivery_1.initPubKey.SC.ok).json(certs);
|
|
34
35
|
}
|
|
35
36
|
else {
|
|
36
|
-
|
|
37
|
+
(0, utils_1.replyWithErr)(delivery_1.initPubKey.SC.pkeyNotRegistered, 'No public key registered for the recipient.', res);
|
|
37
38
|
session.close();
|
|
38
39
|
}
|
|
39
40
|
}
|
|
@@ -42,7 +43,7 @@ function getRecipientPubKey(pkeyProvidingFunc) {
|
|
|
42
43
|
next(err);
|
|
43
44
|
}
|
|
44
45
|
else if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
45
|
-
|
|
46
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.server, "Recipient disappeared from the system.", res);
|
|
46
47
|
session.close();
|
|
47
48
|
}
|
|
48
49
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 - 2026 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
|
|
@@ -21,23 +21,18 @@ const recipients_1 = require("../../resources/recipients");
|
|
|
21
21
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
22
22
|
const confUtil = require("../../../lib-server/conf-util");
|
|
23
23
|
const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
24
|
+
const utils_1 = require("../../resources/utils");
|
|
24
25
|
function findProblemWithObjIds(ids) {
|
|
25
26
|
if (!Array.isArray(ids)) {
|
|
26
|
-
return
|
|
27
|
-
error: "Object ids are missing."
|
|
28
|
-
};
|
|
27
|
+
return "Object ids are missing.";
|
|
29
28
|
}
|
|
30
29
|
const checkedIds = new Set();
|
|
31
30
|
for (const objId of ids) {
|
|
32
31
|
if (checkedIds.has(objId)) {
|
|
33
|
-
return
|
|
34
|
-
error: "Duplication of object ids."
|
|
35
|
-
};
|
|
32
|
+
return "Duplication of object ids.";
|
|
36
33
|
}
|
|
37
34
|
if (!buffer_utils_1.base64urlSafe.allCharsFromAlphabet(objId)) {
|
|
38
|
-
return
|
|
39
|
-
error: "Object id is invalid."
|
|
40
|
-
};
|
|
35
|
+
return "Object id is invalid.";
|
|
41
36
|
}
|
|
42
37
|
checkedIds.add(objId);
|
|
43
38
|
}
|
|
@@ -47,18 +42,15 @@ function saveMetadata(setMsgStorageFunc, maxChunk) {
|
|
|
47
42
|
const maxChunkSize = confUtil.stringToNumOfBytes(maxChunk);
|
|
48
43
|
return async (req, res, next) => {
|
|
49
44
|
const session = req.session;
|
|
50
|
-
const msgMeta = req.body;
|
|
51
|
-
const recipient = session.params.recipient;
|
|
52
|
-
const objIds = msgMeta.objIds;
|
|
53
45
|
if (session.params.msgId) {
|
|
54
|
-
|
|
55
|
-
error: "This protocol request has already been served."
|
|
56
|
-
});
|
|
57
|
-
return;
|
|
46
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.duplicateReq, "This protocol request has already been served.", res);
|
|
58
47
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
const recipient = session.params.recipient;
|
|
49
|
+
const msgMeta = req.body;
|
|
50
|
+
const objIds = msgMeta.objIds;
|
|
51
|
+
const errWithWithObjIds = findProblemWithObjIds(objIds);
|
|
52
|
+
if (errWithWithObjIds) {
|
|
53
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, errWithWithObjIds, res);
|
|
62
54
|
}
|
|
63
55
|
try {
|
|
64
56
|
const msgId = await setMsgStorageFunc(recipient, msgMeta, session.params.sender, session.params.invite, session.params.maxMsgLength);
|
|
@@ -73,7 +65,7 @@ function saveMetadata(setMsgStorageFunc, maxChunk) {
|
|
|
73
65
|
next(err);
|
|
74
66
|
}
|
|
75
67
|
else if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
76
|
-
|
|
68
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.server, "Recipient disappeared from the system.", res);
|
|
77
69
|
session.close();
|
|
78
70
|
}
|
|
79
71
|
}
|
|
@@ -20,44 +20,43 @@ exports.saveMsgObj = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
22
22
|
const confUtil = require("../../../lib-server/conf-util");
|
|
23
|
-
const
|
|
23
|
+
const utils_1 = require("../../resources/utils");
|
|
24
24
|
function saveMsgObj(saveObjFunc, chunkLimit) {
|
|
25
25
|
const maxChunkSize = confUtil.stringToNumOfBytes(chunkLimit);
|
|
26
26
|
return async (req, res, next) => {
|
|
27
27
|
if (!req.is(recipients_1.BIN_TYPE)) {
|
|
28
|
-
(0,
|
|
29
|
-
res.status(delivery_1.ERR_SC.wrongContentType).send(`Content-Type must be ${recipients_1.BIN_TYPE} for this call.`);
|
|
30
|
-
return;
|
|
28
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.wrongContentType, `Content-Type must be ${recipients_1.BIN_TYPE} for this call.`, res, req);
|
|
31
29
|
}
|
|
32
30
|
const session = req.session;
|
|
33
31
|
const recipient = session.params.recipient;
|
|
34
32
|
const msgId = session.params.msgId;
|
|
35
33
|
if (!msgId) {
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.earlyReq, "Metadata has not been sent, yet.", res, req);
|
|
35
|
+
}
|
|
36
|
+
const { objId, objIdParseErr } = (0, utils_1.getObjIdFromParams)(req);
|
|
37
|
+
if (objIdParseErr) {
|
|
38
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, objIdParseErr, res);
|
|
38
39
|
}
|
|
39
|
-
const objId = req.params.objId;
|
|
40
40
|
// get and check Content-Length, implicitly sending replies for bad length
|
|
41
41
|
let len = getContentLenOrSendError(req, res, maxChunkSize);
|
|
42
42
|
if (len === undefined) {
|
|
43
|
-
(0, body_parsers_1.attachByteDrainToRequest)(req);
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
46
45
|
// extract and check query parameters
|
|
47
46
|
const opts = extractQueryOptions(req);
|
|
48
47
|
if (!opts) {
|
|
49
|
-
return
|
|
48
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Bad query parameters", res, req);
|
|
50
49
|
}
|
|
51
50
|
if (opts.fstReq) {
|
|
52
51
|
// check options versus chunk length
|
|
53
52
|
if (opts.fstReq.header > len) {
|
|
54
|
-
return
|
|
53
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Bad query parameters", res, req);
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
else if (opts.sndReq) {
|
|
58
57
|
// check options versus chunk length
|
|
59
58
|
if ((len === 0) && !opts.sndReq.last) {
|
|
60
|
-
return
|
|
59
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "No segment bytes", res, req);
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
else {
|
|
@@ -69,8 +68,7 @@ function saveMsgObj(saveObjFunc, chunkLimit) {
|
|
|
69
68
|
session.params.currentMsgLength += len;
|
|
70
69
|
}
|
|
71
70
|
else {
|
|
72
|
-
|
|
73
|
-
return;
|
|
71
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.contentTooLong, "This request goes over the message limit.", res, req);
|
|
74
72
|
}
|
|
75
73
|
try {
|
|
76
74
|
await saveObjFunc(recipient, msgId, objId, opts.fstReq, opts.sndReq, len, req);
|
|
@@ -82,24 +80,24 @@ function saveMsgObj(saveObjFunc, chunkLimit) {
|
|
|
82
80
|
next(err);
|
|
83
81
|
}
|
|
84
82
|
else if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
85
|
-
|
|
83
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.server, "Recipient disappeared from the system.", res);
|
|
86
84
|
session.close();
|
|
87
85
|
}
|
|
88
86
|
else if (err === recipients_1.SC.OBJ_EXIST) {
|
|
89
|
-
|
|
87
|
+
(0, utils_1.replyWithErr)(delivery_1.msgObj.SC.objAlreadyExists, `Object ${objId} already exists.`, res);
|
|
90
88
|
}
|
|
91
89
|
else if (err === recipients_1.SC.MSG_UNKNOWN) {
|
|
92
|
-
|
|
90
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.server, "Message disappeared from the system.", res);
|
|
93
91
|
session.close();
|
|
94
92
|
}
|
|
95
93
|
else if (err === recipients_1.SC.OBJ_UNKNOWN) {
|
|
96
|
-
|
|
94
|
+
(0, utils_1.replyWithErr)(delivery_1.msgObj.SC.unknownObj, `Object ${objId} is unknown.`, res);
|
|
97
95
|
}
|
|
98
96
|
else if (err === recipients_1.SC.WRONG_OBJ_STATE) {
|
|
99
|
-
|
|
97
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, `Object ${objId} is not in a different state.`, res);
|
|
100
98
|
}
|
|
101
99
|
else if (err === recipients_1.SC.OBJ_FILE_INCOMPLETE) {
|
|
102
|
-
|
|
100
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.objIncomplete, `Object ${objId} is not complete.`, res);
|
|
103
101
|
}
|
|
104
102
|
else {
|
|
105
103
|
next(new Error(`Unhandled storage error code: ${err}`));
|
|
@@ -135,18 +133,14 @@ function extractQueryOptions(req) {
|
|
|
135
133
|
function getContentLenOrSendError(req, res, maxChunkSize) {
|
|
136
134
|
const contentLength = parseInt(req.get(delivery_1.HTTP_HEADER.contentLength));
|
|
137
135
|
if (isNaN(contentLength)) {
|
|
138
|
-
|
|
136
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.contentLenMissing, "Content-Length header is required with proper number.", res, req);
|
|
139
137
|
}
|
|
140
138
|
else if (contentLength > maxChunkSize) {
|
|
141
|
-
|
|
139
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.contentTooLong, "Request body is too long.", res, req);
|
|
142
140
|
}
|
|
143
141
|
else {
|
|
144
142
|
return contentLength;
|
|
145
143
|
}
|
|
146
144
|
return;
|
|
147
145
|
}
|
|
148
|
-
function replyToMalformed(req, msg, res) {
|
|
149
|
-
(0, body_parsers_1.attachByteDrainToRequest)(req);
|
|
150
|
-
res.status(delivery_1.ERR_SC.malformed).send(msg);
|
|
151
|
-
}
|
|
152
146
|
Object.freeze(exports);
|
|
@@ -4,14 +4,10 @@ import { GenerateSession, GetSessionForMsg } from '../../resources/delivery-sess
|
|
|
4
4
|
import { Redirect } from './start-session';
|
|
5
5
|
/**
|
|
6
6
|
* This creates a session restart route handler.
|
|
7
|
-
* @param sessionGenFunc is a promise returning function that generates new
|
|
8
|
-
* session
|
|
9
|
-
* @param
|
|
10
|
-
* a
|
|
11
|
-
* @param incompleteMsgFunc is a function that promises parameters of a message
|
|
12
|
-
* that is still in delivery.
|
|
13
|
-
* @param redirectFunc is an optional function that returns a promise,
|
|
14
|
-
* resolvable to
|
|
7
|
+
* @param sessionGenFunc is a promise returning function that generates new session objects.
|
|
8
|
+
* @param sessionForMsgFunc is a function that promises existing session for a known message in delivery.
|
|
9
|
+
* @param incompleteMsgFunc is a function that promises parameters of a message that is still in delivery.
|
|
10
|
+
* @param redirectFunc is an optional function that returns a promise, resolvable to
|
|
15
11
|
* (1) string with URI for ASMail service, which is serving given recipient,
|
|
16
12
|
* (2) undefined, if it is this server should service given recipient.
|
|
17
13
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2017, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2017, 2025 - 2026 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
|
|
@@ -21,16 +21,13 @@ const recipients_1 = require("../../resources/recipients");
|
|
|
21
21
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
22
22
|
const canonical_address_1 = require("../../../lib-common/canonical-address");
|
|
23
23
|
const confUtil = require("../../../lib-server/conf-util");
|
|
24
|
+
const utils_1 = require("../../resources/utils");
|
|
24
25
|
/**
|
|
25
26
|
* This creates a session restart route handler.
|
|
26
|
-
* @param sessionGenFunc is a promise returning function that generates new
|
|
27
|
-
* session
|
|
28
|
-
* @param
|
|
29
|
-
* a
|
|
30
|
-
* @param incompleteMsgFunc is a function that promises parameters of a message
|
|
31
|
-
* that is still in delivery.
|
|
32
|
-
* @param redirectFunc is an optional function that returns a promise,
|
|
33
|
-
* resolvable to
|
|
27
|
+
* @param sessionGenFunc is a promise returning function that generates new session objects.
|
|
28
|
+
* @param sessionForMsgFunc is a function that promises existing session for a known message in delivery.
|
|
29
|
+
* @param incompleteMsgFunc is a function that promises parameters of a message that is still in delivery.
|
|
30
|
+
* @param redirectFunc is an optional function that returns a promise, resolvable to
|
|
34
31
|
* (1) string with URI for ASMail service, which is serving given recipient,
|
|
35
32
|
* (2) undefined, if it is this server should service given recipient.
|
|
36
33
|
*/
|
|
@@ -69,17 +66,11 @@ function restartSession(sessionGenFunc, sessionForMsgFunc, incompleteMsgFunc, ma
|
|
|
69
66
|
}
|
|
70
67
|
// missing recipient makes a bad request
|
|
71
68
|
if (!recipient) {
|
|
72
|
-
|
|
73
|
-
error: "Recipient is either missing in the request, or is malformed"
|
|
74
|
-
});
|
|
75
|
-
return;
|
|
69
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Recipient is either missing in the request, or is malformed", res);
|
|
76
70
|
}
|
|
77
71
|
// check message id
|
|
78
72
|
if (typeof msgId !== 'string') {
|
|
79
|
-
|
|
80
|
-
error: "Message id is either missing, or is malformed"
|
|
81
|
-
});
|
|
82
|
-
return;
|
|
73
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Message id is either missing, or is malformed", res);
|
|
83
74
|
}
|
|
84
75
|
try {
|
|
85
76
|
if (redirectFunc) {
|
|
@@ -99,14 +90,10 @@ function restartSession(sessionGenFunc, sessionForMsgFunc, incompleteMsgFunc, ma
|
|
|
99
90
|
}
|
|
100
91
|
catch (err) {
|
|
101
92
|
if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
102
|
-
|
|
103
|
-
error: `Recipient ${recipient} is unknown.`
|
|
104
|
-
});
|
|
93
|
+
(0, utils_1.replyWithErr)(delivery_1.sessionRestart.SC.unknownRecipient, `Recipient ${recipient} is unknown.`, res);
|
|
105
94
|
}
|
|
106
95
|
else if (err === recipients_1.SC.MSG_UNKNOWN) {
|
|
107
|
-
|
|
108
|
-
error: `Recipient ${recipient} is unknown.`
|
|
109
|
-
});
|
|
96
|
+
(0, utils_1.replyWithErr)(delivery_1.sessionRestart.SC.unknownMsg, `Recipient ${recipient} is unknown.`, res);
|
|
110
97
|
}
|
|
111
98
|
else {
|
|
112
99
|
next(err);
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.authorize = void 0;
|
|
20
20
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
21
|
+
const utils_1 = require("../../resources/utils");
|
|
21
22
|
/**
|
|
22
23
|
* This creates an authorize-sender route handler.
|
|
23
24
|
* @param relyingPartyDomain at which this service operates, as seen by client
|
|
@@ -28,8 +29,7 @@ const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
|
28
29
|
function authorize(relyingPartyDomain, midAuthorizingFunc) {
|
|
29
30
|
return async (req, res, next) => {
|
|
30
31
|
if (req.session.isAuthorized) {
|
|
31
|
-
|
|
32
|
-
return;
|
|
32
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.duplicateReq, "This protocol request has already been served.", res);
|
|
33
33
|
}
|
|
34
34
|
const rb = req.body;
|
|
35
35
|
const sender = req.session.params.sender;
|
|
@@ -37,12 +37,12 @@ function authorize(relyingPartyDomain, midAuthorizingFunc) {
|
|
|
37
37
|
if (!sender) {
|
|
38
38
|
// This case must be rejected, because place for authorizing
|
|
39
39
|
// anonymous connection is at the session start.
|
|
40
|
-
|
|
40
|
+
(0, utils_1.replyWithErr)(delivery_1.authSender.SC.authFailed, "Server is not accepting provided credentials.", res);
|
|
41
41
|
req.session.close();
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
if (!rb.assertion || !rb.userCert || !rb.provCert) {
|
|
45
|
-
|
|
45
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "No credentials given.", res);
|
|
46
46
|
req.session.close();
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
@@ -53,7 +53,7 @@ function authorize(relyingPartyDomain, midAuthorizingFunc) {
|
|
|
53
53
|
res.status(delivery_1.authSender.SC.ok).send();
|
|
54
54
|
}
|
|
55
55
|
else {
|
|
56
|
-
|
|
56
|
+
(0, utils_1.replyWithErr)(delivery_1.authSender.SC.authFailed, "Server is not accepting provided credentials.", res);
|
|
57
57
|
req.session.close();
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 - 2026 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,6 +20,7 @@ exports.startSession = void 0;
|
|
|
20
20
|
const recipients_1 = require("../../resources/recipients");
|
|
21
21
|
const delivery_1 = require("../../../lib-common/service-api/asmail/delivery");
|
|
22
22
|
const canonical_address_1 = require("../../../lib-common/canonical-address");
|
|
23
|
+
const utils_1 = require("../../resources/utils");
|
|
23
24
|
/**
|
|
24
25
|
* This creates a start-session route handler.
|
|
25
26
|
* @param allowedMsgSizeFunc is a function returning promises, that
|
|
@@ -55,14 +56,10 @@ function startSession(allowedMsgSizeFunc, sessionGenFunc, redirectFunc) {
|
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
else if (msgSize === 0) {
|
|
58
|
-
|
|
59
|
-
error: `${sender ? sender : "Anonymous sender "} is not allowed to leave mail for ${recipient}`
|
|
60
|
-
});
|
|
59
|
+
(0, utils_1.replyWithErr)(delivery_1.sessionStart.SC.senderNotAllowed, `${sender ? sender : "Anonymous sender "} is not allowed to leave mail for ${recipient}`, res);
|
|
61
60
|
}
|
|
62
61
|
else if (msgSize === -1) {
|
|
63
|
-
|
|
64
|
-
error: `Mail box for ${recipient} is full.`
|
|
65
|
-
});
|
|
62
|
+
(0, utils_1.replyWithErr)(delivery_1.sessionStart.SC.inboxFull, `Mail box for ${recipient} is full.`, res);
|
|
66
63
|
}
|
|
67
64
|
else {
|
|
68
65
|
throw new Error(`Unrecognized code ${msgSize} for message size limits.`);
|
|
@@ -76,34 +73,24 @@ function startSession(allowedMsgSizeFunc, sessionGenFunc, redirectFunc) {
|
|
|
76
73
|
const session = req.session;
|
|
77
74
|
// already existing session indicates repeated call, which should be bounced off
|
|
78
75
|
if (session) {
|
|
79
|
-
|
|
80
|
-
error: "This protocol request has already been served."
|
|
81
|
-
});
|
|
76
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.duplicateReq, "This protocol request has already been served.", res);
|
|
82
77
|
return;
|
|
83
78
|
}
|
|
84
79
|
// missing recipient makes a bad request
|
|
85
80
|
if (!recipient) {
|
|
86
|
-
|
|
87
|
-
error: "Recipient is either missing in the request, or is malformed"
|
|
88
|
-
});
|
|
81
|
+
(0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Recipient is either missing in the request, or is malformed", res);
|
|
89
82
|
return;
|
|
90
83
|
}
|
|
91
84
|
// if sender is given, we canonicalize the address
|
|
92
85
|
if (sender) {
|
|
93
86
|
sender = (0, canonical_address_1.checkAndTransformAddress)(sender);
|
|
94
87
|
if (!sender) {
|
|
95
|
-
|
|
96
|
-
error: "Sender field is malformed"
|
|
97
|
-
});
|
|
98
|
-
return;
|
|
88
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Sender field is malformed", res);
|
|
99
89
|
}
|
|
100
90
|
}
|
|
101
91
|
// check invitation field
|
|
102
92
|
if ((invitation !== undefined) && (typeof invitation !== 'string')) {
|
|
103
|
-
|
|
104
|
-
error: "Inviation field is malformed"
|
|
105
|
-
});
|
|
106
|
-
return;
|
|
93
|
+
return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Inviation field is malformed", res);
|
|
107
94
|
}
|
|
108
95
|
try {
|
|
109
96
|
if (redirectFunc) {
|
|
@@ -123,9 +110,7 @@ function startSession(allowedMsgSizeFunc, sessionGenFunc, redirectFunc) {
|
|
|
123
110
|
}
|
|
124
111
|
catch (err) {
|
|
125
112
|
if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
126
|
-
|
|
127
|
-
error: `Recipient ${recipient} is unknown.`
|
|
128
|
-
});
|
|
113
|
+
(0, utils_1.replyWithErr)(delivery_1.sessionStart.SC.unknownRecipient, `Recipient ${recipient} is unknown.`, res);
|
|
129
114
|
}
|
|
130
115
|
else {
|
|
131
116
|
next(err);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 - 2026 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
|
|
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
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
|
+
const utils_1 = require("../../resources/utils");
|
|
22
23
|
function getMsgMeta(getMsgMetaFunc) {
|
|
23
24
|
return async (req, res, next) => {
|
|
24
25
|
const userId = req.session.params.userId;
|
|
@@ -32,14 +33,10 @@ function getMsgMeta(getMsgMetaFunc) {
|
|
|
32
33
|
next(err);
|
|
33
34
|
}
|
|
34
35
|
else if (err === recipients_1.SC.MSG_UNKNOWN) {
|
|
35
|
-
|
|
36
|
-
error: "Message " + msgId + " is unknown."
|
|
37
|
-
});
|
|
36
|
+
(0, utils_1.replyWithErr)(retrieval_1.msgMetadata.SC.unknownMsg, "Message " + msgId + " is unknown.", res);
|
|
38
37
|
}
|
|
39
38
|
else if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
40
|
-
|
|
41
|
-
error: "Recipient disappeared from the system."
|
|
42
|
-
});
|
|
39
|
+
(0, utils_1.replyWithErr)(retrieval_1.ERR_SC.server, "Recipient disappeared from the system.", res);
|
|
43
40
|
req.session.close();
|
|
44
41
|
}
|
|
45
42
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2017, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2017, 2025 - 2026 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
|
|
@@ -21,6 +21,7 @@ const recipients_1 = require("../../resources/recipients");
|
|
|
21
21
|
const retrieval_1 = require("../../../lib-common/service-api/asmail/retrieval");
|
|
22
22
|
const error_1 = require("../../../lib-common/exceptions/error");
|
|
23
23
|
const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
24
|
+
const utils_1 = require("../../resources/utils");
|
|
24
25
|
function extractQueryOptions(req) {
|
|
25
26
|
// query fields are string or undefined, yet, type info helps the show
|
|
26
27
|
const query = req.query;
|
|
@@ -41,11 +42,13 @@ function getMsgObj(getMsgObjFunc) {
|
|
|
41
42
|
return async (req, res, next) => {
|
|
42
43
|
const userId = req.session.params.userId;
|
|
43
44
|
const msgId = req.params.msgId;
|
|
44
|
-
const objId = req
|
|
45
|
+
const { objId, objIdParseErr } = (0, utils_1.getObjIdFromParams)(req);
|
|
46
|
+
if (objIdParseErr) {
|
|
47
|
+
return (0, utils_1.replyWithErr)(retrieval_1.ERR_SC.malformed, objIdParseErr, res);
|
|
48
|
+
}
|
|
45
49
|
const opts = extractQueryOptions(req);
|
|
46
50
|
if (!opts) {
|
|
47
|
-
|
|
48
|
-
return;
|
|
51
|
+
return (0, utils_1.replyWithErr)(retrieval_1.ERR_SC.malformed, "Bad query parameters", res);
|
|
49
52
|
}
|
|
50
53
|
try {
|
|
51
54
|
const reader = await getMsgObjFunc(userId, msgId, objId, opts.header, opts.ofs, opts.limit);
|
|
@@ -76,13 +79,13 @@ function getMsgObj(getMsgObjFunc) {
|
|
|
76
79
|
next(err);
|
|
77
80
|
}
|
|
78
81
|
else if (err === recipients_1.SC.OBJ_UNKNOWN) {
|
|
79
|
-
|
|
82
|
+
(0, utils_1.replyWithErr)(retrieval_1.msgObj.SC.unknownMsgOrObj, `Object ${objId} is unknown.`, res);
|
|
80
83
|
}
|
|
81
84
|
else if (err === recipients_1.SC.MSG_UNKNOWN) {
|
|
82
|
-
|
|
85
|
+
(0, utils_1.replyWithErr)(retrieval_1.msgObj.SC.unknownMsgOrObj, `Message ${msgId} is unknown.`, res);
|
|
83
86
|
}
|
|
84
87
|
else if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
85
|
-
|
|
88
|
+
(0, utils_1.replyWithErr)(retrieval_1.ERR_SC.server, `Recipient disappeared from the system.`, res);
|
|
86
89
|
req.session.close();
|
|
87
90
|
}
|
|
88
91
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2016, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2016, 2025 - 2026 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
|
|
@@ -19,13 +19,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
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
|
+
const utils_1 = require("../../resources/utils");
|
|
22
23
|
function listMsgIds(listMsgIdsFunc) {
|
|
23
24
|
return async (req, res, next) => {
|
|
24
25
|
const userId = req.session.params.userId;
|
|
25
26
|
const opts = extractQueryOptions(req);
|
|
26
27
|
if (!opts) {
|
|
27
|
-
|
|
28
|
-
return;
|
|
28
|
+
return (0, utils_1.replyWithErr)(retrieval_1.ERR_SC.malformed, "Bad query parameters", res);
|
|
29
29
|
}
|
|
30
30
|
try {
|
|
31
31
|
const { from, to } = opts;
|
|
@@ -37,7 +37,7 @@ function listMsgIds(listMsgIdsFunc) {
|
|
|
37
37
|
next(err);
|
|
38
38
|
}
|
|
39
39
|
else if (err === recipients_1.SC.USER_UNKNOWN) {
|
|
40
|
-
|
|
40
|
+
(0, utils_1.replyWithErr)(retrieval_1.ERR_SC.server, "Recipient disappeared from the system.", res);
|
|
41
41
|
req.session.close();
|
|
42
42
|
}
|
|
43
43
|
else {
|