@pluv/platform-pluv 2.2.8 → 2.3.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/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +21 -0
- package/dist/index.js +72 -15
- package/dist/index.mjs +72 -15
- package/package.json +6 -6
- package/src/PluvPlatform.ts +69 -10
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/platform-pluv@2.
|
|
2
|
+
> @pluv/platform-pluv@2.3.1 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
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
12
|
-
[32mESM[39m ⚡️ Build success in
|
|
13
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
14
|
-
[32mCJS[39m ⚡️ Build success in
|
|
11
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m15.03 KB[39m
|
|
12
|
+
[32mESM[39m ⚡️ Build success in 131ms
|
|
13
|
+
[32mCJS[39m [1mdist/index.js [22m[32m16.87 KB[39m
|
|
14
|
+
[32mCJS[39m ⚡️ Build success in 137ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 6927ms
|
|
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,26 @@
|
|
|
1
1
|
# @pluv/platform-pluv
|
|
2
2
|
|
|
3
|
+
## 2.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 824c98b: Added more webhook logging.
|
|
8
|
+
- @pluv/crdt@2.3.1
|
|
9
|
+
- @pluv/io@2.3.1
|
|
10
|
+
- @pluv/types@2.3.1
|
|
11
|
+
|
|
12
|
+
## 2.3.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- e48e5d8: Added webhook debug logging.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- @pluv/crdt@2.3.0
|
|
21
|
+
- @pluv/io@2.3.0
|
|
22
|
+
- @pluv/types@2.3.0
|
|
23
|
+
|
|
3
24
|
## 2.2.8
|
|
4
25
|
|
|
5
26
|
### 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);
|
|
@@ -341,6 +394,7 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
341
394
|
} catch (error) {
|
|
342
395
|
const message = error instanceof Error ? error.message : "Unexpected error";
|
|
343
396
|
const status = error instanceof HttpError ? error.status : 500;
|
|
397
|
+
this._logDebug("Uncaught error: ", message);
|
|
344
398
|
return createErrorResponse(c, { message }, status);
|
|
345
399
|
}
|
|
346
400
|
}));
|
|
@@ -390,12 +444,15 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
390
444
|
validateConfig(config) {
|
|
391
445
|
this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
|
|
392
446
|
if (!config.authorize) {
|
|
447
|
+
this._logDebug("Config `authorize` must be provided to `platformPluv`");
|
|
393
448
|
throw new Error("Config `authorize` must be provided to `platformPluv`");
|
|
394
449
|
}
|
|
395
450
|
if (!!config.onRoomMessage) {
|
|
451
|
+
this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
396
452
|
throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
397
453
|
}
|
|
398
454
|
if (!!config.onStorageUpdated) {
|
|
455
|
+
this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
399
456
|
throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
400
457
|
}
|
|
401
458
|
this._getInitialStorage = config.getInitialStorage;
|
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);
|
|
@@ -311,6 +364,7 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
311
364
|
} catch (error) {
|
|
312
365
|
const message = error instanceof Error ? error.message : "Unexpected error";
|
|
313
366
|
const status = error instanceof HttpError ? error.status : 500;
|
|
367
|
+
this._logDebug("Uncaught error: ", message);
|
|
314
368
|
return createErrorResponse(c, { message }, status);
|
|
315
369
|
}
|
|
316
370
|
}));
|
|
@@ -360,12 +414,15 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
360
414
|
validateConfig(config) {
|
|
361
415
|
this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
|
|
362
416
|
if (!config.authorize) {
|
|
417
|
+
this._logDebug("Config `authorize` must be provided to `platformPluv`");
|
|
363
418
|
throw new Error("Config `authorize` must be provided to `platformPluv`");
|
|
364
419
|
}
|
|
365
420
|
if (!!config.onRoomMessage) {
|
|
421
|
+
this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
366
422
|
throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
367
423
|
}
|
|
368
424
|
if (!!config.onStorageUpdated) {
|
|
425
|
+
this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
369
426
|
throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
370
427
|
}
|
|
371
428
|
this._getInitialStorage = config.getInitialStorage;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/platform-pluv",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
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/crdt": "^2.
|
|
25
|
-
"@pluv/io": "^2.
|
|
26
|
-
"@pluv/types": "^2.
|
|
24
|
+
"@pluv/crdt": "^2.3.1",
|
|
25
|
+
"@pluv/io": "^2.3.1",
|
|
26
|
+
"@pluv/types": "^2.3.1"
|
|
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.1",
|
|
33
|
+
"eslint-config-pluv": "^2.3.1"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
package/src/PluvPlatform.ts
CHANGED
|
@@ -202,12 +202,15 @@ export class PluvPlatform<
|
|
|
202
202
|
this._logDebug("validating config with properties:", Object.keys(config ?? {}));
|
|
203
203
|
|
|
204
204
|
if (!config.authorize) {
|
|
205
|
+
this._logDebug("Config `authorize` must be provided to `platformPluv`");
|
|
205
206
|
throw new Error("Config `authorize` must be provided to `platformPluv`");
|
|
206
207
|
}
|
|
207
208
|
if (!!config.onRoomMessage) {
|
|
209
|
+
this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
208
210
|
throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
|
|
209
211
|
}
|
|
210
212
|
if (!!config.onStorageUpdated) {
|
|
213
|
+
this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
211
214
|
throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
|
|
212
215
|
}
|
|
213
216
|
|
|
@@ -225,28 +228,62 @@ export class PluvPlatform<
|
|
|
225
228
|
const [algorithm, signature] = c.req.header(SIGNATURE_HEADER)?.split("=") ?? [];
|
|
226
229
|
|
|
227
230
|
try {
|
|
228
|
-
if (!this._webhookSecret)
|
|
229
|
-
|
|
230
|
-
|
|
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
|
+
}
|
|
231
246
|
|
|
232
247
|
const [payload, webhookSecret] = await Promise.all([
|
|
233
248
|
c.req.json(),
|
|
234
249
|
typeof this._webhookSecret === "string"
|
|
235
250
|
? this._webhookSecret
|
|
236
251
|
: await this._webhookSecret(),
|
|
237
|
-
])
|
|
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
|
+
});
|
|
238
259
|
|
|
239
260
|
const verified = await verifyWebhook({
|
|
240
261
|
payload: stringify(payload),
|
|
241
262
|
signature,
|
|
242
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;
|
|
243
271
|
});
|
|
244
272
|
|
|
245
|
-
if (!verified)
|
|
273
|
+
if (!verified) {
|
|
274
|
+
this._logDebug("Failed to verify webhook");
|
|
275
|
+
throw new HttpError("Unauthorized", 401);
|
|
276
|
+
}
|
|
246
277
|
|
|
247
278
|
const parsed = ZodEvent.safeParse(payload);
|
|
248
279
|
|
|
249
|
-
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
|
+
}
|
|
250
287
|
|
|
251
288
|
const { event, data } = parsed.data;
|
|
252
289
|
const context = this._getContext();
|
|
@@ -259,7 +296,12 @@ export class PluvPlatform<
|
|
|
259
296
|
? ((await this._getInitialStorage?.({ context, room })) ?? null)
|
|
260
297
|
: null;
|
|
261
298
|
|
|
262
|
-
|
|
299
|
+
try {
|
|
300
|
+
return createSuccessResponse(c, { event, room, storage });
|
|
301
|
+
} catch (error) {
|
|
302
|
+
this._logDebug("Could not create getInitialStorage response");
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
263
305
|
}
|
|
264
306
|
case "room-deleted": {
|
|
265
307
|
const room = data.room;
|
|
@@ -269,7 +311,12 @@ export class PluvPlatform<
|
|
|
269
311
|
this._listeners?.onRoomDeleted({ context, encodedState, room }),
|
|
270
312
|
);
|
|
271
313
|
|
|
272
|
-
|
|
314
|
+
try {
|
|
315
|
+
return createSuccessResponse(c, { event, room });
|
|
316
|
+
} catch (error) {
|
|
317
|
+
this._logDebug("Could not create onRoomDeleted response");
|
|
318
|
+
throw error;
|
|
319
|
+
}
|
|
273
320
|
}
|
|
274
321
|
case "user-connected": {
|
|
275
322
|
const room = data.room;
|
|
@@ -286,7 +333,12 @@ export class PluvPlatform<
|
|
|
286
333
|
}),
|
|
287
334
|
);
|
|
288
335
|
|
|
289
|
-
|
|
336
|
+
try {
|
|
337
|
+
return createSuccessResponse(c, { event, room });
|
|
338
|
+
} catch (error) {
|
|
339
|
+
this._logDebug("Could not create onUserConnected response");
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
290
342
|
}
|
|
291
343
|
case "user-disconnected": {
|
|
292
344
|
const room = data.room;
|
|
@@ -303,7 +355,12 @@ export class PluvPlatform<
|
|
|
303
355
|
}),
|
|
304
356
|
);
|
|
305
357
|
|
|
306
|
-
|
|
358
|
+
try {
|
|
359
|
+
return createSuccessResponse(c, { event, room });
|
|
360
|
+
} catch (error) {
|
|
361
|
+
this._logDebug("Could not create onUserDisconnected response");
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
307
364
|
}
|
|
308
365
|
default: {
|
|
309
366
|
throw new HttpError("Unknown event", 400);
|
|
@@ -313,6 +370,8 @@ export class PluvPlatform<
|
|
|
313
370
|
const message = error instanceof Error ? error.message : "Unexpected error";
|
|
314
371
|
const status = error instanceof HttpError ? error.status : 500;
|
|
315
372
|
|
|
373
|
+
this._logDebug("Uncaught error: ", message);
|
|
374
|
+
|
|
316
375
|
return createErrorResponse(c, { message }, status);
|
|
317
376
|
}
|
|
318
377
|
});
|