spec-3nweb-server 1.7.0 → 1.7.5
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/3nstorage-app.d.ts +4 -1
- package/build/3nstorage/3nstorage-app.js +18 -9
- package/build/3nstorage/owner.d.ts +3 -2
- package/build/3nstorage/owner.js +39 -32
- package/build/3nstorage/resources/sessions.d.ts +2 -2
- package/build/3nstorage/resources/sessions.js +2 -1
- package/build/3nstorage/resources/store.d.ts +6 -6
- package/build/3nstorage/resources/store.js +3 -12
- package/build/3nstorage/resources/users.d.ts +16 -16
- package/build/3nstorage/resources/users.js +13 -16
- package/build/3nstorage/shared.d.ts +2 -6
- package/build/3nstorage/shared.js +5 -9
- package/build/asmail/asmail-app.d.ts +1 -1
- package/build/asmail/asmail-app.js +3 -3
- package/build/asmail/config.d.ts +2 -6
- package/build/asmail/config.js +20 -12
- package/build/asmail/delivery.d.ts +2 -6
- package/build/asmail/delivery.js +0 -6
- package/build/asmail/resources/delivery-sessions.d.ts +3 -3
- package/build/asmail/resources/delivery-sessions.js +1 -2
- package/build/asmail/resources/inbox.d.ts +26 -35
- package/build/asmail/resources/inbox.js +15 -59
- package/build/asmail/resources/recipients.d.ts +39 -21
- package/build/asmail/resources/recipients.js +62 -22
- package/build/asmail/resources/sessions.d.ts +2 -2
- package/build/asmail/retrieval.d.ts +2 -2
- package/build/asmail/retrieval.js +11 -18
- package/build/asmail/routes/delivery/sender-authorization.d.ts +1 -1
- package/build/asmail/routes/delivery/start-session.d.ts +1 -1
- package/build/config/letsencrypt.d.ts +1 -1
- package/build/config/signup.d.ts +1 -1
- package/build/config/signup.js +2 -1
- package/build/lib-common/assert.js +2 -1
- package/build/lib-common/buffer-utils.js +2 -1
- package/build/lib-common/byte-streaming/common.d.ts +2 -2
- package/build/lib-common/byte-streaming/common.js +16 -16
- package/build/lib-common/bytes-equal.js +2 -1
- package/build/lib-common/exceptions/error.js +2 -1
- package/build/lib-common/exceptions/file.d.ts +1 -1
- package/build/lib-common/exceptions/file.js +2 -1
- package/build/lib-common/exceptions/http.js +2 -1
- package/build/lib-common/ipc/generic-ipc.d.ts +7 -7
- package/build/lib-common/ipc/generic-ipc.js +20 -20
- package/build/lib-common/ipc/ws-ipc.js +2 -1
- package/build/lib-common/json-equal.js +2 -1
- package/build/lib-common/json-utils.js +2 -1
- package/build/lib-common/jwkeys.js +2 -1
- package/build/lib-common/map-of-sets.js +2 -1
- package/build/lib-common/mid-sigs-NaCl-Ed.js +2 -1
- package/build/lib-common/objs-on-disk/file-layout.d.ts +4 -4
- package/build/lib-common/objs-on-disk/file-layout.js +2 -1
- package/build/lib-common/objs-on-disk/obj-file.js +2 -1
- package/build/lib-common/objs-on-disk/utils.d.ts +3 -3
- package/build/lib-common/objs-on-disk/v1-obj-file-format.js +2 -1
- package/build/lib-common/processes.d.ts +1 -1
- package/build/lib-common/processes.js +2 -1
- package/build/lib-common/random-node.js +2 -1
- package/build/lib-common/service-api/3nstorage/owner.d.ts +1 -3
- package/build/lib-common/service-api/3nstorage/owner.js +2 -4
- package/build/lib-common/service-api/asmail/config.d.ts +1 -3
- package/build/lib-common/service-api/asmail/config.js +4 -5
- package/build/lib-common/service-api/asmail/delivery.js +2 -1
- package/build/lib-common/service-api/asmail/retrieval.d.ts +1 -3
- package/build/lib-common/service-api/asmail/retrieval.js +3 -4
- package/build/lib-common/service-api/ipc-api.d.ts +6 -6
- package/build/lib-common/service-api/ipc-api.js +2 -1
- package/build/lib-common/service-api/locker.d.ts +17 -0
- package/build/lib-common/service-api/locker.js +31 -0
- package/build/lib-common/service-api/mailer-id/login.js +2 -1
- package/build/lib-common/service-api/mailer-id/provisioning.d.ts +3 -4
- package/build/lib-common/service-api/mailer-id/provisioning.js +3 -12
- package/build/lib-common/service-api/pub-key-login.js +2 -1
- package/build/lib-common/service-api/web-socket-base.d.ts +1 -1
- package/build/lib-common/service-api/web-socket-base.js +2 -1
- package/build/lib-common/session-encryptor.js +2 -1
- package/build/lib-common/time-window-cache.js +2 -1
- package/build/lib-server/mid-access.d.ts +5 -0
- package/build/lib-server/mid-access.js +28 -0
- package/build/lib-server/middleware/body-parsers.d.ts +7 -7
- package/build/lib-server/middleware/body-parsers.js +14 -14
- package/build/lib-server/middleware/error-handler.d.ts +1 -1
- package/build/lib-server/pkl-access.d.ts +4 -0
- package/build/lib-server/pkl-access.js +28 -0
- package/build/lib-server/resources/dns.d.ts +1 -1
- package/build/lib-server/resources/dns.js +2 -1
- package/build/lib-server/resources/mailerid-authorizer.js +5 -6
- package/build/lib-server/resources/server-data-folders.d.ts +1 -0
- package/build/lib-server/resources/server-data-folders.js +9 -4
- package/build/{mailerId/resources/compute-login-dhshared-key.js → lib-server/resources/server-key-for-pkl-challenge.js} +5 -5
- package/build/lib-server/resources/sessions.d.ts +2 -2
- package/build/lib-server/resources/sessions.js +7 -7
- package/build/lib-server/resources/user-files.d.ts +4 -4
- package/build/lib-server/resources/user-files.js +4 -2
- package/build/lib-server/routes/pub-key-login/start-exchange.d.ts +4 -4
- package/build/lib-server/routes/sessions/close.js +2 -1
- package/build/lib-server/routes/sessions/mid-auth.d.ts +1 -1
- package/build/lib-server/routes/sessions/start.d.ts +4 -4
- package/build/lib-server/web-sockets/app.d.ts +1 -1
- package/build/lib-server/web-sockets/app.js +8 -9
- package/build/lib-server/web-sockets/server-events.d.ts +1 -1
- package/build/lib-server/web-sockets/server-events.js +1 -2
- package/build/lib.d.ts +1 -2
- package/build/lib.js +2 -5
- package/build/locker/locker-app.d.ts +3 -0
- package/build/locker/locker-app.js +41 -0
- package/build/locker/resources/lockers.d.ts +0 -0
- package/build/{lib-common/binding.js → locker/resources/lockers.js} +3 -10
- package/build/locker/resources/sessions.d.ts +9 -0
- package/build/locker/resources/sessions.js +33 -0
- package/build/locker/routes/create-locker.d.ts +4 -0
- package/build/locker/routes/create-locker.js +37 -0
- package/build/mailerId/mailerId-app.d.ts +1 -1
- package/build/mailerId/mailerId-app.js +12 -11
- package/build/mailerId/resources/certifier.d.ts +1 -1
- package/build/mailerId/resources/sessions.d.ts +1 -1
- package/build/mailerId/routes/certify.js +2 -1
- package/build/main.js +1 -1
- package/build/mock/dns.js +3 -4
- package/build/mock/mock-as-child-proc.js +2 -2
- package/build/mock/node-child-ipc.d.ts +2 -2
- package/build/mock/node-child-ipc.js +2 -1
- package/build/mock/run-in-proc.js +2 -2
- package/build/mock/tls-options.js +2 -1
- package/build/services.d.ts +2 -1
- package/build/services.js +22 -11
- package/build/{admin → signup}/resources/users.d.ts +3 -3
- package/build/{admin → signup}/resources/users.js +3 -4
- package/build/{admin/admin-app.d.ts → signup/signup-app.d.ts} +1 -1
- package/build/{admin/admin-app.js → signup/signup-app.js} +6 -16
- package/build/{admin → signup}/signup-tokens.d.ts +1 -1
- package/package.json +3 -3
- package/build/config/from-env.d.ts +0 -9
- package/build/config/from-env.js +0 -117
- package/build/lib-common/binding.d.ts +0 -1
- package/build/run.d.ts +0 -1
- package/build/run.js +0 -45
- /package/build/{mailerId/resources/compute-login-dhshared-key.d.ts → lib-server/resources/server-key-for-pkl-challenge.d.ts} +0 -0
- /package/build/{admin → signup}/routes/add.d.ts +0 -0
- /package/build/{admin → signup}/routes/add.js +0 -0
- /package/build/{admin → signup}/routes/get-available-addresses.d.ts +0 -0
- /package/build/{admin → signup}/routes/get-available-addresses.js +0 -0
- /package/build/{admin → signup}/routes/get-available-domains.d.ts +0 -0
- /package/build/{admin → signup}/routes/get-available-domains.js +0 -0
- /package/build/{admin → signup}/signup-tokens.js +0 -0
|
@@ -13,19 +13,10 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.serviceRoot = exports.certify =
|
|
19
|
-
/**
|
|
20
|
-
* This defines request interfaces for MailerId certificate provisioning.
|
|
21
|
-
*/
|
|
22
|
-
const pklApi = require("../pub-key-login");
|
|
23
|
-
var pkl;
|
|
24
|
-
(function (pkl) {
|
|
25
|
-
pkl.START_URL_END = pklApi.start.URL_END;
|
|
26
|
-
pkl.COMPL_URL_END = pklApi.complete.URL_END;
|
|
27
|
-
})(pkl = exports.pkl || (exports.pkl = {}));
|
|
28
|
-
Object.freeze(pkl);
|
|
19
|
+
exports.serviceRoot = exports.certify = void 0;
|
|
29
20
|
var certify;
|
|
30
21
|
(function (certify) {
|
|
31
22
|
certify.URL_END = 'certify';
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.complete = exports.start = exports.ERR_SC = void 0;
|
|
19
20
|
/**
|
|
@@ -16,7 +16,7 @@ export interface EventEnvelope<T> {
|
|
|
16
16
|
eventChannel: string;
|
|
17
17
|
eventPayload: T;
|
|
18
18
|
}
|
|
19
|
-
export
|
|
19
|
+
export type Envelope = RequestEnvelope<any> | ReplyEnvelope<any> | EventEnvelope<any>;
|
|
20
20
|
export declare namespace events {
|
|
21
21
|
const MISSED_EVENTS_CHANNEL = "missed-events";
|
|
22
22
|
const SUBSCRIBE_REQ_NAME = "subscribe";
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.errorReplyTo = exports.events = void 0;
|
|
19
20
|
var events;
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.makeSessionEncryptor = void 0;
|
|
19
20
|
/**
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.TimeWindowCache = void 0;
|
|
19
20
|
class TimeWindowCache {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Factory as SessionsFactory, SessionParams } from './resources/sessions';
|
|
2
|
+
import { MidAuthorizer } from "./routes/sessions/mid-auth";
|
|
3
|
+
import { Express } from 'express';
|
|
4
|
+
export type AccountExists = (id: string) => Promise<boolean>;
|
|
5
|
+
export declare function addMailerIdLoginRoutes(app: Express, domain: string, urlPrefix: string, sessions: SessionsFactory<SessionParams>, accountExists: AccountExists, midAuthorizer: MidAuthorizer): void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (C) 2024 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 });
|
|
19
|
+
exports.addMailerIdLoginRoutes = void 0;
|
|
20
|
+
const body_parsers_1 = require("./middleware/body-parsers");
|
|
21
|
+
const start_1 = require("./routes/sessions/start");
|
|
22
|
+
const mid_auth_1 = require("./routes/sessions/mid-auth");
|
|
23
|
+
const api = require("../lib-common/service-api/mailer-id/login");
|
|
24
|
+
function addMailerIdLoginRoutes(app, domain, urlPrefix, sessions, accountExists, midAuthorizer) {
|
|
25
|
+
app.post(urlPrefix + api.startSession.URL_END, sessions.checkSession(), (0, body_parsers_1.json)('1kb'), (0, start_1.startSession)(accountExists, sessions.generate));
|
|
26
|
+
app.post(urlPrefix + api.authSession.URL_END, sessions.ensureOpenedSession(), (0, body_parsers_1.json)('4kb'), (0, mid_auth_1.midLogin)(domain, midAuthorizer));
|
|
27
|
+
}
|
|
28
|
+
exports.addMailerIdLoginRoutes = addMailerIdLoginRoutes;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare function attachByteDrainToRequest(req:
|
|
1
|
+
import { Request, RequestHandler } from 'express';
|
|
2
|
+
export declare function attachByteDrainToRequest(req: Request): void;
|
|
3
3
|
/**
|
|
4
4
|
* Use this for empty-body POST and PUT routes, as it does sanitization, and
|
|
5
5
|
* prevents hanging requests, because nothing drains data.
|
|
6
6
|
* @return a middleware function that ensures empty body in requests.
|
|
7
7
|
*/
|
|
8
|
-
export declare function emptyBody():
|
|
8
|
+
export declare function emptyBody(): RequestHandler;
|
|
9
9
|
/**
|
|
10
10
|
* @param req
|
|
11
11
|
* @param expectedLen is an expected non-zero length of a binary body.
|
|
@@ -13,14 +13,14 @@ export declare function emptyBody(): express.RequestHandler;
|
|
|
13
13
|
* @return a promise, resolvable to request's body bytes, parsed from a request
|
|
14
14
|
* object.
|
|
15
15
|
*/
|
|
16
|
-
export declare function parseBinaryBodyWithExpectedSize(req:
|
|
16
|
+
export declare function parseBinaryBodyWithExpectedSize(req: Request, expectedLen: number): Promise<Uint8Array>;
|
|
17
17
|
/**
|
|
18
18
|
* @param maxSize is a maximum allowed body length, given as number of bytes,
|
|
19
19
|
* or string parameter for kb/mb's.
|
|
20
20
|
* @return middleware function, that places all request bytes into Buffer,
|
|
21
21
|
* placed into usual body field of request object.
|
|
22
22
|
*/
|
|
23
|
-
export declare function binary(maxSize: string | number):
|
|
23
|
+
export declare function binary(maxSize: string | number): RequestHandler;
|
|
24
24
|
/**
|
|
25
25
|
* @param maxSize is a maximum allowed body length, given as number of bytes,
|
|
26
26
|
* or string parameter for kb/mb's.
|
|
@@ -29,11 +29,11 @@ export declare function binary(maxSize: string | number): express.RequestHandler
|
|
|
29
29
|
* @return middleware function, that parses all request bytes as JSON, placing
|
|
30
30
|
* result into usual body field of request object.
|
|
31
31
|
*/
|
|
32
|
-
export declare function json(maxSize: string | number, allowNonObject?: boolean):
|
|
32
|
+
export declare function json(maxSize: string | number, allowNonObject?: boolean): RequestHandler;
|
|
33
33
|
/**
|
|
34
34
|
* @param maxSize is a maximum allowed body length, given as number of bytes, or
|
|
35
35
|
* string parameter for kb/mb's.
|
|
36
36
|
* @return middleware function, that parses all request bytes as utf8 text,
|
|
37
37
|
* placing result into usual body field of request object.
|
|
38
38
|
*/
|
|
39
|
-
export declare function textPlain(maxSize: string | number):
|
|
39
|
+
export declare function textPlain(maxSize: 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
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.textPlain = exports.json = exports.binary = exports.parseBinaryBodyWithExpectedSize = exports.emptyBody = exports.attachByteDrainToRequest = void 0;
|
|
19
20
|
const conf_util_1 = require("../conf-util");
|
|
@@ -30,22 +31,19 @@ const TYPES = {
|
|
|
30
31
|
json: 'application/json',
|
|
31
32
|
bin: 'application/octet-stream'
|
|
32
33
|
};
|
|
33
|
-
const noop = {
|
|
34
|
-
onData: (chunk) => { },
|
|
35
|
-
onEnd: () => { }
|
|
36
|
-
};
|
|
37
34
|
function attachByteDrainToRequest(req) {
|
|
38
|
-
req.on('data', noop
|
|
39
|
-
req.on('end', noop
|
|
35
|
+
req.on('data', noop);
|
|
36
|
+
req.on('end', noop);
|
|
40
37
|
}
|
|
41
38
|
exports.attachByteDrainToRequest = attachByteDrainToRequest;
|
|
39
|
+
function noop() { }
|
|
42
40
|
/**
|
|
43
41
|
* Use this for empty-body POST and PUT routes, as it does sanitization, and
|
|
44
42
|
* prevents hanging requests, because nothing drains data.
|
|
45
43
|
* @return a middleware function that ensures empty body in requests.
|
|
46
44
|
*/
|
|
47
45
|
function emptyBody() {
|
|
48
|
-
return (req,
|
|
46
|
+
return (req, _res, next) => {
|
|
49
47
|
attachByteDrainToRequest(req);
|
|
50
48
|
// get and check Content-Length
|
|
51
49
|
const contentLength = parseInt(req.get(HTTP_HEADER.contentLength), 10);
|
|
@@ -195,16 +193,18 @@ exports.binary = binary;
|
|
|
195
193
|
* result into usual body field of request object.
|
|
196
194
|
*/
|
|
197
195
|
function json(maxSize, allowNonObject) {
|
|
198
|
-
return byteCollector(maxSize, TYPES.json, (req,
|
|
196
|
+
return byteCollector(maxSize, TYPES.json, (req, _res, next) => {
|
|
199
197
|
try {
|
|
200
198
|
const bodyAsStr = req.body.toString('utf8');
|
|
201
|
-
req.body =
|
|
199
|
+
req.body = ((bodyAsStr === '') ?
|
|
200
|
+
undefined :
|
|
201
|
+
JSON.parse(bodyAsStr));
|
|
202
202
|
}
|
|
203
203
|
catch (err) {
|
|
204
204
|
return next((0, error_handler_1.makeErr)(400, "Request body cannot be interpreted as JSON."));
|
|
205
205
|
}
|
|
206
|
-
if (!allowNonObject
|
|
207
|
-
(!req.body || (typeof req.body !== 'object'))) {
|
|
206
|
+
if (!allowNonObject
|
|
207
|
+
&& (!req.body || (typeof req.body !== 'object'))) {
|
|
208
208
|
return next((0, error_handler_1.makeErr)(400, "Request body is not a JSON object."));
|
|
209
209
|
}
|
|
210
210
|
next();
|
|
@@ -218,7 +218,7 @@ exports.json = json;
|
|
|
218
218
|
* placing result into usual body field of request object.
|
|
219
219
|
*/
|
|
220
220
|
function textPlain(maxSize) {
|
|
221
|
-
return byteCollector(maxSize, TYPES.plain, (req,
|
|
221
|
+
return byteCollector(maxSize, TYPES.plain, (req, _res, next) => {
|
|
222
222
|
try {
|
|
223
223
|
req.body = req.body.toString('utf8');
|
|
224
224
|
}
|
|
@@ -11,6 +11,6 @@ export interface HttpError extends ErrorWithCause {
|
|
|
11
11
|
* @param cause
|
|
12
12
|
*/
|
|
13
13
|
export declare function makeErr(code: number, msg: string, cause?: any): HttpError;
|
|
14
|
-
export
|
|
14
|
+
export type ErrLogger = (err: any, req: Request) => void;
|
|
15
15
|
export declare function makeErrHandler(log?: ErrLogger): ErrorRequestHandler;
|
|
16
16
|
export declare function makeErrLoggerToConsole(srvName: string): ErrLogger;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Express } from 'express';
|
|
2
|
+
import { Factory as SessionsFactory } from './resources/sessions';
|
|
3
|
+
import { ComputeDHSharedKey, GetUserPKeyAndKeyGenParams, SessionParams } from './routes/pub-key-login/start-exchange';
|
|
4
|
+
export declare function addPKLLoginRoutes(app: Express, urlPrefix: string, getUserParamsAndKey: GetUserPKeyAndKeyGenParams, sessions: SessionsFactory<SessionParams>, computeDHSharedKey: ComputeDHSharedKey): void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (C) 2024 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 });
|
|
19
|
+
exports.addPKLLoginRoutes = void 0;
|
|
20
|
+
const body_parsers_1 = require("./middleware/body-parsers");
|
|
21
|
+
const start_exchange_1 = require("./routes/pub-key-login/start-exchange");
|
|
22
|
+
const complete_exchange_1 = require("./routes/pub-key-login/complete-exchange");
|
|
23
|
+
const api = require("../lib-common/service-api/pub-key-login");
|
|
24
|
+
function addPKLLoginRoutes(app, urlPrefix, getUserParamsAndKey, sessions, computeDHSharedKey) {
|
|
25
|
+
app.post(urlPrefix + api.start.URL_END, sessions.checkSession(), (0, body_parsers_1.json)('1kb'), (0, start_exchange_1.startPKLogin)(getUserParamsAndKey, sessions.generate, computeDHSharedKey));
|
|
26
|
+
app.post(urlPrefix + api.complete.URL_END, sessions.ensureOpenedSession(), (0, body_parsers_1.binary)('1kb'), (0, complete_exchange_1.completePKLogin)());
|
|
27
|
+
}
|
|
28
|
+
exports.addPKLLoginRoutes = addPKLLoginRoutes;
|
|
@@ -2,5 +2,5 @@ export declare const SC: {
|
|
|
2
2
|
RECORDS_MISSING: string;
|
|
3
3
|
DOMAIN_NOT_FOUND: string;
|
|
4
4
|
};
|
|
5
|
-
export
|
|
5
|
+
export type ServiceLabel = 'asmail' | 'mailerid' | '3nstorage';
|
|
6
6
|
export declare function get3NWebRecords(address: string, serviceLabel: ServiceLabel): Promise<string>;
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.get3NWebRecords = exports.SC = void 0;
|
|
19
20
|
const dns = require("dns");
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.validator = void 0;
|
|
19
20
|
const https = require("https");
|
|
@@ -62,9 +63,7 @@ function getRootCert(serviceURL) {
|
|
|
62
63
|
// TODO need to add caching of certs using domain->(kid->cert)
|
|
63
64
|
// (this will speed things up)
|
|
64
65
|
function validator() {
|
|
65
|
-
return (rpDomain, sessionId, userId, assertion, userCert, provCert) =>
|
|
66
|
-
return validate(rpDomain, sessionId, userId, assertion, userCert, provCert);
|
|
67
|
-
};
|
|
66
|
+
return (rpDomain, sessionId, userId, assertion, userCert, provCert) => validate(rpDomain, sessionId, userId, assertion, userCert, provCert);
|
|
68
67
|
}
|
|
69
68
|
exports.validator = validator;
|
|
70
69
|
async function validate(rpDomain, sessionId, userId, assertion, userCert, provCert) {
|
|
@@ -86,8 +85,8 @@ async function validate(rpDomain, sessionId, userId, assertion, userCert, provCe
|
|
|
86
85
|
// get root certificate and check the whole chain
|
|
87
86
|
const rootCert = await getRootCert(serviceURL);
|
|
88
87
|
const assertInfo = mid.relyingParty.verifyAssertion(assertion, { user: userCert, prov: provCert, root: rootCert }, issuer, validAt);
|
|
89
|
-
if ((assertInfo.relyingPartyDomain === rpDomain)
|
|
90
|
-
(assertInfo.sessionId === sessionId)) {
|
|
88
|
+
if ((assertInfo.relyingPartyDomain === rpDomain)
|
|
89
|
+
&& (assertInfo.sessionId === sessionId)) {
|
|
91
90
|
return true;
|
|
92
91
|
}
|
|
93
92
|
else {
|
|
@@ -36,6 +36,7 @@ export interface UserDataTree {
|
|
|
36
36
|
export declare function treeInRootFolder(rootFolder: string): RootDataTree;
|
|
37
37
|
export declare function tokensInRootFolder(rootFolder: string): string;
|
|
38
38
|
export declare function userDataInRootFolder(root: string, userId: string): string;
|
|
39
|
+
export declare function lockerDataInRootFolder(root: string, lockerId: string): string;
|
|
39
40
|
export declare function treeInDefaultsFolder(defaults: string): DefaultsDataTree;
|
|
40
41
|
export declare function treeInUserFolder(userFoder: string): UserDataTree;
|
|
41
42
|
export declare function createFolderTree(structure: RootDataTree | UserDataTree | DefaultsDataTree | FolderDef): Promise<void>;
|
|
@@ -16,17 +16,17 @@
|
|
|
16
16
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.createFolderTreeSync = exports.createFolderTree = exports.treeInUserFolder = exports.treeInDefaultsFolder = exports.userDataInRootFolder = exports.tokensInRootFolder = exports.treeInRootFolder = exports.addressToFName = void 0;
|
|
19
|
+
exports.createFolderTreeSync = exports.createFolderTree = exports.treeInUserFolder = exports.treeInDefaultsFolder = exports.lockerDataInRootFolder = exports.userDataInRootFolder = exports.tokensInRootFolder = exports.treeInRootFolder = exports.addressToFName = void 0;
|
|
20
20
|
const buffer_utils_1 = require("../../lib-common/buffer-utils");
|
|
21
21
|
const canonical_address_1 = require("../../lib-common/canonical-address");
|
|
22
22
|
const path_1 = require("path");
|
|
23
23
|
const fs_1 = require("fs");
|
|
24
24
|
function addressToFName(address) {
|
|
25
|
-
return
|
|
25
|
+
return idStringToFName((0, canonical_address_1.toCanonicalAddress)(address));
|
|
26
26
|
}
|
|
27
27
|
exports.addressToFName = addressToFName;
|
|
28
|
-
function
|
|
29
|
-
return buffer_utils_1.base64urlSafe.pack(buffer_utils_1.utf8.pack(
|
|
28
|
+
function idStringToFName(id) {
|
|
29
|
+
return buffer_utils_1.base64urlSafe.pack(buffer_utils_1.utf8.pack(id));
|
|
30
30
|
}
|
|
31
31
|
function treeInRootFolder(rootFolder) {
|
|
32
32
|
const defaults = (0, path_1.join)(rootFolder, 'defaults');
|
|
@@ -47,6 +47,11 @@ function userDataInRootFolder(root, userId) {
|
|
|
47
47
|
return (0, path_1.join)(root, 'users', addressToFName(userId));
|
|
48
48
|
}
|
|
49
49
|
exports.userDataInRootFolder = userDataInRootFolder;
|
|
50
|
+
// XXX use this instead of userDataInRootFolder for locker storage
|
|
51
|
+
function lockerDataInRootFolder(root, lockerId) {
|
|
52
|
+
return (0, path_1.join)(root, 'lockers', idStringToFName(lockerId));
|
|
53
|
+
}
|
|
54
|
+
exports.lockerDataInRootFolder = lockerDataInRootFolder;
|
|
50
55
|
function treeInDefaultsFolder(defaults) {
|
|
51
56
|
const mail = (0, path_1.join)(defaults, 'mail');
|
|
52
57
|
const mailParams = (0, path_1.join)(mail, 'params');
|
|
@@ -22,14 +22,14 @@ exports.calcNaClBoxSharedKey = void 0;
|
|
|
22
22
|
*/
|
|
23
23
|
const ecma_nacl_1 = require("ecma-nacl");
|
|
24
24
|
const random = require("../../lib-common/random-node");
|
|
25
|
-
// XXX update the key from time-to-time
|
|
26
|
-
const
|
|
27
|
-
const
|
|
25
|
+
// XXX update the key from time-to-time, and this must be single instance
|
|
26
|
+
const skeyForPKLChallenge = random.bytesSync(32);
|
|
27
|
+
const pkeyForPKLChallenge = ecma_nacl_1.box.generate_pubkey(skeyForPKLChallenge);
|
|
28
28
|
function calcNaClBoxSharedKey(userPubKey) {
|
|
29
|
-
const dhsharedKey = ecma_nacl_1.box.calc_dhshared_key(userPubKey,
|
|
29
|
+
const dhsharedKey = ecma_nacl_1.box.calc_dhshared_key(userPubKey, skeyForPKLChallenge);
|
|
30
30
|
return {
|
|
31
31
|
dhsharedKey: dhsharedKey,
|
|
32
|
-
serverPubKey:
|
|
32
|
+
serverPubKey: pkeyForPKLChallenge
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
exports.calcNaClBoxSharedKey = calcNaClBoxSharedKey;
|
|
@@ -22,8 +22,8 @@ export interface Request<T> extends express.Request {
|
|
|
22
22
|
export interface BaseRequest<T> extends http.IncomingMessage {
|
|
23
23
|
session: Session<T>;
|
|
24
24
|
}
|
|
25
|
-
export
|
|
26
|
-
export
|
|
25
|
+
export type CheckSession<T> = (req: BaseRequest<T>) => Promise<boolean>;
|
|
26
|
+
export type GenerateSession<T> = () => Promise<Session<T>>;
|
|
27
27
|
export interface Factory<T> {
|
|
28
28
|
generate: GenerateSession<T>;
|
|
29
29
|
ensureAuthorizedSession(): express.RequestHandler;
|
|
@@ -13,10 +13,10 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.wrapFactory = exports.BaseSessionFactory = exports.SESSION_ID_HEADER = void 0;
|
|
19
|
-
const binding_1 = require("../../lib-common/binding");
|
|
20
20
|
// Constant custom header
|
|
21
21
|
exports.SESSION_ID_HEADER = "X-Session-Id";
|
|
22
22
|
const LOW_CASED_SESSION_ID_HEADER = exports.SESSION_ID_HEADER.toLowerCase();
|
|
@@ -171,11 +171,11 @@ Object.freeze(BaseSessionFactory.prototype);
|
|
|
171
171
|
Object.freeze(BaseSessionFactory);
|
|
172
172
|
function wrapFactory(impl) {
|
|
173
173
|
const wrap = {
|
|
174
|
-
checkSession:
|
|
175
|
-
ensureAuthorizedSession:
|
|
176
|
-
ensureOpenedSession:
|
|
177
|
-
ensureAuthorizedSessionForSocketStart:
|
|
178
|
-
generate:
|
|
174
|
+
checkSession: impl.checkSession.bind(impl),
|
|
175
|
+
ensureAuthorizedSession: impl.ensureAuthorizedSession.bind(impl),
|
|
176
|
+
ensureOpenedSession: impl.ensureOpenedSession.bind(impl),
|
|
177
|
+
ensureAuthorizedSessionForSocketStart: impl.ensureAuthorizedSessionForSocketStart.bind(impl),
|
|
178
|
+
generate: impl.generate.bind(impl)
|
|
179
179
|
};
|
|
180
180
|
return wrap;
|
|
181
181
|
}
|
|
@@ -3,7 +3,7 @@ export declare const SC: {
|
|
|
3
3
|
USER_UNKNOWN: string;
|
|
4
4
|
};
|
|
5
5
|
export declare function addressToFName(address: string): string;
|
|
6
|
-
export declare abstract class UserFiles {
|
|
6
|
+
export declare abstract class UserFiles<ParamTypes extends object> {
|
|
7
7
|
readonly userId: string;
|
|
8
8
|
readonly path: string;
|
|
9
9
|
protected readonly fileWritingBufferSize: number;
|
|
@@ -12,10 +12,10 @@ export declare abstract class UserFiles {
|
|
|
12
12
|
ensureUserExistsOnDisk(): Promise<void>;
|
|
13
13
|
private commonInfoFolder;
|
|
14
14
|
getSpaceQuota(): Promise<number>;
|
|
15
|
-
getParam<
|
|
16
|
-
setParam<
|
|
15
|
+
getParam<P extends keyof ParamTypes>(paramFileName: P): Promise<ParamTypes[P]>;
|
|
16
|
+
protected setParam<P extends keyof ParamTypes>(paramFileName: P, param: ParamTypes[P]): Promise<void>;
|
|
17
17
|
}
|
|
18
|
-
export
|
|
18
|
+
export type ObjPipe = (outStream: NodeJS.WritableStream) => Promise<void>;
|
|
19
19
|
export interface ObjReader {
|
|
20
20
|
len: number;
|
|
21
21
|
/**
|
|
@@ -70,10 +70,12 @@ class UserFiles {
|
|
|
70
70
|
return readJsonFile((0, path_1.join)(this.commonInfoFolder(), 'quota'));
|
|
71
71
|
}
|
|
72
72
|
getParam(paramFileName) {
|
|
73
|
-
|
|
73
|
+
const filePath = (0, path_1.join)(this.path, 'params', paramFileName);
|
|
74
|
+
return readJsonFile(filePath);
|
|
74
75
|
}
|
|
75
76
|
setParam(paramFileName, param) {
|
|
76
|
-
|
|
77
|
+
const filePath = (0, path_1.join)(this.path, 'params', paramFileName);
|
|
78
|
+
return fs.writeFile(filePath, JSON.stringify(param), { encoding: 'utf8', flag: 'w' });
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
exports.UserFiles = UserFiles;
|
|
@@ -10,7 +10,7 @@ export interface SessionParams extends UserParams {
|
|
|
10
10
|
sessionKey: Uint8Array;
|
|
11
11
|
serverVerificationBytes: Uint8Array;
|
|
12
12
|
}
|
|
13
|
-
export
|
|
13
|
+
export type Request = SessReq<SessionParams>;
|
|
14
14
|
export interface UserPKeyAndKeyGenParams {
|
|
15
15
|
pkey: Uint8Array;
|
|
16
16
|
params?: any;
|
|
@@ -22,7 +22,7 @@ export interface UserPKeyAndKeyGenParams {
|
|
|
22
22
|
* Else, if incoming id is not ok, undefined is returned.
|
|
23
23
|
* @params initUserId is a an incoming string, that should be an id
|
|
24
24
|
*/
|
|
25
|
-
export
|
|
25
|
+
export type CheckAndTransformUserId = (initUserId: string) => string | undefined;
|
|
26
26
|
/**
|
|
27
27
|
* This returns a promise of user public key and related parameters.
|
|
28
28
|
* If user is not found, undefined is returned.
|
|
@@ -30,8 +30,8 @@ export declare type CheckAndTransformUserId = (initUserId: string) => string | u
|
|
|
30
30
|
* @param kid is a key id that should be used at login. Undefined value
|
|
31
31
|
* indicates that default key should be used.
|
|
32
32
|
*/
|
|
33
|
-
export
|
|
34
|
-
export
|
|
33
|
+
export type GetUserPKeyAndKeyGenParams = (userId: string, kid: string | undefined) => Promise<UserPKeyAndKeyGenParams | undefined>;
|
|
34
|
+
export type ComputeDHSharedKey = (userKey: Uint8Array) => {
|
|
35
35
|
dhsharedKey: Uint8Array;
|
|
36
36
|
serverPubKey: Uint8Array;
|
|
37
37
|
};
|
|
@@ -13,7 +13,8 @@
|
|
|
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/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.closeSession = void 0;
|
|
19
20
|
function closeSession() {
|
|
@@ -6,7 +6,7 @@ import { SignedLoad } from '../../../lib-common/jwkeys';
|
|
|
6
6
|
* Autherization failure may be due to either, invalid MailerId credentials, or
|
|
7
7
|
* due to other service's restriction(s) on users.
|
|
8
8
|
*/
|
|
9
|
-
export
|
|
9
|
+
export type MidAuthorizer = (rpDomain: string, sessionId: string, userId: string, mailerIdAssertion: SignedLoad, userCert: SignedLoad, provCert: SignedLoad) => Promise<boolean>;
|
|
10
10
|
/**
|
|
11
11
|
* @param relyingPartyDomain is a domain of service, for which this assertion
|
|
12
12
|
* check is done. Usually, it is this site's domain, which we set explicitly.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
2
|
import { GenerateSession, Request as SessionReq, SessionParams } from '../../resources/sessions';
|
|
3
|
-
export
|
|
3
|
+
export type Request = SessionReq<SessionParams>;
|
|
4
4
|
/**
|
|
5
5
|
* This function checks overall shape of a given user id, possibly
|
|
6
6
|
* transforming it to some canonical form, used by the service.
|
|
@@ -8,9 +8,9 @@ export declare type Request = SessionReq<SessionParams>;
|
|
|
8
8
|
* Else, if incoming id is not ok, undefined is returned.
|
|
9
9
|
* @params initUserId is a an incoming string, that should be an id
|
|
10
10
|
*/
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
11
|
+
export type CheckAndTransformUserId = (initUserId: string) => string | undefined;
|
|
12
|
+
export type UserExists = (userId: string) => Promise<boolean>;
|
|
13
|
+
export type Redirect = (userId: string) => Promise<string>;
|
|
14
14
|
/**
|
|
15
15
|
* This returns route handler that creates sessions for a given userId, with
|
|
16
16
|
* potential redirect for a named user.
|
|
@@ -5,7 +5,7 @@ import * as https from 'https';
|
|
|
5
5
|
import * as express from 'express';
|
|
6
6
|
import * as WebSocket from 'ws';
|
|
7
7
|
import { CheckSession, SessionParams } from '../resources/sessions';
|
|
8
|
-
export
|
|
8
|
+
export type HttpServer = http.Server | https.Server;
|
|
9
9
|
export declare class UserSockets {
|
|
10
10
|
checkSession: CheckSession<SessionParams>;
|
|
11
11
|
/**
|
|
@@ -21,7 +21,6 @@ const http = require("http");
|
|
|
21
21
|
const https = require("https");
|
|
22
22
|
const express = require("express");
|
|
23
23
|
const WebSocket = require("ws");
|
|
24
|
-
const binding_1 = require("../../lib-common/binding");
|
|
25
24
|
const map_of_sets_1 = require("../../lib-common/map-of-sets");
|
|
26
25
|
const url_1 = require("url");
|
|
27
26
|
const MAX_MSG_PAYLOAD = 4 * 1024;
|
|
@@ -57,9 +56,9 @@ class UserSocketsServer {
|
|
|
57
56
|
server,
|
|
58
57
|
clientTracking: true,
|
|
59
58
|
maxPayload: MAX_MSG_PAYLOAD,
|
|
60
|
-
verifyClient:
|
|
59
|
+
verifyClient: this.verifyClient.bind(this)
|
|
61
60
|
})
|
|
62
|
-
.on('connection',
|
|
61
|
+
.on('connection', this.handleConnection.bind(this))
|
|
63
62
|
.on('error', (err) => { console.error(err); });
|
|
64
63
|
}
|
|
65
64
|
disconnect() {
|
|
@@ -209,6 +208,12 @@ class PingSender {
|
|
|
209
208
|
Object.freeze(PingSender.prototype);
|
|
210
209
|
Object.freeze(PingSender);
|
|
211
210
|
class AppWithWSs {
|
|
211
|
+
get sockServer() {
|
|
212
|
+
if (!this.socks) {
|
|
213
|
+
this.socks = new UserSocketsServer();
|
|
214
|
+
}
|
|
215
|
+
return this.socks;
|
|
216
|
+
}
|
|
212
217
|
constructor(httpApp) {
|
|
213
218
|
this.server = undefined;
|
|
214
219
|
this.closingProc = undefined;
|
|
@@ -216,12 +221,6 @@ class AppWithWSs {
|
|
|
216
221
|
this.http = (httpApp ? httpApp : express());
|
|
217
222
|
Object.seal(this);
|
|
218
223
|
}
|
|
219
|
-
get sockServer() {
|
|
220
|
-
if (!this.socks) {
|
|
221
|
-
this.socks = new UserSocketsServer();
|
|
222
|
-
}
|
|
223
|
-
return this.socks;
|
|
224
|
-
}
|
|
225
224
|
addWS(path, socks) {
|
|
226
225
|
if (typeof path === 'string') {
|
|
227
226
|
socks.path = ensureSlashesOnFront(path);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as WebSocket from 'ws';
|
|
2
2
|
import { SocketIPCs } from './app';
|
|
3
|
-
export
|
|
3
|
+
export type EventsSink<T> = (userId: string, channel: string, event: T) => void;
|
|
4
4
|
export declare class ServerEvents<T> implements SocketIPCs {
|
|
5
5
|
ipcChannel: string | undefined;
|
|
6
6
|
private eventChannels;
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.ServerEvents = void 0;
|
|
20
20
|
const ws_ipc_1 = require("../../lib-common/ipc/ws-ipc");
|
|
21
|
-
const binding_1 = require("../../lib-common/binding");
|
|
22
21
|
class ServerEvents {
|
|
23
22
|
constructor(ipcChannel, eventChannels, getSocket) {
|
|
24
23
|
this.ipcChannel = ipcChannel;
|
|
@@ -49,7 +48,7 @@ class ServerEvents {
|
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
get eventsSink() {
|
|
52
|
-
return
|
|
51
|
+
return this.sendEvent.bind(this);
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
exports.ServerEvents = ServerEvents;
|