Files
warmbly/admin/src/hooks/useInstanceHealth.ts
T
Matthew Meszaros 734cb5fe08 feat: make self-hosted onboarding survivable by fixing invite_only, which could not onboard anyone (the accept route is JWT-only, so redeeming the invitation that would create your account required already having one, making the self-host default silently identical to fully closed), threading the invitation token through registration so an invited person lands in the inviting organization instead of a stray workspace, gating SSO just-in-time provisioning behind DISABLE_REGISTRATION (it bypassed the gate entirely, so an instance set to true was still open to anyone the IdP would assert) with SSO_AUTO_PROVISION as the opt-out, correcting the OIDC redirect URL that pointed at /api/v1 against a route at /v1 and 404'd every SSO login, scoping the first-launch exemption so it no longer overrides an explicit lockdown, preserving the remaining TTL when restoring a losing setup token so a public endpoint cannot hold the claim window open forever, replacing a generic 403 with typed registration_invite_only, registration_closed, invitation_invalid, setup_token_invalid and setup_already_complete codes that name the next step, logging why no claim link was issued on an already-claimed instance instead of staying silent, adding a warmblyctl operator CLI (status with health checks and a non-zero exit, reissuable setup-link, user create/list/reset-password/grant-admin/revoke-admin/disable-2fa, hash-password) so a locked-out operator no longer needs hand-written psql, adding read-only instance configuration over 104 environment variables with structural secret redaction and fingerprints, 35 health checks, a database-backed settings tier for the three keys no environment variable owns, hiding the signup form when the config already says invite_only rather than failing the whole form with a toast, and documenting first run, accounts and access, configuration, instance health and troubleshooting alongside the root .env.example the README told operators to write but never shipped (#114)
2026-08-16 05:58:11 +02:00

36 lines
1.2 KiB
TypeScript

import { useQuery } from "@tanstack/react-query";
import {
getInstanceHealth,
type CheckSeverity,
type InstanceHealthResult,
} from "@/lib/api/client/admin/instance";
export const INSTANCE_HEALTH_KEY = ["admin", "instance", "health"] as const;
// One cache entry feeds the sidebar badge, the Overview panel and the
// Setup and health page, so they can never disagree.
export function useInstanceHealth(options?: { enabled?: boolean }) {
return useQuery({
queryKey: INSTANCE_HEALTH_KEY,
queryFn: getInstanceHealth,
refetchInterval: 60_000,
retry: false,
enabled: options?.enabled ?? true,
});
}
// The endpoint returns only non-ok checks, so the list length is the count.
export function findingCount(data: InstanceHealthResult | undefined): number {
return data?.checks?.length ?? 0;
}
export function worstSeverity(
data: InstanceHealthResult | undefined,
): CheckSeverity | null {
const checks = data?.checks ?? [];
if (checks.some((c) => c.severity === "error")) return "error";
if (checks.some((c) => c.severity === "warning")) return "warning";
if (checks.length > 0) return "info";
return null;
}