@01.software/sdk 0.17.0 → 0.19.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/README.md +29 -14
- package/dist/analytics.cjs.map +1 -1
- package/dist/analytics.js.map +1 -1
- package/dist/{const-D2K5HxpP.d.cts → const-B9oeZoDy.d.ts} +3 -3
- package/dist/{const-DG8TrouX.d.ts → const-CkhnGqnb.d.cts} +3 -3
- package/dist/index.cjs +96 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -52
- package/dist/index.d.ts +27 -52
- package/dist/index.js +96 -79
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-CMoyAOjJ.d.cts → payload-types-DfQct8Dj.d.cts} +927 -195
- package/dist/{payload-types-CMoyAOjJ.d.ts → payload-types-DfQct8Dj.d.ts} +927 -195
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/realtime.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook-CJq7v5Da.d.cts +61 -0
- package/dist/webhook-CKqXQInG.d.ts +61 -0
- package/dist/webhook.cjs +53 -4
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +3 -3
- package/dist/webhook.d.ts +3 -3
- package/dist/webhook.js +53 -4
- package/dist/webhook.js.map +1 -1
- package/package.json +3 -3
- package/dist/webhook-Dm2zz7FQ.d.cts +0 -20
- package/dist/webhook-IhuUWnt5.d.ts +0 -20
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(src_exports, {
|
|
|
24
24
|
AuthError: () => AuthError,
|
|
25
25
|
BaseApi: () => BaseApi,
|
|
26
26
|
COLLECTIONS: () => COLLECTIONS,
|
|
27
|
+
CUSTOMER_PASSWORD_RESET_OPERATION: () => CUSTOMER_PASSWORD_RESET_OPERATION,
|
|
27
28
|
CartApi: () => CartApi,
|
|
28
29
|
Client: () => Client,
|
|
29
30
|
CollectionClient: () => CollectionClient,
|
|
@@ -65,6 +66,7 @@ __export(src_exports, {
|
|
|
65
66
|
createAuthError: () => createAuthError,
|
|
66
67
|
createClient: () => createClient,
|
|
67
68
|
createConflictError: () => createConflictError,
|
|
69
|
+
createCustomerAuthWebhookHandler: () => createCustomerAuthWebhookHandler,
|
|
68
70
|
createNotFoundError: () => createNotFoundError,
|
|
69
71
|
createPermissionError: () => createPermissionError,
|
|
70
72
|
createRateLimitError: () => createRateLimitError,
|
|
@@ -91,6 +93,7 @@ __export(src_exports, {
|
|
|
91
93
|
isAuthError: () => isAuthError,
|
|
92
94
|
isConfigError: () => isConfigError,
|
|
93
95
|
isConflictError: () => isConflictError,
|
|
96
|
+
isCustomerPasswordResetWebhookEvent: () => isCustomerPasswordResetWebhookEvent,
|
|
94
97
|
isGoneError: () => isGoneError,
|
|
95
98
|
isNetworkError: () => isNetworkError,
|
|
96
99
|
isNotFoundError: () => isNotFoundError,
|
|
@@ -529,7 +532,7 @@ async function parseErrorBody(response) {
|
|
|
529
532
|
};
|
|
530
533
|
try {
|
|
531
534
|
const body = await response.json();
|
|
532
|
-
const reason = typeof body.reason === "string" ? body.reason : void 0;
|
|
535
|
+
const reason = typeof body.reason === "string" ? body.reason : typeof body.code === "string" ? body.code : void 0;
|
|
533
536
|
if (body.errors && Array.isArray(body.errors)) {
|
|
534
537
|
const fieldErrors = [];
|
|
535
538
|
for (const e of body.errors) {
|
|
@@ -552,6 +555,7 @@ async function parseErrorBody(response) {
|
|
|
552
555
|
errorMessage: `HTTP ${response.status}: ${details}`,
|
|
553
556
|
userMessage: details,
|
|
554
557
|
reason,
|
|
558
|
+
body,
|
|
555
559
|
errors: fieldErrors.length > 0 ? fieldErrors : body.errors
|
|
556
560
|
};
|
|
557
561
|
}
|
|
@@ -560,17 +564,19 @@ async function parseErrorBody(response) {
|
|
|
560
564
|
return {
|
|
561
565
|
errorMessage: `HTTP ${response.status}: ${body.error}`,
|
|
562
566
|
userMessage: body.error,
|
|
563
|
-
reason
|
|
567
|
+
reason,
|
|
568
|
+
body
|
|
564
569
|
};
|
|
565
570
|
}
|
|
566
571
|
if (body.message) {
|
|
567
572
|
return {
|
|
568
573
|
errorMessage: `HTTP ${response.status}: ${body.message}`,
|
|
569
574
|
userMessage: body.message,
|
|
570
|
-
reason
|
|
575
|
+
reason,
|
|
576
|
+
body
|
|
571
577
|
};
|
|
572
578
|
}
|
|
573
|
-
return { ...fallback, reason };
|
|
579
|
+
return { ...fallback, reason, body };
|
|
574
580
|
} catch {
|
|
575
581
|
return fallback;
|
|
576
582
|
}
|
|
@@ -587,7 +593,6 @@ async function httpFetch(url, options) {
|
|
|
587
593
|
publishableKey,
|
|
588
594
|
secretKey,
|
|
589
595
|
customerToken,
|
|
590
|
-
tenantId,
|
|
591
596
|
timeout = DEFAULT_TIMEOUT,
|
|
592
597
|
debug,
|
|
593
598
|
retry,
|
|
@@ -617,9 +622,6 @@ async function httpFetch(url, options) {
|
|
|
617
622
|
if (authToken) {
|
|
618
623
|
headers.set("Authorization", `Bearer ${authToken}`);
|
|
619
624
|
}
|
|
620
|
-
if (tenantId) {
|
|
621
|
-
headers.set("X-Tenant-Id", tenantId);
|
|
622
|
-
}
|
|
623
625
|
if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
|
|
624
626
|
headers.set("Content-Type", "application/json");
|
|
625
627
|
}
|
|
@@ -786,10 +788,9 @@ async function httpFetch(url, options) {
|
|
|
786
788
|
|
|
787
789
|
// src/core/collection/http-client.ts
|
|
788
790
|
var HttpClient = class {
|
|
789
|
-
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId
|
|
791
|
+
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId) {
|
|
790
792
|
this.publishableKey = publishableKey;
|
|
791
793
|
this.secretKey = secretKey;
|
|
792
|
-
this.tenantId = tenantId;
|
|
793
794
|
this.getCustomerToken = getCustomerToken;
|
|
794
795
|
this.onUnauthorized = onUnauthorized;
|
|
795
796
|
this.onRequestId = onRequestId;
|
|
@@ -799,9 +800,6 @@ var HttpClient = class {
|
|
|
799
800
|
publishableKey: this.publishableKey,
|
|
800
801
|
secretKey: this.secretKey
|
|
801
802
|
};
|
|
802
|
-
if (this.secretKey?.startsWith("pat01_") && this.tenantId) {
|
|
803
|
-
opts.tenantId = this.tenantId;
|
|
804
|
-
}
|
|
805
803
|
const token = this.getCustomerToken?.();
|
|
806
804
|
if (token) {
|
|
807
805
|
opts.customerToken = token;
|
|
@@ -1077,8 +1075,6 @@ var INTERNAL_COLLECTIONS = [
|
|
|
1077
1075
|
"track-assets",
|
|
1078
1076
|
"audiences",
|
|
1079
1077
|
"email-logs",
|
|
1080
|
-
"tenant-auth-settings",
|
|
1081
|
-
"tenant-community-settings",
|
|
1082
1078
|
"api-usage",
|
|
1083
1079
|
"tenant-analytics-daily",
|
|
1084
1080
|
"analytics-event-schemas",
|
|
@@ -1092,7 +1088,8 @@ var INTERNAL_COLLECTIONS = [
|
|
|
1092
1088
|
"webhook-deliveries",
|
|
1093
1089
|
"audit-logs",
|
|
1094
1090
|
"plans",
|
|
1095
|
-
"webhooks"
|
|
1091
|
+
"webhooks",
|
|
1092
|
+
"event-registrations"
|
|
1096
1093
|
];
|
|
1097
1094
|
var COLLECTIONS = [
|
|
1098
1095
|
"tenants",
|
|
@@ -1126,10 +1123,10 @@ var COLLECTIONS = [
|
|
|
1126
1123
|
"documents",
|
|
1127
1124
|
"document-categories",
|
|
1128
1125
|
"document-types",
|
|
1129
|
-
"
|
|
1130
|
-
"
|
|
1131
|
-
"
|
|
1132
|
-
"
|
|
1126
|
+
"articles",
|
|
1127
|
+
"article-authors",
|
|
1128
|
+
"article-categories",
|
|
1129
|
+
"article-tags",
|
|
1133
1130
|
"playlists",
|
|
1134
1131
|
"playlist-categories",
|
|
1135
1132
|
"playlist-tags",
|
|
@@ -1158,14 +1155,19 @@ var COLLECTIONS = [
|
|
|
1158
1155
|
"forms",
|
|
1159
1156
|
"form-submissions",
|
|
1160
1157
|
// Community
|
|
1161
|
-
"
|
|
1158
|
+
"posts",
|
|
1162
1159
|
"comments",
|
|
1163
1160
|
"reactions",
|
|
1164
1161
|
"reaction-types",
|
|
1165
1162
|
"bookmarks",
|
|
1166
|
-
"
|
|
1163
|
+
"post-categories",
|
|
1167
1164
|
"reports",
|
|
1168
|
-
"community-bans"
|
|
1165
|
+
"community-bans",
|
|
1166
|
+
// Events
|
|
1167
|
+
"event-calendars",
|
|
1168
|
+
"events",
|
|
1169
|
+
"event-occurrences",
|
|
1170
|
+
"event-tags"
|
|
1169
1171
|
];
|
|
1170
1172
|
|
|
1171
1173
|
// src/core/api/parse-response.ts
|
|
@@ -1219,7 +1221,6 @@ var CommunityClient = class {
|
|
|
1219
1221
|
constructor(options) {
|
|
1220
1222
|
this.publishableKey = options.publishableKey ?? "";
|
|
1221
1223
|
this.secretKey = options.secretKey;
|
|
1222
|
-
this.tenantId = options.tenantId;
|
|
1223
1224
|
this.customerToken = options.customerToken;
|
|
1224
1225
|
this.onUnauthorized = options.onUnauthorized;
|
|
1225
1226
|
this.onRequestId = options.onRequestId;
|
|
@@ -1231,13 +1232,11 @@ var CommunityClient = class {
|
|
|
1231
1232
|
}
|
|
1232
1233
|
async execute(endpoint, method, body) {
|
|
1233
1234
|
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
1234
|
-
const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
|
|
1235
1235
|
try {
|
|
1236
1236
|
const response = await httpFetch(endpoint, {
|
|
1237
1237
|
method,
|
|
1238
1238
|
publishableKey: this.publishableKey,
|
|
1239
1239
|
secretKey: this.secretKey,
|
|
1240
|
-
tenantId,
|
|
1241
1240
|
customerToken: token ?? void 0,
|
|
1242
1241
|
...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
|
|
1243
1242
|
...body !== void 0 && { body: JSON.stringify(body) }
|
|
@@ -1250,49 +1249,48 @@ var CommunityClient = class {
|
|
|
1250
1249
|
throw err;
|
|
1251
1250
|
}
|
|
1252
1251
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
return this.execute("/api/threads", "POST", params);
|
|
1252
|
+
createPost(params) {
|
|
1253
|
+
return this.execute("/api/posts", "POST", params);
|
|
1256
1254
|
}
|
|
1257
|
-
|
|
1255
|
+
getMyPosts(params) {
|
|
1258
1256
|
return this.execute(
|
|
1259
|
-
`/api/
|
|
1257
|
+
`/api/posts/my${this.buildQuery(params)}`,
|
|
1260
1258
|
"GET"
|
|
1261
1259
|
);
|
|
1262
1260
|
}
|
|
1263
1261
|
getTrending(params) {
|
|
1264
1262
|
return this.execute(
|
|
1265
|
-
`/api/
|
|
1263
|
+
`/api/posts/trending${this.buildQuery(params)}`,
|
|
1266
1264
|
"GET"
|
|
1267
1265
|
);
|
|
1268
1266
|
}
|
|
1269
1267
|
incrementView(params) {
|
|
1270
1268
|
return this.execute(
|
|
1271
|
-
`/api/
|
|
1269
|
+
`/api/posts/${params.postId}/view`,
|
|
1272
1270
|
"POST"
|
|
1273
1271
|
);
|
|
1274
1272
|
}
|
|
1275
|
-
|
|
1276
|
-
const {
|
|
1273
|
+
reportPost(params) {
|
|
1274
|
+
const { postId, ...body } = params;
|
|
1277
1275
|
return this.execute(
|
|
1278
|
-
`/api/
|
|
1276
|
+
`/api/posts/${postId}/report`,
|
|
1279
1277
|
"POST",
|
|
1280
1278
|
body
|
|
1281
1279
|
);
|
|
1282
1280
|
}
|
|
1283
1281
|
// Comments
|
|
1284
1282
|
createComment(params) {
|
|
1285
|
-
const {
|
|
1286
|
-
const body = {
|
|
1283
|
+
const { postId, parentId, body: commentBody } = params;
|
|
1284
|
+
const body = { post: postId, body: commentBody };
|
|
1287
1285
|
if (parentId !== void 0) {
|
|
1288
1286
|
body.parent = parentId;
|
|
1289
1287
|
}
|
|
1290
1288
|
return this.execute("/api/comments", "POST", body);
|
|
1291
1289
|
}
|
|
1292
1290
|
listComments(params) {
|
|
1293
|
-
const {
|
|
1291
|
+
const { postId, page, limit, rootComment } = params;
|
|
1294
1292
|
const urlParams = new URLSearchParams();
|
|
1295
|
-
urlParams.set("where[
|
|
1293
|
+
urlParams.set("where[post][equals]", postId);
|
|
1296
1294
|
urlParams.set("sort", "-createdAt");
|
|
1297
1295
|
if (limit !== void 0) urlParams.set("limit", String(limit));
|
|
1298
1296
|
if (page !== void 0) urlParams.set("page", String(page));
|
|
@@ -1326,16 +1324,16 @@ var CommunityClient = class {
|
|
|
1326
1324
|
}
|
|
1327
1325
|
// Reactions
|
|
1328
1326
|
addReaction(params) {
|
|
1329
|
-
const {
|
|
1327
|
+
const { postId, type } = params;
|
|
1330
1328
|
return this.execute("/api/reactions", "POST", {
|
|
1331
|
-
|
|
1329
|
+
post: postId,
|
|
1332
1330
|
type
|
|
1333
1331
|
});
|
|
1334
1332
|
}
|
|
1335
1333
|
removeReaction(params) {
|
|
1336
|
-
const {
|
|
1334
|
+
const { postId, type } = params;
|
|
1337
1335
|
return this.execute(
|
|
1338
|
-
`/api/
|
|
1336
|
+
`/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,
|
|
1339
1337
|
"DELETE"
|
|
1340
1338
|
);
|
|
1341
1339
|
}
|
|
@@ -1355,7 +1353,7 @@ var CommunityClient = class {
|
|
|
1355
1353
|
}
|
|
1356
1354
|
getReactionSummary(params) {
|
|
1357
1355
|
return this.execute(
|
|
1358
|
-
`/api/
|
|
1356
|
+
`/api/posts/${params.postId}/reactions`,
|
|
1359
1357
|
"GET"
|
|
1360
1358
|
);
|
|
1361
1359
|
}
|
|
@@ -1368,12 +1366,12 @@ var CommunityClient = class {
|
|
|
1368
1366
|
// Bookmarks
|
|
1369
1367
|
addBookmark(params) {
|
|
1370
1368
|
return this.execute("/api/bookmarks", "POST", {
|
|
1371
|
-
|
|
1369
|
+
post: params.postId
|
|
1372
1370
|
});
|
|
1373
1371
|
}
|
|
1374
1372
|
removeBookmark(params) {
|
|
1375
1373
|
return this.execute(
|
|
1376
|
-
`/api/
|
|
1374
|
+
`/api/posts/${params.postId}/bookmark`,
|
|
1377
1375
|
"DELETE"
|
|
1378
1376
|
);
|
|
1379
1377
|
}
|
|
@@ -1393,18 +1391,15 @@ var BaseApi = class {
|
|
|
1393
1391
|
}
|
|
1394
1392
|
this.publishableKey = options.publishableKey ?? "";
|
|
1395
1393
|
this.secretKey = options.secretKey;
|
|
1396
|
-
this.tenantId = options.tenantId;
|
|
1397
1394
|
this.onRequestId = options.onRequestId;
|
|
1398
1395
|
}
|
|
1399
1396
|
async request(endpoint, body, options) {
|
|
1400
1397
|
const method = options?.method ?? "POST";
|
|
1401
|
-
const tenantId = this.secretKey.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
|
|
1402
1398
|
try {
|
|
1403
1399
|
const response = await httpFetch(endpoint, {
|
|
1404
1400
|
method,
|
|
1405
1401
|
publishableKey: this.publishableKey,
|
|
1406
1402
|
secretKey: this.secretKey,
|
|
1407
|
-
tenantId,
|
|
1408
1403
|
...body !== void 0 && { body: JSON.stringify(body) },
|
|
1409
1404
|
...options?.headers && { headers: options.headers }
|
|
1410
1405
|
});
|
|
@@ -1581,15 +1576,6 @@ var CustomerAuth = class {
|
|
|
1581
1576
|
body: JSON.stringify({ currentPassword, newPassword })
|
|
1582
1577
|
});
|
|
1583
1578
|
}
|
|
1584
|
-
/**
|
|
1585
|
-
* Verify email using the verification token
|
|
1586
|
-
*/
|
|
1587
|
-
async verifyEmail(token) {
|
|
1588
|
-
await this.requestJson("/api/customers/verify-email", {
|
|
1589
|
-
method: "POST",
|
|
1590
|
-
body: JSON.stringify({ token })
|
|
1591
|
-
});
|
|
1592
|
-
}
|
|
1593
1579
|
/**
|
|
1594
1580
|
* Get the authenticated customer's orders with pagination and optional status filter
|
|
1595
1581
|
*/
|
|
@@ -1699,20 +1685,17 @@ var CartApi = class {
|
|
|
1699
1685
|
}
|
|
1700
1686
|
this.publishableKey = options.publishableKey ?? "";
|
|
1701
1687
|
this.secretKey = options.secretKey;
|
|
1702
|
-
this.tenantId = options.tenantId;
|
|
1703
1688
|
this.customerToken = options.customerToken;
|
|
1704
1689
|
this.onUnauthorized = options.onUnauthorized;
|
|
1705
1690
|
this.onRequestId = options.onRequestId;
|
|
1706
1691
|
}
|
|
1707
1692
|
async execute(endpoint, method, body) {
|
|
1708
1693
|
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
1709
|
-
const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
|
|
1710
1694
|
try {
|
|
1711
1695
|
const response = await httpFetch(endpoint, {
|
|
1712
1696
|
method,
|
|
1713
1697
|
publishableKey: this.publishableKey,
|
|
1714
1698
|
secretKey: this.secretKey,
|
|
1715
|
-
tenantId,
|
|
1716
1699
|
customerToken: token ?? void 0,
|
|
1717
1700
|
...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
|
|
1718
1701
|
...body !== void 0 && { body: JSON.stringify(body) }
|
|
@@ -1899,7 +1882,6 @@ var ServerCommerceClient = class {
|
|
|
1899
1882
|
const serverOptions = {
|
|
1900
1883
|
publishableKey: options.publishableKey,
|
|
1901
1884
|
secretKey: options.secretKey,
|
|
1902
|
-
tenantId: options.tenantId,
|
|
1903
1885
|
onRequestId: options.onRequestId
|
|
1904
1886
|
};
|
|
1905
1887
|
const productApi = new ProductApi(serverOptions);
|
|
@@ -2309,14 +2291,6 @@ var CustomerHooks = class {
|
|
|
2309
2291
|
options
|
|
2310
2292
|
);
|
|
2311
2293
|
}
|
|
2312
|
-
useCustomerVerifyEmail(options) {
|
|
2313
|
-
return createMutation(
|
|
2314
|
-
(token) => this.ensureCustomerAuth().verifyEmail(token).then(() => {
|
|
2315
|
-
}),
|
|
2316
|
-
options,
|
|
2317
|
-
this.invalidateMe
|
|
2318
|
-
);
|
|
2319
|
-
}
|
|
2320
2294
|
useCustomerRefreshToken(options) {
|
|
2321
2295
|
return createMutation(
|
|
2322
2296
|
() => this.ensureCustomerAuth().refreshToken(),
|
|
@@ -2361,7 +2335,6 @@ var QueryHooks = class extends CollectionHooks {
|
|
|
2361
2335
|
this.useCustomerLogout = (...args) => this._customer.useCustomerLogout(...args);
|
|
2362
2336
|
this.useCustomerForgotPassword = (...args) => this._customer.useCustomerForgotPassword(...args);
|
|
2363
2337
|
this.useCustomerResetPassword = (...args) => this._customer.useCustomerResetPassword(...args);
|
|
2364
|
-
this.useCustomerVerifyEmail = (...args) => this._customer.useCustomerVerifyEmail(...args);
|
|
2365
2338
|
this.useCustomerRefreshToken = (...args) => this._customer.useCustomerRefreshToken(...args);
|
|
2366
2339
|
this.useCustomerUpdateProfile = (...args) => this._customer.useCustomerUpdateProfile(...args);
|
|
2367
2340
|
this.useCustomerChangePassword = (...args) => this._customer.useCustomerChangePassword(...args);
|
|
@@ -2561,7 +2534,6 @@ var ServerClient = class {
|
|
|
2561
2534
|
const serverOptions = {
|
|
2562
2535
|
publishableKey: this.config.publishableKey,
|
|
2563
2536
|
secretKey: this.config.secretKey,
|
|
2564
|
-
tenantId: this.config.tenantId,
|
|
2565
2537
|
onRequestId
|
|
2566
2538
|
};
|
|
2567
2539
|
this.commerce = new ServerCommerceClient(serverOptions);
|
|
@@ -2578,8 +2550,7 @@ var ServerClient = class {
|
|
|
2578
2550
|
this.config.secretKey,
|
|
2579
2551
|
void 0,
|
|
2580
2552
|
void 0,
|
|
2581
|
-
onRequestId
|
|
2582
|
-
this.config.tenantId
|
|
2553
|
+
onRequestId
|
|
2583
2554
|
);
|
|
2584
2555
|
this.queryClient = getQueryClient();
|
|
2585
2556
|
this.query = new QueryHooks(this.queryClient, this.collections);
|
|
@@ -2745,9 +2716,34 @@ var RealtimeConnection = class {
|
|
|
2745
2716
|
function isValidWebhookEvent(data) {
|
|
2746
2717
|
if (typeof data !== "object" || data === null) return false;
|
|
2747
2718
|
const obj = data;
|
|
2748
|
-
return typeof obj.collection === "string" &&
|
|
2719
|
+
return typeof obj.collection === "string" && typeof obj.operation === "string" && obj.operation.length > 0 && typeof obj.data === "object" && obj.data !== null;
|
|
2720
|
+
}
|
|
2721
|
+
var CUSTOMER_PASSWORD_RESET_OPERATION = "password-reset";
|
|
2722
|
+
function isRecord(value) {
|
|
2723
|
+
return typeof value === "object" && value !== null;
|
|
2724
|
+
}
|
|
2725
|
+
function hasString(value, key) {
|
|
2726
|
+
return typeof value[key] === "string";
|
|
2727
|
+
}
|
|
2728
|
+
function hasStringOrNumber(value, key) {
|
|
2729
|
+
return typeof value[key] === "string" || typeof value[key] === "number";
|
|
2730
|
+
}
|
|
2731
|
+
function isCustomerPasswordResetWebhookEvent(event) {
|
|
2732
|
+
if (event.collection !== "customers" || event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION || !isRecord(event.data)) {
|
|
2733
|
+
return false;
|
|
2734
|
+
}
|
|
2735
|
+
return hasStringOrNumber(event.data, "customerId") && hasString(event.data, "email") && hasString(event.data, "name") && hasString(event.data, "resetPasswordToken") && hasString(event.data, "resetPasswordExpiresAt");
|
|
2749
2736
|
}
|
|
2750
|
-
|
|
2737
|
+
function createCustomerAuthWebhookHandler(handlers) {
|
|
2738
|
+
return async (event) => {
|
|
2739
|
+
if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {
|
|
2740
|
+
await handlers.passwordReset(event.data, event);
|
|
2741
|
+
return;
|
|
2742
|
+
}
|
|
2743
|
+
await handlers.unhandled?.(event);
|
|
2744
|
+
};
|
|
2745
|
+
}
|
|
2746
|
+
async function verifySignature(payload, secret, signature, timestamp, deliveryId) {
|
|
2751
2747
|
const encoder = new TextEncoder();
|
|
2752
2748
|
const key = await crypto.subtle.importKey(
|
|
2753
2749
|
"raw",
|
|
@@ -2762,14 +2758,35 @@ async function verifySignature(payload, secret, signature) {
|
|
|
2762
2758
|
const sigBytes = new Uint8Array(
|
|
2763
2759
|
(signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16))
|
|
2764
2760
|
);
|
|
2765
|
-
return crypto.subtle.verify(
|
|
2761
|
+
return crypto.subtle.verify(
|
|
2762
|
+
"HMAC",
|
|
2763
|
+
key,
|
|
2764
|
+
sigBytes,
|
|
2765
|
+
encoder.encode(`${timestamp}.${deliveryId}.${payload}`)
|
|
2766
|
+
);
|
|
2767
|
+
}
|
|
2768
|
+
function timestampIsFresh(timestamp, toleranceSeconds) {
|
|
2769
|
+
if (!/^\d+$/.test(timestamp)) return false;
|
|
2770
|
+
const timestampMs = Number(timestamp);
|
|
2771
|
+
if (!Number.isFinite(timestampMs)) return false;
|
|
2772
|
+
const skewMs = Math.abs(Date.now() - timestampMs);
|
|
2773
|
+
return skewMs <= toleranceSeconds * 1e3;
|
|
2766
2774
|
}
|
|
2767
2775
|
async function handleWebhook(request, handler, options) {
|
|
2768
2776
|
try {
|
|
2769
2777
|
const rawBody = await request.text();
|
|
2770
2778
|
if (options?.secret) {
|
|
2771
2779
|
const signature = request.headers.get("x-webhook-signature") || "";
|
|
2772
|
-
const
|
|
2780
|
+
const timestamp = request.headers.get("x-webhook-timestamp") || "";
|
|
2781
|
+
const deliveryId = request.headers.get("x-webhook-delivery-id") || "";
|
|
2782
|
+
const toleranceSeconds = options.toleranceSeconds ?? 300;
|
|
2783
|
+
const valid = Boolean(timestamp && deliveryId) && timestampIsFresh(timestamp, toleranceSeconds) && await verifySignature(
|
|
2784
|
+
rawBody,
|
|
2785
|
+
options.secret,
|
|
2786
|
+
signature,
|
|
2787
|
+
timestamp,
|
|
2788
|
+
deliveryId
|
|
2789
|
+
);
|
|
2773
2790
|
if (!valid) {
|
|
2774
2791
|
return new Response(
|
|
2775
2792
|
JSON.stringify({ error: "Invalid webhook signature" }),
|