@porulle/adapter-woocommerce 0.74.3 → 0.74.4
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/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/webhooks.d.ts +3 -2
- package/dist/webhooks.js +4 -11
- package/package.json +2 -2
- package/src/webhooks.ts +4 -12
package/dist/webhooks.d.ts
CHANGED
|
@@ -7,8 +7,9 @@ export declare const WOO_WEBHOOK_TOPICS: readonly ["product.created", "product.u
|
|
|
7
7
|
* (form body `webhook_id=N`, unsigned) is `Ok(null)`. Everything else must carry a valid signature.
|
|
8
8
|
*
|
|
9
9
|
* The id is ours: `X-WC-Webhook-Delivery-ID` hashes the subscription id and the current SECOND, so two
|
|
10
|
-
* deliveries in one second collide.
|
|
11
|
-
*
|
|
10
|
+
* deliveries in one second collide. So does `date_modified_gmt`, which is also to the second: two stock
|
|
11
|
+
* changes inside one second differ only in the stock. The topic and the whole signed body identify a
|
|
12
|
+
* delivery: a replay is the same bytes, and any other state is a change to apply.
|
|
12
13
|
*/
|
|
13
14
|
export declare function verifyDelivery(store: ChannelStore, request: Request): Promise<Result<ChannelWebhookEvent | null, ChannelConnectorError>>;
|
|
14
15
|
/**
|
package/dist/webhooks.js
CHANGED
|
@@ -7,12 +7,6 @@ import { ORDER_META_KEY, wooOrderSchema } from "./orders.js";
|
|
|
7
7
|
/** What every store is subscribed to: catalogue and stock changes, and every change to an order. */
|
|
8
8
|
export const WOO_WEBHOOK_TOPICS = ["product.created", "product.updated", "product.deleted", "order.updated"];
|
|
9
9
|
const id = z.union([z.number(), z.string()]).transform(String);
|
|
10
|
-
/** Fields of a delivery body that identify the change it reports. */
|
|
11
|
-
const deliveryBody = z.object({
|
|
12
|
-
id: id.optional(),
|
|
13
|
-
status: z.string().nullish(),
|
|
14
|
-
date_modified_gmt: z.string().nullish(),
|
|
15
|
-
});
|
|
16
10
|
function validSignature(secret, body, signature) {
|
|
17
11
|
if (!signature || !secret)
|
|
18
12
|
return false;
|
|
@@ -25,8 +19,9 @@ function validSignature(secret, body, signature) {
|
|
|
25
19
|
* (form body `webhook_id=N`, unsigned) is `Ok(null)`. Everything else must carry a valid signature.
|
|
26
20
|
*
|
|
27
21
|
* The id is ours: `X-WC-Webhook-Delivery-ID` hashes the subscription id and the current SECOND, so two
|
|
28
|
-
* deliveries in one second collide.
|
|
29
|
-
*
|
|
22
|
+
* deliveries in one second collide. So does `date_modified_gmt`, which is also to the second: two stock
|
|
23
|
+
* changes inside one second differ only in the stock. The topic and the whole signed body identify a
|
|
24
|
+
* delivery: a replay is the same bytes, and any other state is a change to apply.
|
|
30
25
|
*/
|
|
31
26
|
export async function verifyDelivery(store, request) {
|
|
32
27
|
const body = await request.text();
|
|
@@ -45,9 +40,7 @@ export async function verifyDelivery(store, request) {
|
|
|
45
40
|
catch {
|
|
46
41
|
return Err({ code: "INVALID_WEBHOOK", message: "A WooCommerce delivery body was not JSON.", retriable: false });
|
|
47
42
|
}
|
|
48
|
-
|
|
49
|
-
const change = fields.success ? [topic, fields.data.id ?? "", fields.data.status ?? "", fields.data.date_modified_gmt ?? ""] : [topic, body];
|
|
50
|
-
return Ok({ id: createHash("sha256").update(change.join("|")).digest("hex"), type: topic, data });
|
|
43
|
+
return Ok({ id: createHash("sha256").update(`${topic}|${body}`).digest("hex"), type: topic, data });
|
|
51
44
|
}
|
|
52
45
|
const variationNudge = z.object({ id, type: z.string().optional(), parent_id: id.nullish() });
|
|
53
46
|
/** A product delivery is a nudge: the product (and its stock) is read fresh. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@porulle/adapter-woocommerce",
|
|
3
|
-
"version": "0.74.
|
|
3
|
+
"version": "0.74.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"zod": "^4.1.11",
|
|
19
|
-
"@porulle/core": "0.74.
|
|
19
|
+
"@porulle/core": "0.74.4"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^24.5.2",
|
package/src/webhooks.ts
CHANGED
|
@@ -13,13 +13,6 @@ export const WOO_WEBHOOK_TOPICS = ["product.created", "product.updated", "produc
|
|
|
13
13
|
|
|
14
14
|
const id = z.union([z.number(), z.string()]).transform(String);
|
|
15
15
|
|
|
16
|
-
/** Fields of a delivery body that identify the change it reports. */
|
|
17
|
-
const deliveryBody = z.object({
|
|
18
|
-
id: id.optional(),
|
|
19
|
-
status: z.string().nullish(),
|
|
20
|
-
date_modified_gmt: z.string().nullish(),
|
|
21
|
-
});
|
|
22
|
-
|
|
23
16
|
function validSignature(secret: string, body: string, signature: string | null): boolean {
|
|
24
17
|
if (!signature || !secret) return false;
|
|
25
18
|
const expected = createHmac("sha256", secret).update(body, "utf8").digest();
|
|
@@ -32,8 +25,9 @@ function validSignature(secret: string, body: string, signature: string | null):
|
|
|
32
25
|
* (form body `webhook_id=N`, unsigned) is `Ok(null)`. Everything else must carry a valid signature.
|
|
33
26
|
*
|
|
34
27
|
* The id is ours: `X-WC-Webhook-Delivery-ID` hashes the subscription id and the current SECOND, so two
|
|
35
|
-
* deliveries in one second collide.
|
|
36
|
-
*
|
|
28
|
+
* deliveries in one second collide. So does `date_modified_gmt`, which is also to the second: two stock
|
|
29
|
+
* changes inside one second differ only in the stock. The topic and the whole signed body identify a
|
|
30
|
+
* delivery: a replay is the same bytes, and any other state is a change to apply.
|
|
37
31
|
*/
|
|
38
32
|
export async function verifyDelivery(store: ChannelStore, request: Request): Promise<Result<ChannelWebhookEvent | null, ChannelConnectorError>> {
|
|
39
33
|
const body = await request.text();
|
|
@@ -49,9 +43,7 @@ export async function verifyDelivery(store: ChannelStore, request: Request): Pro
|
|
|
49
43
|
} catch {
|
|
50
44
|
return Err({ code: "INVALID_WEBHOOK", message: "A WooCommerce delivery body was not JSON.", retriable: false });
|
|
51
45
|
}
|
|
52
|
-
|
|
53
|
-
const change = fields.success ? [topic, fields.data.id ?? "", fields.data.status ?? "", fields.data.date_modified_gmt ?? ""] : [topic, body];
|
|
54
|
-
return Ok({ id: createHash("sha256").update(change.join("|")).digest("hex"), type: topic, data });
|
|
46
|
+
return Ok({ id: createHash("sha256").update(`${topic}|${body}`).digest("hex"), type: topic, data });
|
|
55
47
|
}
|
|
56
48
|
|
|
57
49
|
const variationNudge = z.object({ id, type: z.string().optional(), parent_id: id.nullish() });
|