v0.8.0: dep prune, memtest introspection fix, concurrent uploads, x-api-key
Dependency cleanup (ponytail audit): - Drop 14 unused dependency declarations across 7 crates; quick-xml and x509-parser leave the tree entirely (SAML cert/XML work is handled by bergshamra + roxmltree). Fixes: - introspect: drop the over-broad "microsoft" UTF-16 bulk-scan marker that mislabeled Secure-Boot-signed non-Windows bootables (memtest86, signed BSDs, firmware tools) as Windows — the string lives in their MS-signed EFI loader's FAT long-filename entries. INTROSPECT_REV 3 -> 4 re-probes existing local ISOs on startup so the bogus label clears on upgrade. - upload: begin_upload now reclaims an abandoned <id>.partial instead of rejecting the re-upload with "already uploading". Robust against browser refresh, tab close, and dropped connections (the chunked protocol can't resume a dead session anyway). Features: - Storage upload: multi-file + concurrent. Each dropped/selected .iso gets its own progress row and uploads independently; a single page-leave guard plus a pagehide keepalive-abort replace the old shared singletons. - Operator API key (x-api-key): a persisted key authenticates /api/* exactly like an operator session, for Postman/scripts. New core ApiKeyStore (generated on first run, regenerable), accepted in require_auth alongside the session cookie, surfaced in Settings -> Advanced with copy + regenerate and a usage reference. GET /api/api-key + POST /api/api-key/regenerate. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
27703c437a
commit
1c262a6d61
@@ -147,6 +147,14 @@ pub fn build_router(state: AppState) -> Router {
|
||||
.route("/api/logout", post(auth_api::api_logout))
|
||||
.route("/api/me", get(auth_api::api_me))
|
||||
.route("/api/me/credentials", put(auth_api::api_update_credentials))
|
||||
// v0.8.0: operator API key surface (read current + regenerate).
|
||||
// Gated by require_auth like the rest of /api/*; a logged-in
|
||||
// operator or an x-api-key holder can read/rotate it.
|
||||
.route("/api/api-key", get(auth_api::api_api_key_get))
|
||||
.route(
|
||||
"/api/api-key/regenerate",
|
||||
post(auth_api::api_api_key_regenerate),
|
||||
)
|
||||
// SAML SSO configuration (FleetDM-shaped). Gated behind auth — the
|
||||
// operator pastes their IdP metadata, Entity ID, and toggles here.
|
||||
.route("/api/sso", get(api_sso_get).put(api_sso_put))
|
||||
@@ -1944,6 +1952,10 @@ async fn api_docs() -> Json<serde_json::Value> {
|
||||
"summary": "Auth status — { setup_required, authenticated, user }. Always 200."},
|
||||
{"method": "PUT", "path": "/api/me/credentials",
|
||||
"summary": "Rotate the admin's credentials. Body: { current_password, new_username?, new_password? }. Revokes all other sessions on success."},
|
||||
{"method": "GET", "path": "/api/api-key",
|
||||
"summary": "Return the operator API key + the header to send it in (x-api-key). That header authenticates API calls without a browser session — full operator access."},
|
||||
{"method": "POST", "path": "/api/api-key/regenerate",
|
||||
"summary": "Mint a fresh API key, invalidating the previous one immediately."},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user