react-oauth2-code-pkce
Advanced tools
Comparing version 1.13.3 to 1.13.4
import React from 'react'; | ||
import { IAuthContext, IAuthProvider } from './Types'; | ||
export declare const AuthContext: React.Context<IAuthContext>; | ||
export declare const AuthProvider: ({ authConfig, children }: IAuthProvider) => JSX.Element; | ||
export declare const AuthProvider: ({ authConfig, children }: IAuthProvider) => React.JSX.Element; |
@@ -30,6 +30,6 @@ "use strict"; | ||
exports.AuthProvider = exports.AuthContext = void 0; | ||
const react_1 = __importStar(require("react")); // eslint-disable-line | ||
const react_1 = __importStar(require("react")); | ||
const authentication_1 = require("./authentication"); | ||
const Hooks_1 = __importDefault(require("./Hooks")); | ||
const validateAuthConfig_1 = require("./validateAuthConfig"); | ||
const authConfig_1 = require("./authConfig"); | ||
const timeUtils_1 = require("./timeUtils"); | ||
@@ -46,6 +46,3 @@ const decodeJWT_1 = require("./decodeJWT"); | ||
const AuthProvider = ({ authConfig, children }) => { | ||
// Set default values for internal config object | ||
const { autoLogin = true, clearURL = true, decodeToken = true, scope = '', preLogin = () => null, postLogin = () => null, onRefreshTokenExpire = undefined, storage = 'local', } = authConfig; | ||
const config = Object.assign(Object.assign({}, authConfig), { autoLogin: autoLogin, clearURL: clearURL, decodeToken: decodeToken, scope: scope, preLogin: preLogin, postLogin: postLogin, onRefreshTokenExpire: onRefreshTokenExpire, storage: storage }); | ||
(0, validateAuthConfig_1.validateAuthConfig)(config); | ||
const config = (0, react_1.useMemo)(() => (0, authConfig_1.createInternalConfig)(authConfig), [authConfig]); | ||
const [refreshToken, setRefreshToken] = (0, Hooks_1.default)('ROCP_refreshToken', undefined, config.storage); | ||
@@ -83,3 +80,3 @@ const [refreshTokenExpire, setRefreshTokenExpire] = (0, Hooks_1.default)('ROCP_refreshTokenExpire', (0, timeUtils_1.epochAtSecondsFromNow)(2 * timeUtils_1.FALLBACK_EXPIRE_TIME), config.storage); | ||
let typeSafePassedState = state; | ||
if (typeof state !== 'string') { | ||
if (state && typeof state !== 'string') { | ||
console.warn(`Passed login state must be of type 'string'. Received '${state}'. Ignoring value...`); | ||
@@ -123,31 +120,32 @@ typeSafePassedState = undefined; | ||
// TODO: Breaking change - remove automatic login during ongoing session | ||
else if (!onRefreshTokenExpire) | ||
else if (!config.onRefreshTokenExpire) | ||
return login(); | ||
else | ||
return onRefreshTokenExpire({ login }); | ||
return config.onRefreshTokenExpire({ login }); | ||
} | ||
function refreshAccessToken(initial = false) { | ||
// Only refresh if no other instance (tab) is currently refreshing, or it's initial page load | ||
if (token && (0, timeUtils_1.epochTimeIsPast)(tokenExpire) && (!refreshInProgress || initial)) { | ||
// We have a refreshToken, and it is not expired | ||
if (refreshToken && !(0, timeUtils_1.epochTimeIsPast)(refreshTokenExpire)) { | ||
setRefreshInProgress(true); | ||
(0, authentication_1.fetchWithRefreshToken)({ config, refreshToken }) | ||
.then((result) => handleTokenResponse(result)) | ||
.catch((error) => { | ||
if (error instanceof errors_1.FetchError) { | ||
// If the fetch failed with status 400, assume expired refresh token | ||
if (error.status === 400) { | ||
return handleExpiredRefreshToken(initial); | ||
} | ||
// Unknown error. Set error, and login if first page load | ||
else { | ||
console.error(error); | ||
setError(error.message); | ||
if (initial) | ||
login(); | ||
} | ||
if (!token) | ||
return; | ||
// The token has not expired. Do nothing | ||
if (!(0, timeUtils_1.epochTimeIsPast)(tokenExpire)) | ||
return; | ||
// Other instance (tab) is currently refreshing. This instance skip the refresh if not initial | ||
if (refreshInProgress && !initial) | ||
return; | ||
// The refreshToken has expired | ||
if ((0, timeUtils_1.epochTimeIsPast)(refreshTokenExpire)) | ||
return handleExpiredRefreshToken(initial); | ||
// The access_token has expired, and we have a non-expired refresh_token. Use it to refresh access_token. | ||
if (refreshToken) { | ||
setRefreshInProgress(true); | ||
(0, authentication_1.fetchWithRefreshToken)({ config, refreshToken }) | ||
.then((result) => handleTokenResponse(result)) | ||
.catch((error) => { | ||
if (error instanceof errors_1.FetchError) { | ||
// If the fetch failed with status 400, assume expired refresh token | ||
if (error.status === 400) { | ||
return handleExpiredRefreshToken(initial); | ||
} | ||
// Unknown error. Set error, and login if first page load | ||
else if (error instanceof Error) { | ||
else { | ||
console.error(error); | ||
@@ -158,14 +156,17 @@ setError(error.message); | ||
} | ||
}) | ||
.finally(() => { | ||
setRefreshInProgress(false); | ||
}); | ||
} | ||
// The refreshToken has expired | ||
else { | ||
return handleExpiredRefreshToken(initial); | ||
} | ||
} | ||
// Unknown error. Set error, and login if first page load | ||
else if (error instanceof Error) { | ||
console.error(error); | ||
setError(error.message); | ||
if (initial) | ||
login(); | ||
} | ||
}) | ||
.finally(() => { | ||
setRefreshInProgress(false); | ||
}); | ||
return; | ||
} | ||
// The token has not expired. Do nothing | ||
return; | ||
console.warn('Failed to refresh access_token. Most likely there is no refresh_token, or the authentication server did not reply with an explicit expire time, and the default expire times are longer than the actual tokens expire time'); | ||
} | ||
@@ -183,4 +184,4 @@ // Register the 'check for soon expiring access token' interval (Every 10 seconds) | ||
(0, react_1.useEffect)(() => { | ||
// The client has been redirected back from the auth endpoint with an auth code | ||
if (loginInProgress) { | ||
// The client has been redirected back from the Auth endpoint with an auth code | ||
const urlParams = new URLSearchParams(window.location.search); | ||
@@ -193,4 +194,6 @@ if (!urlParams.get('code')) { | ||
logOut(); | ||
return; | ||
} | ||
else if (!didFetchTokens.current) { | ||
// Make sure we only try to use the auth code once | ||
if (!didFetchTokens.current) { | ||
didFetchTokens.current = true; | ||
@@ -204,3 +207,3 @@ try { | ||
} | ||
// Request token from auth server with the auth code | ||
// Request tokens from auth server with the auth code | ||
(0, authentication_1.fetchTokens)(config) | ||
@@ -224,22 +227,24 @@ .then((tokens) => { | ||
}); | ||
return; | ||
} | ||
} | ||
else if (!token) { | ||
// First page visit | ||
if (config.autoLogin) | ||
login(); | ||
// First page visit | ||
if (!token && config.autoLogin) | ||
return login(); | ||
// Page refresh after login has succeeded | ||
try { | ||
if (idToken) | ||
setIdTokenData((0, decodeJWT_1.decodeJWT)(idToken)); | ||
} | ||
else { | ||
if (decodeToken) { | ||
try { | ||
setTokenData((0, decodeJWT_1.decodeJWT)(token)); | ||
if (idToken) | ||
setIdTokenData((0, decodeJWT_1.decodeJWT)(idToken)); | ||
} | ||
catch (e) { | ||
setError(e.message); | ||
} | ||
} | ||
refreshAccessToken(true); // Check if token should be updated | ||
catch (e) { | ||
console.warn(`Failed to decode idToken: ${e.message}`); | ||
} | ||
try { | ||
if (config.decodeToken) | ||
setTokenData((0, decodeJWT_1.decodeJWT)(token)); | ||
} | ||
catch (e) { | ||
console.warn(`Failed to decode access token: ${e.message}`); | ||
} | ||
refreshAccessToken(true); // Check if token should be updated | ||
}, []); // eslint-disable-line | ||
@@ -246,0 +251,0 @@ return (react_1.default.createElement(exports.AuthContext.Provider, { value: { token, tokenData, idToken, idTokenData, login, logOut, error, loginInProgress } }, children)); |
@@ -27,4 +27,8 @@ "use strict"; | ||
} | ||
return tokenExpiresIn + exports.FALLBACK_EXPIRE_TIME; | ||
// If the response has a refresh_token, but no expire_time. Assume it's at least 10m longer than access_token's expire | ||
if (response.refresh_token) | ||
return tokenExpiresIn + exports.FALLBACK_EXPIRE_TIME; | ||
// The token response had no refresh_token. Set refresh_expire equals to access_token expire | ||
return tokenExpiresIn; | ||
} | ||
exports.getRefreshExpiresIn = getRefreshExpiresIn; |
{ | ||
"name": "react-oauth2-code-pkce", | ||
"version": "1.13.3", | ||
"version": "1.13.4", | ||
"description": "Provider agnostic react package for OAuth2 Authorization Code flow with PKCE", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
45582
751