@pluv/platform-pluv 2.2.7 → 2.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/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +22 -0
- package/dist/index.js +78 -18
- package/dist/index.mjs +78 -18
- package/package.json +6 -6
- package/src/PluvPlatform.ts +75 -13
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/platform-pluv@2.
|
|
2
|
+
> @pluv/platform-pluv@2.3.0 build /home/runner/work/pluv/pluv/packages/platform-pluv
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
12
|
-
[32mCJS[39m ⚡️ Build success in
|
|
13
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
14
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m16.82 KB[39m
|
|
12
|
+
[32mCJS[39m ⚡️ Build success in 64ms
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m14.98 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 65ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 6964ms
|
|
17
17
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.79 KB[39m
|
|
18
18
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.79 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @pluv/platform-pluv
|
|
2
2
|
|
|
3
|
+
## 2.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e48e5d8: Added webhook debug logging.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- @pluv/crdt@2.3.0
|
|
12
|
+
- @pluv/io@2.3.0
|
|
13
|
+
- @pluv/types@2.3.0
|
|
14
|
+
|
|
15
|
+
## 2.2.8
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- b60ccd8: Fix `PluvServer` fetch config validation.
|
|
20
|
+
- Updated dependencies [b60ccd8]
|
|
21
|
+
- @pluv/io@2.2.8
|
|
22
|
+
- @pluv/crdt@2.2.8
|
|
23
|
+
- @pluv/types@2.2.8
|
|
24
|
+
|
|
3
25
|
## 2.2.7
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -270,46 +270,89 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
270
270
|
return token;
|
|
271
271
|
});
|
|
272
272
|
this._webhooksRouter = new import_hono.Hono().basePath("/").post("/", (c) => __async(this, null, function* () {
|
|
273
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
273
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
274
274
|
const [algorithm, signature] = (_b = (_a = c.req.header(SIGNATURE_HEADER)) == null ? void 0 : _a.split("=")) != null ? _b : [];
|
|
275
275
|
try {
|
|
276
|
-
if (!this._webhookSecret)
|
|
277
|
-
|
|
278
|
-
|
|
276
|
+
if (!this._webhookSecret) {
|
|
277
|
+
this._logDebug("Missing webhook secret");
|
|
278
|
+
throw new HttpError("Unauthorized", 401);
|
|
279
|
+
}
|
|
280
|
+
if (algorithm !== SIGNATURE_ALGORITHM) {
|
|
281
|
+
this._logDebug(
|
|
282
|
+
`Verification algorithm is not ${SIGNATURE_ALGORITHM}. Found: `,
|
|
283
|
+
algorithm
|
|
284
|
+
);
|
|
285
|
+
throw new HttpError("Unauthorized", 401);
|
|
286
|
+
}
|
|
287
|
+
if (!signature) {
|
|
288
|
+
this._logDebug("Missing webhook signature");
|
|
289
|
+
throw new HttpError("Unauthorized", 401);
|
|
290
|
+
}
|
|
279
291
|
const [payload, webhookSecret] = yield Promise.all([
|
|
280
292
|
c.req.json(),
|
|
281
293
|
typeof this._webhookSecret === "string" ? this._webhookSecret : yield this._webhookSecret()
|
|
282
|
-
])
|
|
294
|
+
]).catch((error) => {
|
|
295
|
+
this._logDebug(
|
|
296
|
+
"Could not derive webhook secret: ",
|
|
297
|
+
error instanceof Error ? error.message : "Unexpected error"
|
|
298
|
+
);
|
|
299
|
+
throw error;
|
|
300
|
+
});
|
|
283
301
|
const verified = yield verifyWebhook({
|
|
284
302
|
payload: (0, import_fast_json_stable_stringify.default)(payload),
|
|
285
303
|
signature,
|
|
286
304
|
secret: webhookSecret
|
|
305
|
+
}).catch((error) => {
|
|
306
|
+
this._logDebug(
|
|
307
|
+
"Error while verifying webhook: ",
|
|
308
|
+
error instanceof Error ? error.message : "Unexpected error"
|
|
309
|
+
);
|
|
310
|
+
return false;
|
|
287
311
|
});
|
|
288
|
-
if (!verified)
|
|
312
|
+
if (!verified) {
|
|
313
|
+
this._logDebug("Failed to verify webhook");
|
|
314
|
+
throw new HttpError("Unauthorized", 401);
|
|
315
|
+
}
|
|
289
316
|
const parsed = ZodEvent.safeParse(payload);
|
|
290
|
-
if (!parsed.success)
|
|
317
|
+
if (!parsed.success) {
|
|
318
|
+
this._logDebug(
|
|
319
|
+
"Failed to validate event payload:",
|
|
320
|
+
JSON.stringify((_c = parsed.data) != null ? _c : {}, null, 4)
|
|
321
|
+
);
|
|
322
|
+
throw new HttpError("Invalid request", 400);
|
|
323
|
+
}
|
|
291
324
|
const { event, data } = parsed.data;
|
|
292
325
|
const context = this._getContext();
|
|
293
326
|
switch (event) {
|
|
294
327
|
case "initial-storage": {
|
|
295
328
|
const room = data.room;
|
|
296
|
-
const storage = typeof room === "string" ? (
|
|
297
|
-
|
|
329
|
+
const storage = typeof room === "string" ? (_e = yield (_d = this._getInitialStorage) == null ? void 0 : _d.call(this, { context, room })) != null ? _e : null : null;
|
|
330
|
+
try {
|
|
331
|
+
return createSuccessResponse(c, { event, room, storage });
|
|
332
|
+
} catch (error) {
|
|
333
|
+
this._logDebug("Could not create getInitialStorage response");
|
|
334
|
+
throw error;
|
|
335
|
+
}
|
|
298
336
|
}
|
|
299
337
|
case "room-deleted": {
|
|
300
338
|
const room = data.room;
|
|
301
339
|
const encodedState = data.storage;
|
|
302
340
|
yield Promise.resolve(
|
|
303
|
-
(
|
|
341
|
+
(_f = this._listeners) == null ? void 0 : _f.onRoomDeleted({ context, encodedState, room })
|
|
304
342
|
);
|
|
305
|
-
|
|
343
|
+
try {
|
|
344
|
+
return createSuccessResponse(c, { event, room });
|
|
345
|
+
} catch (error) {
|
|
346
|
+
this._logDebug("Could not create onRoomDeleted response");
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
306
349
|
}
|
|
307
350
|
case "user-connected": {
|
|
308
351
|
const room = data.room;
|
|
309
352
|
const encodedState = data.storage;
|
|
310
353
|
const user = data.user;
|
|
311
354
|
yield Promise.resolve(
|
|
312
|
-
(
|
|
355
|
+
(_g = this._listeners) == null ? void 0 : _g.onUserConnected({
|
|
313
356
|
context,
|
|
314
357
|
encodedState,
|
|
315
358
|
platform: this,
|
|
@@ -317,14 +360,19 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
317
360
|
user
|
|
318
361
|
})
|
|
319
362
|
);
|
|
320
|
-
|
|
363
|
+
try {
|
|
364
|
+
return createSuccessResponse(c, { event, room });
|
|
365
|
+
} catch (error) {
|
|
366
|
+
this._logDebug("Could not create onUserConnected response");
|
|
367
|
+
throw error;
|
|
368
|
+
}
|
|
321
369
|
}
|
|
322
370
|
case "user-disconnected": {
|
|
323
371
|
const room = data.room;
|
|
324
372
|
const encodedState = data.storage;
|
|
325
373
|
const user = data.user;
|
|
326
374
|
yield Promise.resolve(
|
|
327
|
-
(
|
|
375
|
+
(_h = this._listeners) == null ? void 0 : _h.onUserDisconnected({
|
|
328
376
|
context,
|
|
329
377
|
encodedState,
|
|
330
378
|
platform: this,
|
|
@@ -332,7 +380,12 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
332
380
|
user
|
|
333
381
|
})
|
|
334
382
|
);
|
|
335
|
-
|
|
383
|
+
try {
|
|
384
|
+
return createSuccessResponse(c, { event, room });
|
|
385
|
+
} catch (error) {
|
|
386
|
+
this._logDebug("Could not create onUserDisconnected response");
|
|
387
|
+
throw error;
|
|
388
|
+
}
|
|
336
389
|
}
|
|
337
390
|
default: {
|
|
338
391
|
throw new HttpError("Unknown event", 400);
|
|
@@ -388,12 +441,19 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
388
441
|
throw new Error("Not implemented");
|
|
389
442
|
}
|
|
390
443
|
validateConfig(config) {
|
|
391
|
-
|
|
444
|
+
this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
|
|
445
|
+
if (!config.authorize) {
|
|
446
|
+
this._logDebug("Config `authorize` must be provided to `platformPluv`");
|
|
392
447
|
throw new Error("Config `authorize` must be provided to `platformPluv`");
|
|
393
|
-
|
|
448
|
+
}
|
|
449
|
+
if (!!config.onRoomMessage) {
|
|
450
|
+
this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
394
451
|
throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
395
|
-
|
|
452
|
+
}
|
|
453
|
+
if (!!config.onStorageUpdated) {
|
|
454
|
+
this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
396
455
|
throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
456
|
+
}
|
|
397
457
|
this._getInitialStorage = config.getInitialStorage;
|
|
398
458
|
this._listeners = {
|
|
399
459
|
onRoomDeleted: (event) => {
|
package/dist/index.mjs
CHANGED
|
@@ -240,46 +240,89 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
240
240
|
return token;
|
|
241
241
|
});
|
|
242
242
|
this._webhooksRouter = new Hono().basePath("/").post("/", (c) => __async(this, null, function* () {
|
|
243
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
243
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
244
244
|
const [algorithm, signature] = (_b = (_a = c.req.header(SIGNATURE_HEADER)) == null ? void 0 : _a.split("=")) != null ? _b : [];
|
|
245
245
|
try {
|
|
246
|
-
if (!this._webhookSecret)
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
if (!this._webhookSecret) {
|
|
247
|
+
this._logDebug("Missing webhook secret");
|
|
248
|
+
throw new HttpError("Unauthorized", 401);
|
|
249
|
+
}
|
|
250
|
+
if (algorithm !== SIGNATURE_ALGORITHM) {
|
|
251
|
+
this._logDebug(
|
|
252
|
+
`Verification algorithm is not ${SIGNATURE_ALGORITHM}. Found: `,
|
|
253
|
+
algorithm
|
|
254
|
+
);
|
|
255
|
+
throw new HttpError("Unauthorized", 401);
|
|
256
|
+
}
|
|
257
|
+
if (!signature) {
|
|
258
|
+
this._logDebug("Missing webhook signature");
|
|
259
|
+
throw new HttpError("Unauthorized", 401);
|
|
260
|
+
}
|
|
249
261
|
const [payload, webhookSecret] = yield Promise.all([
|
|
250
262
|
c.req.json(),
|
|
251
263
|
typeof this._webhookSecret === "string" ? this._webhookSecret : yield this._webhookSecret()
|
|
252
|
-
])
|
|
264
|
+
]).catch((error) => {
|
|
265
|
+
this._logDebug(
|
|
266
|
+
"Could not derive webhook secret: ",
|
|
267
|
+
error instanceof Error ? error.message : "Unexpected error"
|
|
268
|
+
);
|
|
269
|
+
throw error;
|
|
270
|
+
});
|
|
253
271
|
const verified = yield verifyWebhook({
|
|
254
272
|
payload: stringify(payload),
|
|
255
273
|
signature,
|
|
256
274
|
secret: webhookSecret
|
|
275
|
+
}).catch((error) => {
|
|
276
|
+
this._logDebug(
|
|
277
|
+
"Error while verifying webhook: ",
|
|
278
|
+
error instanceof Error ? error.message : "Unexpected error"
|
|
279
|
+
);
|
|
280
|
+
return false;
|
|
257
281
|
});
|
|
258
|
-
if (!verified)
|
|
282
|
+
if (!verified) {
|
|
283
|
+
this._logDebug("Failed to verify webhook");
|
|
284
|
+
throw new HttpError("Unauthorized", 401);
|
|
285
|
+
}
|
|
259
286
|
const parsed = ZodEvent.safeParse(payload);
|
|
260
|
-
if (!parsed.success)
|
|
287
|
+
if (!parsed.success) {
|
|
288
|
+
this._logDebug(
|
|
289
|
+
"Failed to validate event payload:",
|
|
290
|
+
JSON.stringify((_c = parsed.data) != null ? _c : {}, null, 4)
|
|
291
|
+
);
|
|
292
|
+
throw new HttpError("Invalid request", 400);
|
|
293
|
+
}
|
|
261
294
|
const { event, data } = parsed.data;
|
|
262
295
|
const context = this._getContext();
|
|
263
296
|
switch (event) {
|
|
264
297
|
case "initial-storage": {
|
|
265
298
|
const room = data.room;
|
|
266
|
-
const storage = typeof room === "string" ? (
|
|
267
|
-
|
|
299
|
+
const storage = typeof room === "string" ? (_e = yield (_d = this._getInitialStorage) == null ? void 0 : _d.call(this, { context, room })) != null ? _e : null : null;
|
|
300
|
+
try {
|
|
301
|
+
return createSuccessResponse(c, { event, room, storage });
|
|
302
|
+
} catch (error) {
|
|
303
|
+
this._logDebug("Could not create getInitialStorage response");
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
268
306
|
}
|
|
269
307
|
case "room-deleted": {
|
|
270
308
|
const room = data.room;
|
|
271
309
|
const encodedState = data.storage;
|
|
272
310
|
yield Promise.resolve(
|
|
273
|
-
(
|
|
311
|
+
(_f = this._listeners) == null ? void 0 : _f.onRoomDeleted({ context, encodedState, room })
|
|
274
312
|
);
|
|
275
|
-
|
|
313
|
+
try {
|
|
314
|
+
return createSuccessResponse(c, { event, room });
|
|
315
|
+
} catch (error) {
|
|
316
|
+
this._logDebug("Could not create onRoomDeleted response");
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
276
319
|
}
|
|
277
320
|
case "user-connected": {
|
|
278
321
|
const room = data.room;
|
|
279
322
|
const encodedState = data.storage;
|
|
280
323
|
const user = data.user;
|
|
281
324
|
yield Promise.resolve(
|
|
282
|
-
(
|
|
325
|
+
(_g = this._listeners) == null ? void 0 : _g.onUserConnected({
|
|
283
326
|
context,
|
|
284
327
|
encodedState,
|
|
285
328
|
platform: this,
|
|
@@ -287,14 +330,19 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
287
330
|
user
|
|
288
331
|
})
|
|
289
332
|
);
|
|
290
|
-
|
|
333
|
+
try {
|
|
334
|
+
return createSuccessResponse(c, { event, room });
|
|
335
|
+
} catch (error) {
|
|
336
|
+
this._logDebug("Could not create onUserConnected response");
|
|
337
|
+
throw error;
|
|
338
|
+
}
|
|
291
339
|
}
|
|
292
340
|
case "user-disconnected": {
|
|
293
341
|
const room = data.room;
|
|
294
342
|
const encodedState = data.storage;
|
|
295
343
|
const user = data.user;
|
|
296
344
|
yield Promise.resolve(
|
|
297
|
-
(
|
|
345
|
+
(_h = this._listeners) == null ? void 0 : _h.onUserDisconnected({
|
|
298
346
|
context,
|
|
299
347
|
encodedState,
|
|
300
348
|
platform: this,
|
|
@@ -302,7 +350,12 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
302
350
|
user
|
|
303
351
|
})
|
|
304
352
|
);
|
|
305
|
-
|
|
353
|
+
try {
|
|
354
|
+
return createSuccessResponse(c, { event, room });
|
|
355
|
+
} catch (error) {
|
|
356
|
+
this._logDebug("Could not create onUserDisconnected response");
|
|
357
|
+
throw error;
|
|
358
|
+
}
|
|
306
359
|
}
|
|
307
360
|
default: {
|
|
308
361
|
throw new HttpError("Unknown event", 400);
|
|
@@ -358,12 +411,19 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
358
411
|
throw new Error("Not implemented");
|
|
359
412
|
}
|
|
360
413
|
validateConfig(config) {
|
|
361
|
-
|
|
414
|
+
this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
|
|
415
|
+
if (!config.authorize) {
|
|
416
|
+
this._logDebug("Config `authorize` must be provided to `platformPluv`");
|
|
362
417
|
throw new Error("Config `authorize` must be provided to `platformPluv`");
|
|
363
|
-
|
|
418
|
+
}
|
|
419
|
+
if (!!config.onRoomMessage) {
|
|
420
|
+
this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
364
421
|
throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
365
|
-
|
|
422
|
+
}
|
|
423
|
+
if (!!config.onStorageUpdated) {
|
|
424
|
+
this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
366
425
|
throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
426
|
+
}
|
|
367
427
|
this._getInitialStorage = config.getInitialStorage;
|
|
368
428
|
this._listeners = {
|
|
369
429
|
onRoomDeleted: (event) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/platform-pluv",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "@pluv/io adapter for pluv.io",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"fast-json-stable-stringify": "^2.1.0",
|
|
22
22
|
"hono": "^4.7.10",
|
|
23
23
|
"zod": "^3.25.17",
|
|
24
|
-
"@pluv/
|
|
25
|
-
"@pluv/
|
|
26
|
-
"@pluv/
|
|
24
|
+
"@pluv/types": "^2.3.0",
|
|
25
|
+
"@pluv/crdt": "^2.3.0",
|
|
26
|
+
"@pluv/io": "^2.3.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"eslint": "^9.27.0",
|
|
30
30
|
"tsup": "^8.5.0",
|
|
31
31
|
"typescript": "^5.8.3",
|
|
32
|
-
"@pluv/tsconfig": "^2.
|
|
33
|
-
"eslint-config-pluv": "^2.
|
|
32
|
+
"@pluv/tsconfig": "^2.3.0",
|
|
33
|
+
"eslint-config-pluv": "^2.3.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
package/src/PluvPlatform.ts
CHANGED
|
@@ -199,12 +199,20 @@ export class PluvPlatform<
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
public validateConfig(config: any): void {
|
|
202
|
-
|
|
202
|
+
this._logDebug("validating config with properties:", Object.keys(config ?? {}));
|
|
203
|
+
|
|
204
|
+
if (!config.authorize) {
|
|
205
|
+
this._logDebug("Config `authorize` must be provided to `platformPluv`");
|
|
203
206
|
throw new Error("Config `authorize` must be provided to `platformPluv`");
|
|
204
|
-
|
|
207
|
+
}
|
|
208
|
+
if (!!config.onRoomMessage) {
|
|
209
|
+
this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
205
210
|
throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
206
|
-
|
|
211
|
+
}
|
|
212
|
+
if (!!config.onStorageUpdated) {
|
|
213
|
+
this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
207
214
|
throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
215
|
+
}
|
|
208
216
|
|
|
209
217
|
this._getInitialStorage = config.getInitialStorage;
|
|
210
218
|
this._listeners = {
|
|
@@ -220,28 +228,62 @@ export class PluvPlatform<
|
|
|
220
228
|
const [algorithm, signature] = c.req.header(SIGNATURE_HEADER)?.split("=") ?? [];
|
|
221
229
|
|
|
222
230
|
try {
|
|
223
|
-
if (!this._webhookSecret)
|
|
224
|
-
|
|
225
|
-
|
|
231
|
+
if (!this._webhookSecret) {
|
|
232
|
+
this._logDebug("Missing webhook secret");
|
|
233
|
+
throw new HttpError("Unauthorized", 401);
|
|
234
|
+
}
|
|
235
|
+
if (algorithm !== SIGNATURE_ALGORITHM) {
|
|
236
|
+
this._logDebug(
|
|
237
|
+
`Verification algorithm is not ${SIGNATURE_ALGORITHM}. Found: `,
|
|
238
|
+
algorithm,
|
|
239
|
+
);
|
|
240
|
+
throw new HttpError("Unauthorized", 401);
|
|
241
|
+
}
|
|
242
|
+
if (!signature) {
|
|
243
|
+
this._logDebug("Missing webhook signature");
|
|
244
|
+
throw new HttpError("Unauthorized", 401);
|
|
245
|
+
}
|
|
226
246
|
|
|
227
247
|
const [payload, webhookSecret] = await Promise.all([
|
|
228
248
|
c.req.json(),
|
|
229
249
|
typeof this._webhookSecret === "string"
|
|
230
250
|
? this._webhookSecret
|
|
231
251
|
: await this._webhookSecret(),
|
|
232
|
-
])
|
|
252
|
+
]).catch((error) => {
|
|
253
|
+
this._logDebug(
|
|
254
|
+
"Could not derive webhook secret: ",
|
|
255
|
+
error instanceof Error ? error.message : "Unexpected error",
|
|
256
|
+
);
|
|
257
|
+
throw error;
|
|
258
|
+
});
|
|
233
259
|
|
|
234
260
|
const verified = await verifyWebhook({
|
|
235
261
|
payload: stringify(payload),
|
|
236
262
|
signature,
|
|
237
263
|
secret: webhookSecret,
|
|
264
|
+
}).catch((error) => {
|
|
265
|
+
this._logDebug(
|
|
266
|
+
"Error while verifying webhook: ",
|
|
267
|
+
error instanceof Error ? error.message : "Unexpected error",
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
return false;
|
|
238
271
|
});
|
|
239
272
|
|
|
240
|
-
if (!verified)
|
|
273
|
+
if (!verified) {
|
|
274
|
+
this._logDebug("Failed to verify webhook");
|
|
275
|
+
throw new HttpError("Unauthorized", 401);
|
|
276
|
+
}
|
|
241
277
|
|
|
242
278
|
const parsed = ZodEvent.safeParse(payload);
|
|
243
279
|
|
|
244
|
-
if (!parsed.success)
|
|
280
|
+
if (!parsed.success) {
|
|
281
|
+
this._logDebug(
|
|
282
|
+
"Failed to validate event payload:",
|
|
283
|
+
JSON.stringify(parsed.data ?? {}, null, 4),
|
|
284
|
+
);
|
|
285
|
+
throw new HttpError("Invalid request", 400);
|
|
286
|
+
}
|
|
245
287
|
|
|
246
288
|
const { event, data } = parsed.data;
|
|
247
289
|
const context = this._getContext();
|
|
@@ -254,7 +296,12 @@ export class PluvPlatform<
|
|
|
254
296
|
? ((await this._getInitialStorage?.({ context, room })) ?? null)
|
|
255
297
|
: null;
|
|
256
298
|
|
|
257
|
-
|
|
299
|
+
try {
|
|
300
|
+
return createSuccessResponse(c, { event, room, storage });
|
|
301
|
+
} catch (error) {
|
|
302
|
+
this._logDebug("Could not create getInitialStorage response");
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
258
305
|
}
|
|
259
306
|
case "room-deleted": {
|
|
260
307
|
const room = data.room;
|
|
@@ -264,7 +311,12 @@ export class PluvPlatform<
|
|
|
264
311
|
this._listeners?.onRoomDeleted({ context, encodedState, room }),
|
|
265
312
|
);
|
|
266
313
|
|
|
267
|
-
|
|
314
|
+
try {
|
|
315
|
+
return createSuccessResponse(c, { event, room });
|
|
316
|
+
} catch (error) {
|
|
317
|
+
this._logDebug("Could not create onRoomDeleted response");
|
|
318
|
+
throw error;
|
|
319
|
+
}
|
|
268
320
|
}
|
|
269
321
|
case "user-connected": {
|
|
270
322
|
const room = data.room;
|
|
@@ -281,7 +333,12 @@ export class PluvPlatform<
|
|
|
281
333
|
}),
|
|
282
334
|
);
|
|
283
335
|
|
|
284
|
-
|
|
336
|
+
try {
|
|
337
|
+
return createSuccessResponse(c, { event, room });
|
|
338
|
+
} catch (error) {
|
|
339
|
+
this._logDebug("Could not create onUserConnected response");
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
285
342
|
}
|
|
286
343
|
case "user-disconnected": {
|
|
287
344
|
const room = data.room;
|
|
@@ -298,7 +355,12 @@ export class PluvPlatform<
|
|
|
298
355
|
}),
|
|
299
356
|
);
|
|
300
357
|
|
|
301
|
-
|
|
358
|
+
try {
|
|
359
|
+
return createSuccessResponse(c, { event, room });
|
|
360
|
+
} catch (error) {
|
|
361
|
+
this._logDebug("Could not create onUserDisconnected response");
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
302
364
|
}
|
|
303
365
|
default: {
|
|
304
366
|
throw new HttpError("Unknown event", 400);
|