UNPKG

@nitra/vite-boot

Version:
127 lines (106 loc) 3.72 kB
import jwtDecode from '@nitra/jwt-decode' import { apolloClient, wsClient } from './apollo.js' import { defaultLogin } from './login.js' import { setUser, unsetUser } from './user.js' // @ts-ignore const allowedRoles = import.meta.env.VITE_HASURA_ROLE.split(',') /** * Запам'ятовуємо поточну сторінку * та перенаправляємо на сторінку входу * @param {string} token - JWT токен * @returns {{result: string, decoded?: {}}} - Повертає результат перевірки токена */ export function checkToken(token) { const decoded = jwtDecode(token) if (!decoded || !decoded['https://hasura.io/jwt/claims']) { cleanToken() return { result: 'cleaned' } } if (!decoded['https://hasura.io/jwt/claims']['x-hasura-allowed-roles'].some(x => allowedRoles.includes(x))) { // Виходимо return { result: 'broken-role' } } const isExpired = !decoded || Math.floor(Date.now() / 1000) > decoded.exp if (isExpired) { refreshToken() return { result: 'expired' } } return { result: 'ok', decoded } } /** * Токен з кукі */ export function getToken() { // інакше з кукі const cookieObj = new URLSearchParams(document.cookie.replaceAll('; ', '&')) const token = cookieObj.get('__session') if (token) { return token } // Якщо задано що токен беремо з localStorage return localStorage.getItem('__session') } /** * Переводимо в анонімного користувача */ export function cleanToken() { unsetUser() // видаляємо з localStorage localStorage.removeItem('__session') // @ts-ignore document.cookie = `__session=; Max-Age=0; path=/; domain=${import.meta.env.VITE_DOMAIN}` // eslint-disable-line unicorn/no-document-cookie } /** * */ export async function refreshToken() { try { const token = getToken() // Чекаємо, можливо це паралельний JWTExpired // виходимо якщо вже пішов рефреш токена від іншого запиту if (!token) { return } // Прибираємо токен, щоб інші паралельні JWTExpired не виконувались // cleanToken() const response = await fetch('/auth/refresh-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token }) }) const result = await response.json() // Якщо НЕ успішно отримали токен if (!result.token) { // cleanToken() return } const check = checkToken(result.token) if (check.result !== 'ok') { // cleanToken() return } // Якщо запущений аполо // допускаємо що ми всередині прикладення if (window.location.pathname !== '/login' && apolloClient) { setUser(check.decoded) // перезавантажуємо щоб він вступив в дію wsClient.restart() } else { await defaultLogin(check.decoded, result.token) } } catch (error) { console.error('Error:', error) // } finally { // // Якщо невдача отримання токену // if (!successToken) { // // Якщо користувач не анонімний зараз // // TODO: допрацювати // if (Object.keys(connectionParam).length === 0) { // // перезавантажуємо щоб він вступив в дію як анонімний // wsClient.restart() // } // } } }