Compare commits

..
Author SHA1 Message Date
ajnart f7b594c8ca fix(backup): prompt re-login after restore 2026-09-06 10:21:28 +02:00
6 changed files with 41 additions and 8 deletions

No files matched your search

+3 -2
View File
@@ -30,8 +30,9 @@ needed to restore encrypted integration credentials.
Select a Homarr backup ZIP. The browser previews entity counts, board names, and required database migrations before
the archive is uploaded.
Restoring replaces the current SQLite database and cannot be undone. After a successful restore, the Next.js process
restarts and the page reloads when Homarr is ready.
Restoring replaces the current SQLite database and cannot be undone. It also invalidates the current database session.
After a successful management restore, Homarr waits for the restarted server and sends the administrator to sign in
again. The first-run onboarding restore keeps its existing board destination.
A backup can be restored on another Homarr instance. When its `SECRET_ENCRYPTION_KEY` differs, Homarr re-encrypts stored
integration secrets for the target instance. Version metadata is used to apply compatible migrations.
@@ -204,8 +204,12 @@ export const DatabaseRestoreFlow = ({ variant = "card", onRestoreComplete }: Dat
}
onRestoreComplete?.();
const destination =
variant === "standalone" && homeBoardName ? `/boards/${encodeURIComponent(homeBoardName)}` : null;
let destination: string | null = null;
if (variant === "standalone" && homeBoardName) {
destination = `/boards/${encodeURIComponent(homeBoardName)}`;
} else if (variant === "card") {
destination = "/auth/login";
}
startReadinessCheck(restartAfterMs, destination);
}, [file, onRestoreComplete, startReadinessCheck, t, variant]);
@@ -317,6 +321,7 @@ export const DatabaseRestoreFlow = ({ variant = "card", onRestoreComplete }: Dat
<RestoreProgressPanel
active
status={restoreStatus}
reloginRequired={variant === "card"}
onRetry={() => startReadinessCheck(0)}
onReload={() => window.location.reload()}
/>
@@ -11,11 +11,18 @@ export type RestoreProgressStatus = "restoring" | "restarting" | "timedOut";
interface RestoreProgressPanelProps {
active: boolean;
status: RestoreProgressStatus;
reloginRequired?: boolean;
onRetry: () => void;
onReload: () => void;
}
export const RestoreProgressPanel = ({ active, status, onRetry, onReload }: RestoreProgressPanelProps) => {
export const RestoreProgressPanel = ({
active,
status,
reloginRequired = false,
onRetry,
onReload,
}: RestoreProgressPanelProps) => {
const t = useI18n("management.page.tool.backup.restore");
const tCommon = useI18n("common");
const reduceMotion = useReducedMotion();
@@ -63,6 +70,12 @@ export const RestoreProgressPanel = ({ active, status, onRetry, onReload }: Rest
</div>
</Group>
{reloginRequired && !isRestoring ? (
<Text size="sm" c="dimmed">
{t("progress.relogin")}
</Text>
) : null}
{isTimedOut ? (
<Group>
<Button variant="light" onClick={onRetry} leftSection={<IconRefresh size={16} />}>
@@ -39,8 +39,9 @@ export class UnraidIntegration extends Integration implements ISystemHealthMonit
const cpuUtilization = systemInfo.metrics.cpu.cpus.reduce((acc, val) => acc + val.percentTotal, 0);
const cpuCount = systemInfo.info.cpu.cores;
const totalMemory = systemInfo.metrics.memory.total;
const usedMemory = Math.max(totalMemory - systemInfo.metrics.memory.available, 0);
// We use "info" object instead of the stats since this is the exact amount the kernel sees, which is what Unraid displays.
const totalMemory = systemInfo.info.memory.layout.reduce((acc, layout) => layout.size + acc, 0);
const usedMemory = totalMemory * (systemInfo.metrics.memory.percentTotal / 100);
const uptime = dayjs(systemInfo.info.os.uptime);
return {
@@ -135,6 +136,11 @@ export class UnraidIntegration extends Integration implements ISystemHealthMonit
brand,
cores,
threads
},
memory {
layout {
size
}
}
}
}
@@ -60,6 +60,13 @@ export const unraidSystemInfoSchema = z.object({
cores: z.number(),
threads: z.number(),
}),
memory: z.object({
layout: z.array(
z.object({
size: z.number(),
}),
),
}),
}),
});
+2 -1
View File
@@ -6456,7 +6456,8 @@
},
"progress": {
"title": "Restoring database...",
"restarting": "Restarting server"
"restarting": "Restarting server",
"relogin": "Restoring the database invalidated your current session. Homarr will send you to sign in when the server is ready."
},
"timeout": {
"title": "Server did not come back online",