fix: remove auth middleware — single-user pedal doesn't need it
CI / test (push) Has been cancelled

Auth was blocking all POST/PUT operations with 401.
Disabled per user request. PIN generation kept (harmless).
Frontend reverted to no-auth API helpers.
This commit is contained in:
2026-06-17 23:06:46 -04:00
parent 95029c6c8c
commit aa0bcf35fe
2 changed files with 8 additions and 73 deletions
+5 -11
View File
@@ -37,12 +37,6 @@ function _ch(url) {
}
// ── API helpers ────────────────────────────────────────────────
let _authPin = '';
function _authHeaders() {
return _authPin ? { 'X-Pedal-Auth': _authPin } : {};
}
async function apiGet(path) {
const r = await fetch(`${API}${_ch(path)}`);
if (!r.ok) throw new Error(`${path} => ${r.status}`);
@@ -51,7 +45,7 @@ async function apiGet(path) {
async function apiPost(path, data) {
const r = await fetch(`${API}${_ch(path)}`, {
method: 'POST', headers: { 'Content-Type': 'application/json', ..._authHeaders() },
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: data != null ? JSON.stringify(data) : undefined,
});
if (!r.ok) throw new Error(`${path} => ${r.status}`);
@@ -60,7 +54,7 @@ async function apiPost(path, data) {
async function apiPut(path, data) {
const r = await fetch(`${API}${_ch(path)}`, {
method: 'PUT', headers: { 'Content-Type': 'application/json', ..._authHeaders() },
method: 'PUT', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!r.ok) throw new Error(`${path} => ${r.status}`);
@@ -68,7 +62,7 @@ async function apiPut(path, data) {
}
async function apiDelete(path) {
const r = await fetch(`${API}${_ch(path)}`, { method: 'DELETE', headers: _authHeaders() });
const r = await fetch(`${API}${_ch(path)}`, { method: 'DELETE' });
if (!r.ok) throw new Error(`${path} => ${r.status}`);
return r.json();
}
@@ -76,7 +70,7 @@ async function apiDelete(path) {
async function apiUpload(path, file) {
const fd = new FormData();
fd.append('file', file);
const r = await fetch(`${API}${_ch(path)}`, { method: 'POST', body: fd, headers: _authHeaders() });
const r = await fetch(`${API}${_ch(path)}`, { method: 'POST', body: fd });
if (!r.ok) throw new Error(`${path} => ${r.status}`);
return r.json();
}
@@ -90,7 +84,7 @@ function usePedalState() {
useEffect(() => {
// Fetch initial state
apiGet('/api/state').then(s => { setState(s); setConnected(true); _authPin = s.auth_pin || ''; }).catch(() => { setConnected(false); });
apiGet('/api/state').then(s => { setState(s); setConnected(true); }).catch(() => { setConnected(false); });
// WebSocket for real-time updates
let reconnectTimer;
+3 -62
View File
@@ -444,67 +444,9 @@ class WebServer:
request.method, request.url.path, exc, exc_info=True)
return JSONResponse(status_code=500, content={"detail": "Internal server error"})
# ── Auth middleware ──────────────────────────────────────────────
# All /api/ endpoints require X-Pedal-Auth: <pin> header, EXCEPT
# read-only GET endpoints that the UI needs on first load.
# The PIN is set at first boot in config.yaml under web.auth_pin.
AUTH_SAFE_PREFIXES = (
# Read-only endpoints the UI needs for basic operation
# (none of these expose WiFi/BT credentials or settings)
"/api/state",
"/api/presets",
"/api/snapshots",
"/api/models",
"/api/irs",
"/api/audio/profile",
"/api/audio/profiles",
"/api/audio/devices",
"/api/block-params",
"/api/levels",
"/api/tuner/pitch",
"/api/channel-output",
"/api/channel-mode",
"/api/routing",
"/api/system",
"/api/network",
"/api/backing-source",
"/api/midi/mappings",
"/api/nam/engine",
"/api/tonedownload/status",
"/api/models/tonedownload/search",
"/api/irs/tonedownload/search",
"/api/fx/params",
"/api/bluetooth/midi-status",
"/api/bluetooth/midi-devices",
)
@app.middleware("http")
async def auth_middleware(request: Request, call_next):
path = request.url.path
# Static files and the main UI are always public
if path == "/" or path.startswith("/static/"):
return await call_next(request)
# Legacy redirect routes are public
if path in ("/presets", "/models", "/irs", "/settings"):
return await call_next(request)
# Enforce auth on all /api/ endpoints except safe GET prefixes
if path.startswith("/api/"):
# Safe GET endpoints — read-only, no sensitive data
if request.method == "GET" and any(path.startswith(p) for p in AUTH_SAFE_PREFIXES):
return await call_next(request)
pin = self._get_auth_pin()
if pin is not None:
auth = request.headers.get("X-Pedal-Auth", "")
if auth != pin:
logger.warning("Unauthorized request to %s %s", request.method, path)
return JSONResponse(status_code=401, content={"detail": "Unauthorized"})
return await call_next(request)
# ── Auth — disabled per user request (single-user stage pedal) ──
# Auth middleware removed. PIN generation still runs (harmless).
# Remove the X-Pedal-Auth wiring from frontend-react/src/App.jsx too.
# Mount static files
app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static")
@@ -2910,7 +2852,6 @@ iface eth0 inet static
"bluetooth": self._gather_bt_state(),
"current_snapshot": getattr(pm, '_current_snapshot', 0) if pm else 0,
"needs_reboot": self._needs_reboot,
"auth_pin": self._get_auth_pin() or "",
}
def _gather_state(self, channel: Optional[str] = None) -> dict[str, Any]: