iosignal 4.0.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -1
- package/README.md +0 -2
- package/dist/io.d.ts +18 -11
- package/dist/io.js +5 -5
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +5 -5
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +291 -251
- package/dist/types/client/IOCore.d.ts +15 -12
- package/dist/types/client/browser/IOWebSocket.d.ts +4 -0
- package/dist/types/common/constants.d.ts +29 -37
- package/index.js +4 -3
- package/package.json +1 -1
- package/src/auth/BohoAuth.js +48 -11
- package/src/auth/{Auth_File.js → key_providers/FileKeyProvider.js} +8 -20
- package/src/auth/{Auth_Redis.js → key_providers/RedisKeyProvider.js} +4 -7
- package/src/auth/key_providers/StringKeyProvider.js +54 -0
- package/src/client/IOCongSocket.js +4 -4
- package/src/client/IOCore.js +71 -70
- package/src/client/IOWS.js +6 -5
- package/src/client/browser/IOWebSocket.js +4 -4
- package/src/common/constants.js +32 -43
- package/src/common/util.js +3 -0
- package/src/server/Manager.js +4 -4
- package/src/server/Remote.js +4 -1
- package/src/server/RemoteCore.js +28 -19
- package/src/server/Server.js +7 -7
- package/README.en.md +0 -56
- package/auth_file_sample.js +0 -23
- package/auth_file_sample.json +0 -13
- package/src/auth/Auth_Env.js +0 -76
package/src/server/RemoteCore.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import MBP from 'meta-buffer-pack'
|
|
2
2
|
import Boho from 'boho'
|
|
3
3
|
import { serverOption } from './serverOption.js';
|
|
4
|
-
import { IOMsg, ENC_MODE,
|
|
4
|
+
import { IOMsg, ENC_MODE, STATE } from '../common/constants.js'
|
|
5
5
|
import { quotaTable } from '../common/quotaTable.js'
|
|
6
6
|
|
|
7
7
|
const decoder = new TextDecoder()
|
|
@@ -40,7 +40,7 @@ export class RemoteCore {
|
|
|
40
40
|
|
|
41
41
|
this.state;
|
|
42
42
|
this.stateLog = [];
|
|
43
|
-
this.setState(
|
|
43
|
+
this.setState(STATE.OPEN)
|
|
44
44
|
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -49,9 +49,12 @@ export class RemoteCore {
|
|
|
49
49
|
setState(state) {
|
|
50
50
|
this.state = state
|
|
51
51
|
if (serverOption.debug.showAuthInfo) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
this.stateLog.push( state + ":" + STATE[ state] )
|
|
53
|
+
if( state == STATE.AUTH_ACK){
|
|
54
|
+
console.log('[auth success]', this.cid, this.stateLog.join('>'))
|
|
55
|
+
}else if( state == STATE.AUTH_FAIL){
|
|
56
|
+
console.log('[auth_fail]',this.stateLog.join('>'))
|
|
57
|
+
}
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -60,24 +63,30 @@ export class RemoteCore {
|
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
getStateName() { // <String>
|
|
63
|
-
return (
|
|
66
|
+
return (STATE[this.state]).toLowerCase()
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
|
|
67
70
|
showMessageLog(message, isBinary) {
|
|
68
|
-
let
|
|
71
|
+
let h = '->S '
|
|
72
|
+
let from = this.boho.isAuthorized ? ` did: ${this.did} cid: ${this.cid}` : ` cid: ${this.cid}`
|
|
73
|
+
let prnLimit = 20
|
|
69
74
|
if (isBinary) {
|
|
70
75
|
let msgTypeName = IOMsg[message[0]]
|
|
71
76
|
if (!msgTypeName) msgTypeName = Boho.BohoMsg[message[0]]
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
|
|
78
|
+
msgTypeName = '[' + msgTypeName + ']';
|
|
79
|
+
let size = message.byteLength;
|
|
80
|
+
if (size < prnLimit) {
|
|
81
|
+
console.log( h + msgTypeName + from +` [${size}]`, message);
|
|
75
82
|
} else {
|
|
76
|
-
|
|
83
|
+
let elseLen = size - prnLimit
|
|
84
|
+
let some = message.subarray(0,prnLimit)
|
|
85
|
+
console.log( h + msgTypeName + from +` [${size}]` , some , ' ... else: ', elseLen);
|
|
77
86
|
}
|
|
78
87
|
|
|
79
88
|
} else {
|
|
80
|
-
console.log(
|
|
89
|
+
console.log( h + ' [TEXT] %s' + from, message);
|
|
81
90
|
}
|
|
82
91
|
}
|
|
83
92
|
|
|
@@ -162,7 +171,7 @@ export class RemoteCore {
|
|
|
162
171
|
break;
|
|
163
172
|
|
|
164
173
|
case IOMsg.CID_REQ:
|
|
165
|
-
if (this.state <
|
|
174
|
+
if (this.state < STATE.SERVER_READY) {
|
|
166
175
|
// Protocol violation: CID_REQ was sent before receiving the SERVER_READY signal.
|
|
167
176
|
console.log('CID_REQ before SERVER_READY')
|
|
168
177
|
this.close()
|
|
@@ -179,7 +188,7 @@ export class RemoteCore {
|
|
|
179
188
|
MB('#cid', this.cid)
|
|
180
189
|
))
|
|
181
190
|
|
|
182
|
-
this.setState(
|
|
191
|
+
this.setState(STATE.CID_RES)
|
|
183
192
|
break;
|
|
184
193
|
|
|
185
194
|
case IOMsg.ECHO:
|
|
@@ -285,24 +294,24 @@ export class RemoteCore {
|
|
|
285
294
|
// Auth
|
|
286
295
|
case Boho.BohoMsg.AUTH_REQ:
|
|
287
296
|
if (!this.manager.authManager) return
|
|
288
|
-
if (this.state <
|
|
297
|
+
if (this.state < STATE.SERVER_READY) {
|
|
289
298
|
console.log('protocol error. auth_req before server_ready')
|
|
290
299
|
this.close();
|
|
291
300
|
}
|
|
292
|
-
this.setState(
|
|
301
|
+
this.setState(STATE.AUTH_REQ)
|
|
293
302
|
let auth_nonce_pack = this.boho.auth_nonce()
|
|
294
303
|
// console.log('## auth_nonce_pack', auth_nonce_pack )
|
|
295
304
|
this.send(auth_nonce_pack)
|
|
296
|
-
this.setState(
|
|
305
|
+
this.setState(STATE.AUTH_NONCE)
|
|
297
306
|
break;
|
|
298
307
|
|
|
299
308
|
case Boho.BohoMsg.AUTH_HMAC:
|
|
300
309
|
if (!this.manager.authManager) return
|
|
301
|
-
if (this.state <
|
|
310
|
+
if (this.state < STATE.AUTH_NONCE) {
|
|
302
311
|
console.log('protocol error. auth_hmac before server_nonce')
|
|
303
312
|
this.close();
|
|
304
313
|
}
|
|
305
|
-
this.setState(
|
|
314
|
+
this.setState(STATE.AUTH_HMAC)
|
|
306
315
|
//async
|
|
307
316
|
this.manager.authManager.verify_auth_hmac(message, this)
|
|
308
317
|
.then(authInfo => {
|
package/src/server/Server.js
CHANGED
|
@@ -81,7 +81,7 @@ export class Server extends EventEmitter {
|
|
|
81
81
|
|
|
82
82
|
this.wss.once('listening', () => {
|
|
83
83
|
this.port = this.wss.address().port;
|
|
84
|
-
console.log('wss server bound port:', this.port );
|
|
84
|
+
// console.log('wss server bound port:', this.port );
|
|
85
85
|
this.listeningServerCount++;
|
|
86
86
|
if (this.listeningServerCount === this.serverCountToListen) {
|
|
87
87
|
this.emit('ready');
|
|
@@ -97,7 +97,7 @@ export class Server extends EventEmitter {
|
|
|
97
97
|
})
|
|
98
98
|
|
|
99
99
|
this.wss.on('close', () => {
|
|
100
|
-
console.log('### WS server is closed.')
|
|
100
|
+
// console.log('### WS server is closed.')
|
|
101
101
|
})
|
|
102
102
|
|
|
103
103
|
this.wss.on('connection', (ws, req) => {
|
|
@@ -118,10 +118,10 @@ export class Server extends EventEmitter {
|
|
|
118
118
|
process.exit()
|
|
119
119
|
}
|
|
120
120
|
}).on('close', () => {
|
|
121
|
-
console.log('### congsocket server is closed.')
|
|
121
|
+
// console.log('### congsocket server is closed.')
|
|
122
122
|
}).listen(this.congPort, () => {
|
|
123
123
|
this.congPort = this.congServer.address().port;
|
|
124
|
-
console.log('congsocket server bound port:', this.congPort );
|
|
124
|
+
// console.log('congsocket server bound port:', this.congPort );
|
|
125
125
|
this.listeningServerCount++;
|
|
126
126
|
if (this.listeningServerCount === this.serverCountToListen) {
|
|
127
127
|
this.emit('ready');
|
|
@@ -156,7 +156,7 @@ export class Server extends EventEmitter {
|
|
|
156
156
|
return
|
|
157
157
|
}
|
|
158
158
|
if( api.commands.includes( req.topic )){
|
|
159
|
-
console.log('server api req', req )
|
|
159
|
+
// console.log('server api req', req )
|
|
160
160
|
await api.request(remote, req)
|
|
161
161
|
}else{
|
|
162
162
|
remote.response(req.mid, STATUS.ERROR, "UNKNOWN_COMMAND");
|
|
@@ -186,7 +186,7 @@ export class Server extends EventEmitter {
|
|
|
186
186
|
})
|
|
187
187
|
}
|
|
188
188
|
this.apiNames.add(target)
|
|
189
|
-
console.log(`[API registed: ${target} ] accept commands: ${api.commands}`)
|
|
189
|
+
// console.log(`[API registed: ${target} ] accept commands: ${api.commands}`)
|
|
190
190
|
return this
|
|
191
191
|
}
|
|
192
192
|
|
|
@@ -226,7 +226,7 @@ export class Server extends EventEmitter {
|
|
|
226
226
|
|
|
227
227
|
if (this.congServer) {
|
|
228
228
|
this.congServer.close((err) => {
|
|
229
|
-
if (err) console.error('congServer close error', err)
|
|
229
|
+
// if (err) console.error('congServer close error', err)
|
|
230
230
|
// console.log('cong server closed.')
|
|
231
231
|
onClosed()
|
|
232
232
|
})
|
package/README.en.md
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
[ English | [한국어](./README.md) ]
|
|
2
|
-
|
|
3
|
-
# IOSignal
|
|
4
|
-
|
|
5
|
-
IOSignal enables real-time communication across web browsers, Node.js, and Arduino. It features built-in secure authentication, encrypted communication, and a pre-configured signaling protocol, allowing server deployment without complex programming.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Features
|
|
9
|
-
|
|
10
|
-
### Built-in Message Trasport Protocol
|
|
11
|
-
- pub/sub multicast by channel name.
|
|
12
|
-
- uni-cast: one to one messaging by CID.
|
|
13
|
-
- `CID` is a Communication Id
|
|
14
|
-
- CID subscribing: subscribe one peer using CID.
|
|
15
|
-
- HomeChannel: group by IP address.
|
|
16
|
-
|
|
17
|
-
### Built-in Security
|
|
18
|
-
- Authentication
|
|
19
|
-
- Encryption
|
|
20
|
-
- E2EE
|
|
21
|
-
- thanks to the `Boho` [ [github](https://github.com/remocons/boho) ]
|
|
22
|
-
|
|
23
|
-
## Connection
|
|
24
|
-
- Web browser use WebSocket.
|
|
25
|
-
- Node.js use WebSocket or CongSocket.
|
|
26
|
-
- Arduino use CongSocket.
|
|
27
|
-
|
|
28
|
-
## IOSignal Server Architecture
|
|
29
|
-

|
|
30
|
-
|
|
31
|
-
## IOSignal repositories.
|
|
32
|
-
|
|
33
|
-
- Javascript: `iosignal` [ [github](https://github.com/remocons/iosignal) | [npm](https://www.npmjs.com/package/iosignal) ]
|
|
34
|
-
- Node.js server ( WebSocket, CongSocket)
|
|
35
|
-
- Node.js client ( WebSocket, CongSocket)
|
|
36
|
-
- Web Browser client( WebSocket)
|
|
37
|
-
|
|
38
|
-
- CLI program
|
|
39
|
-
- `iosignal-cli` [ [github](https://github.com/remocons/iosignal-cli) | [npm](https://www.npmjs.com/package/iosignal-cli) ]
|
|
40
|
-
- install: `npm i -g iosignal-cli` or `sudo npm i -g iosignal-cli`
|
|
41
|
-
- support mac, linux and windows.
|
|
42
|
-
- server and client
|
|
43
|
-
|
|
44
|
-
- Arduino iosignal library and examples:
|
|
45
|
-
- use Arduino Library Manager: `iosignal`
|
|
46
|
-
- or `iosignal-arduino` [ [github](https://github.com/remocons/iosignal-arduino) ]
|
|
47
|
-
- web app : http://test.iosignal.net
|
|
48
|
-
|
|
49
|
-
- Arduino remocon library and examples:
|
|
50
|
-
- use Arduino Library Manager: `remocon`
|
|
51
|
-
- or `remocon-arduino` [ [github](https://github.com/remocons/remocon-arduino) ]
|
|
52
|
-
- web app : https://remocon.kr
|
|
53
|
-
|
|
54
|
-
## License
|
|
55
|
-
|
|
56
|
-
This code is released under the MIT License.
|
package/auth_file_sample.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/*
|
|
3
|
-
Authentication data sample.
|
|
4
|
-
|
|
5
|
-
device props: ["did", "key", "cid", level ]
|
|
6
|
-
|
|
7
|
-
did: ( device id ) authentication id. maximum 8 chars.
|
|
8
|
-
key: ( device key ) authentication key. no size limit.
|
|
9
|
-
cid: ( communication id ) signal target id. maximum 12 chars.
|
|
10
|
-
level:( quota level) <Number> ref. /server/quotaTable.js
|
|
11
|
-
|
|
12
|
-
*/
|
|
13
|
-
export const authInfo = [
|
|
14
|
-
["did","passowrd","cid",0],
|
|
15
|
-
["device1","device1_key","device1_cid",0],
|
|
16
|
-
["device2","device2_key","device2_cid",0],
|
|
17
|
-
["uno","uno-key","uno",1],
|
|
18
|
-
["go","go-key","go",2],
|
|
19
|
-
["bro","bro-key","bro",3],
|
|
20
|
-
["admin","admin-key","admin",255],
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
|
package/auth_file_sample.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
["sampleid","samplekey","sample_cid",0],
|
|
3
|
-
["id_max8","no_key_size_limit","communication_id",0],
|
|
4
|
-
["device1","device1_key","device1_cid",0],
|
|
5
|
-
["device2","device2_key","device2_cid",0],
|
|
6
|
-
["uno","uno","uno",1],
|
|
7
|
-
["go","go","go",2],
|
|
8
|
-
["bro","bro","bro",3],
|
|
9
|
-
["admin","admin","admin",255],
|
|
10
|
-
["adminb","adminb","adminb",255]
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
|
package/src/auth/Auth_Env.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auth_Env.js
|
|
3
|
-
*
|
|
4
|
-
* You can use environment variable BOHO_AUTH.
|
|
5
|
-
*
|
|
6
|
-
* BOHO_AUTH=id1.key1.level,id2:key2.level
|
|
7
|
-
*
|
|
8
|
-
* or constructor parameter.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* [ authInfo ]
|
|
12
|
-
* id: <String> max 8chars
|
|
13
|
-
* key: <String>
|
|
14
|
-
* level: <Numbrer> range: 0~255
|
|
15
|
-
* separator: ','
|
|
16
|
-
*
|
|
17
|
-
* example => process.env.BOHO_AUTH=id1.key1.255,id2.key2.200
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { BohoAuth } from './BohoAuth.js';
|
|
21
|
-
import Boho from 'boho'
|
|
22
|
-
|
|
23
|
-
export class Auth_Env extends BohoAuth {
|
|
24
|
-
constructor(authInfo) {
|
|
25
|
-
super()
|
|
26
|
-
let id_keys;
|
|
27
|
-
if (authInfo) {
|
|
28
|
-
id_keys = authInfo.split(',')
|
|
29
|
-
} else if (process.env.BOHO_AUTH) {
|
|
30
|
-
authInfo = process.env.BOHO_AUTH
|
|
31
|
-
id_keys = process.env.BOHO_AUTH.split(',')
|
|
32
|
-
} else {
|
|
33
|
-
console.log("Auth_Env: None of process.env.BOHO_AUTH or authInfo")
|
|
34
|
-
process.exit()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
this.AUTH = new Map();
|
|
38
|
-
|
|
39
|
-
if (id_keys.length >= 1) {
|
|
40
|
-
id_keys.forEach(v => {
|
|
41
|
-
|
|
42
|
-
let did = v.split('.')[0]
|
|
43
|
-
let key = v.split('.')[1]
|
|
44
|
-
let level = v.split('.')[2]
|
|
45
|
-
level = parseInt(level)
|
|
46
|
-
|
|
47
|
-
if (did && key && typeof level == 'number') {
|
|
48
|
-
let cid = did;
|
|
49
|
-
this.addAuth(did, key, cid, level)
|
|
50
|
-
} else {
|
|
51
|
-
console.log("Wrong process.env.BOHO_AUTH authentication value.", id, key, level)
|
|
52
|
-
process.exit();
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
} else {
|
|
57
|
-
console.log("Wrong process.env.BOHO_AUTH authentication value.")
|
|
58
|
-
process.exit();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async getAuth(id) {
|
|
64
|
-
return this.AUTH.get(id)
|
|
65
|
-
}
|
|
66
|
-
async getAuthIdList() {
|
|
67
|
-
return Array.from(this.AUTH.keys())
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
addAuth(id, keyStr, cid, level = 0) {
|
|
71
|
-
let Base64hashKey = Buffer.from(Boho.sha256.hash(keyStr)).toString('base64')
|
|
72
|
-
this.AUTH.set(id, { key: Base64hashKey, cid: cid, level: level })
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|