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}