
* Install jwt-decode * Add token refetch hook * Fix types * Remove app settings * Regenerate lock * Fix jwt test issues * CR fixes * Bump node and npm * Reinstall jwt-decode
57 lines
1.4 KiB
TypeScript
57 lines
1.4 KiB
TypeScript
import jwt_decode from "jwt-decode";
|
|
import { useEffect, useRef } from "react";
|
|
|
|
interface AppToken {
|
|
exp?: number;
|
|
iat?: number;
|
|
}
|
|
|
|
const TIME_BEFORE_REFRESH = 30 * 1000; // 30 seconds
|
|
|
|
const useTokenRefresh = (token?: string, refetch?: () => void) => {
|
|
let decoded: AppToken;
|
|
|
|
// For some reason jwt_decode causes seemingly unrelated error in tests
|
|
// It seems like at some point undefined token is passed
|
|
// Wrapping it in try..catch and if fixes the issue
|
|
try {
|
|
if (token) {
|
|
decoded = jwt_decode(token) as AppToken;
|
|
}
|
|
} catch (e) {
|
|
console.warn(e);
|
|
}
|
|
|
|
const decodedSuccesfully = !!decoded?.iat && !!decoded?.exp;
|
|
|
|
const refreshTimeout = useRef<null | ReturnType<typeof setTimeout>>(null);
|
|
|
|
const tokenLife = (decoded?.exp - decoded?.iat) * 1000; // in ms
|
|
const refreshTime = tokenLife - TIME_BEFORE_REFRESH;
|
|
|
|
const setUpTimeout = () => {
|
|
refetch();
|
|
createTimeout();
|
|
};
|
|
|
|
const createTimeout = () => {
|
|
refreshTimeout.current = setTimeout(setUpTimeout, refreshTime);
|
|
};
|
|
|
|
const deleteTimeout = () => {
|
|
if (refreshTimeout?.current) {
|
|
clearTimeout(refreshTimeout.current);
|
|
refreshTimeout.current = null;
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (refetch && decodedSuccesfully) {
|
|
createTimeout();
|
|
}
|
|
|
|
return () => !!refetch && decodedSuccesfully && deleteTimeout();
|
|
}, [token]);
|
|
};
|
|
|
|
export default useTokenRefresh;
|