Spaces:
Running on Zero
Running on Zero
| import { config } from '$lib/stores/settings.svelte'; | |
| import { CORS_PROXY_HEADER_PREFIX, REDACTED_HEADERS } from '$lib/constants'; | |
| import { redactValue } from './redact'; | |
| /** | |
| * Get authorization headers for API requests | |
| * Includes Bearer token if API key is configured | |
| */ | |
| export function getAuthHeaders(): Record<string, string> { | |
| const currentConfig = config(); | |
| const apiKey = currentConfig.apiKey?.toString().trim(); | |
| return apiKey ? { Authorization: `Bearer ${apiKey}` } : {}; | |
| } | |
| /** | |
| * Get standard JSON headers with optional authorization | |
| */ | |
| export function getJsonHeaders(): Record<string, string> { | |
| return { | |
| 'Content-Type': 'application/json', | |
| ...getAuthHeaders() | |
| }; | |
| } | |
| /** | |
| * Sanitize HTTP headers by redacting sensitive values. | |
| * Known sensitive headers (from REDACTED_HEADERS) and any extra headers | |
| * specified by the caller are fully redacted. Headers listed in | |
| * `partialRedactHeaders` are partially redacted, showing only the | |
| * specified number of trailing characters. | |
| * | |
| * @param headers - Headers to sanitize | |
| * @param extraRedactedHeaders - Additional header names to fully redact | |
| * @param partialRedactHeaders - Map of header name -> number of trailing chars to keep visible | |
| * @returns Object with header names as keys and (possibly redacted) values | |
| */ | |
| export function sanitizeHeaders( | |
| headers?: HeadersInit, | |
| extraRedactedHeaders?: Iterable<string>, | |
| partialRedactHeaders?: Map<string, number> | |
| ): Record<string, string> { | |
| if (!headers) { | |
| return {}; | |
| } | |
| const normalized = new Headers(headers); | |
| const sanitized: Record<string, string> = {}; | |
| const redactedHeaders = new Set( | |
| Array.from(extraRedactedHeaders ?? [], (header) => header.toLowerCase()) | |
| ); | |
| for (const [key, value] of normalized.entries()) { | |
| const normalizedKey = key.toLowerCase(); | |
| const unproxiedKey = normalizedKey.startsWith(CORS_PROXY_HEADER_PREFIX) | |
| ? normalizedKey.slice(CORS_PROXY_HEADER_PREFIX.length) | |
| : normalizedKey; | |
| const partialChars = | |
| partialRedactHeaders?.get(normalizedKey) ?? partialRedactHeaders?.get(unproxiedKey); | |
| if (partialChars !== undefined) { | |
| sanitized[key] = redactValue(value, partialChars); | |
| } else if ( | |
| REDACTED_HEADERS.has(normalizedKey) || | |
| REDACTED_HEADERS.has(unproxiedKey) || | |
| redactedHeaders.has(normalizedKey) || | |
| redactedHeaders.has(unproxiedKey) | |
| ) { | |
| sanitized[key] = redactValue(value); | |
| } else { | |
| sanitized[key] = value; | |
| } | |
| } | |
| return sanitized; | |
| } | |