iosignal 5.2.0 → 5.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/README.md +163 -0
- package/dist/browser/esm/io.d.ts +8 -9
- package/dist/browser/esm/io.js +5 -5
- package/dist/browser/esm/io.js.map +1 -1
- package/dist/browser/iife/io.js +5 -5
- package/dist/browser/iife/io.js.map +1 -1
- package/dist/node/iosignal.cjs +124 -119
- package/dist/node/iosignal.js +123 -118
- package/dist/types/client/IOCore.d.ts +2 -2
- package/dist/types/client/browser/IOWebSocket.d.ts +4 -4
- package/dist/types/common/payload.d.ts +2 -2
- package/package.json +21 -3
- package/.vscode/settings.json +0 -3
- package/index.js +0 -26
- package/rollup.config.js +0 -59
- package/src/auth/BohoAuth.js +0 -196
- package/src/auth/key_providers/FileKeyProvider.js +0 -59
- package/src/auth/key_providers/RedisKeyProvider.js +0 -46
- package/src/auth/key_providers/StringKeyProvider.js +0 -54
- package/src/client/CongPacket.js +0 -143
- package/src/client/IOCongSocket.js +0 -92
- package/src/client/IOCore.js +0 -1202
- package/src/client/IOWS.js +0 -78
- package/src/client/browser/IOWebSocket.js +0 -202
- package/src/common/constants.js +0 -210
- package/src/common/payload.js +0 -82
- package/src/common/quotaTable.js +0 -68
- package/src/common/util.js +0 -64
- package/src/server/FileLogger.js +0 -30
- package/src/server/Manager.js +0 -450
- package/src/server/Metrics.js +0 -155
- package/src/server/Remote.js +0 -216
- package/src/server/RemoteCore.js +0 -427
- package/src/server/Server.js +0 -236
- package/src/server/serverOption.js +0 -56
- package/src/services/RedisService.js +0 -53
- package/src/services/constant.js +0 -7
- package/src/services/replyService.js +0 -39
- package/src/services/sudoService.js +0 -85
- package/tsconfig.json +0 -25
|
@@ -77,7 +77,7 @@ export class IOCore {
|
|
|
77
77
|
* @type {Boho}
|
|
78
78
|
*/
|
|
79
79
|
boho: Boho;
|
|
80
|
-
serverTimeNonce:
|
|
80
|
+
serverTimeNonce: import("buffer").Buffer;
|
|
81
81
|
/**
|
|
82
82
|
* Indicates if the connection is TLS (wss).
|
|
83
83
|
* @type {boolean}
|
|
@@ -408,5 +408,5 @@ export type SIZE_LIMIT = import("../common/constants.js").SIZE_LIMIT;
|
|
|
408
408
|
export type ENC_MODE = import("../common/constants.js").ENC_MODE;
|
|
409
409
|
export type STATE = import("../common/constants.js").STATE;
|
|
410
410
|
export type quotaTable = any;
|
|
411
|
-
export type Boho = import("boho").Boho;
|
|
412
411
|
export type Buffer = import("boho").Buffer;
|
|
412
|
+
import Boho from "boho";
|
|
@@ -15,9 +15,9 @@ export default class IO extends IOCore {
|
|
|
15
15
|
static binaryType: string;
|
|
16
16
|
/**
|
|
17
17
|
* The Boho library instance.
|
|
18
|
-
* @type {Boho}
|
|
18
|
+
* @type {typeof Boho}
|
|
19
19
|
*/
|
|
20
|
-
static Boho: Boho;
|
|
20
|
+
static Boho: typeof Boho;
|
|
21
21
|
/**
|
|
22
22
|
* The MBP (MessagePack-Boho) instance.
|
|
23
23
|
* @type {MBP}
|
|
@@ -73,7 +73,7 @@ export default class IO extends IOCore {
|
|
|
73
73
|
*/
|
|
74
74
|
socket_send(data: BufferSource): void;
|
|
75
75
|
}
|
|
76
|
-
export type
|
|
77
|
-
export type MBP = typeof import("meta-buffer-pack");
|
|
76
|
+
export type MBP = import("boho").MBP;
|
|
78
77
|
export type Buffer = import("boho").Buffer;
|
|
79
78
|
import { IOCore } from "../IOCore.js";
|
|
79
|
+
import Boho from 'boho';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export function getSignalPack(tag: any, ...args: any[]): Buffer
|
|
1
|
+
export function getSignalPack(tag: any, ...args: any[]): import("buffer").Buffer;
|
|
2
2
|
export function parsePayload(args: any): {
|
|
3
3
|
type: number;
|
|
4
|
-
buffer: Uint8Array<ArrayBuffer> | Buffer
|
|
4
|
+
buffer: Uint8Array<ArrayBuffer> | import("buffer").Buffer | null | undefined;
|
|
5
5
|
};
|
|
6
6
|
export function getPayloadFromSignalPack(signalPack: any): any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iosignal",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "iosignal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -17,7 +17,11 @@
|
|
|
17
17
|
"unpkg": "./dist/browser/iife/io.js",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "rollup -c && npm run build:types",
|
|
20
|
-
"build:types": "tsc --project tsconfig.json"
|
|
20
|
+
"build:types": "tsc --project tsconfig.json",
|
|
21
|
+
"test": "node --test --test-timeout=15000 checks/*.test.mjs test/integration/*.test.mjs",
|
|
22
|
+
"verify": "node scripts/verify.mjs",
|
|
23
|
+
"prepack": "npm run verify",
|
|
24
|
+
"test:integration": "node --test --test-timeout=15000 test/integration/*.test.mjs"
|
|
21
25
|
},
|
|
22
26
|
"author": {
|
|
23
27
|
"name": "Taeo Lee",
|
|
@@ -36,7 +40,7 @@
|
|
|
36
40
|
"typescript": "^6.0.3"
|
|
37
41
|
},
|
|
38
42
|
"dependencies": {
|
|
39
|
-
"boho": "^2.
|
|
43
|
+
"boho": "^2.2.0",
|
|
40
44
|
"eventemitter3": "^5.0.4",
|
|
41
45
|
"meta-buffer-pack": "^2.1.3",
|
|
42
46
|
"ws": "^8.21.3"
|
|
@@ -63,5 +67,19 @@
|
|
|
63
67
|
"iot",
|
|
64
68
|
"arduino",
|
|
65
69
|
"auth"
|
|
70
|
+
],
|
|
71
|
+
"files": [
|
|
72
|
+
"dist/browser/esm/io.d.ts",
|
|
73
|
+
"dist/browser/esm/io.js",
|
|
74
|
+
"dist/browser/esm/io.js.map",
|
|
75
|
+
"dist/browser/iife/io.js",
|
|
76
|
+
"dist/browser/iife/io.js.map",
|
|
77
|
+
"dist/node/iosignal.cjs",
|
|
78
|
+
"dist/node/iosignal.js",
|
|
79
|
+
"dist/types/client/IOCore.d.ts",
|
|
80
|
+
"dist/types/client/browser/IOWebSocket.d.ts",
|
|
81
|
+
"dist/types/common/constants.d.ts",
|
|
82
|
+
"dist/types/common/payload.d.ts",
|
|
83
|
+
"dist/types/common/quotaTable.d.ts"
|
|
66
84
|
]
|
|
67
85
|
}
|
package/.vscode/settings.json
DELETED
package/index.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import pkg from './package.json' with { type: 'json' };
|
|
2
|
-
export const version = pkg.version;
|
|
3
|
-
export { IOCongSocket } from './src/client/IOCongSocket.js'
|
|
4
|
-
export { IOWS as IO } from './src/client/IOWS.js'
|
|
5
|
-
export { pack, CongRx } from './src/client/CongPacket.js'
|
|
6
|
-
export { Server } from './src/server/Server.js'
|
|
7
|
-
export { serverOption } from './src/server/serverOption.js'
|
|
8
|
-
export { FileLogger } from './src/server/FileLogger.js'
|
|
9
|
-
export { getSignalPack, parsePayload, getPayloadFromSignalPack } from './src/common/payload.js'
|
|
10
|
-
export * from './src/common/constants.js'
|
|
11
|
-
export * from './src/common/util.js'
|
|
12
|
-
|
|
13
|
-
// MBP
|
|
14
|
-
export { default as MBP } from 'meta-buffer-pack'
|
|
15
|
-
|
|
16
|
-
// boho auth
|
|
17
|
-
export { default as Boho} from 'boho'
|
|
18
|
-
export { BohoAuth } from './src/auth/BohoAuth.js'
|
|
19
|
-
export { FileKeyProvider } from './src/auth/key_providers/FileKeyProvider.js'
|
|
20
|
-
export { RedisKeyProvider } from './src/auth/key_providers/RedisKeyProvider.js'
|
|
21
|
-
export { StringKeyProvider } from './src/auth/key_providers/StringKeyProvider.js'
|
|
22
|
-
|
|
23
|
-
// services
|
|
24
|
-
export * as replyService from './src/services/replyService.js'
|
|
25
|
-
export * as sudoService from './src/services/sudoService.js'
|
|
26
|
-
export { RedisService } from './src/services/RedisService.js'
|
package/rollup.config.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import resolve from '@rollup/plugin-node-resolve'
|
|
2
|
-
import commonjs from '@rollup/plugin-commonjs'
|
|
3
|
-
import json from '@rollup/plugin-json'
|
|
4
|
-
import terser from '@rollup/plugin-terser'
|
|
5
|
-
import dts from 'rollup-plugin-dts'
|
|
6
|
-
|
|
7
|
-
export default [
|
|
8
|
-
{
|
|
9
|
-
input: './src/client/browser/IOWebSocket.js',
|
|
10
|
-
output: [
|
|
11
|
-
{
|
|
12
|
-
file: './dist/browser/esm/io.js',
|
|
13
|
-
format: 'es',
|
|
14
|
-
sourcemap: true,
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
file: './dist/browser/iife/io.js',
|
|
18
|
-
format: 'iife',
|
|
19
|
-
name: 'IO',
|
|
20
|
-
sourcemap: true,
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
plugins: [
|
|
24
|
-
resolve({
|
|
25
|
-
preferBuiltins: false
|
|
26
|
-
}),
|
|
27
|
-
commonjs(),
|
|
28
|
-
json(),
|
|
29
|
-
terser()
|
|
30
|
-
]
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
input: './src/client/browser/IOWebSocket.js',
|
|
34
|
-
output: { file: './dist/browser/esm/io.d.ts', format: 'es' },
|
|
35
|
-
plugins: [dts()]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
,{
|
|
39
|
-
input: './index.js',
|
|
40
|
-
output: [
|
|
41
|
-
{
|
|
42
|
-
file: './dist/node/iosignal.js',
|
|
43
|
-
format: 'es'
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
file: "./dist/node/iosignal.cjs",
|
|
47
|
-
format: 'cjs'
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
plugins: [
|
|
51
|
-
resolve({
|
|
52
|
-
preferBuiltins: true
|
|
53
|
-
}),
|
|
54
|
-
json(),
|
|
55
|
-
commonjs()
|
|
56
|
-
]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
]
|
package/src/auth/BohoAuth.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import MBP from 'meta-buffer-pack'
|
|
2
|
-
import Boho from 'boho'
|
|
3
|
-
import { quotaTable } from '../common/quotaTable.js'
|
|
4
|
-
import { serverOption } from '../server/serverOption.js'
|
|
5
|
-
import { IOMsg, STATE } from '../common/constants.js'
|
|
6
|
-
import { FileLogger } from '../server/FileLogger.js'
|
|
7
|
-
|
|
8
|
-
const decoder = new TextDecoder()
|
|
9
|
-
export class BohoAuth {
|
|
10
|
-
constructor(keyProvider) {
|
|
11
|
-
if (!keyProvider) {
|
|
12
|
-
throw new Error('BohoAuth must be initialized with a keyProvider.');
|
|
13
|
-
}
|
|
14
|
-
this.keyProvider = keyProvider;
|
|
15
|
-
this.keepOldConnection = true;
|
|
16
|
-
this.authLogger;
|
|
17
|
-
if (serverOption.fileLogger.auth.use) {
|
|
18
|
-
this.authLogger = new FileLogger(serverOption.fileLogger.auth.path)
|
|
19
|
-
console.log('Auth: begin file logger.[auth]')
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
send_auth_fail(peer, reason) {
|
|
24
|
-
if (this.authLogger) {
|
|
25
|
-
let peerInfo = `FAIL #${peer.ssid} reason:${reason} `
|
|
26
|
-
this.authLogger.log(peerInfo)
|
|
27
|
-
}
|
|
28
|
-
// console.log('##### AUTH_FAIL reason: ', reason)
|
|
29
|
-
peer.setState(STATE.AUTH_FAIL)
|
|
30
|
-
// add some delay time.
|
|
31
|
-
setTimeout(e => {
|
|
32
|
-
peer.send(Buffer.from([Boho.BohoMsg.AUTH_FAIL]))
|
|
33
|
-
}, serverOption.auth.delay_auth_fail)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
async verify_auth_req(auth_req, peer) {
|
|
38
|
-
try {
|
|
39
|
-
//1. unpack
|
|
40
|
-
let infoPack = MBP.unpack(auth_req, Boho.Meta.AUTH_REQ)
|
|
41
|
-
if (!infoPack) {
|
|
42
|
-
this.send_auth_fail(peer, 'unpack auth_pack fail');
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let id = ""
|
|
47
|
-
if (infoPack.id8.includes(0)) {
|
|
48
|
-
id = decoder.decode(infoPack.id8.subarray(0, infoPack.id8.indexOf(0)));
|
|
49
|
-
} else {
|
|
50
|
-
id = decoder.decode(infoPack.id8);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
//2. get key of id from DB
|
|
54
|
-
let authInfo = await this.keyProvider.getAuth(id)
|
|
55
|
-
if (!authInfo) {
|
|
56
|
-
this.send_auth_fail(peer, 'NO ID:' + id);
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (serverOption.debug.showAuthInfo) {
|
|
61
|
-
console.log('[debug]showAuthInfo', authInfo)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
peer.boho.copy_id8(infoPack.id8)
|
|
65
|
-
// type of key
|
|
66
|
-
let authKey;
|
|
67
|
-
const SHA256_HASH_BASE64_LEN = 44
|
|
68
|
-
if (authInfo.key.length == SHA256_HASH_BASE64_LEN) {
|
|
69
|
-
// hashed key
|
|
70
|
-
authKey = Buffer.from(authInfo.key, 'base64')
|
|
71
|
-
peer.boho.copy_key(authKey)
|
|
72
|
-
} else {
|
|
73
|
-
// plain key
|
|
74
|
-
peer.boho.set_key(authInfo.key)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
//3. check hmac
|
|
78
|
-
let auth_res = peer.boho.verify_auth_req(infoPack)
|
|
79
|
-
if (!auth_res) {
|
|
80
|
-
this.send_auth_fail(peer, 'hmac dismatched');
|
|
81
|
-
return
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
//4. get info
|
|
85
|
-
|
|
86
|
-
//5. check duplicate login.
|
|
87
|
-
if (peer.manager.cid2remote.has(authInfo.cid)) {
|
|
88
|
-
let old = peer.manager.cid2remote.get(authInfo.cid)
|
|
89
|
-
console.log('[WARN]DUPLICATE_LOGIN detected.', old.cid)
|
|
90
|
-
old.ping(); // check the connection.
|
|
91
|
-
if (old == peer) {
|
|
92
|
-
console.log('## trying to RELOGIN after login.')
|
|
93
|
-
return
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let authClearSignal = MBP.pack(
|
|
97
|
-
MBP.MB('#MsgType', '8', IOMsg.AUTH_CLEAR),
|
|
98
|
-
MBP.MB('#reason', 'duplicate login.')
|
|
99
|
-
)
|
|
100
|
-
if (this.keepOldConnection) { // default true
|
|
101
|
-
// keep old connection. reject new connection by sending auth_fail signal.
|
|
102
|
-
// peer.send(authClearSignal)
|
|
103
|
-
if( peer.socketType == 'websocket'){
|
|
104
|
-
this.send_auth_fail(peer, 'duplicate login')
|
|
105
|
-
}else{
|
|
106
|
-
peer.close(); //arduino
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
// accept new connection. stop the old connection by sending auth_clear signal.
|
|
110
|
-
old.send(authClearSignal)
|
|
111
|
-
peer.close()
|
|
112
|
-
}
|
|
113
|
-
return
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
//6. delete current (or anonymouse)cid if exist.
|
|
117
|
-
if (peer.cid) {
|
|
118
|
-
// console.log('if peer has cid', peer.cid)
|
|
119
|
-
peer.manager.cid2remote.delete(peer.cid)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
//7. setting info.
|
|
123
|
-
peer.did = id
|
|
124
|
-
peer.cid = authInfo.cid
|
|
125
|
-
peer.nick = authInfo.cid // temporary: nick as cid
|
|
126
|
-
if (authInfo.uid) peer.uid = authInfo.uid
|
|
127
|
-
|
|
128
|
-
//8. setting quota level.
|
|
129
|
-
let quotaLevel = serverOption.defaultQuotaIndex;
|
|
130
|
-
if (authInfo.level) quotaLevel = authInfo.level;
|
|
131
|
-
quotaLevel = parseInt(quotaLevel)
|
|
132
|
-
let newQuota = quotaTable[quotaLevel];
|
|
133
|
-
if (!newQuota) {
|
|
134
|
-
let err = 'no index quotaTable for auth.level: ' + quotaLevel
|
|
135
|
-
this.send_auth_fail(peer, err);
|
|
136
|
-
return
|
|
137
|
-
} else {
|
|
138
|
-
peer.level = quotaLevel;
|
|
139
|
-
peer.quota = newQuota;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (peer.level === serverOption.adminLevel) {
|
|
143
|
-
console.log('## LOGIN ADMIN CID:', peer.cid)
|
|
144
|
-
peer.isAdmin = true;
|
|
145
|
-
}
|
|
146
|
-
// send quota.level
|
|
147
|
-
peer.send(Buffer.from([IOMsg.QUOTA_LEVEL, quotaLevel]))
|
|
148
|
-
|
|
149
|
-
//9. set cid2remote
|
|
150
|
-
peer.manager.cid2remote.set(peer.cid, peer)
|
|
151
|
-
//10. send ack.
|
|
152
|
-
peer.send(auth_res)
|
|
153
|
-
peer.setState(STATE.AUTH_RES)
|
|
154
|
-
if (this.authLogger) {
|
|
155
|
-
let peerInfo = `OK #${peer.ssid} cid: ${peer.cid} did:${peer.did}`
|
|
156
|
-
if (peer.isAdmin) peerInfo = "#ADMIN# " + peerInfo
|
|
157
|
-
this.authLogger.log(peerInfo)
|
|
158
|
-
}
|
|
159
|
-
return authInfo
|
|
160
|
-
} catch (error) {
|
|
161
|
-
console.log('verify_auth_req error', error)
|
|
162
|
-
this.send_auth_fail(peer, '[BohoAuth]caught: unknown error:' + error);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async getAuth(id) {
|
|
167
|
-
return this.keyProvider.getAuth(id);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async getAuthIdList() {
|
|
171
|
-
if (typeof this.keyProvider.getAuthIdList === 'function') {
|
|
172
|
-
return this.keyProvider.getAuthIdList();
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async addAuth(id, keyStr, cid, level = 0) {
|
|
177
|
-
if (typeof this.keyProvider.addAuth === 'function') {
|
|
178
|
-
return this.keyProvider.addAuth(id, keyStr, cid, level);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async delAuth(id) {
|
|
183
|
-
if (typeof this.keyProvider.delAuth === 'function') {
|
|
184
|
-
return this.keyProvider.delAuth(id);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async save() {
|
|
189
|
-
if (typeof this.keyProvider.save === 'function') {
|
|
190
|
-
return this.keyProvider.save();
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'fs'
|
|
2
|
-
import Boho from 'boho'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
|
|
5
|
-
export class FileKeyProvider {
|
|
6
|
-
constructor(_path) {
|
|
7
|
-
this.AUTH = new Map();
|
|
8
|
-
let pathObj = path.parse(_path)
|
|
9
|
-
this.path = path.resolve(_path)
|
|
10
|
-
console.log('auth from file path:', this.path)
|
|
11
|
-
let ext = pathObj.ext;
|
|
12
|
-
if (ext.toLowerCase() == '.js') {
|
|
13
|
-
// Read auth data from file
|
|
14
|
-
console.log("#JS path:", this.path);
|
|
15
|
-
this.loadAuthInfoFile_JS(this.path)
|
|
16
|
-
} else if (ext.toLowerCase() == '.json') {
|
|
17
|
-
console.log("#JSON path:", this.path);
|
|
18
|
-
this.loadAuthInfoFile_JSON(this.path)
|
|
19
|
-
} else {
|
|
20
|
-
console.log('no authinfofile path.')
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
//loaded when server start.
|
|
25
|
-
loadAuthInfoFile_JS(path) {
|
|
26
|
-
import(path).then((file) => {
|
|
27
|
-
console.log(file.authInfo);
|
|
28
|
-
file.authInfo.forEach(item => {
|
|
29
|
-
this.addAuth(...item)
|
|
30
|
-
})
|
|
31
|
-
console.log('total AUTH INFO size: ', this.AUTH.size)
|
|
32
|
-
}).catch(e => {
|
|
33
|
-
console.log(e)
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
loadAuthInfoFile_JSON(path) {
|
|
38
|
-
let file = readFileSync(path)
|
|
39
|
-
file = new TextDecoder().decode(file)
|
|
40
|
-
let list = JSON.parse(file)
|
|
41
|
-
list.forEach(item => {
|
|
42
|
-
this.addAuth(...item)
|
|
43
|
-
})
|
|
44
|
-
console.log('total AUTH INFO size: ', this.AUTH.size)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async getAuth(id) {
|
|
48
|
-
return this.AUTH.get(id)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async getAuthIdList() {
|
|
52
|
-
return Array.from(this.AUTH.keys())
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
addAuth(id, keyStr, cid, level = 0) {
|
|
56
|
-
let Base64hashKey = Buffer.from(Boho.sha256.hash(keyStr)).toString('base64')
|
|
57
|
-
this.AUTH.set(id, { key: Base64hashKey, cid: cid, level: level })
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import Boho from 'boho'
|
|
2
|
-
const DEVICE_PREFIX = "device:"
|
|
3
|
-
|
|
4
|
-
export class RedisKeyProvider {
|
|
5
|
-
constructor(redisClient) {
|
|
6
|
-
if (!redisClient) {
|
|
7
|
-
throw new Error("RedisKeyProvider constructor: no redisClient")
|
|
8
|
-
}
|
|
9
|
-
this.redis = redisClient
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// get device key from DB. (for Boho auth.)
|
|
13
|
-
async getAuth(id) {
|
|
14
|
-
try {
|
|
15
|
-
let result = await this.redis.hGetAll(DEVICE_PREFIX + id)
|
|
16
|
-
if (result && result.key) return result
|
|
17
|
-
else return null;
|
|
18
|
-
} catch (error) {
|
|
19
|
-
console.log('getAuth', error)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
//sudoService call
|
|
24
|
-
async getAuthIdList() {
|
|
25
|
-
let result = await this.redis.keys(DEVICE_PREFIX + '*')
|
|
26
|
-
result = result.map(v => {
|
|
27
|
-
return v.split(':')[1]
|
|
28
|
-
})
|
|
29
|
-
if (result) return result
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// add device auth info
|
|
33
|
-
async addAuth(id, keyStr, cid = '', level = 0) {
|
|
34
|
-
let Base64hashKey = Buffer.from(Boho.sha256.hash(keyStr)).toString('base64')
|
|
35
|
-
return this.redis.hSet(DEVICE_PREFIX + id, { 'key': Base64hashKey, 'cid': cid, 'level': level })
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
//sudoService call
|
|
39
|
-
async delAuth(id) {
|
|
40
|
-
return this.redis.del(DEVICE_PREFIX + id)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async save(id) {
|
|
44
|
-
return this.redis.save()
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StringKeyProvider.js
|
|
3
|
-
*
|
|
4
|
-
* authInfo <String>
|
|
5
|
-
* id: max 8chars
|
|
6
|
-
* key: ~44 base64 chars recomended
|
|
7
|
-
* cid:
|
|
8
|
-
* level: range: 0~255
|
|
9
|
-
* separator: ',' for multiple devices.
|
|
10
|
-
*
|
|
11
|
-
* example => authInfo = 'id1.key1.cid1.255,id2.key2.cid2.200'
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import Boho from 'boho'
|
|
15
|
-
|
|
16
|
-
export class StringKeyProvider {
|
|
17
|
-
constructor(authInfo) {
|
|
18
|
-
|
|
19
|
-
if (!authInfo) {
|
|
20
|
-
throw TypeError("StringKeyProvider constructor() missing authInfo.")
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
let id_keys = authInfo.split(',')
|
|
24
|
-
|
|
25
|
-
this.AUTH = new Map();
|
|
26
|
-
|
|
27
|
-
if (id_keys.length >= 1) {
|
|
28
|
-
id_keys.forEach(v => {
|
|
29
|
-
let [ did, key, cid, level ] = v.split('.')
|
|
30
|
-
level = parseInt(level)
|
|
31
|
-
if (did && key && cid && typeof level == 'number') {
|
|
32
|
-
this.addAuth(did, key, cid, level)
|
|
33
|
-
} else {
|
|
34
|
-
throw TypeError("StringKeyProvider invalid authInfo.")
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
} else {
|
|
38
|
-
throw TypeError("StringKeyProvider invalid authInfo.")
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async getAuth(id) {
|
|
44
|
-
return this.AUTH.get(id)
|
|
45
|
-
}
|
|
46
|
-
async getAuthIdList() {
|
|
47
|
-
return Array.from(this.AUTH.keys())
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
addAuth(id, keyStr, cid, level = 0) {
|
|
51
|
-
let Base64hashKey = Buffer.from(Boho.sha256.hash(keyStr)).toString('base64')
|
|
52
|
-
this.AUTH.set(id, { key: Base64hashKey, cid: cid, level: level })
|
|
53
|
-
}
|
|
54
|
-
}
|
package/src/client/CongPacket.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Transform } from 'stream'
|
|
2
|
-
import MBP from 'meta-buffer-pack'
|
|
3
|
-
|
|
4
|
-
export const CongType = {
|
|
5
|
-
TYPE_LEN1: 1,
|
|
6
|
-
TYPE_LEN2: 2,
|
|
7
|
-
TYPE_LEN3: 3,
|
|
8
|
-
TYPE_LEN4: 4
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// support LittleEndian system.
|
|
12
|
-
export function pack(payload) {
|
|
13
|
-
|
|
14
|
-
if( payload.byteLength == undefined ) payload = Buffer.from(payload)
|
|
15
|
-
|
|
16
|
-
if (payload.byteLength < 256) { //one byte len
|
|
17
|
-
return MBP.pack(
|
|
18
|
-
MBP.MB('#type', '8', CongType.TYPE_LEN1),
|
|
19
|
-
MBP.MB('#payloadLen1', '8', payload.byteLength),
|
|
20
|
-
MBP.MB('#payload', payload)
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
} else if (payload.byteLength < 65536) { // 2bytes len
|
|
24
|
-
return MBP.pack(
|
|
25
|
-
MBP.MB('#type', '8', CongType.TYPE_LEN2),
|
|
26
|
-
MBP.MB('#payloadLen2', '16L', payload.byteLength),
|
|
27
|
-
MBP.MB('#payload', payload)
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
} else if (payload.byteLength < 2 ** 24) { // 3bytes len
|
|
31
|
-
let len4Buffer = Buffer.alloc(4)
|
|
32
|
-
len4Buffer.writeUint32LE(payload.byteLength)
|
|
33
|
-
let cropLen3 = len4Buffer.subarray(0, 3)
|
|
34
|
-
return MBP.pack(
|
|
35
|
-
MBP.MB('#type', '8', CongType.TYPE_LEN3),
|
|
36
|
-
MBP.MB('#payloadLen3', cropLen3),
|
|
37
|
-
MBP.MB('#payload', payload)
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
} else { //use 4 bytes.
|
|
41
|
-
return MBP.pack(
|
|
42
|
-
MBP.MB('#type', '8', CongType.TYPE_LEN4),
|
|
43
|
-
MBP.MB('#payloadLen4', '32L', payload.byteLength),
|
|
44
|
-
MBP.MB('#payload', payload)
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export class CongRx extends Transform {
|
|
51
|
-
constructor(options) {
|
|
52
|
-
super(options)
|
|
53
|
-
this.buffer = Buffer.alloc(0)
|
|
54
|
-
this.frames = []
|
|
55
|
-
this.rxi = 0;
|
|
56
|
-
this.rxi_zero = 0;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
_transform(chunk, encoding, callback) {
|
|
62
|
-
this.addData(chunk)
|
|
63
|
-
if (this.frames.length > 0) {
|
|
64
|
-
this.frames.forEach(frame => {
|
|
65
|
-
this.push(frame)
|
|
66
|
-
})
|
|
67
|
-
this.frames = []
|
|
68
|
-
}
|
|
69
|
-
callback()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
addData(chunk) {
|
|
74
|
-
let c = chunk.byteLength;
|
|
75
|
-
let i = 0;
|
|
76
|
-
while (c--) {
|
|
77
|
-
this.rxi++
|
|
78
|
-
if (chunk[i++] == 0) {
|
|
79
|
-
this.rxi_zero++
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (this.buffer.byteLength > 0) {
|
|
84
|
-
this.buffer = Buffer.concat([this.buffer, chunk])
|
|
85
|
-
} else {
|
|
86
|
-
this.buffer = chunk
|
|
87
|
-
}
|
|
88
|
-
this.parse()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
parse() {
|
|
93
|
-
let head = this.buffer[0]
|
|
94
|
-
let headerLen;
|
|
95
|
-
let payloadSize;
|
|
96
|
-
|
|
97
|
-
if (head == CongType.TYPE_LEN1) {
|
|
98
|
-
headerLen = 2;
|
|
99
|
-
if (this.buffer.byteLength < headerLen) return;
|
|
100
|
-
payloadSize = this.buffer.readUint8(1)
|
|
101
|
-
|
|
102
|
-
} else if (head == CongType.TYPE_LEN2) {
|
|
103
|
-
headerLen = 3;
|
|
104
|
-
if (this.buffer.byteLength < headerLen) return;
|
|
105
|
-
payloadSize = this.buffer.readUint16LE(1)
|
|
106
|
-
|
|
107
|
-
} else if (head == CongType.TYPE_LEN3) {
|
|
108
|
-
headerLen = 4;
|
|
109
|
-
if (this.buffer.byteLength < headerLen) return;
|
|
110
|
-
payloadSize = this.buffer.readUint16LE(1) + this.buffer.readUint8(3) * 65536
|
|
111
|
-
|
|
112
|
-
} else if (head == CongType.TYPE_LEN4) {
|
|
113
|
-
headerLen = 5;
|
|
114
|
-
if (this.buffer.byteLength < headerLen) return;
|
|
115
|
-
payloadSize = this.buffer.readUint32LE(1)
|
|
116
|
-
|
|
117
|
-
} else {
|
|
118
|
-
this.emit('wrong', this.buffer)
|
|
119
|
-
this.buffer = Buffer.alloc(0)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (payloadSize == this.buffer.byteLength - headerLen) {
|
|
124
|
-
this.frames.push(this.buffer.subarray(headerLen))
|
|
125
|
-
this.buffer = Buffer.alloc(0)
|
|
126
|
-
return
|
|
127
|
-
} else if (payloadSize < this.buffer.byteLength - headerLen) {
|
|
128
|
-
this.frames.push(this.buffer.subarray(headerLen, headerLen + payloadSize))
|
|
129
|
-
this.buffer = this.buffer.subarray(headerLen + payloadSize)
|
|
130
|
-
this.parse()
|
|
131
|
-
} else {
|
|
132
|
-
// not ready
|
|
133
|
-
// console.log('+')
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|