Files
HealthLog/src/lib/export/__tests__/account-settings-restore.test.ts
T
Marc-André Bombeck 16d1b542a5 fix(backup): keep an erased account's copy out of admin accounts
A restore read the account settings under the operator's AI endpoint
policy whenever the receiving account was an admin. For a copy put into
a chosen account, the settings were written by the erased account's
owner, not by the operator, yet an admin account could be chosen as the
target, and an ordinary target promoted later got the same trust.

Admin accounts are now refused as a target, in the check and the
picker, with backup.target.admin_account. A copy uploaded into a chosen
account is stored as RETARGETED_UPLOAD_<ms>, and its restore never reads
its settings as the operator's, whatever the account's role is by then.
2026-10-29 21:36:33 +01:00

67 lines
2.1 KiB
TypeScript

/**
* Whose word a restored AI endpoint is taken on. An admin's own copy is the
* operator's configuration, so the operator's wider endpoint policy applies;
* a copy uploaded into an account other than the one that wrote it is the
* word of whoever wrote it, whatever the receiving account's role.
*/
import { afterEach, describe, expect, it, vi } from "vitest";
import type { Prisma } from "@/generated/prisma/client";
import { restoreAccountSettings } from "@/lib/export/account-settings-restore";
const PRIVATE_ENDPOINT = "http://10.20.30.40:11434";
function adminTx() {
const update = vi.fn(async () => ({}));
const tx = {
user: {
findUniqueOrThrow: vi.fn(async () => ({
role: "ADMIN",
aiProvider: null,
unitPreference: "metric",
glucoseUnit: "mg/dL",
})),
update,
},
} as unknown as Prisma.TransactionClient;
return { tx, update };
}
const payload = {
accountSettings: { aiProvider: "LOCAL", aiBaseUrl: PRIVATE_ENDPOINT },
};
afterEach(() => {
vi.unstubAllEnvs();
});
describe("restoring an admin account's settings", () => {
it("takes a private AI endpoint from the admin's own copy under the operator's policy", async () => {
vi.stubEnv("AI_PRIVATE_ORIGINS", "");
vi.stubEnv("ALLOW_LOCAL_AI_PRIVATE_HOSTS", "true");
const { tx, update } = adminTx();
const result = await restoreAccountSettings(tx, "admin-1", payload, {
retargeted: false,
});
expect(result.refused).toEqual([]);
expect(update).toHaveBeenCalledWith({
where: { id: "admin-1" },
data: { aiProvider: "LOCAL", aiBaseUrl: PRIVATE_ENDPOINT },
});
});
it("refuses it from a copy that was uploaded into the account from someone else's file", async () => {
vi.stubEnv("AI_PRIVATE_ORIGINS", "");
vi.stubEnv("ALLOW_LOCAL_AI_PRIVATE_HOSTS", "true");
const { tx, update } = adminTx();
const result = await restoreAccountSettings(tx, "admin-1", payload, {
retargeted: true,
});
expect(result.refused).toEqual(["aiBaseUrl"]);
expect(update).toHaveBeenCalledWith({
where: { id: "admin-1" },
data: { aiProvider: "LOCAL" },
});
});
});