iosignal 3.2.0 → 4.0.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 +3 -0
- package/README.en.md +56 -0
- package/README.md +39 -782
- package/dist/io.d.ts +10 -3
- package/dist/io.js +4 -4
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +4 -4
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +266 -217
- package/dist/types/client/IOCore.d.ts +10 -3
- package/package.json +3 -4
- package/src/api/RedisAPI.js +19 -31
- package/src/api/api_reply.js +14 -6
- package/src/api/api_sudo.js +2 -8
- package/src/auth/Auth_Redis.js +8 -3
- package/src/auth/BohoAuth.js +12 -12
- package/src/client/CongPacket.js +2 -0
- package/src/client/IOCore.js +98 -52
- package/src/server/Manager.js +12 -12
- package/src/server/Metric.js +1 -2
- package/src/server/RemoteCore.js +27 -34
- package/src/server/Server.js +69 -60
- package/src/server/serverOption.js +3 -2
- package/README.ko.md +0 -566
- package/docs/iosignal_architecture.png +0 -0
- package/examples/react-chat-js/dist/assets/index-Cy4qaVcJ.js +0 -56
- package/examples/react-chat-js/dist/assets/index-NETrjYhz.css +0 -1
- package/examples/react-chat-js/dist/index.html +0 -14
- package/examples/react-chat-js/index.html +0 -13
- package/examples/react-chat-js/package-lock.json +0 -1723
- package/examples/react-chat-js/package.json +0 -20
- package/examples/react-chat-js/src/App.css +0 -61
- package/examples/react-chat-js/src/App.jsx +0 -125
- package/examples/react-chat-js/src/index.css +0 -13
- package/examples/react-chat-js/src/main.jsx +0 -13
- package/examples/react-chat-js/src/shared_io.js +0 -12
- package/examples/react-chat-js/vite.config.js +0 -7
- package/examples/server/index.js +0 -12
- package/examples/server/package-lock.json +0 -47
- package/examples/server/package.json +0 -12
- package/examples/svelte-chat-js/.devtools +0 -3
- package/examples/svelte-chat-js/README.md +0 -38
- package/examples/svelte-chat-js/package-lock.json +0 -1505
- package/examples/svelte-chat-js/package.json +0 -22
- package/examples/svelte-chat-js/src/app.css +0 -105
- package/examples/svelte-chat-js/src/app.d.ts +0 -13
- package/examples/svelte-chat-js/src/app.html +0 -12
- package/examples/svelte-chat-js/src/lib/images/github.svg +0 -1
- package/examples/svelte-chat-js/src/lib/images/svelte-logo.svg +0 -1
- package/examples/svelte-chat-js/src/lib/images/svelte-welcome.png +0 -0
- package/examples/svelte-chat-js/src/lib/images/svelte-welcome.webp +0 -0
- package/examples/svelte-chat-js/src/lib/shared_io.js +0 -12
- package/examples/svelte-chat-js/src/routes/+layout.svelte +0 -9
- package/examples/svelte-chat-js/src/routes/+page.js +0 -3
- package/examples/svelte-chat-js/src/routes/+page.svelte +0 -162
- package/examples/svelte-chat-js/static/favicon.svg +0 -1
- package/examples/svelte-chat-js/static/global.css +0 -19
- package/examples/svelte-chat-js/static/robots.txt +0 -3
- package/examples/svelte-chat-js/svelte.config.js +0 -15
- package/examples/svelte-chat-js/vite.config.js +0 -6
- package/test-browser/favicon.ico +0 -0
- package/test-browser/index.html +0 -95
- package/test-browser/server.js +0 -12
- package/test-nodejs/client-playToggle.js +0 -19
- package/test-nodejs/client.js +0 -17
- package/test-nodejs/client_api_reply.js +0 -15
- package/test-nodejs/server-Auth_Env.js +0 -19
- package/test-nodejs/server-Auth_File.js +0 -12
- package/test-nodejs/server-api_reply.js +0 -6
- package/test-nodejs/server-api_sudo.js +0 -7
- package/test-nodejs/server.js +0 -20
- package/test-nodejs/signalPack.js +0 -34
- package/test-nodejs/signaling.js +0 -61
- package/test-nodejs/simple-server.js +0 -13
- /package/{auth_file.js → auth_file_sample.js} +0 -0
- /package/{auth_file.json → auth_file_sample.json} +0 -0
package/dist/iosignal.js
CHANGED
|
@@ -13,7 +13,7 @@ import require$$2 from 'os';
|
|
|
13
13
|
import require$$0$1 from 'buffer';
|
|
14
14
|
import { memoryUsage } from 'process';
|
|
15
15
|
|
|
16
|
-
var version$1 = "
|
|
16
|
+
var version$1 = "4.0.0";
|
|
17
17
|
var pkg = {
|
|
18
18
|
version: version$1};
|
|
19
19
|
|
|
@@ -985,7 +985,7 @@ class IOCore extends EventEmitter {
|
|
|
985
985
|
close() {
|
|
986
986
|
if (this._closed) return;
|
|
987
987
|
this._closed = true;
|
|
988
|
-
|
|
988
|
+
// console.log('####### IOCOre.js close() called')
|
|
989
989
|
// If auto-reconnect is disabled, we must stop the keep-alive timer.
|
|
990
990
|
if (this.autoReconnect === false) {
|
|
991
991
|
clearInterval(this.connectionCheckerIntervalID);
|
|
@@ -1206,13 +1206,25 @@ class IOCore extends EventEmitter {
|
|
|
1206
1206
|
case IOMsg.PONG:
|
|
1207
1207
|
break;
|
|
1208
1208
|
|
|
1209
|
+
case IOMsg.ECHO:
|
|
1210
|
+
try {
|
|
1211
|
+
let str = decoder$4.decode(buffer.subarray(1));
|
|
1212
|
+
|
|
1213
|
+
this.emit('echo', str);
|
|
1214
|
+
} catch (error) {
|
|
1215
|
+
this.emit('error', new Error('ECHO data error'));
|
|
1216
|
+
}
|
|
1217
|
+
break;
|
|
1218
|
+
|
|
1209
1219
|
case IOMsg.IAM_RES:
|
|
1210
1220
|
try {
|
|
1211
1221
|
let str = decoder$4.decode(buffer.subarray(1));
|
|
1212
1222
|
let jsonInfo = JSON.parse(str);
|
|
1213
|
-
if (jsonInfo.ip) {
|
|
1214
|
-
|
|
1215
|
-
}
|
|
1223
|
+
if (jsonInfo.ip) { this.ip = jsonInfo.ip; }
|
|
1224
|
+
if (jsonInfo.nick) { this.nick = jsonInfo.nick; }
|
|
1225
|
+
if (jsonInfo.did) { this.did = jsonInfo.did; }
|
|
1226
|
+
if (jsonInfo.uid) { this.uid = jsonInfo.uid; }
|
|
1227
|
+
this.emit('iam_res', str );
|
|
1216
1228
|
} catch (error) {
|
|
1217
1229
|
this.emit('error', new Error('IAM_RES data error'));
|
|
1218
1230
|
}
|
|
@@ -1223,7 +1235,7 @@ class IOCore extends EventEmitter {
|
|
|
1223
1235
|
this.cid = cidStr;
|
|
1224
1236
|
|
|
1225
1237
|
// **IMPORTANT** change state before subscribe.
|
|
1226
|
-
this.stateChange('ready', 'cid_ready');
|
|
1238
|
+
this.stateChange('ready', 'cid_ready');
|
|
1227
1239
|
this.subscribe_memory_channels();
|
|
1228
1240
|
break;
|
|
1229
1241
|
|
|
@@ -1231,13 +1243,14 @@ class IOCore extends EventEmitter {
|
|
|
1231
1243
|
let quotaLevel = buffer[1];
|
|
1232
1244
|
this.level = quotaLevel;
|
|
1233
1245
|
this.quota = quotaTable[quotaLevel];
|
|
1234
|
-
console.log('
|
|
1246
|
+
console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota));
|
|
1235
1247
|
break;
|
|
1236
1248
|
|
|
1237
1249
|
case IOMsg.SERVER_CLEAR_AUTH:
|
|
1238
1250
|
this.useAuth = false;
|
|
1239
1251
|
this.boho.clearAuth();
|
|
1240
1252
|
this.stop();
|
|
1253
|
+
console.log('[SERVER_CLEAR_AUTH] io stop.');
|
|
1241
1254
|
break;
|
|
1242
1255
|
|
|
1243
1256
|
case IOMsg.SERVER_REDIRECT:
|
|
@@ -1311,8 +1324,11 @@ class IOCore extends EventEmitter {
|
|
|
1311
1324
|
switch (payloadType) {
|
|
1312
1325
|
|
|
1313
1326
|
case PAYLOAD_TYPE.EMPTY:
|
|
1314
|
-
if (tag.indexOf('@') === 0) this.emit('@',
|
|
1315
|
-
else
|
|
1327
|
+
if (tag.indexOf('@') === 0) this.emit('@', tag, null);
|
|
1328
|
+
else {
|
|
1329
|
+
this.emit(tag, tag, null);
|
|
1330
|
+
this.emit('message', tag, null );
|
|
1331
|
+
}
|
|
1316
1332
|
break;
|
|
1317
1333
|
|
|
1318
1334
|
case PAYLOAD_TYPE.TEXT:
|
|
@@ -1323,33 +1339,48 @@ class IOCore extends EventEmitter {
|
|
|
1323
1339
|
payloadStringWithoutNull = payloadBuffer.subarray(0, payloadBuffer.byteLength - 1);
|
|
1324
1340
|
}
|
|
1325
1341
|
let oneString = decoder$4.decode(payloadStringWithoutNull);
|
|
1326
|
-
if (tag.indexOf('@') === 0) this.emit('@',
|
|
1327
|
-
if (tag !== '@')
|
|
1342
|
+
if (tag.indexOf('@') === 0) this.emit('@', tag, oneString);
|
|
1343
|
+
if (tag !== '@'){
|
|
1344
|
+
this.emit(tag, tag, oneString);
|
|
1345
|
+
this.emit('message', tag, oneString);
|
|
1346
|
+
}
|
|
1328
1347
|
break;
|
|
1329
1348
|
|
|
1330
1349
|
case PAYLOAD_TYPE.BINARY:
|
|
1331
|
-
if (tag.indexOf('@') === 0) this.emit('@',
|
|
1332
|
-
if (tag !== '@')
|
|
1350
|
+
if (tag.indexOf('@') === 0) this.emit('@', tag, payloadBuffer);
|
|
1351
|
+
if (tag !== '@'){
|
|
1352
|
+
this.emit(tag, tag, payloadBuffer);
|
|
1353
|
+
this.emit('message', tag, payloadBuffer);
|
|
1354
|
+
}
|
|
1333
1355
|
break;
|
|
1334
1356
|
|
|
1335
1357
|
case PAYLOAD_TYPE.OBJECT:
|
|
1336
1358
|
let oneObjectBuffer = decoder$4.decode(payloadBuffer);
|
|
1337
1359
|
let oneJSONObject = JSON.parse(oneObjectBuffer);
|
|
1338
|
-
if (tag.indexOf('@') === 0) this.emit('@',
|
|
1339
|
-
if (tag !== '@')
|
|
1360
|
+
if (tag.indexOf('@') === 0) this.emit('@', tag, oneJSONObject);
|
|
1361
|
+
if (tag !== '@'){
|
|
1362
|
+
this.emit(tag, tag, oneJSONObject);
|
|
1363
|
+
this.emit('message', tag, oneJSONObject);
|
|
1364
|
+
}
|
|
1340
1365
|
break;
|
|
1341
1366
|
|
|
1342
1367
|
case PAYLOAD_TYPE.MJSON:
|
|
1343
1368
|
let mjsonBuffer = decoder$4.decode(payloadBuffer);
|
|
1344
1369
|
let mjson = JSON.parse(mjsonBuffer);
|
|
1345
|
-
if (tag.indexOf('@') === 0) this.emit('@', ...mjson
|
|
1346
|
-
if (tag !== '@')
|
|
1370
|
+
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mjson);
|
|
1371
|
+
if (tag !== '@'){
|
|
1372
|
+
this.emit(tag, tag, ...mjson);
|
|
1373
|
+
this.emit('message', tag, ...mjson);
|
|
1374
|
+
}
|
|
1347
1375
|
break;
|
|
1348
1376
|
|
|
1349
1377
|
case PAYLOAD_TYPE.MBA:
|
|
1350
1378
|
let mbaObject = M$1.unpack(payloadBuffer);
|
|
1351
|
-
if (tag.indexOf('@') === 0) this.emit('@', ...mbaObject.args
|
|
1352
|
-
if (tag !== '@')
|
|
1379
|
+
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mbaObject.args);
|
|
1380
|
+
if (tag !== '@'){
|
|
1381
|
+
this.emit(tag, tag, ...mbaObject.args);
|
|
1382
|
+
this.emit('message', tag, ...mbaObject.args );
|
|
1383
|
+
}
|
|
1353
1384
|
break;
|
|
1354
1385
|
|
|
1355
1386
|
default:
|
|
@@ -1441,7 +1472,7 @@ class IOCore extends EventEmitter {
|
|
|
1441
1472
|
*/
|
|
1442
1473
|
echo(args) {
|
|
1443
1474
|
if (args) {
|
|
1444
|
-
console.log('echo args:', args)
|
|
1475
|
+
// console.log('send echo args:', args)
|
|
1445
1476
|
this.send_enc_mode(M$1.pack(
|
|
1446
1477
|
M$1.MB('#MsgType', '8', IOMsg.ECHO),
|
|
1447
1478
|
M$1.MB('#msg', args)
|
|
@@ -1530,13 +1561,13 @@ class IOCore extends EventEmitter {
|
|
|
1530
1561
|
*/
|
|
1531
1562
|
setMsgPromise(mid) {
|
|
1532
1563
|
return new Promise((resolve, reject) => {
|
|
1533
|
-
|
|
1534
|
-
setTimeout(e => {
|
|
1564
|
+
const timeoutId = setTimeout(e => {
|
|
1535
1565
|
if (this.promiseMap.has(mid)) {
|
|
1536
1566
|
reject('timeout');
|
|
1537
1567
|
this.promiseMap.delete(mid);
|
|
1538
1568
|
}
|
|
1539
1569
|
}, this.promiseTimeOut);
|
|
1570
|
+
this.promiseMap.set(mid, [resolve, reject, timeoutId]);
|
|
1540
1571
|
})
|
|
1541
1572
|
}
|
|
1542
1573
|
|
|
@@ -1550,7 +1581,8 @@ class IOCore extends EventEmitter {
|
|
|
1550
1581
|
if (!res) return
|
|
1551
1582
|
|
|
1552
1583
|
if (this.promiseMap.has(res.mid)) {
|
|
1553
|
-
let [resolve, reject] = this.promiseMap.get(res.mid);
|
|
1584
|
+
let [resolve, reject, timeoutId] = this.promiseMap.get(res.mid);
|
|
1585
|
+
clearTimeout(timeoutId);
|
|
1554
1586
|
this.promiseMap.delete(res.mid);
|
|
1555
1587
|
|
|
1556
1588
|
if (res.status < 128) {
|
|
@@ -1659,9 +1691,9 @@ class IOCore extends EventEmitter {
|
|
|
1659
1691
|
|
|
1660
1692
|
|
|
1661
1693
|
/**
|
|
1662
|
-
* Sends a request to a target and topic.
|
|
1663
|
-
* @param {string} target - The target of the request.
|
|
1664
|
-
* @param {string} topic - The topic of the request.
|
|
1694
|
+
* Sends a request to a target and topic.(remote api call)
|
|
1695
|
+
* @param {string} target - The target(api name) of the request.
|
|
1696
|
+
* @param {string} topic - The topic(api function name) of the request.
|
|
1665
1697
|
* @param {...any} args - Optional arguments for the request.
|
|
1666
1698
|
* @returns {Promise<any>}
|
|
1667
1699
|
*/
|
|
@@ -1697,21 +1729,24 @@ class IOCore extends EventEmitter {
|
|
|
1697
1729
|
*/
|
|
1698
1730
|
subscribe(tag) {
|
|
1699
1731
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1732
|
+
if (tag.length > SIZE_LIMIT.TAG_LEN1) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN1)
|
|
1700
1733
|
if (this.state !== STATES.READY) return
|
|
1701
1734
|
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
if (tagEncoded.byteLength > SIZE_LIMIT.TAG_LEN1) throw TypeError('please use tag string bytelength below:' + SIZE_LIMIT.TAG_LEN1)
|
|
1735
|
+
// subscribe 사용시, 사용 'ready' 이벤트시 메뉴얼 등록되므로 여기에 등록하면 2중 호출된다.
|
|
1736
|
+
// 즉, channels 등록은 listen 같은 자동화 구독시만 사용.
|
|
1737
|
+
// let tagList = tag.split(',')
|
|
1738
|
+
// tagList.forEach(tag => {
|
|
1739
|
+
// this.channels.add(tag)
|
|
1740
|
+
// })
|
|
1709
1741
|
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1742
|
+
try {
|
|
1743
|
+
let tagEncoded = encoder$1.encode(tag);
|
|
1744
|
+
this.send_enc_mode(
|
|
1745
|
+
Buffer$1.concat([
|
|
1746
|
+
M$1.NB('8', IOMsg.SUBSCRIBE),
|
|
1747
|
+
M$1.NB('8', tagEncoded.byteLength),
|
|
1748
|
+
tagEncoded]));
|
|
1749
|
+
} catch (error) { }
|
|
1715
1750
|
}
|
|
1716
1751
|
|
|
1717
1752
|
/**
|
|
@@ -1722,20 +1757,22 @@ class IOCore extends EventEmitter {
|
|
|
1722
1757
|
*/
|
|
1723
1758
|
subscribe_promise(tag) {
|
|
1724
1759
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1760
|
+
if (tag.length > SIZE_LIMIT.TAG_LEN2) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN2)
|
|
1761
|
+
|
|
1725
1762
|
if (this.state !== STATES.READY) {
|
|
1726
1763
|
return Promise.reject('subscribe_promise:: connection is not ready')
|
|
1727
1764
|
}
|
|
1728
1765
|
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1766
|
+
try {
|
|
1767
|
+
let tagEncoded = encoder$1.encode(tag);
|
|
1768
|
+
this.send_enc_mode(
|
|
1769
|
+
Buffer$1.concat([
|
|
1770
|
+
M$1.NB('8', IOMsg.SUBSCRIBE_REQ),
|
|
1771
|
+
M$1.NB('16', ++this.mid),
|
|
1772
|
+
M$1.NB('16', tagEncoded.byteLength),
|
|
1773
|
+
tagEncoded]));
|
|
1774
|
+
return this.setMsgPromise(this.mid)
|
|
1775
|
+
} catch (error) { }
|
|
1739
1776
|
}
|
|
1740
1777
|
|
|
1741
1778
|
/**
|
|
@@ -1932,14 +1969,23 @@ class IOCore extends EventEmitter {
|
|
|
1932
1969
|
* Changes the connection state and emits events.
|
|
1933
1970
|
* @param {string} state - The new state name (e.g., 'ready', 'closed').
|
|
1934
1971
|
* @param {string} [emitEventAndMessage] - Optional message to emit with the state change event.
|
|
1972
|
+
*
|
|
1973
|
+
* 주의.
|
|
1974
|
+
* 1. 상태가 변경 될 때만 'change' 이벤트 호출된다.
|
|
1975
|
+
* 2. emitEventAndMessage 옵션 값이 지정되야 해당 이벤트 이름이 호출된다.
|
|
1976
|
+
* 보통 이벤트 이름과 동일하게 적거나 이벤트 상황 안내문을 넣는다.
|
|
1935
1977
|
*/
|
|
1936
1978
|
stateChange(state, emitEventAndMessage) {
|
|
1937
|
-
// STATES constant name
|
|
1938
|
-
// eventName
|
|
1939
|
-
// .state
|
|
1979
|
+
// STATES constant name <string> upperCase
|
|
1980
|
+
// eventName and .stateName <string> lowerCase
|
|
1981
|
+
// .state <number>
|
|
1982
|
+
// console.log('### stateChange reason:', emitEventAndMessage )
|
|
1940
1983
|
let eventName = state.toLowerCase();
|
|
1941
1984
|
this.state = STATES[state.toUpperCase()]; // state: number
|
|
1942
|
-
|
|
1985
|
+
|
|
1986
|
+
if (emitEventAndMessage){
|
|
1987
|
+
this.emit(eventName, emitEventAndMessage);
|
|
1988
|
+
}
|
|
1943
1989
|
|
|
1944
1990
|
if (this.stateName !== eventName) {
|
|
1945
1991
|
this.stateName = eventName;
|
|
@@ -1959,6 +2005,8 @@ const CongType = {
|
|
|
1959
2005
|
// support LittleEndian system.
|
|
1960
2006
|
function pack(payload) {
|
|
1961
2007
|
|
|
2008
|
+
if( payload.byteLength == undefined ) payload = Buffer.from(payload);
|
|
2009
|
+
|
|
1962
2010
|
if (payload.byteLength < 256) { //one byte len
|
|
1963
2011
|
return M$1.pack(
|
|
1964
2012
|
M$1.MB('#type', '8', CongType.TYPE_LEN1),
|
|
@@ -7591,6 +7639,7 @@ let serverOption = {
|
|
|
7591
7639
|
port: null, // WebSocket
|
|
7592
7640
|
congPort: null, // CongSocket
|
|
7593
7641
|
httpServer: null,
|
|
7642
|
+
wsPath: null,
|
|
7594
7643
|
timeout: 50000,
|
|
7595
7644
|
showMessage: 'none',
|
|
7596
7645
|
showMetric: 0,
|
|
@@ -7632,10 +7681,10 @@ let serverOption = {
|
|
|
7632
7681
|
},
|
|
7633
7682
|
|
|
7634
7683
|
auth: {
|
|
7635
|
-
delay_auth_fail:
|
|
7684
|
+
delay_auth_fail: 600,
|
|
7636
7685
|
},
|
|
7637
7686
|
|
|
7638
|
-
|
|
7687
|
+
membersOnly: false
|
|
7639
7688
|
|
|
7640
7689
|
};
|
|
7641
7690
|
|
|
@@ -7662,15 +7711,13 @@ class RemoteCore {
|
|
|
7662
7711
|
this.ssid = RemoteCore.ssid++; // ordered index number
|
|
7663
7712
|
this.manager = manager;
|
|
7664
7713
|
|
|
7665
|
-
this.cid; // Communication Id
|
|
7666
|
-
this.did; // Device Id
|
|
7667
|
-
this.uid; // User Id
|
|
7668
|
-
this.nick =
|
|
7669
|
-
|
|
7714
|
+
this.cid = ''; // Communication Id
|
|
7715
|
+
this.did = ''; // Device Id
|
|
7716
|
+
this.uid = ''; // User Id
|
|
7717
|
+
this.nick = '';
|
|
7670
7718
|
|
|
7671
|
-
this.lastEchoMessage = "N";
|
|
7672
7719
|
this.privateNode = false;
|
|
7673
|
-
this.HOME_CHANNEL =
|
|
7720
|
+
this.HOME_CHANNEL = '';
|
|
7674
7721
|
this.level = serverOption.defaultQuotaIndex;
|
|
7675
7722
|
this.quota = quotaTable[this.level];
|
|
7676
7723
|
this.isAdmin = false;
|
|
@@ -7686,7 +7733,8 @@ class RemoteCore {
|
|
|
7686
7733
|
setState(state) {
|
|
7687
7734
|
this.state = state;
|
|
7688
7735
|
if (serverOption.debug.showAuthInfo) {
|
|
7689
|
-
|
|
7736
|
+
// let s = state + ":" + CLIENT_STATE[ state]
|
|
7737
|
+
this.stateLog.push( state );
|
|
7690
7738
|
console.log(this.stateLog.join('>'));
|
|
7691
7739
|
}
|
|
7692
7740
|
}
|
|
@@ -7701,7 +7749,7 @@ class RemoteCore {
|
|
|
7701
7749
|
|
|
7702
7750
|
|
|
7703
7751
|
showMessageLog(message, isBinary) {
|
|
7704
|
-
let from = this.boho.isAuthorized ? `did: ${this.did}
|
|
7752
|
+
let from = this.boho.isAuthorized ? `[FROM]did: ${this.did} cid:${this.cid}` : `[FROM]cid:${this.cid}`;
|
|
7705
7753
|
if (isBinary) {
|
|
7706
7754
|
let msgTypeName = IOMsg[message[0]];
|
|
7707
7755
|
if (!msgTypeName) msgTypeName = tt.BohoMsg[message[0]];
|
|
@@ -7798,6 +7846,7 @@ class RemoteCore {
|
|
|
7798
7846
|
case IOMsg.CID_REQ:
|
|
7799
7847
|
if (this.state < CLIENT_STATE.SENT_SERVER_READY) {
|
|
7800
7848
|
// Protocol violation: CID_REQ was sent before receiving the SERVER_READY signal.
|
|
7849
|
+
console.log('CID_REQ before SERVER_READY');
|
|
7801
7850
|
this.close();
|
|
7802
7851
|
}
|
|
7803
7852
|
|
|
@@ -7815,22 +7864,16 @@ class RemoteCore {
|
|
|
7815
7864
|
this.setState(CLIENT_STATE.CID_READY);
|
|
7816
7865
|
break;
|
|
7817
7866
|
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
let msg = decoder$3.decode(message.subarray(1));
|
|
7822
|
-
this.lastEchoMessage = msg;
|
|
7823
|
-
} catch (error) {
|
|
7824
|
-
// console.log('ECHO message is not a text')
|
|
7867
|
+
case IOMsg.ECHO:
|
|
7868
|
+
if( message.byteLength < 30) {
|
|
7869
|
+
this.send(message, isBinary);
|
|
7825
7870
|
}
|
|
7826
|
-
this.send(message, isBinary);
|
|
7827
7871
|
break;
|
|
7828
7872
|
|
|
7829
7873
|
case IOMsg.IAM:
|
|
7830
|
-
if (message.byteLength > 1) {
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
console.log('iam nick reset', this.nick);
|
|
7874
|
+
if (message.byteLength > 1 && message.byteLength < 30) {
|
|
7875
|
+
// if iam request has a text message then reset the nick property.
|
|
7876
|
+
this.nick = decoder$3.decode(message.subarray(1));
|
|
7834
7877
|
}
|
|
7835
7878
|
this.iamResponse();
|
|
7836
7879
|
break;
|
|
@@ -7851,7 +7894,7 @@ class RemoteCore {
|
|
|
7851
7894
|
|
|
7852
7895
|
case IOMsg.UNSUBSCRIBE:
|
|
7853
7896
|
if (message.byteLength == 2) {
|
|
7854
|
-
this.manager.unsubscribe([
|
|
7897
|
+
this.manager.unsubscribe([''], this);
|
|
7855
7898
|
} else if (message.byteLength >= 3) {
|
|
7856
7899
|
let tagLen = message.readUInt8(1);
|
|
7857
7900
|
|
|
@@ -7925,7 +7968,7 @@ class RemoteCore {
|
|
|
7925
7968
|
case tt.BohoMsg.AUTH_REQ:
|
|
7926
7969
|
if (!this.manager.authManager) return
|
|
7927
7970
|
if (this.state < CLIENT_STATE.SENT_SERVER_READY) {
|
|
7928
|
-
|
|
7971
|
+
console.log('protocol error. auth_req before server_ready');
|
|
7929
7972
|
this.close();
|
|
7930
7973
|
}
|
|
7931
7974
|
this.setState(CLIENT_STATE.RECV_AUTH_REQ);
|
|
@@ -7938,22 +7981,23 @@ class RemoteCore {
|
|
|
7938
7981
|
case tt.BohoMsg.AUTH_HMAC:
|
|
7939
7982
|
if (!this.manager.authManager) return
|
|
7940
7983
|
if (this.state < CLIENT_STATE.SENT_SERVER_NONCE) {
|
|
7941
|
-
|
|
7984
|
+
console.log('protocol error. auth_hmac before server_nonce');
|
|
7942
7985
|
this.close();
|
|
7943
7986
|
}
|
|
7944
7987
|
this.setState(CLIENT_STATE.RECV_AUTH_HMAC);
|
|
7945
7988
|
//async
|
|
7946
7989
|
this.manager.authManager.verify_auth_hmac(message, this)
|
|
7947
7990
|
.then(authInfo => {
|
|
7948
|
-
if (authInfo) {
|
|
7949
|
-
this.manager.deligateSignal(
|
|
7991
|
+
if (authInfo?.name) {
|
|
7992
|
+
this.manager.deligateSignal(this, '@$name', authInfo.name);
|
|
7950
7993
|
// console.log('device login success authInfo', authInfo)
|
|
7951
7994
|
// this.manager.sender('@$name', authInfo.name )
|
|
7952
7995
|
}
|
|
7953
7996
|
|
|
7997
|
+
// console.log('[VERIFY AUTH_HMAC] SubClass of BohoAuth return authInfo:', authInfo )
|
|
7954
7998
|
})
|
|
7955
7999
|
.catch(e => {
|
|
7956
|
-
|
|
8000
|
+
console.log('authInfo return fail.', e );
|
|
7957
8001
|
});
|
|
7958
8002
|
|
|
7959
8003
|
return;
|
|
@@ -7979,23 +8023,19 @@ class RemoteCore {
|
|
|
7979
8023
|
response(msgId, statusCode, body) {
|
|
7980
8024
|
// console.log('response body', body)
|
|
7981
8025
|
if (body) {
|
|
7982
|
-
|
|
7983
8026
|
this.send_enc_mode(M$1.pack(
|
|
7984
8027
|
MB('#type', '8', IOMsg.RESPONSE_MBP),
|
|
7985
8028
|
MB('status', '8', statusCode),
|
|
7986
8029
|
MB('mid', '16', msgId),
|
|
7987
8030
|
MB('body', body)
|
|
7988
8031
|
));
|
|
7989
|
-
|
|
7990
8032
|
} else {
|
|
7991
8033
|
this.send_enc_mode(M$1.pack(
|
|
7992
8034
|
MB('#type', '8', IOMsg.RESPONSE_MBP),
|
|
7993
8035
|
MB('status', '8', statusCode),
|
|
7994
8036
|
MB('mid', '16', msgId)
|
|
7995
8037
|
));
|
|
7996
|
-
|
|
7997
8038
|
}
|
|
7998
|
-
|
|
7999
8039
|
}
|
|
8000
8040
|
|
|
8001
8041
|
|
|
@@ -8036,9 +8076,9 @@ class RemoteCore {
|
|
|
8036
8076
|
|
|
8037
8077
|
|
|
8038
8078
|
|
|
8039
|
-
iamResponse(info =
|
|
8079
|
+
iamResponse(info = '') {
|
|
8040
8080
|
|
|
8041
|
-
if (info ==
|
|
8081
|
+
if (info == '') {
|
|
8042
8082
|
let channels = [];
|
|
8043
8083
|
for (let tag of this.channels.keys()) {
|
|
8044
8084
|
channels.push(tag);
|
|
@@ -8046,15 +8086,17 @@ class RemoteCore {
|
|
|
8046
8086
|
|
|
8047
8087
|
info = {
|
|
8048
8088
|
"ssid": this.ssid,
|
|
8049
|
-
"uid": this.uid,
|
|
8050
8089
|
"cid": this.cid,
|
|
8051
8090
|
"did": this.did,
|
|
8091
|
+
"uid": this.uid,
|
|
8092
|
+
"level": this.level,
|
|
8052
8093
|
"nick": this.nick,
|
|
8053
8094
|
"ip": this.ip
|
|
8054
8095
|
, 'tag': channels
|
|
8055
8096
|
};
|
|
8056
8097
|
}
|
|
8057
8098
|
|
|
8099
|
+
// console.log( 'iam res info', info )
|
|
8058
8100
|
let pack = M$1.pack(
|
|
8059
8101
|
MB('#MsgType', '8', IOMsg.IAM_RES),
|
|
8060
8102
|
MB('#info', info)
|
|
@@ -8440,8 +8482,7 @@ class Metric {
|
|
|
8440
8482
|
ip: remote.ip,
|
|
8441
8483
|
uptime: Math.trunc((Date.now() - remote.socket.openTime) / 1000),
|
|
8442
8484
|
nick: remote.nick,
|
|
8443
|
-
ssid: remote.ssid
|
|
8444
|
-
echo: remote.lastEchoMessage
|
|
8485
|
+
ssid: remote.ssid
|
|
8445
8486
|
}
|
|
8446
8487
|
} else if (mode == 3) {
|
|
8447
8488
|
return {
|
|
@@ -8644,8 +8685,8 @@ class Manager {
|
|
|
8644
8685
|
serverSignalTo(tag, ...args) {
|
|
8645
8686
|
let cid = tag.split('@')[0];
|
|
8646
8687
|
let topic = tag.split('@')[1];
|
|
8647
|
-
let sigPack = getSignalPack('@' + topic, ...args);
|
|
8648
8688
|
if (cid && this.cid2remote.has(cid)) {
|
|
8689
|
+
let sigPack = getSignalPack('@' + topic, ...args);
|
|
8649
8690
|
let targetRemote = this.cid2remote.get(cid);
|
|
8650
8691
|
console.log('target', targetRemote.state, targetRemote.cid);
|
|
8651
8692
|
targetRemote.send_enc_mode(sigPack);
|
|
@@ -8656,11 +8697,11 @@ class Manager {
|
|
|
8656
8697
|
}
|
|
8657
8698
|
|
|
8658
8699
|
sender(tag, remote, message) {
|
|
8659
|
-
if (serverOption.
|
|
8660
|
-
|
|
8700
|
+
if (serverOption.membersOnly && !remote.boho.isAuthorized) {
|
|
8701
|
+
console.log("[membersOnly] unAuthorized remote.",tag );
|
|
8661
8702
|
remote.send(Buffer.from([IOMsg.SERVER_CLEAR_AUTH]));
|
|
8662
8703
|
remote.close();
|
|
8663
|
-
return ['err', '
|
|
8704
|
+
return ['err', 'unAuthorized']
|
|
8664
8705
|
}
|
|
8665
8706
|
|
|
8666
8707
|
if (tag.indexOf('$') == 0) return ['err', 'prefix $ is reserved for userSet tag.']
|
|
@@ -8742,13 +8783,18 @@ class Manager {
|
|
|
8742
8783
|
// console.log('## null remote' )
|
|
8743
8784
|
break;
|
|
8744
8785
|
}
|
|
8745
|
-
|
|
8786
|
+
// change: from v4.x allow receiveSelfMessages.
|
|
8787
|
+
// if (c !== remote) {
|
|
8746
8788
|
c.send_enc_mode(message);
|
|
8747
8789
|
sentCounter++;
|
|
8748
|
-
}
|
|
8790
|
+
// }
|
|
8749
8791
|
}
|
|
8750
8792
|
|
|
8751
|
-
if (serverOption.useQuota.publishCounter)
|
|
8793
|
+
// if (serverOption.useQuota.publishCounter) {
|
|
8794
|
+
// // console.log(`pub >> [${tag}] sent: ${sentCounter} [use quota limit: ${remote.quota.publishCounter }] total: ${remotes.size} subscribers. ` )
|
|
8795
|
+
// } else {
|
|
8796
|
+
// // console.log(`pub >> [${tag}] sent: ${sentCounter} [no quota limit] total: ${remotes.size} subscribers. ` )
|
|
8797
|
+
// }
|
|
8752
8798
|
return ['ok', sentCounter]
|
|
8753
8799
|
}
|
|
8754
8800
|
}
|
|
@@ -8895,7 +8941,6 @@ class Manager {
|
|
|
8895
8941
|
this.retain_messages.clear();
|
|
8896
8942
|
this.channel_map.clear();
|
|
8897
8943
|
|
|
8898
|
-
console.log('Manager closed');
|
|
8899
8944
|
}
|
|
8900
8945
|
}
|
|
8901
8946
|
|
|
@@ -8919,20 +8964,20 @@ class Server extends require$$0$3 {
|
|
|
8919
8964
|
let pingT = parseInt(options.timeout);
|
|
8920
8965
|
if (pingT && pingT >= 1000) serverOption.timeout = pingT;
|
|
8921
8966
|
}
|
|
8922
|
-
|
|
8923
8967
|
if (options.monitorPeriod) {
|
|
8924
8968
|
let monitorT = parseInt(options.monitorPeriod);
|
|
8925
8969
|
if (monitorT && monitorT >= 1000) serverOption.monitorPeriod = monitorT;
|
|
8926
8970
|
}
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
8971
|
if (options.showMessage) {
|
|
8930
8972
|
serverOption.showMessage = options.showMessage;
|
|
8931
8973
|
}
|
|
8932
|
-
|
|
8933
8974
|
if (options.showMetric) {
|
|
8934
8975
|
serverOption.showMetric = options.showMetric;
|
|
8935
8976
|
}
|
|
8977
|
+
if (options.membersOnly) {
|
|
8978
|
+
serverOption.membersOnly = options.membersOnly;
|
|
8979
|
+
}
|
|
8980
|
+
|
|
8936
8981
|
|
|
8937
8982
|
if (options.port || options.port == 0) {
|
|
8938
8983
|
this.port = parseInt(options.port);
|
|
@@ -8942,6 +8987,10 @@ class Server extends require$$0$3 {
|
|
|
8942
8987
|
this.httpServer = options.httpServer;
|
|
8943
8988
|
}
|
|
8944
8989
|
|
|
8990
|
+
if (options.wsPath) {
|
|
8991
|
+
this.wsPath = options.wsPath;
|
|
8992
|
+
}
|
|
8993
|
+
|
|
8945
8994
|
if (options.congPort || options.congPort == 0) {
|
|
8946
8995
|
this.congPort = parseInt(options.congPort);
|
|
8947
8996
|
}
|
|
@@ -8954,7 +9003,7 @@ class Server extends require$$0$3 {
|
|
|
8954
9003
|
if (this.congPort || this.congPort == 0) this.serverCountToListen++;
|
|
8955
9004
|
|
|
8956
9005
|
if (this.serverCountToListen === 0) {
|
|
8957
|
-
|
|
9006
|
+
throw new Error('Cannot create Server: At least one of "port", "httpServer", or "congPort" must be specified.');
|
|
8958
9007
|
} else {
|
|
8959
9008
|
if (this.port || this.port == 0 || this.httpServer) this.startWSServer();
|
|
8960
9009
|
if (this.congPort || this.congPort == 0) this.startCongServer();
|
|
@@ -8964,14 +9013,11 @@ class Server extends require$$0$3 {
|
|
|
8964
9013
|
|
|
8965
9014
|
|
|
8966
9015
|
startWSServer() {
|
|
8967
|
-
|
|
8968
9016
|
// console.log('optoins', options )
|
|
8969
9017
|
if (this.port || this.port == 0) {
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
console.log('opening WebSocket Server external httpServer:');
|
|
8974
|
-
this.wss = new WebSocketServer({ server: this.httpServer });
|
|
9018
|
+
this.wss = new WebSocketServer({ port: this.port , path: this.wsPath });
|
|
9019
|
+
} else if (this.httpServer ) {
|
|
9020
|
+
this.wss = new WebSocketServer({ server: this.httpServer, path: this.wsPath });
|
|
8975
9021
|
} else {
|
|
8976
9022
|
throw new TypeError(
|
|
8977
9023
|
'One and only one of the "port", "httpServer"' +
|
|
@@ -8979,7 +9025,6 @@ class Server extends require$$0$3 {
|
|
|
8979
9025
|
);
|
|
8980
9026
|
}
|
|
8981
9027
|
|
|
8982
|
-
|
|
8983
9028
|
this.wss.once('listening', () => {
|
|
8984
9029
|
this.port = this.wss.address().port;
|
|
8985
9030
|
console.log('wss server bound port:', this.port );
|
|
@@ -8990,7 +9035,6 @@ class Server extends require$$0$3 {
|
|
|
8990
9035
|
});
|
|
8991
9036
|
|
|
8992
9037
|
// this.wss.setMaxListeners(0)
|
|
8993
|
-
|
|
8994
9038
|
this.wss.on('error', (err) => {
|
|
8995
9039
|
console.error('### ws server error:', err.message);
|
|
8996
9040
|
if (err.code == 'EADDRINUSE') {
|
|
@@ -8998,8 +9042,8 @@ class Server extends require$$0$3 {
|
|
|
8998
9042
|
}
|
|
8999
9043
|
});
|
|
9000
9044
|
|
|
9001
|
-
this.wss.on('close', (
|
|
9002
|
-
console.log('### WS server closed.'
|
|
9045
|
+
this.wss.on('close', () => {
|
|
9046
|
+
console.log('### WS server is closed.');
|
|
9003
9047
|
});
|
|
9004
9048
|
|
|
9005
9049
|
this.wss.on('connection', (ws, req) => {
|
|
@@ -9011,8 +9055,6 @@ class Server extends require$$0$3 {
|
|
|
9011
9055
|
}
|
|
9012
9056
|
|
|
9013
9057
|
startCongServer() {
|
|
9014
|
-
console.log('opening CongSocket Server port:', this.congPort);
|
|
9015
|
-
|
|
9016
9058
|
this.congServer = net.createServer((socket) => {
|
|
9017
9059
|
this.manager.addRemote(socket);
|
|
9018
9060
|
})
|
|
@@ -9022,7 +9064,7 @@ class Server extends require$$0$3 {
|
|
|
9022
9064
|
process.exit();
|
|
9023
9065
|
}
|
|
9024
9066
|
}).on('close', () => {
|
|
9025
|
-
console.log('###
|
|
9067
|
+
console.log('### congsocket server is closed.');
|
|
9026
9068
|
}).listen(this.congPort, () => {
|
|
9027
9069
|
this.congPort = this.congServer.address().port;
|
|
9028
9070
|
console.log('congsocket server bound port:', this.congPort );
|
|
@@ -9033,64 +9075,76 @@ class Server extends require$$0$3 {
|
|
|
9033
9075
|
});
|
|
9034
9076
|
}
|
|
9035
9077
|
|
|
9036
|
-
|
|
9037
|
-
|
|
9078
|
+
/**
|
|
9079
|
+
* API register.
|
|
9080
|
+
* target: api_name <string>
|
|
9081
|
+
* api: api_module <function module|class instance>
|
|
9082
|
+
* return this
|
|
9083
|
+
*/
|
|
9038
9084
|
api(target, api) {
|
|
9039
9085
|
|
|
9040
|
-
|
|
9041
|
-
|
|
9086
|
+
if( typeof target !== 'string'){
|
|
9087
|
+
throw new Error(`api( target ,api ) target name is not a string.`)
|
|
9088
|
+
}
|
|
9042
9089
|
if (!api.checkPermission || typeof api.checkPermission != 'function') {
|
|
9043
|
-
throw new Error(
|
|
9090
|
+
throw new Error(`API ${target} : no checkPermission or not a function.`)
|
|
9044
9091
|
}
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9092
|
+
if(!api.commands || !Array.isArray(api.commands) ){
|
|
9093
|
+
throw new Error(`API ${target} : no commands or !Array.`)
|
|
9094
|
+
}
|
|
9095
|
+
|
|
9096
|
+
// API TYPE 1. single request() function.
|
|
9097
|
+
if ( api.request && typeof api.request == 'function' ) {
|
|
9098
|
+
this.on(target, async (remote, req) => {
|
|
9099
|
+
try {
|
|
9100
|
+
if (!api.checkPermission(remote, req)) {
|
|
9101
|
+
remote.response(req.mid, STATUS.ERROR, "NO_PERMISSION.");
|
|
9102
|
+
return
|
|
9103
|
+
}
|
|
9104
|
+
if( api.commands.includes( req.topic )){
|
|
9105
|
+
console.log('server api req', req );
|
|
9106
|
+
await api.request(remote, req);
|
|
9107
|
+
}else {
|
|
9108
|
+
remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
|
|
9109
|
+
}
|
|
9110
|
+
} catch (error) {
|
|
9111
|
+
console.error(`Unhandled API Error in target [${target}]:`, error);
|
|
9112
|
+
remote.response(req.mid, STATUS.ERROR, "INTERNAL_SERVER_ERROR");
|
|
9055
9113
|
}
|
|
9056
9114
|
});
|
|
9057
|
-
|
|
9058
9115
|
} else {
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
console.log(`API TYPE2. Multiple function list. target: ${target} list:${apiList}`);
|
|
9066
|
-
|
|
9067
|
-
this.on(target, (remote, req) => {
|
|
9068
|
-
let r;
|
|
9069
|
-
if (!api.checkPermission(remote, req)) {
|
|
9070
|
-
r = "NO_PERMISSION.";
|
|
9071
|
-
} else {
|
|
9072
|
-
if (api[req.topic]) {
|
|
9073
|
-
console.log(`API TYPE2. request target: ${target} has topic:${req.topic}`);
|
|
9074
|
-
api[req.topic](remote, req);
|
|
9116
|
+
// API TYPE 2. multiple functions.
|
|
9117
|
+
this.on(target, async (remote, req) => {
|
|
9118
|
+
try {
|
|
9119
|
+
if (!api.checkPermission(remote, req)) {
|
|
9120
|
+
remote.response(req.mid, STATUS.ERROR, "NO_PERMISSION.");
|
|
9075
9121
|
return
|
|
9076
|
-
} else {
|
|
9077
|
-
r = `target: ${req.target} has not topic name: ${req.topic}`;
|
|
9078
9122
|
}
|
|
9123
|
+
if( api.commands.includes( req.topic )){
|
|
9124
|
+
await api[req.topic](remote, req);
|
|
9125
|
+
}else {
|
|
9126
|
+
remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
|
|
9127
|
+
}
|
|
9128
|
+
} catch (error) {
|
|
9129
|
+
console.error(`Unhandled API Error in target [${target}]:`, error);
|
|
9130
|
+
remote.response(req.mid, STATUS.ERROR, "INTERNAL_SERVER_ERROR");
|
|
9079
9131
|
}
|
|
9080
|
-
|
|
9081
|
-
remote.response(req.mid, STATUS.ERROR, r);
|
|
9082
9132
|
});
|
|
9083
9133
|
}
|
|
9084
|
-
|
|
9134
|
+
this.apiNames.add(target);
|
|
9135
|
+
console.log(`[API registed: ${target} ] accept commands: ${api.commands}`);
|
|
9085
9136
|
return this
|
|
9086
9137
|
}
|
|
9087
9138
|
|
|
9088
9139
|
close(callback) {
|
|
9089
|
-
console.log('closing
|
|
9140
|
+
console.log('closing iosignal server...');
|
|
9090
9141
|
if (this.manager) {
|
|
9091
9142
|
this.manager.close();
|
|
9092
9143
|
}
|
|
9093
9144
|
|
|
9145
|
+
this.apiNames.forEach(v => this.removeAllListeners(v));
|
|
9146
|
+
this.apiNames.clear();
|
|
9147
|
+
|
|
9094
9148
|
let serverCount = 0;
|
|
9095
9149
|
if (this.wss) serverCount++;
|
|
9096
9150
|
if (this.congServer) serverCount++;
|
|
@@ -9104,14 +9158,14 @@ class Server extends require$$0$3 {
|
|
|
9104
9158
|
const onClosed = () => {
|
|
9105
9159
|
closedCount++;
|
|
9106
9160
|
if (closedCount === serverCount) {
|
|
9107
|
-
console.log('
|
|
9161
|
+
console.log('IOSignal server is closed.');
|
|
9108
9162
|
if (callback) callback();
|
|
9109
9163
|
}
|
|
9110
9164
|
};
|
|
9111
9165
|
|
|
9112
9166
|
if (this.wss) {
|
|
9113
9167
|
this.wss.close(() => {
|
|
9114
|
-
console.log('wss server closed.')
|
|
9168
|
+
// console.log('wss server closed.')
|
|
9115
9169
|
onClosed();
|
|
9116
9170
|
});
|
|
9117
9171
|
}
|
|
@@ -9119,7 +9173,7 @@ class Server extends require$$0$3 {
|
|
|
9119
9173
|
if (this.congServer) {
|
|
9120
9174
|
this.congServer.close((err) => {
|
|
9121
9175
|
if (err) console.error('congServer close error', err);
|
|
9122
|
-
console.log('cong server closed.')
|
|
9176
|
+
// console.log('cong server closed.')
|
|
9123
9177
|
onClosed();
|
|
9124
9178
|
});
|
|
9125
9179
|
}
|
|
@@ -9142,10 +9196,9 @@ class BohoAuth {
|
|
|
9142
9196
|
let peerInfo = `FAIL #${peer.ssid} reason:${reason} `;
|
|
9143
9197
|
this.authLogger.log(peerInfo);
|
|
9144
9198
|
}
|
|
9145
|
-
|
|
9146
|
-
console.log('## AUTH_FAIL reason:', reason);
|
|
9147
|
-
// peer.send( Buffer.from( [Boho.BohoMsg.AUTH_FAIL] ))
|
|
9199
|
+
// console.log('##### AUTH_FAIL reason: ', reason)
|
|
9148
9200
|
peer.setState(CLIENT_STATE.AUTH_FAIL);
|
|
9201
|
+
// add some delay time.
|
|
9149
9202
|
setTimeout(e => {
|
|
9150
9203
|
peer.send(Buffer.from([tt.BohoMsg.AUTH_FAIL]));
|
|
9151
9204
|
}, serverOption.auth.delay_auth_fail);
|
|
@@ -9155,30 +9208,31 @@ class BohoAuth {
|
|
|
9155
9208
|
try {
|
|
9156
9209
|
//1. unpack
|
|
9157
9210
|
let infoPack = M$1.unpack(auth_hmac, tt.Meta.AUTH_HMAC);
|
|
9211
|
+
|
|
9158
9212
|
if (!infoPack) {
|
|
9159
9213
|
this.send_auth_fail(peer, 'unpack auth_pack fail');
|
|
9160
9214
|
return
|
|
9161
9215
|
}
|
|
9162
|
-
|
|
9216
|
+
|
|
9163
9217
|
let id = "";
|
|
9164
9218
|
if (infoPack.id8.includes(0)) {
|
|
9165
9219
|
id = decoder.decode(infoPack.id8.subarray(0, infoPack.id8.indexOf(0)));
|
|
9166
9220
|
} else {
|
|
9167
9221
|
id = decoder.decode(infoPack.id8);
|
|
9168
9222
|
}
|
|
9169
|
-
|
|
9223
|
+
|
|
9170
9224
|
//2. get key of id from DB
|
|
9171
9225
|
let authInfo = await this.getAuth(id);
|
|
9172
9226
|
|
|
9173
|
-
// console.log('##### authInfo',authInfo )
|
|
9174
|
-
if (serverOption.debug.showAuthInfo) {
|
|
9175
|
-
}
|
|
9176
|
-
|
|
9177
9227
|
if (!authInfo) {
|
|
9178
9228
|
this.send_auth_fail(peer, 'NO ID:' + id);
|
|
9179
9229
|
return
|
|
9180
9230
|
}
|
|
9181
9231
|
|
|
9232
|
+
if (serverOption.debug.showAuthInfo) {
|
|
9233
|
+
console.log('[debug]showAuthInfo',authInfo );
|
|
9234
|
+
}
|
|
9235
|
+
|
|
9182
9236
|
// console.log('db authInfo.key: ', authInfo.key)
|
|
9183
9237
|
peer.boho.copy_id8(infoPack.id8);
|
|
9184
9238
|
// type of key
|
|
@@ -9229,6 +9283,7 @@ class BohoAuth {
|
|
|
9229
9283
|
|
|
9230
9284
|
//6. delete current (temp rand)cid if exist.
|
|
9231
9285
|
if (peer.cid) {
|
|
9286
|
+
console.log('duplicate cid');
|
|
9232
9287
|
peer.manager.cid2remote.delete(peer.cid);
|
|
9233
9288
|
}
|
|
9234
9289
|
|
|
@@ -9236,6 +9291,7 @@ class BohoAuth {
|
|
|
9236
9291
|
peer.did = id;
|
|
9237
9292
|
peer.cid = authInfo.cid;
|
|
9238
9293
|
peer.nick = authInfo.cid; // temporary: nick as cid
|
|
9294
|
+
if( authInfo.uid ) peer.uid = authInfo.uid;
|
|
9239
9295
|
|
|
9240
9296
|
//8. setting quota level.
|
|
9241
9297
|
let quotaLevel = serverOption.defaultQuotaIndex;
|
|
@@ -9274,14 +9330,12 @@ class BohoAuth {
|
|
|
9274
9330
|
}
|
|
9275
9331
|
return authInfo
|
|
9276
9332
|
} catch (error) {
|
|
9277
|
-
this.send_auth_fail(peer, 'caught: unknown error' + error);
|
|
9333
|
+
this.send_auth_fail(peer, '[BohoAuth]caught: unknown error:' + error);
|
|
9278
9334
|
}
|
|
9279
9335
|
|
|
9280
9336
|
}
|
|
9281
9337
|
|
|
9282
9338
|
|
|
9283
|
-
|
|
9284
|
-
|
|
9285
9339
|
}
|
|
9286
9340
|
|
|
9287
9341
|
class Auth_File extends BohoAuth {
|
|
@@ -9437,11 +9491,15 @@ class Auth_Redis extends BohoAuth {
|
|
|
9437
9491
|
|
|
9438
9492
|
// get device key from DB. (for Boho auth.)
|
|
9439
9493
|
async getAuth(id) {
|
|
9440
|
-
|
|
9441
|
-
|
|
9494
|
+
try {
|
|
9495
|
+
let result = await this.redis.hGetAll(DEVICE_PREFIX + id);
|
|
9496
|
+
if (result.key) return result
|
|
9497
|
+
} catch (error) {
|
|
9498
|
+
console.log('getAuth', error);
|
|
9499
|
+
}
|
|
9442
9500
|
}
|
|
9443
9501
|
|
|
9444
|
-
|
|
9502
|
+
//api_sudo call
|
|
9445
9503
|
async getAuthIdList() {
|
|
9446
9504
|
let result = await this.redis.keys(DEVICE_PREFIX + '*');
|
|
9447
9505
|
result = result.map(v => {
|
|
@@ -9456,6 +9514,7 @@ class Auth_Redis extends BohoAuth {
|
|
|
9456
9514
|
return this.redis.hSet(DEVICE_PREFIX + id, { 'key': Base64hashKey, 'cid': cid, 'level': level })
|
|
9457
9515
|
}
|
|
9458
9516
|
|
|
9517
|
+
//api_sudo call
|
|
9459
9518
|
async delAuth(id) {
|
|
9460
9519
|
return this.redis.del(DEVICE_PREFIX + id)
|
|
9461
9520
|
}
|
|
@@ -9466,16 +9525,16 @@ class Auth_Redis extends BohoAuth {
|
|
|
9466
9525
|
|
|
9467
9526
|
}
|
|
9468
9527
|
|
|
9469
|
-
const
|
|
9528
|
+
const commands$1 = ['echo', 'date', 'unixtime'];
|
|
9470
9529
|
|
|
9530
|
+
const MIN_LEVEL$2 = 0;
|
|
9471
9531
|
function checkPermission$1(remote) {
|
|
9472
|
-
|
|
9473
|
-
return true
|
|
9474
|
-
} else {
|
|
9475
|
-
return false
|
|
9476
|
-
}
|
|
9532
|
+
return (remote.level >= MIN_LEVEL$2) ? true : false;
|
|
9477
9533
|
}
|
|
9478
9534
|
|
|
9535
|
+
/**
|
|
9536
|
+
* client api call example: await io.req('reply','echo','hello')
|
|
9537
|
+
*/
|
|
9479
9538
|
async function echo(remote, req) {
|
|
9480
9539
|
if (!req.args)
|
|
9481
9540
|
remote.response(req.mid, STATUS.ERROR, 'no message to echo');
|
|
@@ -9483,11 +9542,17 @@ async function echo(remote, req) {
|
|
|
9483
9542
|
remote.response(req.mid, STATUS.OK, req.args);
|
|
9484
9543
|
}
|
|
9485
9544
|
|
|
9545
|
+
/**
|
|
9546
|
+
* client api call example: await io.req('reply','date')
|
|
9547
|
+
*/
|
|
9486
9548
|
async function date(remote, req) {
|
|
9487
9549
|
let r = new Date().toUTCString();
|
|
9488
9550
|
remote.response(req.mid, STATUS.OK, r);
|
|
9489
9551
|
}
|
|
9490
9552
|
|
|
9553
|
+
/**
|
|
9554
|
+
* client api call example: await io.req('reply','unixtime')
|
|
9555
|
+
*/
|
|
9491
9556
|
async function unixtime(remote, req) {
|
|
9492
9557
|
let r = Math.floor(Date.now() / 1000);
|
|
9493
9558
|
remote.response(req.mid, STATUS.OK, r);
|
|
@@ -9496,13 +9561,12 @@ async function unixtime(remote, req) {
|
|
|
9496
9561
|
var api_reply = /*#__PURE__*/Object.freeze({
|
|
9497
9562
|
__proto__: null,
|
|
9498
9563
|
checkPermission: checkPermission$1,
|
|
9564
|
+
commands: commands$1,
|
|
9499
9565
|
date: date,
|
|
9500
9566
|
echo: echo,
|
|
9501
9567
|
unixtime: unixtime
|
|
9502
9568
|
});
|
|
9503
9569
|
|
|
9504
|
-
const MIN_LEVEL$1 = 255;
|
|
9505
|
-
|
|
9506
9570
|
const commands = [
|
|
9507
9571
|
'cid', 'remotes', 'clients',
|
|
9508
9572
|
'channels', 'subscribers',
|
|
@@ -9512,13 +9576,9 @@ const commands = [
|
|
|
9512
9576
|
'adddevice', 'getdevice', 'deldevice'
|
|
9513
9577
|
];
|
|
9514
9578
|
|
|
9515
|
-
|
|
9579
|
+
const MIN_LEVEL$1 = 255;
|
|
9516
9580
|
function checkPermission(remote) {
|
|
9517
|
-
|
|
9518
|
-
return true
|
|
9519
|
-
} else {
|
|
9520
|
-
return false
|
|
9521
|
-
}
|
|
9581
|
+
return (remote.level >= MIN_LEVEL$1) ? true : false;
|
|
9522
9582
|
}
|
|
9523
9583
|
|
|
9524
9584
|
async function request(remote, req) {
|
|
@@ -9595,15 +9655,23 @@ var api_sudo = /*#__PURE__*/Object.freeze({
|
|
|
9595
9655
|
request: request
|
|
9596
9656
|
});
|
|
9597
9657
|
|
|
9658
|
+
/**
|
|
9659
|
+
* RedisAPI <IOSignal API>
|
|
9660
|
+
*
|
|
9661
|
+
* iosignal 클라이언트의 redis 질의 요청을 받으면,
|
|
9662
|
+
* redisClient 로 연결된 redis-server 에게 질의 후 결과를 되돌려 준다.
|
|
9663
|
+
*
|
|
9664
|
+
* client ex:
|
|
9665
|
+
* await io.req('redis','hget','user:id' )
|
|
9666
|
+
*
|
|
9667
|
+
*/
|
|
9668
|
+
|
|
9598
9669
|
const MIN_LEVEL = 200;
|
|
9599
9670
|
const COMMANDS = [
|
|
9600
|
-
'GET', 'SET',
|
|
9601
|
-
'
|
|
9602
|
-
'
|
|
9603
|
-
'
|
|
9604
|
-
'EXISTS', 'SREM',
|
|
9605
|
-
'DEL', 'KEYS',
|
|
9606
|
-
'SAVE'
|
|
9671
|
+
'GET', 'SET', 'HGETALL', 'HGET', 'HSET', 'SADD', 'SISMEMBER',
|
|
9672
|
+
'SMEMBERS', 'EXISTS', 'SREM', 'DEL', 'KEYS', 'SAVE',
|
|
9673
|
+
'get', 'set', 'hGetAll', 'hGet', 'hSet', 'sAdd', 'sIsMember',
|
|
9674
|
+
'sMembers', 'exists', 'sRem', 'del', 'keys', 'save'
|
|
9607
9675
|
];
|
|
9608
9676
|
|
|
9609
9677
|
class RedisAPI {
|
|
@@ -9616,42 +9684,23 @@ class RedisAPI {
|
|
|
9616
9684
|
this.commands = COMMANDS;
|
|
9617
9685
|
}
|
|
9618
9686
|
|
|
9619
|
-
|
|
9620
9687
|
checkPermission(remote, req) {
|
|
9621
|
-
|
|
9622
|
-
if (remote.level >= this.minLevel) {
|
|
9623
|
-
return true
|
|
9624
|
-
} else {
|
|
9625
|
-
return false
|
|
9626
|
-
}
|
|
9688
|
+
return (remote.level >= this.minLevel) ? true : false;
|
|
9627
9689
|
}
|
|
9628
9690
|
|
|
9629
|
-
|
|
9630
9691
|
async request(remote, req) {
|
|
9631
|
-
|
|
9632
9692
|
let result;
|
|
9633
|
-
let status = STATUS.OK;
|
|
9634
9693
|
try {
|
|
9635
9694
|
let cmd = req.topic;
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
console.log('RedisAPI call:', cmd, req.args);
|
|
9639
|
-
|
|
9640
|
-
if (req.args.length > 0) {
|
|
9641
|
-
result = await this.redisClient[cmd](...req.args);
|
|
9642
|
-
} else {
|
|
9643
|
-
result = await this.redisClient[cmd]();
|
|
9644
|
-
}
|
|
9645
|
-
|
|
9646
|
-
|
|
9695
|
+
if (req.args?.length > 0) {
|
|
9696
|
+
result = await this.redisClient[cmd](...req.args);
|
|
9647
9697
|
} else {
|
|
9648
|
-
|
|
9698
|
+
result = await this.redisClient[cmd]();
|
|
9649
9699
|
}
|
|
9650
|
-
remote.response(req.mid,
|
|
9700
|
+
remote.response(req.mid, STATUS.OK, result);
|
|
9651
9701
|
} catch (e) {
|
|
9652
9702
|
remote.response(req.mid, STATUS.ERROR, e.message);
|
|
9653
9703
|
}
|
|
9654
|
-
|
|
9655
9704
|
}
|
|
9656
9705
|
|
|
9657
9706
|
}
|