spec-3nweb-server 1.8.10 → 1.8.12

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 (36) hide show
  1. package/.gitlab-ci-linux.yml +18 -5
  2. package/.gitlab-ci.yml +0 -10
  3. package/build/3nstorage/routes/owner/param-getter.js +1 -4
  4. package/build/3nstorage/routes/owner/session-params.js +1 -1
  5. package/build/asmail/resources/utils.d.ts +4 -0
  6. package/build/asmail/resources/utils.js +8 -1
  7. package/build/asmail/routes/delivery/restart-session.js +3 -1
  8. package/build/asmail/routes/retrieval/get-message-meta.js +4 -1
  9. package/build/asmail/routes/retrieval/get-message-obj.js +4 -1
  10. package/build/asmail/routes/retrieval/remove-message.js +4 -1
  11. package/build/mock/run-in-proc.js +3 -1
  12. package/build/tests/libs-for-tests/mailerid.js +1 -2
  13. package/build/tests/protocols/asmail/delivery/specs/restart-session.js +1 -1
  14. package/build/tests/protocols/asmail/delivery/test-utils.js +1 -2
  15. package/build/tests/shared-checks/check-mid-login.js +1 -1
  16. package/package.json +1 -1
  17. package/ts-code/3nstorage/routes/owner/archive-obj-version.ts +1 -0
  18. package/ts-code/3nstorage/routes/owner/cancel-trans.ts +1 -0
  19. package/ts-code/3nstorage/routes/owner/delete-obj.ts +1 -0
  20. package/ts-code/3nstorage/routes/owner/get-archived-obj-ver.ts +1 -0
  21. package/ts-code/3nstorage/routes/owner/get-current-obj.ts +1 -0
  22. package/ts-code/3nstorage/routes/owner/get-obj-status.ts +1 -0
  23. package/ts-code/3nstorage/routes/owner/param-getter.ts +1 -5
  24. package/ts-code/3nstorage/routes/owner/put-current-obj.ts +1 -0
  25. package/ts-code/3nstorage/routes/owner/session-params.ts +1 -1
  26. package/ts-code/asmail/resources/utils.ts +10 -0
  27. package/ts-code/asmail/routes/delivery/restart-session.ts +6 -1
  28. package/ts-code/asmail/routes/retrieval/get-message-meta.ts +6 -2
  29. package/ts-code/asmail/routes/retrieval/get-message-obj.ts +6 -2
  30. package/ts-code/asmail/routes/retrieval/remove-message.ts +6 -2
  31. package/ts-code/mock/run-in-proc.ts +5 -1
  32. package/ts-code/tests/libs-for-tests/mailerid.ts +1 -2
  33. package/ts-code/tests/libs-for-tests/pkl.ts +1 -1
  34. package/ts-code/tests/protocols/asmail/delivery/specs/restart-session.ts +2 -3
  35. package/ts-code/tests/protocols/asmail/delivery/test-utils.ts +6 -7
  36. package/ts-code/tests/shared-checks/check-mid-login.ts +2 -2
@@ -6,7 +6,7 @@
6
6
  build for linux:
7
7
  extends: build
8
8
  rules: [ { when: on_success } ]
9
- image: node-22
9
+ image: node-24
10
10
 
11
11
 
12
12
  test on linux:
@@ -14,7 +14,7 @@ test on linux:
14
14
  rules: [ { when: on_success } ]
15
15
  needs:
16
16
  - build for linux
17
- image: node-22
17
+ image: node-24
18
18
 
19
19
 
20
20
  pack for linux:
@@ -23,7 +23,7 @@ pack for linux:
23
23
  needs:
24
24
  - build for linux
25
25
  - test on linux
26
- image: node-22
26
+ image: node-24
27
27
 
28
28
 
29
29
  pack mock for linux:
@@ -32,7 +32,7 @@ pack mock for linux:
32
32
  needs:
33
33
  - build for linux
34
34
  - test on linux
35
- image: node-22
35
+ image: node-24
36
36
 
37
37
 
38
38
  # pack deb:
