- Added new methods for creating mailings and testing targets. - Updated configuration files for JWT settings and connection strings. - Introduced new DTOs for target column updates and test targets. - Enhanced MailingStatistic with a new SentDate property. - Created new components for handling cancelled mailings and target samples. - Refactored authentication in Login.tsx to use fetch API. - Updated various services and repositories to support new functionalities.
198 lines
7.1 KiB
TypeScript
198 lines
7.1 KiB
TypeScript
export class ApiError extends Error {
|
|
public status: number;
|
|
public data: unknown;
|
|
|
|
constructor(status: number, data: unknown) {
|
|
super(`HTTP error! status: ${status}`);
|
|
this.status = status;
|
|
this.data = data;
|
|
Object.setPrototypeOf(this, ApiError.prototype);
|
|
}
|
|
}
|
|
|
|
const utils = {
|
|
isTokenExpired: (token: string): boolean => {
|
|
const payload = JSON.parse(atob(token.split('.')[1])); // Decode JWT payload
|
|
return payload.exp * 1000 < Date.now(); // Compare expiration (in ms) to current time
|
|
},
|
|
getUserRoles: (token: string): string[] => {
|
|
try {
|
|
const payload = JSON.parse(atob(token.split('.')[1]));
|
|
return payload['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'] || // Standard role claim
|
|
payload.role || // Fallback for custom 'role' claim
|
|
[];
|
|
} catch {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
/*The following may not be needed any longer?
|
|
**TODO: WebMethod should be changed to mimic fetch command but add in auth headers?
|
|
fetch('/api/protected-endpoint', {
|
|
headers: {
|
|
'Authorization': `Bearer ${localStorage.getItem('accessToken')}`
|
|
}
|
|
});
|
|
|
|
*/
|
|
getCookie: (name: string): string | null => {
|
|
const value = `; ${document.cookie}`;
|
|
const parts = value.split(`; ${name}=`);
|
|
if (parts.length === 2) return parts.pop()?.split(';').shift() ?? null;
|
|
return null;
|
|
},
|
|
getParameterByName: (name: string): string | null => {
|
|
const regex = new RegExp(`[?&]${name}=([^&#]*)`);
|
|
const results = regex.exec(window.location.search);
|
|
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
|
|
},
|
|
//addAuthHeaders: (headers: Record<string, string> = {}): Record<string, string> => {
|
|
// const authToken = utils.getCookie('Auth-Token');
|
|
// if (authToken) {
|
|
// headers['Auth-Token'] = authToken;
|
|
// }
|
|
|
|
// const impersonateGuid = utils.getParameterByName("impersonateid") || sessionStorage.getItem('Auth-Impersonate-Guid');
|
|
// if (impersonateGuid) {
|
|
// sessionStorage.setItem('Auth-Impersonate-Guid', impersonateGuid);
|
|
// headers['Auth-Impersonate-Guid'] = impersonateGuid;
|
|
// }
|
|
|
|
// const franchiseCode = sessionStorage.getItem('franchiseCode');
|
|
// if (franchiseCode) {
|
|
// headers['Auth-Current-Franchise'] = franchiseCode;
|
|
// }
|
|
|
|
// return headers;
|
|
//},
|
|
//webMethod: async <T = unknown>({
|
|
// httpMethod = 'POST',
|
|
// baseMethodPath = 'api/',
|
|
// methodPage = '',
|
|
// methodName = '',
|
|
// parameters = {} as Record<string, unknown>,
|
|
// contentType = 'application/json;',
|
|
// timeout = 300000,
|
|
// success = (_data: T) => { },
|
|
// error = (_err: unknown) => { },
|
|
//}: {
|
|
// httpMethod?: string;
|
|
// baseMethodPath?: string;
|
|
// methodPage?: string;
|
|
// methodName?: string;
|
|
// contentType?: string;
|
|
// parameters?: Record<string, unknown>;
|
|
// timeout?: number;
|
|
// success?: (_data: T) => void;
|
|
// error?: (_err: unknown) => void;
|
|
//}): Promise<void> => {
|
|
// try {
|
|
// const baseUrl = window.API_BASE_URL || '';
|
|
// const url = `${baseUrl.replace(/\/$/, '')}/${baseMethodPath.replace(/\/$/, '')}/${methodPage}${methodName ? '/' + methodName : ''}`;
|
|
|
|
// const headers = utils.addAuthHeaders({
|
|
// 'Content-Type': contentType,
|
|
// });
|
|
|
|
// const controller = new AbortController();
|
|
// //const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
// setTimeout(() => controller.abort(), timeout);
|
|
|
|
// const response = await fetch(url, {
|
|
// method: httpMethod,
|
|
// headers,
|
|
// body: (httpMethod.toUpperCase() == "GET" ? null : JSON.stringify(parameters)),
|
|
// signal: controller.signal,
|
|
// });
|
|
|
|
// if (!response.ok) {
|
|
// let data = null;
|
|
// try {
|
|
// data = await response.json();
|
|
// } catch {
|
|
// // Intentionally empty, if not json ignore
|
|
// }
|
|
// throw new ApiError(response.status, data);
|
|
// }
|
|
|
|
// const authToken = response.headers.get('Auth-Token');
|
|
// const loggedIn = response.headers.get('usahl_logged_in') === 'true';
|
|
|
|
// const expires = loggedIn ? 365 : 14;
|
|
// document.cookie = `Auth-Token=${authToken};path=/;max-age=${expires * 24 * 60 * 60}`;
|
|
// document.cookie = `usahl_logged_in=${loggedIn};path=/;max-age=${expires * 24 * 60 * 60}`;
|
|
|
|
// const data = await response.json();
|
|
// success(data);
|
|
// } catch (err) {
|
|
// if ((err as Error).name === 'AbortError') {
|
|
// console.error('Request timed out');
|
|
// }
|
|
// error(err);
|
|
// }
|
|
//},
|
|
getBoolean: (variable: any): boolean => {
|
|
if (variable != null) {
|
|
switch (typeof variable) {
|
|
case 'boolean':
|
|
return variable;
|
|
case 'number':
|
|
return variable !== 0;
|
|
case 'string':
|
|
return /^(true|yes)$/i.test(variable) || variable.length > 0;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
//isLoggedIn: (): boolean => {
|
|
// return utils.getBoolean(utils.getCookie('usahl_logged_in'));
|
|
//},
|
|
//sessionStorage: (key: string, value?: any): any => {
|
|
// if (value === undefined) {
|
|
// let val = window.sessionStorage.getItem(key);
|
|
// if (val && val.startsWith('usahl_json:')) {
|
|
// val = val.substring(11);
|
|
// return JSON.parse(val);
|
|
// }
|
|
// return val;
|
|
// } else {
|
|
// const val = typeof value === 'object' ? `usahl_json:${JSON.stringify(value)}` : value;
|
|
// window.sessionStorage.setItem(key, val);
|
|
// }
|
|
//},
|
|
//sessionStorageClear: (): void => {
|
|
// window.sessionStorage.clear();
|
|
//},
|
|
//sessionStorageRemove: (key: string): void => {
|
|
// window.sessionStorage.removeItem(key);
|
|
//},
|
|
//localStorage: (key: string, value?: any): any => {
|
|
// if (value === undefined) {
|
|
// let val = window.localStorage.getItem(key);
|
|
// if (val && val.startsWith('usahl_json:')) {
|
|
// val = val.substring(11);
|
|
// return JSON.parse(val);
|
|
// }
|
|
// return val;
|
|
// } else {
|
|
// const val = typeof value === 'object' ? `usahl_json:${JSON.stringify(value)}` : value;
|
|
// window.localStorage.setItem(key, val);
|
|
// }
|
|
//},
|
|
//localStorageClear: (): void => {
|
|
// window.localStorage.clear();
|
|
//},
|
|
//localStorageRemove: (key: string): void => {
|
|
// window.localStorage.removeItem(key);
|
|
//},
|
|
};
|
|
|
|
declare global {
|
|
interface Window {
|
|
utils: object
|
|
}
|
|
}
|
|
window.utils = utils;
|
|
|
|
export default utils;
|