import fromUnixTime from 'date-fns/fromUnixTime'; import differenceInDays from 'date-fns/differenceInDays'; import Cookies from 'js-cookie'; import { LOCAL_STORAGE_KEYS } from 'dashboard/constants/localStorage'; import { SESSION_STORAGE_KEYS } from 'dashboard/constants/sessionStorage'; import { LocalStorage } from 'shared/helpers/localStorage'; import SessionStorage from 'shared/helpers/sessionStorage'; import { emitter } from 'shared/helpers/mitt'; import { ANALYTICS_IDENTITY, ANALYTICS_RESET, CHATWOOT_RESET, CHATWOOT_SET_USER, } from '../../constants/appEvents'; Cookies.defaults = { sameSite: 'Lax' }; export const getLoadingStatus = state => state.fetchAPIloadingStatus; export const setLoadingStatus = (state, status) => { state.fetchAPIloadingStatus = status; }; export const setUser = user => { emitter.emit(CHATWOOT_SET_USER, { user }); emitter.emit(ANALYTICS_IDENTITY, { user }); }; export const getHeaderExpiry = response => fromUnixTime(response.headers.expiry); export const setAuthCredentials = response => { const expiryDate = getHeaderExpiry(response); Cookies.set('cw_d_session_info', JSON.stringify(response.headers), { expires: differenceInDays(expiryDate, new Date()), }); setUser(response.data.data, expiryDate); }; export const clearBrowserSessionCookies = () => { Cookies.remove('cw_d_session_info'); Cookies.remove('auth_data'); Cookies.remove('user'); }; export const clearLocalStorageOnLogout = () => { LocalStorage.remove(LOCAL_STORAGE_KEYS.DRAFT_MESSAGES); }; export const clearSessionStorageOnLogout = () => { SessionStorage.remove(SESSION_STORAGE_KEYS.IMPERSONATION_USER); }; export const deleteIndexedDBOnLogout = async () => { let dbs = []; try { dbs = await window.indexedDB.databases(); dbs = dbs.map(db => db.name); } catch (e) { dbs = JSON.parse(localStorage.getItem('cw-idb-names') || '[]'); } dbs.forEach(dbName => { const deleteRequest = window.indexedDB.deleteDatabase(dbName); deleteRequest.onerror = event => { // eslint-disable-next-line no-console console.error(`Error deleting database ${dbName}.`, event); }; deleteRequest.onsuccess = () => { // eslint-disable-next-line no-console console.log(`Database ${dbName} deleted successfully.`); }; }); localStorage.removeItem('cw-idb-names'); }; export const clearCookiesOnLogout = () => { emitter.emit(CHATWOOT_RESET); emitter.emit(ANALYTICS_RESET); clearBrowserSessionCookies(); clearLocalStorageOnLogout(); clearSessionStorageOnLogout(); const globalConfig = window.globalConfig || {}; const logoutRedirectLink = globalConfig.LOGOUT_REDIRECT_LINK || '/'; window.location = logoutRedirectLink; }; export const parseAPIErrorResponse = error => { if (error?.response?.data?.message) { return error?.response?.data?.message; } if (error?.response?.data?.error) { // error could be a string or an object with a message property if (typeof error.response.data.error === 'string') { return error.response.data.error; } if (error.response.data.error?.message) { return error.response.data.error.message; } return JSON.stringify(error.response.data.error); } if (error?.response?.data?.errors) { const first = error.response.data.errors; if (Array.isArray(first)) { return first[0]; } return first; } // Fallback: return a useful default message rather than the raw error object if (error?.message && typeof error.message === 'string') { return error.message; } return 'Request failed. Please try again.'; }; export const throwErrorMessage = error => { const errorMessage = parseAPIErrorResponse(error); throw new Error(errorMessage); }; export const parseLinearAPIErrorResponse = (error, defaultMessage) => { const errorData = error.response.data; const errorMessage = errorData?.error?.errors?.[0]?.message || defaultMessage; return errorMessage; };