initial commit
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
const AxiosManager = (() => {
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: '/api',
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
});
|
||||
|
||||
let isRefreshing = false;
|
||||
let retryQueue = [];
|
||||
|
||||
axiosInstance.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = StorageManager.getAccessToken();
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
axiosInstance.interceptors.response.use(
|
||||
(response) => response,
|
||||
async (error) => {
|
||||
const originalRequest = error.config;
|
||||
if (error.response && error.response.status === 498) {
|
||||
if (!isRefreshing) {
|
||||
isRefreshing = true;
|
||||
|
||||
try {
|
||||
const refreshToken = StorageManager.getRefreshToken();
|
||||
const response = await axiosInstance.post('/Security/RefreshToken', { refreshToken });
|
||||
|
||||
if (response?.data?.code === 200) {
|
||||
StorageManager.saveLoginResult(response?.data);
|
||||
isRefreshing = false;
|
||||
retryQueue.forEach((cb) => cb());
|
||||
retryQueue = [];
|
||||
return axiosInstance(originalRequest);
|
||||
} else {
|
||||
throw new Error('Refresh token failed');
|
||||
}
|
||||
} catch (refreshError) {
|
||||
retryQueue.forEach((cb) => cb());
|
||||
retryQueue = [];
|
||||
isRefreshing = false;
|
||||
throw refreshError;
|
||||
}
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
retryQueue.push(() => {
|
||||
resolve(axiosInstance(originalRequest));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
const request = async (method, url, data = {}, customHeaders = {}, responseType = 'json') => {
|
||||
try {
|
||||
const response = await axiosInstance({
|
||||
method,
|
||||
url,
|
||||
data,
|
||||
headers: {
|
||||
...customHeaders,
|
||||
},
|
||||
responseType,
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
request,
|
||||
get: (url, config = {}) => request('get', url, {}, config.headers, config.responseType),
|
||||
post: (url, data, config = {}) => request('post', url, data, config.headers, config.responseType),
|
||||
put: (url, data, config = {}) => request('put', url, data, config.headers, config.responseType),
|
||||
delete: (url, config = {}) => request('delete', url, {}, config.headers, config.responseType),
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,25 @@
|
||||
const DateFormatManager = {
|
||||
formatToLocale: (date) => {
|
||||
const formatter = new Intl.DateTimeFormat('en-CA', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
});
|
||||
const newDate = new Date(date)
|
||||
return formatter.format(newDate);
|
||||
},
|
||||
|
||||
preserveClientDate: (date) => {
|
||||
if (!date) return null
|
||||
const now = new Date()
|
||||
const localDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), now.getHours(), now.getMinutes(), now.getSeconds())
|
||||
return localDate.getFullYear() + '-' +
|
||||
String(localDate.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(localDate.getDate()).padStart(2, '0') + 'T' +
|
||||
String(localDate.getHours()).padStart(2, '0') + ':' +
|
||||
String(localDate.getMinutes()).padStart(2, '0') + ':' +
|
||||
String(localDate.getSeconds()).padStart(2, '0')
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
const NumberFormatManager = {
|
||||
formatToLocale: (number) => {
|
||||
const userLocale = navigator.language || 'en-US';
|
||||
|
||||
const formatter = new Intl.NumberFormat(userLocale, {
|
||||
style: 'decimal',
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
|
||||
if (typeof number !== 'number') {
|
||||
console.warn("Input must be a number, default value returned: 0");
|
||||
number = 0;
|
||||
}
|
||||
return formatter.format(number);
|
||||
},
|
||||
formatToLocaleNoDecimal: (number) => {
|
||||
const userLocale = navigator.language || 'en-US';
|
||||
|
||||
const formatter = new Intl.NumberFormat(userLocale, {
|
||||
style: 'decimal',
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
});
|
||||
|
||||
if (typeof number !== 'number') {
|
||||
console.warn("Input must be a number, default value returned: 0");
|
||||
number = 0;
|
||||
}
|
||||
return formatter.format(number);
|
||||
},
|
||||
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
const SecurityManager = {
|
||||
authorizePage: async (requiredRoles) => {
|
||||
const userRoles = StorageManager.getUserRoles();
|
||||
const isAuthorized = userRoles?.some(role => requiredRoles.includes(role));
|
||||
if (!isAuthorized) {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Unauthorized',
|
||||
text: 'You are being redirected...',
|
||||
timer: 2000,
|
||||
showConfirmButton: false
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = '/Accounts/Login';
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
validateToken: async () => {
|
||||
|
||||
try {
|
||||
const response = await AxiosManager.post('/Security/ValidateToken',
|
||||
{},
|
||||
);
|
||||
|
||||
if (response?.data?.code === 200) {
|
||||
return true;
|
||||
} else {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Token not valid',
|
||||
text: 'You are being redirected...',
|
||||
timer: 2000,
|
||||
showConfirmButton: false
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = '/Accounts/Login';
|
||||
}, 2000);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: error?.response?.data?.message || 'Error validating token',
|
||||
text: 'You are being redirected...',
|
||||
timer: 2000,
|
||||
showConfirmButton: false
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = '/Accounts/Login';
|
||||
}, 2000);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
const STORAGE_KEYS = {
|
||||
ACCESS_TOKEN: 'accessToken',
|
||||
REFRESH_TOKEN: 'refreshToken',
|
||||
IS_AUTHENTICATED: 'isAuthenticated',
|
||||
FIRST_NAME: 'firstName',
|
||||
LAST_NAME: 'lastName',
|
||||
EMAIL: 'email',
|
||||
USER_ID: 'userId',
|
||||
USER_ROLES: 'userRoles',
|
||||
MENU_NAVIGATION: 'menuNavigation',
|
||||
AVATAR: 'avatar',
|
||||
COMPANY: 'company'
|
||||
};
|
||||
|
||||
const StorageManager = {
|
||||
save: (key, value) => {
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
} catch (error) {
|
||||
console.error('Failed to save data to localStorage', error);
|
||||
}
|
||||
},
|
||||
|
||||
get: (key) => {
|
||||
try {
|
||||
const value = localStorage.getItem(key);
|
||||
return value ? JSON.parse(value) : null;
|
||||
} catch (error) {
|
||||
console.error('Failed to retrieve data from localStorage', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
try {
|
||||
localStorage.removeItem(key);
|
||||
} catch (error) {
|
||||
console.error('Failed to remove data from localStorage', error);
|
||||
}
|
||||
},
|
||||
|
||||
clearStorage: () => {
|
||||
try {
|
||||
localStorage.clear();
|
||||
} catch (error) {
|
||||
console.error('Failed to clear localStorage', error);
|
||||
}
|
||||
},
|
||||
|
||||
saveAccessToken: (token) => StorageManager.save(STORAGE_KEYS.ACCESS_TOKEN, token),
|
||||
getAccessToken: () => StorageManager.get(STORAGE_KEYS.ACCESS_TOKEN),
|
||||
removeAccessToken: () => StorageManager.remove(STORAGE_KEYS.ACCESS_TOKEN),
|
||||
|
||||
saveRefreshToken: (token) => StorageManager.save(STORAGE_KEYS.REFRESH_TOKEN, token),
|
||||
getRefreshToken: () => StorageManager.get(STORAGE_KEYS.REFRESH_TOKEN),
|
||||
removeRefreshToken: () => StorageManager.remove(STORAGE_KEYS.REFRESH_TOKEN),
|
||||
|
||||
saveIsAuthenticated: (status) => StorageManager.save(STORAGE_KEYS.IS_AUTHENTICATED, status),
|
||||
getIsAuthenticated: () => StorageManager.get(STORAGE_KEYS.IS_AUTHENTICATED),
|
||||
removeIsAuthenticated: () => StorageManager.remove(STORAGE_KEYS.IS_AUTHENTICATED),
|
||||
|
||||
saveFirstName: (firstName) => StorageManager.save(STORAGE_KEYS.FIRST_NAME, firstName),
|
||||
getFirstName: () => StorageManager.get(STORAGE_KEYS.FIRST_NAME),
|
||||
removeFirstName: () => StorageManager.remove(STORAGE_KEYS.FIRST_NAME),
|
||||
|
||||
saveLastName: (lastName) => StorageManager.save(STORAGE_KEYS.LAST_NAME, lastName),
|
||||
getLastName: () => StorageManager.get(STORAGE_KEYS.LAST_NAME),
|
||||
removeLastName: () => StorageManager.remove(STORAGE_KEYS.LAST_NAME),
|
||||
|
||||
saveEmail: (email) => StorageManager.save(STORAGE_KEYS.EMAIL, email),
|
||||
getEmail: () => StorageManager.get(STORAGE_KEYS.EMAIL),
|
||||
removeEmail: () => StorageManager.remove(STORAGE_KEYS.EMAIL),
|
||||
|
||||
saveUserId: (userId) => StorageManager.save(STORAGE_KEYS.USER_ID, userId),
|
||||
getUserId: () => StorageManager.get(STORAGE_KEYS.USER_ID),
|
||||
removeUserId: () => StorageManager.remove(STORAGE_KEYS.USER_ID),
|
||||
|
||||
saveUserRoles: (roles) => StorageManager.save(STORAGE_KEYS.USER_ROLES, roles),
|
||||
getUserRoles: () => StorageManager.get(STORAGE_KEYS.USER_ROLES),
|
||||
removeUserRoles: () => StorageManager.remove(STORAGE_KEYS.USER_ROLES),
|
||||
|
||||
saveMenuNavigation: (navigations) => StorageManager.save(STORAGE_KEYS.MENU_NAVIGATION, navigations),
|
||||
getMenuNavigation: () => StorageManager.get(STORAGE_KEYS.MENU_NAVIGATION),
|
||||
removeMenuNavigation: () => StorageManager.remove(STORAGE_KEYS.MENU_NAVIGATION),
|
||||
|
||||
saveAvatar: (avatar) => StorageManager.save(STORAGE_KEYS.AVATAR, avatar),
|
||||
getAvatar: () => StorageManager.get(STORAGE_KEYS.AVATAR),
|
||||
removeAvatar: () => StorageManager.remove(STORAGE_KEYS.AVATAR),
|
||||
|
||||
saveCompany: (company) => StorageManager.save(STORAGE_KEYS.COMPANY, company),
|
||||
getCompany: () => StorageManager.get(STORAGE_KEYS.COMPANY),
|
||||
removeCompany: () => StorageManager.remove(STORAGE_KEYS.COMPANY),
|
||||
|
||||
saveLoginResult: (data) => {
|
||||
StorageManager.saveAccessToken(data?.content?.data?.accessToken);
|
||||
StorageManager.saveRefreshToken(data?.content?.data?.refreshToken);
|
||||
StorageManager.saveFirstName(data?.content?.data?.firstName);
|
||||
StorageManager.saveLastName(data?.content?.data?.lastName);
|
||||
StorageManager.saveEmail(data?.content?.data?.email);
|
||||
StorageManager.saveUserId(data?.content?.data?.userId);
|
||||
StorageManager.saveUserRoles(data?.content?.data?.roles);
|
||||
StorageManager.saveMenuNavigation(data?.content?.data?.menuNavigation);
|
||||
StorageManager.saveIsAuthenticated(StorageManager.getUserId() != null);
|
||||
StorageManager.saveAvatar(data?.content?.data?.avatar);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user