@algovoi/webhook-verifier 0.1.0 → 0.2.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/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +25 -0
- package/dist/index.mjs +24 -1
- package/package.json +47 -46
package/dist/index.d.mts
CHANGED
|
@@ -59,5 +59,7 @@ declare const KNOWN_EVENT_TYPES: ReadonlySet<string>;
|
|
|
59
59
|
* @throws {WebhookVerificationError} on any verification failure.
|
|
60
60
|
*/
|
|
61
61
|
declare function verifyWebhook(options: VerifyOptions): WebhookEvent;
|
|
62
|
+
declare function keystoneBlock(event: any): any;
|
|
63
|
+
declare function verifyKeystoneRef(event: any): boolean;
|
|
62
64
|
|
|
63
|
-
export { DEFAULT_TOLERANCE, ERROR_CODES, type ErrorCode, KNOWN_EVENT_TYPES, SIGNATURE_HEADER, type VerifyOptions, type WebhookEvent, WebhookVerificationError, verifyWebhook };
|
|
65
|
+
export { DEFAULT_TOLERANCE, ERROR_CODES, type ErrorCode, KNOWN_EVENT_TYPES, SIGNATURE_HEADER, type VerifyOptions, type WebhookEvent, WebhookVerificationError, keystoneBlock, verifyKeystoneRef, verifyWebhook };
|
package/dist/index.d.ts
CHANGED
|
@@ -59,5 +59,7 @@ declare const KNOWN_EVENT_TYPES: ReadonlySet<string>;
|
|
|
59
59
|
* @throws {WebhookVerificationError} on any verification failure.
|
|
60
60
|
*/
|
|
61
61
|
declare function verifyWebhook(options: VerifyOptions): WebhookEvent;
|
|
62
|
+
declare function keystoneBlock(event: any): any;
|
|
63
|
+
declare function verifyKeystoneRef(event: any): boolean;
|
|
62
64
|
|
|
63
|
-
export { DEFAULT_TOLERANCE, ERROR_CODES, type ErrorCode, KNOWN_EVENT_TYPES, SIGNATURE_HEADER, type VerifyOptions, type WebhookEvent, WebhookVerificationError, verifyWebhook };
|
|
65
|
+
export { DEFAULT_TOLERANCE, ERROR_CODES, type ErrorCode, KNOWN_EVENT_TYPES, SIGNATURE_HEADER, type VerifyOptions, type WebhookEvent, WebhookVerificationError, keystoneBlock, verifyKeystoneRef, verifyWebhook };
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,8 @@ __export(index_exports, {
|
|
|
25
25
|
KNOWN_EVENT_TYPES: () => KNOWN_EVENT_TYPES,
|
|
26
26
|
SIGNATURE_HEADER: () => SIGNATURE_HEADER,
|
|
27
27
|
WebhookVerificationError: () => WebhookVerificationError,
|
|
28
|
+
keystoneBlock: () => keystoneBlock,
|
|
29
|
+
verifyKeystoneRef: () => verifyKeystoneRef,
|
|
28
30
|
verifyWebhook: () => verifyWebhook
|
|
29
31
|
});
|
|
30
32
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -152,6 +154,27 @@ function verifyWebhook(options) {
|
|
|
152
154
|
}
|
|
153
155
|
return event;
|
|
154
156
|
}
|
|
157
|
+
function keystoneBlock(event) {
|
|
158
|
+
return event && typeof event.keystone === "object" && event.keystone ? event.keystone : event;
|
|
159
|
+
}
|
|
160
|
+
function verifyKeystoneRef(event) {
|
|
161
|
+
const k = keystoneBlock(event);
|
|
162
|
+
try {
|
|
163
|
+
const claimed = k.execution_ref;
|
|
164
|
+
const obj = {
|
|
165
|
+
action_type: k.action_type,
|
|
166
|
+
decision_ref: k.decision_ref,
|
|
167
|
+
executed_at_ms: Number(k.executed_at_ms),
|
|
168
|
+
outcome: k.outcome,
|
|
169
|
+
scope: k.scope
|
|
170
|
+
};
|
|
171
|
+
const s = "{" + Object.keys(obj).sort().map((kk) => JSON.stringify(kk) + ":" + JSON.stringify(obj[kk])).join(",") + "}";
|
|
172
|
+
const recomputed = "sha256:" + (0, import_crypto2.createHash)("sha256").update(s).digest("hex");
|
|
173
|
+
return recomputed === claimed;
|
|
174
|
+
} catch {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
155
178
|
// Annotate the CommonJS export names for ESM import in node:
|
|
156
179
|
0 && (module.exports = {
|
|
157
180
|
DEFAULT_TOLERANCE,
|
|
@@ -159,5 +182,7 @@ function verifyWebhook(options) {
|
|
|
159
182
|
KNOWN_EVENT_TYPES,
|
|
160
183
|
SIGNATURE_HEADER,
|
|
161
184
|
WebhookVerificationError,
|
|
185
|
+
keystoneBlock,
|
|
186
|
+
verifyKeystoneRef,
|
|
162
187
|
verifyWebhook
|
|
163
188
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
3
|
-
import { hkdfSync } from "crypto";
|
|
3
|
+
import { hkdfSync, createHash } from "crypto";
|
|
4
4
|
var ERROR_CODES = /* @__PURE__ */ new Set([
|
|
5
5
|
"MISSING_SIGNATURE",
|
|
6
6
|
"MALFORMED_SIGNATURE",
|
|
@@ -123,11 +123,34 @@ function verifyWebhook(options) {
|
|
|
123
123
|
}
|
|
124
124
|
return event;
|
|
125
125
|
}
|
|
126
|
+
function keystoneBlock(event) {
|
|
127
|
+
return event && typeof event.keystone === "object" && event.keystone ? event.keystone : event;
|
|
128
|
+
}
|
|
129
|
+
function verifyKeystoneRef(event) {
|
|
130
|
+
const k = keystoneBlock(event);
|
|
131
|
+
try {
|
|
132
|
+
const claimed = k.execution_ref;
|
|
133
|
+
const obj = {
|
|
134
|
+
action_type: k.action_type,
|
|
135
|
+
decision_ref: k.decision_ref,
|
|
136
|
+
executed_at_ms: Number(k.executed_at_ms),
|
|
137
|
+
outcome: k.outcome,
|
|
138
|
+
scope: k.scope
|
|
139
|
+
};
|
|
140
|
+
const s = "{" + Object.keys(obj).sort().map((kk) => JSON.stringify(kk) + ":" + JSON.stringify(obj[kk])).join(",") + "}";
|
|
141
|
+
const recomputed = "sha256:" + createHash("sha256").update(s).digest("hex");
|
|
142
|
+
return recomputed === claimed;
|
|
143
|
+
} catch {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
126
147
|
export {
|
|
127
148
|
DEFAULT_TOLERANCE,
|
|
128
149
|
ERROR_CODES,
|
|
129
150
|
KNOWN_EVENT_TYPES,
|
|
130
151
|
SIGNATURE_HEADER,
|
|
131
152
|
WebhookVerificationError,
|
|
153
|
+
keystoneBlock,
|
|
154
|
+
verifyKeystoneRef,
|
|
132
155
|
verifyWebhook
|
|
133
156
|
};
|
package/package.json
CHANGED
|
@@ -1,46 +1,47 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@algovoi/webhook-verifier",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Cryptographic verifier for AlgoVoi webhook signatures (v1 HMAC-SHA256 + v2 HKDF-SHA256/HMAC-SHA384)",
|
|
5
|
-
"license": "Apache-2.0",
|
|
6
|
-
"author": "AlgoVoi <dev@algovoi.co.uk>",
|
|
7
|
-
"homepage": "https://docs.algovoi.co.uk/webhook-verifier",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "https://github.com/chopmob-cloud/algovoi-webhook-verifier"
|
|
11
|
-
},
|
|
12
|
-
"main": "./dist/index.
|
|
13
|
-
"module": "./dist/index.
|
|
14
|
-
"types": "./dist/index.d.ts",
|
|
15
|
-
"exports": {
|
|
16
|
-
".": {
|
|
17
|
-
"import": "./dist/index.
|
|
18
|
-
"require": "./dist/index.
|
|
19
|
-
"types": "./dist/index.d.ts"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"files": [
|
|
23
|
-
"dist"
|
|
24
|
-
],
|
|
25
|
-
"keywords": [
|
|
26
|
-
"webhook",
|
|
27
|
-
"hmac",
|
|
28
|
-
"signature",
|
|
29
|
-
"verification",
|
|
30
|
-
"algovoi"
|
|
31
|
-
],
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">=18"
|
|
34
|
-
},
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@algovoi/webhook-verifier",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Cryptographic verifier for AlgoVoi webhook signatures (v1 HMAC-SHA256 + v2 HKDF-SHA256/HMAC-SHA384)",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "AlgoVoi <dev@algovoi.co.uk>",
|
|
7
|
+
"homepage": "https://docs.algovoi.co.uk/webhook-verifier",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/chopmob-cloud/algovoi-webhook-verifier"
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"module": "./dist/index.mjs",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"webhook",
|
|
27
|
+
"hmac",
|
|
28
|
+
"signature",
|
|
29
|
+
"verification",
|
|
30
|
+
"algovoi"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"typecheck": "tsc --noEmit"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^25.9.1",
|
|
43
|
+
"tsup": "^8.0.0",
|
|
44
|
+
"typescript": "^5.4.0",
|
|
45
|
+
"vitest": "^1.6.0"
|
|
46
|
+
}
|
|
47
|
+
}
|