@feelflow/ffid-sdk 5.10.0 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-IZSL6DI7.cjs → chunk-JFFRO2Q5.cjs} +308 -11
- package/dist/{chunk-OJ3OJTIE.js → chunk-RATTQIKM.js} +304 -12
- package/dist/components/index.cjs +8 -8
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/{ffid-client-DRjzfAaS.d.cts → ffid-client-BG0Qr86U.d.ts} +228 -71
- package/dist/{ffid-client-gboJROw0.d.ts → ffid-client-C3K3sAqq.d.cts} +228 -71
- package/dist/{index-DSvX4q8E.d.cts → index-C6dnexXf.d.cts} +24 -43
- package/dist/{index-DSvX4q8E.d.ts → index-C6dnexXf.d.ts} +24 -43
- package/dist/index.cjs +56 -36
- package/dist/index.d.cts +266 -4
- package/dist/index.d.ts +266 -4
- package/dist/index.js +2 -2
- package/dist/server/index.cjs +144 -5
- package/dist/server/index.d.cts +3 -3
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +144 -5
- package/dist/server/test/index.d.cts +2 -2
- package/dist/server/test/index.d.ts +2 -2
- package/dist/{types-BYdtyO_2.d.cts → types-BeVl-z12.d.cts} +10 -1
- package/dist/{types-BYdtyO_2.d.ts → types-BeVl-z12.d.ts} +10 -1
- package/dist/webhooks/index.cjs +5 -2
- package/dist/webhooks/index.d.cts +1 -1
- package/dist/webhooks/index.d.ts +1 -1
- package/dist/webhooks/index.js +5 -2
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -118,6 +118,9 @@ function normalizeUserinfo(raw) {
|
|
|
118
118
|
return {
|
|
119
119
|
sub: raw.sub,
|
|
120
120
|
email: raw.email,
|
|
121
|
+
// #3791: undefined → undefined を保つ(false に丸めない)。古い FFID は wire に
|
|
122
|
+
// 含めないため、consumer は undefined を「未確認」ではなく「不明」として扱える。
|
|
123
|
+
emailVerified: raw.email_verified,
|
|
121
124
|
name: raw.name,
|
|
122
125
|
picture: raw.picture,
|
|
123
126
|
companyName: raw.company_name ?? null,
|
|
@@ -373,6 +376,9 @@ function createVerifyAccessToken(deps) {
|
|
|
373
376
|
const base = {
|
|
374
377
|
sub: introspectResponse.sub,
|
|
375
378
|
email: introspectResponse.email ?? null,
|
|
379
|
+
// #3791: preserve undefined (do NOT coerce to false) so introspect-strategy
|
|
380
|
+
// callers can distinguish "verified" / "not verified" / "older server".
|
|
381
|
+
email_verified: introspectResponse.email_verified,
|
|
376
382
|
name: introspectResponse.name ?? null,
|
|
377
383
|
picture: introspectResponse.picture ?? null,
|
|
378
384
|
company_name: introspectResponse.company_name ?? null,
|
|
@@ -430,6 +436,8 @@ function createVerifyAccessToken(deps) {
|
|
|
430
436
|
// src/client/billing-methods.ts
|
|
431
437
|
var BILLING_CHECKOUT_ENDPOINT = "/api/v1/billing/checkout";
|
|
432
438
|
var BILLING_PORTAL_ENDPOINT = "/api/v1/billing/portal";
|
|
439
|
+
var EXT_INVOICES_ENDPOINT = "/api/v1/billing/ext/invoices";
|
|
440
|
+
var EXT_RETRY_PAYMENT_ENDPOINT = "/api/v1/billing/ext/retry-payment";
|
|
433
441
|
function createBillingMethods(deps) {
|
|
434
442
|
const { fetchWithAuth, createError } = deps;
|
|
435
443
|
async function createCheckoutSession(params) {
|
|
@@ -471,7 +479,31 @@ function createBillingMethods(deps) {
|
|
|
471
479
|
`${BILLING_PORTAL_ENDPOINT}?${query.toString()}`
|
|
472
480
|
);
|
|
473
481
|
}
|
|
474
|
-
|
|
482
|
+
async function listInvoices(params) {
|
|
483
|
+
if (!params.organizationId) {
|
|
484
|
+
return { error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059") };
|
|
485
|
+
}
|
|
486
|
+
const query = new URLSearchParams({ organizationId: params.organizationId });
|
|
487
|
+
return fetchWithAuth(`${EXT_INVOICES_ENDPOINT}?${query.toString()}`);
|
|
488
|
+
}
|
|
489
|
+
async function getInvoice(params) {
|
|
490
|
+
if (!params.invoiceId) {
|
|
491
|
+
return { error: createError("VALIDATION_ERROR", "invoiceId \u306F\u5FC5\u9808\u3067\u3059") };
|
|
492
|
+
}
|
|
493
|
+
return fetchWithAuth(
|
|
494
|
+
`${EXT_INVOICES_ENDPOINT}/${encodeURIComponent(params.invoiceId)}`
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
async function retryPayment(params) {
|
|
498
|
+
if (!params.organizationId) {
|
|
499
|
+
return { error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059") };
|
|
500
|
+
}
|
|
501
|
+
return fetchWithAuth(EXT_RETRY_PAYMENT_ENDPOINT, {
|
|
502
|
+
method: "POST",
|
|
503
|
+
body: JSON.stringify({ organizationId: params.organizationId })
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
return { createCheckoutSession, createPortalSession, listInvoices, getInvoice, retryPayment };
|
|
475
507
|
}
|
|
476
508
|
|
|
477
509
|
// src/client/subscription-methods.ts
|
|
@@ -813,6 +845,45 @@ function createMembersMethods(deps) {
|
|
|
813
845
|
return { listMembers, addMember, updateMemberRole, removeMember };
|
|
814
846
|
}
|
|
815
847
|
|
|
848
|
+
// src/client/seat-methods.ts
|
|
849
|
+
function seatsEndpoint(subscriptionId) {
|
|
850
|
+
return `/api/v1/subscriptions/ext/${encodeURIComponent(subscriptionId)}/seats/assignments`;
|
|
851
|
+
}
|
|
852
|
+
function createSeatMethods(deps) {
|
|
853
|
+
const { fetchWithAuth, createError } = deps;
|
|
854
|
+
async function listSeatAssignments(params) {
|
|
855
|
+
if (!params.subscriptionId) {
|
|
856
|
+
return { error: createError("VALIDATION_ERROR", "subscriptionId \u306F\u5FC5\u9808\u3067\u3059") };
|
|
857
|
+
}
|
|
858
|
+
return fetchWithAuth(seatsEndpoint(params.subscriptionId));
|
|
859
|
+
}
|
|
860
|
+
async function assignSeats(params) {
|
|
861
|
+
if (!params.subscriptionId) {
|
|
862
|
+
return { error: createError("VALIDATION_ERROR", "subscriptionId \u306F\u5FC5\u9808\u3067\u3059") };
|
|
863
|
+
}
|
|
864
|
+
if (!Array.isArray(params.userIds) || params.userIds.length === 0) {
|
|
865
|
+
return { error: createError("VALIDATION_ERROR", "userIds \u306F 1 \u4EF6\u4EE5\u4E0A\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044") };
|
|
866
|
+
}
|
|
867
|
+
return fetchWithAuth(seatsEndpoint(params.subscriptionId), {
|
|
868
|
+
method: "POST",
|
|
869
|
+
body: JSON.stringify({ userIds: params.userIds })
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
async function unassignSeat(params) {
|
|
873
|
+
if (!params.subscriptionId) {
|
|
874
|
+
return { error: createError("VALIDATION_ERROR", "subscriptionId \u306F\u5FC5\u9808\u3067\u3059") };
|
|
875
|
+
}
|
|
876
|
+
if (!params.userId) {
|
|
877
|
+
return { error: createError("VALIDATION_ERROR", "userId \u306F\u5FC5\u9808\u3067\u3059") };
|
|
878
|
+
}
|
|
879
|
+
return fetchWithAuth(
|
|
880
|
+
`${seatsEndpoint(params.subscriptionId)}/${encodeURIComponent(params.userId)}`,
|
|
881
|
+
{ method: "DELETE" }
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
return { listSeatAssignments, assignSeats, unassignSeat };
|
|
885
|
+
}
|
|
886
|
+
|
|
816
887
|
// src/client/profile-methods.ts
|
|
817
888
|
var EXT_PROFILE_ENDPOINT = "/api/v1/users/ext/me";
|
|
818
889
|
function resolveAuthOverride(options, createError) {
|
|
@@ -863,7 +934,7 @@ function createProfileMethods(deps) {
|
|
|
863
934
|
}
|
|
864
935
|
|
|
865
936
|
// src/client/version-check.ts
|
|
866
|
-
var SDK_VERSION = "5.
|
|
937
|
+
var SDK_VERSION = "5.13.0";
|
|
867
938
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
868
939
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
869
940
|
function sdkHeaders() {
|
|
@@ -935,9 +1006,20 @@ function createOAuthTokenMethods(deps) {
|
|
|
935
1006
|
logger,
|
|
936
1007
|
errorCodes
|
|
937
1008
|
} = deps;
|
|
938
|
-
async function exchangeCodeForTokens(code, codeVerifier) {
|
|
1009
|
+
async function exchangeCodeForTokens(code, codeVerifier, opts) {
|
|
939
1010
|
const url = `${baseUrl}${OAUTH_TOKEN_ENDPOINT}`;
|
|
940
1011
|
logger.debug("Exchanging code for tokens:", url);
|
|
1012
|
+
if (opts?.expectedState !== void 0 || opts?.actualState !== void 0) {
|
|
1013
|
+
if (opts?.expectedState !== opts?.actualState) {
|
|
1014
|
+
logger.error("Token exchange aborted: OAuth state mismatch or omitted (possible CSRF)");
|
|
1015
|
+
return {
|
|
1016
|
+
error: {
|
|
1017
|
+
code: errorCodes.STATE_MISMATCH_ERROR,
|
|
1018
|
+
message: "OAuth state \u304C\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002CSRF \u306E\u53EF\u80FD\u6027\u304C\u3042\u308B\u305F\u3081\u8A8D\u8A3C\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F"
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
941
1023
|
const effectiveRedirectUri = resolvedRedirectUri ?? (typeof window !== "undefined" ? window.location.origin + window.location.pathname : null);
|
|
942
1024
|
if (!effectiveRedirectUri) {
|
|
943
1025
|
logger.error("redirectUri is required for token exchange in SSR environments. Set config.redirectUri explicitly.");
|
|
@@ -1382,6 +1464,46 @@ function base64UrlEncode(buffer) {
|
|
|
1382
1464
|
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1383
1465
|
}
|
|
1384
1466
|
|
|
1467
|
+
// src/auth/state.ts
|
|
1468
|
+
var STATE_STORAGE_KEY = "ffid_oauth_state";
|
|
1469
|
+
var STATE_FALLBACK_STORAGE_KEY = "ffid_oauth_state_fb";
|
|
1470
|
+
var STATE_FALLBACK_TIMESTAMP_KEY = "ffid_oauth_state_fb_ts";
|
|
1471
|
+
function storeState(state, logger) {
|
|
1472
|
+
if (typeof window === "undefined") {
|
|
1473
|
+
logger?.warn("storeState: storage is not available in SSR context");
|
|
1474
|
+
return false;
|
|
1475
|
+
}
|
|
1476
|
+
let sessionStored = false;
|
|
1477
|
+
try {
|
|
1478
|
+
window.sessionStorage.setItem(STATE_STORAGE_KEY, state);
|
|
1479
|
+
sessionStored = true;
|
|
1480
|
+
} catch (error) {
|
|
1481
|
+
logger?.warn("storeState: sessionStorage \u3078\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1482
|
+
}
|
|
1483
|
+
let localStored = false;
|
|
1484
|
+
try {
|
|
1485
|
+
window.localStorage.setItem(STATE_FALLBACK_STORAGE_KEY, state);
|
|
1486
|
+
window.localStorage.setItem(STATE_FALLBACK_TIMESTAMP_KEY, String(Date.now()));
|
|
1487
|
+
localStored = true;
|
|
1488
|
+
} catch (error) {
|
|
1489
|
+
logger?.warn("storeState: localStorage fallback \u3078\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1490
|
+
}
|
|
1491
|
+
return sessionStored || localStored;
|
|
1492
|
+
}
|
|
1493
|
+
function cleanupStateStorage(logger) {
|
|
1494
|
+
try {
|
|
1495
|
+
window.sessionStorage.removeItem(STATE_STORAGE_KEY);
|
|
1496
|
+
} catch (error) {
|
|
1497
|
+
logger?.warn("retrieveState: sessionStorage \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1498
|
+
}
|
|
1499
|
+
try {
|
|
1500
|
+
window.localStorage.removeItem(STATE_FALLBACK_STORAGE_KEY);
|
|
1501
|
+
window.localStorage.removeItem(STATE_FALLBACK_TIMESTAMP_KEY);
|
|
1502
|
+
} catch (error) {
|
|
1503
|
+
logger?.warn("retrieveState: localStorage \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1385
1507
|
// src/client/redirect.ts
|
|
1386
1508
|
var OAUTH_AUTHORIZE_ENDPOINT = "/api/v1/oauth/authorize";
|
|
1387
1509
|
var AUTH_LOGOUT_ENDPOINT = "/api/v1/auth/logout";
|
|
@@ -1513,6 +1635,7 @@ function createRedirectMethods(deps) {
|
|
|
1513
1635
|
const recentCount = getRecentRedirectCount(authorizeKey, now, logger);
|
|
1514
1636
|
if (recentCount >= REDIRECT_LOOP_THRESHOLD) {
|
|
1515
1637
|
cleanupVerifierStorage(logger);
|
|
1638
|
+
cleanupStateStorage(logger);
|
|
1516
1639
|
logger.warn("[FFID SDK] redirect loop detected \u2014 \u81EA\u52D5\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3092\u505C\u6B62\u3057\u307E\u3057\u305F", {
|
|
1517
1640
|
authorizeKey,
|
|
1518
1641
|
recentCount,
|
|
@@ -1536,6 +1659,11 @@ function createRedirectMethods(deps) {
|
|
|
1536
1659
|
return { success: false, error: errorMessage };
|
|
1537
1660
|
}
|
|
1538
1661
|
const state = generateRandomState();
|
|
1662
|
+
if (!storeState(state, logger)) {
|
|
1663
|
+
logger.error(
|
|
1664
|
+
"redirectToAuthorize: OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08storage \u5229\u7528\u4E0D\u53EF\uFF09\u3002\u30B3\u30FC\u30EB\u30D0\u30C3\u30AF\u3067\u306E CSRF \u691C\u8A3C\u304C\u5931\u6557\u3057\u307E\u3059"
|
|
1665
|
+
);
|
|
1666
|
+
}
|
|
1539
1667
|
const redirectUri = resolvedRedirectUri ?? window.location.origin + window.location.pathname;
|
|
1540
1668
|
const params = new URLSearchParams({
|
|
1541
1669
|
response_type: "code",
|
|
@@ -2250,7 +2378,8 @@ var FFID_ERROR_CODES = {
|
|
|
2250
2378
|
TOKEN_EXCHANGE_ERROR: "TOKEN_EXCHANGE_ERROR",
|
|
2251
2379
|
TOKEN_REFRESH_ERROR: "TOKEN_REFRESH_ERROR",
|
|
2252
2380
|
NO_TOKENS: "NO_TOKENS",
|
|
2253
|
-
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR"
|
|
2381
|
+
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR",
|
|
2382
|
+
STATE_MISMATCH_ERROR: "STATE_MISMATCH_ERROR"
|
|
2254
2383
|
};
|
|
2255
2384
|
var EXT_CHECK_ENDPOINT = "/api/v1/subscriptions/ext/check";
|
|
2256
2385
|
var DEFAULT_ALLOW_GRACE = true;
|
|
@@ -2608,7 +2737,11 @@ function createFFIDClient(config) {
|
|
|
2608
2737
|
}
|
|
2609
2738
|
return result;
|
|
2610
2739
|
}
|
|
2611
|
-
const { createCheckoutSession, createPortalSession } = createBillingMethods({
|
|
2740
|
+
const { createCheckoutSession, createPortalSession, listInvoices, getInvoice, retryPayment } = createBillingMethods({
|
|
2741
|
+
fetchWithAuth,
|
|
2742
|
+
createError
|
|
2743
|
+
});
|
|
2744
|
+
const { listSeatAssignments, assignSeats, unassignSeat } = createSeatMethods({
|
|
2612
2745
|
fetchWithAuth,
|
|
2613
2746
|
createError
|
|
2614
2747
|
});
|
|
@@ -2717,6 +2850,12 @@ function createFFIDClient(config) {
|
|
|
2717
2850
|
getAnalyticsConfig,
|
|
2718
2851
|
createCheckoutSession,
|
|
2719
2852
|
createPortalSession,
|
|
2853
|
+
listInvoices,
|
|
2854
|
+
getInvoice,
|
|
2855
|
+
retryPayment,
|
|
2856
|
+
listSeatAssignments,
|
|
2857
|
+
assignSeats,
|
|
2858
|
+
unassignSeat,
|
|
2720
2859
|
listPlans,
|
|
2721
2860
|
getSubscription,
|
|
2722
2861
|
subscribe,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-
|
|
2
|
-
import '../../types-
|
|
1
|
+
import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-C3K3sAqq.cjs';
|
|
2
|
+
import '../../types-BeVl-z12.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* FFID SDK - Test mode client (E2E / integration test bypass)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-
|
|
2
|
-
import '../../types-
|
|
1
|
+
import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-BG0Qr86U.js';
|
|
2
|
+
import '../../types-BeVl-z12.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* FFID SDK - Test mode client (E2E / integration test bypass)
|
|
@@ -49,6 +49,15 @@
|
|
|
49
49
|
* @see /api/v1/subscriptions/ext/check
|
|
50
50
|
* @see docs/03-implementation/EXPIRED_CONTRACT_HANDLING.md
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
declare const EFFECTIVE_SUBSCRIPTION_STATUSES: readonly ["active", "active_canceling", "past_due_grace", "blocked", "canceled", "trial_expired", "expired"];
|
|
53
|
+
/**
|
|
54
|
+
* Derived from {@link EFFECTIVE_SUBSCRIPTION_STATUSES} so the literal set has
|
|
55
|
+
* a runtime representation. The server mirrors the same const in
|
|
56
|
+
* `src/lib/common/subscription-helpers.ts`, and a server-side unit test pins
|
|
57
|
+
* element-equality between the two arrays (#3474) — convention-only sync
|
|
58
|
+
* could drift silently in the server-extending direction (a new server
|
|
59
|
+
* literal would fall through SDK consumers' `switch` defaults).
|
|
60
|
+
*/
|
|
61
|
+
type EffectiveSubscriptionStatus = (typeof EFFECTIVE_SUBSCRIPTION_STATUSES)[number];
|
|
53
62
|
|
|
54
63
|
export type { EffectiveSubscriptionStatus as E };
|
|
@@ -49,6 +49,15 @@
|
|
|
49
49
|
* @see /api/v1/subscriptions/ext/check
|
|
50
50
|
* @see docs/03-implementation/EXPIRED_CONTRACT_HANDLING.md
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
declare const EFFECTIVE_SUBSCRIPTION_STATUSES: readonly ["active", "active_canceling", "past_due_grace", "blocked", "canceled", "trial_expired", "expired"];
|
|
53
|
+
/**
|
|
54
|
+
* Derived from {@link EFFECTIVE_SUBSCRIPTION_STATUSES} so the literal set has
|
|
55
|
+
* a runtime representation. The server mirrors the same const in
|
|
56
|
+
* `src/lib/common/subscription-helpers.ts`, and a server-side unit test pins
|
|
57
|
+
* element-equality between the two arrays (#3474) — convention-only sync
|
|
58
|
+
* could drift silently in the server-extending direction (a new server
|
|
59
|
+
* literal would fall through SDK consumers' `switch` defaults).
|
|
60
|
+
*/
|
|
61
|
+
type EffectiveSubscriptionStatus = (typeof EFFECTIVE_SUBSCRIPTION_STATUSES)[number];
|
|
53
62
|
|
|
54
63
|
export type { EffectiveSubscriptionStatus as E };
|
package/dist/webhooks/index.cjs
CHANGED
|
@@ -92,6 +92,7 @@ function verifyWebhookSignature(rawBody, signatureHeader, secret, toleranceSecon
|
|
|
92
92
|
var SDK_LOG_PREFIX = "[FFID Webhook SDK]";
|
|
93
93
|
var HTTP_OK = 200;
|
|
94
94
|
var HTTP_BAD_REQUEST = 400;
|
|
95
|
+
var HTTP_INTERNAL_SERVER_ERROR = 500;
|
|
95
96
|
var noopLogger = {
|
|
96
97
|
debug: () => {
|
|
97
98
|
},
|
|
@@ -184,7 +185,8 @@ function createFFIDWebhookHandler(config) {
|
|
|
184
185
|
}).catch((error) => {
|
|
185
186
|
logger.error("Webhook processing failed:", error);
|
|
186
187
|
const message = error instanceof Error ? error.message : "Webhook processing failed";
|
|
187
|
-
|
|
188
|
+
const status = error instanceof FFIDWebhookError ? HTTP_BAD_REQUEST : HTTP_INTERNAL_SERVER_ERROR;
|
|
189
|
+
res.status(status).json({ error: message });
|
|
188
190
|
});
|
|
189
191
|
};
|
|
190
192
|
}
|
|
@@ -211,9 +213,10 @@ function createFFIDWebhookHandler(config) {
|
|
|
211
213
|
} catch (error) {
|
|
212
214
|
logger.error("Webhook processing failed:", error);
|
|
213
215
|
const message = error instanceof Error ? error.message : "Webhook processing failed";
|
|
216
|
+
const status = error instanceof FFIDWebhookError ? HTTP_BAD_REQUEST : HTTP_INTERNAL_SERVER_ERROR;
|
|
214
217
|
return new Response(
|
|
215
218
|
JSON.stringify({ error: message }),
|
|
216
|
-
{ status
|
|
219
|
+
{ status, headers: { "Content-Type": "application/json" } }
|
|
217
220
|
);
|
|
218
221
|
}
|
|
219
222
|
};
|
package/dist/webhooks/index.d.ts
CHANGED
package/dist/webhooks/index.js
CHANGED
|
@@ -90,6 +90,7 @@ function verifyWebhookSignature(rawBody, signatureHeader, secret, toleranceSecon
|
|
|
90
90
|
var SDK_LOG_PREFIX = "[FFID Webhook SDK]";
|
|
91
91
|
var HTTP_OK = 200;
|
|
92
92
|
var HTTP_BAD_REQUEST = 400;
|
|
93
|
+
var HTTP_INTERNAL_SERVER_ERROR = 500;
|
|
93
94
|
var noopLogger = {
|
|
94
95
|
debug: () => {
|
|
95
96
|
},
|
|
@@ -182,7 +183,8 @@ function createFFIDWebhookHandler(config) {
|
|
|
182
183
|
}).catch((error) => {
|
|
183
184
|
logger.error("Webhook processing failed:", error);
|
|
184
185
|
const message = error instanceof Error ? error.message : "Webhook processing failed";
|
|
185
|
-
|
|
186
|
+
const status = error instanceof FFIDWebhookError ? HTTP_BAD_REQUEST : HTTP_INTERNAL_SERVER_ERROR;
|
|
187
|
+
res.status(status).json({ error: message });
|
|
186
188
|
});
|
|
187
189
|
};
|
|
188
190
|
}
|
|
@@ -209,9 +211,10 @@ function createFFIDWebhookHandler(config) {
|
|
|
209
211
|
} catch (error) {
|
|
210
212
|
logger.error("Webhook processing failed:", error);
|
|
211
213
|
const message = error instanceof Error ? error.message : "Webhook processing failed";
|
|
214
|
+
const status = error instanceof FFIDWebhookError ? HTTP_BAD_REQUEST : HTTP_INTERNAL_SERVER_ERROR;
|
|
212
215
|
return new Response(
|
|
213
216
|
JSON.stringify({ error: message }),
|
|
214
|
-
{ status
|
|
217
|
+
{ status, headers: { "Content-Type": "application/json" } }
|
|
215
218
|
);
|
|
216
219
|
}
|
|
217
220
|
};
|