homeio
PublicForked from doctor-io/homeio
route.test.ts
import { describe, expect, it, vi } from "vitest";
vi.mock("@/lib/server/modules/auth/repository", () => ({
hasAnyUsers: vi.fn(),
}));
vi.mock("@/lib/server/modules/auth/service", () => {
class AuthError extends Error {
constructor(
message: string,
public readonly statusCode: number,
) {
super(message);
}
}
return {
AuthError,
registerUser: vi.fn(),
};
});
vi.mock("@/lib/server/modules/store/catalog", () => ({
bootstrapDefaultCasaosCatalog: vi.fn(),
}));
vi.mock("@/lib/server/storage/data-root", () => ({
ensureDataRootDirectories: vi.fn(),
resolveDataRootDirectory: vi.fn(() => "/DATA"),
}));
import { POST } from "@/app/api/auth/register/route";
import { hasAnyUsers } from "@/lib/server/modules/auth/repository";
import { registerUser } from "@/lib/server/modules/auth/service";
import { bootstrapDefaultCasaosCatalog } from "@/lib/server/modules/store/catalog";
import { ensureDataRootDirectories } from "@/lib/server/storage/data-root";
describe("POST /api/auth/register", () => {
it("refuses a second account, whatever the environment says", async () => {
// The database is the only authority on this. There used to be an
// AUTH_ALLOW_REGISTRATION env var alongside it, which install.sh set to
// `true` and never unset — so a script-installed server kept handing out
// full accounts to anyone who could reach the endpoint.
vi.mocked(hasAnyUsers).mockResolvedValueOnce(true);
const request = new Request("http://localhost/api/auth/register", {
method: "POST",
body: JSON.stringify({
username: "admin",
password: "StrongPass123",
confirmPassword: "StrongPass123",
}),
});
const response = await POST(request);
const json = (await response.json()) as { error: string };
expect(response.status).toBe(403);
expect(json.error).toContain("already has an account");
expect(registerUser).not.toHaveBeenCalled();
expect(ensureDataRootDirectories).not.toHaveBeenCalled();
expect(bootstrapDefaultCasaosCatalog).not.toHaveBeenCalled();
});
it("allows first registration when no users exist and bootstraps the catalog", async () => {
vi.mocked(hasAnyUsers).mockResolvedValueOnce(false);
vi.mocked(bootstrapDefaultCasaosCatalog).mockResolvedValueOnce({
path: "/DATA/AppStore/CasaOS-AppStore",
indexedApps: 10,
});
vi.mocked(registerUser).mockResolvedValueOnce({
id: "11111111-1111-1111-1111-111111111111",
username: "admin",
});
const request = new Request("http://localhost/api/auth/register", {
method: "POST",
body: JSON.stringify({
username: "admin",
password: "StrongPass123",
confirmPassword: "StrongPass123",
}),
});
const response = await POST(request);
const json = (await response.json()) as {
data: { username: string };
};
expect(response.status).toBe(201);
expect(json.data.username).toBe("admin");
expect(ensureDataRootDirectories).toHaveBeenCalledTimes(1);
expect(bootstrapDefaultCasaosCatalog).toHaveBeenCalledTimes(1);
});
});