@feelflow/ffid-sdk 5.24.1 → 5.24.3
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-L5SBAHY3.cjs → chunk-AMVL7J2G.cjs} +65 -36
- package/dist/{chunk-C4RNFEME.js → chunk-O3HGRALD.js} +65 -36
- 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-DX2PTTFr.d.ts → ffid-client-B-xjtrCb.d.ts} +69 -41
- package/dist/{ffid-client-D0Jh4bO7.d.cts → ffid-client-BjZphrz9.d.cts} +69 -41
- package/dist/{index-GqflEaKi.d.cts → index-BRMn6xT0.d.cts} +77 -1
- package/dist/{index-GqflEaKi.d.ts → index-BRMn6xT0.d.ts} +77 -1
- package/dist/index.cjs +42 -42
- package/dist/index.d.cts +17 -45
- package/dist/index.d.ts +17 -45
- package/dist/index.js +2 -2
- package/dist/server/index.cjs +58 -45
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +58 -45
- package/dist/server/test/index.d.cts +1 -1
- package/dist/server/test/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1228,8 +1228,35 @@ function createNonContractMethods(deps) {
|
|
|
1228
1228
|
};
|
|
1229
1229
|
}
|
|
1230
1230
|
|
|
1231
|
+
// src/shared/token-response.ts
|
|
1232
|
+
function invalidTokenFields(tokenResponse) {
|
|
1233
|
+
const invalid = [];
|
|
1234
|
+
if (typeof tokenResponse.access_token !== "string" || tokenResponse.access_token.length === 0) {
|
|
1235
|
+
invalid.push("access_token");
|
|
1236
|
+
}
|
|
1237
|
+
if (typeof tokenResponse.refresh_token !== "string" || tokenResponse.refresh_token.length === 0) {
|
|
1238
|
+
invalid.push("refresh_token");
|
|
1239
|
+
}
|
|
1240
|
+
if (typeof tokenResponse.expires_in !== "number" || !Number.isFinite(tokenResponse.expires_in) || tokenResponse.expires_in <= 0) {
|
|
1241
|
+
invalid.push("expires_in");
|
|
1242
|
+
}
|
|
1243
|
+
return invalid;
|
|
1244
|
+
}
|
|
1245
|
+
function hasValidatedTokens(tokenResponse) {
|
|
1246
|
+
return invalidTokenFields(tokenResponse).length === 0;
|
|
1247
|
+
}
|
|
1248
|
+
function validateTokenResponse(tokenResponse) {
|
|
1249
|
+
if (hasValidatedTokens(tokenResponse)) {
|
|
1250
|
+
return { ok: true, tokens: tokenResponse };
|
|
1251
|
+
}
|
|
1252
|
+
return {
|
|
1253
|
+
ok: false,
|
|
1254
|
+
message: `\u30C8\u30FC\u30AF\u30F3\u30EC\u30B9\u30DD\u30F3\u30B9\u306B\u4E0D\u6B63\u306A\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u3042\u308A\u307E\u3059: ${invalidTokenFields(tokenResponse).join(", ")}`
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1231
1258
|
// src/client/version-check.ts
|
|
1232
|
-
var SDK_VERSION = "5.24.
|
|
1259
|
+
var SDK_VERSION = "5.24.3";
|
|
1233
1260
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
1234
1261
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
1235
1262
|
function sdkHeaders() {
|
|
@@ -1276,22 +1303,6 @@ npm install @feelflow/ffid-sdk@latest \u3067\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8
|
|
|
1276
1303
|
var OAUTH_TOKEN_ENDPOINT = "/api/v1/oauth/token";
|
|
1277
1304
|
var OAUTH_REVOKE_ENDPOINT = "/api/v1/oauth/revoke";
|
|
1278
1305
|
var MS_PER_SECOND = 1e3;
|
|
1279
|
-
function validateTokenResponse(tokenResponse) {
|
|
1280
|
-
const invalid = [];
|
|
1281
|
-
if (!tokenResponse.access_token) {
|
|
1282
|
-
invalid.push("access_token");
|
|
1283
|
-
}
|
|
1284
|
-
if (!tokenResponse.refresh_token) {
|
|
1285
|
-
invalid.push("refresh_token");
|
|
1286
|
-
}
|
|
1287
|
-
if (typeof tokenResponse.expires_in !== "number" || !Number.isFinite(tokenResponse.expires_in) || tokenResponse.expires_in <= 0) {
|
|
1288
|
-
invalid.push("expires_in");
|
|
1289
|
-
}
|
|
1290
|
-
if (invalid.length > 0) {
|
|
1291
|
-
return `\u30C8\u30FC\u30AF\u30F3\u30EC\u30B9\u30DD\u30F3\u30B9\u306B\u4E0D\u6B63\u306A\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u3042\u308A\u307E\u3059: ${invalid.join(", ")}`;
|
|
1292
|
-
}
|
|
1293
|
-
return null;
|
|
1294
|
-
}
|
|
1295
1306
|
function createOAuthTokenMethods(deps) {
|
|
1296
1307
|
const {
|
|
1297
1308
|
baseUrl,
|
|
@@ -1379,20 +1390,20 @@ function createOAuthTokenMethods(deps) {
|
|
|
1379
1390
|
}
|
|
1380
1391
|
};
|
|
1381
1392
|
}
|
|
1382
|
-
const
|
|
1383
|
-
if (
|
|
1384
|
-
logger.error("Token exchange validation failed:",
|
|
1393
|
+
const validation = validateTokenResponse(tokenResponse);
|
|
1394
|
+
if (!validation.ok) {
|
|
1395
|
+
logger.error("Token exchange validation failed:", validation.message);
|
|
1385
1396
|
return {
|
|
1386
1397
|
error: {
|
|
1387
1398
|
code: errorCodes.TOKEN_EXCHANGE_ERROR,
|
|
1388
|
-
message:
|
|
1399
|
+
message: validation.message
|
|
1389
1400
|
}
|
|
1390
1401
|
};
|
|
1391
1402
|
}
|
|
1392
1403
|
tokenStore.setTokens({
|
|
1393
|
-
accessToken:
|
|
1394
|
-
refreshToken:
|
|
1395
|
-
expiresAt: Date.now() +
|
|
1404
|
+
accessToken: validation.tokens.access_token,
|
|
1405
|
+
refreshToken: validation.tokens.refresh_token,
|
|
1406
|
+
expiresAt: Date.now() + validation.tokens.expires_in * MS_PER_SECOND
|
|
1396
1407
|
});
|
|
1397
1408
|
logger.debug("Token exchange successful");
|
|
1398
1409
|
return { data: void 0 };
|
|
@@ -1457,20 +1468,20 @@ function createOAuthTokenMethods(deps) {
|
|
|
1457
1468
|
}
|
|
1458
1469
|
};
|
|
1459
1470
|
}
|
|
1460
|
-
const
|
|
1461
|
-
if (
|
|
1462
|
-
logger.error("Token refresh validation failed:",
|
|
1471
|
+
const validation = validateTokenResponse(tokenResponse);
|
|
1472
|
+
if (!validation.ok) {
|
|
1473
|
+
logger.error("Token refresh validation failed:", validation.message);
|
|
1463
1474
|
return {
|
|
1464
1475
|
error: {
|
|
1465
1476
|
code: errorCodes.TOKEN_REFRESH_ERROR,
|
|
1466
|
-
message:
|
|
1477
|
+
message: validation.message
|
|
1467
1478
|
}
|
|
1468
1479
|
};
|
|
1469
1480
|
}
|
|
1470
1481
|
tokenStore.setTokens({
|
|
1471
|
-
accessToken:
|
|
1472
|
-
refreshToken:
|
|
1473
|
-
expiresAt: Date.now() +
|
|
1482
|
+
accessToken: validation.tokens.access_token,
|
|
1483
|
+
refreshToken: validation.tokens.refresh_token,
|
|
1484
|
+
expiresAt: Date.now() + validation.tokens.expires_in * MS_PER_SECOND
|
|
1474
1485
|
});
|
|
1475
1486
|
logger.debug("Token refresh successful");
|
|
1476
1487
|
return { data: void 0 };
|
|
@@ -3012,10 +3023,16 @@ function createFFIDClient(config) {
|
|
|
3012
3023
|
}
|
|
3013
3024
|
const logger = config.logger ?? (config.debug ? consoleLogger : noopLogger);
|
|
3014
3025
|
const resolvedRedirectUri = resolveRedirectUri(rawRedirectUri, logger);
|
|
3015
|
-
const tokenStore = authMode === "token" ? createTokenStore() : createTokenStore("memory");
|
|
3026
|
+
const tokenStore = authMode === "token" ? config.tokenStore ?? createTokenStore() : createTokenStore("memory");
|
|
3016
3027
|
function createError(code, message) {
|
|
3017
3028
|
return { code, message };
|
|
3018
3029
|
}
|
|
3030
|
+
function getAccessToken() {
|
|
3031
|
+
if (authMode !== "token") return null;
|
|
3032
|
+
if (tokenStore.isAccessTokenExpired()) return null;
|
|
3033
|
+
const accessToken = tokenStore.getTokens()?.accessToken;
|
|
3034
|
+
return accessToken && accessToken.length > 0 ? accessToken : null;
|
|
3035
|
+
}
|
|
3019
3036
|
function buildFetchOptions(options, authOverride) {
|
|
3020
3037
|
if (authOverride) {
|
|
3021
3038
|
return {
|
|
@@ -3425,6 +3442,11 @@ function createFFIDClient(config) {
|
|
|
3425
3442
|
inquiry,
|
|
3426
3443
|
/** Token store (token mode only) */
|
|
3427
3444
|
tokenStore,
|
|
3445
|
+
/**
|
|
3446
|
+
* Return the currently-valid access token, or null (token mode only; #4318).
|
|
3447
|
+
* Live-reads the store and applies the 30s expiry buffer.
|
|
3448
|
+
*/
|
|
3449
|
+
getAccessToken,
|
|
3428
3450
|
/** Resolved auth mode */
|
|
3429
3451
|
authMode,
|
|
3430
3452
|
/** Resolved logger instance */
|
|
@@ -3549,6 +3571,7 @@ function FFIDProvider({
|
|
|
3549
3571
|
authMode,
|
|
3550
3572
|
clientId,
|
|
3551
3573
|
timeout,
|
|
3574
|
+
tokenStore,
|
|
3552
3575
|
cleanCallbackUrl = true
|
|
3553
3576
|
}) {
|
|
3554
3577
|
const [user, setUser] = react.useState(null);
|
|
@@ -3574,9 +3597,10 @@ function FFIDProvider({
|
|
|
3574
3597
|
logger,
|
|
3575
3598
|
authMode,
|
|
3576
3599
|
clientId,
|
|
3577
|
-
timeout
|
|
3600
|
+
timeout,
|
|
3601
|
+
tokenStore
|
|
3578
3602
|
}),
|
|
3579
|
-
[serviceCode, scope, apiBaseUrl, debug, logger, authMode, clientId, timeout]
|
|
3603
|
+
[serviceCode, scope, apiBaseUrl, debug, logger, authMode, clientId, timeout, tokenStore]
|
|
3580
3604
|
);
|
|
3581
3605
|
const refresh = react.useCallback(async () => {
|
|
3582
3606
|
client.logger.debug("Refreshing session...");
|
|
@@ -3790,7 +3814,10 @@ function FFIDProvider({
|
|
|
3790
3814
|
login,
|
|
3791
3815
|
logout,
|
|
3792
3816
|
switchOrganization,
|
|
3793
|
-
refresh
|
|
3817
|
+
refresh,
|
|
3818
|
+
// Stable across renders (client is memoized): live-reads the shared store
|
|
3819
|
+
// so refreshed/cleared tokens are reflected without host polling (#4318).
|
|
3820
|
+
getAccessToken: client.getAccessToken
|
|
3794
3821
|
}),
|
|
3795
3822
|
[
|
|
3796
3823
|
user,
|
|
@@ -3802,7 +3829,8 @@ function FFIDProvider({
|
|
|
3802
3829
|
login,
|
|
3803
3830
|
logout,
|
|
3804
3831
|
switchOrganization,
|
|
3805
|
-
refresh
|
|
3832
|
+
refresh,
|
|
3833
|
+
client
|
|
3806
3834
|
]
|
|
3807
3835
|
);
|
|
3808
3836
|
return /* @__PURE__ */ jsxRuntime.jsx(FFIDClientContext.Provider, { value: client, children: /* @__PURE__ */ jsxRuntime.jsx(FFIDContext.Provider, { value: contextValue, children }) });
|
|
@@ -3841,6 +3869,7 @@ function useFFID() {
|
|
|
3841
3869
|
switchAccount: client.switchAccount,
|
|
3842
3870
|
switchOrganization: context.switchOrganization,
|
|
3843
3871
|
refresh: context.refresh,
|
|
3872
|
+
getAccessToken: context.getAccessToken,
|
|
3844
3873
|
getLoginUrl: client.getLoginUrl,
|
|
3845
3874
|
getSignupUrl: client.getSignupUrl,
|
|
3846
3875
|
getSubscribeUrl: client.getSubscribeUrl,
|
|
@@ -1226,8 +1226,35 @@ function createNonContractMethods(deps) {
|
|
|
1226
1226
|
};
|
|
1227
1227
|
}
|
|
1228
1228
|
|
|
1229
|
+
// src/shared/token-response.ts
|
|
1230
|
+
function invalidTokenFields(tokenResponse) {
|
|
1231
|
+
const invalid = [];
|
|
1232
|
+
if (typeof tokenResponse.access_token !== "string" || tokenResponse.access_token.length === 0) {
|
|
1233
|
+
invalid.push("access_token");
|
|
1234
|
+
}
|
|
1235
|
+
if (typeof tokenResponse.refresh_token !== "string" || tokenResponse.refresh_token.length === 0) {
|
|
1236
|
+
invalid.push("refresh_token");
|
|
1237
|
+
}
|
|
1238
|
+
if (typeof tokenResponse.expires_in !== "number" || !Number.isFinite(tokenResponse.expires_in) || tokenResponse.expires_in <= 0) {
|
|
1239
|
+
invalid.push("expires_in");
|
|
1240
|
+
}
|
|
1241
|
+
return invalid;
|
|
1242
|
+
}
|
|
1243
|
+
function hasValidatedTokens(tokenResponse) {
|
|
1244
|
+
return invalidTokenFields(tokenResponse).length === 0;
|
|
1245
|
+
}
|
|
1246
|
+
function validateTokenResponse(tokenResponse) {
|
|
1247
|
+
if (hasValidatedTokens(tokenResponse)) {
|
|
1248
|
+
return { ok: true, tokens: tokenResponse };
|
|
1249
|
+
}
|
|
1250
|
+
return {
|
|
1251
|
+
ok: false,
|
|
1252
|
+
message: `\u30C8\u30FC\u30AF\u30F3\u30EC\u30B9\u30DD\u30F3\u30B9\u306B\u4E0D\u6B63\u306A\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u3042\u308A\u307E\u3059: ${invalidTokenFields(tokenResponse).join(", ")}`
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1229
1256
|
// src/client/version-check.ts
|
|
1230
|
-
var SDK_VERSION = "5.24.
|
|
1257
|
+
var SDK_VERSION = "5.24.3";
|
|
1231
1258
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
1232
1259
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
1233
1260
|
function sdkHeaders() {
|
|
@@ -1274,22 +1301,6 @@ npm install @feelflow/ffid-sdk@latest \u3067\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8
|
|
|
1274
1301
|
var OAUTH_TOKEN_ENDPOINT = "/api/v1/oauth/token";
|
|
1275
1302
|
var OAUTH_REVOKE_ENDPOINT = "/api/v1/oauth/revoke";
|
|
1276
1303
|
var MS_PER_SECOND = 1e3;
|
|
1277
|
-
function validateTokenResponse(tokenResponse) {
|
|
1278
|
-
const invalid = [];
|
|
1279
|
-
if (!tokenResponse.access_token) {
|
|
1280
|
-
invalid.push("access_token");
|
|
1281
|
-
}
|
|
1282
|
-
if (!tokenResponse.refresh_token) {
|
|
1283
|
-
invalid.push("refresh_token");
|
|
1284
|
-
}
|
|
1285
|
-
if (typeof tokenResponse.expires_in !== "number" || !Number.isFinite(tokenResponse.expires_in) || tokenResponse.expires_in <= 0) {
|
|
1286
|
-
invalid.push("expires_in");
|
|
1287
|
-
}
|
|
1288
|
-
if (invalid.length > 0) {
|
|
1289
|
-
return `\u30C8\u30FC\u30AF\u30F3\u30EC\u30B9\u30DD\u30F3\u30B9\u306B\u4E0D\u6B63\u306A\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u3042\u308A\u307E\u3059: ${invalid.join(", ")}`;
|
|
1290
|
-
}
|
|
1291
|
-
return null;
|
|
1292
|
-
}
|
|
1293
1304
|
function createOAuthTokenMethods(deps) {
|
|
1294
1305
|
const {
|
|
1295
1306
|
baseUrl,
|
|
@@ -1377,20 +1388,20 @@ function createOAuthTokenMethods(deps) {
|
|
|
1377
1388
|
}
|
|
1378
1389
|
};
|
|
1379
1390
|
}
|
|
1380
|
-
const
|
|
1381
|
-
if (
|
|
1382
|
-
logger.error("Token exchange validation failed:",
|
|
1391
|
+
const validation = validateTokenResponse(tokenResponse);
|
|
1392
|
+
if (!validation.ok) {
|
|
1393
|
+
logger.error("Token exchange validation failed:", validation.message);
|
|
1383
1394
|
return {
|
|
1384
1395
|
error: {
|
|
1385
1396
|
code: errorCodes.TOKEN_EXCHANGE_ERROR,
|
|
1386
|
-
message:
|
|
1397
|
+
message: validation.message
|
|
1387
1398
|
}
|
|
1388
1399
|
};
|
|
1389
1400
|
}
|
|
1390
1401
|
tokenStore.setTokens({
|
|
1391
|
-
accessToken:
|
|
1392
|
-
refreshToken:
|
|
1393
|
-
expiresAt: Date.now() +
|
|
1402
|
+
accessToken: validation.tokens.access_token,
|
|
1403
|
+
refreshToken: validation.tokens.refresh_token,
|
|
1404
|
+
expiresAt: Date.now() + validation.tokens.expires_in * MS_PER_SECOND
|
|
1394
1405
|
});
|
|
1395
1406
|
logger.debug("Token exchange successful");
|
|
1396
1407
|
return { data: void 0 };
|
|
@@ -1455,20 +1466,20 @@ function createOAuthTokenMethods(deps) {
|
|
|
1455
1466
|
}
|
|
1456
1467
|
};
|
|
1457
1468
|
}
|
|
1458
|
-
const
|
|
1459
|
-
if (
|
|
1460
|
-
logger.error("Token refresh validation failed:",
|
|
1469
|
+
const validation = validateTokenResponse(tokenResponse);
|
|
1470
|
+
if (!validation.ok) {
|
|
1471
|
+
logger.error("Token refresh validation failed:", validation.message);
|
|
1461
1472
|
return {
|
|
1462
1473
|
error: {
|
|
1463
1474
|
code: errorCodes.TOKEN_REFRESH_ERROR,
|
|
1464
|
-
message:
|
|
1475
|
+
message: validation.message
|
|
1465
1476
|
}
|
|
1466
1477
|
};
|
|
1467
1478
|
}
|
|
1468
1479
|
tokenStore.setTokens({
|
|
1469
|
-
accessToken:
|
|
1470
|
-
refreshToken:
|
|
1471
|
-
expiresAt: Date.now() +
|
|
1480
|
+
accessToken: validation.tokens.access_token,
|
|
1481
|
+
refreshToken: validation.tokens.refresh_token,
|
|
1482
|
+
expiresAt: Date.now() + validation.tokens.expires_in * MS_PER_SECOND
|
|
1472
1483
|
});
|
|
1473
1484
|
logger.debug("Token refresh successful");
|
|
1474
1485
|
return { data: void 0 };
|
|
@@ -3010,10 +3021,16 @@ function createFFIDClient(config) {
|
|
|
3010
3021
|
}
|
|
3011
3022
|
const logger = config.logger ?? (config.debug ? consoleLogger : noopLogger);
|
|
3012
3023
|
const resolvedRedirectUri = resolveRedirectUri(rawRedirectUri, logger);
|
|
3013
|
-
const tokenStore = authMode === "token" ? createTokenStore() : createTokenStore("memory");
|
|
3024
|
+
const tokenStore = authMode === "token" ? config.tokenStore ?? createTokenStore() : createTokenStore("memory");
|
|
3014
3025
|
function createError(code, message) {
|
|
3015
3026
|
return { code, message };
|
|
3016
3027
|
}
|
|
3028
|
+
function getAccessToken() {
|
|
3029
|
+
if (authMode !== "token") return null;
|
|
3030
|
+
if (tokenStore.isAccessTokenExpired()) return null;
|
|
3031
|
+
const accessToken = tokenStore.getTokens()?.accessToken;
|
|
3032
|
+
return accessToken && accessToken.length > 0 ? accessToken : null;
|
|
3033
|
+
}
|
|
3017
3034
|
function buildFetchOptions(options, authOverride) {
|
|
3018
3035
|
if (authOverride) {
|
|
3019
3036
|
return {
|
|
@@ -3423,6 +3440,11 @@ function createFFIDClient(config) {
|
|
|
3423
3440
|
inquiry,
|
|
3424
3441
|
/** Token store (token mode only) */
|
|
3425
3442
|
tokenStore,
|
|
3443
|
+
/**
|
|
3444
|
+
* Return the currently-valid access token, or null (token mode only; #4318).
|
|
3445
|
+
* Live-reads the store and applies the 30s expiry buffer.
|
|
3446
|
+
*/
|
|
3447
|
+
getAccessToken,
|
|
3426
3448
|
/** Resolved auth mode */
|
|
3427
3449
|
authMode,
|
|
3428
3450
|
/** Resolved logger instance */
|
|
@@ -3547,6 +3569,7 @@ function FFIDProvider({
|
|
|
3547
3569
|
authMode,
|
|
3548
3570
|
clientId,
|
|
3549
3571
|
timeout,
|
|
3572
|
+
tokenStore,
|
|
3550
3573
|
cleanCallbackUrl = true
|
|
3551
3574
|
}) {
|
|
3552
3575
|
const [user, setUser] = useState(null);
|
|
@@ -3572,9 +3595,10 @@ function FFIDProvider({
|
|
|
3572
3595
|
logger,
|
|
3573
3596
|
authMode,
|
|
3574
3597
|
clientId,
|
|
3575
|
-
timeout
|
|
3598
|
+
timeout,
|
|
3599
|
+
tokenStore
|
|
3576
3600
|
}),
|
|
3577
|
-
[serviceCode, scope, apiBaseUrl, debug, logger, authMode, clientId, timeout]
|
|
3601
|
+
[serviceCode, scope, apiBaseUrl, debug, logger, authMode, clientId, timeout, tokenStore]
|
|
3578
3602
|
);
|
|
3579
3603
|
const refresh = useCallback(async () => {
|
|
3580
3604
|
client.logger.debug("Refreshing session...");
|
|
@@ -3788,7 +3812,10 @@ function FFIDProvider({
|
|
|
3788
3812
|
login,
|
|
3789
3813
|
logout,
|
|
3790
3814
|
switchOrganization,
|
|
3791
|
-
refresh
|
|
3815
|
+
refresh,
|
|
3816
|
+
// Stable across renders (client is memoized): live-reads the shared store
|
|
3817
|
+
// so refreshed/cleared tokens are reflected without host polling (#4318).
|
|
3818
|
+
getAccessToken: client.getAccessToken
|
|
3792
3819
|
}),
|
|
3793
3820
|
[
|
|
3794
3821
|
user,
|
|
@@ -3800,7 +3827,8 @@ function FFIDProvider({
|
|
|
3800
3827
|
login,
|
|
3801
3828
|
logout,
|
|
3802
3829
|
switchOrganization,
|
|
3803
|
-
refresh
|
|
3830
|
+
refresh,
|
|
3831
|
+
client
|
|
3804
3832
|
]
|
|
3805
3833
|
);
|
|
3806
3834
|
return /* @__PURE__ */ jsx(FFIDClientContext.Provider, { value: client, children: /* @__PURE__ */ jsx(FFIDContext.Provider, { value: contextValue, children }) });
|
|
@@ -3839,6 +3867,7 @@ function useFFID() {
|
|
|
3839
3867
|
switchAccount: client.switchAccount,
|
|
3840
3868
|
switchOrganization: context.switchOrganization,
|
|
3841
3869
|
refresh: context.refresh,
|
|
3870
|
+
getAccessToken: context.getAccessToken,
|
|
3842
3871
|
getLoginUrl: client.getLoginUrl,
|
|
3843
3872
|
getSignupUrl: client.getSignupUrl,
|
|
3844
3873
|
getSubscribeUrl: client.getSubscribeUrl,
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkAMVL7J2G_cjs = require('../chunk-AMVL7J2G.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 chunkAMVL7J2G_cjs.FFIDAnnouncementBadge; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "FFIDAnnouncementList", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkAMVL7J2G_cjs.FFIDAnnouncementList; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "FFIDInquiryForm", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkAMVL7J2G_cjs.FFIDInquiryForm; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "FFIDLoginButton", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkAMVL7J2G_cjs.FFIDLoginButton; }
|
|
22
22
|
});
|
|
23
23
|
Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
|
|
24
24
|
enumerable: true,
|
|
25
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkAMVL7J2G_cjs.FFIDOrganizationSwitcher; }
|
|
26
26
|
});
|
|
27
27
|
Object.defineProperty(exports, "FFIDSubscriptionBadge", {
|
|
28
28
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunkAMVL7J2G_cjs.FFIDSubscriptionBadge; }
|
|
30
30
|
});
|
|
31
31
|
Object.defineProperty(exports, "FFIDUserMenu", {
|
|
32
32
|
enumerable: true,
|
|
33
|
-
get: function () { return
|
|
33
|
+
get: function () { return chunkAMVL7J2G_cjs.FFIDUserMenu; }
|
|
34
34
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { H as FFIDAnnouncementBadge,
|
|
1
|
+
export { H as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, I as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, S as FFIDInquiryForm, U as FFIDInquiryFormCategoryItem, V as FFIDInquiryFormClassNames, W as FFIDInquiryFormLegalLayout, X as FFIDInquiryFormOrganization, Y as FFIDInquiryFormPlaceholderContext, Z as FFIDInquiryFormPrefill, _ as FFIDInquiryFormProps, $ as FFIDInquiryFormSubmitData, a0 as FFIDInquiryFormSubmitResult, a2 as FFIDLoginButton, ap as FFIDLoginButtonProps, a5 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, aa as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ac as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-BRMn6xT0.cjs';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { H as FFIDAnnouncementBadge,
|
|
1
|
+
export { H as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, I as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, S as FFIDInquiryForm, U as FFIDInquiryFormCategoryItem, V as FFIDInquiryFormClassNames, W as FFIDInquiryFormLegalLayout, X as FFIDInquiryFormOrganization, Y as FFIDInquiryFormPlaceholderContext, Z as FFIDInquiryFormPrefill, _ as FFIDInquiryFormProps, $ as FFIDInquiryFormSubmitData, a0 as FFIDInquiryFormSubmitResult, a2 as FFIDLoginButton, ap as FFIDLoginButtonProps, a5 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, aa as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ac as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-BRMn6xT0.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-O3HGRALD.js';
|
|
@@ -270,6 +270,47 @@ interface FFIDServiceAccessDecision {
|
|
|
270
270
|
error?: FFIDServiceAccessError;
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Token Store
|
|
275
|
+
*
|
|
276
|
+
* Manages OAuth 2.0 tokens (access + refresh) with dual-storage support.
|
|
277
|
+
* Falls back to in-memory storage when localStorage is unavailable
|
|
278
|
+
* (e.g., Safari private browsing mode).
|
|
279
|
+
*/
|
|
280
|
+
/**
|
|
281
|
+
* Token data stored by the token store
|
|
282
|
+
*/
|
|
283
|
+
interface TokenData {
|
|
284
|
+
/** OAuth 2.0 access token */
|
|
285
|
+
accessToken: string;
|
|
286
|
+
/** OAuth 2.0 refresh token */
|
|
287
|
+
refreshToken: string;
|
|
288
|
+
/** Expiration timestamp in milliseconds (Unix epoch) */
|
|
289
|
+
expiresAt: number;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Token store interface for managing OAuth tokens
|
|
293
|
+
*/
|
|
294
|
+
interface TokenStore {
|
|
295
|
+
/** Get stored tokens (null if not stored) */
|
|
296
|
+
getTokens(): TokenData | null;
|
|
297
|
+
/** Store new tokens */
|
|
298
|
+
setTokens(tokens: TokenData): void;
|
|
299
|
+
/** Clear all stored tokens */
|
|
300
|
+
clearTokens(): void;
|
|
301
|
+
/** Check if access token is expired (with 30s buffer) */
|
|
302
|
+
isAccessTokenExpired(): boolean;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Create a token store with the specified storage type.
|
|
306
|
+
*
|
|
307
|
+
* When storageType is 'localStorage' (default in browser), falls back
|
|
308
|
+
* to memory if localStorage is not available (e.g., Safari private mode).
|
|
309
|
+
*
|
|
310
|
+
* @param storageType - 'localStorage' (default) or 'memory'
|
|
311
|
+
*/
|
|
312
|
+
declare function createTokenStore(storageType?: 'localStorage' | 'memory'): TokenStore;
|
|
313
|
+
|
|
273
314
|
/**
|
|
274
315
|
* Billing checkout / portal session types.
|
|
275
316
|
*
|
|
@@ -1608,6 +1649,29 @@ interface FFIDConfig {
|
|
|
1608
1649
|
* @default undefined (no timeout, uses fetch default)
|
|
1609
1650
|
*/
|
|
1610
1651
|
timeout?: number | undefined;
|
|
1652
|
+
/**
|
|
1653
|
+
* Token mode only: inject a shared {@link TokenStore} instance so the SDK and
|
|
1654
|
+
* the host app read/write the *same* token source (#4318).
|
|
1655
|
+
*
|
|
1656
|
+
* By default the client creates its own store internally
|
|
1657
|
+
* (`createTokenStore()` in `token` mode, `createTokenStore('memory')`
|
|
1658
|
+
* otherwise). That is fine when `localStorage` is available, because a
|
|
1659
|
+
* separately-created `localStorage` store still points at the same
|
|
1660
|
+
* `ffid_tokens` key. But when `localStorage` is unavailable (e.g. Safari
|
|
1661
|
+
* Private Mode) the SDK falls back to an *in-memory* store, and a store the
|
|
1662
|
+
* host app creates independently is a **different** object — so the app would
|
|
1663
|
+
* see the user as signed-out even though the SDK holds valid tokens.
|
|
1664
|
+
*
|
|
1665
|
+
* Passing a single instance here (typically `createTokenStore()` created once
|
|
1666
|
+
* by the host) guarantees both sides share one source of truth regardless of
|
|
1667
|
+
* storage backend. Prefer reading the token via `useFFID().getAccessToken()`
|
|
1668
|
+
* so refresh/logout stay reflected without the host polling the store.
|
|
1669
|
+
*
|
|
1670
|
+
* Ignored in `cookie` and `service-key` modes (neither exposes a browser
|
|
1671
|
+
* access-token store). When omitted, behavior is unchanged from previous
|
|
1672
|
+
* versions.
|
|
1673
|
+
*/
|
|
1674
|
+
tokenStore?: TokenStore | undefined;
|
|
1611
1675
|
}
|
|
1612
1676
|
/**
|
|
1613
1677
|
* OIDC `prompt` values the SDK forwards to FFID `/oauth/authorize` (#4027).
|
|
@@ -1850,47 +1914,6 @@ interface FFIDGetLoginHistoryParams {
|
|
|
1850
1914
|
limit?: number;
|
|
1851
1915
|
}
|
|
1852
1916
|
|
|
1853
|
-
/**
|
|
1854
|
-
* Token Store
|
|
1855
|
-
*
|
|
1856
|
-
* Manages OAuth 2.0 tokens (access + refresh) with dual-storage support.
|
|
1857
|
-
* Falls back to in-memory storage when localStorage is unavailable
|
|
1858
|
-
* (e.g., Safari private browsing mode).
|
|
1859
|
-
*/
|
|
1860
|
-
/**
|
|
1861
|
-
* Token data stored by the token store
|
|
1862
|
-
*/
|
|
1863
|
-
interface TokenData {
|
|
1864
|
-
/** OAuth 2.0 access token */
|
|
1865
|
-
accessToken: string;
|
|
1866
|
-
/** OAuth 2.0 refresh token */
|
|
1867
|
-
refreshToken: string;
|
|
1868
|
-
/** Expiration timestamp in milliseconds (Unix epoch) */
|
|
1869
|
-
expiresAt: number;
|
|
1870
|
-
}
|
|
1871
|
-
/**
|
|
1872
|
-
* Token store interface for managing OAuth tokens
|
|
1873
|
-
*/
|
|
1874
|
-
interface TokenStore {
|
|
1875
|
-
/** Get stored tokens (null if not stored) */
|
|
1876
|
-
getTokens(): TokenData | null;
|
|
1877
|
-
/** Store new tokens */
|
|
1878
|
-
setTokens(tokens: TokenData): void;
|
|
1879
|
-
/** Clear all stored tokens */
|
|
1880
|
-
clearTokens(): void;
|
|
1881
|
-
/** Check if access token is expired (with 30s buffer) */
|
|
1882
|
-
isAccessTokenExpired(): boolean;
|
|
1883
|
-
}
|
|
1884
|
-
/**
|
|
1885
|
-
* Create a token store with the specified storage type.
|
|
1886
|
-
*
|
|
1887
|
-
* When storageType is 'localStorage' (default in browser), falls back
|
|
1888
|
-
* to memory if localStorage is not available (e.g., Safari private mode).
|
|
1889
|
-
*
|
|
1890
|
-
* @param storageType - 'localStorage' (default) or 'memory'
|
|
1891
|
-
*/
|
|
1892
|
-
declare function createTokenStore(storageType?: 'localStorage' | 'memory'): TokenStore;
|
|
1893
|
-
|
|
1894
1917
|
/** OAuth token operations - exchangeCodeForTokens / refreshAccessToken / signOutToken */
|
|
1895
1918
|
|
|
1896
1919
|
/**
|
|
@@ -2065,6 +2088,11 @@ declare function createFFIDClient(config: FFIDConfig): {
|
|
|
2065
2088
|
};
|
|
2066
2089
|
/** Token store (token mode only) */
|
|
2067
2090
|
tokenStore: TokenStore;
|
|
2091
|
+
/**
|
|
2092
|
+
* Return the currently-valid access token, or null (token mode only; #4318).
|
|
2093
|
+
* Live-reads the store and applies the 30s expiry buffer.
|
|
2094
|
+
*/
|
|
2095
|
+
getAccessToken: () => string | null;
|
|
2068
2096
|
/** Resolved auth mode */
|
|
2069
2097
|
authMode: FFIDAuthMode;
|
|
2070
2098
|
/** Resolved logger instance */
|