import jwt_decode from 'jwt-decode'; import auth from '@/api/auth'; import useCookies from '@/composables/useCookies'; export default () => { const getRaw = (key = 'access') => { const { getItem } = useCookies(); // Get the token const jwt = getItem(key); // If it is not returned, it's expired or doesn't exist if (!jwt) return null; // Isolate the header and payload portions const [header, payload, ...rest] = jwt.split('.'); // Return them, concatenated by a period return `${header}.${payload}`; } const getDecoded = (jwt = null) => { // Get the token if required if (!jwt) jwt = getRaw(); // If it is not returned, it's expired or doesn't exist if (!jwt) return null; // Decode the token const payload = jwt_decode(jwt); // If it is not returned then it is invalid if (!payload) return null; // Case to numeric id payload.sub = parseInt(payload.sub); // Return the decoded payload return payload; } const isAccessValid = async () => { console.log('isAccessValid'); // Check the validity of the access token if (isAccessTokenExpired()) { console.log('its expired'); // Check the validity of the refresh token if (isRefreshTokenExpired()) return false; console.log('refresh token is okay'); // If the refresh was not permitted if (!await attemptRefresh()) return false; console.log('managed to refresh it'); } console.log('it is valid'); // At this point the token is valid return true; } const getDecodedOrRefresh = async (jwt = null) => { console.log('getDecodedOrRefresh') let decodedJwt = getDecoded(jwt); if (decodedJwt) return decodedJwt; const tokenValid = await isAccessValid(); if (!tokenValid) return null; decodedJwt = getDecoded(); return decodedJwt; } const attemptRefresh = async () => { const { status } = await auth.refresh(); if (status !== 200) return false; return true; } const isAccessTokenExpired = () => { // Check the validity of the access token return isTokenExpired('access'); } const isRefreshTokenExpired = () => { // Check the validity of the refresh token return isTokenExpired('refresh'); } const isTokenExpired = (key = null, jwt = null) => { if (!key && !jwt) { console.log('Invalid usage for checkTokenExpiry'); return true; } // Get the access / refresh token cookie if the key is present if (key) jwt = getRaw(key); console.log('isTokenExpired within useJwt, key jwt', key, jwt) // Ensure that the cookie exists if (!jwt) return true; // Try to decode the payload const payload = getDecoded(jwt); console.log('isTokenExpired within useJwt, decoded payload', payload) // If the cookie has expired then no cookie is returned if (!payload) return true; // Check the current system time const timeNow = new Date().getTime(); console.log('isTokenExpired within useJwt, timeNow', timeNow) console.log('isTokenExpired within useJwt, typeof timeNow', typeof timeNow) console.log('isTokenExpired within useJwt, payload.exp*1000', payload.exp*1000) console.log('isTokenExpired within useJwt, typeof payload.exp*1000', typeof (payload.exp*1000)) console.log('isTokenExpired within useJwt, timeNow >= (payload.exp*1000)', timeNow >= parseInt(payload.exp*1000)) // When the token has expired if (timeNow >= (payload.exp*1000)) return true; // The token has not expired return false; } // From auth0 jwt handbook // const getDecoded = (jwt = null) => { // if (!jwt) jwt = getRaw(); // if (!jwt) return null; // const [headerB64, payloadB64] = jwt.split('.'); // // These supports parsing the URL safe variant of Base64 as well. // const headerStr = new Buffer(headerB64, 'base64').toString(); // const payloadStr = new Buffer(payloadB64, 'base64').toString(); // return { // header: JSON.parse(headerStr), // payload: JSON.parse(payloadStr) // }; // } return { getRaw, getDecoded, getDecodedOrRefresh, isTokenExpired, isAccessValid, attemptRefresh }; };