@@ -41,10 +41,23 @@ pack mock for linux:
41
41
  # needs:
42
42
  # - build for linux
43
43
  # - test on linux
44
- # image: node-16
44
+ # image: node-24
45
45
  # script:
46
46
  # - npm run pack-deb
47
47
  # artifacts:
48
48
  # paths:
49
49
  # - 3nweb-*.deb
50
50
  # expire_in: 3d
51
+
52
+
53
+ publish to npm:
54
+ stage: publish
55
+ rules:
56
+ - if: '$CI_COMMIT_BRANCH == "master"'
57
+ when: manual
58
+ needs:
59
+ - build for linux
60
+ - test on linux
61
+ image: node-24
62
+ script:
63
+ - bash publish-task.sh $NPM_PUBLISH_TOKEN
package/.gitlab-ci.yml CHANGED
@@ -47,16 +47,6 @@ pack mock:
47
47
  - npm run clear-for-packing-mock
48
48
 
49
49
 
50
- publish to npm:
51
- stage: publish
52
- rules:
53
- - if: '$CI_COMMIT_BRANCH == "master"'
54
- when: manual
55
- image: node-22
56
- script:
57
- - bash publish-task.sh $NPM_PUBLISH_TOKEN
58
-
59
-
60
50
  include:
61
51
  - .gitlab-ci-linux.yml
62
52
  - .gitlab-ci-windows.yml
@@ -20,9 +20,6 @@ exports.getParam = void 0;
20
20
  const users_1 = require("../../resources/users");
21
21
  const owner_1 = require("../../../lib-common/service-api/3nstorage/owner");
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;
@@ -32,7 +29,7 @@ function getParam(paramGetter) {
32
29
  }
