diff --git a/.env.example b/.env.example
index ce39a6e..5f3279e 100644
--- a/.env.example
+++ b/.env.example
@@ -9,8 +9,8 @@ JWT_REFRESH_EXPIRES_IN="7d"
# Server
NODE_ENV="production"
-WHM_PORT=2087
-CPANEL_PORT=2083
+NIXSERVER_PORT=2087
+NIXCLIENT_PORT=2083
HOST="0.0.0.0"
# Admin
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3b456c9
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,9 @@
+# Default — normalize to LF on commit
+* text=auto eol=lf
+
+# Shell scripts must always be LF
+*.sh text eol=lf
+
+# Windows-only files (if any)
+*.bat text eol=crlf
+*.cmd text eol=crlf
diff --git a/cpanel/index.html b/nixclient/index.html
similarity index 100%
rename from cpanel/index.html
rename to nixclient/index.html
diff --git a/cpanel/package.json b/nixclient/package.json
similarity index 96%
rename from cpanel/package.json
rename to nixclient/package.json
index cdc56a6..2693ddf 100644
--- a/cpanel/package.json
+++ b/nixclient/package.json
@@ -1,6 +1,6 @@
{
"name": "@nixpanel/cpanel",
- "version": "0.1.0",
+ "version": "0.2.0",
"private": true,
"type": "module",
"scripts": {
diff --git a/cpanel/postcss.config.js b/nixclient/postcss.config.js
similarity index 100%
rename from cpanel/postcss.config.js
rename to nixclient/postcss.config.js
diff --git a/cpanel/src/App.tsx b/nixclient/src/App.tsx
similarity index 100%
rename from cpanel/src/App.tsx
rename to nixclient/src/App.tsx
diff --git a/cpanel/src/api/client.ts b/nixclient/src/api/client.ts
similarity index 100%
rename from cpanel/src/api/client.ts
rename to nixclient/src/api/client.ts
diff --git a/cpanel/src/components/Layout.tsx b/nixclient/src/components/Layout.tsx
similarity index 99%
rename from cpanel/src/components/Layout.tsx
rename to nixclient/src/components/Layout.tsx
index db6a9ee..b77c91f 100644
--- a/cpanel/src/components/Layout.tsx
+++ b/nixclient/src/components/Layout.tsx
@@ -34,7 +34,7 @@ export default function Layout() {
{sidebarOpen && (
-
NixPanel
+
NixClient
{user?.domain}
)}
diff --git a/cpanel/src/contexts/AuthContext.tsx b/nixclient/src/contexts/AuthContext.tsx
similarity index 95%
rename from cpanel/src/contexts/AuthContext.tsx
rename to nixclient/src/contexts/AuthContext.tsx
index 519bc57..622a27c 100644
--- a/cpanel/src/contexts/AuthContext.tsx
+++ b/nixclient/src/contexts/AuthContext.tsx
@@ -40,7 +40,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
const login = async (username: string, password: string) => {
const { data } = await api.post('/auth/login', { username, password })
- if (data.data.role !== 'user') throw new Error('Use WHM to log in as admin or reseller')
+ if (data.data.role !== 'user') throw new Error('Use NixServer to log in as admin or reseller')
localStorage.setItem('access_token', data.data.accessToken)
localStorage.setItem('refresh_token', data.data.refreshToken)
setUser(data.data.user)
diff --git a/cpanel/src/index.css b/nixclient/src/index.css
similarity index 100%
rename from cpanel/src/index.css
rename to nixclient/src/index.css
diff --git a/cpanel/src/main.tsx b/nixclient/src/main.tsx
similarity index 100%
rename from cpanel/src/main.tsx
rename to nixclient/src/main.tsx
diff --git a/cpanel/src/pages/CronJobs.tsx b/nixclient/src/pages/CronJobs.tsx
similarity index 94%
rename from cpanel/src/pages/CronJobs.tsx
rename to nixclient/src/pages/CronJobs.tsx
index c281024..7ff736e 100644
--- a/cpanel/src/pages/CronJobs.tsx
+++ b/nixclient/src/pages/CronJobs.tsx
@@ -22,7 +22,7 @@ export default function CronJobs() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/cpanel/cron'); setJobs(r.data.data) }
+ try { const r = await api.get('/nixclient/cron'); setJobs(r.data.data) }
finally { setLoading(false) }
}
@@ -30,18 +30,18 @@ export default function CronJobs() {
const save = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
- try { await api.post('/cpanel/cron', form); setShowModal(false); setForm({ schedule: '0 * * * *', command: '', comment: '', enabled: true }); fetch() }
+ try { await api.post('/nixclient/cron', form); setShowModal(false); setForm({ schedule: '0 * * * *', command: '', comment: '', enabled: true }); fetch() }
catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
}
const del = async (id: number) => {
if (!confirm('Delete this cron job?')) return
- try { await api.delete(`/cpanel/cron/${id}`); fetch() } catch {}
+ try { await api.delete(`/nixclient/cron/${id}`); fetch() } catch {}
}
const toggle = async (job: CronJob) => {
- try { await api.put(`/cpanel/cron/${job.id}`, { enabled: !job.enabled }); fetch() } catch {}
+ try { await api.put(`/nixclient/cron/${job.id}`, { enabled: !job.enabled }); fetch() } catch {}
}
return (
diff --git a/cpanel/src/pages/Databases.tsx b/nixclient/src/pages/Databases.tsx
similarity index 94%
rename from cpanel/src/pages/Databases.tsx
rename to nixclient/src/pages/Databases.tsx
index 446065a..5cc6ca5 100644
--- a/cpanel/src/pages/Databases.tsx
+++ b/nixclient/src/pages/Databases.tsx
@@ -18,7 +18,7 @@ export default function Databases() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/cpanel/databases'); setDbs(r.data.data) }
+ try { const r = await api.get('/nixclient/databases'); setDbs(r.data.data) }
finally { setLoading(false) }
}
@@ -26,27 +26,27 @@ export default function Databases() {
const createDb = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
- try { await api.post('/cpanel/databases', dbForm); setShowDbModal(false); setDbForm({ name: '' }); fetch() }
+ try { await api.post('/nixclient/databases', dbForm); setShowDbModal(false); setDbForm({ name: '' }); fetch() }
catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
}
const deleteDb = async (id: number) => {
if (!confirm('Delete this database and all its data?')) return
- try { await api.delete(`/cpanel/databases/${id}`); fetch() }
+ try { await api.delete(`/nixclient/databases/${id}`); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
}
const createUser = async (e: React.FormEvent) => {
e.preventDefault(); if (!showUserModal) return
setSaving(true); setError('')
- try { await api.post(`/cpanel/databases/${showUserModal}/users`, userForm); setShowUserModal(null); setUserForm({ username: '', password: '', privileges: 'ALL' }); fetch() }
+ try { await api.post(`/nixclient/databases/${showUserModal}/users`, userForm); setShowUserModal(null); setUserForm({ username: '', password: '', privileges: 'ALL' }); fetch() }
catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
}
const deleteUser = async (dbId: number, userId: number) => {
- try { await api.delete(`/cpanel/databases/${dbId}/users/${userId}`); fetch() }
+ try { await api.delete(`/nixclient/databases/${dbId}/users/${userId}`); fetch() }
catch {}
}
diff --git a/cpanel/src/pages/Domains.tsx b/nixclient/src/pages/Domains.tsx
similarity index 90%
rename from cpanel/src/pages/Domains.tsx
rename to nixclient/src/pages/Domains.tsx
index a3a5014..9b7b39c 100644
--- a/cpanel/src/pages/Domains.tsx
+++ b/nixclient/src/pages/Domains.tsx
@@ -18,7 +18,7 @@ export default function Domains() {
const fetch = async () => {
setLoading(true)
try {
- const r = await api.get(`/cpanel/domains/${tab}`)
+ const r = await api.get(`/nixclient/domains/${tab}`)
setItems(r.data.data)
} finally { setLoading(false) }
}
@@ -28,9 +28,9 @@ export default function Domains() {
const save = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
try {
- if (tab === 'subdomains') await api.post('/cpanel/domains/subdomains', { subdomain: form.subdomain })
- else if (tab === 'addon') await api.post('/cpanel/domains/addon', { domain: form.domain })
- else await api.post('/cpanel/domains/parked', { domain: form.domain })
+ if (tab === 'subdomains') await api.post('/nixclient/domains/subdomains', { subdomain: form.subdomain })
+ else if (tab === 'addon') await api.post('/nixclient/domains/addon', { domain: form.domain })
+ else await api.post('/nixclient/domains/parked', { domain: form.domain })
setShowModal(false); setForm({ subdomain: '', domain: '' }); fetch()
} catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
@@ -39,9 +39,9 @@ export default function Domains() {
const del = async (id: number) => {
if (!confirm('Remove this domain?')) return
try {
- if (tab === 'subdomains') await api.delete(`/cpanel/domains/subdomains/${id}`)
- else if (tab === 'addon') await api.delete(`/cpanel/domains/addon/${id}`)
- else await api.delete(`/cpanel/domains/parked/${id}`)
+ if (tab === 'subdomains') await api.delete(`/nixclient/domains/subdomains/${id}`)
+ else if (tab === 'addon') await api.delete(`/nixclient/domains/addon/${id}`)
+ else await api.delete(`/nixclient/domains/parked/${id}`)
fetch()
} catch {}
}
diff --git a/cpanel/src/pages/Email.tsx b/nixclient/src/pages/Email.tsx
similarity index 95%
rename from cpanel/src/pages/Email.tsx
rename to nixclient/src/pages/Email.tsx
index b727857..3eb55e3 100644
--- a/cpanel/src/pages/Email.tsx
+++ b/nixclient/src/pages/Email.tsx
@@ -20,7 +20,7 @@ export default function Email() {
const fetch = async () => {
setLoading(true)
try {
- const [em, fw] = await Promise.all([api.get('/cpanel/email'), api.get('/cpanel/email/forwarders')])
+ const [em, fw] = await Promise.all([api.get('/nixclient/email'), api.get('/nixclient/email/forwarders')])
setAccounts(em.data.data)
setForwarders(fw.data.data)
} finally { setLoading(false) }
@@ -31,7 +31,7 @@ export default function Email() {
const createAccount = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
try {
- await api.post('/cpanel/email', form)
+ await api.post('/nixclient/email', form)
setShowModal(false); fetch()
} catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
@@ -39,18 +39,18 @@ export default function Email() {
const del = async (id: number) => {
if (!confirm('Delete this email account?')) return
- try { await api.delete(`/cpanel/email/${id}`); fetch() } catch {}
+ try { await api.delete(`/nixclient/email/${id}`); fetch() } catch {}
}
const addForwarder = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
- try { await api.post('/cpanel/email/forwarders', fwdForm); setShowFwd(false); fetch() }
+ try { await api.post('/nixclient/email/forwarders', fwdForm); setShowFwd(false); fetch() }
catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
}
const delFwd = async (id: number) => {
- try { await api.delete(`/cpanel/email/forwarders/${id}`); fetch() } catch {}
+ try { await api.delete(`/nixclient/email/forwarders/${id}`); fetch() } catch {}
}
return (
diff --git a/cpanel/src/pages/FTP.tsx b/nixclient/src/pages/FTP.tsx
similarity index 95%
rename from cpanel/src/pages/FTP.tsx
rename to nixclient/src/pages/FTP.tsx
index 748fa04..fa94768 100644
--- a/cpanel/src/pages/FTP.tsx
+++ b/nixclient/src/pages/FTP.tsx
@@ -14,7 +14,7 @@ export default function FTP() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/cpanel/ftp'); setAccounts(r.data.data) }
+ try { const r = await api.get('/nixclient/ftp'); setAccounts(r.data.data) }
finally { setLoading(false) }
}
@@ -22,14 +22,14 @@ export default function FTP() {
const save = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
- try { await api.post('/cpanel/ftp', form); setShowModal(false); fetch() }
+ try { await api.post('/nixclient/ftp', form); setShowModal(false); fetch() }
catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
}
const del = async (id: number) => {
if (!confirm('Delete this FTP account?')) return
- try { await api.delete(`/cpanel/ftp/${id}`); fetch() } catch {}
+ try { await api.delete(`/nixclient/ftp/${id}`); fetch() } catch {}
}
return (
diff --git a/cpanel/src/pages/FileManager.tsx b/nixclient/src/pages/FileManager.tsx
similarity index 95%
rename from cpanel/src/pages/FileManager.tsx
rename to nixclient/src/pages/FileManager.tsx
index d2e06c1..1394730 100644
--- a/cpanel/src/pages/FileManager.tsx
+++ b/nixclient/src/pages/FileManager.tsx
@@ -19,7 +19,7 @@ export default function FileManager() {
const loadDir = async (p: string) => {
setLoading(true); setSelected(new Set())
try {
- const r = await api.get(`/cpanel/files?path=${encodeURIComponent(p)}`)
+ const r = await api.get(`/nixclient/files?path=${encodeURIComponent(p)}`)
setFiles(r.data.data.files); setPath(r.data.data.path)
} catch (e: unknown) {
alert((e as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed to load directory')
@@ -35,7 +35,7 @@ export default function FileManager() {
const openFile = async (filePath: string) => {
try {
- const r = await api.get(`/cpanel/files/content?path=${encodeURIComponent(filePath)}`)
+ const r = await api.get(`/nixclient/files/content?path=${encodeURIComponent(filePath)}`)
setEditing({ path: filePath, content: r.data.data.content })
} catch (e: unknown) {
alert((e as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Cannot open file')
@@ -46,7 +46,7 @@ export default function FileManager() {
if (!editing) return
setSaving(true)
try {
- await api.put('/cpanel/files/content', { path: editing.path, content: editing.content })
+ await api.put('/nixclient/files/content', { path: editing.path, content: editing.content })
setEditing(null)
} catch (e: unknown) {
alert((e as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Save failed')
@@ -56,7 +56,7 @@ export default function FileManager() {
const deleteSelected = async () => {
if (!selected.size || !confirm(`Delete ${selected.size} item(s)?`)) return
try {
- await api.delete('/cpanel/files', { data: { paths: Array.from(selected) } })
+ await api.delete('/nixclient/files', { data: { paths: Array.from(selected) } })
loadDir(path)
} catch {}
}
@@ -64,7 +64,7 @@ export default function FileManager() {
const createDir = async (e: React.FormEvent) => {
e.preventDefault()
try {
- await api.post('/cpanel/files/mkdir', { path: `${path}/${newDir}` })
+ await api.post('/nixclient/files/mkdir', { path: `${path}/${newDir}` })
setNewDir(''); setShowNewDir(false); loadDir(path)
} catch (e: unknown) {
alert((e as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed')
diff --git a/cpanel/src/pages/Login.tsx b/nixclient/src/pages/Login.tsx
similarity index 96%
rename from cpanel/src/pages/Login.tsx
rename to nixclient/src/pages/Login.tsx
index fdb62a9..f86d706 100644
--- a/cpanel/src/pages/Login.tsx
+++ b/nixclient/src/pages/Login.tsx
@@ -27,7 +27,7 @@ export default function Login() {
N
- NixPanel
+ NixClient
Hosting Control Panel
@@ -49,7 +49,7 @@ export default function Login() {
- NixPanel v0.1.0 · Port 2083
+ NixClient v0.2.0 · Port 2083
)
diff --git a/cpanel/src/pages/Overview.tsx b/nixclient/src/pages/Overview.tsx
similarity index 98%
rename from cpanel/src/pages/Overview.tsx
rename to nixclient/src/pages/Overview.tsx
index 1367b56..60d0144 100644
--- a/cpanel/src/pages/Overview.tsx
+++ b/nixclient/src/pages/Overview.tsx
@@ -53,7 +53,7 @@ export default function Overview() {
const [stats, setStats] = useState(null)
useEffect(() => {
- api.get('/cpanel/stats').then(r => setStats(r.data.data)).catch(() => {})
+ api.get('/nixclient/stats').then(r => setStats(r.data.data)).catch(() => {})
}, [])
return (
diff --git a/cpanel/src/pages/SSL.tsx b/nixclient/src/pages/SSL.tsx
similarity index 96%
rename from cpanel/src/pages/SSL.tsx
rename to nixclient/src/pages/SSL.tsx
index 4d1054b..664ef35 100644
--- a/cpanel/src/pages/SSL.tsx
+++ b/nixclient/src/pages/SSL.tsx
@@ -10,14 +10,14 @@ export default function SSL() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/whm/ssl'); setCerts(r.data.data) }
+ try { const r = await api.get('/nixserver/ssl'); setCerts(r.data.data) }
finally { setLoading(false) }
}
useEffect(() => { fetch() }, [])
const renew = async (id: number) => {
- try { await api.post(`/whm/ssl/${id}/renew`); fetch() }
+ try { await api.post(`/nixserver/ssl/${id}/renew`); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Renewal failed') }
}
diff --git a/cpanel/src/pages/Stats.tsx b/nixclient/src/pages/Stats.tsx
similarity index 97%
rename from cpanel/src/pages/Stats.tsx
rename to nixclient/src/pages/Stats.tsx
index 025713f..2b991eb 100644
--- a/cpanel/src/pages/Stats.tsx
+++ b/nixclient/src/pages/Stats.tsx
@@ -34,7 +34,7 @@ export default function Stats() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/cpanel/stats'); setStats(r.data.data) }
+ try { const r = await api.get('/nixclient/stats'); setStats(r.data.data) }
finally { setLoading(false) }
}
diff --git a/cpanel/tailwind.config.js b/nixclient/tailwind.config.js
similarity index 100%
rename from cpanel/tailwind.config.js
rename to nixclient/tailwind.config.js
diff --git a/cpanel/tsconfig.json b/nixclient/tsconfig.json
similarity index 100%
rename from cpanel/tsconfig.json
rename to nixclient/tsconfig.json
diff --git a/cpanel/tsconfig.node.json b/nixclient/tsconfig.node.json
similarity index 100%
rename from cpanel/tsconfig.node.json
rename to nixclient/tsconfig.node.json
diff --git a/cpanel/vite.config.ts b/nixclient/vite.config.ts
similarity index 100%
rename from cpanel/vite.config.ts
rename to nixclient/vite.config.ts
diff --git a/whm/index.html b/nixserver/index.html
similarity index 100%
rename from whm/index.html
rename to nixserver/index.html
diff --git a/whm/package.json b/nixserver/package.json
similarity index 96%
rename from whm/package.json
rename to nixserver/package.json
index c6b8bf4..8fca5ba 100644
--- a/whm/package.json
+++ b/nixserver/package.json
@@ -1,6 +1,6 @@
{
"name": "@nixpanel/whm",
- "version": "0.1.0",
+ "version": "0.2.0",
"private": true,
"type": "module",
"scripts": {
diff --git a/whm/postcss.config.js b/nixserver/postcss.config.js
similarity index 100%
rename from whm/postcss.config.js
rename to nixserver/postcss.config.js
diff --git a/whm/src/App.tsx b/nixserver/src/App.tsx
similarity index 100%
rename from whm/src/App.tsx
rename to nixserver/src/App.tsx
diff --git a/whm/src/api/client.ts b/nixserver/src/api/client.ts
similarity index 100%
rename from whm/src/api/client.ts
rename to nixserver/src/api/client.ts
diff --git a/whm/src/components/Layout.tsx b/nixserver/src/components/Layout.tsx
similarity index 97%
rename from whm/src/components/Layout.tsx
rename to nixserver/src/components/Layout.tsx
index 7454425..61a1085 100644
--- a/whm/src/components/Layout.tsx
+++ b/nixserver/src/components/Layout.tsx
@@ -49,8 +49,8 @@ export default function Layout() {
{sidebarOpen && (
-
NixPanel
-
WHM
+
NixServer
+
Admin Panel
)}
diff --git a/whm/src/contexts/AuthContext.tsx b/nixserver/src/contexts/AuthContext.tsx
similarity index 95%
rename from whm/src/contexts/AuthContext.tsx
rename to nixserver/src/contexts/AuthContext.tsx
index ef95abe..5065961 100644
--- a/whm/src/contexts/AuthContext.tsx
+++ b/nixserver/src/contexts/AuthContext.tsx
@@ -44,7 +44,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
const login = async (username: string, password: string) => {
const { data } = await api.post('/auth/login', { username, password })
if (data.data.role !== 'admin' && data.data.role !== 'reseller') {
- throw new Error('Access denied — WHM is for administrators and resellers only')
+ throw new Error('Access denied — NixServer is for administrators and resellers only')
}
localStorage.setItem('access_token', data.data.accessToken)
localStorage.setItem('refresh_token', data.data.refreshToken)
diff --git a/whm/src/index.css b/nixserver/src/index.css
similarity index 100%
rename from whm/src/index.css
rename to nixserver/src/index.css
diff --git a/whm/src/main.tsx b/nixserver/src/main.tsx
similarity index 100%
rename from whm/src/main.tsx
rename to nixserver/src/main.tsx
diff --git a/whm/src/pages/Accounts.tsx b/nixserver/src/pages/Accounts.tsx
similarity index 96%
rename from whm/src/pages/Accounts.tsx
rename to nixserver/src/pages/Accounts.tsx
index 9327248..fd4d783 100644
--- a/whm/src/pages/Accounts.tsx
+++ b/nixserver/src/pages/Accounts.tsx
@@ -43,7 +43,7 @@ export default function Accounts() {
const params = new URLSearchParams({ page: String(page), limit: '25' })
if (search) params.set('search', search)
if (status) params.set('status', status)
- const r = await api.get(`/whm/accounts?${params}`)
+ const r = await api.get(`/nixserver/accounts?${params}`)
setData(r.data.data)
} finally {
setLoading(false)
@@ -56,9 +56,9 @@ export default function Accounts() {
setActionMenu(null)
if (act === 'terminate' && !confirm('Terminate this account? This cannot be undone.')) return
try {
- if (act === 'suspend') await api.post(`/whm/accounts/${id}/suspend`)
- else if (act === 'unsuspend') await api.post(`/whm/accounts/${id}/unsuspend`)
- else await api.delete(`/whm/accounts/${id}`)
+ if (act === 'suspend') await api.post(`/nixserver/accounts/${id}/suspend`)
+ else if (act === 'unsuspend') await api.post(`/nixserver/accounts/${id}/unsuspend`)
+ else await api.delete(`/nixserver/accounts/${id}`)
fetch()
} catch (e: unknown) {
alert((e as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Action failed')
diff --git a/whm/src/pages/Backup.tsx b/nixserver/src/pages/Backup.tsx
similarity index 93%
rename from whm/src/pages/Backup.tsx
rename to nixserver/src/pages/Backup.tsx
index d016bd7..bc12af5 100644
--- a/whm/src/pages/Backup.tsx
+++ b/nixserver/src/pages/Backup.tsx
@@ -16,7 +16,7 @@ export default function Backup() {
const fetch = async () => {
setLoading(true)
try {
- const [b, a] = await Promise.all([api.get('/whm/backup/list'), api.get('/whm/accounts?limit=100')])
+ const [b, a] = await Promise.all([api.get('/nixserver/backup/list'), api.get('/nixserver/accounts?limit=100')])
setBackups(b.data.data)
setAccounts(a.data.data.items)
} finally { setLoading(false) }
@@ -27,7 +27,7 @@ export default function Backup() {
const backupAccount = async () => {
if (!selectedAccount) return alert('Select an account')
setBacking(true)
- try { await api.post(`/whm/backup/account/${selectedAccount}`); fetch() }
+ try { await api.post(`/nixserver/backup/account/${selectedAccount}`); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Backup failed') }
finally { setBacking(false) }
}
@@ -35,14 +35,14 @@ export default function Backup() {
const backupServer = async () => {
if (!confirm('Start a full server backup? This may take a while.')) return
setBacking(true)
- try { await api.post('/whm/backup/server'); fetch() }
+ try { await api.post('/nixserver/backup/server'); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Backup failed') }
finally { setBacking(false) }
}
const del = async (path: string) => {
if (!confirm('Delete this backup?')) return
- try { await api.delete('/whm/backup', { data: { path } }); fetch() }
+ try { await api.delete('/nixserver/backup', { data: { path } }); fetch() }
catch {}
}
diff --git a/whm/src/pages/CreateAccount.tsx b/nixserver/src/pages/CreateAccount.tsx
similarity index 93%
rename from whm/src/pages/CreateAccount.tsx
rename to nixserver/src/pages/CreateAccount.tsx
index df361c1..7388cea 100644
--- a/whm/src/pages/CreateAccount.tsx
+++ b/nixserver/src/pages/CreateAccount.tsx
@@ -15,7 +15,7 @@ export default function CreateAccount() {
})
useEffect(() => {
- api.get('/whm/packages').then(r => setPackages(r.data.data)).catch(() => {})
+ api.get('/nixserver/packages').then(r => setPackages(r.data.data)).catch(() => {})
}, [])
const set = (k: keyof typeof form) => (e: React.ChangeEvent) =>
@@ -26,7 +26,7 @@ export default function CreateAccount() {
setError('')
setLoading(true)
try {
- await api.post('/whm/accounts', {
+ await api.post('/nixserver/accounts', {
...form,
packageId: form.packageId ? parseInt(form.packageId, 10) : undefined,
})
@@ -56,7 +56,7 @@ export default function CreateAccount() {
{ key: 'username', label: 'Username', type: 'text', placeholder: 'john', hint: 'Lowercase letters, numbers, hyphens' },
{ key: 'domain', label: 'Primary Domain', type: 'text', placeholder: 'example.com' },
{ key: 'email', label: 'Contact Email', type: 'email', placeholder: 'john@example.com' },
- { key: 'password', label: 'cPanel Password', type: 'password', placeholder: '••••••••', hint: 'Min 8 characters' },
+ { key: 'password', label: 'NixClient Password', type: 'password', placeholder: '••••••••', hint: 'Min 8 characters' },
].map(({ key, label, type, placeholder, hint }) => (
diff --git a/whm/src/pages/DNS.tsx b/nixserver/src/pages/DNS.tsx
similarity index 94%
rename from whm/src/pages/DNS.tsx
rename to nixserver/src/pages/DNS.tsx
index ed3169f..a60e7bb 100644
--- a/whm/src/pages/DNS.tsx
+++ b/nixserver/src/pages/DNS.tsx
@@ -16,13 +16,13 @@ export default function DNS() {
const fetchZones = async () => {
setLoading(true)
- try { const r = await api.get('/whm/dns'); setZones(r.data.data) }
+ try { const r = await api.get('/nixserver/dns'); setZones(r.data.data) }
finally { setLoading(false) }
}
const loadZone = async (zone: Zone) => {
setSelected(zone)
- const r = await api.get(`/whm/dns/${zone.id}`)
+ const r = await api.get(`/nixserver/dns/${zone.id}`)
setRecords(r.data.data.records ?? [])
}
@@ -32,7 +32,7 @@ export default function DNS() {
e.preventDefault(); if (!selected) return
setSaving(true)
try {
- await api.post(`/whm/dns/${selected.id}/records`, { ...form, priority: form.priority ? parseInt(form.priority, 10) : undefined })
+ await api.post(`/nixserver/dns/${selected.id}/records`, { ...form, priority: form.priority ? parseInt(form.priority, 10) : undefined })
setShowForm(false)
loadZone(selected)
} catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
@@ -41,7 +41,7 @@ export default function DNS() {
const deleteRecord = async (recordId: number) => {
if (!selected || !confirm('Delete this DNS record?')) return
- try { await api.delete(`/whm/dns/${selected.id}/records/${recordId}`); loadZone(selected) }
+ try { await api.delete(`/nixserver/dns/${selected.id}/records/${recordId}`); loadZone(selected) }
catch {}
}
diff --git a/whm/src/pages/Dashboard.tsx b/nixserver/src/pages/Dashboard.tsx
similarity index 97%
rename from whm/src/pages/Dashboard.tsx
rename to nixserver/src/pages/Dashboard.tsx
index a699ce8..4e2a655 100644
--- a/whm/src/pages/Dashboard.tsx
+++ b/nixserver/src/pages/Dashboard.tsx
@@ -38,8 +38,8 @@ export default function Dashboard() {
const wsRef = useRef
(null)
useEffect(() => {
- api.get('/whm/accounts/stats').then(r => setAccountStats(r.data.data)).catch(() => {})
- api.get('/whm/system/stats').then(r => setStats(r.data.data)).catch(() => {})
+ api.get('/nixserver/accounts/stats').then(r => setAccountStats(r.data.data)).catch(() => {})
+ api.get('/nixserver/system/stats').then(r => setStats(r.data.data)).catch(() => {})
// WebSocket live stats
const token = localStorage.getItem('access_token')
diff --git a/whm/src/pages/Email.tsx b/nixserver/src/pages/Email.tsx
similarity index 95%
rename from whm/src/pages/Email.tsx
rename to nixserver/src/pages/Email.tsx
index dff6342..6a48332 100644
--- a/whm/src/pages/Email.tsx
+++ b/nixserver/src/pages/Email.tsx
@@ -16,7 +16,7 @@ export default function Email() {
const fetch = async () => {
setLoading(true)
try {
- const [em, acc] = await Promise.all([api.get('/whm/email'), api.get('/whm/accounts?limit=100')])
+ const [em, acc] = await Promise.all([api.get('/nixserver/email'), api.get('/nixserver/accounts?limit=100')])
setAccounts(em.data.data)
setHosting(acc.data.data.items)
} finally { setLoading(false) }
@@ -27,7 +27,7 @@ export default function Email() {
const save = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
try {
- await api.post('/whm/email', { ...form, accountId: parseInt(form.accountId, 10), quotaMb: form.quotaMb })
+ await api.post('/nixserver/email', { ...form, accountId: parseInt(form.accountId, 10), quotaMb: form.quotaMb })
setShowModal(false); fetch()
} catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
@@ -35,7 +35,7 @@ export default function Email() {
const del = async (id: number, address: string) => {
if (!confirm(`Delete ${address}?`)) return
- try { await api.delete(`/whm/email/${id}`); fetch() }
+ try { await api.delete(`/nixserver/email/${id}`); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
}
diff --git a/whm/src/pages/Login.tsx b/nixserver/src/pages/Login.tsx
similarity index 96%
rename from whm/src/pages/Login.tsx
rename to nixserver/src/pages/Login.tsx
index 0b561bd..d5cf668 100644
--- a/whm/src/pages/Login.tsx
+++ b/nixserver/src/pages/Login.tsx
@@ -34,7 +34,7 @@ export default function Login() {
- NixPanel WHM
+ NixServer
Web Host Manager
@@ -81,7 +81,7 @@ export default function Login() {
- NixPanel v0.1.0 · WHM Port 2087
+ NixServer v0.2.0 · Port 2087
diff --git a/whm/src/pages/PHP.tsx b/nixserver/src/pages/PHP.tsx
similarity index 95%
rename from whm/src/pages/PHP.tsx
rename to nixserver/src/pages/PHP.tsx
index 335cbeb..6167b26 100644
--- a/whm/src/pages/PHP.tsx
+++ b/nixserver/src/pages/PHP.tsx
@@ -13,7 +13,7 @@ export default function PHP() {
const fetch = async () => {
setLoading(true)
try {
- const [v, a] = await Promise.all([api.get('/whm/php/versions'), api.get('/whm/php/accounts')])
+ const [v, a] = await Promise.all([api.get('/nixserver/php/versions'), api.get('/nixserver/php/accounts')])
setVersions(v.data.data)
setAccounts(a.data.data)
} finally { setLoading(false) }
@@ -23,7 +23,7 @@ export default function PHP() {
const changeVersion = async (accountId: number, phpVersion: string) => {
try {
- await api.put(`/whm/php/accounts/${accountId}`, { phpVersion })
+ await api.put(`/nixserver/php/accounts/${accountId}`, { phpVersion })
fetch()
} catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
}
diff --git a/whm/src/pages/Packages.tsx b/nixserver/src/pages/Packages.tsx
similarity index 96%
rename from whm/src/pages/Packages.tsx
rename to nixserver/src/pages/Packages.tsx
index b2aaed3..0e601d6 100644
--- a/whm/src/pages/Packages.tsx
+++ b/nixserver/src/pages/Packages.tsx
@@ -27,7 +27,7 @@ export default function Packages() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/whm/packages'); setPackages(r.data.data) }
+ try { const r = await api.get('/nixserver/packages'); setPackages(r.data.data) }
finally { setLoading(false) }
}
@@ -44,8 +44,8 @@ export default function Packages() {
const save = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
try {
- if (editing) await api.put(`/whm/packages/${editing.id}`, form)
- else await api.post('/whm/packages', form)
+ if (editing) await api.put(`/nixserver/packages/${editing.id}`, form)
+ else await api.post('/nixserver/packages', form)
setShowModal(false); fetch()
} catch (err: unknown) {
setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Save failed')
@@ -54,7 +54,7 @@ export default function Packages() {
const del = async (p: Package) => {
if (!confirm(`Delete package "${p.name}"?`)) return
- try { await api.delete(`/whm/packages/${p.id}`); fetch() }
+ try { await api.delete(`/nixserver/packages/${p.id}`); fetch() }
catch (err: unknown) {
alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Delete failed')
}
diff --git a/whm/src/pages/Resellers.tsx b/nixserver/src/pages/Resellers.tsx
similarity index 94%
rename from whm/src/pages/Resellers.tsx
rename to nixserver/src/pages/Resellers.tsx
index c72b1de..38733e2 100644
--- a/whm/src/pages/Resellers.tsx
+++ b/nixserver/src/pages/Resellers.tsx
@@ -17,7 +17,7 @@ export default function Resellers() {
setLoading(true)
try {
const params = search ? `?search=${encodeURIComponent(search)}` : ''
- const r = await api.get(`/whm/resellers${params}`)
+ const r = await api.get(`/nixserver/resellers${params}`)
setItems(r.data.data.items ?? r.data.data)
} finally { setLoading(false) }
}, [search])
@@ -26,7 +26,7 @@ export default function Resellers() {
const save = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
- try { await api.post('/whm/resellers', form); setShowModal(false); fetch() }
+ try { await api.post('/nixserver/resellers', form); setShowModal(false); fetch() }
catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
}
@@ -34,9 +34,9 @@ export default function Resellers() {
const act = async (id: number, action: 'suspend' | 'unsuspend' | 'delete') => {
if (action === 'delete' && !confirm('Delete this reseller?')) return
try {
- if (action === 'suspend') await api.post(`/whm/resellers/${id}/suspend`)
- else if (action === 'unsuspend') await api.post(`/whm/resellers/${id}/unsuspend`)
- else await api.delete(`/whm/resellers/${id}`)
+ if (action === 'suspend') await api.post(`/nixserver/resellers/${id}/suspend`)
+ else if (action === 'unsuspend') await api.post(`/nixserver/resellers/${id}/unsuspend`)
+ else await api.delete(`/nixserver/resellers/${id}`)
fetch()
} catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
}
diff --git a/whm/src/pages/SSL.tsx b/nixserver/src/pages/SSL.tsx
similarity index 95%
rename from whm/src/pages/SSL.tsx
rename to nixserver/src/pages/SSL.tsx
index b66c6b6..83a8b5e 100644
--- a/whm/src/pages/SSL.tsx
+++ b/nixserver/src/pages/SSL.tsx
@@ -23,7 +23,7 @@ export default function SSL() {
const fetch = async () => {
setLoading(true)
try {
- const [sl, acc] = await Promise.all([api.get('/whm/ssl'), api.get('/whm/accounts?limit=100')])
+ const [sl, acc] = await Promise.all([api.get('/nixserver/ssl'), api.get('/nixserver/accounts?limit=100')])
setCerts(sl.data.data)
setHosting(acc.data.data.items)
} finally { setLoading(false) }
@@ -34,20 +34,20 @@ export default function SSL() {
const issue = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true); setError('')
try {
- await api.post('/whm/ssl/issue', { ...form, accountId: parseInt(form.accountId, 10) })
+ await api.post('/nixserver/ssl/issue', { ...form, accountId: parseInt(form.accountId, 10) })
setShowModal(false); fetch()
} catch (err: unknown) { setError((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setSaving(false) }
}
const renew = async (id: number) => {
- try { await api.post(`/whm/ssl/${id}/renew`); fetch() }
+ try { await api.post(`/nixserver/ssl/${id}/renew`); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Renewal failed') }
}
const revoke = async (id: number) => {
if (!confirm('Revoke this certificate?')) return
- try { await api.post(`/whm/ssl/${id}/revoke`); fetch() }
+ try { await api.post(`/nixserver/ssl/${id}/revoke`); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Revoke failed') }
}
diff --git a/whm/src/pages/Security.tsx b/nixserver/src/pages/Security.tsx
similarity index 93%
rename from whm/src/pages/Security.tsx
rename to nixserver/src/pages/Security.tsx
index c34c18c..d8e62c1 100644
--- a/whm/src/pages/Security.tsx
+++ b/nixserver/src/pages/Security.tsx
@@ -22,8 +22,8 @@ export default function Security() {
setLoading(true)
try {
const [b, e] = await Promise.all([
- api.get('/whm/security/blocked-ips'),
- api.get('/whm/security/events'),
+ api.get('/nixserver/security/blocked-ips'),
+ api.get('/nixserver/security/events'),
])
setBlocked(b.data.data)
setEvents(e.data.data.items ?? e.data.data)
@@ -34,17 +34,17 @@ export default function Security() {
const block = async (e: React.FormEvent) => {
e.preventDefault()
- try { await api.post('/whm/security/blocked-ips', { ip: newIp, reason }); setNewIp(''); setReason(''); fetch() }
+ try { await api.post('/nixserver/security/blocked-ips', { ip: newIp, reason }); setNewIp(''); setReason(''); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
}
const unblock = async (id: number) => {
- try { await api.delete(`/whm/security/blocked-ips/${id}`); fetch() }
+ try { await api.delete(`/nixserver/security/blocked-ips/${id}`); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
}
const resolve = async (id: number) => {
- try { await api.post(`/whm/security/events/${id}/resolve`); fetch() }
+ try { await api.post(`/nixserver/security/events/${id}/resolve`); fetch() }
catch {}
}
diff --git a/whm/src/pages/Services.tsx b/nixserver/src/pages/Services.tsx
similarity index 96%
rename from whm/src/pages/Services.tsx
rename to nixserver/src/pages/Services.tsx
index 012f0f6..80f0e1f 100644
--- a/whm/src/pages/Services.tsx
+++ b/nixserver/src/pages/Services.tsx
@@ -18,7 +18,7 @@ export default function Services() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/whm/services'); setServices(r.data.data) }
+ try { const r = await api.get('/nixserver/services'); setServices(r.data.data) }
finally { setLoading(false) }
}
@@ -26,7 +26,7 @@ export default function Services() {
const act = async (name: string, action: string) => {
setActing(name + action)
- try { await api.post(`/whm/services/${name}`, { action }); fetch() }
+ try { await api.post(`/nixserver/services/${name}`, { action }); fetch() }
catch (e: unknown) { alert((e as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed') }
finally { setActing(null) }
}
diff --git a/whm/src/pages/Settings.tsx b/nixserver/src/pages/Settings.tsx
similarity index 90%
rename from whm/src/pages/Settings.tsx
rename to nixserver/src/pages/Settings.tsx
index bb375ce..931f78a 100644
--- a/whm/src/pages/Settings.tsx
+++ b/nixserver/src/pages/Settings.tsx
@@ -10,7 +10,7 @@ export default function Settings() {
const fetch = async () => {
setLoading(true)
- try { const r = await api.get('/whm/system/settings'); setSettings(r.data.data) }
+ try { const r = await api.get('/nixserver/system/settings'); setSettings(r.data.data) }
finally { setLoading(false) }
}
@@ -18,7 +18,7 @@ export default function Settings() {
const save = async (e: React.FormEvent) => {
e.preventDefault(); setSaving(true)
- try { await api.put('/whm/system/settings', settings); setSaved(true); setTimeout(() => setSaved(false), 2000) }
+ try { await api.put('/nixserver/system/settings', settings); setSaved(true); setTimeout(() => setSaved(false), 2000) }
finally { setSaving(false) }
}
diff --git a/whm/src/pages/System.tsx b/nixserver/src/pages/System.tsx
similarity index 96%
rename from whm/src/pages/System.tsx
rename to nixserver/src/pages/System.tsx
index d5a2aa2..c3f573a 100644
--- a/whm/src/pages/System.tsx
+++ b/nixserver/src/pages/System.tsx
@@ -14,8 +14,8 @@ export default function System() {
setLoading(true)
try {
const [infoR, procR] = await Promise.all([
- api.get('/whm/system/info'),
- api.get('/whm/system/processes'),
+ api.get('/nixserver/system/info'),
+ api.get('/nixserver/system/processes'),
])
setInfo(infoR.data.data)
setProcesses(procR.data.data)
diff --git a/whm/src/pages/WebServer.tsx b/nixserver/src/pages/WebServer.tsx
similarity index 92%
rename from whm/src/pages/WebServer.tsx
rename to nixserver/src/pages/WebServer.tsx
index 10e8bdf..bfe0522 100644
--- a/whm/src/pages/WebServer.tsx
+++ b/nixserver/src/pages/WebServer.tsx
@@ -14,9 +14,9 @@ export default function WebServer() {
setLoading(true)
try {
const [s, v, l] = await Promise.all([
- api.get('/whm/webserver/status'),
- api.get('/whm/webserver/vhosts'),
- api.get(`/whm/webserver/logs/${logType}`),
+ api.get('/nixserver/webserver/status'),
+ api.get('/nixserver/webserver/vhosts'),
+ api.get(`/nixserver/webserver/logs/${logType}`),
])
setStatus(s.data.data); setVhosts(v.data.data); setLogs(l.data.data)
} finally { setLoading(false) }
@@ -25,12 +25,12 @@ export default function WebServer() {
useEffect(() => { fetch() }, [logType])
const testConfig = async () => {
- const r = await api.post('/whm/webserver/nginx/test')
+ const r = await api.post('/nixserver/webserver/nginx/test')
setTestResult(r.data.data.output)
}
const reload = async () => {
- try { await api.post('/whm/webserver/nginx/reload'); fetch() }
+ try { await api.post('/nixserver/webserver/nginx/reload'); fetch() }
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Reload failed') }
}
diff --git a/whm/tailwind.config.js b/nixserver/tailwind.config.js
similarity index 100%
rename from whm/tailwind.config.js
rename to nixserver/tailwind.config.js
diff --git a/whm/tsconfig.json b/nixserver/tsconfig.json
similarity index 100%
rename from whm/tsconfig.json
rename to nixserver/tsconfig.json
diff --git a/whm/tsconfig.node.json b/nixserver/tsconfig.node.json
similarity index 100%
rename from whm/tsconfig.node.json
rename to nixserver/tsconfig.node.json
diff --git a/whm/vite.config.ts b/nixserver/vite.config.ts
similarity index 100%
rename from whm/vite.config.ts
rename to nixserver/vite.config.ts
diff --git a/package.json b/package.json
index 3542b06..0b3497c 100644
--- a/package.json
+++ b/package.json
@@ -1,18 +1,18 @@
{
"name": "nixpanel-server",
- "version": "0.1.0",
+ "version": "0.2.0",
"private": true,
"workspaces": [
"server",
- "whm",
- "cpanel"
+ "nixserver",
+ "nixclient"
],
"scripts": {
- "dev": "concurrently \"npm run dev --workspace=server\" \"npm run dev --workspace=whm\" \"npm run dev --workspace=cpanel\"",
+ "dev": "concurrently \"npm run dev --workspace=server\" \"npm run dev --workspace=nixserver\" \"npm run dev --workspace=nixclient\"",
"dev:server": "npm run dev --workspace=server",
- "dev:whm": "npm run dev --workspace=whm",
- "dev:cpanel": "npm run dev --workspace=cpanel",
- "build": "npm run build --workspace=server && npm run build --workspace=whm && npm run build --workspace=cpanel",
+ "dev:nixserver": "npm run dev --workspace=nixserver",
+ "dev:nixclient": "npm run dev --workspace=nixclient",
+ "build": "npm run build --workspace=server && npm run build --workspace=nixserver && npm run build --workspace=nixclient",
"db:migrate": "npm run db:migrate --workspace=server",
"db:studio": "npm run db:studio --workspace=server"
},
diff --git a/scripts/install.sh b/scripts/install.sh
index 9d97504..ecb09ea 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -30,8 +30,8 @@ EOF
echo -e "${RESET}"
echo -e " Version : ${BOLD}0.1.0${RESET}"
echo -e " GitHub : ${BOLD}https://github.com/NixReaper/nixpanel-server${RESET}"
-echo -e " WHM : ${BOLD}https://:2087${RESET}"
-echo -e " cPanel : ${BOLD}https://:2083${RESET}"
+echo -e " NixServer: ${BOLD}https://:2087${RESET}"
+echo -e " NixClient: ${BOLD}https://:2083${RESET}"
echo ""
# ── Root check ────────────────────────────────────────────────────────────────
@@ -341,8 +341,8 @@ JWT_REFRESH_EXPIRES_IN="7d"
# Server
NODE_ENV="production"
-WHM_PORT=2087
-CPANEL_PORT=2083
+NIXSERVER_PORT=2087
+NIXCLIENT_PORT=2083
HOST="0.0.0.0"
# Admin credentials (used during initial seed only)
@@ -398,11 +398,11 @@ ADMIN_EMAIL="${ADMIN_EMAIL}" \
success "Default admin, packages, and settings seeded"
# ── Build frontends ───────────────────────────────────────────────────────────
-step "Building WHM + cPanel frontends"
+step "Building NixServer + NixClient frontends"
cd "$INSTALL_DIR"
-npm run build --workspace=whm --silent
-npm run build --workspace=cpanel --silent
+npm run build --workspace=nixserver --silent
+npm run build --workspace=nixclient --silent
success "Frontends built"
# ── systemd service ───────────────────────────────────────────────────────────
@@ -453,13 +453,13 @@ fi
cat > /etc/nginx/sites-available/nixpanel.conf </dev/null
ufw allow 80/tcp comment "HTTP" >/dev/null
ufw allow 443/tcp comment "HTTPS" >/dev/null
- ufw allow 2087/tcp comment "WHM" >/dev/null
- ufw allow 2083/tcp comment "cPanel" >/dev/null
+ ufw allow 2087/tcp comment "NixServer" >/dev/null
+ ufw allow 2083/tcp comment "NixClient" >/dev/null
ufw allow 21/tcp comment "FTP" >/dev/null
ufw allow 25/tcp comment "SMTP" >/dev/null
ufw allow 143/tcp comment "IMAP" >/dev/null
@@ -637,12 +637,12 @@ echo -e "${BOLD}${GREEN}╔═════════════════
echo -e "${BOLD}${GREEN}║ NixPanel Installation Complete! ║${RESET}"
echo -e "${BOLD}${GREEN}╚══════════════════════════════════════════════════════╝${RESET}"
echo ""
-echo -e " ${BOLD}WHM (Admin Panel)${RESET}"
+echo -e " ${BOLD}NixServer (Admin Panel)${RESET}"
echo -e " URL : ${CYAN}http://${SERVER_IP}:2087${RESET}"
echo -e " Username : ${BOLD}${ADMIN_USER}${RESET}"
echo -e " Password : ${BOLD}${ADMIN_PASS}${RESET}"
echo ""
-echo -e " ${BOLD}cPanel (User Panel)${RESET}"
+echo -e " ${BOLD}NixClient (User Panel)${RESET}"
echo -e " URL : ${CYAN}http://${SERVER_IP}:2083${RESET}"
echo ""
echo -e " ${BOLD}Database${RESET}"
@@ -671,8 +671,8 @@ CRED_FILE="/root/.nixpanel_credentials"
cat > "$CRED_FILE" < ({
status: 'ok',
- version: '0.1.0',
+ version: '0.2.0',
timestamp: new Date().toISOString(),
}))
diff --git a/server/src/config.ts b/server/src/config.ts
index 5fb2626..18a6108 100644
--- a/server/src/config.ts
+++ b/server/src/config.ts
@@ -16,8 +16,8 @@ export const config = {
server: {
host: optional('HOST', '0.0.0.0'),
- whmPort: parseInt(optional('WHM_PORT', '2087'), 10),
- cpanelPort: parseInt(optional('CPANEL_PORT', '2083'), 10),
+ nixserverPort: parseInt(optional('NIXSERVER_PORT', '2087'), 10),
+ nixclientPort: parseInt(optional('NIXCLIENT_PORT', '2083'), 10),
},
db: {
diff --git a/server/src/core/dns.ts b/server/src/core/dns.ts
index 4146346..dca4593 100644
--- a/server/src/core/dns.ts
+++ b/server/src/core/dns.ts
@@ -45,7 +45,7 @@ $TTL ${ttl}
www IN A ${ip}
mail IN A ${ip}
ftp IN A ${ip}
-cpanel IN A ${ip}
+nixclient IN A ${ip}
webmail IN A ${ip}
; MX record
diff --git a/server/src/index.ts b/server/src/index.ts
index dd0f494..90c4356 100644
--- a/server/src/index.ts
+++ b/server/src/index.ts
@@ -13,10 +13,10 @@ async function start() {
app = await buildApp()
- // WHM server on port 2087
- await app.listen({ port: config.server.whmPort, host: config.server.host })
- console.log(`NixPanel WHM running on port ${config.server.whmPort}`)
- console.log(`NixPanel cPanel API running on port ${config.server.whmPort} (/api/cpanel)`)
+ // NixServer on port 2087
+ await app.listen({ port: config.server.nixserverPort, host: config.server.host })
+ console.log(`NixServer running on port ${config.server.nixserverPort}`)
+ console.log(`NixClient API running on port ${config.server.nixserverPort} (/api/cpanel)`)
} catch (err) {
console.error('Failed to start server:', err)
diff --git a/server/src/routes/auth/index.ts b/server/src/routes/auth/index.ts
index ced31a6..048e2e0 100644
--- a/server/src/routes/auth/index.ts
+++ b/server/src/routes/auth/index.ts
@@ -37,7 +37,7 @@ function signTokens(
export default async function authRoutes(fastify: FastifyInstance) {
/**
* POST /api/auth/login
- * Login for admin, reseller, or cPanel user.
+ * Login for admin, reseller, or NixClient user.
* Body: { username, password }
* Returns: { accessToken, refreshToken, role, user }
*/
@@ -111,7 +111,7 @@ export default async function authRoutes(fastify: FastifyInstance) {
})
}
- // Try hosting account (cPanel user)
+ // Try hosting account (NixClient user)
const account = await prisma.account.findUnique({ where: { username } })
if (account) {
if (account.status !== 'active') {
diff --git a/server/src/routes/cpanel/cron.ts b/server/src/routes/nixclient/cron.ts
similarity index 100%
rename from server/src/routes/cpanel/cron.ts
rename to server/src/routes/nixclient/cron.ts
diff --git a/server/src/routes/cpanel/databases.ts b/server/src/routes/nixclient/databases.ts
similarity index 96%
rename from server/src/routes/cpanel/databases.ts
rename to server/src/routes/nixclient/databases.ts
index 0ca0a00..422083a 100644
--- a/server/src/routes/cpanel/databases.ts
+++ b/server/src/routes/nixclient/databases.ts
@@ -12,7 +12,7 @@ function mysqlEscape(s: string): string {
export default async function databaseRoutes(fastify: FastifyInstance) {
const preHandler = [requireAuth]
- // GET /api/cpanel/databases
+ // GET /api/nixclient/databases
fastify.get('/', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : parseInt((request.query as Record).accountId ?? '0', 10)
@@ -25,7 +25,7 @@ export default async function databaseRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: databases })
})
- // POST /api/cpanel/databases
+ // POST /api/nixclient/databases
fastify.post('/', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : parseInt((request.body as Record).accountId ?? '0', 10)
@@ -74,7 +74,7 @@ export default async function databaseRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: db })
})
- // DELETE /api/cpanel/databases/:id
+ // DELETE /api/nixclient/databases/:id
fastify.delete('/:id', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const user = request.user!
@@ -93,7 +93,7 @@ export default async function databaseRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: `Database ${db.name} deleted` } })
})
- // POST /api/cpanel/databases/:id/users
+ // POST /api/nixclient/databases/:id/users
fastify.post('/:id/users', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const user = request.user!
@@ -139,7 +139,7 @@ export default async function databaseRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: safe })
})
- // DELETE /api/cpanel/databases/:id/users/:userId
+ // DELETE /api/nixclient/databases/:id/users/:userId
fastify.delete('/:id/users/:userId', { preHandler }, async (request, reply) => {
const { id, userId } = request.params as { id: string; userId: string }
diff --git a/server/src/routes/cpanel/domains.ts b/server/src/routes/nixclient/domains.ts
similarity index 100%
rename from server/src/routes/cpanel/domains.ts
rename to server/src/routes/nixclient/domains.ts
diff --git a/server/src/routes/cpanel/email.ts b/server/src/routes/nixclient/email.ts
similarity index 95%
rename from server/src/routes/cpanel/email.ts
rename to server/src/routes/nixclient/email.ts
index 4385127..ce03d5d 100644
--- a/server/src/routes/cpanel/email.ts
+++ b/server/src/routes/nixclient/email.ts
@@ -8,7 +8,7 @@ import { exec } from '../../core/exec.js'
export default async function cpanelEmailRoutes(fastify: FastifyInstance) {
const preHandler = [requireAuth]
- // GET /api/cpanel/email
+ // GET /api/nixclient/email
fastify.get('/', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : parseInt((request.query as Record).accountId ?? '0', 10)
@@ -21,7 +21,7 @@ export default async function cpanelEmailRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: accounts })
})
- // POST /api/cpanel/email
+ // POST /api/nixclient/email
fastify.post('/', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : (request.body as Record).accountId as number
@@ -62,7 +62,7 @@ export default async function cpanelEmailRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: safe })
})
- // DELETE /api/cpanel/email/:id
+ // DELETE /api/nixclient/email/:id
fastify.delete('/:id', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : 0
@@ -80,7 +80,7 @@ export default async function cpanelEmailRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Email account deleted' } })
})
- // GET /api/cpanel/email/forwarders
+ // GET /api/nixclient/email/forwarders
fastify.get('/forwarders', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : parseInt((request.query as Record).accountId ?? '0', 10)
@@ -89,7 +89,7 @@ export default async function cpanelEmailRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: forwarders })
})
- // POST /api/cpanel/email/forwarders
+ // POST /api/nixclient/email/forwarders
fastify.post('/forwarders', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : (request.body as Record).accountId as number
@@ -107,7 +107,7 @@ export default async function cpanelEmailRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: forwarder })
})
- // DELETE /api/cpanel/email/forwarders/:id
+ // DELETE /api/nixclient/email/forwarders/:id
fastify.delete('/forwarders/:id', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : 0
diff --git a/server/src/routes/cpanel/files.ts b/server/src/routes/nixclient/files.ts
similarity index 92%
rename from server/src/routes/cpanel/files.ts
rename to server/src/routes/nixclient/files.ts
index e1298c8..243d8fc 100644
--- a/server/src/routes/cpanel/files.ts
+++ b/server/src/routes/nixclient/files.ts
@@ -26,10 +26,10 @@ async function getAccount(fastify: FastifyInstance, userId: number) {
export default async function fileRoutes(fastify: FastifyInstance) {
const preHandler = [requireAuth]
- // GET /api/cpanel/files?path=
+ // GET /api/nixclient/files?path=
fastify.get('/', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
@@ -73,10 +73,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { path: userPath, files } })
})
- // GET /api/cpanel/files/content?path=
+ // GET /api/nixclient/files/content?path=
fastify.get('/content', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
@@ -102,10 +102,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { path: q.path, content } })
})
- // PUT /api/cpanel/files/content — save file content
+ // PUT /api/nixclient/files/content — save file content
fastify.put('/content', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
@@ -133,10 +133,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'File saved' } })
})
- // POST /api/cpanel/files/mkdir
+ // POST /api/nixclient/files/mkdir
fastify.post('/mkdir', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
@@ -157,10 +157,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Directory created' } })
})
- // DELETE /api/cpanel/files
+ // DELETE /api/nixclient/files
fastify.delete('/', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
@@ -189,10 +189,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { deleted, errors } })
})
- // POST /api/cpanel/files/rename
+ // POST /api/nixclient/files/rename
fastify.post('/rename', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
@@ -207,10 +207,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Renamed' } })
})
- // POST /api/cpanel/files/chmod
+ // POST /api/nixclient/files/chmod
fastify.post('/chmod', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
@@ -228,10 +228,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Permissions updated' } })
})
- // POST /api/cpanel/files/compress — zip files
+ // POST /api/nixclient/files/compress — zip files
fastify.post('/compress', { preHandler }, async (request, reply) => {
const user = request.user!
- if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'cPanel users only' })
+ if (user.role !== 'user') return reply.code(403).send({ success: false, error: 'NixClient users only' })
const account = await getAccount(fastify, user.sub)
if (!account) return reply.code(404).send({ success: false, error: 'Account not found' })
diff --git a/server/src/routes/cpanel/ftp.ts b/server/src/routes/nixclient/ftp.ts
similarity index 100%
rename from server/src/routes/cpanel/ftp.ts
rename to server/src/routes/nixclient/ftp.ts
diff --git a/server/src/routes/cpanel/index.ts b/server/src/routes/nixclient/index.ts
similarity index 90%
rename from server/src/routes/cpanel/index.ts
rename to server/src/routes/nixclient/index.ts
index 2175e7c..d1a7a27 100644
--- a/server/src/routes/cpanel/index.ts
+++ b/server/src/routes/nixclient/index.ts
@@ -7,7 +7,7 @@ import ftpRoutes from './ftp.js'
import cronRoutes from './cron.js'
import statsRoutes from './stats.js'
-export default async function cpanelRoutes(fastify: FastifyInstance) {
+export default async function nixclientRoutes(fastify: FastifyInstance) {
fastify.register(fileRoutes, { prefix: '/files' })
fastify.register(databaseRoutes, { prefix: '/databases' })
fastify.register(emailRoutes, { prefix: '/email' })
diff --git a/server/src/routes/cpanel/stats.ts b/server/src/routes/nixclient/stats.ts
similarity index 94%
rename from server/src/routes/cpanel/stats.ts
rename to server/src/routes/nixclient/stats.ts
index 0efd2f3..ae289d3 100644
--- a/server/src/routes/cpanel/stats.ts
+++ b/server/src/routes/nixclient/stats.ts
@@ -6,7 +6,7 @@ import { exec } from '../../core/exec.js'
export default async function statsRoutes(fastify: FastifyInstance) {
const preHandler = [requireAuth]
- // GET /api/cpanel/stats — account resource usage summary
+ // GET /api/nixclient/stats — account resource usage summary
fastify.get('/', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : parseInt((request.query as Record).accountId ?? '0', 10)
@@ -57,7 +57,7 @@ export default async function statsRoutes(fastify: FastifyInstance) {
})
})
- // GET /api/cpanel/stats/bandwidth — bandwidth usage over time (placeholder for log parsing)
+ // GET /api/nixclient/stats/bandwidth — bandwidth usage over time (placeholder for log parsing)
fastify.get('/bandwidth', { preHandler }, async (request, reply) => {
const user = request.user!
const accountId = user.role === 'user' ? user.sub : parseInt((request.query as Record).accountId ?? '0', 10)
diff --git a/server/src/routes/whm/accounts.ts b/server/src/routes/nixserver/accounts.ts
similarity index 97%
rename from server/src/routes/whm/accounts.ts
rename to server/src/routes/nixserver/accounts.ts
index 3075f6f..f7734ed 100644
--- a/server/src/routes/whm/accounts.ts
+++ b/server/src/routes/nixserver/accounts.ts
@@ -28,7 +28,7 @@ const UpdateAccountSchema = z.object({
export default async function accountRoutes(fastify: FastifyInstance) {
const preHandler = [requireAdminOrReseller]
- // GET /api/whm/accounts
+ // GET /api/nixserver/accounts
fastify.get('/', { preHandler }, async (request, reply) => {
const q = request.query as Record
const page = Math.max(1, parseInt(q.page ?? '1', 10))
@@ -69,7 +69,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
})
})
- // GET /api/whm/accounts/stats
+ // GET /api/nixserver/accounts/stats
fastify.get('/stats', { preHandler }, async (request, reply) => {
const where = request.user!.role === 'reseller' ? { resellerId: request.user!.sub } : {}
@@ -83,7 +83,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { total, active, suspended, terminated } })
})
- // GET /api/whm/accounts/:id
+ // GET /api/nixserver/accounts/:id
fastify.get('/:id', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const where: Record = { id: parseInt(id, 10) }
@@ -111,7 +111,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: safe })
})
- // POST /api/whm/accounts
+ // POST /api/nixserver/accounts
fastify.post('/', { preHandler }, async (request, reply) => {
const body = CreateAccountSchema.safeParse(request.body)
if (!body.success) {
@@ -228,7 +228,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: safe })
})
- // PUT /api/whm/accounts/:id
+ // PUT /api/nixserver/accounts/:id
fastify.put('/:id', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const body = UpdateAccountSchema.safeParse(request.body)
@@ -261,7 +261,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: safe })
})
- // POST /api/whm/accounts/:id/suspend
+ // POST /api/nixserver/accounts/:id/suspend
fastify.post('/:id/suspend', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const { reason } = (request.body as Record) ?? {}
@@ -291,7 +291,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: `Account ${account.username} suspended` } })
})
- // POST /api/whm/accounts/:id/unsuspend
+ // POST /api/nixserver/accounts/:id/unsuspend
fastify.post('/:id/unsuspend', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
@@ -319,7 +319,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: `Account ${account.username} unsuspended` } })
})
- // DELETE /api/whm/accounts/:id
+ // DELETE /api/nixserver/accounts/:id
fastify.delete('/:id', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const { removeFiles } = (request.body as Record) ?? {}
@@ -364,7 +364,7 @@ export default async function accountRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: `Account ${account.username} terminated` } })
})
- // POST /api/whm/accounts/bulk
+ // POST /api/nixserver/accounts/bulk
fastify.post('/bulk', { preHandler }, async (request, reply) => {
const body = z.object({
action: z.enum(['suspend', 'unsuspend', 'terminate']),
diff --git a/server/src/routes/whm/backup.ts b/server/src/routes/nixserver/backup.ts
similarity index 93%
rename from server/src/routes/whm/backup.ts
rename to server/src/routes/nixserver/backup.ts
index 9fc1d86..dc44c38 100644
--- a/server/src/routes/whm/backup.ts
+++ b/server/src/routes/nixserver/backup.ts
@@ -9,7 +9,7 @@ import { config } from '../../config.js'
const BACKUP_DIR = '/var/nixpanel/backups'
export default async function backupRoutes(fastify: FastifyInstance) {
- // POST /api/whm/backup/account/:id — backup a single account
+ // POST /api/nixserver/backup/account/:id — backup a single account
fastify.post('/account/:id', { preHandler: [requireAdmin] }, async (request, reply) => {
const { id } = request.params as { id: string }
const account = await prisma.account.findUnique({ where: { id: parseInt(id, 10) } })
@@ -39,7 +39,7 @@ export default async function backupRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { filename, path: dest, size, createdAt: new Date() } })
})
- // POST /api/whm/backup/server — full server backup
+ // POST /api/nixserver/backup/server — full server backup
fastify.post('/server', { preHandler: [requireAdmin] }, async (request, reply) => {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
const filename = `server-backup-${timestamp}.tar.gz`
@@ -61,7 +61,7 @@ export default async function backupRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { filename, path: dest, createdAt: new Date() } })
})
- // GET /api/whm/backup/list — list available backups
+ // GET /api/nixserver/backup/list — list available backups
fastify.get('/list', { preHandler: [requireAdmin] }, async (request, reply) => {
const result = await exec('find', [BACKUP_DIR, '-name', '*.tar.gz', '-printf', '%p %s %T@\n'])
if (result.exitCode !== 0 && !result.stdout) {
@@ -81,7 +81,7 @@ export default async function backupRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: backups })
})
- // DELETE /api/whm/backup — delete a backup file
+ // DELETE /api/nixserver/backup — delete a backup file
fastify.delete('/', { preHandler: [requireAdmin] }, async (request, reply) => {
const body = z.object({ path: z.string() }).safeParse(request.body)
if (!body.success) {
@@ -96,7 +96,7 @@ export default async function backupRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Backup deleted' } })
})
- // POST /api/whm/backup/restore/:filename
+ // POST /api/nixserver/backup/restore/:filename
fastify.post('/restore/:filename', { preHandler: [requireAdmin] }, async (request, reply) => {
const { filename } = request.params as { filename: string }
// Sanitize — no path traversal
diff --git a/server/src/routes/whm/dns.ts b/server/src/routes/nixserver/dns.ts
similarity index 95%
rename from server/src/routes/whm/dns.ts
rename to server/src/routes/nixserver/dns.ts
index eeb482d..3ed02fd 100644
--- a/server/src/routes/whm/dns.ts
+++ b/server/src/routes/nixserver/dns.ts
@@ -16,7 +16,7 @@ const DnsRecordSchema = z.object({
export default async function dnsRoutes(fastify: FastifyInstance) {
const preHandler = [requireAdminOrReseller]
- // GET /api/whm/dns
+ // GET /api/nixserver/dns
fastify.get('/', { preHandler }, async (request, reply) => {
const q = request.query as Record
const where: Record = {}
@@ -34,7 +34,7 @@ export default async function dnsRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: zones })
})
- // GET /api/whm/dns/:id
+ // GET /api/nixserver/dns/:id
fastify.get('/:id', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const zone = await prisma.dnsZone.findUnique({
@@ -48,7 +48,7 @@ export default async function dnsRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: zone })
})
- // POST /api/whm/dns/:id/records
+ // POST /api/nixserver/dns/:id/records
fastify.post('/:id/records', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const body = DnsRecordSchema.safeParse(request.body)
@@ -72,7 +72,7 @@ export default async function dnsRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: record })
})
- // PUT /api/whm/dns/:zoneId/records/:recordId
+ // PUT /api/nixserver/dns/:zoneId/records/:recordId
fastify.put('/:zoneId/records/:recordId', { preHandler }, async (request, reply) => {
const { zoneId, recordId } = request.params as { zoneId: string; recordId: string }
const body = DnsRecordSchema.partial().safeParse(request.body)
@@ -95,7 +95,7 @@ export default async function dnsRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: updated })
})
- // DELETE /api/whm/dns/:zoneId/records/:recordId
+ // DELETE /api/nixserver/dns/:zoneId/records/:recordId
fastify.delete('/:zoneId/records/:recordId', { preHandler }, async (request, reply) => {
const { zoneId, recordId } = request.params as { zoneId: string; recordId: string }
@@ -110,7 +110,7 @@ export default async function dnsRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Record deleted' } })
})
- // POST /api/whm/dns/:id/reload
+ // POST /api/nixserver/dns/:id/reload
fastify.post('/:id/reload', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
await rebuildZone(parseInt(id, 10))
diff --git a/server/src/routes/whm/email.ts b/server/src/routes/nixserver/email.ts
similarity index 94%
rename from server/src/routes/whm/email.ts
rename to server/src/routes/nixserver/email.ts
index dbffd62..1df1f50 100644
--- a/server/src/routes/whm/email.ts
+++ b/server/src/routes/nixserver/email.ts
@@ -8,7 +8,7 @@ import { exec } from '../../core/exec.js'
export default async function emailRoutes(fastify: FastifyInstance) {
const preHandler = [requireAdminOrReseller]
- // GET /api/whm/email?accountId=
+ // GET /api/nixserver/email?accountId=
fastify.get('/', { preHandler }, async (request, reply) => {
const q = request.query as Record
const where: Record = {}
@@ -27,7 +27,7 @@ export default async function emailRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: accounts })
})
- // POST /api/whm/email
+ // POST /api/nixserver/email
fastify.post('/', { preHandler }, async (request, reply) => {
const body = z.object({
accountId: z.number().int().positive(),
@@ -81,7 +81,7 @@ export default async function emailRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: safe })
})
- // DELETE /api/whm/email/:id
+ // DELETE /api/nixserver/email/:id
fastify.delete('/:id', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const emailAccount = await prisma.emailAccount.findUnique({ where: { id: parseInt(id, 10) } })
@@ -93,7 +93,7 @@ export default async function emailRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Email account deleted' } })
})
- // POST /api/whm/email/:id/password
+ // POST /api/nixserver/email/:id/password
fastify.post('/:id/password', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const body = z.object({ password: z.string().min(8) }).safeParse(request.body)
@@ -110,7 +110,7 @@ export default async function emailRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Password updated' } })
})
- // GET /api/whm/email/forwarders?accountId=
+ // GET /api/nixserver/email/forwarders?accountId=
fastify.get('/forwarders', { preHandler }, async (request, reply) => {
const q = request.query as Record
const where: Record = {}
@@ -120,7 +120,7 @@ export default async function emailRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: forwarders })
})
- // POST /api/whm/email/forwarders
+ // POST /api/nixserver/email/forwarders
fastify.post('/forwarders', { preHandler }, async (request, reply) => {
const body = z.object({
accountId: z.number().int().positive(),
@@ -136,7 +136,7 @@ export default async function emailRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: forwarder })
})
- // DELETE /api/whm/email/forwarders/:id
+ // DELETE /api/nixserver/email/forwarders/:id
fastify.delete('/forwarders/:id', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
await prisma.emailForwarder.delete({ where: { id: parseInt(id, 10) } })
diff --git a/server/src/routes/whm/index.ts b/server/src/routes/nixserver/index.ts
similarity index 94%
rename from server/src/routes/whm/index.ts
rename to server/src/routes/nixserver/index.ts
index cad6040..48f067e 100644
--- a/server/src/routes/whm/index.ts
+++ b/server/src/routes/nixserver/index.ts
@@ -12,7 +12,7 @@ import securityRoutes from './security.js'
import backupRoutes from './backup.js'
import webserverRoutes from './webserver.js'
-export default async function whmRoutes(fastify: FastifyInstance) {
+export default async function nixserverRoutes(fastify: FastifyInstance) {
fastify.register(accountRoutes, { prefix: '/accounts' })
fastify.register(packageRoutes, { prefix: '/packages' })
fastify.register(resellerRoutes, { prefix: '/resellers' })
diff --git a/server/src/routes/whm/packages.ts b/server/src/routes/nixserver/packages.ts
similarity index 100%
rename from server/src/routes/whm/packages.ts
rename to server/src/routes/nixserver/packages.ts
diff --git a/server/src/routes/whm/php.ts b/server/src/routes/nixserver/php.ts
similarity index 93%
rename from server/src/routes/whm/php.ts
rename to server/src/routes/nixserver/php.ts
index 872e1eb..dc78881 100644
--- a/server/src/routes/whm/php.ts
+++ b/server/src/routes/nixserver/php.ts
@@ -8,7 +8,7 @@ import { writeFile } from '../../core/exec.js'
const SUPPORTED_PHP_VERSIONS = ['7.4', '8.0', '8.1', '8.2', '8.3']
export default async function phpRoutes(fastify: FastifyInstance) {
- // GET /api/whm/php/versions — list installed PHP versions
+ // GET /api/nixserver/php/versions — list installed PHP versions
fastify.get('/versions', { preHandler: [requireAdmin] }, async (request, reply) => {
const versions: { version: string; installed: boolean; active: boolean }[] = []
@@ -21,7 +21,7 @@ export default async function phpRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: versions })
})
- // GET /api/whm/php/accounts — list which PHP version each account uses
+ // GET /api/nixserver/php/accounts — list which PHP version each account uses
fastify.get('/accounts', { preHandler: [requireAdmin] }, async (request, reply) => {
const accounts = await prisma.account.findMany({
where: { status: 'active' },
@@ -33,7 +33,7 @@ export default async function phpRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: accounts })
})
- // PUT /api/whm/php/accounts/:id — change PHP version for account
+ // PUT /api/nixserver/php/accounts/:id — change PHP version for account
fastify.put('/accounts/:id', { preHandler: [requireAdmin] }, async (request, reply) => {
const { id } = request.params as { id: string }
const body = z.object({
@@ -82,7 +82,7 @@ php_admin_value[error_log] = ${account.homedir}/logs/php_errors.log
return reply.send({ success: true, data: { message: `PHP version set to ${body.data.phpVersion}` } })
})
- // GET /api/whm/php/ini/:version — get php.ini settings
+ // GET /api/nixserver/php/ini/:version — get php.ini settings
fastify.get('/ini/:version', { preHandler: [requireAdmin] }, async (request, reply) => {
const { version } = request.params as { version: string }
if (!SUPPORTED_PHP_VERSIONS.includes(version)) {
diff --git a/server/src/routes/whm/resellers.ts b/server/src/routes/nixserver/resellers.ts
similarity index 100%
rename from server/src/routes/whm/resellers.ts
rename to server/src/routes/nixserver/resellers.ts
diff --git a/server/src/routes/whm/security.ts b/server/src/routes/nixserver/security.ts
similarity index 90%
rename from server/src/routes/whm/security.ts
rename to server/src/routes/nixserver/security.ts
index 57d9ff4..a5f95c3 100644
--- a/server/src/routes/whm/security.ts
+++ b/server/src/routes/nixserver/security.ts
@@ -5,7 +5,7 @@ import { requireAdmin } from '../../middleware/auth.js'
import { exec } from '../../core/exec.js'
export default async function securityRoutes(fastify: FastifyInstance) {
- // GET /api/whm/security/events
+ // GET /api/nixserver/security/events
fastify.get('/events', { preHandler: [requireAdmin] }, async (request, reply) => {
const q = request.query as Record
const page = Math.max(1, parseInt(q.page ?? '1', 10))
@@ -25,7 +25,7 @@ export default async function securityRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { items, total, page, limit, totalPages: Math.ceil(total / limit) } })
})
- // POST /api/whm/security/events/:id/resolve
+ // POST /api/nixserver/security/events/:id/resolve
fastify.post('/events/:id/resolve', { preHandler: [requireAdmin] }, async (request, reply) => {
const { id } = request.params as { id: string }
await prisma.securityEvent.update({
@@ -35,13 +35,13 @@ export default async function securityRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Event resolved' } })
})
- // GET /api/whm/security/blocked-ips
+ // GET /api/nixserver/security/blocked-ips
fastify.get('/blocked-ips', { preHandler: [requireAdmin] }, async (request, reply) => {
const blocked = await prisma.blockedIp.findMany({ orderBy: { createdAt: 'desc' } })
return reply.send({ success: true, data: blocked })
})
- // POST /api/whm/security/blocked-ips
+ // POST /api/nixserver/security/blocked-ips
fastify.post('/blocked-ips', { preHandler: [requireAdmin] }, async (request, reply) => {
const body = z.object({
ip: z.string().ip(),
@@ -69,7 +69,7 @@ export default async function securityRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: blocked })
})
- // DELETE /api/whm/security/blocked-ips/:id
+ // DELETE /api/nixserver/security/blocked-ips/:id
fastify.delete('/blocked-ips/:id', { preHandler: [requireAdmin] }, async (request, reply) => {
const { id } = request.params as { id: string }
const blocked = await prisma.blockedIp.findUnique({ where: { id: parseInt(id, 10) } })
@@ -81,13 +81,13 @@ export default async function securityRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: `${blocked.ip} unblocked` } })
})
- // GET /api/whm/security/whitelisted-ips
+ // GET /api/nixserver/security/whitelisted-ips
fastify.get('/whitelisted-ips', { preHandler: [requireAdmin] }, async (request, reply) => {
const list = await prisma.whitelistedIp.findMany({ orderBy: { createdAt: 'desc' } })
return reply.send({ success: true, data: list })
})
- // POST /api/whm/security/whitelisted-ips
+ // POST /api/nixserver/security/whitelisted-ips
fastify.post('/whitelisted-ips', { preHandler: [requireAdmin] }, async (request, reply) => {
const body = z.object({
ip: z.string().ip(),
@@ -102,20 +102,20 @@ export default async function securityRoutes(fastify: FastifyInstance) {
return reply.code(201).send({ success: true, data: entry })
})
- // DELETE /api/whm/security/whitelisted-ips/:id
+ // DELETE /api/nixserver/security/whitelisted-ips/:id
fastify.delete('/whitelisted-ips/:id', { preHandler: [requireAdmin] }, async (request, reply) => {
const { id } = request.params as { id: string }
await prisma.whitelistedIp.delete({ where: { id: parseInt(id, 10) } })
return reply.send({ success: true, data: { message: 'Removed from whitelist' } })
})
- // GET /api/whm/security/fail2ban
+ // GET /api/nixserver/security/fail2ban
fastify.get('/fail2ban', { preHandler: [requireAdmin] }, async (request, reply) => {
const result = await exec('fail2ban-client', ['status'])
return reply.send({ success: true, data: { output: result.stdout } })
})
- // GET /api/whm/security/fail2ban/:jail
+ // GET /api/nixserver/security/fail2ban/:jail
fastify.get('/fail2ban/:jail', { preHandler: [requireAdmin] }, async (request, reply) => {
const { jail } = request.params as { jail: string }
const result = await exec('fail2ban-client', ['status', jail])
diff --git a/server/src/routes/whm/services.ts b/server/src/routes/nixserver/services.ts
similarity index 90%
rename from server/src/routes/whm/services.ts
rename to server/src/routes/nixserver/services.ts
index 8859019..9fca6c5 100644
--- a/server/src/routes/whm/services.ts
+++ b/server/src/routes/nixserver/services.ts
@@ -9,13 +9,13 @@ const ServiceActionSchema = z.object({
})
export default async function serviceRoutes(fastify: FastifyInstance) {
- // GET /api/whm/services — list all managed services and their status
+ // GET /api/nixserver/services — list all managed services and their status
fastify.get('/', { preHandler: [requireAdmin] }, async (request, reply) => {
const statuses = await Promise.all(MANAGED_SERVICES.map(getServiceStatus))
return reply.send({ success: true, data: statuses })
})
- // GET /api/whm/services/:name
+ // GET /api/nixserver/services/:name
fastify.get('/:name', { preHandler: [requireAdmin] }, async (request, reply) => {
const { name } = request.params as { name: string }
if (!MANAGED_SERVICES.includes(name)) {
@@ -25,7 +25,7 @@ export default async function serviceRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: status })
})
- // POST /api/whm/services/:name — start/stop/restart/reload/enable/disable
+ // POST /api/nixserver/services/:name — start/stop/restart/reload/enable/disable
fastify.post('/:name', { preHandler: [requireAdmin] }, async (request, reply) => {
const { name } = request.params as { name: string }
const body = ServiceActionSchema.safeParse(request.body)
diff --git a/server/src/routes/whm/ssl.ts b/server/src/routes/nixserver/ssl.ts
similarity index 96%
rename from server/src/routes/whm/ssl.ts
rename to server/src/routes/nixserver/ssl.ts
index 9105b6a..bb32c6a 100644
--- a/server/src/routes/whm/ssl.ts
+++ b/server/src/routes/nixserver/ssl.ts
@@ -10,7 +10,7 @@ import { config } from '../../config.js'
export default async function sslRoutes(fastify: FastifyInstance) {
const preHandler = [requireAdminOrReseller]
- // GET /api/whm/ssl
+ // GET /api/nixserver/ssl
fastify.get('/', { preHandler }, async (request, reply) => {
const q = request.query as Record
const where: Record = {}
@@ -25,7 +25,7 @@ export default async function sslRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: certs })
})
- // POST /api/whm/ssl/issue — issue Let's Encrypt cert via certbot
+ // POST /api/nixserver/ssl/issue — issue Let's Encrypt cert via certbot
fastify.post('/issue', { preHandler }, async (request, reply) => {
const body = z.object({
accountId: z.number().int().positive(),
@@ -100,7 +100,7 @@ export default async function sslRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: cert })
})
- // POST /api/whm/ssl/revoke
+ // POST /api/nixserver/ssl/revoke
fastify.post('/:id/revoke', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const cert = await prisma.sslCertificate.findUnique({ where: { id: parseInt(id, 10) } })
@@ -121,7 +121,7 @@ export default async function sslRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: 'Certificate revoked' } })
})
- // POST /api/whm/ssl/:id/renew
+ // POST /api/nixserver/ssl/:id/renew
fastify.post('/:id/renew', { preHandler }, async (request, reply) => {
const { id } = request.params as { id: string }
const cert = await prisma.sslCertificate.findUnique({ where: { id: parseInt(id, 10) } })
diff --git a/server/src/routes/whm/system.ts b/server/src/routes/nixserver/system.ts
similarity index 93%
rename from server/src/routes/whm/system.ts
rename to server/src/routes/nixserver/system.ts
index 6594eb7..cef6e3c 100644
--- a/server/src/routes/whm/system.ts
+++ b/server/src/routes/nixserver/system.ts
@@ -6,13 +6,13 @@ import { exec } from '../../core/exec.js'
import { readFile } from 'fs/promises'
export default async function systemRoutes(fastify: FastifyInstance) {
- // GET /api/whm/system/stats
+ // GET /api/nixserver/system/stats
fastify.get('/stats', { preHandler: [requireAdmin] }, async (request, reply) => {
const stats = await getSystemStats()
return reply.send({ success: true, data: stats })
})
- // GET /api/whm/system/info
+ // GET /api/nixserver/system/info
fastify.get('/info', { preHandler: [requireAdmin] }, async (request, reply) => {
const [hostname, osRelease, kernel, uptime] = await Promise.all([
exec('hostname', ['-f']),
@@ -39,7 +39,7 @@ export default async function systemRoutes(fastify: FastifyInstance) {
})
})
- // GET /api/whm/system/processes
+ // GET /api/nixserver/system/processes
fastify.get('/processes', { preHandler: [requireAdmin] }, async (request, reply) => {
const result = await exec('ps', ['aux', '--sort=-%cpu'])
if (result.exitCode !== 0) {
@@ -61,7 +61,7 @@ export default async function systemRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: processes })
})
- // POST /api/whm/system/processes/:pid/kill
+ // POST /api/nixserver/system/processes/:pid/kill
fastify.post('/processes/:pid/kill', { preHandler: [requireAdmin] }, async (request, reply) => {
const { pid } = request.params as { pid: string }
if (!/^\d+$/.test(pid) || parseInt(pid, 10) <= 1) {
@@ -74,7 +74,7 @@ export default async function systemRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: { message: `Process ${pid} killed` } })
})
- // GET /api/whm/system/audit-log
+ // GET /api/nixserver/system/audit-log
fastify.get('/audit-log', { preHandler: [requireAdmin] }, async (request, reply) => {
const q = request.query as Record
const page = Math.max(1, parseInt(q.page ?? '1', 10))
@@ -96,7 +96,7 @@ export default async function systemRoutes(fastify: FastifyInstance) {
})
})
- // GET /api/whm/system/settings
+ // GET /api/nixserver/system/settings
fastify.get('/settings', { preHandler: [requireAdmin] }, async (request, reply) => {
const settings = await prisma.setting.findMany({ orderBy: { key: 'asc' } })
const map: Record = {}
@@ -104,7 +104,7 @@ export default async function systemRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: map })
})
- // PUT /api/whm/system/settings
+ // PUT /api/nixserver/system/settings
fastify.put('/settings', { preHandler: [requireAdmin] }, async (request, reply) => {
const body = request.body as Record
if (typeof body !== 'object' || Array.isArray(body)) {
diff --git a/server/src/routes/whm/webserver.ts b/server/src/routes/nixserver/webserver.ts
similarity index 90%
rename from server/src/routes/whm/webserver.ts
rename to server/src/routes/nixserver/webserver.ts
index 39d72bf..e2d5d44 100644
--- a/server/src/routes/whm/webserver.ts
+++ b/server/src/routes/nixserver/webserver.ts
@@ -5,7 +5,7 @@ import { exec } from '../../core/exec.js'
import { readFile } from 'fs/promises'
export default async function webserverRoutes(fastify: FastifyInstance) {
- // GET /api/whm/webserver/status
+ // GET /api/nixserver/webserver/status
fastify.get('/status', { preHandler: [requireAdmin] }, async (request, reply) => {
const [nginx, apache] = await Promise.all([
exec('systemctl', ['is-active', 'nginx']),
@@ -20,7 +20,7 @@ export default async function webserverRoutes(fastify: FastifyInstance) {
})
})
- // GET /api/whm/webserver/vhosts
+ // GET /api/nixserver/webserver/vhosts
fastify.get('/vhosts', { preHandler: [requireAdmin] }, async (request, reply) => {
const result = await exec('find', ['/etc/nginx/sites-enabled', '-name', '*.conf', '-type', 'f'])
const files = result.stdout.split('\n').filter(Boolean)
@@ -31,7 +31,7 @@ export default async function webserverRoutes(fastify: FastifyInstance) {
return reply.send({ success: true, data: vhosts })
})
- // GET /api/whm/webserver/vhosts/:domain
+ // GET /api/nixserver/webserver/vhosts/:domain
fastify.get('/vhosts/:domain', { preHandler: [requireAdmin] }, async (request, reply) => {
const { domain } = request.params as { domain: string }
if (domain.includes('/') || domain.includes('..')) {
@@ -45,7 +45,7 @@ export default async function webserverRoutes(fastify: FastifyInstance) {
}
})
- // POST /api/whm/webserver/nginx/test
+ // POST /api/nixserver/webserver/nginx/test
fastify.post('/nginx/test', { preHandler: [requireAdmin] }, async (request, reply) => {
const result = await exec('nginx', ['-t'])
return reply.send({
@@ -54,7 +54,7 @@ export default async function webserverRoutes(fastify: FastifyInstance) {
})
})
- // POST /api/whm/webserver/nginx/reload
+ // POST /api/nixserver/webserver/nginx/reload
fastify.post('/nginx/reload', { preHandler: [requireAdmin] }, async (request, reply) => {
const test = await exec('nginx', ['-t'])
if (test.exitCode !== 0) {
@@ -64,7 +64,7 @@ export default async function webserverRoutes(fastify: FastifyInstance) {
return reply.send({ success: result.exitCode === 0, data: { output: result.stdout } })
})
- // GET /api/whm/webserver/logs/:type — access or error log (last 200 lines)
+ // GET /api/nixserver/webserver/logs/:type — access or error log (last 200 lines)
fastify.get('/logs/:type', { preHandler: [requireAdmin] }, async (request, reply) => {
const { type } = request.params as { type: string }
const logFile = type === 'error' ? '/var/log/nginx/error.log' : '/var/log/nginx/access.log'