quidproquo-web-react 0.1.8 → 0.1.10
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/lib/commonjs/auth/RefreshAuthTokensProvider.d.ts +1 -0
- package/lib/commonjs/auth/RefreshAuthTokensProvider.js +2 -2
- package/lib/commonjs/auth/RefreshAuthTokensProvider.js.map +1 -1
- package/lib/commonjs/auth/hooks/useRefreshTokens.d.ts +1 -1
- package/lib/commonjs/auth/hooks/useRefreshTokens.js +8 -4
- package/lib/commonjs/auth/hooks/useRefreshTokens.js.map +1 -1
- package/lib/esm/auth/RefreshAuthTokensProvider.d.ts +1 -0
- package/lib/esm/auth/RefreshAuthTokensProvider.js +2 -2
- package/lib/esm/auth/RefreshAuthTokensProvider.js.map +1 -1
- package/lib/esm/auth/hooks/useRefreshTokens.d.ts +1 -1
- package/lib/esm/auth/hooks/useRefreshTokens.js +8 -4
- package/lib/esm/auth/hooks/useRefreshTokens.js.map +1 -1
- package/package.json +8 -8
|
@@ -3,5 +3,6 @@ export type RefreshAuthTokensProviderProps = {
|
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
authenticationInfo?: AuthenticationInfo;
|
|
5
5
|
refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>;
|
|
6
|
+
bufferMinutes?: number;
|
|
6
7
|
};
|
|
7
8
|
export declare const RefreshAuthTokensProvider: import("react").NamedExoticComponent<RefreshAuthTokensProviderProps>;
|
|
@@ -4,8 +4,8 @@ exports.RefreshAuthTokensProvider = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const hooks_1 = require("./hooks");
|
|
7
|
-
const RefreshAuthTokensProviderComponent = ({ children, authenticationInfo, refreshTokens }) => {
|
|
8
|
-
(0, hooks_1.useRefreshTokens)(authenticationInfo, refreshTokens);
|
|
7
|
+
const RefreshAuthTokensProviderComponent = ({ children, authenticationInfo, refreshTokens, bufferMinutes, }) => {
|
|
8
|
+
(0, hooks_1.useRefreshTokens)(authenticationInfo, refreshTokens, bufferMinutes);
|
|
9
9
|
// This fragment is not useless!
|
|
10
10
|
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
|
|
11
11
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RefreshAuthTokensProvider.js","sourceRoot":"","sources":["../../../src/auth/RefreshAuthTokensProvider.tsx"],"names":[],"mappings":";;;;AAEA,iCAA6B;AAE7B,mCAA2C;
|
|
1
|
+
{"version":3,"file":"RefreshAuthTokensProvider.js","sourceRoot":"","sources":["../../../src/auth/RefreshAuthTokensProvider.tsx"],"names":[],"mappings":";;;;AAEA,iCAA6B;AAE7B,mCAA2C;AAU3C,MAAM,kCAAkC,GAA6C,CAAC,EACpF,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,EAAE,EAAE;IACH,IAAA,wBAAgB,EAAC,kBAAkB,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;IAEnE,gCAAgC;IAChC,OAAO,2DAAG,QAAQ,GAAI,CAAC;AACzB,CAAC,CAAC;AAEW,QAAA,yBAAyB,GAAG,IAAA,YAAI,EAAC,kCAAkC,CAAC,CAAC","sourcesContent":["import { AuthenticationInfo } from 'quidproquo-core';\n\nimport { memo } from 'react';\n\nimport { useRefreshTokens } from './hooks';\n\nexport type RefreshAuthTokensProviderProps = {\n children: React.ReactNode;\n authenticationInfo?: AuthenticationInfo;\n refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>;\n // Minutes before expiry to proactively refresh (default 10). Lower it for short-lived tokens.\n bufferMinutes?: number;\n};\n\nconst RefreshAuthTokensProviderComponent: React.FC<RefreshAuthTokensProviderProps> = ({\n children,\n authenticationInfo,\n refreshTokens,\n bufferMinutes,\n}) => {\n useRefreshTokens(authenticationInfo, refreshTokens, bufferMinutes);\n\n // This fragment is not useless!\n return <>{children}</>;\n};\n\nexport const RefreshAuthTokensProvider = memo(RefreshAuthTokensProviderComponent);\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { AuthenticationInfo } from 'quidproquo-core';
|
|
2
|
-
export declare const useRefreshTokens: (authenticationInfo: AuthenticationInfo | undefined, refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any
|
|
2
|
+
export declare const useRefreshTokens: (authenticationInfo: AuthenticationInfo | undefined, refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>, bufferMinutes?: number) => void;
|
|
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.useRefreshTokens = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const useFastCallback_1 = require("../../hooks/useFastCallback");
|
|
6
|
-
|
|
6
|
+
// How many minutes before a token expires to proactively refresh it. Must be shorter than
|
|
7
|
+
// the token's lifetime, or `refreshTime` is always negative and every render refreshes
|
|
8
|
+
// immediately (a loop). Apps with short-lived tokens should lower this.
|
|
9
|
+
const DEFAULT_REFRESH_BUFFER_MINUTES = 10;
|
|
10
|
+
const useRefreshTokens = (authenticationInfo, refreshTokens, bufferMinutes = DEFAULT_REFRESH_BUFFER_MINUTES) => {
|
|
7
11
|
const stableRefreshTokens = (0, useFastCallback_1.useFastCallback)(refreshTokens);
|
|
8
12
|
// Stable identity so the effect below can list it as a dependency without
|
|
9
13
|
// re-running on every render.
|
|
@@ -11,8 +15,8 @@ const useRefreshTokens = (authenticationInfo, refreshTokens) => {
|
|
|
11
15
|
if (authenticationInfo && authenticationInfo.refreshToken && authenticationInfo.expiresAt) {
|
|
12
16
|
const now = new Date().toISOString();
|
|
13
17
|
const timeToExpire = new Date(authenticationInfo.expiresAt).getTime() - new Date(now).getTime();
|
|
14
|
-
// Refresh
|
|
15
|
-
const bufferTime =
|
|
18
|
+
// Refresh `bufferMinutes` before expiry so there's margin for the refresh round-trip.
|
|
19
|
+
const bufferTime = bufferMinutes * 60 * 1000;
|
|
16
20
|
const refreshTime = timeToExpire - bufferTime;
|
|
17
21
|
if (refreshTime > 0) {
|
|
18
22
|
return setTimeout(() => {
|
|
@@ -40,7 +44,7 @@ const useRefreshTokens = (authenticationInfo, refreshTokens) => {
|
|
|
40
44
|
// reference would re-run this effect every render — and when the token is
|
|
41
45
|
// expired/near-expiry the "refresh immediately" branch would then fire a
|
|
42
46
|
// network refresh on every render, an unbounded loop.
|
|
43
|
-
}, [refresh, authenticationInfo === null || authenticationInfo === void 0 ? void 0 : authenticationInfo.expiresAt, authenticationInfo === null || authenticationInfo === void 0 ? void 0 : authenticationInfo.refreshToken]);
|
|
47
|
+
}, [refresh, authenticationInfo === null || authenticationInfo === void 0 ? void 0 : authenticationInfo.expiresAt, authenticationInfo === null || authenticationInfo === void 0 ? void 0 : authenticationInfo.refreshToken, bufferMinutes]);
|
|
44
48
|
};
|
|
45
49
|
exports.useRefreshTokens = useRefreshTokens;
|
|
46
50
|
//# sourceMappingURL=useRefreshTokens.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRefreshTokens.js","sourceRoot":"","sources":["../../../../src/auth/hooks/useRefreshTokens.ts"],"names":[],"mappings":";;;AAEA,iCAAkC;AAElC,iEAA8D;
|
|
1
|
+
{"version":3,"file":"useRefreshTokens.js","sourceRoot":"","sources":["../../../../src/auth/hooks/useRefreshTokens.ts"],"names":[],"mappings":";;;AAEA,iCAAkC;AAElC,iEAA8D;AAE9D,0FAA0F;AAC1F,uFAAuF;AACvF,wEAAwE;AACxE,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAEnC,MAAM,gBAAgB,GAAG,CAC9B,kBAAkD,EAClD,aAAuE,EACvE,gBAAwB,8BAA8B,EACtD,EAAE;IACF,MAAM,mBAAmB,GAAG,IAAA,iCAAe,EAAC,aAAa,CAAC,CAAC;IAE3D,0EAA0E;IAC1E,8BAA8B;IAC9B,MAAM,OAAO,GAAG,IAAA,iCAAe,EAAC,GAAG,EAAE;QACnC,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,YAAY,IAAI,kBAAkB,CAAC,SAAS,EAAE,CAAC;YAC1F,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;YAEhG,sFAAsF;YACtF,MAAM,UAAU,GAAG,aAAa,GAAG,EAAE,GAAG,IAAI,CAAC;YAC7C,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;YAE9C,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACpB,OAAO,UAAU,CAAC,GAAG,EAAE;oBACrB,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;gBAC1C,CAAC,EAAE,WAAW,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,mFAAmF;gBACnF,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;QAE1B,OAAO,GAAG,EAAE;YACV,+CAA+C;YAC/C,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QACF,sEAAsE;QACtE,wEAAwE;QACxE,2EAA2E;QAC3E,0EAA0E;QAC1E,yEAAyE;QACzE,sDAAsD;IACxD,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,SAAS,EAAE,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;AAChG,CAAC,CAAC;AA/CW,QAAA,gBAAgB,oBA+C3B","sourcesContent":["import { AuthenticationInfo } from 'quidproquo-core';\n\nimport { useEffect } from 'react';\n\nimport { useFastCallback } from '../../hooks/useFastCallback';\n\n// How many minutes before a token expires to proactively refresh it. Must be shorter than\n// the token's lifetime, or `refreshTime` is always negative and every render refreshes\n// immediately (a loop). Apps with short-lived tokens should lower this.\nconst DEFAULT_REFRESH_BUFFER_MINUTES = 10;\n\nexport const useRefreshTokens = (\n authenticationInfo: AuthenticationInfo | undefined,\n refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>,\n bufferMinutes: number = DEFAULT_REFRESH_BUFFER_MINUTES,\n) => {\n const stableRefreshTokens = useFastCallback(refreshTokens);\n\n // Stable identity so the effect below can list it as a dependency without\n // re-running on every render.\n const refresh = useFastCallback(() => {\n if (authenticationInfo && authenticationInfo.refreshToken && authenticationInfo.expiresAt) {\n const now = new Date().toISOString();\n const timeToExpire = new Date(authenticationInfo.expiresAt).getTime() - new Date(now).getTime();\n\n // Refresh `bufferMinutes` before expiry so there's margin for the refresh round-trip.\n const bufferTime = bufferMinutes * 60 * 1000;\n const refreshTime = timeToExpire - bufferTime;\n\n if (refreshTime > 0) {\n return setTimeout(() => {\n stableRefreshTokens(authenticationInfo);\n }, refreshTime);\n } else {\n // If the token is already expired or very close to expiration, refresh immediately\n stableRefreshTokens(authenticationInfo);\n }\n }\n\n return null;\n });\n\n useEffect(() => {\n const timerId = refresh();\n\n return () => {\n // Cleanup on unmount or when authState changes\n if (timerId) {\n clearTimeout(timerId);\n }\n };\n // Key on the stable primitives that actually drive a refresh, not the\n // authenticationInfo object itself. Callers commonly derive that object\n // fresh on every render (e.g. an unmemoized selector), so depending on its\n // reference would re-run this effect every render — and when the token is\n // expired/near-expiry the \"refresh immediately\" branch would then fire a\n // network refresh on every render, an unbounded loop.\n }, [refresh, authenticationInfo?.expiresAt, authenticationInfo?.refreshToken, bufferMinutes]);\n};\n"]}
|
|
@@ -3,5 +3,6 @@ export type RefreshAuthTokensProviderProps = {
|
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
authenticationInfo?: AuthenticationInfo;
|
|
5
5
|
refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>;
|
|
6
|
+
bufferMinutes?: number;
|
|
6
7
|
};
|
|
7
8
|
export declare const RefreshAuthTokensProvider: import("react").NamedExoticComponent<RefreshAuthTokensProviderProps>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { useRefreshTokens } from './hooks';
|
|
4
|
-
const RefreshAuthTokensProviderComponent = ({ children, authenticationInfo, refreshTokens }) => {
|
|
5
|
-
useRefreshTokens(authenticationInfo, refreshTokens);
|
|
4
|
+
const RefreshAuthTokensProviderComponent = ({ children, authenticationInfo, refreshTokens, bufferMinutes, }) => {
|
|
5
|
+
useRefreshTokens(authenticationInfo, refreshTokens, bufferMinutes);
|
|
6
6
|
// This fragment is not useless!
|
|
7
7
|
return _jsx(_Fragment, { children: children });
|
|
8
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RefreshAuthTokensProvider.js","sourceRoot":"","sources":["../../../src/auth/RefreshAuthTokensProvider.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"RefreshAuthTokensProvider.js","sourceRoot":"","sources":["../../../src/auth/RefreshAuthTokensProvider.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAU3C,MAAM,kCAAkC,GAA6C,CAAC,EACpF,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,EAAE,EAAE;IACH,gBAAgB,CAAC,kBAAkB,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;IAEnE,gCAAgC;IAChC,OAAO,4BAAG,QAAQ,GAAI,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC,kCAAkC,CAAC,CAAC","sourcesContent":["import { AuthenticationInfo } from 'quidproquo-core';\n\nimport { memo } from 'react';\n\nimport { useRefreshTokens } from './hooks';\n\nexport type RefreshAuthTokensProviderProps = {\n children: React.ReactNode;\n authenticationInfo?: AuthenticationInfo;\n refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>;\n // Minutes before expiry to proactively refresh (default 10). Lower it for short-lived tokens.\n bufferMinutes?: number;\n};\n\nconst RefreshAuthTokensProviderComponent: React.FC<RefreshAuthTokensProviderProps> = ({\n children,\n authenticationInfo,\n refreshTokens,\n bufferMinutes,\n}) => {\n useRefreshTokens(authenticationInfo, refreshTokens, bufferMinutes);\n\n // This fragment is not useless!\n return <>{children}</>;\n};\n\nexport const RefreshAuthTokensProvider = memo(RefreshAuthTokensProviderComponent);\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { AuthenticationInfo } from 'quidproquo-core';
|
|
2
|
-
export declare const useRefreshTokens: (authenticationInfo: AuthenticationInfo | undefined, refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any
|
|
2
|
+
export declare const useRefreshTokens: (authenticationInfo: AuthenticationInfo | undefined, refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>, bufferMinutes?: number) => void;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { useFastCallback } from '../../hooks/useFastCallback';
|
|
3
|
-
|
|
3
|
+
// How many minutes before a token expires to proactively refresh it. Must be shorter than
|
|
4
|
+
// the token's lifetime, or `refreshTime` is always negative and every render refreshes
|
|
5
|
+
// immediately (a loop). Apps with short-lived tokens should lower this.
|
|
6
|
+
const DEFAULT_REFRESH_BUFFER_MINUTES = 10;
|
|
7
|
+
export const useRefreshTokens = (authenticationInfo, refreshTokens, bufferMinutes = DEFAULT_REFRESH_BUFFER_MINUTES) => {
|
|
4
8
|
const stableRefreshTokens = useFastCallback(refreshTokens);
|
|
5
9
|
// Stable identity so the effect below can list it as a dependency without
|
|
6
10
|
// re-running on every render.
|
|
@@ -8,8 +12,8 @@ export const useRefreshTokens = (authenticationInfo, refreshTokens) => {
|
|
|
8
12
|
if (authenticationInfo && authenticationInfo.refreshToken && authenticationInfo.expiresAt) {
|
|
9
13
|
const now = new Date().toISOString();
|
|
10
14
|
const timeToExpire = new Date(authenticationInfo.expiresAt).getTime() - new Date(now).getTime();
|
|
11
|
-
// Refresh
|
|
12
|
-
const bufferTime =
|
|
15
|
+
// Refresh `bufferMinutes` before expiry so there's margin for the refresh round-trip.
|
|
16
|
+
const bufferTime = bufferMinutes * 60 * 1000;
|
|
13
17
|
const refreshTime = timeToExpire - bufferTime;
|
|
14
18
|
if (refreshTime > 0) {
|
|
15
19
|
return setTimeout(() => {
|
|
@@ -37,6 +41,6 @@ export const useRefreshTokens = (authenticationInfo, refreshTokens) => {
|
|
|
37
41
|
// reference would re-run this effect every render — and when the token is
|
|
38
42
|
// expired/near-expiry the "refresh immediately" branch would then fire a
|
|
39
43
|
// network refresh on every render, an unbounded loop.
|
|
40
|
-
}, [refresh, authenticationInfo?.expiresAt, authenticationInfo?.refreshToken]);
|
|
44
|
+
}, [refresh, authenticationInfo?.expiresAt, authenticationInfo?.refreshToken, bufferMinutes]);
|
|
41
45
|
};
|
|
42
46
|
//# sourceMappingURL=useRefreshTokens.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRefreshTokens.js","sourceRoot":"","sources":["../../../../src/auth/hooks/useRefreshTokens.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,kBAAkD,EAClD,aAAuE,EACvE,EAAE;IACF,MAAM,mBAAmB,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IAE3D,0EAA0E;IAC1E,8BAA8B;IAC9B,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,EAAE;QACnC,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,YAAY,IAAI,kBAAkB,CAAC,SAAS,EAAE,CAAC;YAC1F,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;YAEhG,
|
|
1
|
+
{"version":3,"file":"useRefreshTokens.js","sourceRoot":"","sources":["../../../../src/auth/hooks/useRefreshTokens.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,0FAA0F;AAC1F,uFAAuF;AACvF,wEAAwE;AACxE,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,kBAAkD,EAClD,aAAuE,EACvE,gBAAwB,8BAA8B,EACtD,EAAE;IACF,MAAM,mBAAmB,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IAE3D,0EAA0E;IAC1E,8BAA8B;IAC9B,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,EAAE;QACnC,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,YAAY,IAAI,kBAAkB,CAAC,SAAS,EAAE,CAAC;YAC1F,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;YAEhG,sFAAsF;YACtF,MAAM,UAAU,GAAG,aAAa,GAAG,EAAE,GAAG,IAAI,CAAC;YAC7C,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;YAE9C,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACpB,OAAO,UAAU,CAAC,GAAG,EAAE;oBACrB,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;gBAC1C,CAAC,EAAE,WAAW,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,mFAAmF;gBACnF,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;QAE1B,OAAO,GAAG,EAAE;YACV,+CAA+C;YAC/C,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QACF,sEAAsE;QACtE,wEAAwE;QACxE,2EAA2E;QAC3E,0EAA0E;QAC1E,yEAAyE;QACzE,sDAAsD;IACxD,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;AAChG,CAAC,CAAC","sourcesContent":["import { AuthenticationInfo } from 'quidproquo-core';\n\nimport { useEffect } from 'react';\n\nimport { useFastCallback } from '../../hooks/useFastCallback';\n\n// How many minutes before a token expires to proactively refresh it. Must be shorter than\n// the token's lifetime, or `refreshTime` is always negative and every render refreshes\n// immediately (a loop). Apps with short-lived tokens should lower this.\nconst DEFAULT_REFRESH_BUFFER_MINUTES = 10;\n\nexport const useRefreshTokens = (\n authenticationInfo: AuthenticationInfo | undefined,\n refreshTokens: (authenticationInfo: AuthenticationInfo) => Promise<any>,\n bufferMinutes: number = DEFAULT_REFRESH_BUFFER_MINUTES,\n) => {\n const stableRefreshTokens = useFastCallback(refreshTokens);\n\n // Stable identity so the effect below can list it as a dependency without\n // re-running on every render.\n const refresh = useFastCallback(() => {\n if (authenticationInfo && authenticationInfo.refreshToken && authenticationInfo.expiresAt) {\n const now = new Date().toISOString();\n const timeToExpire = new Date(authenticationInfo.expiresAt).getTime() - new Date(now).getTime();\n\n // Refresh `bufferMinutes` before expiry so there's margin for the refresh round-trip.\n const bufferTime = bufferMinutes * 60 * 1000;\n const refreshTime = timeToExpire - bufferTime;\n\n if (refreshTime > 0) {\n return setTimeout(() => {\n stableRefreshTokens(authenticationInfo);\n }, refreshTime);\n } else {\n // If the token is already expired or very close to expiration, refresh immediately\n stableRefreshTokens(authenticationInfo);\n }\n }\n\n return null;\n });\n\n useEffect(() => {\n const timerId = refresh();\n\n return () => {\n // Cleanup on unmount or when authState changes\n if (timerId) {\n clearTimeout(timerId);\n }\n };\n // Key on the stable primitives that actually drive a refresh, not the\n // authenticationInfo object itself. Callers commonly derive that object\n // fresh on every render (e.g. an unmemoized selector), so depending on its\n // reference would re-run this effect every render — and when the token is\n // expired/near-expiry the \"refresh immediately\" branch would then fire a\n // network refresh on every render, an unbounded loop.\n }, [refresh, authenticationInfo?.expiresAt, authenticationInfo?.refreshToken, bufferMinutes]);\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quidproquo-web-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@testing-library/dom": "^10.4.1",
|
|
36
36
|
"@testing-library/react": "^16.3.2",
|
|
37
|
-
"quidproquo-core": "0.1.
|
|
38
|
-
"quidproquo-tsconfig": "0.1.
|
|
37
|
+
"quidproquo-core": "0.1.10",
|
|
38
|
+
"quidproquo-tsconfig": "0.1.10",
|
|
39
39
|
"typescript": "^5.8.2"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"jotai": "^2.12.1",
|
|
46
|
-
"quidproquo-actionprocessor-node": "0.1.
|
|
47
|
-
"quidproquo-actionprocessor-web": "0.1.
|
|
48
|
-
"quidproquo-features": "0.1.
|
|
49
|
-
"quidproquo-web": "0.1.
|
|
50
|
-
"quidproquo-webserver": "0.1.
|
|
46
|
+
"quidproquo-actionprocessor-node": "0.1.10",
|
|
47
|
+
"quidproquo-actionprocessor-web": "0.1.10",
|
|
48
|
+
"quidproquo-features": "0.1.10",
|
|
49
|
+
"quidproquo-web": "0.1.10",
|
|
50
|
+
"quidproquo-webserver": "0.1.10",
|
|
51
51
|
"symbol-observable": "^4.0.0"
|
|
52
52
|
}
|
|
53
53
|
}
|