Voeg tenant beheer toe aan rikx-offerte
- Login pagina met HMAC-sessie authenticatie - /tenants overzicht: lijst alle rikx-platform accounts - Nieuw tenant aanmaken (naam, slug, admin gebruiker) - Tenant verwijderen (cascade via foreign keys) - Leest rikx-platform SQLite DB via /rikx-platform-data mount - Homepage redirect naar /tenants of /login Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
"use server";
|
||||
|
||||
import { redirect } from "next/navigation";
|
||||
import { randomBytes, scryptSync } from "crypto";
|
||||
import { getPlatformDb } from "../../lib/platform-db";
|
||||
import { getSession } from "../../lib/auth";
|
||||
|
||||
function requireAuth() {
|
||||
// Called inside server actions — session check is synchronous-safe via cache
|
||||
}
|
||||
|
||||
function hashPassword(password: string): string {
|
||||
const salt = randomBytes(16).toString("hex");
|
||||
const hash = scryptSync(password, salt, 64).toString("hex");
|
||||
return `${salt}:${hash}`;
|
||||
}
|
||||
|
||||
export async function createTenant(formData: FormData) {
|
||||
const session = await getSession();
|
||||
if (!session) redirect("/login");
|
||||
|
||||
const name = (formData.get("name") as string).trim();
|
||||
const slug = (formData.get("slug") as string).trim().toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
||||
const adminEmail = (formData.get("admin_email") as string).trim();
|
||||
const adminPassword = formData.get("admin_password") as string;
|
||||
const adminName = (formData.get("admin_name") as string).trim();
|
||||
|
||||
if (!name || !slug || !adminEmail || !adminPassword || !adminName) {
|
||||
redirect("/tenants?error=missing");
|
||||
}
|
||||
|
||||
const db = getPlatformDb();
|
||||
|
||||
const existing = db.prepare("SELECT id FROM accounts WHERE slug = ?").get(slug);
|
||||
if (existing) redirect("/tenants?error=slug");
|
||||
|
||||
db.prepare("INSERT INTO accounts (name, slug) VALUES (?, ?)").run(name, slug);
|
||||
const account = db.prepare("SELECT id FROM accounts WHERE slug = ?").get(slug) as { id: number };
|
||||
|
||||
db.prepare(
|
||||
"INSERT INTO users (account_id, email, password_hash, name, role) VALUES (?, ?, ?, ?, 'admin')"
|
||||
).run(account.id, adminEmail, hashPassword(adminPassword), adminName);
|
||||
|
||||
redirect("/tenants");
|
||||
}
|
||||
|
||||
export async function deleteTenant(formData: FormData) {
|
||||
const session = await getSession();
|
||||
if (!session) redirect("/login");
|
||||
|
||||
const accountId = Number(formData.get("account_id"));
|
||||
if (!accountId) redirect("/tenants");
|
||||
|
||||
const db = getPlatformDb();
|
||||
// Cascade via foreign keys: users, participants, measurements are deleted automatically
|
||||
db.prepare("DELETE FROM accounts WHERE id = ?").run(accountId);
|
||||
|
||||
redirect("/tenants");
|
||||
}
|
||||
Reference in New Issue
Block a user