orb-billing 2.1.2 → 2.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/CHANGELOG.md +22 -0
- package/README.md +29 -0
- package/index.d.mts +8 -1
- package/index.d.ts +8 -1
- package/index.d.ts.map +1 -1
- package/index.js +5 -1
- package/index.js.map +1 -1
- package/index.mjs +5 -1
- package/index.mjs.map +1 -1
- package/package.json +2 -3
- package/resources/customers/credits/ledger.d.ts +4 -4
- package/resources/index.d.ts +1 -0
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js +3 -1
- package/resources/index.js.map +1 -1
- package/resources/index.mjs +1 -0
- package/resources/index.mjs.map +1 -1
- package/resources/invoices.d.ts +2 -0
- package/resources/invoices.d.ts.map +1 -1
- package/resources/invoices.js.map +1 -1
- package/resources/invoices.mjs.map +1 -1
- package/resources/prices/prices.d.ts +147 -2
- package/resources/prices/prices.d.ts.map +1 -1
- package/resources/prices/prices.js.map +1 -1
- package/resources/prices/prices.mjs.map +1 -1
- package/resources/subscriptions.d.ts +44 -1
- package/resources/subscriptions.d.ts.map +1 -1
- package/resources/subscriptions.js.map +1 -1
- package/resources/subscriptions.mjs.map +1 -1
- package/resources/webhooks.d.ts +24 -0
- package/resources/webhooks.d.ts.map +1 -0
- package/resources/webhooks.js +108 -0
- package/resources/webhooks.js.map +1 -0
- package/resources/webhooks.mjs +104 -0
- package/resources/webhooks.mjs.map +1 -0
- package/src/index.ts +11 -0
- package/src/resources/customers/credits/ledger.ts +4 -4
- package/src/resources/index.ts +1 -0
- package/src/resources/invoices.ts +4 -0
- package/src/resources/prices/prices.ts +209 -0
- package/src/resources/subscriptions.ts +55 -0
- package/src/resources/webhooks.ts +140 -0
- package/src/version.ts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/src/resources/index.ts
CHANGED
|
@@ -273,6 +273,8 @@ export interface Invoice {
|
|
|
273
273
|
*/
|
|
274
274
|
invoice_pdf: string | null;
|
|
275
275
|
|
|
276
|
+
invoice_source: 'subscription' | 'partial' | 'one_off';
|
|
277
|
+
|
|
276
278
|
/**
|
|
277
279
|
* If the invoice failed to issue, this will be the last time it failed to issue
|
|
278
280
|
* (even if it is now in a different state.)
|
|
@@ -1353,6 +1355,8 @@ export interface InvoiceFetchUpcomingResponse {
|
|
|
1353
1355
|
*/
|
|
1354
1356
|
invoice_pdf: string | null;
|
|
1355
1357
|
|
|
1358
|
+
invoice_source: 'subscription' | 'partial' | 'one_off';
|
|
1359
|
+
|
|
1356
1360
|
/**
|
|
1357
1361
|
* If the invoice failed to issue, this will be the last time it failed to issue
|
|
1358
1362
|
* (even if it is now in a different state.)
|
|
@@ -297,7 +297,9 @@ export type Price =
|
|
|
297
297
|
| Price.BulkPrice
|
|
298
298
|
| Price.ThresholdTotalAmountPrice
|
|
299
299
|
| Price.TieredPackagePrice
|
|
300
|
+
| Price.GroupedTieredPrice
|
|
300
301
|
| Price.TieredWithMinimumPrice
|
|
302
|
+
| Price.TieredPackageWithMinimumPrice
|
|
301
303
|
| Price.PackageWithAllocationPrice
|
|
302
304
|
| Price.UnitWithPercentPrice
|
|
303
305
|
| Price.MatrixWithAllocationPrice;
|
|
@@ -1234,6 +1236,82 @@ export namespace Price {
|
|
|
1234
1236
|
}
|
|
1235
1237
|
}
|
|
1236
1238
|
|
|
1239
|
+
export interface GroupedTieredPrice {
|
|
1240
|
+
id: string;
|
|
1241
|
+
|
|
1242
|
+
billable_metric: GroupedTieredPrice.BillableMetric | null;
|
|
1243
|
+
|
|
1244
|
+
cadence: 'one_time' | 'monthly' | 'quarterly' | 'annual';
|
|
1245
|
+
|
|
1246
|
+
created_at: string;
|
|
1247
|
+
|
|
1248
|
+
currency: string;
|
|
1249
|
+
|
|
1250
|
+
discount: Shared.Discount | null;
|
|
1251
|
+
|
|
1252
|
+
external_price_id: string | null;
|
|
1253
|
+
|
|
1254
|
+
fixed_price_quantity: number | null;
|
|
1255
|
+
|
|
1256
|
+
grouped_tiered_config: Record<string, unknown>;
|
|
1257
|
+
|
|
1258
|
+
item: GroupedTieredPrice.Item;
|
|
1259
|
+
|
|
1260
|
+
maximum: GroupedTieredPrice.Maximum | null;
|
|
1261
|
+
|
|
1262
|
+
maximum_amount: string | null;
|
|
1263
|
+
|
|
1264
|
+
minimum: GroupedTieredPrice.Minimum | null;
|
|
1265
|
+
|
|
1266
|
+
minimum_amount: string | null;
|
|
1267
|
+
|
|
1268
|
+
model_type: 'grouped_tiered';
|
|
1269
|
+
|
|
1270
|
+
name: string;
|
|
1271
|
+
|
|
1272
|
+
plan_phase_order: number | null;
|
|
1273
|
+
|
|
1274
|
+
price_type: 'usage_price' | 'fixed_price';
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
export namespace GroupedTieredPrice {
|
|
1278
|
+
export interface BillableMetric {
|
|
1279
|
+
id: string;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
export interface Item {
|
|
1283
|
+
id: string;
|
|
1284
|
+
|
|
1285
|
+
name: string;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
export interface Maximum {
|
|
1289
|
+
/**
|
|
1290
|
+
* List of price_ids that this maximum amount applies to. For plan/plan phase
|
|
1291
|
+
* maximums, this can be a subset of prices.
|
|
1292
|
+
*/
|
|
1293
|
+
applies_to_price_ids: Array<string>;
|
|
1294
|
+
|
|
1295
|
+
/**
|
|
1296
|
+
* Maximum amount applied
|
|
1297
|
+
*/
|
|
1298
|
+
maximum_amount: string;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
export interface Minimum {
|
|
1302
|
+
/**
|
|
1303
|
+
* List of price_ids that this minimum amount applies to. For plan/plan phase
|
|
1304
|
+
* minimums, this can be a subset of prices.
|
|
1305
|
+
*/
|
|
1306
|
+
applies_to_price_ids: Array<string>;
|
|
1307
|
+
|
|
1308
|
+
/**
|
|
1309
|
+
* Minimum amount applied
|
|
1310
|
+
*/
|
|
1311
|
+
minimum_amount: string;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1237
1315
|
export interface TieredWithMinimumPrice {
|
|
1238
1316
|
id: string;
|
|
1239
1317
|
|
|
@@ -1310,6 +1388,82 @@ export namespace Price {
|
|
|
1310
1388
|
}
|
|
1311
1389
|
}
|
|
1312
1390
|
|
|
1391
|
+
export interface TieredPackageWithMinimumPrice {
|
|
1392
|
+
id: string;
|
|
1393
|
+
|
|
1394
|
+
billable_metric: TieredPackageWithMinimumPrice.BillableMetric | null;
|
|
1395
|
+
|
|
1396
|
+
cadence: 'one_time' | 'monthly' | 'quarterly' | 'annual';
|
|
1397
|
+
|
|
1398
|
+
created_at: string;
|
|
1399
|
+
|
|
1400
|
+
currency: string;
|
|
1401
|
+
|
|
1402
|
+
discount: Shared.Discount | null;
|
|
1403
|
+
|
|
1404
|
+
external_price_id: string | null;
|
|
1405
|
+
|
|
1406
|
+
fixed_price_quantity: number | null;
|
|
1407
|
+
|
|
1408
|
+
item: TieredPackageWithMinimumPrice.Item;
|
|
1409
|
+
|
|
1410
|
+
maximum: TieredPackageWithMinimumPrice.Maximum | null;
|
|
1411
|
+
|
|
1412
|
+
maximum_amount: string | null;
|
|
1413
|
+
|
|
1414
|
+
minimum: TieredPackageWithMinimumPrice.Minimum | null;
|
|
1415
|
+
|
|
1416
|
+
minimum_amount: string | null;
|
|
1417
|
+
|
|
1418
|
+
model_type: 'tiered_package_with_minimum';
|
|
1419
|
+
|
|
1420
|
+
name: string;
|
|
1421
|
+
|
|
1422
|
+
plan_phase_order: number | null;
|
|
1423
|
+
|
|
1424
|
+
price_type: 'usage_price' | 'fixed_price';
|
|
1425
|
+
|
|
1426
|
+
tiered_package_with_minimum_config: Record<string, unknown>;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
export namespace TieredPackageWithMinimumPrice {
|
|
1430
|
+
export interface BillableMetric {
|
|
1431
|
+
id: string;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
export interface Item {
|
|
1435
|
+
id: string;
|
|
1436
|
+
|
|
1437
|
+
name: string;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
export interface Maximum {
|
|
1441
|
+
/**
|
|
1442
|
+
* List of price_ids that this maximum amount applies to. For plan/plan phase
|
|
1443
|
+
* maximums, this can be a subset of prices.
|
|
1444
|
+
*/
|
|
1445
|
+
applies_to_price_ids: Array<string>;
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* Maximum amount applied
|
|
1449
|
+
*/
|
|
1450
|
+
maximum_amount: string;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
export interface Minimum {
|
|
1454
|
+
/**
|
|
1455
|
+
* List of price_ids that this minimum amount applies to. For plan/plan phase
|
|
1456
|
+
* minimums, this can be a subset of prices.
|
|
1457
|
+
*/
|
|
1458
|
+
applies_to_price_ids: Array<string>;
|
|
1459
|
+
|
|
1460
|
+
/**
|
|
1461
|
+
* Minimum amount applied
|
|
1462
|
+
*/
|
|
1463
|
+
minimum_amount: string;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1313
1467
|
export interface PackageWithAllocationPrice {
|
|
1314
1468
|
id: string;
|
|
1315
1469
|
|
|
@@ -1589,6 +1743,7 @@ export type PriceCreateParams =
|
|
|
1589
1743
|
| PriceCreateParams.NewFloatingBulkPrice
|
|
1590
1744
|
| PriceCreateParams.NewFloatingThresholdTotalAmountPrice
|
|
1591
1745
|
| PriceCreateParams.NewFloatingTieredPackagePrice
|
|
1746
|
+
| PriceCreateParams.NewFloatingGroupedTieredPrice
|
|
1592
1747
|
| PriceCreateParams.NewFloatingTieredWithMinimumPrice
|
|
1593
1748
|
| PriceCreateParams.NewFloatingPackageWithAllocationPrice
|
|
1594
1749
|
| PriceCreateParams.NewFloatingTieredPackageWithMinimumPrice
|
|
@@ -2416,6 +2571,60 @@ export namespace PriceCreateParams {
|
|
|
2416
2571
|
invoice_grouping_key?: string | null;
|
|
2417
2572
|
}
|
|
2418
2573
|
|
|
2574
|
+
export interface NewFloatingGroupedTieredPrice {
|
|
2575
|
+
/**
|
|
2576
|
+
* The cadence to bill for this price on.
|
|
2577
|
+
*/
|
|
2578
|
+
cadence: 'annual' | 'monthly' | 'quarterly' | 'one_time';
|
|
2579
|
+
|
|
2580
|
+
/**
|
|
2581
|
+
* An ISO 4217 currency string for which this price is billed in.
|
|
2582
|
+
*/
|
|
2583
|
+
currency: string;
|
|
2584
|
+
|
|
2585
|
+
grouped_tiered_config: Record<string, unknown>;
|
|
2586
|
+
|
|
2587
|
+
/**
|
|
2588
|
+
* The id of the item the plan will be associated with.
|
|
2589
|
+
*/
|
|
2590
|
+
item_id: string;
|
|
2591
|
+
|
|
2592
|
+
model_type: 'grouped_tiered';
|
|
2593
|
+
|
|
2594
|
+
/**
|
|
2595
|
+
* The name of the price.
|
|
2596
|
+
*/
|
|
2597
|
+
name: string;
|
|
2598
|
+
|
|
2599
|
+
/**
|
|
2600
|
+
* The id of the billable metric for the price. Only needed if the price is
|
|
2601
|
+
* usage-based.
|
|
2602
|
+
*/
|
|
2603
|
+
billable_metric_id?: string | null;
|
|
2604
|
+
|
|
2605
|
+
/**
|
|
2606
|
+
* If the Price represents a fixed cost, the price will be billed in-advance if
|
|
2607
|
+
* this is true, and in-arrears if this is false.
|
|
2608
|
+
*/
|
|
2609
|
+
billed_in_advance?: boolean | null;
|
|
2610
|
+
|
|
2611
|
+
/**
|
|
2612
|
+
* An alias for the price.
|
|
2613
|
+
*/
|
|
2614
|
+
external_price_id?: string | null;
|
|
2615
|
+
|
|
2616
|
+
/**
|
|
2617
|
+
* If the Price represents a fixed cost, this represents the quantity of units
|
|
2618
|
+
* applied.
|
|
2619
|
+
*/
|
|
2620
|
+
fixed_price_quantity?: number | null;
|
|
2621
|
+
|
|
2622
|
+
/**
|
|
2623
|
+
* The property used to group this price on an invoice
|
|
2624
|
+
*/
|
|
2625
|
+
invoice_grouping_key?: string | null;
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2419
2628
|
export interface NewFloatingTieredWithMinimumPrice {
|
|
2420
2629
|
/**
|
|
2421
2630
|
* The cadence to bill for this price on.
|
|
@@ -3309,6 +3309,7 @@ export namespace SubscriptionPriceIntervalsParams {
|
|
|
3309
3309
|
| Add.NewFloatingBulkPrice
|
|
3310
3310
|
| Add.NewFloatingThresholdTotalAmountPrice
|
|
3311
3311
|
| Add.NewFloatingTieredPackagePrice
|
|
3312
|
+
| Add.NewFloatingGroupedTieredPrice
|
|
3312
3313
|
| Add.NewFloatingTieredWithMinimumPrice
|
|
3313
3314
|
| Add.NewFloatingPackageWithAllocationPrice
|
|
3314
3315
|
| Add.NewFloatingTieredPackageWithMinimumPrice
|
|
@@ -4184,6 +4185,60 @@ export namespace SubscriptionPriceIntervalsParams {
|
|
|
4184
4185
|
invoice_grouping_key?: string | null;
|
|
4185
4186
|
}
|
|
4186
4187
|
|
|
4188
|
+
export interface NewFloatingGroupedTieredPrice {
|
|
4189
|
+
/**
|
|
4190
|
+
* The cadence to bill for this price on.
|
|
4191
|
+
*/
|
|
4192
|
+
cadence: 'annual' | 'monthly' | 'quarterly' | 'one_time';
|
|
4193
|
+
|
|
4194
|
+
/**
|
|
4195
|
+
* An ISO 4217 currency string for which this price is billed in.
|
|
4196
|
+
*/
|
|
4197
|
+
currency: string;
|
|
4198
|
+
|
|
4199
|
+
grouped_tiered_config: Record<string, unknown>;
|
|
4200
|
+
|
|
4201
|
+
/**
|
|
4202
|
+
* The id of the item the plan will be associated with.
|
|
4203
|
+
*/
|
|
4204
|
+
item_id: string;
|
|
4205
|
+
|
|
4206
|
+
model_type: 'grouped_tiered';
|
|
4207
|
+
|
|
4208
|
+
/**
|
|
4209
|
+
* The name of the price.
|
|
4210
|
+
*/
|
|
4211
|
+
name: string;
|
|
4212
|
+
|
|
4213
|
+
/**
|
|
4214
|
+
* The id of the billable metric for the price. Only needed if the price is
|
|
4215
|
+
* usage-based.
|
|
4216
|
+
*/
|
|
4217
|
+
billable_metric_id?: string | null;
|
|
4218
|
+
|
|
4219
|
+
/**
|
|
4220
|
+
* If the Price represents a fixed cost, the price will be billed in-advance if
|
|
4221
|
+
* this is true, and in-arrears if this is false.
|
|
4222
|
+
*/
|
|
4223
|
+
billed_in_advance?: boolean | null;
|
|
4224
|
+
|
|
4225
|
+
/**
|
|
4226
|
+
* An alias for the price.
|
|
4227
|
+
*/
|
|
4228
|
+
external_price_id?: string | null;
|
|
4229
|
+
|
|
4230
|
+
/**
|
|
4231
|
+
* If the Price represents a fixed cost, this represents the quantity of units
|
|
4232
|
+
* applied.
|
|
4233
|
+
*/
|
|
4234
|
+
fixed_price_quantity?: number | null;
|
|
4235
|
+
|
|
4236
|
+
/**
|
|
4237
|
+
* The property used to group this price on an invoice
|
|
4238
|
+
*/
|
|
4239
|
+
invoice_grouping_key?: string | null;
|
|
4240
|
+
}
|
|
4241
|
+
|
|
4187
4242
|
export interface NewFloatingTieredWithMinimumPrice {
|
|
4188
4243
|
/**
|
|
4189
4244
|
* The cadence to bill for this price on.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless.
|
|
2
|
+
|
|
3
|
+
import { APIResource } from "../resource";
|
|
4
|
+
import { createHmac } from 'crypto';
|
|
5
|
+
import { getRequiredHeader, HeadersLike } from "../core";
|
|
6
|
+
|
|
7
|
+
export class Webhooks extends APIResource {
|
|
8
|
+
/**
|
|
9
|
+
* Validates that the given payload was sent by Orb and parses the payload.
|
|
10
|
+
*
|
|
11
|
+
* An error will be raised if the webhook payload was not sent by Orb.
|
|
12
|
+
*/
|
|
13
|
+
unwrap(
|
|
14
|
+
payload: string,
|
|
15
|
+
headers: HeadersLike,
|
|
16
|
+
secret: string | undefined | null = this._client.webhookSecret,
|
|
17
|
+
): Object {
|
|
18
|
+
this.verifySignature(payload, headers, secret);
|
|
19
|
+
return JSON.parse(payload);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private parseSecret(secret: string | null | undefined): Uint8Array {
|
|
23
|
+
if (!secret) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
"The webhook secret must either be set using the env var, ORB_WEBHOOK_SECRET, on the client class, Orb({ webhookSecret: '123' }), or passed to this function",
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const buf = Buffer.from(secret, 'utf-8');
|
|
30
|
+
if (buf.toString('utf-8') !== secret) {
|
|
31
|
+
throw new Error(`Given secret is not valid`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return new Uint8Array(buf);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private signPayload(payload: string, { timestamp, secret }: { timestamp: string; secret: Uint8Array }) {
|
|
38
|
+
const encoder = new TextEncoder();
|
|
39
|
+
const toSign = encoder.encode(`v1:${timestamp}:${payload}`);
|
|
40
|
+
|
|
41
|
+
const hmac = createHmac('sha256', secret);
|
|
42
|
+
hmac.update(toSign);
|
|
43
|
+
|
|
44
|
+
return `v1=${hmac.digest('hex')}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Make an assertion, if not `true`, then throw. */
|
|
48
|
+
private assert(expr: unknown, msg = ''): asserts expr {
|
|
49
|
+
if (!expr) {
|
|
50
|
+
throw new Error(msg);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Compare to array buffers or data views in a way that timing based attacks
|
|
55
|
+
* cannot gain information about the platform. */
|
|
56
|
+
private timingSafeEqual(
|
|
57
|
+
a: ArrayBufferView | ArrayBufferLike | DataView,
|
|
58
|
+
b: ArrayBufferView | ArrayBufferLike | DataView,
|
|
59
|
+
): boolean {
|
|
60
|
+
if (a.byteLength !== b.byteLength) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (!(a instanceof DataView)) {
|
|
64
|
+
a = new DataView(ArrayBuffer.isView(a) ? a.buffer : a);
|
|
65
|
+
}
|
|
66
|
+
if (!(b instanceof DataView)) {
|
|
67
|
+
b = new DataView(ArrayBuffer.isView(b) ? b.buffer : b);
|
|
68
|
+
}
|
|
69
|
+
this.assert(a instanceof DataView);
|
|
70
|
+
this.assert(b instanceof DataView);
|
|
71
|
+
const length = a.byteLength;
|
|
72
|
+
let out = 0;
|
|
73
|
+
let i = -1;
|
|
74
|
+
while (++i < length) {
|
|
75
|
+
out |= a.getUint8(i) ^ b.getUint8(i);
|
|
76
|
+
}
|
|
77
|
+
return out === 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validates whether or not the webhook payload was sent by Orb.
|
|
82
|
+
*
|
|
83
|
+
* An error will be raised if the webhook payload was not sent by Orb.
|
|
84
|
+
*/
|
|
85
|
+
verifySignature(
|
|
86
|
+
body: string,
|
|
87
|
+
headers: HeadersLike,
|
|
88
|
+
secret: string | undefined | null = this._client.webhookSecret,
|
|
89
|
+
): void {
|
|
90
|
+
const whsecret = this.parseSecret(secret);
|
|
91
|
+
|
|
92
|
+
const msgTimestamp = getRequiredHeader(headers, 'X-Orb-Timestamp');
|
|
93
|
+
const msgSignature = getRequiredHeader(headers, 'X-Orb-Signature');
|
|
94
|
+
|
|
95
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
96
|
+
const timestamp = new Date(msgTimestamp);
|
|
97
|
+
const timestampSeconds = Math.floor(timestamp.getTime() / 1000);
|
|
98
|
+
if (isNaN(timestampSeconds)) {
|
|
99
|
+
throw new Error('Invalid timestamp header');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const webhookToleranceInSeconds = 5 * 60; // 5 minutes
|
|
103
|
+
if (nowSeconds - timestampSeconds > webhookToleranceInSeconds) {
|
|
104
|
+
throw new Error('Webhook timestamp is too old');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (timestampSeconds > nowSeconds + webhookToleranceInSeconds) {
|
|
108
|
+
console.warn({ timestampSeconds, nowSeconds, webhookToleranceInSeconds });
|
|
109
|
+
throw new Error('Webhook timestamp is too new');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (typeof body !== 'string') {
|
|
113
|
+
throw new Error(
|
|
114
|
+
'Webhook body must be passed as the raw JSON string sent from the server (do not parse it first).',
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const computedSignature = this.signPayload(body, { timestamp: msgTimestamp, secret: whsecret });
|
|
119
|
+
const expectedSignature = computedSignature.split('=')[1];
|
|
120
|
+
|
|
121
|
+
const passedSignatures = msgSignature.split(' ');
|
|
122
|
+
|
|
123
|
+
const encoder = new globalThis.TextEncoder();
|
|
124
|
+
for (const versionedSignature of passedSignatures) {
|
|
125
|
+
const [version, signature] = versionedSignature.split('=');
|
|
126
|
+
console.log({ version, signature, expectedSignature, computedSignature });
|
|
127
|
+
|
|
128
|
+
if (version !== 'v1') {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (this.timingSafeEqual(encoder.encode(signature), encoder.encode(expectedSignature))) {
|
|
133
|
+
// valid!
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
throw new Error('None of the given webhook signatures match the expected signature');
|
|
139
|
+
}
|
|
140
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '2.
|
|
1
|
+
export const VERSION = '2.2.0'; // x-release-please-version
|
package/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.2.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/version.js
CHANGED
package/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '2.
|
|
1
|
+
export const VERSION = '2.2.0'; // x-release-please-version
|
|
2
2
|
//# sourceMappingURL=version.mjs.map
|