feat: rename WHM→NixServer, cPanel→NixClient, bump v0.2.0
- Rename frontend workspaces: whm/ → nixserver/, cpanel/ → nixclient/ - Rename server route dirs: routes/whm/ → routes/nixserver/, routes/cpanel/ → routes/nixclient/ - Update all API prefixes: /api/whm → /api/nixserver, /api/cpanel → /api/nixclient - Rename env vars: WHM_PORT → NIXSERVER_PORT, CPANEL_PORT → NIXCLIENT_PORT - Update config properties: whmPort → nixserverPort, cpanelPort → nixclientPort - Update all UI labels, login pages, sidebar branding, and error messages - Update installer and update scripts to match new names - Add cpanel email route (missing from initial scaffold) - Add .gitattributes to enforce LF line endings - Bump version to 0.2.0 across all package.json files
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nixpanel/server",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
+8
-8
@@ -9,8 +9,8 @@ import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { config } from './config.js'
|
||||
import authRoutes from './routes/auth/index.js'
|
||||
import whmRoutes from './routes/whm/index.js'
|
||||
import cpanelRoutes from './routes/cpanel/index.js'
|
||||
import nixserverRoutes from './routes/nixserver/index.js'
|
||||
import nixclientRoutes from './routes/nixclient/index.js'
|
||||
import { getSystemStats } from './core/system.js'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
@@ -59,21 +59,21 @@ export async function buildApp() {
|
||||
|
||||
// ─── Static files ────────────────────────────────────────────────────────────
|
||||
|
||||
// WHM frontend served from /whm
|
||||
const whmDist = path.resolve(__dirname, '../../whm/dist')
|
||||
const cpanelDist = path.resolve(__dirname, '../../cpanel/dist')
|
||||
// NixServer frontend
|
||||
const whmDist = path.resolve(__dirname, '../../nixserver/dist')
|
||||
const cpanelDist = path.resolve(__dirname, '../../nixclient/dist')
|
||||
|
||||
// ─── API Routes ──────────────────────────────────────────────────────────────
|
||||
|
||||
fastify.register(authRoutes, { prefix: '/api/auth' })
|
||||
fastify.register(whmRoutes, { prefix: '/api/whm' })
|
||||
fastify.register(cpanelRoutes, { prefix: '/api/cpanel' })
|
||||
fastify.register(nixserverRoutes, { prefix: '/api/nixserver' })
|
||||
fastify.register(nixclientRoutes, { prefix: '/api/nixclient' })
|
||||
|
||||
// ─── Health check ─────────────────────────────────────────────────────────────
|
||||
|
||||
fastify.get('/api/health', async () => ({
|
||||
status: 'ok',
|
||||
version: '0.1.0',
|
||||
version: '0.2.0',
|
||||
timestamp: new Date().toISOString(),
|
||||
}))
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-4
@@ -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)
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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<string, string>).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<string, string>).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 }
|
||||
|
||||
@@ -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<string, string>).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<string, unknown>).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<string, string>).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<string, unknown>).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
|
||||
@@ -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' })
|
||||
@@ -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' })
|
||||
@@ -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<string, string>).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<string, string>).accountId ?? '0', 10)
|
||||
@@ -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<string, string>
|
||||
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<string, unknown> = { 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<string, string>) ?? {}
|
||||
@@ -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<string, boolean>) ?? {}
|
||||
@@ -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']),
|
||||
@@ -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
|
||||
@@ -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<string, string>
|
||||
const where: Record<string, unknown> = {}
|
||||
@@ -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))
|
||||
@@ -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<string, string>
|
||||
const where: Record<string, unknown> = {}
|
||||
@@ -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<string, string>
|
||||
const where: Record<string, unknown> = {}
|
||||
@@ -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) } })
|
||||
@@ -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' })
|
||||
@@ -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)) {
|
||||
@@ -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<string, string>
|
||||
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])
|
||||
@@ -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)
|
||||
@@ -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<string, string>
|
||||
const where: Record<string, unknown> = {}
|
||||
@@ -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) } })
|
||||
@@ -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<string, string>
|
||||
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<string, string> = {}
|
||||
@@ -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<string, string>
|
||||
if (typeof body !== 'object' || Array.isArray(body)) {
|
||||
@@ -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'
|
||||
Reference in New Issue
Block a user