feat: exposition Traefik + provisioning auth (v0.21.0)

Backend exposé via Traefik+TLS (réseau traefik-public externe, labels,
CHLOVA_DOMAIN) — surface unique. Script provision-auth (hash scrypt +
TOTP otpauth + JWT). .env.example section API/UI. security.md : surface
exposée Phase 4. Compose revalidé.

Palier de risque : privilégié (exposition réseau) — non déployé ; auth
requise pour activer l'API.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kantin-Petit
2026-06-23 02:15:17 +02:00
parent 26debf2fe0
commit e97c885ebf
6 changed files with 80 additions and 4 deletions
+2 -1
View File
@@ -13,7 +13,8 @@
"start": "node dist/index.js",
"typecheck": "tsc -p tsconfig.json",
"test": "vitest run",
"test:watch": "vitest"
"test:watch": "vitest",
"provision-auth": "tsx scripts/provision-auth.ts"
},
"dependencies": {
"@fastify/cors": "11.2.0",
+28
View File
@@ -0,0 +1,28 @@
import { randomBytes } from "node:crypto";
import { generateSecret } from "otplib";
import { hashPassword } from "../src/api/auth.js";
/**
* Génère les secrets d'auth de la surface exposée (Phase 4) à coller dans .env.
* Usage : npm run provision-auth -- <user> <password>
*
* N'imprime que des valeurs à mettre dans le coffre/.env (jamais commitées).
* Le secret TOTP est aussi affiché en otpauth:// pour l'ajouter à une app 2FA.
*/
const [, , user, password] = process.argv;
if (!user || !password) {
console.error("Usage : npm run provision-auth -- <user> <password>");
process.exit(1);
}
const totpSecret = generateSecret();
const jwtSecret = randomBytes(48).toString("base64url");
const otpauth = `otpauth://totp/CHLOVA:${encodeURIComponent(user)}?secret=${totpSecret}&issuer=CHLOVA`;
console.log("# --- À coller dans .env (NE JAMAIS committer) ---");
console.log(`CHLOVA_ADMIN_USER=${user}`);
console.log(`CHLOVA_ADMIN_PASSWORD_HASH=${hashPassword(password)}`);
console.log(`CHLOVA_TOTP_SECRET=${totpSecret}`);
console.log(`CHLOVA_JWT_SECRET=${jwtSecret}`);
console.log("\n# Ajoute ce TOTP à ton app 2FA (Aegis, Google Authenticator…) :");
console.log(otpauth);