iosignal 3.2.0 → 3.3.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/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 = "3.2.0";
16
+ var version$1 = "3.3.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,26 @@ 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
- this.ip = jsonInfo.ip;
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
+ // TIP. cid from [CID_RES], level from [QUOTA_LEVEL]
1228
+ this.emit('iam_res', str );
1216
1229
  } catch (error) {
1217
1230
  this.emit('error', new Error('IAM_RES data error'));
1218
1231
  }
@@ -1231,13 +1244,14 @@ class IOCore extends EventEmitter {
1231
1244
  let quotaLevel = buffer[1];
1232
1245
  this.level = quotaLevel;
1233
1246
  this.quota = quotaTable[quotaLevel];
1234
- console.log('## QUOTA:', quotaLevel, JSON.stringify(this.quota));
1247
+ console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota));
1235
1248
  break;
1236
1249
 
1237
1250
  case IOMsg.SERVER_CLEAR_AUTH:
1238
1251
  this.useAuth = false;
1239
1252
  this.boho.clearAuth();
1240
1253
  this.stop();
1254
+ console.log('[SERVER_CLEAR_AUTH] io stop.');
1241
1255
  break;
1242
1256
 
1243
1257
  case IOMsg.SERVER_REDIRECT:
@@ -1441,7 +1455,7 @@ class IOCore extends EventEmitter {
1441
1455
  */
1442
1456
  echo(args) {
1443
1457
  if (args) {
1444
- console.log('echo args:', args);
1458
+ // console.log('send echo args:', args)
1445
1459
  this.send_enc_mode(M$1.pack(
1446
1460
  M$1.MB('#MsgType', '8', IOMsg.ECHO),
1447
1461
  M$1.MB('#msg', args)
@@ -1530,13 +1544,13 @@ class IOCore extends EventEmitter {
1530
1544
  */
1531
1545
  setMsgPromise(mid) {
1532
1546
  return new Promise((resolve, reject) => {
1533
- this.promiseMap.set(mid, [resolve, reject]);
1534
- setTimeout(e => {
1547
+ const timeoutId = setTimeout(e => {
1535
1548
  if (this.promiseMap.has(mid)) {
1536
1549
  reject('timeout');
1537
1550
  this.promiseMap.delete(mid);
1538
1551
  }
1539
1552
  }, this.promiseTimeOut);
1553
+ this.promiseMap.set(mid, [resolve, reject, timeoutId]);
1540
1554
  })
1541
1555
  }
1542
1556
 
@@ -1550,7 +1564,8 @@ class IOCore extends EventEmitter {
1550
1564
  if (!res) return
1551
1565
 
1552
1566
  if (this.promiseMap.has(res.mid)) {
1553
- let [resolve, reject] = this.promiseMap.get(res.mid);
1567
+ let [resolve, reject, timeoutId] = this.promiseMap.get(res.mid);
1568
+ clearTimeout(timeoutId);
1554
1569
  this.promiseMap.delete(res.mid);
1555
1570
 
1556
1571
  if (res.status < 128) {
@@ -1659,9 +1674,9 @@ class IOCore extends EventEmitter {
1659
1674
 
1660
1675
 
1661
1676
  /**
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.
1677
+ * Sends a request to a target and topic.(remote api call)
1678
+ * @param {string} target - The target(api name) of the request.
1679
+ * @param {string} topic - The topic(api function name) of the request.
1665
1680
  * @param {...any} args - Optional arguments for the request.
1666
1681
  * @returns {Promise<any>}
1667
1682
  */
@@ -1937,6 +1952,7 @@ class IOCore extends EventEmitter {
1937
1952
  // STATES constant name : string upperCase
1938
1953
  // eventName, .stateName : string lowerCase
1939
1954
  // .state : number
1955
+ // console.log('### stateChange reason:', emitEventAndMessage )
1940
1956
  let eventName = state.toLowerCase();
1941
1957
  this.state = STATES[state.toUpperCase()]; // state: number
1942
1958
  if (emitEventAndMessage) this.emit(eventName, emitEventAndMessage);
@@ -1959,6 +1975,8 @@ const CongType = {
1959
1975
  // support LittleEndian system.
1960
1976
  function pack(payload) {
1961
1977
 
1978
+ if( payload.byteLength == undefined ) payload = Buffer.from(payload);
1979
+
1962
1980
  if (payload.byteLength < 256) { //one byte len
1963
1981
  return M$1.pack(
1964
1982
  M$1.MB('#type', '8', CongType.TYPE_LEN1),
@@ -7591,6 +7609,7 @@ let serverOption = {
7591
7609
  port: null, // WebSocket
7592
7610
  congPort: null, // CongSocket
7593
7611
  httpServer: null,
7612
+ wsPath: null,
7594
7613
  timeout: 50000,
7595
7614
  showMessage: 'none',
7596
7615
  showMetric: 0,
@@ -7632,10 +7651,10 @@ let serverOption = {
7632
7651
  },
7633
7652
 
7634
7653
  auth: {
7635
- delay_auth_fail: 1000,
7654
+ delay_auth_fail: 600,
7636
7655
  },
7637
7656
 
7638
- memberOnly: false
7657
+ membersOnly: false
7639
7658
 
7640
7659
  };
7641
7660
 
@@ -7662,15 +7681,13 @@ class RemoteCore {
7662
7681
  this.ssid = RemoteCore.ssid++; // ordered index number
7663
7682
  this.manager = manager;
7664
7683
 
7665
- this.cid; // Communication Id
7666
- this.did; // Device Id
7667
- this.uid; // User Id
7668
- this.nick = "";
7684
+ this.cid = ''; // Communication Id
7685
+ this.did = ''; // Device Id
7686
+ this.uid = ''; // User Id
7687
+ this.nick = '';
7669
7688
 
7670
-
7671
- this.lastEchoMessage = "N";
7672
7689
  this.privateNode = false;
7673
- this.HOME_CHANNEL = "";
7690
+ this.HOME_CHANNEL = '';
7674
7691
  this.level = serverOption.defaultQuotaIndex;
7675
7692
  this.quota = quotaTable[this.level];
7676
7693
  this.isAdmin = false;
@@ -7686,7 +7703,8 @@ class RemoteCore {
7686
7703
  setState(state) {
7687
7704
  this.state = state;
7688
7705
  if (serverOption.debug.showAuthInfo) {
7689
- this.stateLog.push(state);
7706
+ // let s = state + ":" + CLIENT_STATE[ state]
7707
+ this.stateLog.push( state );
7690
7708
  console.log(this.stateLog.join('>'));
7691
7709
  }
7692
7710
  }
@@ -7701,7 +7719,7 @@ class RemoteCore {
7701
7719
 
7702
7720
 
7703
7721
  showMessageLog(message, isBinary) {
7704
- let from = this.boho.isAuthorized ? `did: ${this.did} ${this.cid}@` : `${this.cid}@`;
7722
+ let from = this.boho.isAuthorized ? `[FROM]did: ${this.did} cid:${this.cid}` : `[FROM]cid:${this.cid}`;
7705
7723
  if (isBinary) {
7706
7724
  let msgTypeName = IOMsg[message[0]];
7707
7725
  if (!msgTypeName) msgTypeName = tt.BohoMsg[message[0]];
@@ -7798,6 +7816,7 @@ class RemoteCore {
7798
7816
  case IOMsg.CID_REQ:
7799
7817
  if (this.state < CLIENT_STATE.SENT_SERVER_READY) {
7800
7818
  // Protocol violation: CID_REQ was sent before receiving the SERVER_READY signal.
7819
+ console.log('CID_REQ before SERVER_READY');
7801
7820
  this.close();
7802
7821
  }
7803
7822
 
@@ -7815,22 +7834,16 @@ class RemoteCore {
7815
7834
  this.setState(CLIENT_STATE.CID_READY);
7816
7835
  break;
7817
7836
 
7818
-
7819
- case IOMsg.ECHO: // TEXT only
7820
- try {
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')
7837
+ case IOMsg.ECHO:
7838
+ if( message.byteLength < 30) {
7839
+ this.send(message, isBinary);
7825
7840
  }
7826
- this.send(message, isBinary);
7827
7841
  break;
7828
7842
 
7829
7843
  case IOMsg.IAM:
7830
- if (message.byteLength > 1) {
7831
- let iamInfo = message.subarray(1);
7832
- this.nick = decoder$3.decode(iamInfo);
7833
- console.log('iam nick reset', this.nick);
7844
+ if (message.byteLength > 1 && message.byteLength < 30) {
7845
+ // if iam request has a text message then reset the nick property.
7846
+ this.nick = decoder$3.decode(message.subarray(1));
7834
7847
  }
7835
7848
  this.iamResponse();
7836
7849
  break;
@@ -7851,7 +7864,7 @@ class RemoteCore {
7851
7864
 
7852
7865
  case IOMsg.UNSUBSCRIBE:
7853
7866
  if (message.byteLength == 2) {
7854
- this.manager.unsubscribe([""], this);
7867
+ this.manager.unsubscribe([''], this);
7855
7868
  } else if (message.byteLength >= 3) {
7856
7869
  let tagLen = message.readUInt8(1);
7857
7870
 
@@ -7925,7 +7938,7 @@ class RemoteCore {
7925
7938
  case tt.BohoMsg.AUTH_REQ:
7926
7939
  if (!this.manager.authManager) return
7927
7940
  if (this.state < CLIENT_STATE.SENT_SERVER_READY) {
7928
- // console.log('protocol error. auth_req before server_ready')
7941
+ console.log('protocol error. auth_req before server_ready');
7929
7942
  this.close();
7930
7943
  }
7931
7944
  this.setState(CLIENT_STATE.RECV_AUTH_REQ);
@@ -7938,22 +7951,23 @@ class RemoteCore {
7938
7951
  case tt.BohoMsg.AUTH_HMAC:
7939
7952
  if (!this.manager.authManager) return
7940
7953
  if (this.state < CLIENT_STATE.SENT_SERVER_NONCE) {
7941
- // console.log('protocol error. auth_hmac before server_nonce')
7954
+ console.log('protocol error. auth_hmac before server_nonce');
7942
7955
  this.close();
7943
7956
  }
7944
7957
  this.setState(CLIENT_STATE.RECV_AUTH_HMAC);
7945
7958
  //async
7946
7959
  this.manager.authManager.verify_auth_hmac(message, this)
7947
7960
  .then(authInfo => {
7948
- if (authInfo) {
7949
- this.manager.deligateSignal(remote, '@$name', authInfo.name);
7961
+ if (authInfo?.name) {
7962
+ this.manager.deligateSignal(this, '@$name', authInfo.name);
7950
7963
  // console.log('device login success authInfo', authInfo)
7951
7964
  // this.manager.sender('@$name', authInfo.name )
7952
7965
  }
7953
7966
 
7967
+ // console.log('[VERIFY AUTH_HMAC] SubClass of BohoAuth return authInfo:', authInfo )
7954
7968
  })
7955
7969
  .catch(e => {
7956
-
7970
+ console.log('authInfo return fail.', e );
7957
7971
  });
7958
7972
 
7959
7973
  return;
@@ -7979,23 +7993,19 @@ class RemoteCore {
7979
7993
  response(msgId, statusCode, body) {
7980
7994
  // console.log('response body', body)
7981
7995
  if (body) {
7982
-
7983
7996
  this.send_enc_mode(M$1.pack(
7984
7997
  MB('#type', '8', IOMsg.RESPONSE_MBP),
7985
7998
  MB('status', '8', statusCode),
7986
7999
  MB('mid', '16', msgId),
7987
8000
  MB('body', body)
7988
8001
  ));
7989
-
7990
8002
  } else {
7991
8003
  this.send_enc_mode(M$1.pack(
7992
8004
  MB('#type', '8', IOMsg.RESPONSE_MBP),
7993
8005
  MB('status', '8', statusCode),
7994
8006
  MB('mid', '16', msgId)
7995
8007
  ));
7996
-
7997
8008
  }
7998
-
7999
8009
  }
8000
8010
 
8001
8011
 
@@ -8036,9 +8046,9 @@ class RemoteCore {
8036
8046
 
8037
8047
 
8038
8048
 
8039
- iamResponse(info = "") {
8049
+ iamResponse(info = '') {
8040
8050
 
8041
- if (info == "") {
8051
+ if (info == '') {
8042
8052
  let channels = [];
8043
8053
  for (let tag of this.channels.keys()) {
8044
8054
  channels.push(tag);
@@ -8046,15 +8056,17 @@ class RemoteCore {
8046
8056
 
8047
8057
  info = {
8048
8058
  "ssid": this.ssid,
8049
- "uid": this.uid,
8050
8059
  "cid": this.cid,
8051
8060
  "did": this.did,
8061
+ "uid": this.uid,
8062
+ "level": this.level,
8052
8063
  "nick": this.nick,
8053
8064
  "ip": this.ip
8054
8065
  , 'tag': channels
8055
8066
  };
8056
8067
  }
8057
8068
 
8069
+ // console.log( 'iam res info', info )
8058
8070
  let pack = M$1.pack(
8059
8071
  MB('#MsgType', '8', IOMsg.IAM_RES),
8060
8072
  MB('#info', info)
@@ -8440,8 +8452,7 @@ class Metric {
8440
8452
  ip: remote.ip,
8441
8453
  uptime: Math.trunc((Date.now() - remote.socket.openTime) / 1000),
8442
8454
  nick: remote.nick,
8443
- ssid: remote.ssid,
8444
- echo: remote.lastEchoMessage
8455
+ ssid: remote.ssid
8445
8456
  }
8446
8457
  } else if (mode == 3) {
8447
8458
  return {
@@ -8656,11 +8667,11 @@ class Manager {
8656
8667
  }
8657
8668
 
8658
8669
  sender(tag, remote, message) {
8659
- if (serverOption.memberOnly && !remote.boho.isAuthorized) {
8660
- // console.log("## MemberOnly, reject unAuthorized remote." )
8670
+ if (serverOption.membersOnly && !remote.boho.isAuthorized) {
8671
+ console.log("[membersOnly] unAuthorized remote.",tag );
8661
8672
  remote.send(Buffer.from([IOMsg.SERVER_CLEAR_AUTH]));
8662
8673
  remote.close();
8663
- return ['err', 'not autrized']
8674
+ return ['err', 'unAuthorized']
8664
8675
  }
8665
8676
 
8666
8677
  if (tag.indexOf('$') == 0) return ['err', 'prefix $ is reserved for userSet tag.']
@@ -8895,7 +8906,6 @@ class Manager {
8895
8906
  this.retain_messages.clear();
8896
8907
  this.channel_map.clear();
8897
8908
 
8898
- console.log('Manager closed');
8899
8909
  }
8900
8910
  }
8901
8911
 
@@ -8919,20 +8929,20 @@ class Server extends require$$0$3 {
8919
8929
  let pingT = parseInt(options.timeout);
8920
8930
  if (pingT && pingT >= 1000) serverOption.timeout = pingT;
8921
8931
  }
8922
-
8923
8932
  if (options.monitorPeriod) {
8924
8933
  let monitorT = parseInt(options.monitorPeriod);
8925
8934
  if (monitorT && monitorT >= 1000) serverOption.monitorPeriod = monitorT;
8926
8935
  }
8927
-
8928
-
8929
8936
  if (options.showMessage) {
8930
8937
  serverOption.showMessage = options.showMessage;
8931
8938
  }
8932
-
8933
8939
  if (options.showMetric) {
8934
8940
  serverOption.showMetric = options.showMetric;
8935
8941
  }
8942
+ if (options.membersOnly) {
8943
+ serverOption.membersOnly = options.membersOnly;
8944
+ }
8945
+
8936
8946
 
8937
8947
  if (options.port || options.port == 0) {
8938
8948
  this.port = parseInt(options.port);
@@ -8942,6 +8952,10 @@ class Server extends require$$0$3 {
8942
8952
  this.httpServer = options.httpServer;
8943
8953
  }
8944
8954
 
8955
+ if (options.wsPath) {
8956
+ this.wsPath = options.wsPath;
8957
+ }
8958
+
8945
8959
  if (options.congPort || options.congPort == 0) {
8946
8960
  this.congPort = parseInt(options.congPort);
8947
8961
  }
@@ -8954,7 +8968,7 @@ class Server extends require$$0$3 {
8954
8968
  if (this.congPort || this.congPort == 0) this.serverCountToListen++;
8955
8969
 
8956
8970
  if (this.serverCountToListen === 0) {
8957
- process.nextTick(() => this.emit('ready'));
8971
+ throw new Error('Cannot create Server: At least one of "port", "httpServer", or "congPort" must be specified.');
8958
8972
  } else {
8959
8973
  if (this.port || this.port == 0 || this.httpServer) this.startWSServer();
8960
8974
  if (this.congPort || this.congPort == 0) this.startCongServer();
@@ -8964,14 +8978,11 @@ class Server extends require$$0$3 {
8964
8978
 
8965
8979
 
8966
8980
  startWSServer() {
8967
-
8968
8981
  // console.log('optoins', options )
8969
8982
  if (this.port || this.port == 0) {
8970
- console.log('opening WebSocket Server port:', this.port);
8971
- this.wss = new WebSocketServer({ port: this.port });
8972
- } else if (this.httpServer) {
8973
- console.log('opening WebSocket Server external httpServer:');
8974
- this.wss = new WebSocketServer({ server: this.httpServer });
8983
+ this.wss = new WebSocketServer({ port: this.port , path: this.wsPath });
8984
+ } else if (this.httpServer ) {
8985
+ this.wss = new WebSocketServer({ server: this.httpServer, path: this.wsPath });
8975
8986
  } else {
8976
8987
  throw new TypeError(
8977
8988
  'One and only one of the "port", "httpServer"' +
@@ -8979,7 +8990,6 @@ class Server extends require$$0$3 {
8979
8990
  );
8980
8991
  }
8981
8992
 
8982
-
8983
8993
  this.wss.once('listening', () => {
8984
8994
  this.port = this.wss.address().port;
8985
8995
  console.log('wss server bound port:', this.port );
@@ -8990,7 +9000,6 @@ class Server extends require$$0$3 {
8990
9000
  });
8991
9001
 
8992
9002
  // this.wss.setMaxListeners(0)
8993
-
8994
9003
  this.wss.on('error', (err) => {
8995
9004
  console.error('### ws server error:', err.message);
8996
9005
  if (err.code == 'EADDRINUSE') {
@@ -8998,8 +9007,8 @@ class Server extends require$$0$3 {
8998
9007
  }
8999
9008
  });
9000
9009
 
9001
- this.wss.on('close', (err) => {
9002
- console.log('### WS server closed.', err);
9010
+ this.wss.on('close', () => {
9011
+ console.log('### WS server is closed.');
9003
9012
  });
9004
9013
 
9005
9014
  this.wss.on('connection', (ws, req) => {
@@ -9011,8 +9020,6 @@ class Server extends require$$0$3 {
9011
9020
  }
9012
9021
 
9013
9022
  startCongServer() {
9014
- console.log('opening CongSocket Server port:', this.congPort);
9015
-
9016
9023
  this.congServer = net.createServer((socket) => {
9017
9024
  this.manager.addRemote(socket);
9018
9025
  })
@@ -9022,7 +9029,7 @@ class Server extends require$$0$3 {
9022
9029
  process.exit();
9023
9030
  }
9024
9031
  }).on('close', () => {
9025
- console.log('### cong server closed.');
9032
+ console.log('### congsocket server is closed.');
9026
9033
  }).listen(this.congPort, () => {
9027
9034
  this.congPort = this.congServer.address().port;
9028
9035
  console.log('congsocket server bound port:', this.congPort );
@@ -9033,64 +9040,76 @@ class Server extends require$$0$3 {
9033
9040
  });
9034
9041
  }
9035
9042
 
9036
-
9037
-
9043
+ /**
9044
+ * API register.
9045
+ * target: api_name <string>
9046
+ * api: api_module <function module|class instance>
9047
+ * return this
9048
+ */
9038
9049
  api(target, api) {
9039
9050
 
9040
- this.apiNames.add(target);
9041
-
9051
+ if( typeof target !== 'string'){
9052
+ throw new Error(`api( target ,api ) target name is not a string.`)
9053
+ }
9042
9054
  if (!api.checkPermission || typeof api.checkPermission != 'function') {
9043
- throw new Error('wrong api interface. no checkPermission function.')
9055
+ throw new Error(`API ${target} : no checkPermission or not a function.`)
9044
9056
  }
9045
-
9046
-
9047
- if (typeof api.request == 'function' && Array.isArray(api.commands)) {
9048
- console.log(`API TYPE1. A Class with one request function. target: ${target} list: ${api.commands}`);
9049
-
9050
- this.on(target, (remote, req) => {
9051
- if (api.checkPermission(remote, req)) {
9052
- api.request(remote, req);
9053
- } else {
9054
- remote.response(req.mid, STATUS.ERROR, "NO_PERMISSION.");
9057
+ if(!api.commands || !Array.isArray(api.commands) ){
9058
+ throw new Error(`API ${target} : no commands or !Array.`)
9059
+ }
9060
+
9061
+ // API TYPE 1. single request() function.
9062
+ if ( api.request && typeof api.request == 'function' ) {
9063
+ this.on(target, async (remote, req) => {
9064
+ try {
9065
+ if (!api.checkPermission(remote, req)) {
9066
+ remote.response(req.mid, STATUS.ERROR, "NO_PERMISSION.");
9067
+ return
9068
+ }
9069
+ if( api.commands.includes( req.topic )){
9070
+ console.log('server api req', req );
9071
+ await api.request(remote, req);
9072
+ }else {
9073
+ remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
9074
+ }
9075
+ } catch (error) {
9076
+ console.error(`Unhandled API Error in target [${target}]:`, error);
9077
+ remote.response(req.mid, STATUS.ERROR, "INTERNAL_SERVER_ERROR");
9055
9078
  }
9056
9079
  });
9057
-
9058
9080
  } else {
9059
- let apiList = [];
9060
- Object.keys(api).forEach(v => {
9061
- if (typeof api[v] === 'function') apiList.push(v);
9062
- console.log('api list', typeof api[v], v);
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);
9081
+ // API TYPE 2. multiple functions.
9082
+ this.on(target, async (remote, req) => {
9083
+ try {
9084
+ if (!api.checkPermission(remote, req)) {
9085
+ remote.response(req.mid, STATUS.ERROR, "NO_PERMISSION.");
9075
9086
  return
9076
- } else {
9077
- r = `target: ${req.target} has not topic name: ${req.topic}`;
9078
9087
  }
9088
+ if( api.commands.includes( req.topic )){
9089
+ await api[req.topic](remote, req);
9090
+ }else {
9091
+ remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
9092
+ }
9093
+ } catch (error) {
9094
+ console.error(`Unhandled API Error in target [${target}]:`, error);
9095
+ remote.response(req.mid, STATUS.ERROR, "INTERNAL_SERVER_ERROR");
9079
9096
  }
9080
-
9081
- remote.response(req.mid, STATUS.ERROR, r);
9082
9097
  });
9083
9098
  }
9084
-
9099
+ this.apiNames.add(target);
9100
+ console.log(`[API registed: ${target} ] accept commands: ${api.commands}`);
9085
9101
  return this
9086
9102
  }
9087
9103
 
9088
9104
  close(callback) {
9089
- console.log('closing io-signal server...');
9105
+ console.log('closing iosignal server...');
9090
9106
  if (this.manager) {
9091
9107
  this.manager.close();
9092
9108
  }
9093
9109
 
9110
+ this.apiNames.forEach(v => this.removeAllListeners(v));
9111
+ this.apiNames.clear();
9112
+
9094
9113
  let serverCount = 0;
9095
9114
  if (this.wss) serverCount++;
9096
9115
  if (this.congServer) serverCount++;
@@ -9104,14 +9123,14 @@ class Server extends require$$0$3 {
9104
9123
  const onClosed = () => {
9105
9124
  closedCount++;
9106
9125
  if (closedCount === serverCount) {
9107
- console.log('io-signal server closed.');
9126
+ console.log('IOSignal server is closed.');
9108
9127
  if (callback) callback();
9109
9128
  }
9110
9129
  };
9111
9130
 
9112
9131
  if (this.wss) {
9113
9132
  this.wss.close(() => {
9114
- console.log('wss server closed.');
9133
+ // console.log('wss server closed.')
9115
9134
  onClosed();
9116
9135
  });
9117
9136
  }
@@ -9119,7 +9138,7 @@ class Server extends require$$0$3 {
9119
9138
  if (this.congServer) {
9120
9139
  this.congServer.close((err) => {
9121
9140
  if (err) console.error('congServer close error', err);
9122
- console.log('cong server closed.');
9141
+ // console.log('cong server closed.')
9123
9142
  onClosed();
9124
9143
  });
9125
9144
  }
@@ -9142,10 +9161,9 @@ class BohoAuth {
9142
9161
  let peerInfo = `FAIL #${peer.ssid} reason:${reason} `;
9143
9162
  this.authLogger.log(peerInfo);
9144
9163
  }
9145
-
9146
- console.log('## AUTH_FAIL reason:', reason);
9147
- // peer.send( Buffer.from( [Boho.BohoMsg.AUTH_FAIL] ))
9164
+ // console.log('##### AUTH_FAIL reason: ', reason)
9148
9165
  peer.setState(CLIENT_STATE.AUTH_FAIL);
9166
+ // add some delay time.
9149
9167
  setTimeout(e => {
9150
9168
  peer.send(Buffer.from([tt.BohoMsg.AUTH_FAIL]));
9151
9169
  }, serverOption.auth.delay_auth_fail);
@@ -9155,30 +9173,31 @@ class BohoAuth {
9155
9173
  try {
9156
9174
  //1. unpack
9157
9175
  let infoPack = M$1.unpack(auth_hmac, tt.Meta.AUTH_HMAC);
9176
+
9158
9177
  if (!infoPack) {
9159
9178
  this.send_auth_fail(peer, 'unpack auth_pack fail');
9160
9179
  return
9161
9180
  }
9162
-
9181
+
9163
9182
  let id = "";
9164
9183
  if (infoPack.id8.includes(0)) {
9165
9184
  id = decoder.decode(infoPack.id8.subarray(0, infoPack.id8.indexOf(0)));
9166
9185
  } else {
9167
9186
  id = decoder.decode(infoPack.id8);
9168
9187
  }
9169
-
9188
+
9170
9189
  //2. get key of id from DB
9171
9190
  let authInfo = await this.getAuth(id);
9172
9191
 
9173
- // console.log('##### authInfo',authInfo )
9174
- if (serverOption.debug.showAuthInfo) {
9175
- }
9176
-
9177
9192
  if (!authInfo) {
9178
9193
  this.send_auth_fail(peer, 'NO ID:' + id);
9179
9194
  return
9180
9195
  }
9181
9196
 
9197
+ if (serverOption.debug.showAuthInfo) {
9198
+ console.log('[debug]showAuthInfo',authInfo );
9199
+ }
9200
+
9182
9201
  // console.log('db authInfo.key: ', authInfo.key)
9183
9202
  peer.boho.copy_id8(infoPack.id8);
9184
9203
  // type of key
@@ -9229,6 +9248,7 @@ class BohoAuth {
9229
9248
 
9230
9249
  //6. delete current (temp rand)cid if exist.
9231
9250
  if (peer.cid) {
9251
+ console.log('duplicate cid');
9232
9252
  peer.manager.cid2remote.delete(peer.cid);
9233
9253
  }
9234
9254
 
@@ -9236,6 +9256,7 @@ class BohoAuth {
9236
9256
  peer.did = id;
9237
9257
  peer.cid = authInfo.cid;
9238
9258
  peer.nick = authInfo.cid; // temporary: nick as cid
9259
+ if( authInfo.uid ) peer.uid = authInfo.uid;
9239
9260
 
9240
9261
  //8. setting quota level.
9241
9262
  let quotaLevel = serverOption.defaultQuotaIndex;
@@ -9274,14 +9295,12 @@ class BohoAuth {
9274
9295
  }
9275
9296
  return authInfo
9276
9297
  } catch (error) {
9277
- this.send_auth_fail(peer, 'caught: unknown error' + error);
9298
+ this.send_auth_fail(peer, '[BohoAuth]caught: unknown error:' + error);
9278
9299
  }
9279
9300
 
9280
9301
  }
9281
9302
 
9282
9303
 
9283
-
9284
-
9285
9304
  }
9286
9305
 
9287
9306
  class Auth_File extends BohoAuth {
@@ -9437,11 +9456,15 @@ class Auth_Redis extends BohoAuth {
9437
9456
 
9438
9457
  // get device key from DB. (for Boho auth.)
9439
9458
  async getAuth(id) {
9440
- let result = await this.redis.hGetAll(DEVICE_PREFIX + id);
9441
- if (result.key) return result
9459
+ try {
9460
+ let result = await this.redis.hGetAll(DEVICE_PREFIX + id);
9461
+ if (result.key) return result
9462
+ } catch (error) {
9463
+ console.log('getAuth', error);
9464
+ }
9442
9465
  }
9443
9466
 
9444
-
9467
+ //api_sudo call
9445
9468
  async getAuthIdList() {
9446
9469
  let result = await this.redis.keys(DEVICE_PREFIX + '*');
9447
9470
  result = result.map(v => {
@@ -9456,6 +9479,7 @@ class Auth_Redis extends BohoAuth {
9456
9479
  return this.redis.hSet(DEVICE_PREFIX + id, { 'key': Base64hashKey, 'cid': cid, 'level': level })
9457
9480
  }
9458
9481
 
9482
+ //api_sudo call
9459
9483
  async delAuth(id) {
9460
9484
  return this.redis.del(DEVICE_PREFIX + id)
9461
9485
  }
@@ -9466,16 +9490,16 @@ class Auth_Redis extends BohoAuth {
9466
9490
 
9467
9491
  }
9468
9492
 
9469
- const MIN_LEVEL$2 = 0;
9493
+ const commands$1 = ['echo', 'date', 'unixtime'];
9470
9494
 
9495
+ const MIN_LEVEL$2 = 0;
9471
9496
  function checkPermission$1(remote) {
9472
- if (remote.level >= MIN_LEVEL$2) {
9473
- return true
9474
- } else {
9475
- return false
9476
- }
9497
+ return (remote.level >= MIN_LEVEL$2) ? true : false;
9477
9498
  }
9478
9499
 
9500
+ /**
9501
+ * client api call example: await io.req('reply','echo','hello')
9502
+ */
9479
9503
  async function echo(remote, req) {
9480
9504
  if (!req.args)
9481
9505
  remote.response(req.mid, STATUS.ERROR, 'no message to echo');
@@ -9483,11 +9507,17 @@ async function echo(remote, req) {
9483
9507
  remote.response(req.mid, STATUS.OK, req.args);
9484
9508
  }
9485
9509
 
9510
+ /**
9511
+ * client api call example: await io.req('reply','date')
9512
+ */
9486
9513
  async function date(remote, req) {
9487
9514
  let r = new Date().toUTCString();
9488
9515
  remote.response(req.mid, STATUS.OK, r);
9489
9516
  }
9490
9517
 
9518
+ /**
9519
+ * client api call example: await io.req('reply','unixtime')
9520
+ */
9491
9521
  async function unixtime(remote, req) {
9492
9522
  let r = Math.floor(Date.now() / 1000);
9493
9523
  remote.response(req.mid, STATUS.OK, r);
@@ -9496,13 +9526,12 @@ async function unixtime(remote, req) {
9496
9526
  var api_reply = /*#__PURE__*/Object.freeze({
9497
9527
  __proto__: null,
9498
9528
  checkPermission: checkPermission$1,
9529
+ commands: commands$1,
9499
9530
  date: date,
9500
9531
  echo: echo,
9501
9532
  unixtime: unixtime
9502
9533
  });
9503
9534
 
9504
- const MIN_LEVEL$1 = 255;
9505
-
9506
9535
  const commands = [
9507
9536
  'cid', 'remotes', 'clients',
9508
9537
  'channels', 'subscribers',
@@ -9512,13 +9541,9 @@ const commands = [
9512
9541
  'adddevice', 'getdevice', 'deldevice'
9513
9542
  ];
9514
9543
 
9515
-
9544
+ const MIN_LEVEL$1 = 255;
9516
9545
  function checkPermission(remote) {
9517
- if (remote.level >= MIN_LEVEL$1) {
9518
- return true
9519
- } else {
9520
- return false
9521
- }
9546
+ return (remote.level >= MIN_LEVEL$1) ? true : false;
9522
9547
  }
9523
9548
 
9524
9549
  async function request(remote, req) {
@@ -9595,15 +9620,23 @@ var api_sudo = /*#__PURE__*/Object.freeze({
9595
9620
  request: request
9596
9621
  });
9597
9622
 
9623
+ /**
9624
+ * RedisAPI <IOSignal API>
9625
+ *
9626
+ * iosignal 클라이언트의 redis 질의 요청을 받으면,
9627
+ * redisClient 로 연결된 redis-server 에게 질의 후 결과를 되돌려 준다.
9628
+ *
9629
+ * client ex:
9630
+ * await io.req('redis','hget','user:id' )
9631
+ *
9632
+ */
9633
+
9598
9634
  const MIN_LEVEL = 200;
9599
9635
  const COMMANDS = [
9600
- 'GET', 'SET',
9601
- 'HGETALL', 'HGET',
9602
- 'HSET', 'SADD',
9603
- 'SISMEMBER', 'SMEMBERS',
9604
- 'EXISTS', 'SREM',
9605
- 'DEL', 'KEYS',
9606
- 'SAVE'
9636
+ 'GET', 'SET', 'HGETALL', 'HGET', 'HSET', 'SADD', 'SISMEMBER',
9637
+ 'SMEMBERS', 'EXISTS', 'SREM', 'DEL', 'KEYS', 'SAVE',
9638
+ 'get', 'set', 'hGetAll', 'hGet', 'hSet', 'sAdd', 'sIsMember',
9639
+ 'sMembers', 'exists', 'sRem', 'del', 'keys', 'save'
9607
9640
  ];
9608
9641
 
9609
9642
  class RedisAPI {
@@ -9616,42 +9649,23 @@ class RedisAPI {
9616
9649
  this.commands = COMMANDS;
9617
9650
  }
9618
9651
 
9619
-
9620
9652
  checkPermission(remote, req) {
9621
- console.log('checkPermission', remote.level, 'vs', this.minLevel);
9622
- if (remote.level >= this.minLevel) {
9623
- return true
9624
- } else {
9625
- return false
9626
- }
9653
+ return (remote.level >= this.minLevel) ? true : false;
9627
9654
  }
9628
9655
 
9629
-
9630
9656
  async request(remote, req) {
9631
-
9632
9657
  let result;
9633
- let status = STATUS.OK;
9634
9658
  try {
9635
9659
  let cmd = req.topic;
9636
- cmd = cmd.toUpperCase();
9637
- if (COMMANDS.includes(cmd)) {
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
-
9660
+ if (req.args?.length > 0) {
9661
+ result = await this.redisClient[cmd](...req.args);
9647
9662
  } else {
9648
- status = STATUS.ERROR;
9663
+ result = await this.redisClient[cmd]();
9649
9664
  }
9650
- remote.response(req.mid, status, result);
9665
+ remote.response(req.mid, STATUS.OK, result);
9651
9666
  } catch (e) {
9652
9667
  remote.response(req.mid, STATUS.ERROR, e.message);
9653
9668
  }
9654
-
9655
9669
  }
9656
9670
 
9657
9671
  }