@feelflow/ffid-sdk 5.12.0 → 5.14.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-KB2JG64Z.js → chunk-4II4R7NR.js} +392 -10
- package/dist/{chunk-AOJDV3UO.cjs → chunk-BVDUQQHP.cjs} +395 -9
- 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-5IprSUVR.d.ts → ffid-client-9-lh0G_h.d.ts} +384 -134
- package/dist/{ffid-client-Dx4oc4Cw.d.cts → ffid-client-CKFxY60u.d.cts} +384 -134
- package/dist/{index-DqsWKU16.d.cts → index-CsVJTuPv.d.cts} +14 -112
- package/dist/{index-DqsWKU16.d.ts → index-CsVJTuPv.d.ts} +14 -112
- package/dist/index.cjs +53 -37
- package/dist/index.d.cts +436 -4
- package/dist/index.d.ts +436 -4
- package/dist/index.js +2 -2
- package/dist/legal/index.cjs +14 -0
- package/dist/legal/index.d.cts +16 -1
- package/dist/legal/index.d.ts +16 -1
- package/dist/legal/index.js +14 -0
- package/dist/server/index.cjs +241 -3
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +241 -3
- package/dist/server/test/index.d.cts +1 -1
- package/dist/server/test/index.d.ts +1 -1
- package/dist/webhooks/index.cjs +5 -2
- package/dist/webhooks/index.js +5 -2
- package/package.json +1 -1
package/dist/server/index.cjs
CHANGED
|
@@ -119,6 +119,9 @@ function normalizeUserinfo(raw) {
|
|
|
119
119
|
return {
|
|
120
120
|
sub: raw.sub,
|
|
121
121
|
email: raw.email,
|
|
122
|
+
// #3791: undefined → undefined を保つ(false に丸めない)。古い FFID は wire に
|
|
123
|
+
// 含めないため、consumer は undefined を「未確認」ではなく「不明」として扱える。
|
|
124
|
+
emailVerified: raw.email_verified,
|
|
122
125
|
name: raw.name,
|
|
123
126
|
picture: raw.picture,
|
|
124
127
|
companyName: raw.company_name ?? null,
|
|
@@ -374,6 +377,9 @@ function createVerifyAccessToken(deps) {
|
|
|
374
377
|
const base = {
|
|
375
378
|
sub: introspectResponse.sub,
|
|
376
379
|
email: introspectResponse.email ?? null,
|
|
380
|
+
// #3791: preserve undefined (do NOT coerce to false) so introspect-strategy
|
|
381
|
+
// callers can distinguish "verified" / "not verified" / "older server".
|
|
382
|
+
email_verified: introspectResponse.email_verified,
|
|
377
383
|
name: introspectResponse.name ?? null,
|
|
378
384
|
picture: introspectResponse.picture ?? null,
|
|
379
385
|
company_name: introspectResponse.company_name ?? null,
|
|
@@ -928,8 +934,163 @@ function createProfileMethods(deps) {
|
|
|
928
934
|
return { getProfile, updateProfile };
|
|
929
935
|
}
|
|
930
936
|
|
|
937
|
+
// src/client/login-history-methods.ts
|
|
938
|
+
var EXT_LOGIN_HISTORY_ENDPOINT = "/api/v1/users/ext/me/login-history";
|
|
939
|
+
function createLoginHistoryMethods(deps) {
|
|
940
|
+
const { fetchWithAuth, createError } = deps;
|
|
941
|
+
async function getLoginHistory(params) {
|
|
942
|
+
if (params?.limit !== void 0 && (!Number.isInteger(params.limit) || params.limit <= 0)) {
|
|
943
|
+
return {
|
|
944
|
+
error: createError(
|
|
945
|
+
"VALIDATION_ERROR",
|
|
946
|
+
"limit \u306F1\u4EE5\u4E0A\u306E\u6574\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
947
|
+
)
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
const query = new URLSearchParams();
|
|
951
|
+
if (params?.userId !== void 0) {
|
|
952
|
+
query.set("userId", params.userId);
|
|
953
|
+
}
|
|
954
|
+
if (params?.limit !== void 0) {
|
|
955
|
+
query.set("limit", String(params.limit));
|
|
956
|
+
}
|
|
957
|
+
const queryString = query.toString();
|
|
958
|
+
const endpoint = queryString ? `${EXT_LOGIN_HISTORY_ENDPOINT}?${queryString}` : EXT_LOGIN_HISTORY_ENDPOINT;
|
|
959
|
+
return fetchWithAuth(endpoint);
|
|
960
|
+
}
|
|
961
|
+
return { getLoginHistory };
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// src/client/organization-domains-methods.ts
|
|
965
|
+
var EXT_DOMAINS_ENDPOINT = "/api/v1/organizations/ext/domains";
|
|
966
|
+
function createOrganizationDomainsMethods(deps) {
|
|
967
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
968
|
+
function buildQuery(organizationId) {
|
|
969
|
+
return new URLSearchParams({ organizationId, serviceCode }).toString();
|
|
970
|
+
}
|
|
971
|
+
async function getOrganizationDomains(params) {
|
|
972
|
+
if (!params.organizationId) {
|
|
973
|
+
return {
|
|
974
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
return fetchWithAuth(
|
|
978
|
+
`${EXT_DOMAINS_ENDPOINT}?${buildQuery(params.organizationId)}`
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
return { getOrganizationDomains };
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// src/client/notification-preferences-methods.ts
|
|
985
|
+
var EXT_NOTIFICATION_PREFERENCES_ENDPOINT = "/api/v1/organizations/ext/notification-preferences";
|
|
986
|
+
function createNotificationPreferencesMethods(deps) {
|
|
987
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
988
|
+
function buildQuery(organizationId) {
|
|
989
|
+
return new URLSearchParams({ organizationId, serviceCode }).toString();
|
|
990
|
+
}
|
|
991
|
+
async function getNotificationPreferences(params) {
|
|
992
|
+
if (!params.organizationId) {
|
|
993
|
+
return {
|
|
994
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
return fetchWithAuth(
|
|
998
|
+
`${EXT_NOTIFICATION_PREFERENCES_ENDPOINT}?${buildQuery(params.organizationId)}`
|
|
999
|
+
);
|
|
1000
|
+
}
|
|
1001
|
+
async function updateNotificationPreferences(params) {
|
|
1002
|
+
if (!params.organizationId) {
|
|
1003
|
+
return {
|
|
1004
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
if (params.preferences === null || typeof params.preferences !== "object" || Array.isArray(params.preferences)) {
|
|
1008
|
+
return {
|
|
1009
|
+
error: createError("VALIDATION_ERROR", "preferences \u306F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059")
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
if (Object.keys(params.preferences).length === 0) {
|
|
1013
|
+
return {
|
|
1014
|
+
error: createError("VALIDATION_ERROR", "\u66F4\u65B0\u3059\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u30921\u3064\u4EE5\u4E0A\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044")
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
return fetchWithAuth(
|
|
1018
|
+
`${EXT_NOTIFICATION_PREFERENCES_ENDPOINT}?${buildQuery(params.organizationId)}`,
|
|
1019
|
+
{
|
|
1020
|
+
method: "PATCH",
|
|
1021
|
+
body: JSON.stringify({ preferences: params.preferences })
|
|
1022
|
+
}
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
return { getNotificationPreferences, updateNotificationPreferences };
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
// src/client/invite-methods.ts
|
|
1029
|
+
var EXT_INVITE_ENDPOINT = "/api/v1/organizations/ext/invite";
|
|
1030
|
+
function createInviteMethods(deps) {
|
|
1031
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
1032
|
+
const assignableRoles = /* @__PURE__ */ new Set(["admin", "member", "viewer"]);
|
|
1033
|
+
async function inviteMember(params) {
|
|
1034
|
+
if (!params.organizationId || !params.email) {
|
|
1035
|
+
return {
|
|
1036
|
+
error: createError("VALIDATION_ERROR", "organizationId \u3068 email \u306F\u5FC5\u9808\u3067\u3059")
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
if (params.role !== void 0 && !assignableRoles.has(params.role)) {
|
|
1040
|
+
return {
|
|
1041
|
+
error: createError(
|
|
1042
|
+
"VALIDATION_ERROR",
|
|
1043
|
+
"role \u306F admin\u3001member\u3001viewer \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
1044
|
+
)
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
const query = new URLSearchParams({
|
|
1048
|
+
organizationId: params.organizationId,
|
|
1049
|
+
serviceCode
|
|
1050
|
+
}).toString();
|
|
1051
|
+
return fetchWithAuth(`${EXT_INVITE_ENDPOINT}?${query}`, {
|
|
1052
|
+
method: "POST",
|
|
1053
|
+
body: JSON.stringify({ email: params.email, role: params.role })
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
return { inviteMember };
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/client/org-membership-methods.ts
|
|
1060
|
+
var EXT_USER_ORGANIZATIONS_ENDPOINT = "/api/v1/users/ext/me/organizations";
|
|
1061
|
+
function createOrgMembershipMethods(deps) {
|
|
1062
|
+
const { fetchWithAuth, createError } = deps;
|
|
1063
|
+
async function leaveOrganization(params) {
|
|
1064
|
+
if (!params || !params.organizationId) {
|
|
1065
|
+
return {
|
|
1066
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
let endpoint = `${EXT_USER_ORGANIZATIONS_ENDPOINT}/${encodeURIComponent(params.organizationId)}`;
|
|
1070
|
+
if (params.userId) {
|
|
1071
|
+
endpoint += `?${new URLSearchParams({ userId: params.userId }).toString()}`;
|
|
1072
|
+
}
|
|
1073
|
+
return fetchWithAuth(endpoint, {
|
|
1074
|
+
method: "DELETE"
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
return { leaveOrganization };
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
// src/client/noncontract-methods.ts
|
|
1081
|
+
function createNonContractMethods(deps) {
|
|
1082
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
1083
|
+
return {
|
|
1084
|
+
...createLoginHistoryMethods({ fetchWithAuth, createError }),
|
|
1085
|
+
...createOrganizationDomainsMethods({ fetchWithAuth, createError, serviceCode }),
|
|
1086
|
+
...createNotificationPreferencesMethods({ fetchWithAuth, createError, serviceCode }),
|
|
1087
|
+
...createInviteMethods({ fetchWithAuth, createError, serviceCode }),
|
|
1088
|
+
...createOrgMembershipMethods({ fetchWithAuth, createError })
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
|
|
931
1092
|
// src/client/version-check.ts
|
|
932
|
-
var SDK_VERSION = "5.
|
|
1093
|
+
var SDK_VERSION = "5.14.0";
|
|
933
1094
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
934
1095
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
935
1096
|
function sdkHeaders() {
|
|
@@ -1001,9 +1162,20 @@ function createOAuthTokenMethods(deps) {
|
|
|
1001
1162
|
logger,
|
|
1002
1163
|
errorCodes
|
|
1003
1164
|
} = deps;
|
|
1004
|
-
async function exchangeCodeForTokens(code, codeVerifier) {
|
|
1165
|
+
async function exchangeCodeForTokens(code, codeVerifier, opts) {
|
|
1005
1166
|
const url = `${baseUrl}${OAUTH_TOKEN_ENDPOINT}`;
|
|
1006
1167
|
logger.debug("Exchanging code for tokens:", url);
|
|
1168
|
+
if (opts?.expectedState !== void 0 || opts?.actualState !== void 0) {
|
|
1169
|
+
if (opts?.expectedState !== opts?.actualState) {
|
|
1170
|
+
logger.error("Token exchange aborted: OAuth state mismatch or omitted (possible CSRF)");
|
|
1171
|
+
return {
|
|
1172
|
+
error: {
|
|
1173
|
+
code: errorCodes.STATE_MISMATCH_ERROR,
|
|
1174
|
+
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"
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1007
1179
|
const effectiveRedirectUri = resolvedRedirectUri ?? (typeof window !== "undefined" ? window.location.origin + window.location.pathname : null);
|
|
1008
1180
|
if (!effectiveRedirectUri) {
|
|
1009
1181
|
logger.error("redirectUri is required for token exchange in SSR environments. Set config.redirectUri explicitly.");
|
|
@@ -1448,6 +1620,46 @@ function base64UrlEncode(buffer) {
|
|
|
1448
1620
|
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1449
1621
|
}
|
|
1450
1622
|
|
|
1623
|
+
// src/auth/state.ts
|
|
1624
|
+
var STATE_STORAGE_KEY = "ffid_oauth_state";
|
|
1625
|
+
var STATE_FALLBACK_STORAGE_KEY = "ffid_oauth_state_fb";
|
|
1626
|
+
var STATE_FALLBACK_TIMESTAMP_KEY = "ffid_oauth_state_fb_ts";
|
|
1627
|
+
function storeState(state, logger) {
|
|
1628
|
+
if (typeof window === "undefined") {
|
|
1629
|
+
logger?.warn("storeState: storage is not available in SSR context");
|
|
1630
|
+
return false;
|
|
1631
|
+
}
|
|
1632
|
+
let sessionStored = false;
|
|
1633
|
+
try {
|
|
1634
|
+
window.sessionStorage.setItem(STATE_STORAGE_KEY, state);
|
|
1635
|
+
sessionStored = true;
|
|
1636
|
+
} catch (error) {
|
|
1637
|
+
logger?.warn("storeState: sessionStorage \u3078\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1638
|
+
}
|
|
1639
|
+
let localStored = false;
|
|
1640
|
+
try {
|
|
1641
|
+
window.localStorage.setItem(STATE_FALLBACK_STORAGE_KEY, state);
|
|
1642
|
+
window.localStorage.setItem(STATE_FALLBACK_TIMESTAMP_KEY, String(Date.now()));
|
|
1643
|
+
localStored = true;
|
|
1644
|
+
} catch (error) {
|
|
1645
|
+
logger?.warn("storeState: localStorage fallback \u3078\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1646
|
+
}
|
|
1647
|
+
return sessionStored || localStored;
|
|
1648
|
+
}
|
|
1649
|
+
function cleanupStateStorage(logger) {
|
|
1650
|
+
try {
|
|
1651
|
+
window.sessionStorage.removeItem(STATE_STORAGE_KEY);
|
|
1652
|
+
} catch (error) {
|
|
1653
|
+
logger?.warn("retrieveState: sessionStorage \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1654
|
+
}
|
|
1655
|
+
try {
|
|
1656
|
+
window.localStorage.removeItem(STATE_FALLBACK_STORAGE_KEY);
|
|
1657
|
+
window.localStorage.removeItem(STATE_FALLBACK_TIMESTAMP_KEY);
|
|
1658
|
+
} catch (error) {
|
|
1659
|
+
logger?.warn("retrieveState: localStorage \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1451
1663
|
// src/client/redirect.ts
|
|
1452
1664
|
var OAUTH_AUTHORIZE_ENDPOINT = "/api/v1/oauth/authorize";
|
|
1453
1665
|
var AUTH_LOGOUT_ENDPOINT = "/api/v1/auth/logout";
|
|
@@ -1579,6 +1791,7 @@ function createRedirectMethods(deps) {
|
|
|
1579
1791
|
const recentCount = getRecentRedirectCount(authorizeKey, now, logger);
|
|
1580
1792
|
if (recentCount >= REDIRECT_LOOP_THRESHOLD) {
|
|
1581
1793
|
cleanupVerifierStorage(logger);
|
|
1794
|
+
cleanupStateStorage(logger);
|
|
1582
1795
|
logger.warn("[FFID SDK] redirect loop detected \u2014 \u81EA\u52D5\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3092\u505C\u6B62\u3057\u307E\u3057\u305F", {
|
|
1583
1796
|
authorizeKey,
|
|
1584
1797
|
recentCount,
|
|
@@ -1602,6 +1815,11 @@ function createRedirectMethods(deps) {
|
|
|
1602
1815
|
return { success: false, error: errorMessage };
|
|
1603
1816
|
}
|
|
1604
1817
|
const state = generateRandomState();
|
|
1818
|
+
if (!storeState(state, logger)) {
|
|
1819
|
+
logger.error(
|
|
1820
|
+
"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"
|
|
1821
|
+
);
|
|
1822
|
+
}
|
|
1605
1823
|
const redirectUri = resolvedRedirectUri ?? window.location.origin + window.location.pathname;
|
|
1606
1824
|
const params = new URLSearchParams({
|
|
1607
1825
|
response_type: "code",
|
|
@@ -2316,7 +2534,8 @@ var FFID_ERROR_CODES = {
|
|
|
2316
2534
|
TOKEN_EXCHANGE_ERROR: "TOKEN_EXCHANGE_ERROR",
|
|
2317
2535
|
TOKEN_REFRESH_ERROR: "TOKEN_REFRESH_ERROR",
|
|
2318
2536
|
NO_TOKENS: "NO_TOKENS",
|
|
2319
|
-
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR"
|
|
2537
|
+
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR",
|
|
2538
|
+
STATE_MISMATCH_ERROR: "STATE_MISMATCH_ERROR"
|
|
2320
2539
|
};
|
|
2321
2540
|
var EXT_CHECK_ENDPOINT = "/api/v1/subscriptions/ext/check";
|
|
2322
2541
|
var DEFAULT_ALLOW_GRACE = true;
|
|
@@ -2704,6 +2923,18 @@ function createFFIDClient(config) {
|
|
|
2704
2923
|
fetchWithAuth,
|
|
2705
2924
|
createError
|
|
2706
2925
|
});
|
|
2926
|
+
const {
|
|
2927
|
+
getLoginHistory,
|
|
2928
|
+
getOrganizationDomains,
|
|
2929
|
+
getNotificationPreferences,
|
|
2930
|
+
updateNotificationPreferences,
|
|
2931
|
+
inviteMember,
|
|
2932
|
+
leaveOrganization
|
|
2933
|
+
} = createNonContractMethods({
|
|
2934
|
+
fetchWithAuth,
|
|
2935
|
+
createError,
|
|
2936
|
+
serviceCode: config.serviceCode
|
|
2937
|
+
});
|
|
2707
2938
|
const { getAnalyticsConfig } = createAnalyticsMethods({
|
|
2708
2939
|
fetchWithAuth,
|
|
2709
2940
|
createError
|
|
@@ -2784,6 +3015,13 @@ function createFFIDClient(config) {
|
|
|
2784
3015
|
removeMember,
|
|
2785
3016
|
getProfile,
|
|
2786
3017
|
updateProfile,
|
|
3018
|
+
// Non-contract ext API coverage (#3783)
|
|
3019
|
+
getLoginHistory,
|
|
3020
|
+
getOrganizationDomains,
|
|
3021
|
+
getNotificationPreferences,
|
|
3022
|
+
updateNotificationPreferences,
|
|
3023
|
+
inviteMember,
|
|
3024
|
+
leaveOrganization,
|
|
2787
3025
|
getAnalyticsConfig,
|
|
2788
3026
|
createCheckoutSession,
|
|
2789
3027
|
createPortalSession,
|
package/dist/server/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-
|
|
2
|
-
export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-
|
|
1
|
+
import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-CKFxY60u.cjs';
|
|
2
|
+
export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-CKFxY60u.cjs';
|
|
3
3
|
export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-D61jqRIO.cjs';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import '../types-BeVl-z12.cjs';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-
|
|
2
|
-
export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-
|
|
1
|
+
import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-9-lh0G_h.js';
|
|
2
|
+
export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-9-lh0G_h.js';
|
|
3
3
|
export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-D61jqRIO.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import '../types-BeVl-z12.js';
|
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,
|
|
@@ -927,8 +933,163 @@ function createProfileMethods(deps) {
|
|
|
927
933
|
return { getProfile, updateProfile };
|
|
928
934
|
}
|
|
929
935
|
|
|
936
|
+
// src/client/login-history-methods.ts
|
|
937
|
+
var EXT_LOGIN_HISTORY_ENDPOINT = "/api/v1/users/ext/me/login-history";
|
|
938
|
+
function createLoginHistoryMethods(deps) {
|
|
939
|
+
const { fetchWithAuth, createError } = deps;
|
|
940
|
+
async function getLoginHistory(params) {
|
|
941
|
+
if (params?.limit !== void 0 && (!Number.isInteger(params.limit) || params.limit <= 0)) {
|
|
942
|
+
return {
|
|
943
|
+
error: createError(
|
|
944
|
+
"VALIDATION_ERROR",
|
|
945
|
+
"limit \u306F1\u4EE5\u4E0A\u306E\u6574\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
946
|
+
)
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
const query = new URLSearchParams();
|
|
950
|
+
if (params?.userId !== void 0) {
|
|
951
|
+
query.set("userId", params.userId);
|
|
952
|
+
}
|
|
953
|
+
if (params?.limit !== void 0) {
|
|
954
|
+
query.set("limit", String(params.limit));
|
|
955
|
+
}
|
|
956
|
+
const queryString = query.toString();
|
|
957
|
+
const endpoint = queryString ? `${EXT_LOGIN_HISTORY_ENDPOINT}?${queryString}` : EXT_LOGIN_HISTORY_ENDPOINT;
|
|
958
|
+
return fetchWithAuth(endpoint);
|
|
959
|
+
}
|
|
960
|
+
return { getLoginHistory };
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// src/client/organization-domains-methods.ts
|
|
964
|
+
var EXT_DOMAINS_ENDPOINT = "/api/v1/organizations/ext/domains";
|
|
965
|
+
function createOrganizationDomainsMethods(deps) {
|
|
966
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
967
|
+
function buildQuery(organizationId) {
|
|
968
|
+
return new URLSearchParams({ organizationId, serviceCode }).toString();
|
|
969
|
+
}
|
|
970
|
+
async function getOrganizationDomains(params) {
|
|
971
|
+
if (!params.organizationId) {
|
|
972
|
+
return {
|
|
973
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
return fetchWithAuth(
|
|
977
|
+
`${EXT_DOMAINS_ENDPOINT}?${buildQuery(params.organizationId)}`
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
return { getOrganizationDomains };
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// src/client/notification-preferences-methods.ts
|
|
984
|
+
var EXT_NOTIFICATION_PREFERENCES_ENDPOINT = "/api/v1/organizations/ext/notification-preferences";
|
|
985
|
+
function createNotificationPreferencesMethods(deps) {
|
|
986
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
987
|
+
function buildQuery(organizationId) {
|
|
988
|
+
return new URLSearchParams({ organizationId, serviceCode }).toString();
|
|
989
|
+
}
|
|
990
|
+
async function getNotificationPreferences(params) {
|
|
991
|
+
if (!params.organizationId) {
|
|
992
|
+
return {
|
|
993
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
return fetchWithAuth(
|
|
997
|
+
`${EXT_NOTIFICATION_PREFERENCES_ENDPOINT}?${buildQuery(params.organizationId)}`
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
async function updateNotificationPreferences(params) {
|
|
1001
|
+
if (!params.organizationId) {
|
|
1002
|
+
return {
|
|
1003
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
if (params.preferences === null || typeof params.preferences !== "object" || Array.isArray(params.preferences)) {
|
|
1007
|
+
return {
|
|
1008
|
+
error: createError("VALIDATION_ERROR", "preferences \u306F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059")
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
if (Object.keys(params.preferences).length === 0) {
|
|
1012
|
+
return {
|
|
1013
|
+
error: createError("VALIDATION_ERROR", "\u66F4\u65B0\u3059\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u30921\u3064\u4EE5\u4E0A\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044")
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
return fetchWithAuth(
|
|
1017
|
+
`${EXT_NOTIFICATION_PREFERENCES_ENDPOINT}?${buildQuery(params.organizationId)}`,
|
|
1018
|
+
{
|
|
1019
|
+
method: "PATCH",
|
|
1020
|
+
body: JSON.stringify({ preferences: params.preferences })
|
|
1021
|
+
}
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
return { getNotificationPreferences, updateNotificationPreferences };
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// src/client/invite-methods.ts
|
|
1028
|
+
var EXT_INVITE_ENDPOINT = "/api/v1/organizations/ext/invite";
|
|
1029
|
+
function createInviteMethods(deps) {
|
|
1030
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
1031
|
+
const assignableRoles = /* @__PURE__ */ new Set(["admin", "member", "viewer"]);
|
|
1032
|
+
async function inviteMember(params) {
|
|
1033
|
+
if (!params.organizationId || !params.email) {
|
|
1034
|
+
return {
|
|
1035
|
+
error: createError("VALIDATION_ERROR", "organizationId \u3068 email \u306F\u5FC5\u9808\u3067\u3059")
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
if (params.role !== void 0 && !assignableRoles.has(params.role)) {
|
|
1039
|
+
return {
|
|
1040
|
+
error: createError(
|
|
1041
|
+
"VALIDATION_ERROR",
|
|
1042
|
+
"role \u306F admin\u3001member\u3001viewer \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
1043
|
+
)
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
const query = new URLSearchParams({
|
|
1047
|
+
organizationId: params.organizationId,
|
|
1048
|
+
serviceCode
|
|
1049
|
+
}).toString();
|
|
1050
|
+
return fetchWithAuth(`${EXT_INVITE_ENDPOINT}?${query}`, {
|
|
1051
|
+
method: "POST",
|
|
1052
|
+
body: JSON.stringify({ email: params.email, role: params.role })
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
return { inviteMember };
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// src/client/org-membership-methods.ts
|
|
1059
|
+
var EXT_USER_ORGANIZATIONS_ENDPOINT = "/api/v1/users/ext/me/organizations";
|
|
1060
|
+
function createOrgMembershipMethods(deps) {
|
|
1061
|
+
const { fetchWithAuth, createError } = deps;
|
|
1062
|
+
async function leaveOrganization(params) {
|
|
1063
|
+
if (!params || !params.organizationId) {
|
|
1064
|
+
return {
|
|
1065
|
+
error: createError("VALIDATION_ERROR", "organizationId \u306F\u5FC5\u9808\u3067\u3059")
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
let endpoint = `${EXT_USER_ORGANIZATIONS_ENDPOINT}/${encodeURIComponent(params.organizationId)}`;
|
|
1069
|
+
if (params.userId) {
|
|
1070
|
+
endpoint += `?${new URLSearchParams({ userId: params.userId }).toString()}`;
|
|
1071
|
+
}
|
|
1072
|
+
return fetchWithAuth(endpoint, {
|
|
1073
|
+
method: "DELETE"
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
return { leaveOrganization };
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
// src/client/noncontract-methods.ts
|
|
1080
|
+
function createNonContractMethods(deps) {
|
|
1081
|
+
const { fetchWithAuth, createError, serviceCode } = deps;
|
|
1082
|
+
return {
|
|
1083
|
+
...createLoginHistoryMethods({ fetchWithAuth, createError }),
|
|
1084
|
+
...createOrganizationDomainsMethods({ fetchWithAuth, createError, serviceCode }),
|
|
1085
|
+
...createNotificationPreferencesMethods({ fetchWithAuth, createError, serviceCode }),
|
|
1086
|
+
...createInviteMethods({ fetchWithAuth, createError, serviceCode }),
|
|
1087
|
+
...createOrgMembershipMethods({ fetchWithAuth, createError })
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
|
|
930
1091
|
// src/client/version-check.ts
|
|
931
|
-
var SDK_VERSION = "5.
|
|
1092
|
+
var SDK_VERSION = "5.14.0";
|
|
932
1093
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
933
1094
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
934
1095
|
function sdkHeaders() {
|
|
@@ -1000,9 +1161,20 @@ function createOAuthTokenMethods(deps) {
|
|
|
1000
1161
|
logger,
|
|
1001
1162
|
errorCodes
|
|
1002
1163
|
} = deps;
|
|
1003
|
-
async function exchangeCodeForTokens(code, codeVerifier) {
|
|
1164
|
+
async function exchangeCodeForTokens(code, codeVerifier, opts) {
|
|
1004
1165
|
const url = `${baseUrl}${OAUTH_TOKEN_ENDPOINT}`;
|
|
1005
1166
|
logger.debug("Exchanging code for tokens:", url);
|
|
1167
|
+
if (opts?.expectedState !== void 0 || opts?.actualState !== void 0) {
|
|
1168
|
+
if (opts?.expectedState !== opts?.actualState) {
|
|
1169
|
+
logger.error("Token exchange aborted: OAuth state mismatch or omitted (possible CSRF)");
|
|
1170
|
+
return {
|
|
1171
|
+
error: {
|
|
1172
|
+
code: errorCodes.STATE_MISMATCH_ERROR,
|
|
1173
|
+
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"
|
|
1174
|
+
}
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1006
1178
|
const effectiveRedirectUri = resolvedRedirectUri ?? (typeof window !== "undefined" ? window.location.origin + window.location.pathname : null);
|
|
1007
1179
|
if (!effectiveRedirectUri) {
|
|
1008
1180
|
logger.error("redirectUri is required for token exchange in SSR environments. Set config.redirectUri explicitly.");
|
|
@@ -1447,6 +1619,46 @@ function base64UrlEncode(buffer) {
|
|
|
1447
1619
|
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1448
1620
|
}
|
|
1449
1621
|
|
|
1622
|
+
// src/auth/state.ts
|
|
1623
|
+
var STATE_STORAGE_KEY = "ffid_oauth_state";
|
|
1624
|
+
var STATE_FALLBACK_STORAGE_KEY = "ffid_oauth_state_fb";
|
|
1625
|
+
var STATE_FALLBACK_TIMESTAMP_KEY = "ffid_oauth_state_fb_ts";
|
|
1626
|
+
function storeState(state, logger) {
|
|
1627
|
+
if (typeof window === "undefined") {
|
|
1628
|
+
logger?.warn("storeState: storage is not available in SSR context");
|
|
1629
|
+
return false;
|
|
1630
|
+
}
|
|
1631
|
+
let sessionStored = false;
|
|
1632
|
+
try {
|
|
1633
|
+
window.sessionStorage.setItem(STATE_STORAGE_KEY, state);
|
|
1634
|
+
sessionStored = true;
|
|
1635
|
+
} catch (error) {
|
|
1636
|
+
logger?.warn("storeState: sessionStorage \u3078\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1637
|
+
}
|
|
1638
|
+
let localStored = false;
|
|
1639
|
+
try {
|
|
1640
|
+
window.localStorage.setItem(STATE_FALLBACK_STORAGE_KEY, state);
|
|
1641
|
+
window.localStorage.setItem(STATE_FALLBACK_TIMESTAMP_KEY, String(Date.now()));
|
|
1642
|
+
localStored = true;
|
|
1643
|
+
} catch (error) {
|
|
1644
|
+
logger?.warn("storeState: localStorage fallback \u3078\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1645
|
+
}
|
|
1646
|
+
return sessionStored || localStored;
|
|
1647
|
+
}
|
|
1648
|
+
function cleanupStateStorage(logger) {
|
|
1649
|
+
try {
|
|
1650
|
+
window.sessionStorage.removeItem(STATE_STORAGE_KEY);
|
|
1651
|
+
} catch (error) {
|
|
1652
|
+
logger?.warn("retrieveState: sessionStorage \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1653
|
+
}
|
|
1654
|
+
try {
|
|
1655
|
+
window.localStorage.removeItem(STATE_FALLBACK_STORAGE_KEY);
|
|
1656
|
+
window.localStorage.removeItem(STATE_FALLBACK_TIMESTAMP_KEY);
|
|
1657
|
+
} catch (error) {
|
|
1658
|
+
logger?.warn("retrieveState: localStorage \u306E\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u306B\u5931\u6557\u3057\u307E\u3057\u305F:", error);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1450
1662
|
// src/client/redirect.ts
|
|
1451
1663
|
var OAUTH_AUTHORIZE_ENDPOINT = "/api/v1/oauth/authorize";
|
|
1452
1664
|
var AUTH_LOGOUT_ENDPOINT = "/api/v1/auth/logout";
|
|
@@ -1578,6 +1790,7 @@ function createRedirectMethods(deps) {
|
|
|
1578
1790
|
const recentCount = getRecentRedirectCount(authorizeKey, now, logger);
|
|
1579
1791
|
if (recentCount >= REDIRECT_LOOP_THRESHOLD) {
|
|
1580
1792
|
cleanupVerifierStorage(logger);
|
|
1793
|
+
cleanupStateStorage(logger);
|
|
1581
1794
|
logger.warn("[FFID SDK] redirect loop detected \u2014 \u81EA\u52D5\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3092\u505C\u6B62\u3057\u307E\u3057\u305F", {
|
|
1582
1795
|
authorizeKey,
|
|
1583
1796
|
recentCount,
|
|
@@ -1601,6 +1814,11 @@ function createRedirectMethods(deps) {
|
|
|
1601
1814
|
return { success: false, error: errorMessage };
|
|
1602
1815
|
}
|
|
1603
1816
|
const state = generateRandomState();
|
|
1817
|
+
if (!storeState(state, logger)) {
|
|
1818
|
+
logger.error(
|
|
1819
|
+
"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"
|
|
1820
|
+
);
|
|
1821
|
+
}
|
|
1604
1822
|
const redirectUri = resolvedRedirectUri ?? window.location.origin + window.location.pathname;
|
|
1605
1823
|
const params = new URLSearchParams({
|
|
1606
1824
|
response_type: "code",
|
|
@@ -2315,7 +2533,8 @@ var FFID_ERROR_CODES = {
|
|
|
2315
2533
|
TOKEN_EXCHANGE_ERROR: "TOKEN_EXCHANGE_ERROR",
|
|
2316
2534
|
TOKEN_REFRESH_ERROR: "TOKEN_REFRESH_ERROR",
|
|
2317
2535
|
NO_TOKENS: "NO_TOKENS",
|
|
2318
|
-
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR"
|
|
2536
|
+
TOKEN_VERIFICATION_ERROR: "TOKEN_VERIFICATION_ERROR",
|
|
2537
|
+
STATE_MISMATCH_ERROR: "STATE_MISMATCH_ERROR"
|
|
2319
2538
|
};
|
|
2320
2539
|
var EXT_CHECK_ENDPOINT = "/api/v1/subscriptions/ext/check";
|
|
2321
2540
|
var DEFAULT_ALLOW_GRACE = true;
|
|
@@ -2703,6 +2922,18 @@ function createFFIDClient(config) {
|
|
|
2703
2922
|
fetchWithAuth,
|
|
2704
2923
|
createError
|
|
2705
2924
|
});
|
|
2925
|
+
const {
|
|
2926
|
+
getLoginHistory,
|
|
2927
|
+
getOrganizationDomains,
|
|
2928
|
+
getNotificationPreferences,
|
|
2929
|
+
updateNotificationPreferences,
|
|
2930
|
+
inviteMember,
|
|
2931
|
+
leaveOrganization
|
|
2932
|
+
} = createNonContractMethods({
|
|
2933
|
+
fetchWithAuth,
|
|
2934
|
+
createError,
|
|
2935
|
+
serviceCode: config.serviceCode
|
|
2936
|
+
});
|
|
2706
2937
|
const { getAnalyticsConfig } = createAnalyticsMethods({
|
|
2707
2938
|
fetchWithAuth,
|
|
2708
2939
|
createError
|
|
@@ -2783,6 +3014,13 @@ function createFFIDClient(config) {
|
|
|
2783
3014
|
removeMember,
|
|
2784
3015
|
getProfile,
|
|
2785
3016
|
updateProfile,
|
|
3017
|
+
// Non-contract ext API coverage (#3783)
|
|
3018
|
+
getLoginHistory,
|
|
3019
|
+
getOrganizationDomains,
|
|
3020
|
+
getNotificationPreferences,
|
|
3021
|
+
updateNotificationPreferences,
|
|
3022
|
+
inviteMember,
|
|
3023
|
+
leaveOrganization,
|
|
2786
3024
|
getAnalyticsConfig,
|
|
2787
3025
|
createCheckoutSession,
|
|
2788
3026
|
createPortalSession,
|