33
30
  catch (err) {
34
31
  if (err === users_1.SC.USER_UNKNOWN) {
35
- res.status(owner_1.ERR_SC.server).send("Recipient disappeared from the system.");
32
+ res.status(owner_1.ERR_SC.server).send("User disappeared from the system.");
36
33
  session.close();
37
34
  }
38
35
  else {
@@ -35,7 +35,7 @@ function sessionParams(maxChunk) {
35
35
  next(err);
36
36
  }
37
37
  else if (err === users_1.SC.USER_UNKNOWN) {
38
- res.status(owner_1.ERR_SC.server).send("Recipient disappeared from the system.");
38
+ res.status(owner_1.ERR_SC.server).send("User disappeared from the system.");
39
39
  req.session.close();
40
40
  }
41
41
  else {
@@ -3,4 +3,8 @@ export declare function getObjIdFromParams(req: Request): {
3
3
  objId: string;
4
4
  objIdParseErr?: string;
5
5
  };
6
+ export declare function getMsgIdFromParams(req: Request): {
7
+ msgId: string;
8
+ msgIdParseErr?: string;
9
+ };
6
10
  export declare function replyWithErr(status: number, msg: string, res: Response, reqToDrainBytesFrom?: Request): void;
@@ -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.replyWithErr = exports.getObjIdFromParams = void 0;
19
+ exports.replyWithErr = exports.getMsgIdFromParams = exports.getObjIdFromParams = void 0;
20
20
  const buffer_utils_1 = require("../../lib-common/buffer-utils");
21
21
  const body_parsers_1 = require("../../lib-server/middleware/body-parsers");
22
22
  function getObjIdFromParams(req) {
@@ -26,6 +26,13 @@ function getObjIdFromParams(req) {
26
26
  { objId: undefined, objIdParseErr: "Bad object id" });
27
27
  }
28
28
  exports.getObjIdFromParams = getObjIdFromParams;
29
+ function getMsgIdFromParams(req) {
30
+ const msgId = req.params.msgId;
31
+ return ((!!msgId && buffer_utils_1.base64urlSafe.allCharsFromAlphabet(msgId)) ?
32
+ { msgId } :
33
+ { msgId: undefined, msgIdParseErr: "Bad message id" });
34
+ }
35
+ exports.getMsgIdFromParams = getMsgIdFromParams;
29
36
  function replyWithErr(status, msg, res, reqToDrainBytesFrom) {
30
37
  if (reqToDrainBytesFrom) {
31
38
  (0, body_parsers_1.attachByteDrainToRequest)(reqToDrainBytesFrom);
@@ -22,6 +22,7 @@ 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
24
  const utils_1 = require("../../resources/utils");
25
+ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
25
26
  /**
26
27
  * This creates a session restart route handler.
27
28
  * @param sessionGenFunc is a promise returning function that generates new session objects.
@@ -69,7 +70,8 @@ function restartSession(sessionGenFunc, sessionForMsgFunc, incompleteMsgFunc, ma
69
70
  return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Recipient is either missing in the request, or is malformed", res);
70
71
  }
71
72
  // check message id
72
- if (typeof msgId !== 'string') {
73
+ if ((typeof msgId !== 'string') || !msgId || !buffer_utils_1.base64urlSafe.allCharsFromAlphabet(msgId)) {
74
+ console.log(`msgId ->`, msgId, '\n', `!base64urlSafe.allCharsFromAlphabet(msgId) ->`, !buffer_utils_1.base64urlSafe.allCharsFromAlphabet(msgId));
73
75
  return (0, utils_1.replyWithErr)(delivery_1.ERR_SC.malformed, "Message id is either missing, or is malformed", res);
74
76
  }
75
77
  try {
@@ -23,7 +23,10 @@ const utils_1 = require("../../resources/utils");
23
23
  function getMsgMeta(getMsgMetaFunc) {
24
24
  return async (req, res, next) => {
25
25
  const userId = req.session.params.userId;
26
- const msgId = req.params.msgId;
26
+ const { msgId, msgIdParseErr } = (0, utils_1.getMsgIdFromParams)(req);
27
+ if (msgIdParseErr) {
28
+ return (0, utils_1.replyWithErr)(retrieval_1.ERR_SC.malformed, msgIdParseErr, res, req);
29
+ }
27
30
  try {
28
31
  const meta = await getMsgMetaFunc(userId, msgId);
29
32
  res.status(retrieval_1.msgMetadata.SC.ok).json(meta);
@@ -41,7 +41,10 @@ function extractQueryOptions(req) {
41
41
  function getMsgObj(getMsgObjFunc) {
42
42
  return async (req, res, next) => {
43
43
  const userId = req.session.params.userId;
44
- const msgId = req.params.msgId;
44
+ const { msgId, msgIdParseErr } = (0, utils_1.getMsgIdFromParams)(req);
45
+ if (msgIdParseErr) {
46
+ return (0, utils_1.replyWithErr)(retrieval_1.ERR_SC.malformed, msgIdParseErr, res, req);
47
+ }
45
48
  const { objId, objIdParseErr } = (0, utils_1.getObjIdFromParams)(req);
46
49
  if (objIdParseErr) {
47
50
  return (0, utils_1.replyWithErr)(retrieval_1.ERR_SC.malformed, objIdParseErr, res);
@@ -23,7 +23,10 @@ const utils_1 = require("../../resources/utils");
23
23
  function deleteMsg(delMsgFunc) {
24
24
  return async (req, res, next) => {
25
25
  const userId = req.session.params.userId;
26
- const msgId = req.params.msgId;
26
+ const { msgId, msgIdParseErr } = (0, utils_1.getMsgIdFromParams)(req);
27
+ if (msgIdParseErr) {
28
+ return (0, utils_1.replyWithErr)(retrieval_1.ERR_SC.malformed, msgIdParseErr, res, req);
29
+ }
27
30
  try {
28
31
  await delMsgFunc(userId, msgId);
29
32
  res.status(retrieval_1.rmMsg.SC.ok).send();
@@ -34,13 +34,15 @@ function setTestCertsAndDNS(domains, thisSrvLoc) {
34
34
  https.globalAgent.options.ca = tls_options_1.sslOpts.cert;
35
35
  // inject dns mock
36
36
  const dnsRecs = {};
37
+ const reportAddress = `report@${thisSrvLoc.includes(':') ? thisSrvLoc.substring(0, thisSrvLoc.indexOf(':')) : thisSrvLoc}`;
37
38
  for (const domain of domains) {
38
39
  dnsRecs[domain] = [
39
40
  ['asmail', '=', `${thisSrvLoc}/asmail`],
40
41
  [
41
42
  'mailerid=', `${thisSrvLoc}/mailerid`,
42
43
  `3nstorage=${thisSrvLoc}/3nstorage`
43
- ] // two 3NWeb records in one DNS TXT record
44
+ ],
45
+ [`report=${reportAddress}`]
44
46
  // XXX add other life-like records
45
47
  ];
46
48
  }
@@ -24,7 +24,6 @@ const provisioning_1 = require("../../lib-common/service-api/mailer-id/provision
24
24
  const mid_sigs_NaCl_Ed_1 = require("../../lib-common/mid-sigs-NaCl-Ed");
25
25
  const pkl_1 = require("./pkl");
26
26
  const random_node_1 = require("../../lib-common/random-node");
27
- const url_1 = require("url");
28
27
  async function getMidData(midUrl) {
29
28
  let reqOpts = {
30
29
  url: midUrl,
@@ -97,7 +96,7 @@ async function doMailerIdLogin(loginUrl, user) {
97
96
  responseType: 'json',
98
97
  sessionId
99
98
  };
100
- let serviceDomain = (0, url_1.parse)(loginUrl).hostname;
99
+ let serviceDomain = (new URL(loginUrl)).hostname;
101
100
  if (!serviceDomain) {
102
101
  throw new Error(`Cannot parse hostname from login url ${loginUrl}`);
103
102
  }
@@ -63,7 +63,7 @@ exports.specs.definition = (setup) => (() => {
63
63
  (0, async_jasmine_1.itAsync)(`returns error status when message is not known in delivery`, async () => {
64
64
  const req = {
65
65
  recipient: user2.id,
66
- msgId: 'unknown message'
66
+ msgId: 'unknown_message'
67
67
  };
68
68
  const rep = await (0, xhr_utils_1.doJsonRequest)(reqOpts, req);
69
69
  expect(rep.status).withContext('status for unknown message').toBe(delivery_1.sessionRestart.SC.unknownMsg);
@@ -36,8 +36,7 @@ exports.msg = {
36
36
  msgObjs: [exports.obj1, exports.obj2]
37
37
  };
38
38
  async function startSessionAndSendMsgObjs(deliveryUrl, recipient, msg) {
39
- const sessInfo = await (0, asmail_1.startMsgDelivery)(deliveryUrl, { recipient }, { pid: msg.cryptoMeta.pid,
40
- objIds: [msg.msgObjs[0].objId, msg.msgObjs[1].objId] });
39
+ const sessInfo = await (0, asmail_1.startMsgDelivery)(deliveryUrl, { recipient }, { pid: msg.cryptoMeta.pid, objIds: [msg.msgObjs[0].objId, msg.msgObjs[1].objId] });
41
40
  await (0, asmail_1.sendMsgObj)(deliveryUrl, sessInfo.sessionId, msg.msgObjs[0], sessInfo.maxChunkSize);
42
41
  await (0, asmail_1.sendMsgObj)(deliveryUrl, sessInfo.sessionId, msg.msgObjs[1], sessInfo.maxChunkSize);
43
42
  return sessInfo;
@@ -71,7 +71,7 @@ function midLoginSpecs(loginUrl, user) {
71
71
  responseType: 'json',
72
72
  sessionId
73
73
  };
74
- const serviceDomain = (0, url_1.parse)(loginUrl()).hostname;
74
+ const serviceDomain = (new URL(loginUrl())).hostname;
75
75
  if (!serviceDomain) {
76
76
  throw new Error(`Cannot get hostname from ${loginUrl()}`);
77
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-3nweb-server",
3
- "version": "1.8.10",
3
+ "version": "1.8.12",
4
4
  "description": "3NWeb spec server.",
5
5
  "main": "build/lib.js",
6
6
  "types": "build/lib.d.ts",
@@ -30,6 +30,7 @@ export function archiveCurrentObjVersion(
30
30
  return async (req: Request, res, next) => {
31
31
 
32
32
  const userId = req.session.params.userId;
33
+
33
34
  const { objId, objIdParseErr } = getObjIdFromParams(root, req);
34
35
  if (objIdParseErr) {
35
36
  return replyWithErr(ERR_SC.malformed, objIdParseErr, res);
@@ -28,6 +28,7 @@ export function cancelTransaction(
28
28
  return async (req: Request, res, next) => {
29
29
 
30
30
  const userId = req.session.params.userId;
31
+
31
32
  const { objId, objIdParseErr } = getObjIdFromParams(root, req);
32
33
  if (objIdParseErr) {
33
34
  return replyWithErr(ERR_SC.malformed, objIdParseErr, res);
@@ -33,6 +33,7 @@ function deleteObj(
33
33
  return async (req: Request, res, next) => {
34
34
 
35
35
  const userId = req.session.params.userId;
36
+
36
37
  const { objId, objIdParseErr } = getObjIdFromParams(root, req);
37
38
  if (objIdParseErr) {
38
39
  return replyWithErr(ERR_SC.malformed, objIdParseErr, res);
@@ -56,6 +56,7 @@ export function getArchivedObjVersion(
56
56
  return async (req: Request, res, next) => {
57
57
 
58
58
  const userId = req.session.params.userId;
59
+
59
60
  const { objId, objIdParseErr } = getObjIdFromParams(root, req);
60
61
  if (objIdParseErr) {
61
62
  return replyWithErr(ERR_SC.malformed, objIdParseErr, res);
@@ -63,6 +63,7 @@ export function getCurrentObj(
63
63
  return async (req: Request, res, next) => {
64
64
 
65
65
  const userId = req.session.params.userId;
66
+
66
67
  const { objId, objIdParseErr } = getObjIdFromParams(root, req);
67
68
  if (objIdParseErr) {
68
69
  return replyWithErr(ERR_SC.malformed, objIdParseErr, res);
@@ -28,6 +28,7 @@ export function getObjStatus(
28
28
  return async (req: Request, res, next) => {
29
29
 
30
30
  const userId = req.session.params.userId;
31
+
31
32
  const { objId, objIdParseErr } = getObjIdFromParams(root, req);
32
33
  if (objIdParseErr) {
33
34
  return replyWithErr(ERR_SC.malformed, objIdParseErr, res);
@@ -24,9 +24,6 @@ export function getParam<T>(
24
24
  paramGetter: (userId: string) => Promise<T>
25
25
  ): RequestHandler {
26
26
 
27
- if ('function' !== typeof paramGetter) { throw new TypeError(
28
- "Given argument 'paramGetter' must be function, but is not."); }
29
-
30
27
  return async (req: Request, res, next) => {
31
28
 
32
29
  const session = req.session;
@@ -37,8 +34,7 @@ export function getParam<T>(
37
34
  res.status(PARAM_SC.ok).json(value);
38
35
  } catch (err) {
39
36
  if (err === storeSC.USER_UNKNOWN) {
40
- res.status(ERR_SC.server).send(
41
- "Recipient disappeared from the system.");
37
+ res.status(ERR_SC.server).send("User disappeared from the system.");
42
38
  session.close();
43
39
  } else {
44
40
  next(err);
@@ -47,6 +47,7 @@ export function saveCurrentObj(
47
47
  }
48
48
 
49
49
  const userId = req.session.params.userId;
50
+
50
51
  const { objId, objIdParseErr } = getObjIdFromParams(root, req);
51
52
  if (objIdParseErr) {
52
53
  return replyWithErr(ERR_SC.malformed, objIdParseErr, res, req);
@@ -37,7 +37,7 @@ export function sessionParams(maxChunk: number|string): RequestHandler {
37
37
  if ("string" !== typeof err) {
38
38
  next(err);
39
39
  } else if (err === storeSC.USER_UNKNOWN) {
40
- res.status(ERR_SC.server).send("Recipient disappeared from the system.");
40
+ res.status(ERR_SC.server).send("User disappeared from the system.");
41
41
  req.session.close();
42
42
  } else {
43
43
  next(new Error("Unhandled storage error code: "+err));
@@ -30,6 +30,16 @@ export function getObjIdFromParams(req: Request): {
30
30
  );
31
31
  }
32
32
 
33
+ export function getMsgIdFromParams(req: Request): {
34
+ msgId: string; msgIdParseErr?: string;
35
+ } {
36
+ const msgId = req.params.msgId;
37
+ return ((!!msgId && base64urlSafe.allCharsFromAlphabet(msgId)) ?
38
+ { msgId } :
39
+ { msgId: undefined as any, msgIdParseErr: "Bad message id" }
40
+ );
41
+ }
42
+
33
43
  export function replyWithErr(status: number, msg: string, res: Response, reqToDrainBytesFrom?: Request): void {
34
44
  if (reqToDrainBytesFrom) {
35
45
  attachByteDrainToRequest(reqToDrainBytesFrom);
@@ -23,6 +23,7 @@ import { Redirect } from './start-session';
23
23
  import { checkAndTransformAddress } from '../../../lib-common/canonical-address';
24
24
  import * as confUtil from '../../../lib-server/conf-util';
25
25
  import { replyWithErr } from '../../resources/utils';
26
+ import { base64urlSafe } from '../../../lib-common/buffer-utils';
26
27
 
27
28
  /**
28
29
  * This creates a session restart route handler.
@@ -84,7 +85,11 @@ export function restartSession(
84
85
  }
85
86
 
86
87
  // check message id
87
- if (typeof msgId !== 'string') {
88
+ if ((typeof msgId !== 'string') || !msgId || !base64urlSafe.allCharsFromAlphabet(msgId)) {
89
+ console.log(
90
+ `msgId ->`, msgId, '\n',
91
+ `!base64urlSafe.allCharsFromAlphabet(msgId) ->`, !base64urlSafe.allCharsFromAlphabet(msgId)
92
+ );
88
93
  return replyWithErr(ERR_SC.malformed, "Message id is either missing, or is malformed", res);
89
94
  }
90
95
 
@@ -19,14 +19,18 @@ import { RequestHandler } from 'express';
19
19
  import { SC as recipSC, MsgRetrieval } from '../../resources/recipients';
20
20
  import { msgMetadata as api, ERR_SC } from '../../../lib-common/service-api/asmail/retrieval';
21
21
  import { Request } from '../../resources/sessions';
22
- import { replyWithErr } from '../../resources/utils';
22
+ import { getMsgIdFromParams, replyWithErr } from '../../resources/utils';
23
23
 
24
24
  export function getMsgMeta(
25
25
  getMsgMetaFunc: MsgRetrieval['getMsgMeta']
26
26
  ): RequestHandler {
27
27
  return async (req: Request, res, next) => {
28
28
  const userId = req.session.params.userId;
29
- const msgId: string = req.params.msgId;
29
+
30
+ const { msgId, msgIdParseErr } = getMsgIdFromParams(req);
31
+ if (msgIdParseErr) {
32
+ return replyWithErr(ERR_SC.malformed, msgIdParseErr, res, req);
33
+ }
30
34
 
31
35
  try {
32
36
  const meta = await getMsgMetaFunc(userId, msgId);
@@ -21,7 +21,7 @@ import { GetObjQueryOpts, ERR_SC, msgObj as api, HTTP_HEADER } from '../../../li
21
21
  import { Request } from '../../resources/sessions';
22
22
  import { errWithCause } from '../../../lib-common/exceptions/error';
23
23
  import { EMPTY_BUFFER } from '../../../lib-common/buffer-utils';
24
- import { getObjIdFromParams, replyWithErr } from '../../resources/utils';
24
+ import { getMsgIdFromParams, getObjIdFromParams, replyWithErr } from '../../resources/utils';
25
25
 
26
26
  function extractQueryOptions(req: Request): undefined|{
27
27
  header: boolean; limit: number|undefined; ofs: number;
@@ -52,7 +52,11 @@ export function getMsgObj(
52
52
  return async (req: Request, res, next) => {
53
53
 
54
54
  const userId = req.session.params.userId;
55
- const msgId: string = req.params.msgId;
55
+
56
+ const { msgId, msgIdParseErr } = getMsgIdFromParams(req);
57
+ if (msgIdParseErr) {
58
+ return replyWithErr(ERR_SC.malformed, msgIdParseErr, res, req);
59
+ }
56
60
 
57
61
  const { objId, objIdParseErr } = getObjIdFromParams(req);
58
62
  if (objIdParseErr) {
@@ -19,12 +19,16 @@ import { RequestHandler } from 'express';
19
19
  import { SC as recipSC, MsgRetrieval } from '../../resources/recipients';
20
20
  import { rmMsg as api, ERR_SC } from '../../../lib-common/service-api/asmail/retrieval';
21
21
  import { Request } from '../../resources/sessions';
22
- import { replyWithErr } from '../../resources/utils';
22
+ import { getMsgIdFromParams, replyWithErr } from '../../resources/utils';
23
23
 
24
24
  export function deleteMsg(delMsgFunc: MsgRetrieval['deleteMsg']): RequestHandler {
25
25
  return async (req: Request, res, next) => {
26
26
  const userId = req.session.params.userId;
27
- const msgId: string = req.params.msgId;
27
+
28
+ const { msgId, msgIdParseErr } = getMsgIdFromParams(req);
29
+ if (msgIdParseErr) {
30
+ return replyWithErr(ERR_SC.malformed, msgIdParseErr, res, req);
31
+ }
28
32
 
29
33
  try {
30
34
  await delMsgFunc(userId, msgId);
@@ -37,13 +37,17 @@ export function setTestCertsAndDNS(
37
37
 
38
38
  // inject dns mock
39
39
  const dnsRecs: DnsTxtRecords = {};
40
+ const reportAddress = `report@${
41
+ thisSrvLoc.includes(':') ? thisSrvLoc.substring(0, thisSrvLoc.indexOf(':')) : thisSrvLoc
42
+ }`;
40
43
  for (const domain of domains) {
41
44
  dnsRecs[domain] = [
42
45
  [ 'asmail', '=', `${thisSrvLoc}/asmail` ], // one record in DNS TXT
43
46
  [
44
47
  'mailerid=', `${thisSrvLoc}/mailerid`,
45
48
  `3nstorage=${thisSrvLoc}/3nstorage`
46
- ] // two 3NWeb records in one DNS TXT record
49
+ ], // two 3NWeb records in one DNS TXT record
50
+ [ `report=${reportAddress}` ]
47
51
  // XXX add other life-like records
48
52
  ];
49
53
  }
@@ -25,7 +25,6 @@ import { certify as certApi }
25
25
  import { user as midUser } from '../../lib-common/mid-sigs-NaCl-Ed';
26
26
  import { doPubKeyLogin, User } from './pkl';
27
27
  import { bytesSync as randomBytes } from '../../lib-common/random-node';
28
- import { parse as parseUrl } from 'url';
29
28
 
30
29
  export { User } from './pkl';
31
30
 
@@ -106,7 +105,7 @@ export async function doMailerIdLogin(loginUrl: string, user: User):
106
105
  responseType: 'json',
107
106
  sessionId
108
107
  };
109
- let serviceDomain = parseUrl(loginUrl).hostname;
108
+ let serviceDomain = (new URL(loginUrl)).hostname;
110
109
  if (!serviceDomain) { throw new Error(
111
110
  `Cannot parse hostname from login url ${loginUrl}`); }
112
111
  let req: authSession.Request = {
@@ -23,7 +23,7 @@ import { makeSessionEncryptor, SessionEncryptor }
23
23
  from '../../lib-common/session-encryptor';
24
24
  import { doJsonRequest, RequestOpts, doBinaryRequest }
25
25
  from './xhr-utils';
26
- import { parse as parseUrl, resolve as resolveUrl } from 'url';
26
+ import { resolve as resolveUrl } from 'url';
27
27
  import { bytesEqual } from './bytes-equal';
28
28
 
29
29
  export interface User {
@@ -36,8 +36,7 @@ specs.definition = (setup: () => TestSetup) => (() => {
36
36
  beforeAllAsync(async () => {
37
37
  user2 = setup().user2;
38
38
  const deliveryUrl = await setup().asmailServer.getDeliveryUrl();
39
- initialSession = await startSessionAndSendMsgObjs(
40
- deliveryUrl, user2.id, msg);
39
+ initialSession = await startSessionAndSendMsgObjs(deliveryUrl, user2.id, msg);
41
40
  reqOpts = {
42
41
  url: resolveUrl(deliveryUrl, api.URL_END),
43
42
  method: 'POST',
@@ -74,7 +73,7 @@ specs.definition = (setup: () => TestSetup) => (() => {
74
73
  async () => {
75
74
  const req: api.Request = {
76
75
  recipient: user2.id,
77
- msgId: 'unknown message'
76
+ msgId: 'unknown_message'
78
77
  };
79
78
  const rep = await doJsonRequest<api.Reply>(reqOpts, req);
80
79
  expect(rep.status).withContext('status for unknown message').toBe(api.SC.unknownMsg);
@@ -50,14 +50,13 @@ export const msg: Msg = {
50
50
 
51
51
  export async function startSessionAndSendMsgObjs(deliveryUrl: string,
52
52
  recipient: string, msg: Msg): Promise<DeliveryInfo> {
53
- const sessInfo = await startMsgDelivery(deliveryUrl,
53
+ const sessInfo = await startMsgDelivery(
54
+ deliveryUrl,
54
55
  { recipient },
55
- { pid: msg.cryptoMeta.pid,
56
- objIds: [ msg.msgObjs[0].objId, msg.msgObjs[1].objId ] });
57
- await sendMsgObj(deliveryUrl, sessInfo.sessionId, msg.msgObjs[0],
58
- sessInfo.maxChunkSize);
59
- await sendMsgObj(deliveryUrl, sessInfo.sessionId, msg.msgObjs[1],
60
- sessInfo.maxChunkSize);
56
+ { pid: msg.cryptoMeta.pid, objIds: [ msg.msgObjs[0].objId, msg.msgObjs[1].objId ] }
57
+ );
58
+ await sendMsgObj(deliveryUrl, sessInfo.sessionId, msg.msgObjs[0], sessInfo.maxChunkSize);
59
+ await sendMsgObj(deliveryUrl, sessInfo.sessionId, msg.msgObjs[1], sessInfo.maxChunkSize);
61
60
  return sessInfo;
62
61
  }
63
62
 
@@ -22,7 +22,7 @@ import { startMidSession, provisionMidSigner, User } from '../libs-for-tests/mai
22
22
  import { expectNonAcceptanceOfBadJsonRequest, expectNonAcceptanceOfBadSessionId } from './requests';
23
23
  import * as mid from '../../lib-common/mid-sigs-NaCl-Ed';
24
24
  import { bytesSync as randomBytes } from '../../lib-common/random-node';
25
- import { parse as parseUrl, resolve as resolveUrl } from 'url';
25
+ import { resolve as resolveUrl } from 'url';
26
26
 
27
27
  export function midLoginSpecs(
28
28
  loginUrl: () => string,
@@ -86,7 +86,7 @@ export function midLoginSpecs(
86
86
  sessionId
87
87
  };
88
88
 
89
- const serviceDomain = parseUrl(loginUrl()).hostname;
89
+ const serviceDomain = (new URL(loginUrl())).hostname;
90
90
  if (!serviceDomain) { throw new Error(
91
91
  `Cannot get hostname from ${loginUrl()}`); }
92
92
  const req: authSession.Request = {