import { useGlobalStore } from '@store/globalStore' import { useUserStore } from '@store/UserStore' export * from './ApiTypes' import axios from 'axios' export { addAuthHeaders, API_URL } from './Instance' // import {AlgoliaSearch} from './AlgoliaController' import Paths from '@paths' import { tools } from '@src/store/Modules/tools' import { toolsext } from '@src/store/Modules/toolsext' import { serv_constants } from '@src/store/Modules/serv_constants' import router from '@router' import * as Types from '@src/store/Api/ApiTypes' import { costanti } from '@src/store/Modules/costanti' import * as ApiTables from '@src/store/Modules/ApiTables' import sendRequest from './Inst-Pao' import Request from './Instance' import globalroutines from '../../globalroutines/index' import { useRouter } from 'vue-router' function ReceiveResponsefromServer(tablesync: string, nametab: string, method: string, risdata: any) { // console.log('ReceiveResponsefromServer', nametab, method, risdata) if (risdata) { // Updated somw data after Server arrived data. if (method === 'PATCH') { if (nametab === 'projects') { if (risdata.projectris) { const copyrec = tools.jsonCopy(risdata.projectris) // +*Todo conv: Projects.updateProject({ objproj: copyrec }) } } } } } // const algoliaApi = new AlgoliaSearch() export const Api = { async post(path: string, payload?: any) { const globalStore = useGlobalStore() globalStore.connData.downloading_server = 1 globalStore.connData.uploading_server = 1 return Request('post', path, payload) }, async postFormData(path: string, payload?: any) { const globalStore = useGlobalStore() globalStore.connData.uploading_server = 1 globalStore.connData.downloading_server = 1 return Request('postFormData', path, payload) }, async get(path: string, payload?: any) { const globalStore = useGlobalStore() globalStore.connData.downloading_server = 1 globalStore.connData.uploading_server = 0 return Request('get', path, payload) }, async put(path: string, payload?: any) { const globalStore = useGlobalStore() globalStore.connData.uploading_server = 1 return Request('put', path, payload) }, async patch(path: string, payload?: any) { const globalStore = useGlobalStore() globalStore.connData.uploading_server = 1 return Request('patch', path, payload) }, async Delete(path: string, payload: any) { const globalStore = useGlobalStore() globalStore.connData.uploading_server = 1 return Request('delete', path, payload) }, async checkSession({ token, refresh_token }: any) { return axios.post(process.env.API_URL + Paths.TOKEN_REFRESH, { refresh_token, }, { headers: { Authorization: `Bearer ${token}`, }, }) }, async refreshToken() { // Implementa la logica per ottenere un nuovo token utilizzando il refreshToken // Potrebbe essere una chiamata al server simile a sendRequest() // Se il refreshToken è valido, salva il nuovo token e restituiscilo // Altrimenti, gestisci il caso di refreshToken scaduto o invalido, e.g., redirecting to login try { const userStore = useUserStore() // console.log('refreshToken') const refrTok = localStorage.getItem(toolsext.localStorage.refreshToken) let response = null if (refrTok && refrTok !== 'undefined') { // console.log('refreshToken=', refrTok) response = await sendRequest('/users/newtok', 'POST', { refreshToken: refrTok }) if (response) { // Save the new access token in local storage localStorage.setItem(toolsext.localStorage.token, response.data.token); // Reset the refresh token if it was reset by the server if (response.data.refreshToken) { // console.log('salva refreshtoken', response.data.refreshToken) userStore.setRefreshToken(response.data.refreshToken) } // Return the new access token return response.data.token; } else { userStore.setAuth('', '') localStorage.removeItem(toolsext.localStorage.token) localStorage.removeItem(toolsext.localStorage.refreshToken) } } } catch (error) { // Handle the error, for example by logging out the user console.error(error) localStorage.removeItem(toolsext.localStorage.token) localStorage.removeItem(toolsext.localStorage.refreshToken) throw error } }, async SendReqBase(url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false): Promise { const mydataout = { ...mydata, keyappid: process.env.PAO_APP_ID, idapp: process.env.APP_ID, } const userStore = useUserStore() const globalStore = useGlobalStore() const $router = useRouter() userStore.setServerCode(tools.EMPTY) userStore.setResStatus(0) return new Promise((resolve, reject) => sendRequest(url, method, mydataout) .then((res) => { setTimeout(() => { if (method === 'get') { globalStore.connData.downloading_server = 0 } else { globalStore.connData.uploading_server = 0 globalStore.connData.downloading_server = 0 } }, 1000) if (res.status) { userStore.setResStatus(res.status) if (res.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) { userStore.setServerCode(toolsext.ERR_AUTHENTICATION) userStore.setAuth('', '') return reject({ code: toolsext.ERR_AUTHENTICATION }) } } if (tools.isDebug()) console.log(' ----> ', res) return resolve(res) }) .catch(async (error) => { setTimeout(() => { if (method === 'get') { globalStore.connData.downloading_server = -1 } else { globalStore.connData.uploading_server = -1 globalStore.connData.downloading_server = -1 } }, 1000) if (error.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_TOKEN_EXPIRED) { try { const newAccessToken = await this.refreshToken(); if (newAccessToken) { userStore.setAuth(newAccessToken, userStore.refreshToken); if (!evitaloop) return resolve(this.SendReq(url, method, mydata, setAuthToken, true)); } else { $router.push('/signin') } } catch (err2: any) { console.error('err2', err2) if (err2?.code === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) { userStore.setServerCode(toolsext.ERR_AUTHENTICATION) userStore.setAuth('', '') return reject({ code: toolsext.ERR_AUTHENTICATION }) } } } console.log('ERROR', error) return reject(error) })) }, /** * Creates a Promise that resolves after a specified number of milliseconds. * Useful for creating delayed operations or pause in async functions. * * @param ms - The number of milliseconds to delay * @returns A Promise that resolves after the specified delay * * @example * // Basic usage * await delay(1000); // waits for 1 second * * @example * // Usage in an async function * async function example() { * console.log('Start'); * await delay(2000); * console.log('2 seconds later'); * } * * @example * // Usage with Promise chaining * delay(1000).then(() => console.log('1 second passed')); */ async delay (ms: number): Promise { // Input validation if (ms < 0) { throw new Error('Delay time cannot be negative'); } return new Promise(resolve => setTimeout(resolve, ms)); }, async SendReq( url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false, retryCount = 5, retryDelay = 5000 ): Promise { try { const response = await this.SendReqBase(url, method, mydata, setAuthToken, evitaloop); return response; } catch (error) { if (retryCount > 0) { console.log(`❌❌❌ Retrying request. Attempts remaining: ${retryCount}`); await this.delay(retryDelay); return this.SendReq( url, method, mydata, setAuthToken, evitaloop, retryCount - 1, retryDelay ); } throw error; } }, async syncAlternative(mystrparam: string) { console.log('[ALTERNATIVE Background syncing', mystrparam) const multiparams = mystrparam.split('|') if (multiparams) { if (multiparams.length > 3) { const cmd = multiparams[0] const tablesync = multiparams[1] const nametab = multiparams[2] const method = multiparams[3] // const token = multiparams[3] if (cmd === ApiTables.DB.CMD_SYNC) { let errorfromserver = false let lettoqualcosa = false // console.log('A1) INIZIO.............................................................') return globalroutines('readall', tablesync, null) .then((alldata) => { if (alldata === undefined) { console.log('alldata NON DEFINITA') return true } const myrecs = [...alldata] const promises = myrecs.map((rec) => { let link = `/${ApiTables.getLinkByTableName(nametab)}` if (method !== 'POST') { link += `/${rec._id}` } console.log('----------------------- LEGGO QUALCOSA ', link) // Insert/Delete/Update table to the server return this.SendReq(link, method, rec) .then((ris) => { ReceiveResponsefromServer(tablesync, nametab, method, ris.data) lettoqualcosa = true return globalroutines('delete', tablesync, null, rec._id) }) .then(() => { return globalroutines('delete', 'swmsg', null, mystrparam) }).catch((err) => { if (err.msgerr) { if (err.msgerr.message.includes('Failed to fetch') || err.msgerr.message.includes('Network Error')) { errorfromserver = true } } console.log(' [Alternative] !!!!!!!!!!!!!!! Error while sending data', err, errorfromserver, 'lettoqualcosa', lettoqualcosa) if (!errorfromserver) { return globalroutines('delete', 'swmsg', null, mystrparam) } }) }) // CALL ALL THE PROMISES return Promise.all(promises).then(() => (errorfromserver && !lettoqualcosa)).catch((err) => (errorfromserver && !lettoqualcosa)) }).catch((error) => { console.log('¨¨¨¨¨¨¨¨¨¨¨¨¨¨ errorfromserver:', errorfromserver, error) return (errorfromserver && !lettoqualcosa) }) .then((error) => { const mystate = (error || errorfromserver) ? 'offline' : 'online' const globalStore = useGlobalStore() globalStore.setStateConnection(mystate) globalStore.saveConfig({ _id: costanti.CONFIG_ID_STATE_CONN, value: mystate }) }) } } } return null }, }