1import Axios from 'axios'; 2import router from '../router'; 3import { setupCache, buildWebStorage } from 'axios-cache-interceptor'; 4 5//Do not change store import. 6//Exact match alias set to support 7//dotenv customizations. 8import store from '.'; 9 10Axios.defaults.headers.common['Accept'] = 'application/json'; 11Axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 12 13const axiosInstance = Axios.create({ 14 withCredentials: true, 15}); 16 17const api = setupCache(axiosInstance, { 18 debug: console.log, 19 methods: ['get'], 20 interpretHeader: false, 21 etag: true, 22 modifiedSince: false, 23 staleIfError: false, 24 ttl: 0, 25 storage: buildWebStorage(localStorage, 'webui-vue-cache:'), 26}); 27 28api.interceptors.response.use(undefined, (error) => { 29 let response = error.response; 30 31 // TODO: Provide user with a notification and way to keep system active 32 if (response.status == 401) { 33 if (response.config.url != '/login') { 34 window.location = '/login'; 35 // Commit logout to remove XSRF-TOKEN cookie 36 store.commit('authentication/logout'); 37 } 38 } 39 40 // Check if action is unauthorized. 41 if (response.status == 403) { 42 if (isPasswordExpired(response.data)) { 43 router.push('/change-password'); 44 } else { 45 // Toast error message will appear on screen. 46 store.commit('global/setUnauthorized'); 47 } 48 } 49 50 return Promise.reject(error); 51}); 52 53export default { 54 get(path, config) { 55 return api.get(path, config); 56 }, 57 delete(path, config) { 58 return api.delete(path, config); 59 }, 60 post(path, payload, config) { 61 return api.post(path, payload, config); 62 }, 63 patch(path, payload, config) { 64 return api.patch(path, payload, config); 65 }, 66 put(path, payload, config) { 67 return api.put(path, payload, config); 68 }, 69 all(promises) { 70 return Axios.all(promises); 71 }, 72 spread(callback) { 73 return Axios.spread(callback); 74 }, 75 set_auth_token(token) { 76 axiosInstance.defaults.headers.common['X-Auth-Token'] = token; 77 }, 78}; 79 80export const getResponseCount = (responses) => { 81 let successCount = 0; 82 let errorCount = 0; 83 84 responses.forEach((response) => { 85 if (response instanceof Error) errorCount++; 86 else successCount++; 87 }); 88 89 return { 90 successCount, 91 errorCount, 92 }; 93}; 94 95export const isPasswordExpired = (data) => { 96 return !!findMessageId(data, 'PasswordChangeRequired'); 97}; 98 99/** 100 * Returns the first ExtendedInfo.Message to start with the 101 * Registry Name (Default: "Base") and end with the given key 102 * Ignore versions (.<X>.<Y>) --or-- (.<X>.<Y>.<Z>.), 103 * but adhere to Registry namespace 104 * @param {object} data - AxiosResponse.data 105 * @param { {MessageKey: string}} key - key into the message registry 106 * @param { {MessageRegistryPrefix: string}} [registry=Base] - the name of the 107 * message registry, undefined param defaults to "Base" 108 * @returns {ExtendedInfo.Message} ExtendedInfo.Message | undefined 109 */ 110export const findMessageId = (data, key, registry = 'Base') => { 111 let extInfoMsgs = data?.['@Message.ExtendedInfo']; 112 113 return ( 114 extInfoMsgs && 115 extInfoMsgs.find((i) => { 116 const words = i.MessageId.split('.'); 117 return words[words.length - 1] === key && words[0] === registry; 118 }) 119 ); 120}; 121