@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.js
CHANGED
|
@@ -418,7 +418,7 @@ async function parseErrorBody(response) {
|
|
|
418
418
|
};
|
|
419
419
|
try {
|
|
420
420
|
const body = await response.json();
|
|
421
|
-
const reason = typeof body.reason === "string" ? body.reason : void 0;
|
|
421
|
+
const reason = typeof body.reason === "string" ? body.reason : typeof body.code === "string" ? body.code : void 0;
|
|
422
422
|
if (body.errors && Array.isArray(body.errors)) {
|
|
423
423
|
const fieldErrors = [];
|
|
424
424
|
for (const e of body.errors) {
|
|
@@ -441,6 +441,7 @@ async function parseErrorBody(response) {
|
|
|
441
441
|
errorMessage: `HTTP ${response.status}: ${details}`,
|
|
442
442
|
userMessage: details,
|
|
443
443
|
reason,
|
|
444
|
+
body,
|
|
444
445
|
errors: fieldErrors.length > 0 ? fieldErrors : body.errors
|
|
445
446
|
};
|
|
446
447
|
}
|
|
@@ -449,17 +450,19 @@ async function parseErrorBody(response) {
|
|
|
449
450
|
return {
|
|
450
451
|
errorMessage: `HTTP ${response.status}: ${body.error}`,
|
|
451
452
|
userMessage: body.error,
|
|
452
|
-
reason
|
|
453
|
+
reason,
|
|
454
|
+
body
|
|
453
455
|
};
|
|
454
456
|
}
|
|
455
457
|
if (body.message) {
|
|
456
458
|
return {
|
|
457
459
|
errorMessage: `HTTP ${response.status}: ${body.message}`,
|
|
458
460
|
userMessage: body.message,
|
|
459
|
-
reason
|
|
461
|
+
reason,
|
|
462
|
+
body
|
|
460
463
|
};
|
|
461
464
|
}
|
|
462
|
-
return { ...fallback, reason };
|
|
465
|
+
return { ...fallback, reason, body };
|
|
463
466
|
} catch {
|
|
464
467
|
return fallback;
|
|
465
468
|
}
|
|
@@ -476,7 +479,6 @@ async function httpFetch(url, options) {
|
|
|
476
479
|
publishableKey,
|
|
477
480
|
secretKey,
|
|
478
481
|
customerToken,
|
|
479
|
-
tenantId,
|
|
480
482
|
timeout = DEFAULT_TIMEOUT,
|
|
481
483
|
debug,
|
|
482
484
|
retry,
|
|
@@ -506,9 +508,6 @@ async function httpFetch(url, options) {
|
|
|
506
508
|
if (authToken) {
|
|
507
509
|
headers.set("Authorization", `Bearer ${authToken}`);
|
|
508
510
|
}
|
|
509
|
-
if (tenantId) {
|
|
510
|
-
headers.set("X-Tenant-Id", tenantId);
|
|
511
|
-
}
|
|
512
511
|
if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
|
|
513
512
|
headers.set("Content-Type", "application/json");
|
|
514
513
|
}
|
|
@@ -675,10 +674,9 @@ async function httpFetch(url, options) {
|
|
|
675
674
|
|
|
676
675
|
// src/core/collection/http-client.ts
|
|
677
676
|
var HttpClient = class {
|
|
678
|
-
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId
|
|
677
|
+
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId) {
|
|
679
678
|
this.publishableKey = publishableKey;
|
|
680
679
|
this.secretKey = secretKey;
|
|
681
|
-
this.tenantId = tenantId;
|
|
682
680
|
this.getCustomerToken = getCustomerToken;
|
|
683
681
|
this.onUnauthorized = onUnauthorized;
|
|
684
682
|
this.onRequestId = onRequestId;
|
|
@@ -688,9 +686,6 @@ var HttpClient = class {
|
|
|
688
686
|
publishableKey: this.publishableKey,
|
|
689
687
|
secretKey: this.secretKey
|
|
690
688
|
};
|
|
691
|
-
if (this.secretKey?.startsWith("pat01_") && this.tenantId) {
|
|
692
|
-
opts.tenantId = this.tenantId;
|
|
693
|
-
}
|
|
694
689
|
const token = this.getCustomerToken?.();
|
|
695
690
|
if (token) {
|
|
696
691
|
opts.customerToken = token;
|
|
@@ -966,8 +961,6 @@ var INTERNAL_COLLECTIONS = [
|
|
|
966
961
|
"track-assets",
|
|
967
962
|
"audiences",
|
|
968
963
|
"email-logs",
|
|
969
|
-
"tenant-auth-settings",
|
|
970
|
-
"tenant-community-settings",
|
|
971
964
|
"api-usage",
|
|
972
965
|
"tenant-analytics-daily",
|
|
973
966
|
"analytics-event-schemas",
|
|
@@ -981,7 +974,8 @@ var INTERNAL_COLLECTIONS = [
|
|
|
981
974
|
"webhook-deliveries",
|
|
982
975
|
"audit-logs",
|
|
983
976
|
"plans",
|
|
984
|
-
"webhooks"
|
|
977
|
+
"webhooks",
|
|
978
|
+
"event-registrations"
|
|
985
979
|
];
|
|
986
980
|
var COLLECTIONS = [
|
|
987
981
|
"tenants",
|
|
@@ -1015,10 +1009,10 @@ var COLLECTIONS = [
|
|
|
1015
1009
|
"documents",
|
|
1016
1010
|
"document-categories",
|
|
1017
1011
|
"document-types",
|
|
1018
|
-
"
|
|
1019
|
-
"
|
|
1020
|
-
"
|
|
1021
|
-
"
|
|
1012
|
+
"articles",
|
|
1013
|
+
"article-authors",
|
|
1014
|
+
"article-categories",
|
|
1015
|
+
"article-tags",
|
|
1022
1016
|
"playlists",
|
|
1023
1017
|
"playlist-categories",
|
|
1024
1018
|
"playlist-tags",
|
|
@@ -1047,14 +1041,19 @@ var COLLECTIONS = [
|
|
|
1047
1041
|
"forms",
|
|
1048
1042
|
"form-submissions",
|
|
1049
1043
|
// Community
|
|
1050
|
-
"
|
|
1044
|
+
"posts",
|
|
1051
1045
|
"comments",
|
|
1052
1046
|
"reactions",
|
|
1053
1047
|
"reaction-types",
|
|
1054
1048
|
"bookmarks",
|
|
1055
|
-
"
|
|
1049
|
+
"post-categories",
|
|
1056
1050
|
"reports",
|
|
1057
|
-
"community-bans"
|
|
1051
|
+
"community-bans",
|
|
1052
|
+
// Events
|
|
1053
|
+
"event-calendars",
|
|
1054
|
+
"events",
|
|
1055
|
+
"event-occurrences",
|
|
1056
|
+
"event-tags"
|
|
1058
1057
|
];
|
|
1059
1058
|
|
|
1060
1059
|
// src/core/api/parse-response.ts
|
|
@@ -1108,7 +1107,6 @@ var CommunityClient = class {
|
|
|
1108
1107
|
constructor(options) {
|
|
1109
1108
|
this.publishableKey = options.publishableKey ?? "";
|
|
1110
1109
|
this.secretKey = options.secretKey;
|
|
1111
|
-
this.tenantId = options.tenantId;
|
|
1112
1110
|
this.customerToken = options.customerToken;
|
|
1113
1111
|
this.onUnauthorized = options.onUnauthorized;
|
|
1114
1112
|
this.onRequestId = options.onRequestId;
|
|
@@ -1120,13 +1118,11 @@ var CommunityClient = class {
|
|
|
1120
1118
|
}
|
|
1121
1119
|
async execute(endpoint, method, body) {
|
|
1122
1120
|
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
1123
|
-
const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
|
|
1124
1121
|
try {
|
|
1125
1122
|
const response = await httpFetch(endpoint, {
|
|
1126
1123
|
method,
|
|
1127
1124
|
publishableKey: this.publishableKey,
|
|
1128
1125
|
secretKey: this.secretKey,
|
|
1129
|
-
tenantId,
|
|
1130
1126
|
customerToken: token ?? void 0,
|
|
1131
1127
|
...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
|
|
1132
1128
|
...body !== void 0 && { body: JSON.stringify(body) }
|
|
@@ -1139,49 +1135,48 @@ var CommunityClient = class {
|
|
|
1139
1135
|
throw err;
|
|
1140
1136
|
}
|
|
1141
1137
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
return this.execute("/api/threads", "POST", params);
|
|
1138
|
+
createPost(params) {
|
|
1139
|
+
return this.execute("/api/posts", "POST", params);
|
|
1145
1140
|
}
|
|
1146
|
-
|
|
1141
|
+
getMyPosts(params) {
|
|
1147
1142
|
return this.execute(
|
|
1148
|
-
`/api/
|
|
1143
|
+
`/api/posts/my${this.buildQuery(params)}`,
|
|
1149
1144
|
"GET"
|
|
1150
1145
|
);
|
|
1151
1146
|
}
|
|
1152
1147
|
getTrending(params) {
|
|
1153
1148
|
return this.execute(
|
|
1154
|
-
`/api/
|
|
1149
|
+
`/api/posts/trending${this.buildQuery(params)}`,
|
|
1155
1150
|
"GET"
|
|
1156
1151
|
);
|
|
1157
1152
|
}
|
|
1158
1153
|
incrementView(params) {
|
|
1159
1154
|
return this.execute(
|
|
1160
|
-
`/api/
|
|
1155
|
+
`/api/posts/${params.postId}/view`,
|
|
1161
1156
|
"POST"
|
|
1162
1157
|
);
|
|
1163
1158
|
}
|
|
1164
|
-
|
|
1165
|
-
const {
|
|
1159
|
+
reportPost(params) {
|
|
1160
|
+
const { postId, ...body } = params;
|
|
1166
1161
|
return this.execute(
|
|
1167
|
-
`/api/
|
|
1162
|
+
`/api/posts/${postId}/report`,
|
|
1168
1163
|
"POST",
|
|
1169
1164
|
body
|
|
1170
1165
|
);
|
|
1171
1166
|
}
|
|
1172
1167
|
// Comments
|
|
1173
1168
|
createComment(params) {
|
|
1174
|
-
const {
|
|
1175
|
-
const body = {
|
|
1169
|
+
const { postId, parentId, body: commentBody } = params;
|
|
1170
|
+
const body = { post: postId, body: commentBody };
|
|
1176
1171
|
if (parentId !== void 0) {
|
|
1177
1172
|
body.parent = parentId;
|
|
1178
1173
|
}
|
|
1179
1174
|
return this.execute("/api/comments", "POST", body);
|
|
1180
1175
|
}
|
|
1181
1176
|
listComments(params) {
|
|
1182
|
-
const {
|
|
1177
|
+
const { postId, page, limit, rootComment } = params;
|
|
1183
1178
|
const urlParams = new URLSearchParams();
|
|
1184
|
-
urlParams.set("where[
|
|
1179
|
+
urlParams.set("where[post][equals]", postId);
|
|
1185
1180
|
urlParams.set("sort", "-createdAt");
|
|
1186
1181
|
if (limit !== void 0) urlParams.set("limit", String(limit));
|
|
1187
1182
|
if (page !== void 0) urlParams.set("page", String(page));
|
|
@@ -1215,16 +1210,16 @@ var CommunityClient = class {
|
|
|
1215
1210
|
}
|
|
1216
1211
|
// Reactions
|
|
1217
1212
|
addReaction(params) {
|
|
1218
|
-
const {
|
|
1213
|
+
const { postId, type } = params;
|
|
1219
1214
|
return this.execute("/api/reactions", "POST", {
|
|
1220
|
-
|
|
1215
|
+
post: postId,
|
|
1221
1216
|
type
|
|
1222
1217
|
});
|
|
1223
1218
|
}
|
|
1224
1219
|
removeReaction(params) {
|
|
1225
|
-
const {
|
|
1220
|
+
const { postId, type } = params;
|
|
1226
1221
|
return this.execute(
|
|
1227
|
-
`/api/
|
|
1222
|
+
`/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,
|
|
1228
1223
|
"DELETE"
|
|
1229
1224
|
);
|
|
1230
1225
|
}
|
|
@@ -1244,7 +1239,7 @@ var CommunityClient = class {
|
|
|
1244
1239
|
}
|
|
1245
1240
|
getReactionSummary(params) {
|
|
1246
1241
|
return this.execute(
|
|
1247
|
-
`/api/
|
|
1242
|
+
`/api/posts/${params.postId}/reactions`,
|
|
1248
1243
|
"GET"
|
|
1249
1244
|
);
|
|
1250
1245
|
}
|
|
@@ -1257,12 +1252,12 @@ var CommunityClient = class {
|
|
|
1257
1252
|
// Bookmarks
|
|
1258
1253
|
addBookmark(params) {
|
|
1259
1254
|
return this.execute("/api/bookmarks", "POST", {
|
|
1260
|
-
|
|
1255
|
+
post: params.postId
|
|
1261
1256
|
});
|
|
1262
1257
|
}
|
|
1263
1258
|
removeBookmark(params) {
|
|
1264
1259
|
return this.execute(
|
|
1265
|
-
`/api/
|
|
1260
|
+
`/api/posts/${params.postId}/bookmark`,
|
|
1266
1261
|
"DELETE"
|
|
1267
1262
|
);
|
|
1268
1263
|
}
|
|
@@ -1282,18 +1277,15 @@ var BaseApi = class {
|
|
|
1282
1277
|
}
|
|
1283
1278
|
this.publishableKey = options.publishableKey ?? "";
|
|
1284
1279
|
this.secretKey = options.secretKey;
|
|
1285
|
-
this.tenantId = options.tenantId;
|
|
1286
1280
|
this.onRequestId = options.onRequestId;
|
|
1287
1281
|
}
|
|
1288
1282
|
async request(endpoint, body, options) {
|
|
1289
1283
|
const method = options?.method ?? "POST";
|
|
1290
|
-
const tenantId = this.secretKey.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
|
|
1291
1284
|
try {
|
|
1292
1285
|
const response = await httpFetch(endpoint, {
|
|
1293
1286
|
method,
|
|
1294
1287
|
publishableKey: this.publishableKey,
|
|
1295
1288
|
secretKey: this.secretKey,
|
|
1296
|
-
tenantId,
|
|
1297
1289
|
...body !== void 0 && { body: JSON.stringify(body) },
|
|
1298
1290
|
...options?.headers && { headers: options.headers }
|
|
1299
1291
|
});
|
|
@@ -1470,15 +1462,6 @@ var CustomerAuth = class {
|
|
|
1470
1462
|
body: JSON.stringify({ currentPassword, newPassword })
|
|
1471
1463
|
});
|
|
1472
1464
|
}
|
|
1473
|
-
/**
|
|
1474
|
-
* Verify email using the verification token
|
|
1475
|
-
*/
|
|
1476
|
-
async verifyEmail(token) {
|
|
1477
|
-
await this.requestJson("/api/customers/verify-email", {
|
|
1478
|
-
method: "POST",
|
|
1479
|
-
body: JSON.stringify({ token })
|
|
1480
|
-
});
|
|
1481
|
-
}
|
|
1482
1465
|
/**
|
|
1483
1466
|
* Get the authenticated customer's orders with pagination and optional status filter
|
|
1484
1467
|
*/
|
|
@@ -1588,20 +1571,17 @@ var CartApi = class {
|
|
|
1588
1571
|
}
|
|
1589
1572
|
this.publishableKey = options.publishableKey ?? "";
|
|
1590
1573
|
this.secretKey = options.secretKey;
|
|
1591
|
-
this.tenantId = options.tenantId;
|
|
1592
1574
|
this.customerToken = options.customerToken;
|
|
1593
1575
|
this.onUnauthorized = options.onUnauthorized;
|
|
1594
1576
|
this.onRequestId = options.onRequestId;
|
|
1595
1577
|
}
|
|
1596
1578
|
async execute(endpoint, method, body) {
|
|
1597
1579
|
const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
|
|
1598
|
-
const tenantId = this.secretKey?.startsWith("pat01_") && this.tenantId ? this.tenantId : void 0;
|
|
1599
1580
|
try {
|
|
1600
1581
|
const response = await httpFetch(endpoint, {
|
|
1601
1582
|
method,
|
|
1602
1583
|
publishableKey: this.publishableKey,
|
|
1603
1584
|
secretKey: this.secretKey,
|
|
1604
|
-
tenantId,
|
|
1605
1585
|
customerToken: token ?? void 0,
|
|
1606
1586
|
...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
|
|
1607
1587
|
...body !== void 0 && { body: JSON.stringify(body) }
|
|
@@ -1788,7 +1768,6 @@ var ServerCommerceClient = class {
|
|
|
1788
1768
|
const serverOptions = {
|
|
1789
1769
|
publishableKey: options.publishableKey,
|
|
1790
1770
|
secretKey: options.secretKey,
|
|
1791
|
-
tenantId: options.tenantId,
|
|
1792
1771
|
onRequestId: options.onRequestId
|
|
1793
1772
|
};
|
|
1794
1773
|
const productApi = new ProductApi(serverOptions);
|
|
@@ -2216,14 +2195,6 @@ var CustomerHooks = class {
|
|
|
2216
2195
|
options
|
|
2217
2196
|
);
|
|
2218
2197
|
}
|
|
2219
|
-
useCustomerVerifyEmail(options) {
|
|
2220
|
-
return createMutation(
|
|
2221
|
-
(token) => this.ensureCustomerAuth().verifyEmail(token).then(() => {
|
|
2222
|
-
}),
|
|
2223
|
-
options,
|
|
2224
|
-
this.invalidateMe
|
|
2225
|
-
);
|
|
2226
|
-
}
|
|
2227
2198
|
useCustomerRefreshToken(options) {
|
|
2228
2199
|
return createMutation(
|
|
2229
2200
|
() => this.ensureCustomerAuth().refreshToken(),
|
|
@@ -2268,7 +2239,6 @@ var QueryHooks = class extends CollectionHooks {
|
|
|
2268
2239
|
this.useCustomerLogout = (...args) => this._customer.useCustomerLogout(...args);
|
|
2269
2240
|
this.useCustomerForgotPassword = (...args) => this._customer.useCustomerForgotPassword(...args);
|
|
2270
2241
|
this.useCustomerResetPassword = (...args) => this._customer.useCustomerResetPassword(...args);
|
|
2271
|
-
this.useCustomerVerifyEmail = (...args) => this._customer.useCustomerVerifyEmail(...args);
|
|
2272
2242
|
this.useCustomerRefreshToken = (...args) => this._customer.useCustomerRefreshToken(...args);
|
|
2273
2243
|
this.useCustomerUpdateProfile = (...args) => this._customer.useCustomerUpdateProfile(...args);
|
|
2274
2244
|
this.useCustomerChangePassword = (...args) => this._customer.useCustomerChangePassword(...args);
|
|
@@ -2468,7 +2438,6 @@ var ServerClient = class {
|
|
|
2468
2438
|
const serverOptions = {
|
|
2469
2439
|
publishableKey: this.config.publishableKey,
|
|
2470
2440
|
secretKey: this.config.secretKey,
|
|
2471
|
-
tenantId: this.config.tenantId,
|
|
2472
2441
|
onRequestId
|
|
2473
2442
|
};
|
|
2474
2443
|
this.commerce = new ServerCommerceClient(serverOptions);
|
|
@@ -2485,8 +2454,7 @@ var ServerClient = class {
|
|
|
2485
2454
|
this.config.secretKey,
|
|
2486
2455
|
void 0,
|
|
2487
2456
|
void 0,
|
|
2488
|
-
onRequestId
|
|
2489
|
-
this.config.tenantId
|
|
2457
|
+
onRequestId
|
|
2490
2458
|
);
|
|
2491
2459
|
this.queryClient = getQueryClient();
|
|
2492
2460
|
this.query = new QueryHooks(this.queryClient, this.collections);
|
|
@@ -2652,9 +2620,34 @@ var RealtimeConnection = class {
|
|
|
2652
2620
|
function isValidWebhookEvent(data) {
|
|
2653
2621
|
if (typeof data !== "object" || data === null) return false;
|
|
2654
2622
|
const obj = data;
|
|
2655
|
-
return typeof obj.collection === "string" &&
|
|
2623
|
+
return typeof obj.collection === "string" && typeof obj.operation === "string" && obj.operation.length > 0 && typeof obj.data === "object" && obj.data !== null;
|
|
2624
|
+
}
|
|
2625
|
+
var CUSTOMER_PASSWORD_RESET_OPERATION = "password-reset";
|
|
2626
|
+
function isRecord(value) {
|
|
2627
|
+
return typeof value === "object" && value !== null;
|
|
2628
|
+
}
|
|
2629
|
+
function hasString(value, key) {
|
|
2630
|
+
return typeof value[key] === "string";
|
|
2631
|
+
}
|
|
2632
|
+
function hasStringOrNumber(value, key) {
|
|
2633
|
+
return typeof value[key] === "string" || typeof value[key] === "number";
|
|
2634
|
+
}
|
|
2635
|
+
function isCustomerPasswordResetWebhookEvent(event) {
|
|
2636
|
+
if (event.collection !== "customers" || event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION || !isRecord(event.data)) {
|
|
2637
|
+
return false;
|
|
2638
|
+
}
|
|
2639
|
+
return hasStringOrNumber(event.data, "customerId") && hasString(event.data, "email") && hasString(event.data, "name") && hasString(event.data, "resetPasswordToken") && hasString(event.data, "resetPasswordExpiresAt");
|
|
2656
2640
|
}
|
|
2657
|
-
|
|
2641
|
+
function createCustomerAuthWebhookHandler(handlers) {
|
|
2642
|
+
return async (event) => {
|
|
2643
|
+
if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {
|
|
2644
|
+
await handlers.passwordReset(event.data, event);
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2647
|
+
await handlers.unhandled?.(event);
|
|
2648
|
+
};
|
|
2649
|
+
}
|
|
2650
|
+
async function verifySignature(payload, secret, signature, timestamp, deliveryId) {
|
|
2658
2651
|
const encoder = new TextEncoder();
|
|
2659
2652
|
const key = await crypto.subtle.importKey(
|
|
2660
2653
|
"raw",
|
|
@@ -2669,14 +2662,35 @@ async function verifySignature(payload, secret, signature) {
|
|
|
2669
2662
|
const sigBytes = new Uint8Array(
|
|
2670
2663
|
(signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16))
|
|
2671
2664
|
);
|
|
2672
|
-
return crypto.subtle.verify(
|
|
2665
|
+
return crypto.subtle.verify(
|
|
2666
|
+
"HMAC",
|
|
2667
|
+
key,
|
|
2668
|
+
sigBytes,
|
|
2669
|
+
encoder.encode(`${timestamp}.${deliveryId}.${payload}`)
|
|
2670
|
+
);
|
|
2671
|
+
}
|
|
2672
|
+
function timestampIsFresh(timestamp, toleranceSeconds) {
|
|
2673
|
+
if (!/^\d+$/.test(timestamp)) return false;
|
|
2674
|
+
const timestampMs = Number(timestamp);
|
|
2675
|
+
if (!Number.isFinite(timestampMs)) return false;
|
|
2676
|
+
const skewMs = Math.abs(Date.now() - timestampMs);
|
|
2677
|
+
return skewMs <= toleranceSeconds * 1e3;
|
|
2673
2678
|
}
|
|
2674
2679
|
async function handleWebhook(request, handler, options) {
|
|
2675
2680
|
try {
|
|
2676
2681
|
const rawBody = await request.text();
|
|
2677
2682
|
if (options?.secret) {
|
|
2678
2683
|
const signature = request.headers.get("x-webhook-signature") || "";
|
|
2679
|
-
const
|
|
2684
|
+
const timestamp = request.headers.get("x-webhook-timestamp") || "";
|
|
2685
|
+
const deliveryId = request.headers.get("x-webhook-delivery-id") || "";
|
|
2686
|
+
const toleranceSeconds = options.toleranceSeconds ?? 300;
|
|
2687
|
+
const valid = Boolean(timestamp && deliveryId) && timestampIsFresh(timestamp, toleranceSeconds) && await verifySignature(
|
|
2688
|
+
rawBody,
|
|
2689
|
+
options.secret,
|
|
2690
|
+
signature,
|
|
2691
|
+
timestamp,
|
|
2692
|
+
deliveryId
|
|
2693
|
+
);
|
|
2680
2694
|
if (!valid) {
|
|
2681
2695
|
return new Response(
|
|
2682
2696
|
JSON.stringify({ error: "Invalid webhook signature" }),
|
|
@@ -3244,6 +3258,7 @@ export {
|
|
|
3244
3258
|
AuthError,
|
|
3245
3259
|
BaseApi,
|
|
3246
3260
|
COLLECTIONS,
|
|
3261
|
+
CUSTOMER_PASSWORD_RESET_OPERATION,
|
|
3247
3262
|
CartApi,
|
|
3248
3263
|
Client,
|
|
3249
3264
|
CollectionClient,
|
|
@@ -3285,6 +3300,7 @@ export {
|
|
|
3285
3300
|
createAuthError,
|
|
3286
3301
|
createClient,
|
|
3287
3302
|
createConflictError,
|
|
3303
|
+
createCustomerAuthWebhookHandler,
|
|
3288
3304
|
createNotFoundError,
|
|
3289
3305
|
createPermissionError,
|
|
3290
3306
|
createRateLimitError,
|
|
@@ -3311,6 +3327,7 @@ export {
|
|
|
3311
3327
|
isAuthError,
|
|
3312
3328
|
isConfigError,
|
|
3313
3329
|
isConflictError,
|
|
3330
|
+
isCustomerPasswordResetWebhookEvent,
|
|
3314
3331
|
isGoneError,
|
|
3315
3332
|
isNetworkError,
|
|
3316
3333
|
isNotFoundError,
|