@jskit-ai/realtime 0.1.55 → 0.1.57
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/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/realtime",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.57",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Thin, generic realtime runtime wrappers for socket.io server and client.",
|
|
7
7
|
options: {
|
|
@@ -94,7 +94,7 @@ export default Object.freeze({
|
|
|
94
94
|
mutations: {
|
|
95
95
|
dependencies: {
|
|
96
96
|
runtime: {
|
|
97
|
-
"@jskit-ai/kernel": "0.1.
|
|
97
|
+
"@jskit-ai/kernel": "0.1.58",
|
|
98
98
|
"@socket.io/redis-adapter": "^8.3.0",
|
|
99
99
|
"redis": "^5.8.2",
|
|
100
100
|
"socket.io": "^4.8.3",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/realtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.57",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@socket.io/redis-adapter": "^8.3.0",
|
|
19
|
-
"@jskit-ai/kernel": "0.1.
|
|
19
|
+
"@jskit-ai/kernel": "0.1.58",
|
|
20
20
|
"redis": "^5.8.2",
|
|
21
21
|
"socket.io": "^4.8.3",
|
|
22
22
|
"socket.io-client": "^4.8.3"
|
|
@@ -450,9 +450,40 @@ async function resolveSocketActorId(authService, socket) {
|
|
|
450
450
|
return null;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
const
|
|
454
|
-
|
|
453
|
+
const handshakeHeaders =
|
|
454
|
+
socket?.handshake?.headers && typeof socket.handshake.headers === "object"
|
|
455
|
+
? socket.handshake.headers
|
|
456
|
+
: {};
|
|
457
|
+
const requestHeaders =
|
|
458
|
+
socket?.request?.headers && typeof socket.request.headers === "object"
|
|
459
|
+
? socket.request.headers
|
|
460
|
+
: {};
|
|
461
|
+
const cookieHeader = normalizeText(
|
|
462
|
+
handshakeHeaders.cookie ||
|
|
463
|
+
requestHeaders.cookie
|
|
464
|
+
);
|
|
465
|
+
const cookies = parseCookieHeader(cookieHeader);
|
|
466
|
+
const host = normalizeText(handshakeHeaders.host || requestHeaders.host);
|
|
467
|
+
const remoteAddress = normalizeText(
|
|
468
|
+
socket?.request?.socket?.remoteAddress ||
|
|
469
|
+
socket?.conn?.remoteAddress ||
|
|
470
|
+
socket?.handshake?.address
|
|
471
|
+
);
|
|
472
|
+
const authRequest = {
|
|
455
473
|
cookies
|
|
474
|
+
};
|
|
475
|
+
if (host) {
|
|
476
|
+
authRequest.headers = {
|
|
477
|
+
host
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
if (remoteAddress) {
|
|
481
|
+
authRequest.socket = {
|
|
482
|
+
remoteAddress
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
const authResult = await authService.authenticateRequest({
|
|
486
|
+
...authRequest
|
|
456
487
|
});
|
|
457
488
|
if (!authResult || authResult.authenticated !== true) {
|
|
458
489
|
return null;
|
|
@@ -144,6 +144,96 @@ test("RealtimeServiceProvider boot does not eagerly resolve optional auth/worksp
|
|
|
144
144
|
await provider.shutdown(app);
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
+
test("RealtimeServiceProvider boot authenticates sockets from handshake cookies and joins actor workspace rooms", async () => {
|
|
148
|
+
const app = createSingletonApp();
|
|
149
|
+
app.instance("jskit.fastify", {
|
|
150
|
+
server: createServer()
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const authenticateCalls = [];
|
|
154
|
+
app.singleton("authService", () => ({
|
|
155
|
+
async authenticateRequest(input = {}) {
|
|
156
|
+
authenticateCalls.push(input);
|
|
157
|
+
return {
|
|
158
|
+
authenticated: true,
|
|
159
|
+
profile: {
|
|
160
|
+
id: 9
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}));
|
|
165
|
+
app.singleton("internal.repository.workspace-memberships", () => ({
|
|
166
|
+
async listActiveWorkspaceIdsByUserId(userId) {
|
|
167
|
+
assert.equal(userId, "9");
|
|
168
|
+
return [11, 12];
|
|
169
|
+
}
|
|
170
|
+
}));
|
|
171
|
+
|
|
172
|
+
let connectionHandler = null;
|
|
173
|
+
const io = {
|
|
174
|
+
on(eventName, handler) {
|
|
175
|
+
if (eventName === "connection") {
|
|
176
|
+
connectionHandler = handler;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const provider = new RealtimeServiceProvider();
|
|
182
|
+
provider.register(app);
|
|
183
|
+
app.instance("runtime.realtime.io", io);
|
|
184
|
+
|
|
185
|
+
await provider.boot(app);
|
|
186
|
+
|
|
187
|
+
const joinedRooms = [];
|
|
188
|
+
const socket = {
|
|
189
|
+
handshake: {
|
|
190
|
+
headers: {
|
|
191
|
+
cookie: "session=abc123; theme=dark",
|
|
192
|
+
host: "127.0.0.1:3100"
|
|
193
|
+
},
|
|
194
|
+
address: "127.0.0.1"
|
|
195
|
+
},
|
|
196
|
+
request: {
|
|
197
|
+
headers: {},
|
|
198
|
+
socket: {
|
|
199
|
+
remoteAddress: "127.0.0.1"
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
data: {},
|
|
203
|
+
join(room) {
|
|
204
|
+
joinedRooms.push(room);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
await connectionHandler(socket);
|
|
209
|
+
await provider.shutdown(app);
|
|
210
|
+
|
|
211
|
+
assert.deepEqual(authenticateCalls, [
|
|
212
|
+
{
|
|
213
|
+
cookies: {
|
|
214
|
+
session: "abc123",
|
|
215
|
+
theme: "dark"
|
|
216
|
+
},
|
|
217
|
+
headers: {
|
|
218
|
+
host: "127.0.0.1:3100"
|
|
219
|
+
},
|
|
220
|
+
socket: {
|
|
221
|
+
remoteAddress: "127.0.0.1"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
]);
|
|
225
|
+
assert.equal(socket.data.actorId, "9");
|
|
226
|
+
assert.deepEqual(joinedRooms, [
|
|
227
|
+
"clients",
|
|
228
|
+
"users",
|
|
229
|
+
"user:9",
|
|
230
|
+
"workspace:11",
|
|
231
|
+
"workspace:11:user:9",
|
|
232
|
+
"workspace:12",
|
|
233
|
+
"workspace:12:user:9"
|
|
234
|
+
]);
|
|
235
|
+
});
|
|
236
|
+
|
|
147
237
|
test("RealtimeClientProvider registers runtime realtime client api", () => {
|
|
148
238
|
const app = createSingletonApp();
|
|
149
239
|
const provider = new RealtimeClientProvider();
|