@isnap/sdk 1.3.0-next.99 → 1.4.0-next.203
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/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/dist/client.d.ts +14 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +16 -3
- package/dist/client.js.map +1 -1
- package/dist/generated/openapi.d.ts +2474 -937
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/apps.d.ts +31 -0
- package/dist/resources/apps.d.ts.map +1 -0
- package/dist/resources/apps.js +29 -0
- package/dist/resources/apps.js.map +1 -0
- package/dist/resources/lines.d.ts +206 -6
- package/dist/resources/lines.d.ts.map +1 -1
- package/dist/resources/lines.js +215 -6
- package/dist/resources/lines.js.map +1 -1
- package/dist/resources/macos-sessions.d.ts +48 -0
- package/dist/resources/macos-sessions.d.ts.map +1 -0
- package/dist/resources/macos-sessions.js +51 -0
- package/dist/resources/macos-sessions.js.map +1 -0
- package/dist/resources/preorders.d.ts +31 -8
- package/dist/resources/preorders.d.ts.map +1 -1
- package/dist/resources/preorders.js +31 -8
- package/dist/resources/preorders.js.map +1 -1
- package/dist/resources/webhooks.d.ts +1 -1
- package/dist/resources/webhooks.js +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +13 -5
- package/dist/version.js.map +1 -1
- package/dist/webhooks/types.d.ts +46 -3
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/webhooks/types.js +3 -0
- package/dist/webhooks/types.js.map +1 -1
- package/dist/webhooks/verify.d.ts +22 -9
- package/dist/webhooks/verify.d.ts.map +1 -1
- package/dist/webhooks/verify.js +101 -29
- package/dist/webhooks/verify.js.map +1 -1
- package/package.json +1 -1
package/dist/webhooks/types.d.ts
CHANGED
|
@@ -27,6 +27,18 @@ type ReactionEventDataBase = {
|
|
|
27
27
|
reaction_id: string;
|
|
28
28
|
reaction_type: ReactionType;
|
|
29
29
|
reaction_emoji: string | null;
|
|
30
|
+
/**
|
|
31
|
+
* The `line_<base62>` publicId of the line the tapback happened on, and the
|
|
32
|
+
* routing key a consumer should prefer (WHA-3183). It is the line of the
|
|
33
|
+
* PARENT message — for a shared-plan parent the customer's virtual line, never
|
|
34
|
+
* the physical pool carrier the reporting session runs on.
|
|
35
|
+
*
|
|
36
|
+
* REQUIRED, not optional: both producers resolve it before they enqueue, and a
|
|
37
|
+
* consumer that has not persisted the parent has no other handle on the
|
|
38
|
+
* delivery. Declaring it optional would let that consumer compile against a
|
|
39
|
+
* payload it cannot route.
|
|
40
|
+
*/
|
|
41
|
+
line_id: string;
|
|
30
42
|
removed_at?: string;
|
|
31
43
|
};
|
|
32
44
|
/**
|
|
@@ -65,7 +77,7 @@ export interface ReactionEvent extends WebhookEventBase {
|
|
|
65
77
|
event_type: `reaction.${string}`;
|
|
66
78
|
data: ReactionEventData;
|
|
67
79
|
}
|
|
68
|
-
export type LineEventType = 'line.connected' | 'line.disconnected' | 'line.offline' | 'line.degraded' | 'line.apple_id_flagged' | 'line.quota_warning' | 'line.quota_exceeded' | 'line.capability_changed';
|
|
80
|
+
export type LineEventType = 'line.connected' | 'line.disconnected' | 'line.offline' | 'line.degraded' | 'line.apple_id_flagged' | 'line.quota_warning' | 'line.quota_exceeded' | 'line.capability_changed' | 'line.terminated' | 'line.variant_changed' | 'line.variant_scheduled' | 'line.variant_unscheduled';
|
|
69
81
|
/**
|
|
70
82
|
* `data` is intentionally typed as `Record<string, unknown>` until the
|
|
71
83
|
* contract pins per-event-type field shapes. Today's payloads vary by
|
|
@@ -95,7 +107,7 @@ export interface TrialEvent extends WebhookEventBase {
|
|
|
95
107
|
event_type: `trial.${string}`;
|
|
96
108
|
data: Record<string, unknown>;
|
|
97
109
|
}
|
|
98
|
-
export type PreOrderEventType = 'pre_order.fulfilled' | 'pre_order.cancelled'
|
|
110
|
+
export type PreOrderEventType = 'pre_order.fulfilled' | 'pre_order.cancelled';
|
|
99
111
|
/**
|
|
100
112
|
* Pre-order lifecycle events fired when ops procures hardware against a
|
|
101
113
|
* customer pre-order. `pre_order.fulfilled` carries the freshly-activated
|
|
@@ -127,6 +139,36 @@ export interface BindingEvent extends WebhookEventBase {
|
|
|
127
139
|
event_type: `binding.${string}`;
|
|
128
140
|
data: Record<string, unknown>;
|
|
129
141
|
}
|
|
142
|
+
export type MacosSessionEventType = 'macos_session.rented' | 'macos_session.released';
|
|
143
|
+
/**
|
|
144
|
+
* Rented hosted macOS session lifecycle (contract §4.3.8). Fires on the
|
|
145
|
+
* PARTNER, never on a line, and only for the two changes the partner did
|
|
146
|
+
* NOT just cause — `rent`, `cancel` and `uncancel` are synchronous verbs
|
|
147
|
+
* whose own response already told the caller what happened.
|
|
148
|
+
*
|
|
149
|
+
* `macos_session.rented` is iSnap attaching a session OUT OF BAND: the
|
|
150
|
+
* fulfilment of a `rent` refused for want of stock, or the migration of a
|
|
151
|
+
* tenancy that predates the surface. `data` carries
|
|
152
|
+
* `{ macos_session_id, anniversary_at, rented_at }`.
|
|
153
|
+
*
|
|
154
|
+
* `macos_session.released` is the seat going back to stock. `data` carries
|
|
155
|
+
* `{ macos_session_id, anniversary_at (nullable), cancel_at (nullable),
|
|
156
|
+
* released_at, reason: 'cancelled' | 'detached_by_admin' }` — `reason`
|
|
157
|
+
* separating the cancellation coming due from an operator handing the
|
|
158
|
+
* session back.
|
|
159
|
+
*
|
|
160
|
+
* Routed by ACCOUNT, not by line: a rented session has no line by
|
|
161
|
+
* construction, so there is no `line_id` on this payload.
|
|
162
|
+
*
|
|
163
|
+
* Left as `Record<string, unknown>` for the same reason as `LineEvent`:
|
|
164
|
+
* `event_type` is the template literal `macos_session.${string}` so the
|
|
165
|
+
* guard keeps prefix-matching, and a concrete `data` shape here would
|
|
166
|
+
* mistype any future `macos_session.*` event.
|
|
167
|
+
*/
|
|
168
|
+
export interface MacosSessionEvent extends WebhookEventBase {
|
|
169
|
+
event_type: `macos_session.${string}`;
|
|
170
|
+
data: Record<string, unknown>;
|
|
171
|
+
}
|
|
130
172
|
/**
|
|
131
173
|
* Administrative synthetic probe — the suspended-state health check that
|
|
132
174
|
* decides whether a disabled subscription can be resumed. Not a partner
|
|
@@ -159,7 +201,7 @@ export interface AdminEvent extends WebhookEventBase {
|
|
|
159
201
|
* }
|
|
160
202
|
* ```
|
|
161
203
|
*/
|
|
162
|
-
export type WebhookEvent = MessageEvent | ReactionEvent | LineEvent | TypingIndicatorEvent | TrialEvent | PreOrderEvent | BindingEvent | AdminEvent | WebhookEventBase;
|
|
204
|
+
export type WebhookEvent = MessageEvent | ReactionEvent | LineEvent | TypingIndicatorEvent | TrialEvent | PreOrderEvent | BindingEvent | MacosSessionEvent | AdminEvent | WebhookEventBase;
|
|
163
205
|
export declare function isMessageEvent(event: WebhookEventBase): event is MessageEvent;
|
|
164
206
|
export declare function isReactionEvent(event: WebhookEventBase): event is ReactionEvent;
|
|
165
207
|
export declare function isLineEvent(event: WebhookEventBase): event is LineEvent;
|
|
@@ -167,6 +209,7 @@ export declare function isTypingIndicatorEvent(event: WebhookEventBase): event i
|
|
|
167
209
|
export declare function isTrialEvent(event: WebhookEventBase): event is TrialEvent;
|
|
168
210
|
export declare function isPreOrderEvent(event: WebhookEventBase): event is PreOrderEvent;
|
|
169
211
|
export declare function isBindingEvent(event: WebhookEventBase): event is BindingEvent;
|
|
212
|
+
export declare function isMacosSessionEvent(event: WebhookEventBase): event is MacosSessionEvent;
|
|
170
213
|
export declare function isAdminEvent(event: WebhookEventBase): event is AdminEvent;
|
|
171
214
|
export {};
|
|
172
215
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/webhooks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAErE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AA0BD,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,mBAAmB,GACnB,cAAc,GACd,mBAAmB,GACnB,gBAAgB,GAChB,kBAAkB,GAClB,cAAc,GACd,mBAAmB,GAMnB,4BAA4B,CAAA;AAEhC,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,UAAU,EAAE,WAAW,MAAM,EAAE,CAAA;IAC/B,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;CAC3B;AAID,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,CAAA;AAEtB,wEAAwE;AACxE,KAAK,qBAAqB,GAAG;IAC3B,iBAAiB,EAAE,MAAM,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,YAAY,CAAA;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,iBAAiB,GACzB,CAAC,qBAAqB,GAAG;IACvB,SAAS,EAAE,SAAS,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC,GACF,CAAC,qBAAqB,GAAG;IACvB,SAAS,EAAE,UAAU,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAC,CAAA;AAEN,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,UAAU,EAAE,YAAY,MAAM,EAAE,CAAA;IAChC,IAAI,EAAE,iBAAiB,CAAA;CACxB;AAID,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,mBAAmB,GACnB,cAAc,GACd,eAAe,GACf,uBAAuB,GACvB,oBAAoB,GACpB,qBAAqB,GAMrB,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/webhooks/types.ts"],"names":[],"mappings":"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"}
|
package/dist/webhooks/types.js
CHANGED
|
@@ -20,6 +20,9 @@ export function isPreOrderEvent(event) {
|
|
|
20
20
|
export function isBindingEvent(event) {
|
|
21
21
|
return event.event_type.startsWith('binding.');
|
|
22
22
|
}
|
|
23
|
+
export function isMacosSessionEvent(event) {
|
|
24
|
+
return event.event_type.startsWith('macos_session.');
|
|
25
|
+
}
|
|
23
26
|
export function isAdminEvent(event) {
|
|
24
27
|
return event.event_type.startsWith('webhook.');
|
|
25
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/webhooks/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/webhooks/types.ts"],"names":[],"mappings":"AAyWA,6EAA6E;AAE7E,MAAM,UAAU,cAAc,CAAC,KAAuB;IACpD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAuB;IACrD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAAuB;IAEvB,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAA;AACzD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAuB;IAClD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAuB;IACrD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAuB;IACpD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAuB;IACzD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAuB;IAClD,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAChD,CAAC"}
|
|
@@ -13,12 +13,23 @@ export interface VerifyWebhookOptions {
|
|
|
13
13
|
*/
|
|
14
14
|
now?: () => number;
|
|
15
15
|
}
|
|
16
|
+
type WebhookHeaders = Record<string, string | string[] | undefined> | Headers;
|
|
16
17
|
/**
|
|
17
|
-
* Verify an incoming webhook delivery
|
|
18
|
+
* Verify an incoming webhook delivery. Every iSnap delivery carries two
|
|
19
|
+
* signatures over the same body, and this checks one of them:
|
|
18
20
|
*
|
|
19
|
-
* -
|
|
20
|
-
* `
|
|
21
|
-
*
|
|
21
|
+
* - **Standard Webhooks** (https://www.standardwebhooks.com), checked
|
|
22
|
+
* whenever a `webhook-signature` header is present: `webhook-id`,
|
|
23
|
+
* `webhook-timestamp`, and `webhook-signature` carrying `v1,` + base64
|
|
24
|
+
* `HMAC-SHA256(key, "<webhook-id>.<webhook-timestamp>.<rawBody>")`,
|
|
25
|
+
* where the key is the base64 decoding of the secret without its
|
|
26
|
+
* `whsec_` (or legacy `whs_`) prefix.
|
|
27
|
+
* - **The iSnap scheme**, the fallback when there is no
|
|
28
|
+
* `webhook-signature`: `X-iSnap-Signature` carries the hex-encoded
|
|
29
|
+
* `HMAC-SHA256(secret, "<timestamp>.<rawBody>")` and `X-iSnap-Timestamp`
|
|
30
|
+
* the unix-second issuance time.
|
|
31
|
+
*
|
|
32
|
+
* Both paths take the secret string exactly as the dashboard shows it.
|
|
22
33
|
*
|
|
23
34
|
* Throws `WebhookSignatureError` on missing headers, malformed
|
|
24
35
|
* timestamp, expired timestamp (outside `tolerance`), or signature
|
|
@@ -32,10 +43,12 @@ export interface VerifyWebhookOptions {
|
|
|
32
43
|
* Headers may be a `Record<string, string>` (e.g. Express's `req.headers`)
|
|
33
44
|
* or a `Headers` instance — both are read case-insensitively.
|
|
34
45
|
*
|
|
35
|
-
* **Consumers MUST dedupe by `event.event_id`**
|
|
36
|
-
* envelope (same `event_id`, same body,
|
|
37
|
-
* timestamp). Without consumer-side dedup, an
|
|
38
|
-
* model produces duplicate side-effects on the
|
|
46
|
+
* **Consumers MUST dedupe by `event.event_id`** (also sent as `webhook-id`)
|
|
47
|
+
* — retries replay the same envelope (same `event_id`, same body,
|
|
48
|
+
* refreshed timestamp and signatures). Without consumer-side dedup, an
|
|
49
|
+
* at-least-once delivery model produces duplicate side-effects on the
|
|
50
|
+
* partner system.
|
|
39
51
|
*/
|
|
40
|
-
export declare function verifyWebhook(rawBody: string, headers:
|
|
52
|
+
export declare function verifyWebhook(rawBody: string, headers: WebhookHeaders, secret: string | readonly string[], options?: VerifyWebhookOptions): WebhookEventBase;
|
|
53
|
+
export {};
|
|
41
54
|
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/webhooks/verify.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAIlD,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/webhooks/verify.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAIlD,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,OAAO,CAAA;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAClC,OAAO,GAAE,oBAAyB,GACjC,gBAAgB,CAKlB"}
|
package/dist/webhooks/verify.js
CHANGED
|
@@ -3,11 +3,21 @@ import { WebhookSignatureError } from '../errors.js';
|
|
|
3
3
|
import { parseWebhookEvent } from './parse.js';
|
|
4
4
|
const DEFAULT_TOLERANCE_SECONDS = 300;
|
|
5
5
|
/**
|
|
6
|
-
* Verify an incoming webhook delivery
|
|
6
|
+
* Verify an incoming webhook delivery. Every iSnap delivery carries two
|
|
7
|
+
* signatures over the same body, and this checks one of them:
|
|
7
8
|
*
|
|
8
|
-
* -
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
9
|
+
* - **Standard Webhooks** (https://www.standardwebhooks.com), checked
|
|
10
|
+
* whenever a `webhook-signature` header is present: `webhook-id`,
|
|
11
|
+
* `webhook-timestamp`, and `webhook-signature` carrying `v1,` + base64
|
|
12
|
+
* `HMAC-SHA256(key, "<webhook-id>.<webhook-timestamp>.<rawBody>")`,
|
|
13
|
+
* where the key is the base64 decoding of the secret without its
|
|
14
|
+
* `whsec_` (or legacy `whs_`) prefix.
|
|
15
|
+
* - **The iSnap scheme**, the fallback when there is no
|
|
16
|
+
* `webhook-signature`: `X-iSnap-Signature` carries the hex-encoded
|
|
17
|
+
* `HMAC-SHA256(secret, "<timestamp>.<rawBody>")` and `X-iSnap-Timestamp`
|
|
18
|
+
* the unix-second issuance time.
|
|
19
|
+
*
|
|
20
|
+
* Both paths take the secret string exactly as the dashboard shows it.
|
|
11
21
|
*
|
|
12
22
|
* Throws `WebhookSignatureError` on missing headers, malformed
|
|
13
23
|
* timestamp, expired timestamp (outside `tolerance`), or signature
|
|
@@ -21,12 +31,19 @@ const DEFAULT_TOLERANCE_SECONDS = 300;
|
|
|
21
31
|
* Headers may be a `Record<string, string>` (e.g. Express's `req.headers`)
|
|
22
32
|
* or a `Headers` instance — both are read case-insensitively.
|
|
23
33
|
*
|
|
24
|
-
* **Consumers MUST dedupe by `event.event_id`**
|
|
25
|
-
* envelope (same `event_id`, same body,
|
|
26
|
-
* timestamp). Without consumer-side dedup, an
|
|
27
|
-
* model produces duplicate side-effects on the
|
|
34
|
+
* **Consumers MUST dedupe by `event.event_id`** (also sent as `webhook-id`)
|
|
35
|
+
* — retries replay the same envelope (same `event_id`, same body,
|
|
36
|
+
* refreshed timestamp and signatures). Without consumer-side dedup, an
|
|
37
|
+
* at-least-once delivery model produces duplicate side-effects on the
|
|
38
|
+
* partner system.
|
|
28
39
|
*/
|
|
29
40
|
export function verifyWebhook(rawBody, headers, secret, options = {}) {
|
|
41
|
+
if (getHeader(headers, 'webhook-signature') !== null) {
|
|
42
|
+
return verifyStandardWebhook(rawBody, headers, secret, options);
|
|
43
|
+
}
|
|
44
|
+
return verifyISnapWebhook(rawBody, headers, secret, options);
|
|
45
|
+
}
|
|
46
|
+
function verifyISnapWebhook(rawBody, headers, secret, options) {
|
|
30
47
|
const sigHeader = getHeader(headers, 'x-isnap-signature');
|
|
31
48
|
if (!sigHeader) {
|
|
32
49
|
throw new WebhookSignatureError('Missing X-iSnap-Signature header');
|
|
@@ -35,16 +52,86 @@ export function verifyWebhook(rawBody, headers, secret, options = {}) {
|
|
|
35
52
|
if (!tsHeader) {
|
|
36
53
|
throw new WebhookSignatureError('Missing X-iSnap-Timestamp header');
|
|
37
54
|
}
|
|
55
|
+
const timestamp = checkTimestamp(tsHeader, 'X-iSnap-Timestamp', options);
|
|
56
|
+
const candidates = secretCandidates(secret);
|
|
57
|
+
const provided = decodeHex(sigHeader);
|
|
58
|
+
if (!provided) {
|
|
59
|
+
throw new WebhookSignatureError('X-iSnap-Signature is not valid hex');
|
|
60
|
+
}
|
|
61
|
+
const signedPayload = `${timestamp}.${rawBody}`;
|
|
62
|
+
// Multi-secret loop returns early on first match — this is a minor
|
|
63
|
+
// timing side-channel during the rotate-secret grace window (an
|
|
64
|
+
// attacker who controls request timing could distinguish "matched first
|
|
65
|
+
// candidate" from "matched second"). Practical exploit value is near
|
|
66
|
+
// zero: knowing which secret matched does not help forge signatures
|
|
67
|
+
// for either secret. Worth revisiting if real partners run rotation
|
|
68
|
+
// through hostile networks.
|
|
69
|
+
for (const candidate of candidates) {
|
|
70
|
+
const expected = createHmac('sha256', candidate).update(signedPayload).digest();
|
|
71
|
+
if (provided.length === expected.length && timingSafeEqual(provided, expected)) {
|
|
72
|
+
return parseWebhookEvent(rawBody);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
throw new WebhookSignatureError('Webhook signature did not match any provided secret');
|
|
76
|
+
}
|
|
77
|
+
function verifyStandardWebhook(rawBody, headers, secret, options) {
|
|
78
|
+
const msgId = getHeader(headers, 'webhook-id');
|
|
79
|
+
if (!msgId) {
|
|
80
|
+
throw new WebhookSignatureError('Missing webhook-id header');
|
|
81
|
+
}
|
|
82
|
+
const tsHeader = getHeader(headers, 'webhook-timestamp');
|
|
83
|
+
if (!tsHeader) {
|
|
84
|
+
throw new WebhookSignatureError('Missing webhook-timestamp header');
|
|
85
|
+
}
|
|
86
|
+
const timestamp = checkTimestamp(tsHeader, 'webhook-timestamp', options);
|
|
87
|
+
const candidates = secretCandidates(secret);
|
|
88
|
+
// Space-delimited `<version>,<base64>` pairs; only `v1` (HMAC-SHA256)
|
|
89
|
+
// exists today, and a version this SDK does not know is skipped rather
|
|
90
|
+
// than rejected, so a sender adding a scheme does not break verification.
|
|
91
|
+
const provided = (getHeader(headers, 'webhook-signature') ?? '')
|
|
92
|
+
.split(' ')
|
|
93
|
+
.filter((entry) => entry.startsWith('v1,'))
|
|
94
|
+
.map((entry) => Buffer.from(entry.slice(3), 'base64'));
|
|
95
|
+
if (provided.length === 0) {
|
|
96
|
+
throw new WebhookSignatureError('webhook-signature carries no v1 signature');
|
|
97
|
+
}
|
|
98
|
+
const signedPayload = `${msgId}.${timestamp}.${rawBody}`;
|
|
99
|
+
// Same early-return trade-off as the iSnap scheme above.
|
|
100
|
+
for (const candidate of candidates) {
|
|
101
|
+
const expected = createHmac('sha256', standardWebhookKey(candidate))
|
|
102
|
+
.update(signedPayload)
|
|
103
|
+
.digest();
|
|
104
|
+
for (const signature of provided) {
|
|
105
|
+
if (signature.length === expected.length && timingSafeEqual(signature, expected)) {
|
|
106
|
+
return parseWebhookEvent(rawBody);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
throw new WebhookSignatureError('Webhook signature did not match any provided secret');
|
|
111
|
+
}
|
|
112
|
+
// The Standard Webhooks key: the base64 decoding of the secret without its
|
|
113
|
+
// prefix. iSnap secrets are `whsec_` (or, minted by an older rotation,
|
|
114
|
+
// `whs_`) followed by hex, which is valid base64, so the dashboard string
|
|
115
|
+
// works as-is here and in any official Standard Webhooks library (pass a
|
|
116
|
+
// `whs_` secret to those as `whsec_` + the same hex).
|
|
117
|
+
function standardWebhookKey(secret) {
|
|
118
|
+
for (const prefix of ['whsec_', 'whs_']) {
|
|
119
|
+
if (secret.startsWith(prefix))
|
|
120
|
+
return Buffer.from(secret.slice(prefix.length), 'base64');
|
|
121
|
+
}
|
|
122
|
+
return Buffer.from(secret, 'base64');
|
|
123
|
+
}
|
|
124
|
+
function checkTimestamp(tsHeader, headerName, options) {
|
|
38
125
|
// Strict integer-only check — `Number.parseInt` would happily accept
|
|
39
126
|
// `"1714478400foo"` and silently truncate. The HMAC compare downstream
|
|
40
127
|
// catches the resulting payload mismatch, but rejecting earlier here
|
|
41
128
|
// surfaces a clearer error and avoids one unnecessary HMAC computation.
|
|
42
129
|
if (!/^\d+$/.test(tsHeader)) {
|
|
43
|
-
throw new WebhookSignatureError(`Malformed
|
|
130
|
+
throw new WebhookSignatureError(`Malformed ${headerName}: ${tsHeader}`);
|
|
44
131
|
}
|
|
45
132
|
const timestamp = Number(tsHeader);
|
|
46
133
|
if (!Number.isFinite(timestamp) || timestamp <= 0) {
|
|
47
|
-
throw new WebhookSignatureError(`Malformed
|
|
134
|
+
throw new WebhookSignatureError(`Malformed ${headerName}: ${tsHeader}`);
|
|
48
135
|
}
|
|
49
136
|
const tolerance = options.tolerance ?? DEFAULT_TOLERANCE_SECONDS;
|
|
50
137
|
// Validate before use — `Math.abs(...) > NaN` is always false (so the
|
|
@@ -59,29 +146,14 @@ export function verifyWebhook(rawBody, headers, secret, options = {}) {
|
|
|
59
146
|
if (Math.abs(nowSec - timestamp) > tolerance) {
|
|
60
147
|
throw new WebhookSignatureError(`Webhook timestamp is outside the ${tolerance}s tolerance window (drift: ${nowSec - timestamp}s)`);
|
|
61
148
|
}
|
|
149
|
+
return timestamp;
|
|
150
|
+
}
|
|
151
|
+
function secretCandidates(secret) {
|
|
62
152
|
const candidates = typeof secret === 'string' ? [secret] : secret;
|
|
63
153
|
if (candidates.length === 0) {
|
|
64
154
|
throw new WebhookSignatureError('No webhook secret(s) provided');
|
|
65
155
|
}
|
|
66
|
-
|
|
67
|
-
if (!provided) {
|
|
68
|
-
throw new WebhookSignatureError('X-iSnap-Signature is not valid hex');
|
|
69
|
-
}
|
|
70
|
-
const signedPayload = `${timestamp}.${rawBody}`;
|
|
71
|
-
// Multi-secret loop returns early on first match — this is a minor
|
|
72
|
-
// timing side-channel during the rotate-secret grace window (an
|
|
73
|
-
// attacker who controls request timing could distinguish "matched first
|
|
74
|
-
// candidate" from "matched second"). Practical exploit value is near
|
|
75
|
-
// zero: knowing which secret matched does not help forge signatures
|
|
76
|
-
// for either secret. Worth revisiting if real partners run rotation
|
|
77
|
-
// through hostile networks.
|
|
78
|
-
for (const candidate of candidates) {
|
|
79
|
-
const expected = createHmac('sha256', candidate).update(signedPayload).digest();
|
|
80
|
-
if (provided.length === expected.length && timingSafeEqual(provided, expected)) {
|
|
81
|
-
return parseWebhookEvent(rawBody);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
throw new WebhookSignatureError('Webhook signature did not match any provided secret');
|
|
156
|
+
return candidates;
|
|
85
157
|
}
|
|
86
158
|
function getHeader(headers, name) {
|
|
87
159
|
if (typeof Headers !== 'undefined' && headers instanceof Headers) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/webhooks/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG9C,MAAM,yBAAyB,GAAG,GAAG,CAAA;
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/webhooks/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG9C,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAmBrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,OAAuB,EACvB,MAAkC,EAClC,UAAgC,EAAE;IAElC,IAAI,SAAS,CAAC,OAAO,EAAE,mBAAmB,CAAC,KAAK,IAAI,EAAE,CAAC;QACrD,OAAO,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACjE,CAAC;IACD,OAAO,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AAC9D,CAAC;AAED,SAAS,kBAAkB,CACzB,OAAe,EACf,OAAuB,EACvB,MAAkC,EAClC,OAA6B;IAE7B,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAA;IACzD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,qBAAqB,CAAC,kCAAkC,CAAC,CAAA;IACrE,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAA;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,qBAAqB,CAAC,kCAAkC,CAAC,CAAA;IACrE,CAAC;IACD,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAA;IACxE,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAE3C,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,qBAAqB,CAAC,oCAAoC,CAAC,CAAA;IACvE,CAAC;IACD,MAAM,aAAa,GAAG,GAAG,SAAS,IAAI,OAAO,EAAE,CAAA;IAC/C,mEAAmE;IACnE,gEAAgE;IAChE,wEAAwE;IACxE,qEAAqE;IACrE,oEAAoE;IACpE,oEAAoE;IACpE,4BAA4B;IAC5B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,CAAA;QAC/E,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC/E,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IACD,MAAM,IAAI,qBAAqB,CAAC,qDAAqD,CAAC,CAAA;AACxF,CAAC;AAED,SAAS,qBAAqB,CAC5B,OAAe,EACf,OAAuB,EACvB,MAAkC,EAClC,OAA6B;IAE7B,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,qBAAqB,CAAC,2BAA2B,CAAC,CAAA;IAC9D,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAA;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,qBAAqB,CAAC,kCAAkC,CAAC,CAAA;IACrE,CAAC;IACD,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAA;IACxE,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAE3C,sEAAsE;IACtE,uEAAuE;IACvE,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC;SAC7D,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;SAC1C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;IACxD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,qBAAqB,CAAC,2CAA2C,CAAC,CAAA;IAC9E,CAAC;IACD,MAAM,aAAa,GAAG,GAAG,KAAK,IAAI,SAAS,IAAI,OAAO,EAAE,CAAA;IACxD,yDAAyD;IACzD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;aACjE,MAAM,CAAC,aAAa,CAAC;aACrB,MAAM,EAAE,CAAA;QACX,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;YACjC,IAAI,SAAS,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACjF,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAA;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,qBAAqB,CAAC,qDAAqD,CAAC,CAAA;AACxF,CAAC;AAED,2EAA2E;AAC3E,uEAAuE;AACvE,0EAA0E;AAC1E,yEAAyE;AACzE,sDAAsD;AACtD,SAAS,kBAAkB,CAAC,MAAc;IACxC,KAAK,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;QACxC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC1F,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AACtC,CAAC;AAED,SAAS,cAAc,CACrB,QAAgB,EAChB,UAAkB,EAClB,OAA6B;IAE7B,qEAAqE;IACrE,uEAAuE;IACvE,qEAAqE;IACrE,wEAAwE;IACxE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,qBAAqB,CAAC,aAAa,UAAU,KAAK,QAAQ,EAAE,CAAC,CAAA;IACzE,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,qBAAqB,CAAC,aAAa,UAAU,KAAK,QAAQ,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,yBAAyB,CAAA;IAChE,sEAAsE;IACtE,oEAAoE;IACpE,qEAAqE;IACrE,mEAAmE;IACnE,mEAAmE;IACnE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,qBAAqB,CAC7B,uDAAuD,MAAM,CAAC,SAAS,CAAC,GAAG,CAC5E,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAA;IAC5C,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,EAAE,CAAC;QAC7C,MAAM,IAAI,qBAAqB,CAC7B,oCAAoC,SAAS,8BAA8B,MAAM,GAAG,SAAS,IAAI,CAClG,CAAA;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAkC;IAC1D,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IACjE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,qBAAqB,CAAC,+BAA+B,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,SAAS,SAAS,CAAC,OAAuB,EAAE,IAAY;IACtD,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;QACjE,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,KAAK;YAAE,SAAQ;QACzC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;QACjD,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QAC3C,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACpE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AAChC,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;AACtC,CAAC"}
|