spec-3nweb-server 1.7.14 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2016, 2020 3NSoft Inc.
3
+ Copyright (C) 2015 - 2016, 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
@@ -35,8 +35,8 @@ function setupStaticStorageEntryRoute(app) {
35
35
  path = path + '/';
36
36
  }
37
37
  const json = {
38
- "owner": path + PATHS.owner.substring(1),
39
- "shared": path + PATHS.shared.substring(1)
38
+ owner: path + PATHS.owner.substring(1),
39
+ shared: path + PATHS.shared.substring(1)
40
40
  };
41
41
  // the following implicitly sets content type application/json
42
42
  res.status(200).json(json);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2017, 2022, 2024 3NSoft Inc.
3
+ Copyright (C) 2015 - 2017, 2022, 2024 - 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,10 +33,10 @@ const archive_obj_version_1 = require("./routes/owner/archive-obj-version");
33
33
  const get_obj_status_1 = require("./routes/owner/get-obj-status");
34
34
  const api = require("../lib-common/service-api/3nstorage/owner");
35
35
  const mid_access_1 = require("../lib-server/mid-access");
36
+ const WS_PING_PERIOD_MILLIS = 2 * 60 * 1000;
36
37
  function makeOwnerStorageApp(domain, sessions, users, midAuthorizer) {
37
38
  const app = new app_1.AppWithWSs();
38
- const setupLoginRoutes = (app, urlPrefix) => (0, mid_access_1.addMailerIdLoginRoutes)(app, domain, urlPrefix, sessions, users.exists, midAuthorizer);
39
- setHttpPart(app.http, setupLoginRoutes, sessions, users);
39
+ setHttpPart(app.http, domain, sessions, users, midAuthorizer);
40
40
  setWSPart(app, sessions, users);
41
41
  return app;
42
42
  }
@@ -55,7 +55,7 @@ function makeOwnerStorageForLocker(sessions, users) {
55
55
  }
56
56
  exports.makeOwnerStorageForLocker = makeOwnerStorageForLocker;
