fixing rolodex and search

This commit is contained in:
HotSwapp
2025-08-11 21:58:25 -05:00
parent 278eb7c5d4
commit c76b68d009
25 changed files with 1651 additions and 915 deletions

View File

@@ -9,6 +9,8 @@
window.app = window.app || {};
const CORRELATION_HEADER = 'X-Correlation-ID';
let warnedTokenStorage = false;
let warnedDeprecatedPatch = false;
function generateCorrelationId() {
try {
@@ -34,6 +36,8 @@
async function wrappedFetch(resource, options = {}) {
const url = typeof resource === 'string' ? resource : (resource && resource.url) || '';
const headers = normalizeHeaders(options.headers);
const method = (options.method || 'GET').toUpperCase();
const body = options.body;
// Inject correlation id if not present
let outgoingCid = headers.get(CORRELATION_HEADER);
@@ -48,10 +52,30 @@
if (storedToken && !headers.has('Authorization')) {
headers.set('Authorization', `Bearer ${storedToken}`);
}
// One-time security note if we detect token in localStorage
if (!warnedTokenStorage && typeof localStorage !== 'undefined' && localStorage.getItem('auth_token')) {
warnedTokenStorage = true;
// eslint-disable-next-line no-console
console.warn('Security note: auth tokens are read from localStorage. If this app is exposed to the internet, migrate to HttpOnly cookies.');
}
} catch (_) {
// Ignore storage access errors (e.g., privacy mode)
}
// Inject Content-Type: application/json for JSON string bodies when missing
try {
const hasContentType = headers.has('Content-Type');
const methodAllowsBody = method !== 'GET' && method !== 'HEAD';
if (methodAllowsBody && body != null && !hasContentType) {
// Only auto-set for stringified JSON bodies to avoid interfering with FormData or other types
if (typeof body === 'string') {
headers.set('Content-Type', 'application/json');
}
}
} catch (_) {
// Best-effort only; ignore header normalization errors
}
const requestInit = { ...options, headers };
const response = await originalFetch(resource, requestInit);
@@ -132,10 +156,18 @@
parseErrorEnvelope,
toError,
formatAlert,
wrappedFetch,
};
// Install wrapper
window.fetch = wrappedFetch;
// Install wrapper (deprecated). Keep for backward compatibility, but nudge callers to use window.http.wrappedFetch
window.fetch = async function(...args) {
if (!warnedDeprecatedPatch) {
warnedDeprecatedPatch = true;
// eslint-disable-next-line no-console
console.warn('Deprecated: global fetch() is wrapped. Prefer window.http.wrappedFetch for clarity and testability.');
}
return wrappedFetch(...args);
};
})();