fix: improve onboarding checks and errors
This commit is contained in:
parent
c7d2b81ad8
commit
b017775bdb
@ -255,6 +255,53 @@ def register(app) -> None:
|
|||||||
jellyfin_sync_status = "unknown"
|
jellyfin_sync_status = "unknown"
|
||||||
jellyfin_sync_detail = "unavailable"
|
jellyfin_sync_detail = "unavailable"
|
||||||
|
|
||||||
|
if (
|
||||||
|
username
|
||||||
|
and not vaultwarden_master_set_at
|
||||||
|
and vaultwarden_status in {"", "invited", "needs provisioning"}
|
||||||
|
and settings.PORTAL_DATABASE_URL
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
with connect() as conn:
|
||||||
|
row = conn.execute(
|
||||||
|
"""
|
||||||
|
SELECT request_code
|
||||||
|
FROM access_requests
|
||||||
|
WHERE username = %s AND status IN ('awaiting_onboarding', 'ready')
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
(username,),
|
||||||
|
).fetchone()
|
||||||
|
if not row:
|
||||||
|
row = conn.execute(
|
||||||
|
"""
|
||||||
|
SELECT request_code
|
||||||
|
FROM access_requests
|
||||||
|
WHERE username = %s
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
(username,),
|
||||||
|
).fetchone()
|
||||||
|
if row and isinstance(row, dict):
|
||||||
|
request_code = str(row.get("request_code") or "").strip()
|
||||||
|
if request_code:
|
||||||
|
step = conn.execute(
|
||||||
|
"""
|
||||||
|
SELECT 1
|
||||||
|
FROM access_request_onboarding_steps
|
||||||
|
WHERE request_code = %s AND step = %s
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
(request_code, "vaultwarden_master_password"),
|
||||||
|
).fetchone()
|
||||||
|
if step:
|
||||||
|
vaultwarden_master_set_at = "confirmed"
|
||||||
|
vaultwarden_status = "ready"
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
mailu_username = mailu_email or (f"{username}@{settings.MAILU_DOMAIN}" if username else "")
|
mailu_username = mailu_email or (f"{username}@{settings.MAILU_DOMAIN}" if username else "")
|
||||||
firefly_username = mailu_username
|
firefly_username = mailu_username
|
||||||
vaultwarden_username = vaultwarden_email or mailu_username
|
vaultwarden_username = vaultwarden_email or mailu_username
|
||||||
@ -460,6 +507,16 @@ def register(app) -> None:
|
|||||||
|
|
||||||
return jsonify({"status": "ok", "password": password})
|
return jsonify({"status": "ok", "password": password})
|
||||||
|
|
||||||
|
@app.route("/api/account/wger/rotation/check", methods=["POST"])
|
||||||
|
@require_auth
|
||||||
|
def account_wger_rotation_check() -> Any:
|
||||||
|
ok, resp = require_account_access()
|
||||||
|
if not ok:
|
||||||
|
return resp
|
||||||
|
if ariadne_client.enabled():
|
||||||
|
return ariadne_client.proxy("POST", "/api/account/wger/rotation/check")
|
||||||
|
return jsonify({"error": "server not configured"}), 503
|
||||||
|
|
||||||
@app.route("/api/account/firefly/reset", methods=["POST"])
|
@app.route("/api/account/firefly/reset", methods=["POST"])
|
||||||
@require_auth
|
@require_auth
|
||||||
def account_firefly_reset() -> Any:
|
def account_firefly_reset() -> Any:
|
||||||
@ -513,6 +570,16 @@ def register(app) -> None:
|
|||||||
|
|
||||||
return jsonify({"status": "ok", "password": password})
|
return jsonify({"status": "ok", "password": password})
|
||||||
|
|
||||||
|
@app.route("/api/account/firefly/rotation/check", methods=["POST"])
|
||||||
|
@require_auth
|
||||||
|
def account_firefly_rotation_check() -> Any:
|
||||||
|
ok, resp = require_account_access()
|
||||||
|
if not ok:
|
||||||
|
return resp
|
||||||
|
if ariadne_client.enabled():
|
||||||
|
return ariadne_client.proxy("POST", "/api/account/firefly/rotation/check")
|
||||||
|
return jsonify({"error": "server not configured"}), 503
|
||||||
|
|
||||||
@app.route("/api/account/nextcloud/mail/sync", methods=["POST"])
|
@app.route("/api/account/nextcloud/mail/sync", methods=["POST"])
|
||||||
@require_auth
|
@require_auth
|
||||||
def account_nextcloud_mail_sync() -> Any:
|
def account_nextcloud_mail_sync() -> Any:
|
||||||
|
|||||||
@ -675,6 +675,16 @@ function formatName(req) {
|
|||||||
return parts.length ? parts.join(" ") : "unknown";
|
return parts.length ? parts.join(" ") : "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatActionError(err, fallback) {
|
||||||
|
const message = err?.message || "";
|
||||||
|
if (!message) return fallback;
|
||||||
|
const normalized = message.toLowerCase();
|
||||||
|
if (normalized.includes("ariadne unavailable") || normalized.includes("status 502") || normalized.includes("status 503")) {
|
||||||
|
return "Ariadne is busy. Please try again in a moment.";
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
function toggleFlag(username, flag, event) {
|
function toggleFlag(username, flag, event) {
|
||||||
const checked = Boolean(event?.target?.checked);
|
const checked = Boolean(event?.target?.checked);
|
||||||
const selected = Array.isArray(admin.selectedFlags[username]) ? [...admin.selectedFlags[username]] : [];
|
const selected = Array.isArray(admin.selectedFlags[username]) ? [...admin.selectedFlags[username]] : [];
|
||||||
@ -709,7 +719,7 @@ async function rotateMailu() {
|
|||||||
}
|
}
|
||||||
await refreshOverview();
|
await refreshOverview();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
mailu.error = err.message || "Rotation failed";
|
mailu.error = formatActionError(err, "Rotation failed");
|
||||||
} finally {
|
} finally {
|
||||||
mailu.rotating = false;
|
mailu.rotating = false;
|
||||||
}
|
}
|
||||||
@ -728,7 +738,7 @@ async function resetWger() {
|
|||||||
}
|
}
|
||||||
await refreshOverview();
|
await refreshOverview();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
wger.error = err.message || "Reset failed";
|
wger.error = formatActionError(err, "Reset failed");
|
||||||
} finally {
|
} finally {
|
||||||
wger.resetting = false;
|
wger.resetting = false;
|
||||||
}
|
}
|
||||||
@ -747,7 +757,7 @@ async function resetFirefly() {
|
|||||||
}
|
}
|
||||||
await refreshOverview();
|
await refreshOverview();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
firefly.error = err.message || "Reset failed";
|
firefly.error = formatActionError(err, "Reset failed");
|
||||||
} finally {
|
} finally {
|
||||||
firefly.resetting = false;
|
firefly.resetting = false;
|
||||||
}
|
}
|
||||||
@ -766,7 +776,7 @@ async function syncNextcloudMail() {
|
|||||||
if (!resp.ok) throw new Error(data.error || `status ${resp.status}`);
|
if (!resp.ok) throw new Error(data.error || `status ${resp.status}`);
|
||||||
await refreshOverview();
|
await refreshOverview();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
nextcloudMail.error = err.message || "Sync failed";
|
nextcloudMail.error = formatActionError(err, "Sync failed");
|
||||||
} finally {
|
} finally {
|
||||||
nextcloudMail.syncing = false;
|
nextcloudMail.syncing = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -945,6 +945,12 @@ async function confirmStep(step) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (step.action === "auto") {
|
if (step.action === "auto") {
|
||||||
|
if (step.id === "firefly_password_rotated") {
|
||||||
|
await runRotationCheck("firefly");
|
||||||
|
}
|
||||||
|
if (step.id === "wger_password_rotated") {
|
||||||
|
await runRotationCheck("wger");
|
||||||
|
}
|
||||||
await check();
|
await check();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -956,11 +962,29 @@ async function confirmStep(step) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await setStepCompletion(step.id, true);
|
await setStepCompletion(step.id, true);
|
||||||
|
} catch (err) {
|
||||||
|
error.value = err?.message || "Failed to confirm step";
|
||||||
} finally {
|
} finally {
|
||||||
confirmingStepId.value = "";
|
confirmingStepId.value = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function runRotationCheck(service) {
|
||||||
|
if (!auth.authenticated) {
|
||||||
|
throw new Error("Log in to update onboarding steps.");
|
||||||
|
}
|
||||||
|
const endpoint =
|
||||||
|
service === "firefly"
|
||||||
|
? "/api/account/firefly/rotation/check"
|
||||||
|
: "/api/account/wger/rotation/check";
|
||||||
|
const resp = await authFetch(endpoint, { method: "POST" });
|
||||||
|
const data = await resp.json().catch(() => ({}));
|
||||||
|
if (!resp.ok) {
|
||||||
|
throw new Error(data.error || resp.statusText || `status ${resp.status}`);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
async function requestKeycloakPasswordRotation() {
|
async function requestKeycloakPasswordRotation() {
|
||||||
if (!requestCode.value.trim()) {
|
if (!requestCode.value.trim()) {
|
||||||
error.value = "Request code is missing.";
|
error.value = "Request code is missing.";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user