@arcblock/event-hub 1.25.6 → 1.26.1
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/lib/client.js +70 -17
- package/lib/constant.js +1 -0
- package/lib/index.js +3 -0
- package/lib/server.js +21 -13
- package/package.json +4 -4
package/lib/client.js
CHANGED
|
@@ -6,10 +6,9 @@ const queue = require('axon/lib/plugins/queue');
|
|
|
6
6
|
const { fromSecretKey, WalletType } = require('@ocap/wallet');
|
|
7
7
|
const { DidType, isEthereumType } = require('@arcblock/did');
|
|
8
8
|
|
|
9
|
-
const JWT = require('@arcblock/jwt');
|
|
10
9
|
const { toTypeInfo } = require('@arcblock/did');
|
|
11
10
|
|
|
12
|
-
const { RESERVED_EVENT_PREFIX, EVENT_AUTH, EVENT_AUTH_FAIL } = require('./constant');
|
|
11
|
+
const { RESERVED_EVENT_PREFIX, EVENT_AUTH, EVENT_AUTH_SUCCESS, EVENT_AUTH_FAIL } = require('./constant');
|
|
13
12
|
|
|
14
13
|
const checkEvent = (event) => {
|
|
15
14
|
if (event.startsWith(RESERVED_EVENT_PREFIX)) {
|
|
@@ -33,8 +32,8 @@ const defaultOpts = {
|
|
|
33
32
|
port: undefined,
|
|
34
33
|
hostname: '0.0.0.0',
|
|
35
34
|
autoConnect: false,
|
|
35
|
+
wallet: undefined,
|
|
36
36
|
did: undefined,
|
|
37
|
-
pk: undefined,
|
|
38
37
|
sk: undefined,
|
|
39
38
|
};
|
|
40
39
|
|
|
@@ -42,25 +41,59 @@ class Socket extends axon.SubEmitterSocket {
|
|
|
42
41
|
constructor(opts) {
|
|
43
42
|
super();
|
|
44
43
|
|
|
45
|
-
const wallet = getWallet(opts.sk, toTypeInfo(opts.did));
|
|
44
|
+
const wallet = opts.wallet || getWallet(opts.sk, toTypeInfo(opts.did));
|
|
45
|
+
this._authenticated = false;
|
|
46
|
+
this._pendingMessages = [];
|
|
47
|
+
this._wallet = wallet;
|
|
46
48
|
|
|
47
49
|
this.sock.use((sock) => {
|
|
48
|
-
sock.on('connect', () => {
|
|
50
|
+
sock.on('connect', async () => {
|
|
51
|
+
this._authenticated = false;
|
|
52
|
+
|
|
53
|
+
// Use wallet.signJWT() so business can override it for remote signing
|
|
54
|
+
const token = await wallet.signJWT();
|
|
49
55
|
sock.send(EVENT_AUTH, {
|
|
50
56
|
pk: wallet.publicKey,
|
|
51
|
-
token
|
|
57
|
+
token,
|
|
52
58
|
});
|
|
59
|
+
});
|
|
53
60
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
});
|
|
61
|
+
sock.on('close', () => {
|
|
62
|
+
this._authenticated = false;
|
|
63
|
+
this._pendingMessages = [];
|
|
58
64
|
});
|
|
59
65
|
});
|
|
60
66
|
|
|
67
|
+
// Listen for auth events on the SubEmitterSocket instance (this), not on raw sock
|
|
68
|
+
this.on(EVENT_AUTH_SUCCESS, () => {
|
|
69
|
+
this._authenticated = true;
|
|
70
|
+
|
|
71
|
+
// Send all pending messages after authentication
|
|
72
|
+
const pending = this._pendingMessages.slice();
|
|
73
|
+
this._pendingMessages = [];
|
|
74
|
+
pending.forEach(([event, data]) => this.sock.send(event, data));
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
this.on(EVENT_AUTH_FAIL, ({ msg } = {}) => {
|
|
78
|
+
this.emit('error', { msg });
|
|
79
|
+
this._authenticated = false;
|
|
80
|
+
this._pendingMessages = [];
|
|
81
|
+
this.sock.socks.forEach((s) => s.close());
|
|
82
|
+
});
|
|
83
|
+
|
|
61
84
|
this.sock.use(queue());
|
|
62
85
|
this.sock.use(roundrobin({ fallback: this.sock.enqueue }));
|
|
63
|
-
|
|
86
|
+
|
|
87
|
+
const originalSend = this.sock.send.bind(this.sock);
|
|
88
|
+
this.send = (event, data) => {
|
|
89
|
+
// Check both authentication AND connection status
|
|
90
|
+
const hasConnection = this.sock.socks && this.sock.socks.length > 0;
|
|
91
|
+
if (this._authenticated && hasConnection) {
|
|
92
|
+
originalSend(event, data);
|
|
93
|
+
} else {
|
|
94
|
+
this._pendingMessages.push([event, data]);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
64
97
|
}
|
|
65
98
|
}
|
|
66
99
|
|
|
@@ -72,18 +105,27 @@ class Client extends EventEmitter {
|
|
|
72
105
|
throw new Error('port should not be empty');
|
|
73
106
|
}
|
|
74
107
|
|
|
75
|
-
if (!opts.
|
|
76
|
-
|
|
108
|
+
if (!opts.wallet) {
|
|
109
|
+
if (!opts.did) {
|
|
110
|
+
throw new Error('did should not be empty when wallet is not provided');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// sk should be provided when wallet is not provided
|
|
114
|
+
if (!opts.sk) {
|
|
115
|
+
throw new Error('Either wallet or sk should be provided');
|
|
116
|
+
}
|
|
77
117
|
}
|
|
78
118
|
|
|
79
|
-
const wallet = getWallet(opts.sk, toTypeInfo(opts.did));
|
|
119
|
+
const wallet = opts.wallet || getWallet(opts.sk, toTypeInfo(opts.did));
|
|
120
|
+
const did = opts.wallet ? opts.wallet.address : opts.did;
|
|
80
121
|
|
|
81
|
-
if (wallet.address !==
|
|
82
|
-
throw new Error('did
|
|
122
|
+
if (wallet.address !== did) {
|
|
123
|
+
throw new Error('did does not match the provided wallet/sk');
|
|
83
124
|
}
|
|
84
125
|
|
|
85
|
-
this.opts = Object.assign({}, defaultOpts, opts, {
|
|
126
|
+
this.opts = Object.assign({}, defaultOpts, opts, { wallet, did });
|
|
86
127
|
this._client = new Socket(this.opts);
|
|
128
|
+
this._wallet = wallet;
|
|
87
129
|
|
|
88
130
|
this._bindEvent();
|
|
89
131
|
|
|
@@ -98,6 +140,8 @@ class Client extends EventEmitter {
|
|
|
98
140
|
}
|
|
99
141
|
|
|
100
142
|
close() {
|
|
143
|
+
this._client._authenticated = false;
|
|
144
|
+
this._client._pendingMessages = [];
|
|
101
145
|
this._client.close();
|
|
102
146
|
}
|
|
103
147
|
|
|
@@ -123,6 +167,15 @@ class Client extends EventEmitter {
|
|
|
123
167
|
}
|
|
124
168
|
}
|
|
125
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Get the wallet instance
|
|
172
|
+
* Business can override wallet.signJWT() for remote signing
|
|
173
|
+
* @returns {WalletObject}
|
|
174
|
+
*/
|
|
175
|
+
getWallet() {
|
|
176
|
+
return this._wallet;
|
|
177
|
+
}
|
|
178
|
+
|
|
126
179
|
_bindEvent() {
|
|
127
180
|
this._client.on('error', this.emit.bind(this, 'error'));
|
|
128
181
|
}
|
package/lib/constant.js
CHANGED
package/lib/index.js
CHANGED
package/lib/server.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const axon = require('axon');
|
|
3
3
|
const Message = require('amp-message');
|
|
4
4
|
const JWT = require('@arcblock/jwt');
|
|
5
|
-
const { EVENT_AUTH, EVENT_AUTH_FAIL } = require('./constant');
|
|
5
|
+
const { EVENT_AUTH, EVENT_AUTH_SUCCESS, EVENT_AUTH_FAIL } = require('./constant');
|
|
6
6
|
|
|
7
7
|
const getDid = (jwt) => jwt.iss.replace(/^did:abt:/, '');
|
|
8
8
|
|
|
@@ -101,18 +101,26 @@ class Server extends axon.Socket {
|
|
|
101
101
|
const msg = new Message(buf);
|
|
102
102
|
const [event, data] = msg.args;
|
|
103
103
|
if (event === EVENT_AUTH) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
// JWT.verify returns a Promise but is synchronously resolved (no await inside)
|
|
105
|
+
// We use .then() to handle it and send confirmation to client
|
|
106
|
+
const { pk, token } = data;
|
|
107
|
+
this.jwt
|
|
108
|
+
.verify(token, pk)
|
|
109
|
+
.then((valid) => {
|
|
110
|
+
if (!valid) {
|
|
111
|
+
throw new Error('token verify failed');
|
|
112
|
+
}
|
|
113
|
+
const did = getDid(this.jwt.decode(token));
|
|
114
|
+
sock.channel = did;
|
|
115
|
+
// Send authentication success confirmation
|
|
116
|
+
const successBuf = this.pack([EVENT_AUTH_SUCCESS, {}]);
|
|
117
|
+
sock.write(successBuf);
|
|
118
|
+
})
|
|
119
|
+
.catch((err) => {
|
|
120
|
+
console.error(err);
|
|
121
|
+
const resBuf = this.pack([EVENT_AUTH_FAIL, { msg: err.message }]);
|
|
122
|
+
sock.write(resBuf);
|
|
123
|
+
});
|
|
116
124
|
return;
|
|
117
125
|
}
|
|
118
126
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.26.1",
|
|
7
7
|
"description": "A nodejs module for local and remote Inter Process Event",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"amp-message": "~0.1.2",
|
|
21
21
|
"axon": "^2.0.3",
|
|
22
|
-
"@
|
|
23
|
-
"@arcblock/jwt": "1.
|
|
24
|
-
"@
|
|
22
|
+
"@arcblock/did": "1.26.1",
|
|
23
|
+
"@arcblock/jwt": "1.26.1",
|
|
24
|
+
"@ocap/wallet": "1.26.1"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"jest": "^29.7.0"
|