David Headrick f5b1fe6397 Update mailing and target management features
- 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.
2025-04-07 12:13:44 -05:00

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;