@feelflow/ffid-sdk 10.0.0 → 10.1.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 +1046 -1010
- package/dist/{chunk-OXW6QSTO.js → chunk-ITSQIAO5.js} +123 -42
- package/dist/{chunk-2LU2F3F2.cjs → chunk-VHOIA25Y.cjs} +125 -41
- 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-5uxXRgIO.d.ts → ffid-client-DUbQLYTN.d.ts} +3 -2
- package/dist/{ffid-client-CumygXXz.d.cts → ffid-client-qcfCWLfs.d.cts} +3 -2
- package/dist/{index-KjewcNn1.d.cts → index-CWGoIgYL.d.cts} +2 -1
- package/dist/{index-KjewcNn1.d.ts → index-CWGoIgYL.d.ts} +2 -1
- package/dist/index.cjs +100 -88
- package/dist/index.d.cts +99 -7
- package/dist/index.d.ts +99 -7
- package/dist/index.js +2 -2
- package/dist/server/index.cjs +51 -9
- package/dist/server/index.d.cts +74 -3
- package/dist/server/index.d.ts +74 -3
- package/dist/server/index.js +49 -10
- package/dist/server/test/index.d.cts +1 -1
- package/dist/server/test/index.d.ts +1 -1
- package/package.json +131 -131
|
@@ -1374,7 +1374,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
|
|
|
1374
1374
|
};
|
|
1375
1375
|
|
|
1376
1376
|
// src/client/version-check.ts
|
|
1377
|
-
var SDK_VERSION = "10.
|
|
1377
|
+
var SDK_VERSION = "10.1.0";
|
|
1378
1378
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
1379
1379
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
1380
1380
|
function sdkHeaders() {
|
|
@@ -4609,6 +4609,50 @@ function createFFIDClient(config) {
|
|
|
4609
4609
|
};
|
|
4610
4610
|
}
|
|
4611
4611
|
|
|
4612
|
+
// src/client/authorization-error.ts
|
|
4613
|
+
var FFID_OAUTH_DENIAL_REASONS = [
|
|
4614
|
+
/** The user is not a member of the organization */
|
|
4615
|
+
"no_membership",
|
|
4616
|
+
/** The organization has no usable subscription for the service */
|
|
4617
|
+
"no_active_subscription",
|
|
4618
|
+
/** The organization has a subscription, but the user has no seat in it */
|
|
4619
|
+
"no_seat_assignment",
|
|
4620
|
+
/** The subscription has expired (canceled / past due beyond grace) */
|
|
4621
|
+
"subscription_expired",
|
|
4622
|
+
/** The flat plan's member limit is full, so no seat could be given */
|
|
4623
|
+
"member_limit_reached"
|
|
4624
|
+
];
|
|
4625
|
+
function isFFIDOAuthDenialReason(value) {
|
|
4626
|
+
return typeof value === "string" && FFID_OAUTH_DENIAL_REASONS.includes(value);
|
|
4627
|
+
}
|
|
4628
|
+
var DEFAULT_AUTHORIZATION_ERROR_MESSAGE = "\u8A8D\u53EF\u30B5\u30FC\u30D0\u30FC\u304C\u30A8\u30E9\u30FC\u3092\u8FD4\u3057\u307E\u3057\u305F";
|
|
4629
|
+
function buildAuthorizationError(params) {
|
|
4630
|
+
const oauthError = params.get("error");
|
|
4631
|
+
if (!oauthError) return null;
|
|
4632
|
+
const rawReason = params.get("denial_reason");
|
|
4633
|
+
const errorDescription = params.get("error_description");
|
|
4634
|
+
const details = {
|
|
4635
|
+
source: "authorization",
|
|
4636
|
+
denialReason: isFFIDOAuthDenialReason(rawReason) ? rawReason : null,
|
|
4637
|
+
errorDescription
|
|
4638
|
+
};
|
|
4639
|
+
return {
|
|
4640
|
+
code: oauthError,
|
|
4641
|
+
message: errorDescription ?? DEFAULT_AUTHORIZATION_ERROR_MESSAGE,
|
|
4642
|
+
details: { ...details }
|
|
4643
|
+
};
|
|
4644
|
+
}
|
|
4645
|
+
function getFFIDAuthorizationError(error) {
|
|
4646
|
+
const details = error?.details;
|
|
4647
|
+
if (!error || !details || details.source !== "authorization") return null;
|
|
4648
|
+
const description = details.errorDescription;
|
|
4649
|
+
return {
|
|
4650
|
+
oauthError: error.code,
|
|
4651
|
+
denialReason: isFFIDOAuthDenialReason(details.denialReason) ? details.denialReason : null,
|
|
4652
|
+
errorDescription: typeof description === "string" ? description : null
|
|
4653
|
+
};
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4612
4656
|
// src/client/callback.ts
|
|
4613
4657
|
var CALLBACK_ERROR_CODES = {
|
|
4614
4658
|
/** Stored state missing or did not match the callback `state` (CSRF guard) */
|
|
@@ -4633,16 +4677,43 @@ function extractSearchParams(source) {
|
|
|
4633
4677
|
return new URLSearchParams(query);
|
|
4634
4678
|
}
|
|
4635
4679
|
}
|
|
4636
|
-
|
|
4680
|
+
var CODE_CALLBACK_PARAMS = ["code", "state"];
|
|
4681
|
+
var ERROR_CALLBACK_CONSUMED_PARAMS = ["state"];
|
|
4682
|
+
function cleanCallbackUrlParams(logger, names) {
|
|
4637
4683
|
try {
|
|
4638
4684
|
const cleanUrl = new URL(window.location.href);
|
|
4639
|
-
cleanUrl.searchParams.delete(
|
|
4640
|
-
cleanUrl.searchParams.delete("state");
|
|
4685
|
+
for (const name of names) cleanUrl.searchParams.delete(name);
|
|
4641
4686
|
window.history.replaceState({}, "", cleanUrl.toString());
|
|
4642
4687
|
} catch (error) {
|
|
4643
4688
|
logger.warn("handleRedirectCallback: URL \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
4644
4689
|
}
|
|
4645
4690
|
}
|
|
4691
|
+
function validateCallbackState(client, urlState) {
|
|
4692
|
+
const { logger } = client;
|
|
4693
|
+
const storedState = retrieveState(logger);
|
|
4694
|
+
if (storedState === null && urlState === null) return null;
|
|
4695
|
+
if (storedState !== null && storedState === urlState) return null;
|
|
4696
|
+
if (storedState === null && !isStateStorageAvailable()) {
|
|
4697
|
+
logger.error(
|
|
4698
|
+
"handleRedirectCallback: OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081 CSRF \u691C\u8A3C\u304C\u3067\u304D\u307E\u305B\u3093\uFF08iOS private mode \u7B49\uFF09"
|
|
4699
|
+
);
|
|
4700
|
+
return {
|
|
4701
|
+
error: client.createError(
|
|
4702
|
+
CALLBACK_ERROR_CODES.STATE_UNAVAILABLE,
|
|
4703
|
+
"OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081\u8A8D\u8A3C\u3092\u5B8C\u4E86\u3067\u304D\u307E\u305B\u3093\u3002\u30D6\u30E9\u30A6\u30B6\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8\u30E2\u30FC\u30C9\u3084\u30B9\u30C8\u30EC\u30FC\u30B8\u8A2D\u5B9A\u3092\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044"
|
|
4704
|
+
)
|
|
4705
|
+
};
|
|
4706
|
+
}
|
|
4707
|
+
logger.error(
|
|
4708
|
+
"handleRedirectCallback: OAuth state mismatch or omitted (possible CSRF) \u2014 \u8A8D\u8A3C\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002\u6D88\u8CBB\u6E08\u307F callback \u30D1\u30E9\u30E1\u30FC\u30BF\u306E\u518D\u51E6\u7406\uFF08`cleanUrl: false` \u5229\u7528\u6642\u306E cleanup \u6F0F\u308C\u3084 reload \u7B49\uFF09\u3067\u3082\u767A\u751F\u3057\u307E\u3059"
|
|
4709
|
+
);
|
|
4710
|
+
return {
|
|
4711
|
+
error: client.createError(
|
|
4712
|
+
CALLBACK_ERROR_CODES.STATE_MISMATCH,
|
|
4713
|
+
"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"
|
|
4714
|
+
)
|
|
4715
|
+
};
|
|
4716
|
+
}
|
|
4646
4717
|
async function handleRedirectCallback(client, options) {
|
|
4647
4718
|
const { logger } = client;
|
|
4648
4719
|
const hasWindow = typeof window !== "undefined";
|
|
@@ -4659,6 +4730,24 @@ async function handleRedirectCallback(client, options) {
|
|
|
4659
4730
|
const params = extractSearchParams(source);
|
|
4660
4731
|
const code = params.get("code");
|
|
4661
4732
|
const urlState = params.get("state");
|
|
4733
|
+
const authorizationError = buildAuthorizationError(params);
|
|
4734
|
+
if (authorizationError && urlState !== null) {
|
|
4735
|
+
const stateError2 = validateCallbackState(client, urlState);
|
|
4736
|
+
if (stateError2) return stateError2;
|
|
4737
|
+
retrieveCodeVerifier(logger);
|
|
4738
|
+
logger.warn("handleRedirectCallback: \u8A8D\u53EF\u30B5\u30FC\u30D0\u30FC\u304C\u30A8\u30E9\u30FC\u3092\u8FD4\u3057\u307E\u3057\u305F:", {
|
|
4739
|
+
error: authorizationError.code,
|
|
4740
|
+
denialReason: params.get("denial_reason")
|
|
4741
|
+
});
|
|
4742
|
+
if (hasWindow) {
|
|
4743
|
+
if (options?.cleanUrl !== false) {
|
|
4744
|
+
cleanCallbackUrlParams(logger, ERROR_CALLBACK_CONSUMED_PARAMS);
|
|
4745
|
+
} else {
|
|
4746
|
+
logger.debug("handleRedirectCallback: cleanUrl=false \u306E\u305F\u3081 URL cleanup \u3092 consumer \u306B\u59D4\u8B72\u3057\u307E\u3057\u305F");
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
return { error: authorizationError };
|
|
4750
|
+
}
|
|
4662
4751
|
if (!code) {
|
|
4663
4752
|
logger.warn("handleRedirectCallback: \u8A8D\u53EF\u30B3\u30FC\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
|
|
4664
4753
|
return {
|
|
@@ -4668,37 +4757,13 @@ async function handleRedirectCallback(client, options) {
|
|
|
4668
4757
|
)
|
|
4669
4758
|
};
|
|
4670
4759
|
}
|
|
4671
|
-
const
|
|
4672
|
-
if (
|
|
4673
|
-
const stateMatches = storedState !== null && storedState === urlState;
|
|
4674
|
-
if (!stateMatches) {
|
|
4675
|
-
if (storedState === null && !isStateStorageAvailable()) {
|
|
4676
|
-
logger.error(
|
|
4677
|
-
"handleRedirectCallback: OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081 CSRF \u691C\u8A3C\u304C\u3067\u304D\u307E\u305B\u3093\uFF08iOS private mode \u7B49\uFF09"
|
|
4678
|
-
);
|
|
4679
|
-
return {
|
|
4680
|
-
error: client.createError(
|
|
4681
|
-
CALLBACK_ERROR_CODES.STATE_UNAVAILABLE,
|
|
4682
|
-
"OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081\u8A8D\u8A3C\u3092\u5B8C\u4E86\u3067\u304D\u307E\u305B\u3093\u3002\u30D6\u30E9\u30A6\u30B6\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8\u30E2\u30FC\u30C9\u3084\u30B9\u30C8\u30EC\u30FC\u30B8\u8A2D\u5B9A\u3092\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044"
|
|
4683
|
-
)
|
|
4684
|
-
};
|
|
4685
|
-
}
|
|
4686
|
-
logger.error(
|
|
4687
|
-
"handleRedirectCallback: OAuth state mismatch or omitted (possible CSRF) \u2014 \u8A8D\u8A3C\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002\u6D88\u8CBB\u6E08\u307F callback \u30D1\u30E9\u30E1\u30FC\u30BF\u306E\u518D\u51E6\u7406\uFF08`cleanUrl: false` \u5229\u7528\u6642\u306E cleanup \u6F0F\u308C\u3084 reload \u7B49\uFF09\u3067\u3082\u767A\u751F\u3057\u307E\u3059"
|
|
4688
|
-
);
|
|
4689
|
-
return {
|
|
4690
|
-
error: client.createError(
|
|
4691
|
-
CALLBACK_ERROR_CODES.STATE_MISMATCH,
|
|
4692
|
-
"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"
|
|
4693
|
-
)
|
|
4694
|
-
};
|
|
4695
|
-
}
|
|
4696
|
-
}
|
|
4760
|
+
const stateError = validateCallbackState(client, urlState);
|
|
4761
|
+
if (stateError) return stateError;
|
|
4697
4762
|
const verifier = retrieveCodeVerifier(logger);
|
|
4698
4763
|
const result = await client.exchangeCodeForTokens(code, verifier ?? void 0);
|
|
4699
4764
|
if (!result.error && hasWindow) {
|
|
4700
4765
|
if (options?.cleanUrl !== false) {
|
|
4701
|
-
cleanCallbackUrlParams(logger);
|
|
4766
|
+
cleanCallbackUrlParams(logger, CODE_CALLBACK_PARAMS);
|
|
4702
4767
|
} else {
|
|
4703
4768
|
logger.debug("handleRedirectCallback: cleanUrl=false \u306E\u305F\u3081 URL cleanup \u3092 consumer \u306B\u59D4\u8B72\u3057\u307E\u3057\u305F");
|
|
4704
4769
|
}
|
|
@@ -4707,6 +4772,13 @@ async function handleRedirectCallback(client, options) {
|
|
|
4707
4772
|
}
|
|
4708
4773
|
var DEFAULT_REFRESH_INTERVAL_MS = 5 * 60 * 1e3;
|
|
4709
4774
|
var TOKEN_REFRESH_RATIO = 0.8;
|
|
4775
|
+
function resolveCallbackKey(params) {
|
|
4776
|
+
const code = params.get("code");
|
|
4777
|
+
if (code) return code;
|
|
4778
|
+
const error = params.get("error");
|
|
4779
|
+
const state = params.get("state");
|
|
4780
|
+
return error && state ? `error:${error}:${state}` : null;
|
|
4781
|
+
}
|
|
4710
4782
|
var FFIDContext = createContext(null);
|
|
4711
4783
|
var FFIDClientContext = createContext(null);
|
|
4712
4784
|
function FFIDProvider({
|
|
@@ -4886,19 +4958,26 @@ function FFIDProvider({
|
|
|
4886
4958
|
},
|
|
4887
4959
|
[organizations, client]
|
|
4888
4960
|
);
|
|
4889
|
-
const
|
|
4961
|
+
const handledCallbackRef = useRef(null);
|
|
4962
|
+
const callbackPendingRef = useRef(false);
|
|
4963
|
+
const authorizationDeniedRef = useRef(false);
|
|
4890
4964
|
useEffect(() => {
|
|
4891
4965
|
if (client.authMode !== "token") return;
|
|
4892
4966
|
if (typeof window === "undefined") return;
|
|
4893
|
-
const
|
|
4894
|
-
|
|
4895
|
-
if (
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
client.logger.debug("
|
|
4967
|
+
const callbackKey = resolveCallbackKey(new URLSearchParams(window.location.search));
|
|
4968
|
+
if (!callbackKey) return;
|
|
4969
|
+
if (handledCallbackRef.current === callbackKey) return;
|
|
4970
|
+
handledCallbackRef.current = callbackKey;
|
|
4971
|
+
callbackPendingRef.current = true;
|
|
4972
|
+
client.logger.debug("OAuth callback detected, handling it");
|
|
4899
4973
|
handleRedirectCallback(client, { cleanUrl: cleanCallbackUrl }).then((result) => {
|
|
4900
4974
|
if (result.error) {
|
|
4901
|
-
|
|
4975
|
+
if (getFFIDAuthorizationError(result.error)) {
|
|
4976
|
+
client.logger.warn("FFID \u304C\u30ED\u30B0\u30A4\u30F3\u3092\u62D2\u5426\u3057\u307E\u3057\u305F:", result.error);
|
|
4977
|
+
authorizationDeniedRef.current = true;
|
|
4978
|
+
} else {
|
|
4979
|
+
client.logger.error("Token exchange failed:", result.error);
|
|
4980
|
+
}
|
|
4902
4981
|
if (result.error.code === FFID_ERROR_CODES.STATE_MISMATCH_ERROR && client.tokenStore.getTokens()) {
|
|
4903
4982
|
client.logger.debug(
|
|
4904
4983
|
"Stale callback rejected but stored tokens present, restoring session via refresh"
|
|
@@ -4916,13 +4995,15 @@ function FFIDProvider({
|
|
|
4916
4995
|
}).catch((err) => {
|
|
4917
4996
|
client.logger.error("Token exchange error:", err);
|
|
4918
4997
|
setIsLoading(false);
|
|
4998
|
+
}).finally(() => {
|
|
4999
|
+
callbackPendingRef.current = false;
|
|
4919
5000
|
});
|
|
4920
5001
|
}, [client]);
|
|
4921
5002
|
useEffect(() => {
|
|
4922
5003
|
if (client.authMode === "token") {
|
|
5004
|
+
if (callbackPendingRef.current || authorizationDeniedRef.current) return;
|
|
4923
5005
|
if (typeof window !== "undefined") {
|
|
4924
|
-
|
|
4925
|
-
if (urlParams.has("code")) {
|
|
5006
|
+
if (resolveCallbackKey(new URLSearchParams(window.location.search))) {
|
|
4926
5007
|
return;
|
|
4927
5008
|
}
|
|
4928
5009
|
}
|
|
@@ -6737,4 +6818,4 @@ function FFIDInquiryForm({
|
|
|
6737
6818
|
);
|
|
6738
6819
|
}
|
|
6739
6820
|
|
|
6740
|
-
export { ACCESS_GRANTING_EFFECTIVE_STATUSES, AGENCY_INVITE_COOKIE_MAX_AGE_SEC, AGENCY_INVITE_COOKIE_NAME, AGENCY_INVITE_TOKEN_PARAM, AGENCY_INVITE_TOKEN_REDACTION, BLOCKING_EFFECTIVE_STATUSES, CATALOG_HASH_PATTERN, DEFAULT_API_BASE_URL, DEFAULT_OAUTH_SCOPES, EFFECTIVE_SUBSCRIPTION_STATUSES, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDCatalogHashError, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSDKError, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, FFID_ANNOUNCEMENTS_ERROR_CODES, FFID_CATALOG_ENVIRONMENTS, FFID_CATALOG_PUBLICATION_STATUSES, FFID_COMPANY_SIZE_CODES, FFID_CREDITS_CONSUME_MAX_AMOUNT, FFID_CREDITS_CONSUME_MIN_AMOUNT, FFID_CREDITS_ERROR_CODES, FFID_CREDITS_FEATURE_PATTERN, FFID_CREDITS_HISTORY_DEFAULT_LIMIT, FFID_CREDITS_HISTORY_MAX_LIMIT, FFID_CREDITS_HISTORY_MIN_LIMIT, FFID_CREDITS_IDEMPOTENCY_KEY_PATTERN, FFID_CREDITS_LOW_THRESHOLD_PERCENT, FFID_CREDITS_METADATA_MAX_BYTES, FFID_CREDIT_GRANT_KINDS, FFID_CREDIT_HISTORY_TYPES, FFID_CREDIT_PACK_MAX_QUANTITY, FFID_CREDIT_PACK_MIN_QUANTITY, FFID_ERROR_CODES, FFID_INDUSTRY_CODES, FFID_INQUIRY_ACQUISITION_SOURCES, FFID_INQUIRY_CATEGORIES, FFID_INQUIRY_CATEGORIES_SITE_2026, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, FFID_ORGANIZATION_PROFILE_ERROR_CODES, FFID_SUBSCRIPTION_ERROR_CODES, canonicalizeCatalogValue, captureAgencyInviteToken, cleanupStateStorage, clearAgencyInviteToken, computeEffectiveStatusFromSession, computeFFIDCheckoutCopyHash, computeLegalDisclosureHash, computePaymentConfigurationHash, computePraxisCopyHash, computeScopeHash, computeTaxConfigurationHash, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, handleRedirectCallback, hasAccessFromUserinfo, hashCanonicalJson, isBlockedFromUserinfo, isFFIDInquiryAcquisitionSource, isFFIDInquiryCategorySite2026, normalizeRedirectUri, readAgencyInviteCookie, readAgencyInviteToken, redactAgencyInviteToken, retrieveCodeVerifier, retrieveState, sha256Hex, storeCodeVerifier, storeState, useFFID, useFFIDAnnouncements, useFFIDContext, useSubscription, validatePublishedCatalog, withSubscription };
|
|
6821
|
+
export { ACCESS_GRANTING_EFFECTIVE_STATUSES, AGENCY_INVITE_COOKIE_MAX_AGE_SEC, AGENCY_INVITE_COOKIE_NAME, AGENCY_INVITE_TOKEN_PARAM, AGENCY_INVITE_TOKEN_REDACTION, BLOCKING_EFFECTIVE_STATUSES, CATALOG_HASH_PATTERN, DEFAULT_API_BASE_URL, DEFAULT_OAUTH_SCOPES, EFFECTIVE_SUBSCRIPTION_STATUSES, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDCatalogHashError, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSDKError, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, FFID_ANNOUNCEMENTS_ERROR_CODES, FFID_CATALOG_ENVIRONMENTS, FFID_CATALOG_PUBLICATION_STATUSES, FFID_COMPANY_SIZE_CODES, FFID_CREDITS_CONSUME_MAX_AMOUNT, FFID_CREDITS_CONSUME_MIN_AMOUNT, FFID_CREDITS_ERROR_CODES, FFID_CREDITS_FEATURE_PATTERN, FFID_CREDITS_HISTORY_DEFAULT_LIMIT, FFID_CREDITS_HISTORY_MAX_LIMIT, FFID_CREDITS_HISTORY_MIN_LIMIT, FFID_CREDITS_IDEMPOTENCY_KEY_PATTERN, FFID_CREDITS_LOW_THRESHOLD_PERCENT, FFID_CREDITS_METADATA_MAX_BYTES, FFID_CREDIT_GRANT_KINDS, FFID_CREDIT_HISTORY_TYPES, FFID_CREDIT_PACK_MAX_QUANTITY, FFID_CREDIT_PACK_MIN_QUANTITY, FFID_ERROR_CODES, FFID_INDUSTRY_CODES, FFID_INQUIRY_ACQUISITION_SOURCES, FFID_INQUIRY_CATEGORIES, FFID_INQUIRY_CATEGORIES_SITE_2026, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, FFID_OAUTH_DENIAL_REASONS, FFID_ORGANIZATION_PROFILE_ERROR_CODES, FFID_SUBSCRIPTION_ERROR_CODES, canonicalizeCatalogValue, captureAgencyInviteToken, cleanupStateStorage, clearAgencyInviteToken, computeEffectiveStatusFromSession, computeFFIDCheckoutCopyHash, computeLegalDisclosureHash, computePaymentConfigurationHash, computePraxisCopyHash, computeScopeHash, computeTaxConfigurationHash, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, getFFIDAuthorizationError, handleRedirectCallback, hasAccessFromUserinfo, hashCanonicalJson, isBlockedFromUserinfo, isFFIDInquiryAcquisitionSource, isFFIDInquiryCategorySite2026, isFFIDOAuthDenialReason, normalizeRedirectUri, readAgencyInviteCookie, readAgencyInviteToken, redactAgencyInviteToken, retrieveCodeVerifier, retrieveState, sha256Hex, storeCodeVerifier, storeState, useFFID, useFFIDAnnouncements, useFFIDContext, useSubscription, validatePublishedCatalog, withSubscription };
|
|
@@ -1376,7 +1376,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
|
|
|
1376
1376
|
};
|
|
1377
1377
|
|
|
1378
1378
|
// src/client/version-check.ts
|
|
1379
|
-
var SDK_VERSION = "10.
|
|
1379
|
+
var SDK_VERSION = "10.1.0";
|
|
1380
1380
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
1381
1381
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
1382
1382
|
function sdkHeaders() {
|
|
@@ -4611,6 +4611,50 @@ function createFFIDClient(config) {
|
|
|
4611
4611
|
};
|
|
4612
4612
|
}
|
|
4613
4613
|
|
|
4614
|
+
// src/client/authorization-error.ts
|
|
4615
|
+
var FFID_OAUTH_DENIAL_REASONS = [
|
|
4616
|
+
/** The user is not a member of the organization */
|
|
4617
|
+
"no_membership",
|
|
4618
|
+
/** The organization has no usable subscription for the service */
|
|
4619
|
+
"no_active_subscription",
|
|
4620
|
+
/** The organization has a subscription, but the user has no seat in it */
|
|
4621
|
+
"no_seat_assignment",
|
|
4622
|
+
/** The subscription has expired (canceled / past due beyond grace) */
|
|
4623
|
+
"subscription_expired",
|
|
4624
|
+
/** The flat plan's member limit is full, so no seat could be given */
|
|
4625
|
+
"member_limit_reached"
|
|
4626
|
+
];
|
|
4627
|
+
function isFFIDOAuthDenialReason(value) {
|
|
4628
|
+
return typeof value === "string" && FFID_OAUTH_DENIAL_REASONS.includes(value);
|
|
4629
|
+
}
|
|
4630
|
+
var DEFAULT_AUTHORIZATION_ERROR_MESSAGE = "\u8A8D\u53EF\u30B5\u30FC\u30D0\u30FC\u304C\u30A8\u30E9\u30FC\u3092\u8FD4\u3057\u307E\u3057\u305F";
|
|
4631
|
+
function buildAuthorizationError(params) {
|
|
4632
|
+
const oauthError = params.get("error");
|
|
4633
|
+
if (!oauthError) return null;
|
|
4634
|
+
const rawReason = params.get("denial_reason");
|
|
4635
|
+
const errorDescription = params.get("error_description");
|
|
4636
|
+
const details = {
|
|
4637
|
+
source: "authorization",
|
|
4638
|
+
denialReason: isFFIDOAuthDenialReason(rawReason) ? rawReason : null,
|
|
4639
|
+
errorDescription
|
|
4640
|
+
};
|
|
4641
|
+
return {
|
|
4642
|
+
code: oauthError,
|
|
4643
|
+
message: errorDescription ?? DEFAULT_AUTHORIZATION_ERROR_MESSAGE,
|
|
4644
|
+
details: { ...details }
|
|
4645
|
+
};
|
|
4646
|
+
}
|
|
4647
|
+
function getFFIDAuthorizationError(error) {
|
|
4648
|
+
const details = error?.details;
|
|
4649
|
+
if (!error || !details || details.source !== "authorization") return null;
|
|
4650
|
+
const description = details.errorDescription;
|
|
4651
|
+
return {
|
|
4652
|
+
oauthError: error.code,
|
|
4653
|
+
denialReason: isFFIDOAuthDenialReason(details.denialReason) ? details.denialReason : null,
|
|
4654
|
+
errorDescription: typeof description === "string" ? description : null
|
|
4655
|
+
};
|
|
4656
|
+
}
|
|
4657
|
+
|
|
4614
4658
|
// src/client/callback.ts
|
|
4615
4659
|
var CALLBACK_ERROR_CODES = {
|
|
4616
4660
|
/** Stored state missing or did not match the callback `state` (CSRF guard) */
|
|
@@ -4635,16 +4679,43 @@ function extractSearchParams(source) {
|
|
|
4635
4679
|
return new URLSearchParams(query);
|
|
4636
4680
|
}
|
|
4637
4681
|
}
|
|
4638
|
-
|
|
4682
|
+
var CODE_CALLBACK_PARAMS = ["code", "state"];
|
|
4683
|
+
var ERROR_CALLBACK_CONSUMED_PARAMS = ["state"];
|
|
4684
|
+
function cleanCallbackUrlParams(logger, names) {
|
|
4639
4685
|
try {
|
|
4640
4686
|
const cleanUrl = new URL(window.location.href);
|
|
4641
|
-
cleanUrl.searchParams.delete(
|
|
4642
|
-
cleanUrl.searchParams.delete("state");
|
|
4687
|
+
for (const name of names) cleanUrl.searchParams.delete(name);
|
|
4643
4688
|
window.history.replaceState({}, "", cleanUrl.toString());
|
|
4644
4689
|
} catch (error) {
|
|
4645
4690
|
logger.warn("handleRedirectCallback: URL \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
4646
4691
|
}
|
|
4647
4692
|
}
|
|
4693
|
+
function validateCallbackState(client, urlState) {
|
|
4694
|
+
const { logger } = client;
|
|
4695
|
+
const storedState = retrieveState(logger);
|
|
4696
|
+
if (storedState === null && urlState === null) return null;
|
|
4697
|
+
if (storedState !== null && storedState === urlState) return null;
|
|
4698
|
+
if (storedState === null && !isStateStorageAvailable()) {
|
|
4699
|
+
logger.error(
|
|
4700
|
+
"handleRedirectCallback: OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081 CSRF \u691C\u8A3C\u304C\u3067\u304D\u307E\u305B\u3093\uFF08iOS private mode \u7B49\uFF09"
|
|
4701
|
+
);
|
|
4702
|
+
return {
|
|
4703
|
+
error: client.createError(
|
|
4704
|
+
CALLBACK_ERROR_CODES.STATE_UNAVAILABLE,
|
|
4705
|
+
"OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081\u8A8D\u8A3C\u3092\u5B8C\u4E86\u3067\u304D\u307E\u305B\u3093\u3002\u30D6\u30E9\u30A6\u30B6\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8\u30E2\u30FC\u30C9\u3084\u30B9\u30C8\u30EC\u30FC\u30B8\u8A2D\u5B9A\u3092\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044"
|
|
4706
|
+
)
|
|
4707
|
+
};
|
|
4708
|
+
}
|
|
4709
|
+
logger.error(
|
|
4710
|
+
"handleRedirectCallback: OAuth state mismatch or omitted (possible CSRF) \u2014 \u8A8D\u8A3C\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002\u6D88\u8CBB\u6E08\u307F callback \u30D1\u30E9\u30E1\u30FC\u30BF\u306E\u518D\u51E6\u7406\uFF08`cleanUrl: false` \u5229\u7528\u6642\u306E cleanup \u6F0F\u308C\u3084 reload \u7B49\uFF09\u3067\u3082\u767A\u751F\u3057\u307E\u3059"
|
|
4711
|
+
);
|
|
4712
|
+
return {
|
|
4713
|
+
error: client.createError(
|
|
4714
|
+
CALLBACK_ERROR_CODES.STATE_MISMATCH,
|
|
4715
|
+
"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"
|
|
4716
|
+
)
|
|
4717
|
+
};
|
|
4718
|
+
}
|
|
4648
4719
|
async function handleRedirectCallback(client, options) {
|
|
4649
4720
|
const { logger } = client;
|
|
4650
4721
|
const hasWindow = typeof window !== "undefined";
|
|
@@ -4661,6 +4732,24 @@ async function handleRedirectCallback(client, options) {
|
|
|
4661
4732
|
const params = extractSearchParams(source);
|
|
4662
4733
|
const code = params.get("code");
|
|
4663
4734
|
const urlState = params.get("state");
|
|
4735
|
+
const authorizationError = buildAuthorizationError(params);
|
|
4736
|
+
if (authorizationError && urlState !== null) {
|
|
4737
|
+
const stateError2 = validateCallbackState(client, urlState);
|
|
4738
|
+
if (stateError2) return stateError2;
|
|
4739
|
+
retrieveCodeVerifier(logger);
|
|
4740
|
+
logger.warn("handleRedirectCallback: \u8A8D\u53EF\u30B5\u30FC\u30D0\u30FC\u304C\u30A8\u30E9\u30FC\u3092\u8FD4\u3057\u307E\u3057\u305F:", {
|
|
4741
|
+
error: authorizationError.code,
|
|
4742
|
+
denialReason: params.get("denial_reason")
|
|
4743
|
+
});
|
|
4744
|
+
if (hasWindow) {
|
|
4745
|
+
if (options?.cleanUrl !== false) {
|
|
4746
|
+
cleanCallbackUrlParams(logger, ERROR_CALLBACK_CONSUMED_PARAMS);
|
|
4747
|
+
} else {
|
|
4748
|
+
logger.debug("handleRedirectCallback: cleanUrl=false \u306E\u305F\u3081 URL cleanup \u3092 consumer \u306B\u59D4\u8B72\u3057\u307E\u3057\u305F");
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
return { error: authorizationError };
|
|
4752
|
+
}
|
|
4664
4753
|
if (!code) {
|
|
4665
4754
|
logger.warn("handleRedirectCallback: \u8A8D\u53EF\u30B3\u30FC\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
|
|
4666
4755
|
return {
|
|
@@ -4670,37 +4759,13 @@ async function handleRedirectCallback(client, options) {
|
|
|
4670
4759
|
)
|
|
4671
4760
|
};
|
|
4672
4761
|
}
|
|
4673
|
-
const
|
|
4674
|
-
if (
|
|
4675
|
-
const stateMatches = storedState !== null && storedState === urlState;
|
|
4676
|
-
if (!stateMatches) {
|
|
4677
|
-
if (storedState === null && !isStateStorageAvailable()) {
|
|
4678
|
-
logger.error(
|
|
4679
|
-
"handleRedirectCallback: OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081 CSRF \u691C\u8A3C\u304C\u3067\u304D\u307E\u305B\u3093\uFF08iOS private mode \u7B49\uFF09"
|
|
4680
|
-
);
|
|
4681
|
-
return {
|
|
4682
|
-
error: client.createError(
|
|
4683
|
-
CALLBACK_ERROR_CODES.STATE_UNAVAILABLE,
|
|
4684
|
-
"OAuth state \u3092\u4FDD\u5B58\u3067\u304D\u308B storage \u304C\u5229\u7528\u3067\u304D\u306A\u3044\u305F\u3081\u8A8D\u8A3C\u3092\u5B8C\u4E86\u3067\u304D\u307E\u305B\u3093\u3002\u30D6\u30E9\u30A6\u30B6\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8\u30E2\u30FC\u30C9\u3084\u30B9\u30C8\u30EC\u30FC\u30B8\u8A2D\u5B9A\u3092\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044"
|
|
4685
|
-
)
|
|
4686
|
-
};
|
|
4687
|
-
}
|
|
4688
|
-
logger.error(
|
|
4689
|
-
"handleRedirectCallback: OAuth state mismatch or omitted (possible CSRF) \u2014 \u8A8D\u8A3C\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002\u6D88\u8CBB\u6E08\u307F callback \u30D1\u30E9\u30E1\u30FC\u30BF\u306E\u518D\u51E6\u7406\uFF08`cleanUrl: false` \u5229\u7528\u6642\u306E cleanup \u6F0F\u308C\u3084 reload \u7B49\uFF09\u3067\u3082\u767A\u751F\u3057\u307E\u3059"
|
|
4690
|
-
);
|
|
4691
|
-
return {
|
|
4692
|
-
error: client.createError(
|
|
4693
|
-
CALLBACK_ERROR_CODES.STATE_MISMATCH,
|
|
4694
|
-
"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"
|
|
4695
|
-
)
|
|
4696
|
-
};
|
|
4697
|
-
}
|
|
4698
|
-
}
|
|
4762
|
+
const stateError = validateCallbackState(client, urlState);
|
|
4763
|
+
if (stateError) return stateError;
|
|
4699
4764
|
const verifier = retrieveCodeVerifier(logger);
|
|
4700
4765
|
const result = await client.exchangeCodeForTokens(code, verifier ?? void 0);
|
|
4701
4766
|
if (!result.error && hasWindow) {
|
|
4702
4767
|
if (options?.cleanUrl !== false) {
|
|
4703
|
-
cleanCallbackUrlParams(logger);
|
|
4768
|
+
cleanCallbackUrlParams(logger, CODE_CALLBACK_PARAMS);
|
|
4704
4769
|
} else {
|
|
4705
4770
|
logger.debug("handleRedirectCallback: cleanUrl=false \u306E\u305F\u3081 URL cleanup \u3092 consumer \u306B\u59D4\u8B72\u3057\u307E\u3057\u305F");
|
|
4706
4771
|
}
|
|
@@ -4709,6 +4774,13 @@ async function handleRedirectCallback(client, options) {
|
|
|
4709
4774
|
}
|
|
4710
4775
|
var DEFAULT_REFRESH_INTERVAL_MS = 5 * 60 * 1e3;
|
|
4711
4776
|
var TOKEN_REFRESH_RATIO = 0.8;
|
|
4777
|
+
function resolveCallbackKey(params) {
|
|
4778
|
+
const code = params.get("code");
|
|
4779
|
+
if (code) return code;
|
|
4780
|
+
const error = params.get("error");
|
|
4781
|
+
const state = params.get("state");
|
|
4782
|
+
return error && state ? `error:${error}:${state}` : null;
|
|
4783
|
+
}
|
|
4712
4784
|
var FFIDContext = react.createContext(null);
|
|
4713
4785
|
var FFIDClientContext = react.createContext(null);
|
|
4714
4786
|
function FFIDProvider({
|
|
@@ -4888,19 +4960,26 @@ function FFIDProvider({
|
|
|
4888
4960
|
},
|
|
4889
4961
|
[organizations, client]
|
|
4890
4962
|
);
|
|
4891
|
-
const
|
|
4963
|
+
const handledCallbackRef = react.useRef(null);
|
|
4964
|
+
const callbackPendingRef = react.useRef(false);
|
|
4965
|
+
const authorizationDeniedRef = react.useRef(false);
|
|
4892
4966
|
react.useEffect(() => {
|
|
4893
4967
|
if (client.authMode !== "token") return;
|
|
4894
4968
|
if (typeof window === "undefined") return;
|
|
4895
|
-
const
|
|
4896
|
-
|
|
4897
|
-
if (
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
client.logger.debug("
|
|
4969
|
+
const callbackKey = resolveCallbackKey(new URLSearchParams(window.location.search));
|
|
4970
|
+
if (!callbackKey) return;
|
|
4971
|
+
if (handledCallbackRef.current === callbackKey) return;
|
|
4972
|
+
handledCallbackRef.current = callbackKey;
|
|
4973
|
+
callbackPendingRef.current = true;
|
|
4974
|
+
client.logger.debug("OAuth callback detected, handling it");
|
|
4901
4975
|
handleRedirectCallback(client, { cleanUrl: cleanCallbackUrl }).then((result) => {
|
|
4902
4976
|
if (result.error) {
|
|
4903
|
-
|
|
4977
|
+
if (getFFIDAuthorizationError(result.error)) {
|
|
4978
|
+
client.logger.warn("FFID \u304C\u30ED\u30B0\u30A4\u30F3\u3092\u62D2\u5426\u3057\u307E\u3057\u305F:", result.error);
|
|
4979
|
+
authorizationDeniedRef.current = true;
|
|
4980
|
+
} else {
|
|
4981
|
+
client.logger.error("Token exchange failed:", result.error);
|
|
4982
|
+
}
|
|
4904
4983
|
if (result.error.code === FFID_ERROR_CODES.STATE_MISMATCH_ERROR && client.tokenStore.getTokens()) {
|
|
4905
4984
|
client.logger.debug(
|
|
4906
4985
|
"Stale callback rejected but stored tokens present, restoring session via refresh"
|
|
@@ -4918,13 +4997,15 @@ function FFIDProvider({
|
|
|
4918
4997
|
}).catch((err) => {
|
|
4919
4998
|
client.logger.error("Token exchange error:", err);
|
|
4920
4999
|
setIsLoading(false);
|
|
5000
|
+
}).finally(() => {
|
|
5001
|
+
callbackPendingRef.current = false;
|
|
4921
5002
|
});
|
|
4922
5003
|
}, [client]);
|
|
4923
5004
|
react.useEffect(() => {
|
|
4924
5005
|
if (client.authMode === "token") {
|
|
5006
|
+
if (callbackPendingRef.current || authorizationDeniedRef.current) return;
|
|
4925
5007
|
if (typeof window !== "undefined") {
|
|
4926
|
-
|
|
4927
|
-
if (urlParams.has("code")) {
|
|
5008
|
+
if (resolveCallbackKey(new URLSearchParams(window.location.search))) {
|
|
4928
5009
|
return;
|
|
4929
5010
|
}
|
|
4930
5011
|
}
|
|
@@ -6785,6 +6866,7 @@ exports.FFID_INQUIRY_CATEGORIES = FFID_INQUIRY_CATEGORIES;
|
|
|
6785
6866
|
exports.FFID_INQUIRY_CATEGORIES_SITE_2026 = FFID_INQUIRY_CATEGORIES_SITE_2026;
|
|
6786
6867
|
exports.FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES = FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES;
|
|
6787
6868
|
exports.FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB = FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB;
|
|
6869
|
+
exports.FFID_OAUTH_DENIAL_REASONS = FFID_OAUTH_DENIAL_REASONS;
|
|
6788
6870
|
exports.FFID_ORGANIZATION_PROFILE_ERROR_CODES = FFID_ORGANIZATION_PROFILE_ERROR_CODES;
|
|
6789
6871
|
exports.FFID_SUBSCRIPTION_ERROR_CODES = FFID_SUBSCRIPTION_ERROR_CODES;
|
|
6790
6872
|
exports.canonicalizeCatalogValue = canonicalizeCatalogValue;
|
|
@@ -6803,12 +6885,14 @@ exports.createFFIDClient = createFFIDClient;
|
|
|
6803
6885
|
exports.createTokenStore = createTokenStore;
|
|
6804
6886
|
exports.generateCodeChallenge = generateCodeChallenge;
|
|
6805
6887
|
exports.generateCodeVerifier = generateCodeVerifier;
|
|
6888
|
+
exports.getFFIDAuthorizationError = getFFIDAuthorizationError;
|
|
6806
6889
|
exports.handleRedirectCallback = handleRedirectCallback;
|
|
6807
6890
|
exports.hasAccessFromUserinfo = hasAccessFromUserinfo;
|
|
6808
6891
|
exports.hashCanonicalJson = hashCanonicalJson;
|
|
6809
6892
|
exports.isBlockedFromUserinfo = isBlockedFromUserinfo;
|
|
6810
6893
|
exports.isFFIDInquiryAcquisitionSource = isFFIDInquiryAcquisitionSource;
|
|
6811
6894
|
exports.isFFIDInquiryCategorySite2026 = isFFIDInquiryCategorySite2026;
|
|
6895
|
+
exports.isFFIDOAuthDenialReason = isFFIDOAuthDenialReason;
|
|
6812
6896
|
exports.normalizeRedirectUri = normalizeRedirectUri;
|
|
6813
6897
|
exports.readAgencyInviteCookie = readAgencyInviteCookie;
|
|
6814
6898
|
exports.readAgencyInviteToken = readAgencyInviteToken;
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkVHOIA25Y_cjs = require('../chunk-VHOIA25Y.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "FFIDAnnouncementBadge", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkVHOIA25Y_cjs.FFIDAnnouncementBadge; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "FFIDAnnouncementList", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkVHOIA25Y_cjs.FFIDAnnouncementList; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "FFIDInquiryForm", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkVHOIA25Y_cjs.FFIDInquiryForm; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "FFIDLoginButton", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkVHOIA25Y_cjs.FFIDLoginButton; }
|
|
22
22
|
});
|
|
23
23
|
Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
|
|
24
24
|
enumerable: true,
|
|
25
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkVHOIA25Y_cjs.FFIDOrganizationSwitcher; }
|
|
26
26
|
});
|
|
27
27
|
Object.defineProperty(exports, "FFIDSubscriptionBadge", {
|
|
28
28
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunkVHOIA25Y_cjs.FFIDSubscriptionBadge; }
|
|
30
30
|
});
|
|
31
31
|
Object.defineProperty(exports, "FFIDUserMenu", {
|
|
32
32
|
enumerable: true,
|
|
33
|
-
get: function () { return
|
|
33
|
+
get: function () { return chunkVHOIA25Y_cjs.FFIDUserMenu; }
|
|
34
34
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a8 as FFIDAnnouncementBadge, bk as FFIDAnnouncementBadgeClassNames, bl as FFIDAnnouncementBadgeProps, a9 as FFIDAnnouncementList, bm as FFIDAnnouncementListClassNames, bn as FFIDAnnouncementListProps, ar as FFIDInquiryForm, as as FFIDInquiryFormCategoryItem, at as FFIDInquiryFormClassNames, au as FFIDInquiryFormLegalLayout, av as FFIDInquiryFormOrganization, aw as FFIDInquiryFormPlaceholderContext, ax as FFIDInquiryFormPrefill, ay as FFIDInquiryFormProps, az as FFIDInquiryFormSubmitData, aA as FFIDInquiryFormSubmitResult, aC as FFIDLoginButton, bo as FFIDLoginButtonProps, aE as FFIDOrganizationSwitcher, bp as FFIDOrganizationSwitcherClassNames, bq as FFIDOrganizationSwitcherProps, aS as FFIDSubscriptionBadge, br as FFIDSubscriptionBadgeClassNames, bs as FFIDSubscriptionBadgeProps, aW as FFIDUserMenu, bt as FFIDUserMenuClassNames, bu as FFIDUserMenuProps } from '../index-
|
|
1
|
+
export { a8 as FFIDAnnouncementBadge, bk as FFIDAnnouncementBadgeClassNames, bl as FFIDAnnouncementBadgeProps, a9 as FFIDAnnouncementList, bm as FFIDAnnouncementListClassNames, bn as FFIDAnnouncementListProps, ar as FFIDInquiryForm, as as FFIDInquiryFormCategoryItem, at as FFIDInquiryFormClassNames, au as FFIDInquiryFormLegalLayout, av as FFIDInquiryFormOrganization, aw as FFIDInquiryFormPlaceholderContext, ax as FFIDInquiryFormPrefill, ay as FFIDInquiryFormProps, az as FFIDInquiryFormSubmitData, aA as FFIDInquiryFormSubmitResult, aC as FFIDLoginButton, bo as FFIDLoginButtonProps, aE as FFIDOrganizationSwitcher, bp as FFIDOrganizationSwitcherClassNames, bq as FFIDOrganizationSwitcherProps, aS as FFIDSubscriptionBadge, br as FFIDSubscriptionBadgeClassNames, bs as FFIDSubscriptionBadgeProps, aW as FFIDUserMenu, bt as FFIDUserMenuClassNames, bu as FFIDUserMenuProps } from '../index-CWGoIgYL.cjs';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a8 as FFIDAnnouncementBadge, bk as FFIDAnnouncementBadgeClassNames, bl as FFIDAnnouncementBadgeProps, a9 as FFIDAnnouncementList, bm as FFIDAnnouncementListClassNames, bn as FFIDAnnouncementListProps, ar as FFIDInquiryForm, as as FFIDInquiryFormCategoryItem, at as FFIDInquiryFormClassNames, au as FFIDInquiryFormLegalLayout, av as FFIDInquiryFormOrganization, aw as FFIDInquiryFormPlaceholderContext, ax as FFIDInquiryFormPrefill, ay as FFIDInquiryFormProps, az as FFIDInquiryFormSubmitData, aA as FFIDInquiryFormSubmitResult, aC as FFIDLoginButton, bo as FFIDLoginButtonProps, aE as FFIDOrganizationSwitcher, bp as FFIDOrganizationSwitcherClassNames, bq as FFIDOrganizationSwitcherProps, aS as FFIDSubscriptionBadge, br as FFIDSubscriptionBadgeClassNames, bs as FFIDSubscriptionBadgeProps, aW as FFIDUserMenu, bt as FFIDUserMenuClassNames, bu as FFIDUserMenuProps } from '../index-
|
|
1
|
+
export { a8 as FFIDAnnouncementBadge, bk as FFIDAnnouncementBadgeClassNames, bl as FFIDAnnouncementBadgeProps, a9 as FFIDAnnouncementList, bm as FFIDAnnouncementListClassNames, bn as FFIDAnnouncementListProps, ar as FFIDInquiryForm, as as FFIDInquiryFormCategoryItem, at as FFIDInquiryFormClassNames, au as FFIDInquiryFormLegalLayout, av as FFIDInquiryFormOrganization, aw as FFIDInquiryFormPlaceholderContext, ax as FFIDInquiryFormPrefill, ay as FFIDInquiryFormProps, az as FFIDInquiryFormSubmitData, aA as FFIDInquiryFormSubmitResult, aC as FFIDLoginButton, bo as FFIDLoginButtonProps, aE as FFIDOrganizationSwitcher, bp as FFIDOrganizationSwitcherClassNames, bq as FFIDOrganizationSwitcherProps, aS as FFIDSubscriptionBadge, br as FFIDSubscriptionBadgeClassNames, bs as FFIDSubscriptionBadgeProps, aW as FFIDUserMenu, bt as FFIDUserMenuClassNames, bu as FFIDUserMenuProps } from '../index-CWGoIgYL.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-
|
|
1
|
+
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-ITSQIAO5.js';
|
|
@@ -1014,7 +1014,8 @@ type FFIDServiceAccessFailPolicy = 'failClosed';
|
|
|
1014
1014
|
*
|
|
1015
1015
|
* `member_limit_reached` (10.0.0) is FFID's denial reason when a flat plan's member
|
|
1016
1016
|
* limit is full and the user has no seat. It reaches you through OAuth
|
|
1017
|
-
* (`denial_reason` on authorize / userinfo
|
|
1017
|
+
* (`denial_reason` on the authorize redirect / userinfo 403; see
|
|
1018
|
+
* `FFIDOAuthDenialReason` for that vocabulary); `checkServiceAccess()`
|
|
1018
1019
|
* derives its decision from `effectiveStatus` and never returns it, because a full
|
|
1019
1020
|
* member limit does not change `hasAccess` (CREDITS_API §1-5). It is in this union so
|
|
1020
1021
|
* one exhaustive `switch` over denial reasons covers both paths.
|
|
@@ -2886,4 +2887,4 @@ declare function createFFIDClient(config: FFIDConfig): {
|
|
|
2886
2887
|
/** Type of the FFID client */
|
|
2887
2888
|
type FFIDClient = ReturnType<typeof createFFIDClient>;
|
|
2888
2889
|
|
|
2889
|
-
export { type FFIDProvisionedOrganization as $, type FFIDOrganization as A, type FFIDOrganizationLogoUploadResponse as B, type FFIDOrganizationMember as C, type FFIDOrganizationProfile as D, type FFIDOrganizationProfileErrorCode as E, type
|
|
2890
|
+
export { type FFIDProvisionedOrganization as $, type FFIDOrganization as A, type FFIDOrganizationLogoUploadResponse as B, type FFIDOrganizationMember as C, type FFIDOrganizationProfile as D, type FFIDOrganizationProfileErrorCode as E, type FFIDError as F, type FFIDOrganizationProfileResponse as G, type FFIDOtpSendResponse as H, type FFIDOtpVerifyResponse as I, type FFIDPasswordResetConfirmResponse as J, type FFIDPasswordResetResponse as K, type FFIDPasswordResetVerifyResponse as L, type FFIDProfileCallOptions as M, type FFIDProvisionMemberPlan as N, type FFIDProvisionMemberPlanStatus as O, type FFIDProvisionMemberResult as P, type FFIDProvisionMemberStatus as Q, type FFIDProvisionOrganizationDryRun as R, type FFIDProvisionOrganizationMemberInput as S, type FFIDProvisionOrganizationOutcome as T, type FFIDProvisionOrganizationParams as U, type FFIDProvisionOrganizationResponse as V, type FFIDProvisionUserDryRun as W, type FFIDProvisionUserOutcome as X, type FFIDProvisionUserParams as Y, type FFIDProvisionUserProfileInput as Z, type FFIDProvisionUserResponse as _, type FFIDLogger as a, type FFIDProvisionedUser as a0, type FFIDPublishedPlan as a1, type FFIDRemoveMemberResponse as a2, type FFIDResetSessionResponse as a3, type FFIDSubscription as a4, type FFIDUpdateMemberRoleResponse as a5, type FFIDUpdateUserProfileRequest as a6, type FFIDUploadOrganizationLogoParams as a7, type FFIDUpsertOrganizationProfileParams as a8, type FFIDUpsertOrganizationProfileRequest as a9, type FFIDUser as aa, type FFIDUserProfile as ab, FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES as ac, FFID_CATALOG_ENVIRONMENTS as ad, FFID_CATALOG_PUBLICATION_STATUSES as ae, FFID_COMPANY_SIZE_CODES as af, FFID_INDUSTRY_CODES as ag, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES as ah, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB as ai, FFID_ORGANIZATION_PROFILE_ERROR_CODES as aj, type TokenData as ak, type TokenStore as al, createFFIDClient as am, createTokenStore as an, type FFIDCacheAdapter as b, type FFIDVerifyAccessTokenOptions as c, type FFIDApiResponse as d, type FFIDOAuthUserInfo as e, type FFIDCatalogEnvironment as f, type FFIDBillingInterval as g, type FFIDTaxBehavior as h, type FFIDPublishedCatalog as i, type FFIDAddMemberParams as j, type FFIDAddMemberRequest as k, type FFIDAddMemberResponse as l, type FFIDAllowedLogoMimeType as m, type FFIDAssignableMemberRole as n, type FFIDCacheConfig as o, type FFIDCatalogPublication as p, type FFIDCatalogPublicationStatus as q, type FFIDClient as r, type FFIDCompanySizeCode as s, type FFIDConfig as t, type FFIDIndustryCode as u, type FFIDListMembersResponse as v, type FFIDListingConsentInput as w, type FFIDLogoWallEntry as x, type FFIDLogoWallResponse as y, type FFIDMemberRole as z };
|
|
@@ -1014,7 +1014,8 @@ type FFIDServiceAccessFailPolicy = 'failClosed';
|
|
|
1014
1014
|
*
|
|
1015
1015
|
* `member_limit_reached` (10.0.0) is FFID's denial reason when a flat plan's member
|
|
1016
1016
|
* limit is full and the user has no seat. It reaches you through OAuth
|
|
1017
|
-
* (`denial_reason` on authorize / userinfo
|
|
1017
|
+
* (`denial_reason` on the authorize redirect / userinfo 403; see
|
|
1018
|
+
* `FFIDOAuthDenialReason` for that vocabulary); `checkServiceAccess()`
|
|
1018
1019
|
* derives its decision from `effectiveStatus` and never returns it, because a full
|
|
1019
1020
|
* member limit does not change `hasAccess` (CREDITS_API §1-5). It is in this union so
|
|
1020
1021
|
* one exhaustive `switch` over denial reasons covers both paths.
|
|
@@ -2886,4 +2887,4 @@ declare function createFFIDClient(config: FFIDConfig): {
|
|
|
2886
2887
|
/** Type of the FFID client */
|
|
2887
2888
|
type FFIDClient = ReturnType<typeof createFFIDClient>;
|
|
2888
2889
|
|
|
2889
|
-
export { type FFIDProvisionedOrganization as $, type FFIDOrganization as A, type FFIDOrganizationLogoUploadResponse as B, type FFIDOrganizationMember as C, type FFIDOrganizationProfile as D, type FFIDOrganizationProfileErrorCode as E, type
|
|
2890
|
+
export { type FFIDProvisionedOrganization as $, type FFIDOrganization as A, type FFIDOrganizationLogoUploadResponse as B, type FFIDOrganizationMember as C, type FFIDOrganizationProfile as D, type FFIDOrganizationProfileErrorCode as E, type FFIDError as F, type FFIDOrganizationProfileResponse as G, type FFIDOtpSendResponse as H, type FFIDOtpVerifyResponse as I, type FFIDPasswordResetConfirmResponse as J, type FFIDPasswordResetResponse as K, type FFIDPasswordResetVerifyResponse as L, type FFIDProfileCallOptions as M, type FFIDProvisionMemberPlan as N, type FFIDProvisionMemberPlanStatus as O, type FFIDProvisionMemberResult as P, type FFIDProvisionMemberStatus as Q, type FFIDProvisionOrganizationDryRun as R, type FFIDProvisionOrganizationMemberInput as S, type FFIDProvisionOrganizationOutcome as T, type FFIDProvisionOrganizationParams as U, type FFIDProvisionOrganizationResponse as V, type FFIDProvisionUserDryRun as W, type FFIDProvisionUserOutcome as X, type FFIDProvisionUserParams as Y, type FFIDProvisionUserProfileInput as Z, type FFIDProvisionUserResponse as _, type FFIDLogger as a, type FFIDProvisionedUser as a0, type FFIDPublishedPlan as a1, type FFIDRemoveMemberResponse as a2, type FFIDResetSessionResponse as a3, type FFIDSubscription as a4, type FFIDUpdateMemberRoleResponse as a5, type FFIDUpdateUserProfileRequest as a6, type FFIDUploadOrganizationLogoParams as a7, type FFIDUpsertOrganizationProfileParams as a8, type FFIDUpsertOrganizationProfileRequest as a9, type FFIDUser as aa, type FFIDUserProfile as ab, FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES as ac, FFID_CATALOG_ENVIRONMENTS as ad, FFID_CATALOG_PUBLICATION_STATUSES as ae, FFID_COMPANY_SIZE_CODES as af, FFID_INDUSTRY_CODES as ag, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES as ah, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB as ai, FFID_ORGANIZATION_PROFILE_ERROR_CODES as aj, type TokenData as ak, type TokenStore as al, createFFIDClient as am, createTokenStore as an, type FFIDCacheAdapter as b, type FFIDVerifyAccessTokenOptions as c, type FFIDApiResponse as d, type FFIDOAuthUserInfo as e, type FFIDCatalogEnvironment as f, type FFIDBillingInterval as g, type FFIDTaxBehavior as h, type FFIDPublishedCatalog as i, type FFIDAddMemberParams as j, type FFIDAddMemberRequest as k, type FFIDAddMemberResponse as l, type FFIDAllowedLogoMimeType as m, type FFIDAssignableMemberRole as n, type FFIDCacheConfig as o, type FFIDCatalogPublication as p, type FFIDCatalogPublicationStatus as q, type FFIDClient as r, type FFIDCompanySizeCode as s, type FFIDConfig as t, type FFIDIndustryCode as u, type FFIDListMembersResponse as v, type FFIDListingConsentInput as w, type FFIDLogoWallEntry as x, type FFIDLogoWallResponse as y, type FFIDMemberRole as z };
|
|
@@ -962,7 +962,8 @@ type FFIDServiceAccessFailPolicy = 'failClosed';
|
|
|
962
962
|
*
|
|
963
963
|
* `member_limit_reached` (10.0.0) is FFID's denial reason when a flat plan's member
|
|
964
964
|
* limit is full and the user has no seat. It reaches you through OAuth
|
|
965
|
-
* (`denial_reason` on authorize / userinfo
|
|
965
|
+
* (`denial_reason` on the authorize redirect / userinfo 403; see
|
|
966
|
+
* `FFIDOAuthDenialReason` for that vocabulary); `checkServiceAccess()`
|
|
966
967
|
* derives its decision from `effectiveStatus` and never returns it, because a full
|
|
967
968
|
* member limit does not change `hasAccess` (CREDITS_API §1-5). It is in this union so
|
|
968
969
|
* one exhaustive `switch` over denial reasons covers both paths.
|