mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(web): skip empty Authorization header for forward-auth proxy compatibility
Centralize duplicated getToken() + Bearer header logic into a single formatHeaders() helper in lib/api.ts. When no token exists, the Authorization header is omitted entirely instead of sending an empty Bearer token, which breaks forward-auth proxies like Authelia behind Caddy. Changes: - Add formatHeaders() with try-catch around localStorage access - Replace 20+ duplicated getToken() definitions across tool components - Migrate all call sites including file-details, settings, change-password - Update tests to verify header omission on empty token Based on the fix proposed by @jules2689 in #6, with improvements: file placement (lib/api.ts vs components), localStorage error handling, simplified truthiness check, and complete call-site coverage. Co-Authored-By: Julian Nadeau <julian@jnadeau.ca>
This commit is contained in:
co-authored by
Julian Nadeau
parent
f21579c7a3
commit
d0c69d6a46
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { formatHeaders } from "@/lib/api";
|
||||
|
||||
interface AuthState {
|
||||
loading: boolean;
|
||||
@@ -45,7 +46,7 @@ export function useAuth(): AuthState {
|
||||
}
|
||||
|
||||
const sessionRes = await fetch("/api/auth/session", {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
headers: formatHeaders(),
|
||||
});
|
||||
|
||||
if (sessionRes.ok) {
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { PYTHON_SIDECAR_TOOLS } from "@stirling-image/shared";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { formatHeaders } from "@/lib/api";
|
||||
import { generateId } from "@/lib/utils";
|
||||
import { useFileStore } from "@/stores/file-store";
|
||||
|
||||
function getToken(): string {
|
||||
return localStorage.getItem("stirling-token") || "";
|
||||
}
|
||||
|
||||
interface ProcessResult {
|
||||
jobId: string;
|
||||
downloadUrl: string;
|
||||
@@ -222,10 +219,9 @@ export function useToolProcessor(toolId: string) {
|
||||
};
|
||||
|
||||
xhr.open("POST", `/api/v1/tools/${toolId}`);
|
||||
const token = getToken();
|
||||
if (token) {
|
||||
xhr.setRequestHeader("Authorization", `Bearer ${token}`);
|
||||
}
|
||||
formatHeaders().forEach((value, key) => {
|
||||
xhr.setRequestHeader(key, value);
|
||||
});
|
||||
xhr.send(formData);
|
||||
},
|
||||
[toolId, isAiTool, setProcessing, setError, setProcessedUrl, setSizes, setJobId],
|
||||
@@ -292,10 +288,9 @@ export function useToolProcessor(toolId: string) {
|
||||
formData.append("clientJobId", clientJobId);
|
||||
|
||||
try {
|
||||
const token = getToken();
|
||||
const response = await fetch(`/api/v1/tools/${toolId}/batch`, {
|
||||
method: "POST",
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
||||
headers: formatHeaders(),
|
||||
body: formData,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user