From 389652b2e56b30bcc7b73bfe868c065f1e70ce9e Mon Sep 17 00:00:00 2001 From: NixReaper Date: Sat, 25 Apr 2026 21:32:32 -0500 Subject: [PATCH] feat: real account provisioner, fix NixClient auth bypass - nixpanel-accounts: creates Apache vhost, PHP-FPM pool, PowerDNS zone (A/MX/SPF records), home dir structure, default index.html - nixpanel-api: create_account now calls provisioner after DB insert - NixClient: replace fake setTimeout login with real JWT API call; admin accounts blocked with redirect message; logout clears token - CHANGELOG updated --- CHANGELOG.md | 19 ++ Cargo.toml | 1 + nixclient/src/App.tsx | 54 +++-- nixpanel-accounts/Cargo.toml | 13 ++ nixpanel-accounts/src/main.rs | 322 ++++++++++++++++++++++++++++ nixpanel-api/src/routes/accounts.rs | 29 ++- 6 files changed, 420 insertions(+), 18 deletions(-) create mode 100644 nixpanel-accounts/Cargo.toml create mode 100644 nixpanel-accounts/src/main.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 92643e7..9ce65b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,25 @@ Versions follow [Semantic Versioning](https://semver.org/). ## [Unreleased] +### Added +- `nixpanel-accounts` section binary — full account provisioner + - Creates Apache vhost with PHP-FPM proxy + - Creates PHP-FPM pool (per-user socket, open_basedir isolation) + - Creates PowerDNS zone with A, www, mail, ftp, MX, SPF records + - Builds home directory structure: `public_html/`, `logs/`, `tmp/`, `mail/`, `backups/` + - Writes default `index.html` for new domains + - Sets correct ownership and permissions + - `deprovision` action removes vhost, FPM pool, DNS zone +- NixClient real JWT authentication — login now calls `/api/auth/login` + - Session persists across refresh via `localStorage` + - Admin accounts redirected to NixServer (port 2087) instead of being allowed in + +### Fixed +- NixClient login accepted any username/password (was using fake `setTimeout` bypass) +- NixClient Sign out button now clears JWT and session correctly +- `CreateAccount` `FormField` component moved to module level — fixes focus jumping to next field after one keystroke (React remount bug from component defined inside render function) +- `BIGINT UNSIGNED` columns changed to `BIGINT` in DB schema — fixes `i64` type mismatch error on login + ### Planned - DNS zone editor (CRUD records via PowerDNS API) - Email account management (Dovecot mailbox provisioning) diff --git a/Cargo.toml b/Cargo.toml index b11a2fd..e482683 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "nixpanel-common", "nixpanel-api", + "nixpanel-accounts", "nixpanel-services", "nixpanel-sysinfo", ] diff --git a/nixclient/src/App.tsx b/nixclient/src/App.tsx index 80bb41f..75a2f9e 100644 --- a/nixclient/src/App.tsx +++ b/nixclient/src/App.tsx @@ -1,4 +1,5 @@ -import { useState } from 'react' +import { useState, useEffect } from 'react' +import * as api from './api' /* ── Types ──────────────────────────────────────────────────────────────── */ type Page = @@ -304,14 +305,11 @@ const PAGE_META: Record = { } /* ── Client panel shell ─────────────────────────────────────────────────── */ -function ClientPanel() { +function ClientPanel({ onLogout }: { onLogout: () => void }) { const [page, setPage] = useState('home') - const [loggedIn, setLoggedIn] = useState(true) - - if (!loggedIn) return null - const meta = PAGE_META[page] - const domain = 'yourdomain.com' + const username = localStorage.getItem('nixclient_username') ?? 'user' + const domain = username // domain matches account username for now function renderPage() { if (page === 'home') return @@ -363,7 +361,7 @@ function ClientPanel() { {domain}