saleor-dashboard/src/apps/components/AppFrame/useTokenRefresh.ts

67 lines
1.5 KiB
TypeScript
Raw Normal View History

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 = {
exp: 0,
iat: 0,
};
// 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 || 0) - (decoded?.iat || 0)) * 1000; // in ms
const refreshTime = tokenLife - TIME_BEFORE_REFRESH;
const setUpTimeout = () => {
if (refetch) {
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 () => {
if (!!refetch && decodedSuccesfully) {
deleteTimeout();
}
};
}, [token]);
};
export default useTokenRefresh;