fix: nixclient SSL calls correct user-scoped route, not admin endpoint
- Add /api/nixclient/ssl (GET) — returns certs for authenticated user only - Add /api/nixclient/ssl/:id/renew (POST) — validates cert belongs to user - Register sslRoutes in nixclient index.ts - nixclient SSL.tsx was calling /nixserver/ssl (requireAdminOrReseller) which would always 401 for regular users — fixed to /nixclient/ssl
This commit is contained in:
@@ -10,14 +10,14 @@ export default function SSL() {
|
||||
|
||||
const fetch = async () => {
|
||||
setLoading(true)
|
||||
try { const r = await api.get('/nixserver/ssl'); setCerts(r.data.data) }
|
||||
try { const r = await api.get('/nixclient/ssl'); setCerts(r.data.data) }
|
||||
finally { setLoading(false) }
|
||||
}
|
||||
|
||||
useEffect(() => { fetch() }, [])
|
||||
|
||||
const renew = async (id: number) => {
|
||||
try { await api.post(`/nixserver/ssl/${id}/renew`); fetch() }
|
||||
try { await api.post(`/nixclient/ssl/${id}/renew`); fetch() }
|
||||
catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Renewal failed') }
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import domainRoutes from './domains.js'
|
||||
import ftpRoutes from './ftp.js'
|
||||
import cronRoutes from './cron.js'
|
||||
import statsRoutes from './stats.js'
|
||||
import sslRoutes from './ssl.js'
|
||||
|
||||
export default async function nixclientRoutes(fastify: FastifyInstance) {
|
||||
fastify.register(fileRoutes, { prefix: '/files' })
|
||||
@@ -15,4 +16,5 @@ export default async function nixclientRoutes(fastify: FastifyInstance) {
|
||||
fastify.register(ftpRoutes, { prefix: '/ftp' })
|
||||
fastify.register(cronRoutes, { prefix: '/cron' })
|
||||
fastify.register(statsRoutes, { prefix: '/stats' })
|
||||
fastify.register(sslRoutes, { prefix: '/ssl' })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import type { FastifyInstance } from 'fastify'
|
||||
import prisma from '../../db/client.js'
|
||||
import { requireAuth } from '../../middleware/auth.js'
|
||||
import { exec } from '../../core/exec.js'
|
||||
|
||||
export default async function sslRoutes(fastify: FastifyInstance) {
|
||||
const preHandler = [requireAuth]
|
||||
|
||||
// GET /api/nixclient/ssl — certs for the authenticated user's account only
|
||||
fastify.get('/', { preHandler }, async (request, reply) => {
|
||||
const user = request.user!
|
||||
const accountId = user.sub
|
||||
|
||||
const certs = await prisma.sslCertificate.findMany({
|
||||
where: { accountId },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
})
|
||||
return reply.send({ success: true, data: certs })
|
||||
})
|
||||
|
||||
// POST /api/nixclient/ssl/:id/renew
|
||||
fastify.post('/:id/renew', { preHandler }, async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
const user = request.user!
|
||||
|
||||
const cert = await prisma.sslCertificate.findFirst({
|
||||
where: { id: parseInt(id, 10), accountId: user.sub },
|
||||
})
|
||||
if (!cert) return reply.code(404).send({ success: false, error: 'Certificate not found' })
|
||||
|
||||
const result = await exec('certbot', ['renew', '--cert-name', cert.domain, '--non-interactive'])
|
||||
if (result.exitCode !== 0) {
|
||||
return reply.code(500).send({ success: false, error: `Renewal failed: ${result.stderr}` })
|
||||
}
|
||||
|
||||
const expiresAt = new Date()
|
||||
expiresAt.setDate(expiresAt.getDate() + 90)
|
||||
|
||||
const updated = await prisma.sslCertificate.update({
|
||||
where: { id: cert.id },
|
||||
data: { status: 'active', issuedAt: new Date(), expiresAt },
|
||||
})
|
||||
|
||||
return reply.send({ success: true, data: updated })
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user