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:
@@ -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
@@ -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]:
|
||||
|
||||
Reference in New Issue
Block a user