feat: rebuild xiteng.site homelab platform

This commit is contained in:
2026-08-12 09:48:25 +08:00
parent 557b0eca33
commit 5b84988789
128 changed files with 14979 additions and 292 deletions
+144
View File
@@ -0,0 +1,144 @@
import test from "node:test";
import assert from "node:assert/strict";
import {mkdtempSync, readFileSync, rmSync} from "node:fs";
import {tmpdir} from "node:os";
import {join} from "node:path";
import {createAuthentikAdmin} from "./authentik.mjs";
const user = {
pk: 3,
uuid: "user-uuid",
username: "liooil",
name: "西腾",
email: "[email protected]",
is_active: true,
is_superuser: true,
type: "internal",
path: "users",
groups_obj: [{pk: "group-id", name: "liuhome"}],
last_login: null,
date_joined: "2026-01-01T00:00:00Z"
};
const group = {pk: "group-id", name: "liuhome", is_superuser: false, users: [3], users_obj: [{pk: 3, username: "liooil", name: "西腾"}]};
const application = {pk: "app-id", slug: "xiteng-chat", name: "Xiteng Chat"};
const binding = {pk: "binding-id", target: "app-id", group: "group-id", enabled: true};
function response(payload, status = 200) {
return new Response(payload === null ? null : JSON.stringify(payload), {status, headers: {"Content-Type": "application/json"}});
}
test("summarizes only human users and liuhome application access", async () => {
const directory = mkdtempSync(join(tmpdir(), "authentik-admin-test-"));
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url) => {
const path = new URL(url).pathname;
if (path === "/-/health/ready/") return response({status: "ok"});
if (path === "/api/v3/core/users/") return response({results: [user, {...user, pk: 9, username: "ak-outpost", path: "goauthentik.io/outposts"}]});
if (path === "/api/v3/core/groups/") return response({results: [group]});
if (path === "/api/v3/core/applications/") return response({results: [application]});
if (path === "/api/v3/policies/bindings/") return response({results: [binding]});
if (path === "/api/v3/authenticators/admin/totp/") return response({results: [{pk: 1, name: "Phone", user: {pk: 3}}]});
if (path === "/api/v3/authenticators/admin/webauthn/") return response({results: [{pk: 2, name: "Laptop", user: {pk: 3}}]});
throw new Error(`Unexpected URL ${url}`);
};
try {
const admin = createAuthentikAdmin({baseUrl: "https://auth.example/", token: "token", auditPath: join(directory, "audit.jsonl")});
const summary = await admin.summary();
assert.deepEqual(summary.users.map((item) => item.username), ["liooil"]);
assert.deepEqual(summary.groups.map((item) => item.name), ["liuhome"]);
assert.deepEqual(summary.applications.find((item) => item.slug === "xiteng-chat").allowedGroups, ["liuhome"]);
assert.equal(summary.users[0].totpCount, 1);
assert.equal(summary.users[0].passkeyCount, 1);
} finally {
globalThis.fetch = originalFetch;
rmSync(directory, {recursive: true, force: true});
}
});
test("refuses to disable liooil", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url) => {
if (new URL(url).pathname === "/api/v3/core/users/3/") return response(user);
throw new Error(`Unexpected URL ${url}`);
};
try {
const admin = createAuthentikAdmin({baseUrl: "https://auth.example/", token: "token", auditPath: "/tmp/unused-authentik-audit"});
await assert.rejects(() => admin.mutate("/api/admin/identity/users/3/disable", {}, "liooil"), (error) => {
assert.equal(error.statusCode, 409);
return /不能停用/.test(error.message);
});
} finally {
globalThis.fetch = originalFetch;
}
});
test("does not write temporary passwords to the identity audit", async () => {
const directory = mkdtempSync(join(tmpdir(), "authentik-audit-test-"));
const auditPath = join(directory, "audit.jsonl");
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url, options = {}) => {
const path = new URL(url).pathname;
if (path === "/api/v3/core/users/3/") return response(user);
if (path === "/api/v3/core/users/3/set_password/" && options.method === "POST") return response(null, 204);
throw new Error(`Unexpected URL ${url}`);
};
try {
const admin = createAuthentikAdmin({baseUrl: "https://auth.example/", token: "token", auditPath});
await admin.mutate("/api/admin/identity/users/3/password", {password: "Temporary-secret-2026"}, "liooil");
const audit = readFileSync(auditPath, "utf8");
assert.doesNotMatch(audit, /Temporary-secret-2026/);
assert.match(audit, /user\.password/);
} finally {
globalThis.fetch = originalFetch;
rmSync(directory, {recursive: true, force: true});
}
});
test("returns only the current user's authenticators and sessions", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url) => {
const parsed = new URL(url);
const path = parsed.pathname;
if (path === "/api/v3/core/users/") return response({results: [user]});
if (path === "/api/v3/authenticators/admin/totp/") return response({results: [
{pk: 1, name: "Phone", user: {pk: 3}},
{pk: 9, name: "Other", user: {pk: 99}}
]});
if (path === "/api/v3/authenticators/admin/webauthn/") return response({results: [
{pk: 2, name: "Laptop", created_on: "2026-01-02T00:00:00Z", device_type: "single_device", aaguid: "aaguid", user: {pk: 3}}
]});
if (path === "/api/v3/core/authenticated_sessions/") return response({results: [
{uuid: "session-id", user: 3, current: true, last_ip: "127.0.0.1", last_user_agent: "Browser", last_used: "2026-01-03T00:00:00Z", expires: "2026-01-04T00:00:00Z"},
{uuid: "other-session", user: 99}
]});
throw new Error(`Unexpected URL ${url}`);
};
try {
const admin = createAuthentikAdmin({baseUrl: "https://auth.example/", token: "token", auditPath: "/tmp/unused-authentik-audit"});
const account = await admin.accountSummary("liooil");
assert.equal(account.profile.username, "liooil");
assert.deepEqual(account.security.totp.map((device) => device.name), ["Phone"]);
assert.deepEqual(account.security.passkeys.map((device) => device.name), ["Laptop"]);
assert.deepEqual(account.security.sessions.map((session) => session.id), ["session-id"]);
assert.match(account.security.totpSetupUrl, /default-authenticator-totp-setup/);
assert.match(account.security.passkeySetupUrl, /default-authenticator-webauthn-setup/);
} finally {
globalThis.fetch = originalFetch;
}
});
test("refuses to mutate another user's authenticator", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url) => {
const path = new URL(url).pathname;
if (path === "/api/v3/core/users/") return response({results: [user]});
if (path === "/api/v3/authenticators/admin/webauthn/9/") return response({pk: 9, name: "Other", user: {pk: 99}});
throw new Error(`Unexpected URL ${url}`);
};
try {
const admin = createAuthentikAdmin({baseUrl: "https://auth.example/", token: "token", auditPath: "/tmp/unused-authentik-audit"});
await assert.rejects(() => admin.accountMutate("/api/account/security/passkeys/9/delete", {}, "liooil"), (error) => error.statusCode === 404);
} finally {
globalThis.fetch = originalFetch;
}
});