"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"); }