57
57
  function setWSPart(app, sessions, users) {
58
- const sockets = new app_1.UserSockets(sessions.ensureAuthorizedSessionForSocketStart());
58
+ const sockets = new app_1.UserSockets(sessions.ensureAuthorizedSessionForSocketStart(), WS_PING_PERIOD_MILLIS);
59
59
  const storageEvents = new server_events_1.ServerEvents(undefined, api.events.all, sockets.socketGetter);
60
60
  // give events ipc to both ends
61
61
  sockets.addSocketIPC(storageEvents);
@@ -63,10 +63,10 @@ function setWSPart(app, sessions, users) {
63
63
  app.addWS(api.wsEventChannel.URL_END, sockets);
64
64
  }
65
65
  const MAX_CHUNK_SIZE = '0.5mb';
66
- function setHttpPart(app, setupLoginRoutes, sessions, users) {
66
+ function setHttpPart(app, domain, sessions, users, midAuthorizer) {
67
67
  app.disable('etag');
68
68
  // Login
69
- setupLoginRoutes(app, '/' + api.midLogin.URL_PART);
69
+ (0, mid_access_1.addMailerIdLoginRoutes)(app, domain, '/' + api.midLogin.URL_PART, sessions, users.exists, midAuthorizer);
70
70
  // *** Require authorized session for everything below ***
71
71
  app.use(sessions.ensureAuthorizedSession());
72
72
  app.post('/' + api.closeSession.URL_END, (0, body_parsers_1.emptyBody)(), (0, close_1.closeSession)());
@@ -38,9 +38,9 @@ function setupStaticEntryRoute(app) {
38
38
  path = path + '/';
39
39
  }
40
40
  const json = {
41
- "delivery": path + PATHS.delivery.substring(1),
42
- "retrieval": path + PATHS.retrieval.substring(1),
43
- "config": path + PATHS.config.substring(1)
41
+ delivery: path + PATHS.delivery.substring(1),
42
+ retrieval: path + PATHS.retrieval.substring(1),
43
+ config: path + PATHS.config.substring(1)
44
44
  };
45
45
  // the following implicitly sets content type application/json
46
46
  res.status(200).json(json);
@@ -75,9 +75,11 @@ export declare class Inbox extends UserFiles<InboxParams> {
75
75
  completeMsgDelivery(msgId: string): Promise<void>;
76
76
  private areAllMsgObjsComplete;
77
77
  /**
78
+ * @param fromTS
79
+ * @param toTS
78
80
  * @return a promise, resolvable to a list of available message ids.
79
81
  */
80
- getMsgIds(): Promise<retrievalApi.listMsgs.Reply>;
82
+ getMsgIds(fromTS: number | undefined, toTS: number | undefined): Promise<retrievalApi.listMsgs.Reply>;
81
83
  /**
82
84
  * This method returns parameters of an incomplete message, identified
83
85
  * by a given id.
@@ -237,10 +237,31 @@ class Inbox extends user_files_1.UserFiles {
237
237
  return true;
238
238
  }
239
239
  /**
240
+ * @param fromTS
241
+ * @param toTS
240
242
  * @return a promise, resolvable to a list of available message ids.
241
243
  */
242
- getMsgIds() {
243
- return fs.readdir(this.metas.readyMsgsFolder);
244
+ async getMsgIds(fromTS, toTS) {
245
+ // XXX this isn't efficient, and needs sqlite-powered index
246
+ const lst = await fs.readdir(this.metas.readyMsgsFolder);
247
+ if ((fromTS === undefined) && (toTS === undefined)) {
248
+ return lst;
249
+ }
250
+ const filteredLst = [];
251
+ for (const msgId of lst) {
252
+ try {
253
+ const { deliveryStart } = await this.metas.get(msgId, true);
254
+ if (fromTS && (deliveryStart < fromTS)) {
255
+ continue;
256
+ }
257
+ if (toTS && (toTS < deliveryStart)) {
258
+ continue;
259
+ }
260
+ filteredLst.push(msgId);
261
+ }
262
+ catch (exc) { }
263
+ }
264
+ return filteredLst;
244
265
  }
245
266
  /**
246
267
  * This method returns parameters of an incomplete message, identified
@@ -79,7 +79,7 @@ export interface MsgRetrieval {
79
79
  * This returns a promise, resolvable to array with ids of available
80
80
  * messages. Rejected promise may have a string error code from SC.
81
81
  */
82
- getMsgIds: (userId: string) => Promise<retrievalApi.listMsgs.Reply>;
82
+ getMsgIds: (userId: string, fromTS: number | undefined, toTS: number | undefined) => Promise<retrievalApi.listMsgs.Reply>;
83
83
  /**
84
84
  * This returns a promise, resolvable to message meta.
85
85
  * Rejected promise may have a string error code from SC.
@@ -284,9 +284,9 @@ function makeRecipients(rootFolder, writeBufferSize, readBufferSize) {
284
284
  Object.freeze(delivery);
285
285
  const retrieval = {
286
286
  exists: config.exists,
287
- getMsgIds: async (userId) => {
287
+ getMsgIds: async (userId, fromTS, toTS) => {
288
288
  const inbox = await getInbox(userId);
289
- return inbox.getMsgIds();
289
+ return inbox.getMsgIds(fromTS, toTS);
290
290
  },
291
291
  getMsgMeta: async (userId, msgId) => {
292
292
  const inbox = await getInbox(userId);
@@ -27,6 +27,7 @@ const remove_message_1 = require("./routes/retrieval/remove-message");
27
27
  const get_message_obj_1 = require("./routes/retrieval/get-message-obj");
28
28
  const api = require("../lib-common/service-api/asmail/retrieval");
29
29
  const mid_access_1 = require("../lib-server/mid-access");
30
+ const WS_PING_PERIOD_MILLIS = 2 * 60 * 1000;
30
31
  function makeApp(domain, sessions, recipients, midAuthorizer) {
31
32
  const app = new app_1.AppWithWSs();
32
33
  setHttpPart(app.http, domain, sessions, recipients, midAuthorizer);
@@ -35,9 +36,8 @@ function makeApp(domain, sessions, recipients, midAuthorizer) {
35
36
  }
36
37
  exports.makeApp = makeApp;
37
38
  function setWSPart(app, sessions, recipients) {
38
- const sockets = new app_1.UserSockets(sessions.ensureAuthorizedSessionForSocketStart());
39
- const mailEvents = new server_events_1.ServerEvents(undefined, [api.msgRecievedCompletely.EVENT_NAME,
40
- api.msgMainObjRecieved.EVENT_NAME], sockets.socketGetter);
39
+ const sockets = new app_1.UserSockets(sessions.ensureAuthorizedSessionForSocketStart(), WS_PING_PERIOD_MILLIS);
40
+ const mailEvents = new server_events_1.ServerEvents(undefined, [api.msgRecievedCompletely.EVENT_NAME, api.msgMainObjRecieved.EVENT_NAME], sockets.socketGetter);
41
41
  // give events ipc to both ends
42
42
  sockets.addSocketIPC(mailEvents);
43
43
  recipients.setMailEventsSink(mailEvents.eventsSink);
@@ -46,11 +46,11 @@ function setWSPart(app, sessions, recipients) {
46
46
  function setHttpPart(app, domain, sessions, recipients, midAuthorizer) {
47
47
  app.disable('etag');
48
48
  // Login
49
- (0, mid_access_1.addMailerIdLoginRoutes)(app, domain, '/' + api.midLogin.URL_PART, sessions, recipients.exists, midAuthorizer);
49
+ (0, mid_access_1.addMailerIdLoginRoutes)(app, domain, '/' + api.midLogin.MID_URL_PART, sessions, recipients.exists, midAuthorizer);
50
50
  // *** Require authorized session for everything below ***
51
51
  app.use(sessions.ensureAuthorizedSession());
52
52
  app.post('/' + api.closeSession.URL_END, (0, body_parsers_1.emptyBody)(), (0, close_1.closeSession)());
53
- app.get('/' + api.listMsgs.URL_END, (0, list_messages_1.listMsgIds)(recipients.getMsgIds));
53
+ app.get('/' + api.listMsgs.EXPRESS_URL_END, (0, list_messages_1.listMsgIds)(recipients.getMsgIds));
54
54
  app.get('/' + api.msgMetadata.EXPRESS_URL_END, (0, get_message_meta_1.getMsgMeta)(recipients.getMsgMeta));
55
55
  app.delete('/' + api.rmMsg.EXPRESS_URL_END, (0, remove_message_1.deleteMsg)(recipients.deleteMsg));
56
56
  app.get('/' + api.msgObj.EXPRESS_URL_END, (0, get_message_obj_1.getMsgObj)(recipients.getObj));
@@ -22,8 +22,14 @@ const retrieval_1 = require("../../../lib-common/service-api/asmail/retrieval");
22
22
  function listMsgIds(listMsgIdsFunc) {
23
23
  return async (req, res, next) => {
24
24
  const userId = req.session.params.userId;
25
+ const opts = extractQueryOptions(req);
26
+ if (!opts) {
27
+ res.status(retrieval_1.ERR_SC.malformed).send("Bad query parameters");
28
+ return;
29
+ }
25
30
  try {
26
- const msgIds = await listMsgIdsFunc(userId);
31
+ const { from, to } = opts;
32
+ const msgIds = await listMsgIdsFunc(userId, from, to);
27
33
  res.status(retrieval_1.listMsgs.SC.ok).json(msgIds);
28
34
  }
29
35
  catch (err) {
@@ -41,4 +47,16 @@ function listMsgIds(listMsgIdsFunc) {
41
47
  };
42
48
  }
43
49
  exports.listMsgIds = listMsgIds;
50
+ function extractQueryOptions(req) {
51
+ const query = req.query;
52
+ const from = (query.from ? parseInt(query.from) : undefined);
53
+ if ((from !== undefined) && (isNaN(from) || (from <= 0))) {
54
+ return;
55
+ }
56
+ const to = (query.to ? parseInt(query.to) : undefined);
57
+ if ((to !== undefined) && (isNaN(to) || (to <= 0))) {
58
+ return;
59
+ }
60
+ return { from, to };
61
+ }
44
62
  Object.freeze(exports);
@@ -432,9 +432,9 @@ class EventsReceivingSide extends RequestingSide {
432
432
  * name, to which listener is attached.
433
433
  */
434
434
  this.listeners = new map_of_sets_1.MapOfSets();
435
- this.channels = new IpcEventChannels((ipcChannel) => this.makeRequest(ipc_api_1.events.subscribe.REQ_NAME, ipcChannel)
436
- .catch(err => this.completeEvent(ipcChannel, err)), (ipcChannel) => this.makeRequest(ipc_api_1.events.unsubscribe.REQ_NAME, ipcChannel)
437
- .catch(err => { }));
435
+ this.channels = new IpcEventChannels(ipcChannel => this.makeRequest(ipc_api_1.events.subscribe.REQ_NAME, ipcChannel)
436
+ .catch(err => this.completeEvent(ipcChannel, err)), ipcChannel => this.makeRequest(ipc_api_1.events.unsubscribe.REQ_NAME, ipcChannel)
437
+ .catch(noop));
438
438
  }
439
439
  handleMsg(env) {
440
440
  if (env.type === 'event') {
@@ -581,6 +581,7 @@ class IpcEventChannels {
581
581
  }
582
582
  Object.freeze(IpcEventChannels.prototype);
583
583
  Object.freeze(IpcEventChannels);
584
+ function noop() { }
584
585
  function makeSubscribingClient(channel, comm) {
585
586
  return (new EventsReceivingSide(channel, comm)).wrap();
586
587
  }
@@ -0,0 +1,5 @@
1
+ export interface StorageRootRoute {
2
+ owner?: string;
3
+ shared?: string;
4
+ config?: string;
5
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2025 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -12,13 +12,20 @@ export declare const ERR_SC: {
12
12
  server: number;
13
13
  };
14
14
  export declare namespace midLogin {
15
- const URL_PART = "login/mailerid/";
15
+ const MID_URL_PART = "login/mailerid/";
16
+ const START_URL_END: string;
17
+ const AUTH_URL_END: string;
16
18
  }
17
19
  export declare namespace closeSession {
18
20
  const URL_END = "close-session";
19
21
  }
22
+ export interface ListMsgsOpts {
23
+ from?: number;
24
+ to?: number;
25
+ }
20
26
  export declare namespace listMsgs {
21
- const URL_END = "msg/ids";
27
+ const EXPRESS_URL_END = "msg/ids";
28
+ function genUrlEnd(opts?: ListMsgsOpts): string;
22
29
  interface Reply extends Array<string> {
23
30
  }
24
31
  const SC: {
@@ -35,7 +42,7 @@ export declare namespace rmMsg {
35
42
  }
36
43
  export interface ObjSize {
37
44
  header: number;
38
- segments: number;
45
+ segments: number | undefined;
39
46
  }
40
47
  export interface ObjStatus {
41
48
  completed?: boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015, 2017 3NSoft Inc.
3
+ Copyright (C) 2015, 2017, 2019, 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
@@ -13,8 +13,7 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>.
17
- */
16
+ this program. If not, see <http://www.gnu.org/licenses/>. */
18
17
  Object.defineProperty(exports, "__esModule", { value: true });
19
18
  exports.msgMainObjRecieved = exports.msgRecievedCompletely = exports.wsEventChannel = exports.msgObj = exports.sanitizedMeta = exports.msgMetadata = exports.rmMsg = exports.listMsgs = exports.closeSession = exports.midLogin = exports.ERR_SC = exports.HTTP_HEADER = exports.BIN_TYPE = void 0;
20
19
  /**
@@ -38,7 +37,9 @@ exports.ERR_SC = {
38
37
  Object.freeze(exports.ERR_SC);
39
38
  var midLogin;
40
39
  (function (midLogin) {
41
- midLogin.URL_PART = 'login/mailerid/';
40
+ midLogin.MID_URL_PART = 'login/mailerid/';
41
+ midLogin.START_URL_END = midLogin.MID_URL_PART + midApi.startSession.URL_END;
42
+ midLogin.AUTH_URL_END = midLogin.MID_URL_PART + midApi.authSession.URL_END;
42
43
  })(midLogin = exports.midLogin || (exports.midLogin = {}));
43
44
  Object.freeze(midLogin);
44
45
  var closeSession;
@@ -48,7 +49,12 @@ var closeSession;
48
49
  Object.freeze(closeSession);
49
50
  var listMsgs;
50
51
  (function (listMsgs) {
51
- listMsgs.URL_END = 'msg/ids';
52
+ listMsgs.EXPRESS_URL_END = 'msg/ids';
53
+ function genUrlEnd(opts) {
54
+ let optStr = (opts ? '?' + (0, querystring_1.stringify)(opts) : '');
55
+ return `msg/ids${optStr}`;
56
+ }
57
+ listMsgs.genUrlEnd = genUrlEnd;
52
58
  listMsgs.SC = {
53
59
  ok: 200,
54
60
  };
@@ -144,4 +150,7 @@ var msgMainObjRecieved;
144
150
  msgMainObjRecieved.EVENT_NAME = 'msg-main-obj-received';
145
151
  })(msgMainObjRecieved = exports.msgMainObjRecieved || (exports.msgMainObjRecieved = {}));
146
152
  Object.freeze(msgMainObjRecieved);
153
+ // XXX add event about message removal
154
+ // it is useful in multi-device case, pass implicit implicit signal that will
155
+ // have context-specific meaning.
147
156
  Object.freeze(exports);
@@ -0,0 +1,5 @@
1
+ export interface ASMailRootRoute {
2
+ delivery?: string;
3
+ retrieval?: string;
4
+ config?: string;
5
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2025 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ import { SignedLoad } from "../../jwkeys";
2
+ export interface MailerIdRootRoute {
3
+ "current-cert": SignedLoad;
4
+ "previous-certs": SignedLoad[];
5
+ provisioning: string;
6
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2025 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -8,13 +8,14 @@ import { CheckSession, SessionParams } from '../resources/sessions';
8
8
  export type HttpServer = http.Server | https.Server;
9
9
  export declare class UserSockets {
10
10
  checkSession: CheckSession<SessionParams>;
11
+ private readonly pingMillis;
11
12
  /**
12
13
  * Only connections that match this path are accepted.
13
14
  */
14
15
  path: string;
15
16
  private clients;
16
17
  private ipcs;
17
- constructor(checkSession: CheckSession<SessionParams>);
18
+ constructor(checkSession: CheckSession<SessionParams>, pingMillis: number);
18
19
  disconnect(): void;
19
20
  handleConnection(userId: string, client: WebSocket): void;
20
21
  addSocketIPC(ipc: SocketIPCs): void;
@@ -124,8 +124,9 @@ function ensureSlashesOnFront(path) {
124
124
  return path;
125
125
  }
126
126
  class UserSockets {
127
- constructor(checkSession) {
127
+ constructor(checkSession, pingMillis) {
128
128
  this.checkSession = checkSession;
129
+ this.pingMillis = pingMillis;
129
130
  /**
130
131
  * Only connections that match this path are accepted.
131
132
  */
@@ -140,7 +141,7 @@ class UserSockets {
140
141
  for (const ipc of this.ipcs) {
141
142
  ipc.attachIPC(userId, client);
142
143
  }
143
- let pinger = new PingSender(client);
144
+ let pinger = new PingSender(client, this.pingMillis);
144
145
  client.on('close', () => {
145
146
  this.clients.remove(userId, client);
146
147
  pinger.close();
@@ -162,10 +163,12 @@ exports.UserSockets = UserSockets;
162
163
  Object.freeze(UserSockets.prototype);
163
164
  Object.freeze(UserSockets);
164
165
  class PingSender {
165
- constructor(client) {
166
+ constructor(client, pingMillis) {
167
+ this.pingMillis = pingMillis;
166
168
  this.outstandingPong = 0;
167
169
  this.client = client;
168
- this.fourMinCheck = setInterval(() => this.recurrentPing(), 4 * 60 * 1000);
170
+ this.pongTimeoutMillis = Math.round(this.pingMillis / 2);
171
+ this.fourMinCheck = setInterval(() => this.recurrentPing(), this.pingMillis);
169
172
  this.fourMinCheck.unref();
170
173
  }
171
174
  recurrentPing() {
@@ -175,7 +178,7 @@ class PingSender {
175
178
  if (this.outstandingPong === 0) {
176
179
  }
177
180
  else if (this.outstandingPong === 1) {
178
- setTimeout(() => this.additionalPing(), 2 * 60 * 1000).unref();
181
+ setTimeout(() => this.additionalPing(), this.pongTimeoutMillis).unref();
179
182
  }
180
183
  else {
181
184
  this.client.close();
@@ -59,7 +59,7 @@ function makeMailerIdApp(rootFolder, domain, certFile, errLogger) {
59
59
  const json = {
60
60
  "current-cert": certifier.getRootCert(),
61
61
  "previous-certs": certifier.getPrevCerts(),
62
- "provisioning": path + PROVISIONING_PATH.substring(1)
62
+ provisioning: path + PROVISIONING_PATH.substring(1)
63
63
  };
64
64
  res.status(200).json(json); // content type application/json
65
65
  });
@@ -7,6 +7,8 @@ export interface Configurations {
7
7
  asmail?: boolean;
8
8
  storage?: boolean;
9
9
  mailerId?: boolean;
10
+ };
11
+ auxiliaryServices?: {
10
12
  locker?: boolean;
11
13
  };
12
14
  servicesConnect?: {
package/build/services.js CHANGED
@@ -26,6 +26,7 @@ const signup_app_1 = require("./signup/signup-app");
26
26
  const error_handler_1 = require("./lib-server/middleware/error-handler");
27
27
  const locker_app_1 = require("./locker/locker-app");
28
28
  function servicesApp(conf, errLogger, logSetup) {
29
+ var _a;
29
30
  if (!conf.enabledServices || (typeof conf.enabledServices !== 'object')) {
30
31
  throw new Error('Missing enabled-services sections in confs.');
31
32
  }
@@ -54,7 +55,7 @@ function servicesApp(conf, errLogger, logSetup) {
54
55
  console.log(`Enabled 3NStorage service with provider domain ${conf.domain}`);
55
56
  }
56
57
  }
57
- if (conf.enabledServices.locker) {
58
+ if ((_a = conf.auxiliaryServices) === null || _a === void 0 ? void 0 : _a.locker) {
58
59
  app.use('/locker', (0, locker_app_1.makeLockerApp)(conf.rootFolder, (errLogger === 'console') ? (0, error_handler_1.makeErrLoggerToConsole)('Locker') : errLogger));
59
60
  if (logSetup === 'console') {
60
61
  console.log(`Enabled Locker service`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-3nweb-server",
3
- "version": "1.7.14",
3
+ "version": "1.8.1",
4
4
  "description": "3NWeb spec server.",
5
5
  "main": "build/lib.js",
6
6
  "types": "build/lib.d.ts",