iosignal 4.7.0 → 4.10.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/README.md +0 -3
- package/dist/io.d.ts +3 -9
- package/dist/io.js +4 -4
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +1 -1
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +51 -86
- package/dist/types/client/IOCore.d.ts +3 -9
- package/package.json +1 -1
- package/src/auth/BohoAuth.js +26 -35
- package/src/client/IOCore.js +18 -44
- package/src/server/Remote.js +1 -0
- package/src/server/Server.js +4 -4
- package/src/server/serverOption.js +1 -2
package/dist/iosignal.js
CHANGED
|
@@ -13,7 +13,7 @@ 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.10.0";
|
|
17
17
|
var pkg = {
|
|
18
18
|
version: version$1};
|
|
19
19
|
|
|
@@ -1003,6 +1003,7 @@ class IOCore extends EventEmitter {
|
|
|
1003
1003
|
stop() {
|
|
1004
1004
|
this.autoReconnect = false;
|
|
1005
1005
|
this.close();
|
|
1006
|
+
this.cid = '';
|
|
1006
1007
|
this.stateChange('stop','stop');
|
|
1007
1008
|
}
|
|
1008
1009
|
|
|
@@ -1215,7 +1216,7 @@ class IOCore extends EventEmitter {
|
|
|
1215
1216
|
|
|
1216
1217
|
// **IMPORTANT** change state before subscribe.
|
|
1217
1218
|
this.stateChange('ready', 'cid_ready');
|
|
1218
|
-
this.
|
|
1219
|
+
this.subscribe_channels();
|
|
1219
1220
|
break;
|
|
1220
1221
|
|
|
1221
1222
|
case IOMsg.QUOTA_LEVEL:
|
|
@@ -1319,7 +1320,7 @@ class IOCore extends EventEmitter {
|
|
|
1319
1320
|
}
|
|
1320
1321
|
let oneString = decoder$4.decode(payloadStringWithoutNull);
|
|
1321
1322
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneString);
|
|
1322
|
-
|
|
1323
|
+
else {
|
|
1323
1324
|
this.emit(tag, tag, oneString);
|
|
1324
1325
|
this.emit('message', tag, oneString);
|
|
1325
1326
|
}
|
|
@@ -1327,7 +1328,7 @@ class IOCore extends EventEmitter {
|
|
|
1327
1328
|
|
|
1328
1329
|
case PAYLOAD_TYPE.BINARY:
|
|
1329
1330
|
if (tag.indexOf('@') === 0) this.emit('@', tag, payloadBuffer);
|
|
1330
|
-
|
|
1331
|
+
else {
|
|
1331
1332
|
this.emit(tag, tag, payloadBuffer);
|
|
1332
1333
|
this.emit('message', tag, payloadBuffer);
|
|
1333
1334
|
}
|
|
@@ -1337,7 +1338,7 @@ class IOCore extends EventEmitter {
|
|
|
1337
1338
|
let oneObjectBuffer = decoder$4.decode(payloadBuffer);
|
|
1338
1339
|
let oneJSONObject = JSON.parse(oneObjectBuffer);
|
|
1339
1340
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneJSONObject);
|
|
1340
|
-
|
|
1341
|
+
else {
|
|
1341
1342
|
this.emit(tag, tag, oneJSONObject);
|
|
1342
1343
|
this.emit('message', tag, oneJSONObject);
|
|
1343
1344
|
}
|
|
@@ -1347,7 +1348,7 @@ class IOCore extends EventEmitter {
|
|
|
1347
1348
|
let mjsonBuffer = decoder$4.decode(payloadBuffer);
|
|
1348
1349
|
let mjson = JSON.parse(mjsonBuffer);
|
|
1349
1350
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mjson);
|
|
1350
|
-
|
|
1351
|
+
else {
|
|
1351
1352
|
this.emit(tag, tag, ...mjson);
|
|
1352
1353
|
this.emit('message', tag, ...mjson);
|
|
1353
1354
|
}
|
|
@@ -1356,7 +1357,7 @@ class IOCore extends EventEmitter {
|
|
|
1356
1357
|
case PAYLOAD_TYPE.MBA:
|
|
1357
1358
|
let mbaObject = M$1.unpack(payloadBuffer);
|
|
1358
1359
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mbaObject.args);
|
|
1359
|
-
|
|
1360
|
+
else {
|
|
1360
1361
|
this.emit(tag, tag, ...mbaObject.args);
|
|
1361
1362
|
this.emit('message', tag, ...mbaObject.args);
|
|
1362
1363
|
}
|
|
@@ -1484,6 +1485,7 @@ class IOCore extends EventEmitter {
|
|
|
1484
1485
|
console.log('## your maximum signalSize(bytes) is:', this.quota.signalSize);
|
|
1485
1486
|
return
|
|
1486
1487
|
}
|
|
1488
|
+
// console.log(`C->[${IOMsg[ data[0]]}]`)
|
|
1487
1489
|
this.socket_send(data);
|
|
1488
1490
|
}
|
|
1489
1491
|
|
|
@@ -1710,14 +1712,6 @@ class IOCore extends EventEmitter {
|
|
|
1710
1712
|
subscribe(tag) {
|
|
1711
1713
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
1712
1714
|
if (tag.length > SIZE_LIMIT.TAG_LEN1) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN1)
|
|
1713
|
-
if (this.state !== STATE.READY) return
|
|
1714
|
-
|
|
1715
|
-
// subscribe 사용시, 사용 'ready' 이벤트시 메뉴얼 등록되므로 여기에 등록하면 2중 호출된다.
|
|
1716
|
-
// 즉, channels 등록은 listen 같은 자동화 구독시만 사용.
|
|
1717
|
-
// let tagList = tag.split(',')
|
|
1718
|
-
// tagList.forEach(tag => {
|
|
1719
|
-
// this.channels.add(tag)
|
|
1720
|
-
// })
|
|
1721
1715
|
|
|
1722
1716
|
try {
|
|
1723
1717
|
let tagEncoded = encoder$1.encode(tag);
|
|
@@ -1727,47 +1721,27 @@ class IOCore extends EventEmitter {
|
|
|
1727
1721
|
M$1.NB('8', tagEncoded.byteLength),
|
|
1728
1722
|
tagEncoded]));
|
|
1729
1723
|
} catch (error) { }
|
|
1724
|
+
|
|
1730
1725
|
}
|
|
1731
1726
|
|
|
1727
|
+
|
|
1732
1728
|
/**
|
|
1733
|
-
* Subscribes
|
|
1734
|
-
*
|
|
1735
|
-
* @returns {Promise<any>}
|
|
1736
|
-
* @throws {TypeError} If tag is not a string or exceeds length limit.
|
|
1729
|
+
* Subscribes stored channels.
|
|
1730
|
+
* called client state become 'ready'
|
|
1737
1731
|
*/
|
|
1738
|
-
|
|
1739
|
-
if (
|
|
1740
|
-
if (
|
|
1741
|
-
|
|
1742
|
-
if (this.state !== STATE.READY) {
|
|
1743
|
-
return Promise.reject('subscribe_promise:: connection is not ready')
|
|
1744
|
-
}
|
|
1732
|
+
subscribe_channels() {
|
|
1733
|
+
if (this.state !== STATE.READY) return
|
|
1734
|
+
if (this.channels.size == 0) return
|
|
1735
|
+
let tag = Array.from(this.channels).join(',');
|
|
1745
1736
|
|
|
1746
1737
|
try {
|
|
1747
1738
|
let tagEncoded = encoder$1.encode(tag);
|
|
1748
1739
|
this.send_enc_mode(
|
|
1749
1740
|
Buffer$1.concat([
|
|
1750
|
-
M$1.NB('8', IOMsg.
|
|
1751
|
-
M$1.NB('
|
|
1752
|
-
M$1.NB('16', tagEncoded.byteLength),
|
|
1741
|
+
M$1.NB('8', IOMsg.SUBSCRIBE),
|
|
1742
|
+
M$1.NB('8', tagEncoded.byteLength),
|
|
1753
1743
|
tagEncoded]));
|
|
1754
|
-
return this.setMsgPromise(this.mid)
|
|
1755
1744
|
} catch (error) { }
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
/**
|
|
1759
|
-
* Subscribes to channels stored in memory (local cache).
|
|
1760
|
-
*/
|
|
1761
|
-
subscribe_memory_channels() { //local cache . auto_resubscribe
|
|
1762
|
-
if (this.channels.size == 0) return
|
|
1763
|
-
let chList = Array.from(this.channels).join(',');
|
|
1764
|
-
|
|
1765
|
-
this.subscribe_promise(chList)
|
|
1766
|
-
.then((res) => {
|
|
1767
|
-
// console.log('>> SUBSCRIBE_REQ result', res ) // return code == map.size
|
|
1768
|
-
}).catch((e) => {
|
|
1769
|
-
console.log('>> SUBSCRIBE FAIL:', e);
|
|
1770
|
-
});
|
|
1771
1745
|
|
|
1772
1746
|
}
|
|
1773
1747
|
|
|
@@ -7662,9 +7636,8 @@ let serverOption = {
|
|
|
7662
7636
|
},
|
|
7663
7637
|
|
|
7664
7638
|
auth: {
|
|
7665
|
-
delay_auth_fail: 600
|
|
7639
|
+
delay_auth_fail: 600
|
|
7666
7640
|
},
|
|
7667
|
-
|
|
7668
7641
|
membersOnly: false
|
|
7669
7642
|
|
|
7670
7643
|
};
|
|
@@ -8333,6 +8306,7 @@ class Remote extends RemoteCore {
|
|
|
8333
8306
|
|
|
8334
8307
|
// node.js server side remote.
|
|
8335
8308
|
send(message, isBinary) {
|
|
8309
|
+
// console.log(`<-S [${IOMsg[ message[0]]}]`)
|
|
8336
8310
|
this.manager.txBytes += message.byteLength;
|
|
8337
8311
|
this.socket.txCounter++;
|
|
8338
8312
|
if (this.socketType === 'websocket') {
|
|
@@ -9119,7 +9093,7 @@ class Server extends require$$0$3 {
|
|
|
9119
9093
|
|
|
9120
9094
|
// Service TYPE 1. single call() function.
|
|
9121
9095
|
if ( service_module.call && typeof service_module.call == 'function' ) {
|
|
9122
|
-
this.on(target,
|
|
9096
|
+
this.on(target, (remote, req) => {
|
|
9123
9097
|
try {
|
|
9124
9098
|
if (!service_module.checkPermission(remote, req)) {
|
|
9125
9099
|
remote.response(req.mid, STATUS.ERROR, "NO_PERMISSION.");
|
|
@@ -9127,7 +9101,7 @@ class Server extends require$$0$3 {
|
|
|
9127
9101
|
}
|
|
9128
9102
|
if( service_module.commands.includes( req.topic )){
|
|
9129
9103
|
// console.log('server service_module req', req )
|
|
9130
|
-
|
|
9104
|
+
service_module.call(remote, req);
|
|
9131
9105
|
}else {
|
|
9132
9106
|
remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
|
|
9133
9107
|
}
|
|
@@ -9138,14 +9112,14 @@ class Server extends require$$0$3 {
|
|
|
9138
9112
|
});
|
|
9139
9113
|
} else {
|
|
9140
9114
|
// Service TYPE 2. multiple functions.
|
|
9141
|
-
this.on(target,
|
|
9115
|
+
this.on(target, (remote, req) => {
|
|
9142
9116
|
try {
|
|
9143
9117
|
if (!service_module.checkPermission(remote, req)) {
|
|
9144
9118
|
remote.response(req.mid, STATUS.ERROR, "NO_PERMISSION.");
|
|
9145
9119
|
return
|
|
9146
9120
|
}
|
|
9147
9121
|
if( service_module.commands.includes( req.topic )){
|
|
9148
|
-
|
|
9122
|
+
service_module[req.topic](remote, req);
|
|
9149
9123
|
}else {
|
|
9150
9124
|
remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
|
|
9151
9125
|
}
|
|
@@ -9212,7 +9186,7 @@ class BohoAuth {
|
|
|
9212
9186
|
throw new Error('BohoAuth must be initialized with a keyProvider.');
|
|
9213
9187
|
}
|
|
9214
9188
|
this.keyProvider = keyProvider;
|
|
9215
|
-
|
|
9189
|
+
this.keepOldConnection = true;
|
|
9216
9190
|
this.authLogger;
|
|
9217
9191
|
if (serverOption.fileLogger.auth.use) {
|
|
9218
9192
|
this.authLogger = new FileLogger(serverOption.fileLogger.auth.path);
|
|
@@ -9227,42 +9201,40 @@ class BohoAuth {
|
|
|
9227
9201
|
}
|
|
9228
9202
|
// console.log('##### AUTH_FAIL reason: ', reason)
|
|
9229
9203
|
peer.setState(STATE.AUTH_FAIL);
|
|
9230
|
-
peer.send(Buffer.from([tt.BohoMsg.AUTH_FAIL]));
|
|
9231
9204
|
// add some delay time.
|
|
9232
|
-
|
|
9233
|
-
|
|
9205
|
+
setTimeout(e => {
|
|
9206
|
+
peer.send(Buffer.from([tt.BohoMsg.AUTH_FAIL]));
|
|
9207
|
+
}, serverOption.auth.delay_auth_fail);
|
|
9234
9208
|
}
|
|
9235
9209
|
|
|
9210
|
+
|
|
9236
9211
|
async verify_auth_hmac(auth_hmac, peer) {
|
|
9237
9212
|
try {
|
|
9238
9213
|
//1. unpack
|
|
9239
9214
|
let infoPack = M$1.unpack(auth_hmac, tt.Meta.AUTH_HMAC);
|
|
9240
|
-
|
|
9241
9215
|
if (!infoPack) {
|
|
9242
9216
|
this.send_auth_fail(peer, 'unpack auth_pack fail');
|
|
9243
9217
|
return
|
|
9244
9218
|
}
|
|
9245
|
-
|
|
9219
|
+
|
|
9246
9220
|
let id = "";
|
|
9247
9221
|
if (infoPack.id8.includes(0)) {
|
|
9248
9222
|
id = decoder.decode(infoPack.id8.subarray(0, infoPack.id8.indexOf(0)));
|
|
9249
9223
|
} else {
|
|
9250
9224
|
id = decoder.decode(infoPack.id8);
|
|
9251
9225
|
}
|
|
9252
|
-
|
|
9226
|
+
|
|
9253
9227
|
//2. get key of id from DB
|
|
9254
9228
|
let authInfo = await this.keyProvider.getAuth(id);
|
|
9255
|
-
|
|
9256
9229
|
if (!authInfo) {
|
|
9257
9230
|
this.send_auth_fail(peer, 'NO ID:' + id);
|
|
9258
9231
|
return
|
|
9259
9232
|
}
|
|
9260
9233
|
|
|
9261
9234
|
if (serverOption.debug.showAuthInfo) {
|
|
9262
|
-
console.log('[debug]showAuthInfo',authInfo
|
|
9235
|
+
console.log('[debug]showAuthInfo', authInfo);
|
|
9263
9236
|
}
|
|
9264
9237
|
|
|
9265
|
-
// console.log('db authInfo.key: ', authInfo.key)
|
|
9266
9238
|
peer.boho.copy_id8(infoPack.id8);
|
|
9267
9239
|
// type of key
|
|
9268
9240
|
let authKey;
|
|
@@ -9277,46 +9249,43 @@ class BohoAuth {
|
|
|
9277
9249
|
}
|
|
9278
9250
|
|
|
9279
9251
|
//3. check hmac
|
|
9280
|
-
// console.log('-- found: authKey of id: ', id, authKey.toString('hex'))
|
|
9281
9252
|
let auth_ack = peer.boho.check_auth_hmac(infoPack);
|
|
9282
|
-
|
|
9283
|
-
// console.log('auth_ack', auth_ack )
|
|
9284
9253
|
if (!auth_ack) {
|
|
9285
9254
|
this.send_auth_fail(peer, 'hmac dismatched');
|
|
9286
9255
|
return
|
|
9287
9256
|
}
|
|
9288
9257
|
|
|
9289
9258
|
//4. get info
|
|
9290
|
-
// console.log('#### auth success' )
|
|
9291
9259
|
|
|
9292
9260
|
//5. check duplicate login.
|
|
9293
|
-
// current policy. Deny duplicate login
|
|
9294
|
-
|
|
9295
|
-
// duplicate login policy.
|
|
9296
|
-
// 1. send clear_auth signal to the old connection.
|
|
9297
|
-
// 2. close old connection.
|
|
9298
|
-
// 3. close new connection. retry from begining.
|
|
9299
9261
|
if (peer.manager.cid2remote.has(authInfo.cid)) {
|
|
9300
9262
|
let old = peer.manager.cid2remote.get(authInfo.cid);
|
|
9263
|
+
console.log('[WARN]DUPLICATE_LOGIN detected.', old.cid);
|
|
9264
|
+
old.ping(); // check the connection.
|
|
9301
9265
|
if (old == peer) {
|
|
9302
|
-
console.log('## trying RELOGIN
|
|
9266
|
+
console.log('## trying to RELOGIN after login.');
|
|
9303
9267
|
return
|
|
9304
9268
|
}
|
|
9305
|
-
|
|
9306
|
-
let
|
|
9269
|
+
|
|
9270
|
+
let authClearSignal = M$1.pack(
|
|
9307
9271
|
M$1.MB('#MsgType', '8', IOMsg.AUTH_CLEAR),
|
|
9308
9272
|
M$1.MB('#reason', 'duplicate login.')
|
|
9309
9273
|
);
|
|
9310
|
-
|
|
9311
|
-
|
|
9312
|
-
|
|
9274
|
+
if (this.keepOldConnection) { // default true
|
|
9275
|
+
// keep old connection. reject new connection by sending auth_fail signal.
|
|
9276
|
+
this.send_auth_fail(peer, 'duplicate login');
|
|
9277
|
+
// peer.send(authClearSignal)
|
|
9278
|
+
} else {
|
|
9279
|
+
// accept new connection. stop the old connection by sending auth_clear signal.
|
|
9280
|
+
old.send(authClearSignal);
|
|
9281
|
+
peer.close();
|
|
9282
|
+
}
|
|
9313
9283
|
return
|
|
9314
9284
|
}
|
|
9315
9285
|
|
|
9316
|
-
|
|
9317
|
-
//6. delete current (temp rand)cid if exist.
|
|
9286
|
+
//6. delete current (or anonymouse)cid if exist.
|
|
9318
9287
|
if (peer.cid) {
|
|
9319
|
-
console.log('
|
|
9288
|
+
// console.log('if peer has cid', peer.cid)
|
|
9320
9289
|
peer.manager.cid2remote.delete(peer.cid);
|
|
9321
9290
|
}
|
|
9322
9291
|
|
|
@@ -9324,7 +9293,7 @@ class BohoAuth {
|
|
|
9324
9293
|
peer.did = id;
|
|
9325
9294
|
peer.cid = authInfo.cid;
|
|
9326
9295
|
peer.nick = authInfo.cid; // temporary: nick as cid
|
|
9327
|
-
if(
|
|
9296
|
+
if (authInfo.uid) peer.uid = authInfo.uid;
|
|
9328
9297
|
|
|
9329
9298
|
//8. setting quota level.
|
|
9330
9299
|
let quotaLevel = serverOption.defaultQuotaIndex;
|
|
@@ -9333,7 +9302,6 @@ class BohoAuth {
|
|
|
9333
9302
|
let newQuota = quotaTable[quotaLevel];
|
|
9334
9303
|
if (!newQuota) {
|
|
9335
9304
|
let err = 'no index quotaTable for auth.level: ' + quotaLevel;
|
|
9336
|
-
console.log('##AUTH:DATA ERROR##', err);
|
|
9337
9305
|
this.send_auth_fail(peer, err);
|
|
9338
9306
|
return
|
|
9339
9307
|
} else {
|
|
@@ -9345,14 +9313,11 @@ class BohoAuth {
|
|
|
9345
9313
|
console.log('## LOGIN ADMIN CID:', peer.cid);
|
|
9346
9314
|
peer.isAdmin = true;
|
|
9347
9315
|
}
|
|
9348
|
-
// console.log('auth: peer.quota', peer.quota )
|
|
9349
9316
|
// send quota.level
|
|
9350
9317
|
peer.send(Buffer.from([IOMsg.QUOTA_LEVEL, quotaLevel]));
|
|
9351
9318
|
|
|
9352
9319
|
//9. set cid2remote
|
|
9353
9320
|
peer.manager.cid2remote.set(peer.cid, peer);
|
|
9354
|
-
// console.log( 'done: cid2remote:', peer.manager.cid2remote.keys() )
|
|
9355
|
-
// console.log("LOGIN: ", `id: ${ peer.did}(${peer.cid})` )
|
|
9356
9321
|
//10. send ack.
|
|
9357
9322
|
peer.send(auth_ack);
|
|
9358
9323
|
peer.setState(STATE.AUTH_ACK);
|
|
@@ -9363,9 +9328,9 @@ class BohoAuth {
|
|
|
9363
9328
|
}
|
|
9364
9329
|
return authInfo
|
|
9365
9330
|
} catch (error) {
|
|
9331
|
+
console.log('verify_auth_hmac error', error);
|
|
9366
9332
|
this.send_auth_fail(peer, '[BohoAuth]caught: unknown error:' + error);
|
|
9367
9333
|
}
|
|
9368
|
-
|
|
9369
9334
|
}
|
|
9370
9335
|
|
|
9371
9336
|
async getAuth(id) {
|
|
@@ -318,16 +318,10 @@ export class IOCore extends EventEmitter<string | symbol, any> {
|
|
|
318
318
|
*/
|
|
319
319
|
subscribe(tag: string): void;
|
|
320
320
|
/**
|
|
321
|
-
* Subscribes
|
|
322
|
-
*
|
|
323
|
-
* @returns {Promise<any>}
|
|
324
|
-
* @throws {TypeError} If tag is not a string or exceeds length limit.
|
|
325
|
-
*/
|
|
326
|
-
subscribe_promise(tag: string): Promise<any>;
|
|
327
|
-
/**
|
|
328
|
-
* Subscribes to channels stored in memory (local cache).
|
|
321
|
+
* Subscribes stored channels.
|
|
322
|
+
* called client state become 'ready'
|
|
329
323
|
*/
|
|
330
|
-
|
|
324
|
+
subscribe_channels(): void;
|
|
331
325
|
/**
|
|
332
326
|
* Unsubscribes from a channel or channels.
|
|
333
327
|
* @param {string} [tag=""] - The tag(s) of the channel(s) to unsubscribe from (comma-separated). If empty, unsubscribes from all.
|
package/package.json
CHANGED
package/src/auth/BohoAuth.js
CHANGED
|
@@ -12,7 +12,7 @@ export class BohoAuth {
|
|
|
12
12
|
throw new Error('BohoAuth must be initialized with a keyProvider.');
|
|
13
13
|
}
|
|
14
14
|
this.keyProvider = keyProvider;
|
|
15
|
-
|
|
15
|
+
this.keepOldConnection = true;
|
|
16
16
|
this.authLogger;
|
|
17
17
|
if (serverOption.fileLogger.auth.use) {
|
|
18
18
|
this.authLogger = new FileLogger(serverOption.fileLogger.auth.path)
|
|
@@ -27,42 +27,40 @@ export class BohoAuth {
|
|
|
27
27
|
}
|
|
28
28
|
// console.log('##### AUTH_FAIL reason: ', reason)
|
|
29
29
|
peer.setState(STATE.AUTH_FAIL)
|
|
30
|
-
peer.send(Buffer.from([Boho.BohoMsg.AUTH_FAIL]))
|
|
31
30
|
// add some delay time.
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
setTimeout(e => {
|
|
32
|
+
peer.send(Buffer.from([Boho.BohoMsg.AUTH_FAIL]))
|
|
33
|
+
}, serverOption.auth.delay_auth_fail)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
|
|
36
37
|
async verify_auth_hmac(auth_hmac, peer) {
|
|
37
38
|
try {
|
|
38
39
|
//1. unpack
|
|
39
40
|
let infoPack = MBP.unpack(auth_hmac, Boho.Meta.AUTH_HMAC)
|
|
40
|
-
|
|
41
41
|
if (!infoPack) {
|
|
42
42
|
this.send_auth_fail(peer, 'unpack auth_pack fail');
|
|
43
43
|
return
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
let id = ""
|
|
47
47
|
if (infoPack.id8.includes(0)) {
|
|
48
48
|
id = decoder.decode(infoPack.id8.subarray(0, infoPack.id8.indexOf(0)));
|
|
49
49
|
} else {
|
|
50
50
|
id = decoder.decode(infoPack.id8);
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
//2. get key of id from DB
|
|
54
54
|
let authInfo = await this.keyProvider.getAuth(id)
|
|
55
|
-
|
|
56
55
|
if (!authInfo) {
|
|
57
56
|
this.send_auth_fail(peer, 'NO ID:' + id);
|
|
58
57
|
return
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
if (serverOption.debug.showAuthInfo) {
|
|
62
|
-
console.log('[debug]showAuthInfo',authInfo
|
|
61
|
+
console.log('[debug]showAuthInfo', authInfo)
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
// console.log('db authInfo.key: ', authInfo.key)
|
|
66
64
|
peer.boho.copy_id8(infoPack.id8)
|
|
67
65
|
// type of key
|
|
68
66
|
let authKey;
|
|
@@ -77,46 +75,43 @@ export class BohoAuth {
|
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
//3. check hmac
|
|
80
|
-
// console.log('-- found: authKey of id: ', id, authKey.toString('hex'))
|
|
81
78
|
let auth_ack = peer.boho.check_auth_hmac(infoPack)
|
|
82
|
-
|
|
83
|
-
// console.log('auth_ack', auth_ack )
|
|
84
79
|
if (!auth_ack) {
|
|
85
80
|
this.send_auth_fail(peer, 'hmac dismatched');
|
|
86
81
|
return
|
|
87
82
|
}
|
|
88
83
|
|
|
89
84
|
//4. get info
|
|
90
|
-
// console.log('#### auth success' )
|
|
91
85
|
|
|
92
86
|
//5. check duplicate login.
|
|
93
|
-
// current policy. Deny duplicate login
|
|
94
|
-
|
|
95
|
-
// duplicate login policy.
|
|
96
|
-
// 1. send clear_auth signal to the old connection.
|
|
97
|
-
// 2. close old connection.
|
|
98
|
-
// 3. close new connection. retry from begining.
|
|
99
87
|
if (peer.manager.cid2remote.has(authInfo.cid)) {
|
|
100
88
|
let old = peer.manager.cid2remote.get(authInfo.cid)
|
|
89
|
+
console.log('[WARN]DUPLICATE_LOGIN detected.', old.cid)
|
|
90
|
+
old.ping(); // check the connection.
|
|
101
91
|
if (old == peer) {
|
|
102
|
-
console.log('## trying RELOGIN
|
|
92
|
+
console.log('## trying to RELOGIN after login.')
|
|
103
93
|
return
|
|
104
94
|
}
|
|
105
|
-
|
|
106
|
-
let
|
|
95
|
+
|
|
96
|
+
let authClearSignal = MBP.pack(
|
|
107
97
|
MBP.MB('#MsgType', '8', IOMsg.AUTH_CLEAR),
|
|
108
98
|
MBP.MB('#reason', 'duplicate login.')
|
|
109
99
|
)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
if (this.keepOldConnection) { // default true
|
|
101
|
+
// keep old connection. reject new connection by sending auth_fail signal.
|
|
102
|
+
this.send_auth_fail(peer, 'duplicate login')
|
|
103
|
+
// peer.send(authClearSignal)
|
|
104
|
+
} else {
|
|
105
|
+
// accept new connection. stop the old connection by sending auth_clear signal.
|
|
106
|
+
old.send(authClearSignal)
|
|
107
|
+
peer.close()
|
|
108
|
+
}
|
|
113
109
|
return
|
|
114
110
|
}
|
|
115
111
|
|
|
116
|
-
|
|
117
|
-
//6. delete current (temp rand)cid if exist.
|
|
112
|
+
//6. delete current (or anonymouse)cid if exist.
|
|
118
113
|
if (peer.cid) {
|
|
119
|
-
console.log('
|
|
114
|
+
// console.log('if peer has cid', peer.cid)
|
|
120
115
|
peer.manager.cid2remote.delete(peer.cid)
|
|
121
116
|
}
|
|
122
117
|
|
|
@@ -124,7 +119,7 @@ export class BohoAuth {
|
|
|
124
119
|
peer.did = id
|
|
125
120
|
peer.cid = authInfo.cid
|
|
126
121
|
peer.nick = authInfo.cid // temporary: nick as cid
|
|
127
|
-
if(
|
|
122
|
+
if (authInfo.uid) peer.uid = authInfo.uid
|
|
128
123
|
|
|
129
124
|
//8. setting quota level.
|
|
130
125
|
let quotaLevel = serverOption.defaultQuotaIndex;
|
|
@@ -133,7 +128,6 @@ export class BohoAuth {
|
|
|
133
128
|
let newQuota = quotaTable[quotaLevel];
|
|
134
129
|
if (!newQuota) {
|
|
135
130
|
let err = 'no index quotaTable for auth.level: ' + quotaLevel
|
|
136
|
-
console.log('##AUTH:DATA ERROR##', err)
|
|
137
131
|
this.send_auth_fail(peer, err);
|
|
138
132
|
return
|
|
139
133
|
} else {
|
|
@@ -145,14 +139,11 @@ export class BohoAuth {
|
|
|
145
139
|
console.log('## LOGIN ADMIN CID:', peer.cid)
|
|
146
140
|
peer.isAdmin = true;
|
|
147
141
|
}
|
|
148
|
-
// console.log('auth: peer.quota', peer.quota )
|
|
149
142
|
// send quota.level
|
|
150
143
|
peer.send(Buffer.from([IOMsg.QUOTA_LEVEL, quotaLevel]))
|
|
151
144
|
|
|
152
145
|
//9. set cid2remote
|
|
153
146
|
peer.manager.cid2remote.set(peer.cid, peer)
|
|
154
|
-
// console.log( 'done: cid2remote:', peer.manager.cid2remote.keys() )
|
|
155
|
-
// console.log("LOGIN: ", `id: ${ peer.did}(${peer.cid})` )
|
|
156
147
|
//10. send ack.
|
|
157
148
|
peer.send(auth_ack)
|
|
158
149
|
peer.setState(STATE.AUTH_ACK)
|
|
@@ -163,9 +154,9 @@ export class BohoAuth {
|
|
|
163
154
|
}
|
|
164
155
|
return authInfo
|
|
165
156
|
} catch (error) {
|
|
157
|
+
console.log('verify_auth_hmac error', error)
|
|
166
158
|
this.send_auth_fail(peer, '[BohoAuth]caught: unknown error:' + error);
|
|
167
159
|
}
|
|
168
|
-
|
|
169
160
|
}
|
|
170
161
|
|
|
171
162
|
async getAuth(id) {
|