iosignal 4.0.0 → 4.5.0
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/.vscode/settings.json +1 -1
- package/README.md +0 -2
- package/dist/io.d.ts +11 -9
- package/dist/io.js +5 -5
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +5 -5
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +278 -242
- package/dist/types/client/IOCore.d.ts +12 -10
- package/dist/types/common/constants.d.ts +27 -37
- package/index.js +4 -3
- package/package.json +1 -1
- package/src/auth/BohoAuth.js +48 -11
- package/src/auth/{Auth_File.js → key_providers/FileKeyProvider.js} +8 -20
- package/src/auth/{Auth_Redis.js → key_providers/RedisKeyProvider.js} +4 -7
- package/src/auth/key_providers/StringKeyProvider.js +54 -0
- package/src/client/IOCongSocket.js +5 -3
- package/src/client/IOCore.js +64 -65
- package/src/client/IOWS.js +5 -3
- package/src/client/browser/IOWebSocket.js +5 -3
- package/src/common/constants.js +31 -44
- package/src/common/util.js +3 -0
- package/src/server/Manager.js +4 -4
- package/src/server/Remote.js +4 -1
- package/src/server/RemoteCore.js +23 -17
- package/src/server/Server.js +7 -7
- package/README.en.md +0 -56
- package/auth_file_sample.js +0 -23
- package/auth_file_sample.json +0 -13
- package/src/auth/Auth_Env.js +0 -76
package/dist/iosignal.js
CHANGED
|
@@ -9,11 +9,11 @@ import require$$7 from 'url';
|
|
|
9
9
|
import require$$0 from 'zlib';
|
|
10
10
|
import fs, { readFileSync } from 'fs';
|
|
11
11
|
import path from 'path';
|
|
12
|
-
import require$$2 from 'os';
|
|
12
|
+
import require$$2, { networkInterfaces } from 'os';
|
|
13
13
|
import require$$0$1 from 'buffer';
|
|
14
14
|
import { memoryUsage } from 'process';
|
|
15
15
|
|
|
16
|
-
var version$1 = "4.
|
|
16
|
+
var version$1 = "4.5.0";
|
|
17
17
|
var pkg = {
|
|
18
18
|
version: version$1};
|
|
19
19
|
|
|
@@ -381,53 +381,41 @@ var eventemitter3Exports = requireEventemitter3();
|
|
|
381
381
|
var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
|
|
382
382
|
|
|
383
383
|
/**
|
|
384
|
-
* @typedef {object}
|
|
385
|
-
* @property {number}
|
|
384
|
+
* @typedef {object} STATE
|
|
385
|
+
* @property {number} CONNECTING
|
|
386
386
|
* @property {number} OPEN
|
|
387
|
-
* @property {number} CLOSING
|
|
388
|
-
* @property {number} CLOSED
|
|
389
387
|
* @property {number} SERVER_READY
|
|
390
|
-
* @property {number}
|
|
391
|
-
* @property {number}
|
|
388
|
+
* @property {number} AUTH_ACK
|
|
389
|
+
* @property {number} CLOSING
|
|
392
390
|
* @property {number} READY
|
|
391
|
+
* @property {number} AUTH_FAIL
|
|
392
|
+
* @property {number} AUTH_CLEAR
|
|
393
|
+
* @property {number} CLOSING
|
|
394
|
+
* @property {number} CLOSED
|
|
395
|
+
* @property {number} STOP
|
|
393
396
|
* @property {number} REDIRECTING
|
|
394
397
|
*/
|
|
395
|
-
// Client
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
OPEN:
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
398
|
+
// Client STATE: name and number
|
|
399
|
+
const STATE = {
|
|
400
|
+
CONNECTING: 0,
|
|
401
|
+
OPEN: 1,
|
|
402
|
+
SERVER_READY: 10,
|
|
403
|
+
AUTH_REQ: 11,
|
|
404
|
+
AUTH_NONCE: 12,
|
|
405
|
+
AUTH_HMAC: 13,
|
|
406
|
+
AUTH_ACK: 14,
|
|
407
|
+
AUTH_FAIL: 15,
|
|
408
|
+
AUTH_CLEAR: 16,
|
|
409
|
+
CID_REQ: 17,
|
|
410
|
+
CID_RES: 18,
|
|
411
|
+
READY: 19,
|
|
412
|
+
CLOSING: 2,
|
|
413
|
+
CLOSED: 3,
|
|
414
|
+
STOP: 4,
|
|
415
|
+
REDIRECTING: 5
|
|
406
416
|
};
|
|
407
|
-
for (let c in
|
|
417
|
+
for (let c in STATE) { STATE[STATE[c]] = c; }
|
|
408
418
|
|
|
409
|
-
/**
|
|
410
|
-
* @typedef {object} CLIENT_STATE
|
|
411
|
-
* @property {number} INIT
|
|
412
|
-
* @property {number} SENT_SERVER_READY
|
|
413
|
-
* @property {number} RECV_AUTH_REQ
|
|
414
|
-
* @property {number} SENT_SERVER_NONCE
|
|
415
|
-
* @property {number} RECV_AUTH_HMAC
|
|
416
|
-
* @property {number} AUTH_FAIL
|
|
417
|
-
* @property {number} AUTH_READY
|
|
418
|
-
* @property {number} CID_READY
|
|
419
|
-
*/
|
|
420
|
-
const CLIENT_STATE = {
|
|
421
|
-
INIT: 0,
|
|
422
|
-
SENT_SERVER_READY: 1,
|
|
423
|
-
RECV_AUTH_REQ: 2,
|
|
424
|
-
SENT_SERVER_NONCE: 3,
|
|
425
|
-
RECV_AUTH_HMAC: 4,
|
|
426
|
-
AUTH_FAIL: 5,
|
|
427
|
-
AUTH_READY: 6,
|
|
428
|
-
CID_READY: 7
|
|
429
|
-
};
|
|
430
|
-
for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c; }
|
|
431
419
|
|
|
432
420
|
/**
|
|
433
421
|
* @typedef {object} ENC_MODE
|
|
@@ -456,7 +444,7 @@ for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c; }
|
|
|
456
444
|
const SIZE_LIMIT = {
|
|
457
445
|
TAG_LEN1: 255,
|
|
458
446
|
TAG_LEN2: 65535,
|
|
459
|
-
CONNECTION_CHECKER_PERIOD:
|
|
447
|
+
CONNECTION_CHECKER_PERIOD: 30000,
|
|
460
448
|
PROMISE_TIMEOUT: 5000,
|
|
461
449
|
DID: 8,
|
|
462
450
|
CID: 12
|
|
@@ -488,7 +476,7 @@ for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c; }
|
|
|
488
476
|
* @property {number} CID_REQ
|
|
489
477
|
* @property {number} CID_RES
|
|
490
478
|
* @property {number} QUOTA_LEVEL
|
|
491
|
-
* @property {number}
|
|
479
|
+
* @property {number} AUTH_CLEAR
|
|
492
480
|
* @property {number} SERVER_REDIRECT
|
|
493
481
|
* @property {number} LOOP
|
|
494
482
|
* @property {number} ECHO
|
|
@@ -546,9 +534,8 @@ let IOMsg = {
|
|
|
546
534
|
CID_REQ: 0xC1,
|
|
547
535
|
CID_RES: 0xC2,
|
|
548
536
|
QUOTA_LEVEL: 0xC3,
|
|
549
|
-
|
|
537
|
+
AUTH_CLEAR: 0xC4,
|
|
550
538
|
SERVER_REDIRECT: 0xC5,
|
|
551
|
-
|
|
552
539
|
// ..
|
|
553
540
|
LOOP: 0xCB,
|
|
554
541
|
ECHO: 0xCC,
|
|
@@ -789,7 +776,7 @@ const t=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1
|
|
|
789
776
|
* @typedef {import('../common/constants.js').PAYLOAD_TYPE} PAYLOAD_TYPE
|
|
790
777
|
* @typedef {import('../common/constants.js').SIZE_LIMIT} SIZE_LIMIT
|
|
791
778
|
* @typedef {import('../common/constants.js').ENC_MODE} ENC_MODE
|
|
792
|
-
* @typedef {import('../common/constants.js').
|
|
779
|
+
* @typedef {import('../common/constants.js').STATE} STATE
|
|
793
780
|
* @typedef {import('../common/quotaTable.js').quotaTable} quotaTable
|
|
794
781
|
|
|
795
782
|
* @typedef {import('boho').Boho} Boho
|
|
@@ -843,7 +830,7 @@ class IOCore extends EventEmitter {
|
|
|
843
830
|
* Current connection state (number).
|
|
844
831
|
* @type {number}
|
|
845
832
|
*/
|
|
846
|
-
this.state =
|
|
833
|
+
this.state = STATE.CLOSED; // Number type
|
|
847
834
|
/**
|
|
848
835
|
* Current connection state (string).
|
|
849
836
|
* @type {string}
|
|
@@ -985,7 +972,7 @@ class IOCore extends EventEmitter {
|
|
|
985
972
|
close() {
|
|
986
973
|
if (this._closed) return;
|
|
987
974
|
this._closed = true;
|
|
988
|
-
// console.log('####### IOCOre.js close() called')
|
|
975
|
+
// console.log('####### IOCOre.js close() called')
|
|
989
976
|
// If auto-reconnect is disabled, we must stop the keep-alive timer.
|
|
990
977
|
if (this.autoReconnect === false) {
|
|
991
978
|
clearInterval(this.connectionCheckerIntervalID);
|
|
@@ -1000,7 +987,7 @@ class IOCore extends EventEmitter {
|
|
|
1000
987
|
// To avoid the error, we wait for the connection to open, then immediately close it.
|
|
1001
988
|
// We also clear other handlers to prevent any other logic from running.
|
|
1002
989
|
const socket = this.socket;
|
|
1003
|
-
socket.onopen = () => { if(socket) socket.close(); };
|
|
990
|
+
socket.onopen = () => { if (socket) socket.close(); };
|
|
1004
991
|
socket.onmessage = null;
|
|
1005
992
|
socket.onerror = null;
|
|
1006
993
|
socket.onclose = null;
|
|
@@ -1008,7 +995,7 @@ class IOCore extends EventEmitter {
|
|
|
1008
995
|
try {
|
|
1009
996
|
// For other sockets (like TCP) or other WebSocket states, close directly.
|
|
1010
997
|
this.socket.close?.();
|
|
1011
|
-
} catch {}
|
|
998
|
+
} catch { }
|
|
1012
999
|
}
|
|
1013
1000
|
this.socket = null;
|
|
1014
1001
|
}
|
|
@@ -1016,14 +1003,15 @@ class IOCore extends EventEmitter {
|
|
|
1016
1003
|
this.emit('closed');
|
|
1017
1004
|
this.stateChange('closed');
|
|
1018
1005
|
}
|
|
1019
|
-
|
|
1006
|
+
|
|
1020
1007
|
/**
|
|
1021
1008
|
* Disables auto-reconnect and closes the current connection.
|
|
1022
1009
|
* The instance can be re-opened manually later. For complete cleanup, use destroy().
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1010
|
+
*/
|
|
1011
|
+
stop() {
|
|
1012
|
+
this.autoReconnect = false;
|
|
1013
|
+
this.close();
|
|
1014
|
+
this.stateChange('stop','stop');
|
|
1027
1015
|
}
|
|
1028
1016
|
|
|
1029
1017
|
/**
|
|
@@ -1039,7 +1027,7 @@ class IOCore extends EventEmitter {
|
|
|
1039
1027
|
|
|
1040
1028
|
// Help GC
|
|
1041
1029
|
this.boho = null;
|
|
1042
|
-
}
|
|
1030
|
+
}
|
|
1043
1031
|
|
|
1044
1032
|
/**
|
|
1045
1033
|
* The core keep-alive logic. It checks if auto-reconnect is enabled.
|
|
@@ -1056,8 +1044,8 @@ class IOCore extends EventEmitter {
|
|
|
1056
1044
|
* @param {string} url2 - The new URL to redirect to.
|
|
1057
1045
|
*/
|
|
1058
1046
|
redirect(url2) {
|
|
1047
|
+
this.stateChange('redirecting','redirecting');
|
|
1059
1048
|
this.close();
|
|
1060
|
-
this.stateChange('redirecting');
|
|
1061
1049
|
this.createConnection(url2);
|
|
1062
1050
|
}
|
|
1063
1051
|
|
|
@@ -1114,29 +1102,27 @@ class IOCore extends EventEmitter {
|
|
|
1114
1102
|
|
|
1115
1103
|
/**
|
|
1116
1104
|
* Manually logs in with provided ID and key.
|
|
1117
|
-
* @param {string} id - The user ID.
|
|
1105
|
+
* @param {string} id - The user ID. or 'id.key'
|
|
1118
1106
|
* @param {string} key - The user key.
|
|
1119
|
-
* @returns {
|
|
1107
|
+
* @returns {this}
|
|
1120
1108
|
*/
|
|
1121
1109
|
login(id, key) {
|
|
1122
|
-
|
|
1123
|
-
|
|
1110
|
+
this.auth(id, key);
|
|
1124
1111
|
this.useAuth = true;
|
|
1125
1112
|
let auth_pack = this.boho.auth_req();
|
|
1126
1113
|
this.send(auth_pack);
|
|
1127
|
-
return
|
|
1114
|
+
return this
|
|
1128
1115
|
}
|
|
1129
1116
|
|
|
1130
1117
|
/**
|
|
1131
1118
|
* Sets up authentication for auto-login.
|
|
1132
|
-
* @param {string} id - The user ID.
|
|
1119
|
+
* @param {string} id - The user ID. or 'id.Key'
|
|
1133
1120
|
* @param {string} key - The user key.
|
|
1134
|
-
* @returns {
|
|
1121
|
+
* @returns {this}
|
|
1135
1122
|
*/
|
|
1136
1123
|
auth(id, key) {
|
|
1137
1124
|
if (!id && !key) {
|
|
1138
1125
|
this.emit('error', new Error('auth failed. no id and key.'));
|
|
1139
|
-
return false
|
|
1140
1126
|
}
|
|
1141
1127
|
|
|
1142
1128
|
if (!key && id.includes('.')) {
|
|
@@ -1146,10 +1132,9 @@ class IOCore extends EventEmitter {
|
|
|
1146
1132
|
this.boho.set_key(key);
|
|
1147
1133
|
} else {
|
|
1148
1134
|
this.emit('error', new Error('auth failed. no id or key.'));
|
|
1149
|
-
return false
|
|
1150
1135
|
}
|
|
1151
1136
|
this.useAuth = true;
|
|
1152
|
-
return
|
|
1137
|
+
return this
|
|
1153
1138
|
}
|
|
1154
1139
|
|
|
1155
1140
|
/**
|
|
@@ -1209,13 +1194,13 @@ class IOCore extends EventEmitter {
|
|
|
1209
1194
|
case IOMsg.ECHO:
|
|
1210
1195
|
try {
|
|
1211
1196
|
let str = decoder$4.decode(buffer.subarray(1));
|
|
1212
|
-
|
|
1197
|
+
|
|
1213
1198
|
this.emit('echo', str);
|
|
1214
1199
|
} catch (error) {
|
|
1215
1200
|
this.emit('error', new Error('ECHO data error'));
|
|
1216
1201
|
}
|
|
1217
1202
|
break;
|
|
1218
|
-
|
|
1203
|
+
|
|
1219
1204
|
case IOMsg.IAM_RES:
|
|
1220
1205
|
try {
|
|
1221
1206
|
let str = decoder$4.decode(buffer.subarray(1));
|
|
@@ -1224,7 +1209,7 @@ class IOCore extends EventEmitter {
|
|
|
1224
1209
|
if (jsonInfo.nick) { this.nick = jsonInfo.nick; }
|
|
1225
1210
|
if (jsonInfo.did) { this.did = jsonInfo.did; }
|
|
1226
1211
|
if (jsonInfo.uid) { this.uid = jsonInfo.uid; }
|
|
1227
|
-
this.emit('iam_res', str
|
|
1212
|
+
this.emit('iam_res', str);
|
|
1228
1213
|
} catch (error) {
|
|
1229
1214
|
this.emit('error', new Error('IAM_RES data error'));
|
|
1230
1215
|
}
|
|
@@ -1235,22 +1220,22 @@ class IOCore extends EventEmitter {
|
|
|
1235
1220
|
this.cid = cidStr;
|
|
1236
1221
|
|
|
1237
1222
|
// **IMPORTANT** change state before subscribe.
|
|
1238
|
-
this.stateChange('ready', 'cid_ready');
|
|
1239
|
-
this.subscribe_memory_channels();
|
|
1223
|
+
this.stateChange('ready', 'cid_ready');
|
|
1224
|
+
this.subscribe_memory_channels(); // tags registered by listen() or link().
|
|
1240
1225
|
break;
|
|
1241
1226
|
|
|
1242
1227
|
case IOMsg.QUOTA_LEVEL:
|
|
1243
1228
|
let quotaLevel = buffer[1];
|
|
1244
1229
|
this.level = quotaLevel;
|
|
1245
1230
|
this.quota = quotaTable[quotaLevel];
|
|
1246
|
-
console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota))
|
|
1231
|
+
// console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota))
|
|
1247
1232
|
break;
|
|
1248
1233
|
|
|
1249
|
-
case IOMsg.
|
|
1234
|
+
case IOMsg.AUTH_CLEAR:
|
|
1250
1235
|
this.useAuth = false;
|
|
1251
1236
|
this.boho.clearAuth();
|
|
1237
|
+
this.stateChange('auth_clear', 'server request auth_clear.');
|
|
1252
1238
|
this.stop();
|
|
1253
|
-
console.log('[SERVER_CLEAR_AUTH] io stop.');
|
|
1254
1239
|
break;
|
|
1255
1240
|
|
|
1256
1241
|
case IOMsg.SERVER_REDIRECT:
|
|
@@ -1327,7 +1312,7 @@ class IOCore extends EventEmitter {
|
|
|
1327
1312
|
if (tag.indexOf('@') === 0) this.emit('@', tag, null);
|
|
1328
1313
|
else {
|
|
1329
1314
|
this.emit(tag, tag, null);
|
|
1330
|
-
this.emit('message', tag, null
|
|
1315
|
+
this.emit('message', tag, null);
|
|
1331
1316
|
}
|
|
1332
1317
|
break;
|
|
1333
1318
|
|
|
@@ -1340,7 +1325,7 @@ class IOCore extends EventEmitter {
|
|
|
1340
1325
|
}
|
|
1341
1326
|
let oneString = decoder$4.decode(payloadStringWithoutNull);
|
|
1342
1327
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneString);
|
|
1343
|
-
if (tag !== '@'){
|
|
1328
|
+
if (tag !== '@') {
|
|
1344
1329
|
this.emit(tag, tag, oneString);
|
|
1345
1330
|
this.emit('message', tag, oneString);
|
|
1346
1331
|
}
|
|
@@ -1348,39 +1333,39 @@ class IOCore extends EventEmitter {
|
|
|
1348
1333
|
|
|
1349
1334
|
case PAYLOAD_TYPE.BINARY:
|
|
1350
1335
|
if (tag.indexOf('@') === 0) this.emit('@', tag, payloadBuffer);
|
|
1351
|
-
if (tag !== '@'){
|
|
1336
|
+
if (tag !== '@') {
|
|
1352
1337
|
this.emit(tag, tag, payloadBuffer);
|
|
1353
1338
|
this.emit('message', tag, payloadBuffer);
|
|
1354
|
-
}
|
|
1339
|
+
}
|
|
1355
1340
|
break;
|
|
1356
1341
|
|
|
1357
1342
|
case PAYLOAD_TYPE.OBJECT:
|
|
1358
1343
|
let oneObjectBuffer = decoder$4.decode(payloadBuffer);
|
|
1359
1344
|
let oneJSONObject = JSON.parse(oneObjectBuffer);
|
|
1360
1345
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneJSONObject);
|
|
1361
|
-
if (tag !== '@'){
|
|
1346
|
+
if (tag !== '@') {
|
|
1362
1347
|
this.emit(tag, tag, oneJSONObject);
|
|
1363
1348
|
this.emit('message', tag, oneJSONObject);
|
|
1364
|
-
}
|
|
1349
|
+
}
|
|
1365
1350
|
break;
|
|
1366
1351
|
|
|
1367
1352
|
case PAYLOAD_TYPE.MJSON:
|
|
1368
1353
|
let mjsonBuffer = decoder$4.decode(payloadBuffer);
|
|
1369
1354
|
let mjson = JSON.parse(mjsonBuffer);
|
|
1370
1355
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mjson);
|
|
1371
|
-
if (tag !== '@'){
|
|
1356
|
+
if (tag !== '@') {
|
|
1372
1357
|
this.emit(tag, tag, ...mjson);
|
|
1373
1358
|
this.emit('message', tag, ...mjson);
|
|
1374
|
-
}
|
|
1359
|
+
}
|
|
1375
1360
|
break;
|
|
1376
1361
|
|
|
1377
1362
|
case PAYLOAD_TYPE.MBA:
|
|
1378
1363
|
let mbaObject = M$1.unpack(payloadBuffer);
|
|
1379
1364
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mbaObject.args);
|
|
1380
|
-
if (tag !== '@'){
|
|
1365
|
+
if (tag !== '@') {
|
|
1381
1366
|
this.emit(tag, tag, ...mbaObject.args);
|
|
1382
|
-
this.emit('message', tag, ...mbaObject.args
|
|
1383
|
-
}
|
|
1367
|
+
this.emit('message', tag, ...mbaObject.args);
|
|
1368
|
+
}
|
|
1384
1369
|
break;
|
|
1385
1370
|
|
|
1386
1371
|
default:
|
|
@@ -1388,7 +1373,8 @@ class IOCore extends EventEmitter {
|
|
|
1388
1373
|
}
|
|
1389
1374
|
|
|
1390
1375
|
} catch (err) {
|
|
1391
|
-
this.emit('error', new Error('
|
|
1376
|
+
// this.emit('error', new Error('IOCore IOMsg.SIGNAL parser err', err))
|
|
1377
|
+
console.log('IOCore IOMsg.SIGNAL parser err', err);
|
|
1392
1378
|
}
|
|
1393
1379
|
break;
|
|
1394
1380
|
|
|
@@ -1397,24 +1383,25 @@ class IOCore extends EventEmitter {
|
|
|
1397
1383
|
break;
|
|
1398
1384
|
|
|
1399
1385
|
case tt.BohoMsg.AUTH_NONCE:
|
|
1386
|
+
this.stateChange('auth_nonce','server sent auth_nonce.');
|
|
1400
1387
|
let auth_hmac = this.boho.auth_hmac(buffer);
|
|
1401
1388
|
if (auth_hmac) {
|
|
1402
1389
|
this.send(auth_hmac);
|
|
1403
1390
|
} else {
|
|
1404
|
-
this.stateChange('auth_fail', '
|
|
1391
|
+
this.stateChange('auth_fail', 'boho.auth_hmac() invalid auth_nonce.');
|
|
1405
1392
|
}
|
|
1406
1393
|
break;
|
|
1407
1394
|
|
|
1408
1395
|
case tt.BohoMsg.AUTH_FAIL:
|
|
1409
|
-
this.stateChange('auth_fail', '
|
|
1396
|
+
this.stateChange('auth_fail', 'auth_fail from server.');
|
|
1410
1397
|
break;
|
|
1411
1398
|
|
|
1412
1399
|
case tt.BohoMsg.AUTH_ACK:
|
|
1413
1400
|
if (this.boho.check_auth_ack_hmac(buffer)) {
|
|
1414
|
-
this.stateChange('
|
|
1401
|
+
this.stateChange('auth_ack', 'server sent auth_ack');
|
|
1415
1402
|
this.send(Buffer$1.from([IOMsg.CID_REQ]));
|
|
1416
1403
|
} else {
|
|
1417
|
-
this.stateChange('auth_fail', 'invalid server_hmac');
|
|
1404
|
+
this.stateChange('auth_fail', 'check_auth_ack_hmac() invalid server_hmac');
|
|
1418
1405
|
}
|
|
1419
1406
|
break;
|
|
1420
1407
|
|
|
@@ -1601,14 +1588,15 @@ class IOCore extends EventEmitter {
|
|
|
1601
1588
|
|
|
1602
1589
|
|
|
1603
1590
|
/**
|
|
1604
|
-
*
|
|
1591
|
+
* alias of signal()
|
|
1592
|
+
* Sends a signal with a tag and arguments.
|
|
1593
|
+
* @param {string} tag - The signal tag.
|
|
1605
1594
|
* @param {...any} args - Arguments for the signal.
|
|
1606
1595
|
*/
|
|
1607
|
-
publish(...args) {
|
|
1608
|
-
this.signal(...args);
|
|
1596
|
+
publish(tag, ...args) {
|
|
1597
|
+
this.signal(tag, ...args);
|
|
1609
1598
|
}
|
|
1610
1599
|
|
|
1611
|
-
|
|
1612
1600
|
/**
|
|
1613
1601
|
* Sends a signal with a tag and arguments.
|
|
1614
1602
|
* @param {string} tag - The signal tag.
|
|
@@ -1617,7 +1605,6 @@ class IOCore extends EventEmitter {
|
|
|
1617
1605
|
*/
|
|
1618
1606
|
signal(tag, ...args) {
|
|
1619
1607
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1620
|
-
|
|
1621
1608
|
let signalPack = getSignalPack(tag, ...args);
|
|
1622
1609
|
this.send_enc_mode(signalPack);
|
|
1623
1610
|
}
|
|
@@ -1661,7 +1648,6 @@ class IOCore extends EventEmitter {
|
|
|
1661
1648
|
}
|
|
1662
1649
|
|
|
1663
1650
|
|
|
1664
|
-
|
|
1665
1651
|
/**
|
|
1666
1652
|
* Sets a value in the store.
|
|
1667
1653
|
* @param {string} storeName - The name of the store.
|
|
@@ -1729,8 +1715,8 @@ class IOCore extends EventEmitter {
|
|
|
1729
1715
|
*/
|
|
1730
1716
|
subscribe(tag) {
|
|
1731
1717
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1732
|
-
|
|
1733
|
-
if (this.state !==
|
|
1718
|
+
if (tag.length > SIZE_LIMIT.TAG_LEN1) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN1)
|
|
1719
|
+
if (this.state !== STATE.READY) return
|
|
1734
1720
|
|
|
1735
1721
|
// subscribe 사용시, 사용 'ready' 이벤트시 메뉴얼 등록되므로 여기에 등록하면 2중 호출된다.
|
|
1736
1722
|
// 즉, channels 등록은 listen 같은 자동화 구독시만 사용.
|
|
@@ -1739,7 +1725,7 @@ class IOCore extends EventEmitter {
|
|
|
1739
1725
|
// this.channels.add(tag)
|
|
1740
1726
|
// })
|
|
1741
1727
|
|
|
1742
|
-
try {
|
|
1728
|
+
try {
|
|
1743
1729
|
let tagEncoded = encoder$1.encode(tag);
|
|
1744
1730
|
this.send_enc_mode(
|
|
1745
1731
|
Buffer$1.concat([
|
|
@@ -1759,12 +1745,12 @@ class IOCore extends EventEmitter {
|
|
|
1759
1745
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1760
1746
|
if (tag.length > SIZE_LIMIT.TAG_LEN2) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN2)
|
|
1761
1747
|
|
|
1762
|
-
if (this.state !==
|
|
1748
|
+
if (this.state !== STATE.READY) {
|
|
1763
1749
|
return Promise.reject('subscribe_promise:: connection is not ready')
|
|
1764
1750
|
}
|
|
1765
1751
|
|
|
1766
1752
|
try {
|
|
1767
|
-
let tagEncoded = encoder$1.encode(tag);
|
|
1753
|
+
let tagEncoded = encoder$1.encode(tag);
|
|
1768
1754
|
this.send_enc_mode(
|
|
1769
1755
|
Buffer$1.concat([
|
|
1770
1756
|
M$1.NB('8', IOMsg.SUBSCRIBE_REQ),
|
|
@@ -1834,7 +1820,7 @@ class IOCore extends EventEmitter {
|
|
|
1834
1820
|
}
|
|
1835
1821
|
this.on(tag, handler);
|
|
1836
1822
|
// do not subscribe now.
|
|
1837
|
-
// will subscribe when receive CID_RES
|
|
1823
|
+
// will subscribe when io state is 'ready'. (receive CID_RES from server)
|
|
1838
1824
|
|
|
1839
1825
|
}
|
|
1840
1826
|
|
|
@@ -1945,10 +1931,10 @@ class IOCore extends EventEmitter {
|
|
|
1945
1931
|
*/
|
|
1946
1932
|
getStateName() {
|
|
1947
1933
|
//state <number>
|
|
1948
|
-
//value of constant
|
|
1949
|
-
//type of constant
|
|
1934
|
+
//value of constant STATE.NAME < number >
|
|
1935
|
+
//type of constant STATE.NAME name < string uppercase >
|
|
1950
1936
|
//stateName,eventName <string lowercase>
|
|
1951
|
-
return (
|
|
1937
|
+
return (STATE[this.state]).toLowerCase()
|
|
1952
1938
|
}
|
|
1953
1939
|
|
|
1954
1940
|
/**
|
|
@@ -1976,14 +1962,14 @@ class IOCore extends EventEmitter {
|
|
|
1976
1962
|
* 보통 이벤트 이름과 동일하게 적거나 이벤트 상황 안내문을 넣는다.
|
|
1977
1963
|
*/
|
|
1978
1964
|
stateChange(state, emitEventAndMessage) {
|
|
1979
|
-
//
|
|
1965
|
+
// STATE constant name <string> upperCase
|
|
1980
1966
|
// eventName and .stateName <string> lowerCase
|
|
1981
1967
|
// .state <number>
|
|
1982
1968
|
// console.log('### stateChange reason:', emitEventAndMessage )
|
|
1983
1969
|
let eventName = state.toLowerCase();
|
|
1984
|
-
this.state =
|
|
1970
|
+
this.state = STATE[state.toUpperCase()]; // state: number
|
|
1985
1971
|
|
|
1986
|
-
if (emitEventAndMessage){
|
|
1972
|
+
if (emitEventAndMessage) {
|
|
1987
1973
|
this.emit(eventName, emitEventAndMessage);
|
|
1988
1974
|
}
|
|
1989
1975
|
|
|
@@ -2163,8 +2149,10 @@ class IOCongSocket extends IOCore {
|
|
|
2163
2149
|
keepAlive() {
|
|
2164
2150
|
if (!this.autoReconnect) return;
|
|
2165
2151
|
// Reconnect only if the socket is fully destroyed and the state is closed.
|
|
2166
|
-
if ((!this.socket || this.socket.destroyed)
|
|
2152
|
+
if ((!this.socket || this.socket.destroyed)) {
|
|
2167
2153
|
this.open();
|
|
2154
|
+
}else {
|
|
2155
|
+
this.ping();
|
|
2168
2156
|
}
|
|
2169
2157
|
}
|
|
2170
2158
|
|
|
@@ -2176,7 +2164,7 @@ class IOCongSocket extends IOCore {
|
|
|
2176
2164
|
urlObj = new URL('cong://' + url);
|
|
2177
2165
|
}
|
|
2178
2166
|
this.socket = net.createConnection(urlObj.port, urlObj.hostname);
|
|
2179
|
-
this.stateChange('
|
|
2167
|
+
this.stateChange('connecting','connecting');
|
|
2180
2168
|
|
|
2181
2169
|
this.socket.on('connect', () => {
|
|
2182
2170
|
this.congRx = new CongRx();
|
|
@@ -7590,15 +7578,17 @@ class IOWS extends IOCore {
|
|
|
7590
7578
|
keepAlive() {
|
|
7591
7579
|
if (!this.autoReconnect) return;
|
|
7592
7580
|
// Reconnect only if the socket is closed and the state reflects that.
|
|
7593
|
-
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED)
|
|
7581
|
+
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) ) {
|
|
7594
7582
|
this.open();
|
|
7583
|
+
}else {
|
|
7584
|
+
this.ping();
|
|
7595
7585
|
}
|
|
7596
7586
|
}
|
|
7597
7587
|
|
|
7598
7588
|
createConnection(url) {
|
|
7599
7589
|
// node WebSocket
|
|
7600
7590
|
this.socket = new WebSocket(url);
|
|
7601
|
-
this.stateChange('
|
|
7591
|
+
this.stateChange('connecting','connecting');
|
|
7602
7592
|
|
|
7603
7593
|
this.socket.onopen = () => {
|
|
7604
7594
|
this.socket.on('message', this.onWebSocketMessage.bind(this));
|
|
@@ -7724,7 +7714,7 @@ class RemoteCore {
|
|
|
7724
7714
|
|
|
7725
7715
|
this.state;
|
|
7726
7716
|
this.stateLog = [];
|
|
7727
|
-
this.setState(
|
|
7717
|
+
this.setState(STATE.OPEN);
|
|
7728
7718
|
|
|
7729
7719
|
}
|
|
7730
7720
|
|
|
@@ -7733,7 +7723,7 @@ class RemoteCore {
|
|
|
7733
7723
|
setState(state) {
|
|
7734
7724
|
this.state = state;
|
|
7735
7725
|
if (serverOption.debug.showAuthInfo) {
|
|
7736
|
-
|
|
7726
|
+
state = state + ":" + STATE[ state];
|
|
7737
7727
|
this.stateLog.push( state );
|
|
7738
7728
|
console.log(this.stateLog.join('>'));
|
|
7739
7729
|
}
|
|
@@ -7744,24 +7734,30 @@ class RemoteCore {
|
|
|
7744
7734
|
}
|
|
7745
7735
|
|
|
7746
7736
|
getStateName() { // <String>
|
|
7747
|
-
return (
|
|
7737
|
+
return (STATE[this.state]).toLowerCase()
|
|
7748
7738
|
}
|
|
7749
7739
|
|
|
7750
7740
|
|
|
7751
7741
|
showMessageLog(message, isBinary) {
|
|
7752
|
-
let
|
|
7742
|
+
let h = '->S ';
|
|
7743
|
+
let from = this.boho.isAuthorized ? ` did: ${this.did} cid: ${this.cid}` : ` cid: ${this.cid}`;
|
|
7744
|
+
let prnLimit = 20;
|
|
7753
7745
|
if (isBinary) {
|
|
7754
7746
|
let msgTypeName = IOMsg[message[0]];
|
|
7755
7747
|
if (!msgTypeName) msgTypeName = tt.BohoMsg[message[0]];
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7748
|
+
|
|
7749
|
+
msgTypeName = '[' + msgTypeName + ']';
|
|
7750
|
+
let size = message.byteLength;
|
|
7751
|
+
if (size < prnLimit) {
|
|
7752
|
+
console.log( h + msgTypeName + from +` [${size}]`, message);
|
|
7759
7753
|
} else {
|
|
7760
|
-
|
|
7754
|
+
let elseLen = size - prnLimit;
|
|
7755
|
+
let some = message.subarray(0,prnLimit);
|
|
7756
|
+
console.log( h + msgTypeName + from +` [${size}]` , some , ' ... else: ', elseLen);
|
|
7761
7757
|
}
|
|
7762
7758
|
|
|
7763
7759
|
} else {
|
|
7764
|
-
console.log(
|
|
7760
|
+
console.log( h + ' [TEXT] %s' + from, message);
|
|
7765
7761
|
}
|
|
7766
7762
|
}
|
|
7767
7763
|
|
|
@@ -7844,7 +7840,7 @@ class RemoteCore {
|
|
|
7844
7840
|
break;
|
|
7845
7841
|
|
|
7846
7842
|
case IOMsg.CID_REQ:
|
|
7847
|
-
if (this.state <
|
|
7843
|
+
if (this.state < STATE.SERVER_READY) {
|
|
7848
7844
|
// Protocol violation: CID_REQ was sent before receiving the SERVER_READY signal.
|
|
7849
7845
|
console.log('CID_REQ before SERVER_READY');
|
|
7850
7846
|
this.close();
|
|
@@ -7861,7 +7857,7 @@ class RemoteCore {
|
|
|
7861
7857
|
MB('#cid', this.cid)
|
|
7862
7858
|
));
|
|
7863
7859
|
|
|
7864
|
-
this.setState(
|
|
7860
|
+
this.setState(STATE.CID_RES);
|
|
7865
7861
|
break;
|
|
7866
7862
|
|
|
7867
7863
|
case IOMsg.ECHO:
|
|
@@ -7967,24 +7963,24 @@ class RemoteCore {
|
|
|
7967
7963
|
// Auth
|
|
7968
7964
|
case tt.BohoMsg.AUTH_REQ:
|
|
7969
7965
|
if (!this.manager.authManager) return
|
|
7970
|
-
if (this.state <
|
|
7966
|
+
if (this.state < STATE.SERVER_READY) {
|
|
7971
7967
|
console.log('protocol error. auth_req before server_ready');
|
|
7972
7968
|
this.close();
|
|
7973
7969
|
}
|
|
7974
|
-
this.setState(
|
|
7970
|
+
this.setState(STATE.AUTH_REQ);
|
|
7975
7971
|
let auth_nonce_pack = this.boho.auth_nonce();
|
|
7976
7972
|
// console.log('## auth_nonce_pack', auth_nonce_pack )
|
|
7977
7973
|
this.send(auth_nonce_pack);
|
|
7978
|
-
this.setState(
|
|
7974
|
+
this.setState(STATE.AUTH_NONCE);
|
|
7979
7975
|
break;
|
|
7980
7976
|
|
|
7981
7977
|
case tt.BohoMsg.AUTH_HMAC:
|
|
7982
7978
|
if (!this.manager.authManager) return
|
|
7983
|
-
if (this.state <
|
|
7979
|
+
if (this.state < STATE.AUTH_NONCE) {
|
|
7984
7980
|
console.log('protocol error. auth_hmac before server_nonce');
|
|
7985
7981
|
this.close();
|
|
7986
7982
|
}
|
|
7987
|
-
this.setState(
|
|
7983
|
+
this.setState(STATE.AUTH_HMAC);
|
|
7988
7984
|
//async
|
|
7989
7985
|
this.manager.authManager.verify_auth_hmac(message, this)
|
|
7990
7986
|
.then(authInfo => {
|
|
@@ -8134,11 +8130,42 @@ function isPrivateIP(ip) {
|
|
|
8134
8130
|
return false
|
|
8135
8131
|
}
|
|
8136
8132
|
|
|
8133
|
+
function numberWithCommas(x) {
|
|
8134
|
+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|
8135
|
+
}
|
|
8136
|
+
|
|
8137
8137
|
function getIPv4HexString(ipStr) {
|
|
8138
8138
|
let ipv4 = ipStr.split('.');
|
|
8139
8139
|
return Buffer.from(ipv4).toString('hex')
|
|
8140
8140
|
}
|
|
8141
8141
|
|
|
8142
|
+
function getLocalAddress() {
|
|
8143
|
+
const nets = networkInterfaces();
|
|
8144
|
+
// console.log(nets)
|
|
8145
|
+
const results = Object.create(null); // Or just '{}', an empty object
|
|
8146
|
+
let localAddress = '';
|
|
8147
|
+
for (const name of Object.keys(nets)) {
|
|
8148
|
+
for (const net of nets[name]) {
|
|
8149
|
+
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
|
|
8150
|
+
// 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6
|
|
8151
|
+
const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4;
|
|
8152
|
+
if (net.family === familyV4Value && !net.internal) {
|
|
8153
|
+
if (!results[name]) {
|
|
8154
|
+
results[name] = [];
|
|
8155
|
+
}
|
|
8156
|
+
results[name].push(net.address);
|
|
8157
|
+
localAddress = net.address;
|
|
8158
|
+
}
|
|
8159
|
+
}
|
|
8160
|
+
}
|
|
8161
|
+
|
|
8162
|
+
// console.log('localAddress:', localAddress)
|
|
8163
|
+
return localAddress
|
|
8164
|
+
}
|
|
8165
|
+
|
|
8166
|
+
|
|
8167
|
+
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
8168
|
+
|
|
8142
8169
|
const decoder$2 = new TextDecoder();
|
|
8143
8170
|
|
|
8144
8171
|
class Remote extends RemoteCore {
|
|
@@ -8310,6 +8337,7 @@ class Remote extends RemoteCore {
|
|
|
8310
8337
|
}
|
|
8311
8338
|
}
|
|
8312
8339
|
|
|
8340
|
+
// node.js server side remote.
|
|
8313
8341
|
send(message, isBinary) {
|
|
8314
8342
|
this.manager.txBytes += message.byteLength;
|
|
8315
8343
|
this.socket.txCounter++;
|
|
@@ -8321,13 +8349,15 @@ class Remote extends RemoteCore {
|
|
|
8321
8349
|
this.socket.send(message);
|
|
8322
8350
|
}
|
|
8323
8351
|
} else {
|
|
8352
|
+
console.log('server(ws)Remote.send() called. not open state. current readyState:', this.socket.readyState );
|
|
8324
8353
|
this.close(true);
|
|
8325
8354
|
}
|
|
8326
|
-
|
|
8355
|
+
|
|
8327
8356
|
} else { //CongSocket
|
|
8328
8357
|
if (this.socket.readyState == 'open') {
|
|
8329
8358
|
this.socket.write(pack(message));
|
|
8330
8359
|
} else {
|
|
8360
|
+
console.log('server(cong)Remote.send() called. not open state. current readyState:', this.socket.readyState );
|
|
8331
8361
|
this.close(true);
|
|
8332
8362
|
}
|
|
8333
8363
|
}
|
|
@@ -8583,7 +8613,7 @@ class Manager {
|
|
|
8583
8613
|
let remote = new Remote(socket, req, this);
|
|
8584
8614
|
this.remotes.add(remote);
|
|
8585
8615
|
remote.send(Buffer.from([IOMsg.SERVER_READY]));
|
|
8586
|
-
remote.setState(
|
|
8616
|
+
remote.setState(STATE.SERVER_READY);
|
|
8587
8617
|
this.lastSSID = remote.ssid;
|
|
8588
8618
|
let connectionInfo = `+ IP:${remote.ip} #${remote.ssid} ${socket.socketType === 'websocket' ? "WS" : "CS"} `;
|
|
8589
8619
|
// console.log( connectionInfo)
|
|
@@ -8698,8 +8728,8 @@ class Manager {
|
|
|
8698
8728
|
|
|
8699
8729
|
sender(tag, remote, message) {
|
|
8700
8730
|
if (serverOption.membersOnly && !remote.boho.isAuthorized) {
|
|
8701
|
-
console.log("[membersOnly]
|
|
8702
|
-
remote.send(Buffer.from([IOMsg.
|
|
8731
|
+
// console.log("### server reject client signal reason: [membersOnly]" ,tag, remote.cid )
|
|
8732
|
+
remote.send(Buffer.from([IOMsg.AUTH_CLEAR]));
|
|
8703
8733
|
remote.close();
|
|
8704
8734
|
return ['err', 'unAuthorized']
|
|
8705
8735
|
}
|
|
@@ -9027,7 +9057,7 @@ class Server extends require$$0$3 {
|
|
|
9027
9057
|
|
|
9028
9058
|
this.wss.once('listening', () => {
|
|
9029
9059
|
this.port = this.wss.address().port;
|
|
9030
|
-
console.log('wss server bound port:', this.port );
|
|
9060
|
+
// console.log('wss server bound port:', this.port );
|
|
9031
9061
|
this.listeningServerCount++;
|
|
9032
9062
|
if (this.listeningServerCount === this.serverCountToListen) {
|
|
9033
9063
|
this.emit('ready');
|
|
@@ -9043,7 +9073,7 @@ class Server extends require$$0$3 {
|
|
|
9043
9073
|
});
|
|
9044
9074
|
|
|
9045
9075
|
this.wss.on('close', () => {
|
|
9046
|
-
console.log('### WS server is closed.')
|
|
9076
|
+
// console.log('### WS server is closed.')
|
|
9047
9077
|
});
|
|
9048
9078
|
|
|
9049
9079
|
this.wss.on('connection', (ws, req) => {
|
|
@@ -9064,10 +9094,10 @@ class Server extends require$$0$3 {
|
|
|
9064
9094
|
process.exit();
|
|
9065
9095
|
}
|
|
9066
9096
|
}).on('close', () => {
|
|
9067
|
-
console.log('### congsocket server is closed.')
|
|
9097
|
+
// console.log('### congsocket server is closed.')
|
|
9068
9098
|
}).listen(this.congPort, () => {
|
|
9069
9099
|
this.congPort = this.congServer.address().port;
|
|
9070
|
-
console.log('congsocket server bound port:', this.congPort );
|
|
9100
|
+
// console.log('congsocket server bound port:', this.congPort );
|
|
9071
9101
|
this.listeningServerCount++;
|
|
9072
9102
|
if (this.listeningServerCount === this.serverCountToListen) {
|
|
9073
9103
|
this.emit('ready');
|
|
@@ -9102,7 +9132,7 @@ class Server extends require$$0$3 {
|
|
|
9102
9132
|
return
|
|
9103
9133
|
}
|
|
9104
9134
|
if( api.commands.includes( req.topic )){
|
|
9105
|
-
console.log('server api req', req )
|
|
9135
|
+
// console.log('server api req', req )
|
|
9106
9136
|
await api.request(remote, req);
|
|
9107
9137
|
}else {
|
|
9108
9138
|
remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
|
|
@@ -9132,7 +9162,7 @@ class Server extends require$$0$3 {
|
|
|
9132
9162
|
});
|
|
9133
9163
|
}
|
|
9134
9164
|
this.apiNames.add(target);
|
|
9135
|
-
console.log(`[API registed: ${target} ] accept commands: ${api.commands}`)
|
|
9165
|
+
// console.log(`[API registed: ${target} ] accept commands: ${api.commands}`)
|
|
9136
9166
|
return this
|
|
9137
9167
|
}
|
|
9138
9168
|
|
|
@@ -9172,7 +9202,7 @@ class Server extends require$$0$3 {
|
|
|
9172
9202
|
|
|
9173
9203
|
if (this.congServer) {
|
|
9174
9204
|
this.congServer.close((err) => {
|
|
9175
|
-
if (err) console.error('congServer close error', err)
|
|
9205
|
+
// if (err) console.error('congServer close error', err)
|
|
9176
9206
|
// console.log('cong server closed.')
|
|
9177
9207
|
onClosed();
|
|
9178
9208
|
});
|
|
@@ -9183,7 +9213,12 @@ class Server extends require$$0$3 {
|
|
|
9183
9213
|
|
|
9184
9214
|
const decoder = new TextDecoder();
|
|
9185
9215
|
class BohoAuth {
|
|
9186
|
-
constructor() {
|
|
9216
|
+
constructor(keyProvider) {
|
|
9217
|
+
if (!keyProvider) {
|
|
9218
|
+
throw new Error('BohoAuth must be initialized with a keyProvider.');
|
|
9219
|
+
}
|
|
9220
|
+
this.keyProvider = keyProvider;
|
|
9221
|
+
|
|
9187
9222
|
this.authLogger;
|
|
9188
9223
|
if (serverOption.fileLogger.auth.use) {
|
|
9189
9224
|
this.authLogger = new FileLogger(serverOption.fileLogger.auth.path);
|
|
@@ -9197,11 +9232,11 @@ class BohoAuth {
|
|
|
9197
9232
|
this.authLogger.log(peerInfo);
|
|
9198
9233
|
}
|
|
9199
9234
|
// console.log('##### AUTH_FAIL reason: ', reason)
|
|
9200
|
-
peer.setState(
|
|
9235
|
+
peer.setState(STATE.AUTH_FAIL);
|
|
9236
|
+
peer.send(Buffer.from([tt.BohoMsg.AUTH_FAIL]));
|
|
9201
9237
|
// add some delay time.
|
|
9202
|
-
setTimeout(e => {
|
|
9203
|
-
|
|
9204
|
-
}, serverOption.auth.delay_auth_fail);
|
|
9238
|
+
// setTimeout(e => {
|
|
9239
|
+
// }, serverOption.auth.delay_auth_fail)
|
|
9205
9240
|
}
|
|
9206
9241
|
|
|
9207
9242
|
async verify_auth_hmac(auth_hmac, peer) {
|
|
@@ -9222,7 +9257,7 @@ class BohoAuth {
|
|
|
9222
9257
|
}
|
|
9223
9258
|
|
|
9224
9259
|
//2. get key of id from DB
|
|
9225
|
-
let authInfo = await this.getAuth(id);
|
|
9260
|
+
let authInfo = await this.keyProvider.getAuth(id);
|
|
9226
9261
|
|
|
9227
9262
|
if (!authInfo) {
|
|
9228
9263
|
this.send_auth_fail(peer, 'NO ID:' + id);
|
|
@@ -9273,9 +9308,13 @@ class BohoAuth {
|
|
|
9273
9308
|
console.log('## trying RELOGIN with SAME ID. ignored.');
|
|
9274
9309
|
return
|
|
9275
9310
|
}
|
|
9276
|
-
console.log('###
|
|
9277
|
-
|
|
9278
|
-
|
|
9311
|
+
console.log('### DUPLICATE_LOGIN detected.', old.cid);
|
|
9312
|
+
let sigPack = M$1.pack(
|
|
9313
|
+
M$1.MB('#MsgType', '8', IOMsg.AUTH_CLEAR),
|
|
9314
|
+
M$1.MB('#reason', 'duplicate login.')
|
|
9315
|
+
);
|
|
9316
|
+
old.send( sigPack);
|
|
9317
|
+
// old.close() client will close and stop.
|
|
9279
9318
|
peer.close(); // auto relogin
|
|
9280
9319
|
return
|
|
9281
9320
|
}
|
|
@@ -9322,7 +9361,7 @@ class BohoAuth {
|
|
|
9322
9361
|
// console.log("LOGIN: ", `id: ${ peer.did}(${peer.cid})` )
|
|
9323
9362
|
//10. send ack.
|
|
9324
9363
|
peer.send(auth_ack);
|
|
9325
|
-
peer.setState(
|
|
9364
|
+
peer.setState(STATE.AUTH_ACK);
|
|
9326
9365
|
if (this.authLogger) {
|
|
9327
9366
|
let peerInfo = `OK #${peer.ssid} cid: ${peer.cid} did:${peer.did}`;
|
|
9328
9367
|
if (peer.isAdmin) peerInfo = "#ADMIN# " + peerInfo;
|
|
@@ -9335,12 +9374,39 @@ class BohoAuth {
|
|
|
9335
9374
|
|
|
9336
9375
|
}
|
|
9337
9376
|
|
|
9377
|
+
async getAuth(id) {
|
|
9378
|
+
return this.keyProvider.getAuth(id);
|
|
9379
|
+
}
|
|
9380
|
+
|
|
9381
|
+
async getAuthIdList() {
|
|
9382
|
+
if (typeof this.keyProvider.getAuthIdList === 'function') {
|
|
9383
|
+
return this.keyProvider.getAuthIdList();
|
|
9384
|
+
}
|
|
9385
|
+
}
|
|
9386
|
+
|
|
9387
|
+
async addAuth(id, keyStr, cid, level = 0) {
|
|
9388
|
+
if (typeof this.keyProvider.addAuth === 'function') {
|
|
9389
|
+
return this.keyProvider.addAuth(id, keyStr, cid, level);
|
|
9390
|
+
}
|
|
9391
|
+
}
|
|
9392
|
+
|
|
9393
|
+
async delAuth(id) {
|
|
9394
|
+
if (typeof this.keyProvider.delAuth === 'function') {
|
|
9395
|
+
return this.keyProvider.delAuth(id);
|
|
9396
|
+
}
|
|
9397
|
+
}
|
|
9398
|
+
|
|
9399
|
+
async save() {
|
|
9400
|
+
if (typeof this.keyProvider.save === 'function') {
|
|
9401
|
+
return this.keyProvider.save();
|
|
9402
|
+
}
|
|
9403
|
+
}
|
|
9404
|
+
|
|
9338
9405
|
|
|
9339
9406
|
}
|
|
9340
9407
|
|
|
9341
|
-
class
|
|
9408
|
+
class FileKeyProvider {
|
|
9342
9409
|
constructor(_path) {
|
|
9343
|
-
super();
|
|
9344
9410
|
this.AUTH = new Map();
|
|
9345
9411
|
let pathObj = path.parse(_path);
|
|
9346
9412
|
this.path = path.resolve(_path);
|
|
@@ -9358,20 +9424,9 @@ class Auth_File extends BohoAuth {
|
|
|
9358
9424
|
}
|
|
9359
9425
|
}
|
|
9360
9426
|
|
|
9361
|
-
|
|
9362
|
-
async getAuth(id) {
|
|
9363
|
-
return this.AUTH.get(id)
|
|
9364
|
-
}
|
|
9365
|
-
|
|
9366
|
-
async getAuthIdList() {
|
|
9367
|
-
return Array.from(this.AUTH.keys())
|
|
9368
|
-
}
|
|
9369
|
-
|
|
9370
9427
|
//loaded when server start.
|
|
9371
9428
|
loadAuthInfoFile_JS(path) {
|
|
9372
|
-
|
|
9373
9429
|
import(path).then((file) => {
|
|
9374
|
-
|
|
9375
9430
|
console.log(file.authInfo);
|
|
9376
9431
|
file.authInfo.forEach(item => {
|
|
9377
9432
|
this.addAuth(...item);
|
|
@@ -9380,8 +9435,6 @@ class Auth_File extends BohoAuth {
|
|
|
9380
9435
|
}).catch(e => {
|
|
9381
9436
|
console.log(e);
|
|
9382
9437
|
});
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
9438
|
}
|
|
9386
9439
|
|
|
9387
9440
|
loadAuthInfoFile_JSON(path) {
|
|
@@ -9392,81 +9445,12 @@ class Auth_File extends BohoAuth {
|
|
|
9392
9445
|
this.addAuth(...item);
|
|
9393
9446
|
});
|
|
9394
9447
|
console.log('total AUTH INFO size: ', this.AUTH.size);
|
|
9395
|
-
|
|
9396
|
-
}
|
|
9397
|
-
|
|
9398
|
-
addAuth(id, keyStr, cid, level = 0) {
|
|
9399
|
-
let Base64hashKey = Buffer.from(tt.sha256.hash(keyStr)).toString('base64');
|
|
9400
|
-
this.AUTH.set(id, { key: Base64hashKey, cid: cid, level: level });
|
|
9401
|
-
}
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
}
|
|
9406
|
-
|
|
9407
|
-
/**
|
|
9408
|
-
* Auth_Env.js
|
|
9409
|
-
*
|
|
9410
|
-
* You can use environment variable BOHO_AUTH.
|
|
9411
|
-
*
|
|
9412
|
-
* BOHO_AUTH=id1.key1.level,id2:key2.level
|
|
9413
|
-
*
|
|
9414
|
-
* or constructor parameter.
|
|
9415
|
-
*
|
|
9416
|
-
*
|
|
9417
|
-
* [ authInfo ]
|
|
9418
|
-
* id: <String> max 8chars
|
|
9419
|
-
* key: <String>
|
|
9420
|
-
* level: <Numbrer> range: 0~255
|
|
9421
|
-
* separator: ','
|
|
9422
|
-
*
|
|
9423
|
-
* example => process.env.BOHO_AUTH=id1.key1.255,id2.key2.200
|
|
9424
|
-
*/
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
class Auth_Env extends BohoAuth {
|
|
9428
|
-
constructor(authInfo) {
|
|
9429
|
-
super();
|
|
9430
|
-
let id_keys;
|
|
9431
|
-
if (authInfo) {
|
|
9432
|
-
id_keys = authInfo.split(',');
|
|
9433
|
-
} else if (process.env.BOHO_AUTH) {
|
|
9434
|
-
authInfo = process.env.BOHO_AUTH;
|
|
9435
|
-
id_keys = process.env.BOHO_AUTH.split(',');
|
|
9436
|
-
} else {
|
|
9437
|
-
console.log("Auth_Env: None of process.env.BOHO_AUTH or authInfo");
|
|
9438
|
-
process.exit();
|
|
9439
|
-
}
|
|
9440
|
-
|
|
9441
|
-
this.AUTH = new Map();
|
|
9442
|
-
|
|
9443
|
-
if (id_keys.length >= 1) {
|
|
9444
|
-
id_keys.forEach(v => {
|
|
9445
|
-
|
|
9446
|
-
let did = v.split('.')[0];
|
|
9447
|
-
let key = v.split('.')[1];
|
|
9448
|
-
let level = v.split('.')[2];
|
|
9449
|
-
level = parseInt(level);
|
|
9450
|
-
|
|
9451
|
-
if (did && key && typeof level == 'number') {
|
|
9452
|
-
let cid = did;
|
|
9453
|
-
this.addAuth(did, key, cid, level);
|
|
9454
|
-
} else {
|
|
9455
|
-
console.log("Wrong process.env.BOHO_AUTH authentication value.", id, key, level);
|
|
9456
|
-
process.exit();
|
|
9457
|
-
}
|
|
9458
|
-
});
|
|
9459
|
-
|
|
9460
|
-
} else {
|
|
9461
|
-
console.log("Wrong process.env.BOHO_AUTH authentication value.");
|
|
9462
|
-
process.exit();
|
|
9463
|
-
}
|
|
9464
|
-
|
|
9465
9448
|
}
|
|
9466
9449
|
|
|
9467
9450
|
async getAuth(id) {
|
|
9468
9451
|
return this.AUTH.get(id)
|
|
9469
9452
|
}
|
|
9453
|
+
|
|
9470
9454
|
async getAuthIdList() {
|
|
9471
9455
|
return Array.from(this.AUTH.keys())
|
|
9472
9456
|
}
|
|
@@ -9475,16 +9459,14 @@ class Auth_Env extends BohoAuth {
|
|
|
9475
9459
|
let Base64hashKey = Buffer.from(tt.sha256.hash(keyStr)).toString('base64');
|
|
9476
9460
|
this.AUTH.set(id, { key: Base64hashKey, cid: cid, level: level });
|
|
9477
9461
|
}
|
|
9478
|
-
|
|
9479
9462
|
}
|
|
9480
9463
|
|
|
9481
9464
|
const DEVICE_PREFIX = "device:";
|
|
9482
9465
|
|
|
9483
|
-
class
|
|
9466
|
+
class RedisKeyProvider {
|
|
9484
9467
|
constructor(redisClient) {
|
|
9485
|
-
super();
|
|
9486
9468
|
if (!redisClient) {
|
|
9487
|
-
throw new Error("
|
|
9469
|
+
throw new Error("RedisKeyProvider constructor: no redisClient")
|
|
9488
9470
|
}
|
|
9489
9471
|
this.redis = redisClient;
|
|
9490
9472
|
}
|
|
@@ -9493,7 +9475,8 @@ class Auth_Redis extends BohoAuth {
|
|
|
9493
9475
|
async getAuth(id) {
|
|
9494
9476
|
try {
|
|
9495
9477
|
let result = await this.redis.hGetAll(DEVICE_PREFIX + id);
|
|
9496
|
-
if (result.key) return result
|
|
9478
|
+
if (result && result.key) return result
|
|
9479
|
+
else return null;
|
|
9497
9480
|
} catch (error) {
|
|
9498
9481
|
console.log('getAuth', error);
|
|
9499
9482
|
}
|
|
@@ -9522,7 +9505,60 @@ class Auth_Redis extends BohoAuth {
|
|
|
9522
9505
|
async save(id) {
|
|
9523
9506
|
return this.redis.save()
|
|
9524
9507
|
}
|
|
9508
|
+
}
|
|
9509
|
+
|
|
9510
|
+
/**
|
|
9511
|
+
* StringKeyProvider.js
|
|
9512
|
+
*
|
|
9513
|
+
* authInfo <String>
|
|
9514
|
+
* id: max 8chars
|
|
9515
|
+
* key: ~44 base64 chars recomended
|
|
9516
|
+
* cid:
|
|
9517
|
+
* level: range: 0~255
|
|
9518
|
+
* separator: ',' for multiple devices.
|
|
9519
|
+
*
|
|
9520
|
+
* example => authInfo = 'id1.key1.cid1.255,id2.key2.cid2.200'
|
|
9521
|
+
*/
|
|
9522
|
+
|
|
9523
|
+
|
|
9524
|
+
class StringKeyProvider {
|
|
9525
|
+
constructor(authInfo) {
|
|
9526
|
+
|
|
9527
|
+
if (!authInfo) {
|
|
9528
|
+
throw TypeError("StringKeyProvider constructor() missing authInfo.")
|
|
9529
|
+
}
|
|
9530
|
+
|
|
9531
|
+
let id_keys = authInfo.split(',');
|
|
9532
|
+
|
|
9533
|
+
this.AUTH = new Map();
|
|
9534
|
+
|
|
9535
|
+
if (id_keys.length >= 1) {
|
|
9536
|
+
id_keys.forEach(v => {
|
|
9537
|
+
let [ did, key, cid, level ] = v.split('.');
|
|
9538
|
+
level = parseInt(level);
|
|
9539
|
+
if (did && key && cid && typeof level == 'number') {
|
|
9540
|
+
this.addAuth(did, key, cid, level);
|
|
9541
|
+
} else {
|
|
9542
|
+
throw TypeError("StringKeyProvider invalid authInfo.")
|
|
9543
|
+
}
|
|
9544
|
+
});
|
|
9545
|
+
} else {
|
|
9546
|
+
throw TypeError("StringKeyProvider invalid authInfo.")
|
|
9547
|
+
}
|
|
9548
|
+
|
|
9549
|
+
}
|
|
9525
9550
|
|
|
9551
|
+
async getAuth(id) {
|
|
9552
|
+
return this.AUTH.get(id)
|
|
9553
|
+
}
|
|
9554
|
+
async getAuthIdList() {
|
|
9555
|
+
return Array.from(this.AUTH.keys())
|
|
9556
|
+
}
|
|
9557
|
+
|
|
9558
|
+
addAuth(id, keyStr, cid, level = 0) {
|
|
9559
|
+
let Base64hashKey = Buffer.from(tt.sha256.hash(keyStr)).toString('base64');
|
|
9560
|
+
this.AUTH.set(id, { key: Base64hashKey, cid: cid, level: level });
|
|
9561
|
+
}
|
|
9526
9562
|
}
|
|
9527
9563
|
|
|
9528
9564
|
const commands$1 = ['echo', 'date', 'unixtime'];
|
|
@@ -9707,4 +9743,4 @@ class RedisAPI {
|
|
|
9707
9743
|
|
|
9708
9744
|
const version = pkg.version;
|
|
9709
9745
|
|
|
9710
|
-
export { API_TYPE,
|
|
9746
|
+
export { API_TYPE, tt as Boho, BohoAuth, CongRx, ENC_MODE, FileKeyProvider, FileLogger, IOWS as IO, IOCongSocket, IOMsg, M$1 as MBP, PAYLOAD_TYPE, RedisAPI, RedisKeyProvider, SIZE_LIMIT, STATE, STATUS$1 as STATUS, Server, StringKeyProvider, api_reply, api_sudo, delay, getIPv4HexString, getLocalAddress, getPayloadFromSignalPack, getSignalPack, isPrivateIP, numberWithCommas, pack, parsePayload, serverOption, version };
|