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
+77
View File
@@ -0,0 +1,77 @@
import {existsSync} from "node:fs";
import {loadBuiltinProviders} from "./providers.mjs";
import {breakGlassActor, loadKeyFile, Vault} from "./vault.mjs";
const databasePath = process.env.DATABASE_PATH || "/data/vault.db";
const masterKeyFile = process.env.MASTER_KEY_FILE || "/run/secrets/vault_master_key";
const [command, ...args] = process.argv.slice(2);
function usage() {
console.log(`Usage:
node cli.mjs list [owner-sub]
node cli.mjs audit [limit]
node cli.mjs verify <credential-id>
node cli.mjs delete <credential-id>
node cli.mjs reassign <credential-id> <issuer> <sub> <username>
node cli.mjs rotate-master <new-key-file>
node cli.mjs backup <destination.db>`);
}
if (!command) {
usage();
process.exit(1);
}
const vault = new Vault({
databasePath,
masterKey: loadKeyFile(masterKeyFile),
builtinProviders: loadBuiltinProviders(process.env.PROVIDER_CATALOG_FILE || "/app/providers.json")
});
const actor = breakGlassActor();
try {
if (command === "list") {
const credentials = vault.listCredentials(actor, {all: true});
const filtered = args[0]
? credentials.filter((credential) => credential.owner.sub === args[0])
: credentials;
console.table(filtered.map((credential) => ({
id: credential.id,
owner: credential.owner.username,
sub: credential.owner.sub,
provider: credential.provider,
name: credential.name,
fingerprint: credential.fingerprint,
status: credential.status
})));
} else if (command === "audit") {
console.table(vault.listAudit(actor, {all: true, limit: args[0] || 100}));
} else if (command === "verify" && args[0]) {
console.log(vault.verifyCredential(actor, args[0]));
} else if (command === "delete" && args[0]) {
console.log(vault.deleteCredential(actor, args[0]));
} else if (command === "reassign" && args.length >= 4) {
console.log(vault.reassignCredential(actor, args[0], {
issuer: args[1],
sub: args[2],
username: args[3],
type: "user"
}));
} else if (command === "rotate-master" && args[0]) {
if (!existsSync(args[0])) {
throw new Error(`New key file not found: ${args[0]}`);
}
console.log(vault.rotateMasterKey(actor, loadKeyFile(args[0])));
console.error("Rotation succeeded. Replace the mounted vault_master_key before restarting the service.");
} else if (command === "backup" && args[0]) {
if (existsSync(args[0])) {
throw new Error(`Refusing to overwrite existing backup: ${args[0]}`);
}
console.log(vault.backup(args[0]));
} else {
usage();
process.exitCode = 1;
}
} finally {
vault.close();
}