@radatek/microserver 3.0.5 → 3.0.6
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/microserver.d.ts +6 -22
- package/microserver.js +80 -71
- package/package.json +1 -1
package/microserver.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MicroServer
|
|
3
|
-
* @version 3.0.
|
|
3
|
+
* @version 3.0.6
|
|
4
4
|
* @package @radatek/microserver
|
|
5
5
|
* @copyright Darius Kisonas 2022
|
|
6
6
|
* @license MIT
|
|
@@ -86,7 +86,6 @@ export declare class ServerRequest<T = any> extends http.IncomingMessage {
|
|
|
86
86
|
rawBody: Buffer[];
|
|
87
87
|
/** Request raw body size */
|
|
88
88
|
rawBodySize: number;
|
|
89
|
-
private constructor();
|
|
90
89
|
/** Extend http.IncomingMessage */
|
|
91
90
|
static extend(req: http.IncomingMessage, res: http.ServerResponse, server: MicroServer): ServerRequest;
|
|
92
91
|
/** Check if request is ready */
|
|
@@ -115,7 +114,6 @@ export declare class ServerResponse<T = any> extends http.ServerResponse {
|
|
|
115
114
|
readonly req: ServerRequest<T>;
|
|
116
115
|
/** Should response be json */
|
|
117
116
|
isJson: boolean;
|
|
118
|
-
private constructor();
|
|
119
117
|
/** Extends http.ServerResponse */
|
|
120
118
|
static extend(res: http.ServerResponse): void;
|
|
121
119
|
/** Send error reponse */
|
|
@@ -329,8 +327,6 @@ export declare class WebSocket extends EventEmitter {
|
|
|
329
327
|
constructor(req: ServerRequest, options?: WebSocketOptions);
|
|
330
328
|
/** Close connection */
|
|
331
329
|
close(reason?: number, data?: Buffer): void;
|
|
332
|
-
/** Generate WebSocket frame from data */
|
|
333
|
-
static getFrame(data: number | string | Buffer | undefined, options?: any): Buffer;
|
|
334
330
|
/** Send data */
|
|
335
331
|
send(data: string | Buffer): void;
|
|
336
332
|
/** Send ping frame */
|
|
@@ -346,8 +342,7 @@ export declare class WebSocket extends EventEmitter {
|
|
|
346
342
|
export declare class WebSocketPlugin extends Plugin {
|
|
347
343
|
name: string;
|
|
348
344
|
constructor(options?: any, server?: MicroServer);
|
|
349
|
-
|
|
350
|
-
upgradeHandler(server: MicroServer, req: ServerRequest, socket: net.Socket, head: any): void;
|
|
345
|
+
upgradeHandler(server: MicroServer, req: ServerRequest, socket: net.Socket, head: any): any;
|
|
351
346
|
}
|
|
352
347
|
/** Trust proxy plugin, adds `req.ip` and `req.localip` */
|
|
353
348
|
export declare class TrustProxyPlugin extends Plugin {
|
|
@@ -584,22 +579,11 @@ export declare class Auth {
|
|
|
584
579
|
};
|
|
585
580
|
/** Encode token */
|
|
586
581
|
encode(data: string, expire?: number): string;
|
|
587
|
-
/**
|
|
588
|
-
* Check acl over authenticated user with: `id`, `group/*`, `*`
|
|
589
|
-
* @param {string} id - to authenticate: `id`, `group/id`, `model/action`, comma separated best: true => false => def
|
|
590
|
-
* @param {boolean} [def=false] - default access
|
|
591
|
-
*/
|
|
582
|
+
/** Check acl over authenticated user with: `id`, `group/*`, `*` */
|
|
592
583
|
acl(id: string, def?: boolean): boolean;
|
|
593
|
-
/**
|
|
594
|
-
* Authenticate user and setup cookie
|
|
595
|
-
* @param {string|UserInfo} usr - user id used with options.users to retrieve user object. User object must contain `id` and `acl` object (Ex. usr = {id:'usr', acl:{'users/*':true}})
|
|
596
|
-
* @param {string} [psw] - user password (if used for user authentication with options.users)
|
|
597
|
-
* @param {number} [expire] - expire time in seconds (default: options.expire)
|
|
598
|
-
*/
|
|
584
|
+
/** Generate token from user info */
|
|
599
585
|
token(usr: string | UserInfo | undefined, psw: string | undefined, expire?: number): Promise<string | undefined>;
|
|
600
|
-
/**
|
|
601
|
-
* Authenticate user and setup cookie
|
|
602
|
-
*/
|
|
586
|
+
/** Authenticate user and setup cookie */
|
|
603
587
|
login(usr: string | UserInfo | undefined, psw?: string, options?: {
|
|
604
588
|
expire?: number;
|
|
605
589
|
salt?: string;
|
|
@@ -937,4 +921,4 @@ export declare class MicroCollection<TSchema extends ModelSchema = any> {
|
|
|
937
921
|
modifiedCount: number;
|
|
938
922
|
}>;
|
|
939
923
|
}
|
|
940
|
-
|
|
924
|
+
export {};
|
package/microserver.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MicroServer
|
|
3
|
-
* @version 3.0.
|
|
3
|
+
* @version 3.0.6
|
|
4
4
|
* @package @radatek/microserver
|
|
5
5
|
* @copyright Darius Kisonas 2022
|
|
6
6
|
* @license MIT
|
|
@@ -116,8 +116,11 @@ export class ServerRequest extends http.IncomingMessage {
|
|
|
116
116
|
rawBody;
|
|
117
117
|
/** Request raw body size */
|
|
118
118
|
rawBodySize;
|
|
119
|
+
// @internal
|
|
119
120
|
_body;
|
|
121
|
+
// @internal
|
|
120
122
|
_isReady;
|
|
123
|
+
// @internal
|
|
121
124
|
constructor(res, server) {
|
|
122
125
|
super(new net.Socket());
|
|
123
126
|
ServerRequest.extend(this, res, server);
|
|
@@ -212,6 +215,7 @@ export class ServerRequest extends http.IncomingMessage {
|
|
|
212
215
|
export class ServerResponse extends http.ServerResponse {
|
|
213
216
|
/** Should response be json */
|
|
214
217
|
isJson;
|
|
218
|
+
// @internal
|
|
215
219
|
constructor(server) {
|
|
216
220
|
super(new http.IncomingMessage(new net.Socket()));
|
|
217
221
|
ServerRequest.extend(this.req, this, server);
|
|
@@ -365,9 +369,13 @@ export class MicroServer extends EventEmitter {
|
|
|
365
369
|
config;
|
|
366
370
|
/** Authorization object */
|
|
367
371
|
auth;
|
|
372
|
+
// @internal
|
|
368
373
|
_plugins = {};
|
|
374
|
+
// @internal
|
|
369
375
|
_stack = [];
|
|
376
|
+
// @internal
|
|
370
377
|
_router = new RouterPlugin();
|
|
378
|
+
// @internal
|
|
371
379
|
_worker = new Worker();
|
|
372
380
|
/** All sockets */
|
|
373
381
|
sockets;
|
|
@@ -499,6 +507,7 @@ export class MicroServer extends EventEmitter {
|
|
|
499
507
|
return this._worker.wait('listen');
|
|
500
508
|
}
|
|
501
509
|
/* bind middleware or create one from string like: 'redirect:302,https://redirect.to', 'error:422', 'param:name=value', 'acl:users/get', 'model:User', 'group:Users', 'user:admin' */
|
|
510
|
+
// @internal
|
|
502
511
|
_bind(fn) {
|
|
503
512
|
if (typeof fn === 'string') {
|
|
504
513
|
let name = fn;
|
|
@@ -683,6 +692,7 @@ export class MicroServer extends EventEmitter {
|
|
|
683
692
|
this._router.add(method, url, args.filter(o => o).map((o) => this._bind(o)), true);
|
|
684
693
|
return this._worker.endJob();
|
|
685
694
|
}
|
|
695
|
+
// @internal
|
|
686
696
|
async _plugin(plugin) {
|
|
687
697
|
if (plugin.handler) {
|
|
688
698
|
const middleware = plugin.handler.bind(plugin);
|
|
@@ -793,16 +803,23 @@ export class MicroServer extends EventEmitter {
|
|
|
793
803
|
}
|
|
794
804
|
// #region RouterPlugin
|
|
795
805
|
class RouterItem {
|
|
806
|
+
// @internal
|
|
796
807
|
_stack; // add if middlewares added if not last
|
|
808
|
+
// @internal
|
|
797
809
|
_next; // next middlewares
|
|
810
|
+
// @internal
|
|
798
811
|
_paramName; // param name if param is used
|
|
812
|
+
// @internal
|
|
799
813
|
_paramWild;
|
|
814
|
+
// @internal
|
|
800
815
|
_withParam; // next middlewares if param is used
|
|
816
|
+
// @internal
|
|
801
817
|
_last;
|
|
802
818
|
}
|
|
803
819
|
class RouterPlugin extends Plugin {
|
|
804
820
|
priority = 100;
|
|
805
821
|
name = 'router';
|
|
822
|
+
// @internal
|
|
806
823
|
_tree = {};
|
|
807
824
|
constructor() {
|
|
808
825
|
super();
|
|
@@ -852,6 +869,7 @@ class RouterPlugin extends Plugin {
|
|
|
852
869
|
node._stack.push(...middlewares);
|
|
853
870
|
}
|
|
854
871
|
}
|
|
872
|
+
// @internal
|
|
855
873
|
_getStack(path, treeItems) {
|
|
856
874
|
const out = [];
|
|
857
875
|
const segments = path.split('/').filter(s => s);
|
|
@@ -965,7 +983,9 @@ export class CorsPlugin extends Plugin {
|
|
|
965
983
|
export class MethodsPlugin extends Plugin {
|
|
966
984
|
priority = -90;
|
|
967
985
|
name = 'methods';
|
|
986
|
+
// @internal
|
|
968
987
|
_methods;
|
|
988
|
+
// @internal
|
|
969
989
|
_methodsIdx;
|
|
970
990
|
constructor(methods) {
|
|
971
991
|
super();
|
|
@@ -989,6 +1009,7 @@ export class MethodsPlugin extends Plugin {
|
|
|
989
1009
|
export class BodyPlugin extends Plugin {
|
|
990
1010
|
priority = -80;
|
|
991
1011
|
name = 'body';
|
|
1012
|
+
// @internal
|
|
992
1013
|
_maxBodySize;
|
|
993
1014
|
constructor(options) {
|
|
994
1015
|
super();
|
|
@@ -1043,7 +1064,9 @@ export class BodyPlugin extends Plugin {
|
|
|
1043
1064
|
export class UploadPlugin extends Plugin {
|
|
1044
1065
|
priority = -70;
|
|
1045
1066
|
name = 'upload';
|
|
1067
|
+
// @internal
|
|
1046
1068
|
_maxFileSize;
|
|
1069
|
+
// @internal
|
|
1047
1070
|
_uploadDir;
|
|
1048
1071
|
constructor(options) {
|
|
1049
1072
|
super();
|
|
@@ -1133,6 +1156,10 @@ export class UploadPlugin extends Plugin {
|
|
|
1133
1156
|
const safeWriteLength = buffer.length - lookahead;
|
|
1134
1157
|
if (safeWriteLength > 0) {
|
|
1135
1158
|
lastFile.size += safeWriteLength;
|
|
1159
|
+
if (lastFile.size > this._maxFileSize) {
|
|
1160
|
+
req.setReady(new ResponseError("file too big", 413));
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1136
1163
|
fileStream.write(buffer.subarray(0, safeWriteLength));
|
|
1137
1164
|
buffer = buffer.subarray(safeWriteLength);
|
|
1138
1165
|
}
|
|
@@ -1169,10 +1196,15 @@ const EMPTY_BUFFER = Buffer.alloc(0);
|
|
|
1169
1196
|
const DEFLATE_TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
|
|
1170
1197
|
/** WebSocket class */
|
|
1171
1198
|
export class WebSocket extends EventEmitter {
|
|
1199
|
+
// @internal
|
|
1172
1200
|
_socket;
|
|
1201
|
+
// @internal
|
|
1173
1202
|
_frame;
|
|
1203
|
+
// @internal
|
|
1174
1204
|
_buffers = [EMPTY_BUFFER];
|
|
1205
|
+
// @internal
|
|
1175
1206
|
_buffersLength = 0;
|
|
1207
|
+
// @internal
|
|
1176
1208
|
_options;
|
|
1177
1209
|
ready = false;
|
|
1178
1210
|
constructor(req, options) {
|
|
@@ -1191,7 +1223,7 @@ export class WebSocket extends EventEmitter {
|
|
|
1191
1223
|
const version = +(req.headers['sec-websocket-version'] || 0);
|
|
1192
1224
|
const extensions = req.headers['sec-websocket-extensions'];
|
|
1193
1225
|
const headers = [];
|
|
1194
|
-
if (!key ||
|
|
1226
|
+
if (!key || upgrade?.toLocaleLowerCase() !== 'websocket' || version !== 13) {
|
|
1195
1227
|
this._abort('Invalid WebSocket request', 400);
|
|
1196
1228
|
return;
|
|
1197
1229
|
}
|
|
@@ -1202,12 +1234,12 @@ export class WebSocket extends EventEmitter {
|
|
|
1202
1234
|
headers.push(header);
|
|
1203
1235
|
this._options.deflate = true;
|
|
1204
1236
|
}
|
|
1205
|
-
this.ready = true;
|
|
1206
1237
|
this._upgrade(key, headers, () => {
|
|
1207
|
-
|
|
1238
|
+
this.ready = true;
|
|
1208
1239
|
this.emit('open');
|
|
1209
1240
|
});
|
|
1210
1241
|
}
|
|
1242
|
+
// @internal
|
|
1211
1243
|
_upgrade(key, headers = [], cb) {
|
|
1212
1244
|
const digest = crypto.createHash('sha1')
|
|
1213
1245
|
.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
|
|
@@ -1238,45 +1270,6 @@ export class WebSocket extends EventEmitter {
|
|
|
1238
1270
|
}
|
|
1239
1271
|
return this._sendFrame(0x88, data || EMPTY_BUFFER, () => this._socket.destroy());
|
|
1240
1272
|
}
|
|
1241
|
-
/** Generate WebSocket frame from data */
|
|
1242
|
-
static getFrame(data, options) {
|
|
1243
|
-
let msgType = 8;
|
|
1244
|
-
let dataLength = 0;
|
|
1245
|
-
if (typeof data === 'string') {
|
|
1246
|
-
msgType = 1;
|
|
1247
|
-
dataLength = Buffer.byteLength(data, 'utf8');
|
|
1248
|
-
}
|
|
1249
|
-
else if (data instanceof Buffer) {
|
|
1250
|
-
msgType = 2;
|
|
1251
|
-
dataLength = data.length;
|
|
1252
|
-
}
|
|
1253
|
-
else if (typeof data === 'number') {
|
|
1254
|
-
msgType = data;
|
|
1255
|
-
}
|
|
1256
|
-
const headerSize = 2 + (dataLength < 126 ? 0 : dataLength < 65536 ? 2 : 8) + (dataLength && options?.mask ? 4 : 0);
|
|
1257
|
-
const frame = Buffer.allocUnsafe(headerSize + dataLength);
|
|
1258
|
-
frame[0] = 0x80 | msgType;
|
|
1259
|
-
frame[1] = dataLength > 65535 ? 127 : dataLength > 125 ? 126 : dataLength;
|
|
1260
|
-
if (dataLength > 65535)
|
|
1261
|
-
frame.writeBigUInt64BE(dataLength, 2);
|
|
1262
|
-
else if (dataLength > 125)
|
|
1263
|
-
frame.writeUInt16BE(dataLength, 2);
|
|
1264
|
-
if (dataLength && frame.length > dataLength) {
|
|
1265
|
-
if (typeof data === 'string')
|
|
1266
|
-
frame.write(data, headerSize, 'utf8');
|
|
1267
|
-
else
|
|
1268
|
-
data.copy(frame, headerSize);
|
|
1269
|
-
}
|
|
1270
|
-
if (dataLength && options?.mask) {
|
|
1271
|
-
let i = headerSize, h = headerSize - 4;
|
|
1272
|
-
for (let i = 0; i < 4; i++)
|
|
1273
|
-
frame[h + i] = Math.floor(Math.random() * 256);
|
|
1274
|
-
for (let j = 0; j < dataLength; j++, i++) {
|
|
1275
|
-
frame[i] ^= frame[h + (j & 3)];
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1278
|
-
return frame;
|
|
1279
|
-
}
|
|
1280
1273
|
/** Send data */
|
|
1281
1274
|
send(data) {
|
|
1282
1275
|
let msgType = typeof data === 'string' ? 1 : 2;
|
|
@@ -1298,6 +1291,7 @@ export class WebSocket extends EventEmitter {
|
|
|
1298
1291
|
else
|
|
1299
1292
|
return this._sendFrame(0x80 | msgType, data);
|
|
1300
1293
|
}
|
|
1294
|
+
// @internal
|
|
1301
1295
|
_errorHandler(error) {
|
|
1302
1296
|
this.emit('error', error);
|
|
1303
1297
|
if (this.ready)
|
|
@@ -1306,6 +1300,7 @@ export class WebSocket extends EventEmitter {
|
|
|
1306
1300
|
this._socket.destroy();
|
|
1307
1301
|
this.ready = false;
|
|
1308
1302
|
}
|
|
1303
|
+
// @internal
|
|
1309
1304
|
_headerLength(buffer) {
|
|
1310
1305
|
if (this._frame)
|
|
1311
1306
|
return 0;
|
|
@@ -1314,6 +1309,7 @@ export class WebSocket extends EventEmitter {
|
|
|
1314
1309
|
let hederInfo = buffer[1];
|
|
1315
1310
|
return 2 + (hederInfo & 0x80 ? 4 : 0) + ((hederInfo & 0x7F) === 126 ? 2 : 0) + ((hederInfo & 0x7F) === 127 ? 8 : 0);
|
|
1316
1311
|
}
|
|
1312
|
+
// @internal
|
|
1317
1313
|
_dataHandler(data) {
|
|
1318
1314
|
while (data.length) {
|
|
1319
1315
|
let frame = this._frame;
|
|
@@ -1420,6 +1416,7 @@ export class WebSocket extends EventEmitter {
|
|
|
1420
1416
|
this._buffers.push(EMPTY_BUFFER);
|
|
1421
1417
|
}
|
|
1422
1418
|
}
|
|
1419
|
+
// @internal
|
|
1423
1420
|
_abort(message, code, headers) {
|
|
1424
1421
|
code = code || 400;
|
|
1425
1422
|
message = message || http.STATUS_CODES[code] || 'Closed';
|
|
@@ -1446,6 +1443,7 @@ export class WebSocket extends EventEmitter {
|
|
|
1446
1443
|
pong(buffer) {
|
|
1447
1444
|
this._sendFrame(0x8A, buffer || EMPTY_BUFFER);
|
|
1448
1445
|
}
|
|
1446
|
+
// @internal
|
|
1449
1447
|
_sendFrame(opcode, data, cb) {
|
|
1450
1448
|
if (!this.ready)
|
|
1451
1449
|
return;
|
|
@@ -1465,24 +1463,21 @@ export class WebSocket extends EventEmitter {
|
|
|
1465
1463
|
else
|
|
1466
1464
|
this._socket.write(frame, () => this._socket.write(data, cb));
|
|
1467
1465
|
}
|
|
1468
|
-
on(event, listener) { return super.on(event, listener); }
|
|
1469
|
-
addListener(event, listener) { return super.addListener(event, listener); }
|
|
1470
|
-
once(event, listener) { return super.once(event, listener); }
|
|
1471
|
-
off(event, listener) { return super.off(event, listener); }
|
|
1472
|
-
removeListener(event, listener) { return super.removeListener(event, listener); }
|
|
1473
1466
|
}
|
|
1474
1467
|
export class WebSocketPlugin extends Plugin {
|
|
1475
1468
|
name = 'websocket';
|
|
1469
|
+
// @internal
|
|
1476
1470
|
_handler;
|
|
1477
1471
|
constructor(options, server) {
|
|
1478
1472
|
super();
|
|
1479
1473
|
if (!server)
|
|
1480
1474
|
throw new Error('Server instance is required');
|
|
1481
1475
|
this._handler = this.upgradeHandler.bind(this, server);
|
|
1482
|
-
server.servers?.forEach(srv => this.
|
|
1483
|
-
server.on('listen', (port, address, srv) => this.
|
|
1476
|
+
server.servers?.forEach(srv => this._addUpgradeHandler(srv));
|
|
1477
|
+
server.on('listen', (port, address, srv) => this._addUpgradeHandler(srv));
|
|
1484
1478
|
}
|
|
1485
|
-
|
|
1479
|
+
// @internal
|
|
1480
|
+
_addUpgradeHandler(srv) {
|
|
1486
1481
|
if (!srv.listeners('upgrade').includes(this._handler))
|
|
1487
1482
|
srv.on('upgrade', this._handler);
|
|
1488
1483
|
}
|
|
@@ -1490,7 +1485,6 @@ export class WebSocketPlugin extends Plugin {
|
|
|
1490
1485
|
const host = req.headers.host || '';
|
|
1491
1486
|
const vhostPlugin = server.getPlugin('vhost');
|
|
1492
1487
|
const vserver = vhostPlugin?.vhosts?.[host] || server;
|
|
1493
|
-
req.method = 'WEBSOCKET';
|
|
1494
1488
|
const res = {
|
|
1495
1489
|
req,
|
|
1496
1490
|
get headersSent() {
|
|
@@ -1521,7 +1515,9 @@ export class WebSocketPlugin extends Plugin {
|
|
|
1521
1515
|
socket.write(headers.join('\r\n'), () => { socket.destroy(); });
|
|
1522
1516
|
},
|
|
1523
1517
|
error(code) {
|
|
1524
|
-
|
|
1518
|
+
if (typeof code !== 'number')
|
|
1519
|
+
code = 405;
|
|
1520
|
+
res.statusCode = code || 405;
|
|
1525
1521
|
res.end();
|
|
1526
1522
|
},
|
|
1527
1523
|
send(data) {
|
|
@@ -1531,15 +1527,18 @@ export class WebSocketPlugin extends Plugin {
|
|
|
1531
1527
|
setHeader() { }
|
|
1532
1528
|
};
|
|
1533
1529
|
ServerRequest.extend(req, res, server);
|
|
1534
|
-
let
|
|
1530
|
+
let ws;
|
|
1535
1531
|
Object.defineProperty(req, 'websocket', {
|
|
1536
1532
|
get: () => {
|
|
1537
|
-
if (!
|
|
1538
|
-
|
|
1539
|
-
return
|
|
1533
|
+
if (!ws)
|
|
1534
|
+
ws = new WebSocket(req, server.config.websocket);
|
|
1535
|
+
return ws;
|
|
1540
1536
|
},
|
|
1541
1537
|
enumerable: true
|
|
1542
1538
|
});
|
|
1539
|
+
if (req.method !== 'GET' || req.headers.upgrade?.toLowerCase() !== 'websocket')
|
|
1540
|
+
return res.error(400);
|
|
1541
|
+
req.method = 'WEBSOCKET';
|
|
1543
1542
|
vserver.handler(req, res);
|
|
1544
1543
|
}
|
|
1545
1544
|
}
|
|
@@ -1549,6 +1548,7 @@ export class WebSocketPlugin extends Plugin {
|
|
|
1549
1548
|
export class TrustProxyPlugin extends Plugin {
|
|
1550
1549
|
priority = -60;
|
|
1551
1550
|
name = 'trustproxy';
|
|
1551
|
+
// @internal
|
|
1552
1552
|
_trustProxy = [];
|
|
1553
1553
|
constructor(options) {
|
|
1554
1554
|
super();
|
|
@@ -1965,11 +1965,7 @@ export class Auth {
|
|
|
1965
1965
|
encrypted = iv.toString('base64').slice(0, 22) + cipher.getAuthTag().toString('base64').slice(0, 22) + encrypted;
|
|
1966
1966
|
return encrypted.replace(/==?/, '').replace(/\//g, '.').replace(/\+/g, '-');
|
|
1967
1967
|
}
|
|
1968
|
-
/**
|
|
1969
|
-
* Check acl over authenticated user with: `id`, `group/*`, `*`
|
|
1970
|
-
* @param {string} id - to authenticate: `id`, `group/id`, `model/action`, comma separated best: true => false => def
|
|
1971
|
-
* @param {boolean} [def=false] - default access
|
|
1972
|
-
*/
|
|
1968
|
+
/** Check acl over authenticated user with: `id`, `group/*`, `*` */
|
|
1973
1969
|
acl(id, def = false) {
|
|
1974
1970
|
if (!this.req?.user)
|
|
1975
1971
|
return false;
|
|
@@ -1991,12 +1987,7 @@ export class Auth {
|
|
|
1991
1987
|
access = reqAcl['*'];
|
|
1992
1988
|
return access ?? def;
|
|
1993
1989
|
}
|
|
1994
|
-
/**
|
|
1995
|
-
* Authenticate user and setup cookie
|
|
1996
|
-
* @param {string|UserInfo} usr - user id used with options.users to retrieve user object. User object must contain `id` and `acl` object (Ex. usr = {id:'usr', acl:{'users/*':true}})
|
|
1997
|
-
* @param {string} [psw] - user password (if used for user authentication with options.users)
|
|
1998
|
-
* @param {number} [expire] - expire time in seconds (default: options.expire)
|
|
1999
|
-
*/
|
|
1990
|
+
/** Generate token from user info */
|
|
2000
1991
|
async token(usr, psw, expire) {
|
|
2001
1992
|
let data;
|
|
2002
1993
|
if (typeof usr === 'object' && usr && (usr.id || usr._id))
|
|
@@ -2012,9 +2003,7 @@ export class Auth {
|
|
|
2012
2003
|
if (data)
|
|
2013
2004
|
return this.encode(data, expire);
|
|
2014
2005
|
}
|
|
2015
|
-
/**
|
|
2016
|
-
* Authenticate user and setup cookie
|
|
2017
|
-
*/
|
|
2006
|
+
/** Authenticate user and setup cookie */
|
|
2018
2007
|
async login(usr, psw, options) {
|
|
2019
2008
|
let usrInfo;
|
|
2020
2009
|
if (typeof usr === 'object')
|
|
@@ -2487,7 +2476,9 @@ export class Controller {
|
|
|
2487
2476
|
// #endregion Controller
|
|
2488
2477
|
// #region Worker
|
|
2489
2478
|
class WorkerJob {
|
|
2479
|
+
// @internal
|
|
2490
2480
|
_promises = [];
|
|
2481
|
+
// @internal
|
|
2491
2482
|
_busy = 0;
|
|
2492
2483
|
start() {
|
|
2493
2484
|
this._busy++;
|
|
@@ -2505,7 +2496,9 @@ class WorkerJob {
|
|
|
2505
2496
|
}
|
|
2506
2497
|
}
|
|
2507
2498
|
class Worker {
|
|
2499
|
+
// @internal
|
|
2508
2500
|
_id = 0;
|
|
2501
|
+
// @internal
|
|
2509
2502
|
_jobs = {};
|
|
2510
2503
|
isBusy(id) {
|
|
2511
2504
|
const job = this._jobs[id || 'ready'];
|
|
@@ -2534,11 +2527,17 @@ class Worker {
|
|
|
2534
2527
|
}
|
|
2535
2528
|
/** JSON File store */
|
|
2536
2529
|
export class FileStore {
|
|
2530
|
+
// @internal
|
|
2537
2531
|
_cache;
|
|
2532
|
+
// @internal
|
|
2538
2533
|
_dir;
|
|
2534
|
+
// @internal
|
|
2539
2535
|
_cacheTimeout;
|
|
2536
|
+
// @internal
|
|
2540
2537
|
_cacheItems;
|
|
2538
|
+
// @internal
|
|
2541
2539
|
_debounceTimeout;
|
|
2540
|
+
// @internal
|
|
2542
2541
|
_iter;
|
|
2543
2542
|
constructor(options) {
|
|
2544
2543
|
this._cache = {};
|
|
@@ -2562,7 +2561,9 @@ export class FileStore {
|
|
|
2562
2561
|
}
|
|
2563
2562
|
}
|
|
2564
2563
|
}
|
|
2564
|
+
// @internal
|
|
2565
2565
|
_queue = Promise.resolve();
|
|
2566
|
+
// @internal
|
|
2566
2567
|
async _sync(cb) {
|
|
2567
2568
|
let r;
|
|
2568
2569
|
let p = new Promise(resolve => r = resolve);
|
|
@@ -2741,8 +2742,11 @@ function newObjectId() {
|
|
|
2741
2742
|
return (new Date().getTime() / 1000 | 0).toString(16) + globalObjectId.toString('hex');
|
|
2742
2743
|
}
|
|
2743
2744
|
class ModelCollectionsInternal {
|
|
2745
|
+
// @internal
|
|
2744
2746
|
_ready;
|
|
2747
|
+
// @internal
|
|
2745
2748
|
_wait = new Promise(resolve => this._ready = resolve);
|
|
2749
|
+
// @internal
|
|
2746
2750
|
_db;
|
|
2747
2751
|
set db(db) {
|
|
2748
2752
|
Promise.resolve(db).then(db => this._ready(this._db = db));
|
|
@@ -3045,6 +3049,7 @@ export class Model {
|
|
|
3045
3049
|
}
|
|
3046
3050
|
return res;
|
|
3047
3051
|
}
|
|
3052
|
+
// @internal
|
|
3048
3053
|
_fieldFunction(value, def) {
|
|
3049
3054
|
if (typeof value === 'string' && value.startsWith('${') && value.endsWith('}')) {
|
|
3050
3055
|
const names = value.slice(2, -1).split('.');
|
|
@@ -3062,6 +3067,7 @@ export class Model {
|
|
|
3062
3067
|
return () => def;
|
|
3063
3068
|
return () => value;
|
|
3064
3069
|
}
|
|
3070
|
+
// @internal
|
|
3065
3071
|
_validateField(value, options) {
|
|
3066
3072
|
const field = options.field;
|
|
3067
3073
|
if (value == null) {
|
|
@@ -3189,7 +3195,9 @@ export class Model {
|
|
|
3189
3195
|
}
|
|
3190
3196
|
/** Collection factory */
|
|
3191
3197
|
export class MicroCollectionStore {
|
|
3198
|
+
// @internal
|
|
3192
3199
|
_collections = new Map();
|
|
3200
|
+
// @internal
|
|
3193
3201
|
_store;
|
|
3194
3202
|
constructor(dataPath, storeTimeDelay) {
|
|
3195
3203
|
if (dataPath)
|
|
@@ -3212,6 +3220,7 @@ export class MicroCollection {
|
|
|
3212
3220
|
name;
|
|
3213
3221
|
/** Collection data */
|
|
3214
3222
|
data;
|
|
3223
|
+
// @internal
|
|
3215
3224
|
_save;
|
|
3216
3225
|
constructor(options = {}) {
|
|
3217
3226
|
this.name = options.name || this.constructor.name;
|