初始提交:DSH 多租户平台(dshs)
This commit is contained in:
commit
43976fea6a
167 files changed
+24456
No files matched your search
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Custom-domain routes: set/get a user's domain, regenerate its nginx config,
|
||||
* and admin verification. Real ACME/DNS ownership verification is deferred;
|
||||
* the `verified` flag is set by an admin as a placeholder until then.
|
||||
* @module dshs/web/routes/domain
|
||||
*/
|
||||
|
||||
import type { FastifyPluginAsync } from 'fastify'
|
||||
import { requireAdmin, requireAuth } from '../middleware/authn.js'
|
||||
import { isValidDomain, renderServerBlock } from '../../nginx/generate.js'
|
||||
|
||||
const putSchema = {
|
||||
body: {
|
||||
type: 'object',
|
||||
required: ['domain'],
|
||||
additionalProperties: false,
|
||||
properties: { domain: { type: 'string', minLength: 1, maxLength: 253 } },
|
||||
},
|
||||
} as const
|
||||
|
||||
export const domainRoutes: FastifyPluginAsync = async (app) => {
|
||||
app.get('/api/domain', { preHandler: requireAuth }, async (request) => {
|
||||
const domain = await app.db.findDomainByUser(request.user!.id)
|
||||
if (domain === undefined) return { domain: null }
|
||||
return { domain: domain.domain, verified: domain.verified === 1, nginx_config: domain.nginxConfig }
|
||||
})
|
||||
|
||||
app.put('/api/domain', { preHandler: requireAuth, schema: putSchema }, async (request, reply) => {
|
||||
const normalized = (request.body as { domain: string }).domain.toLowerCase().trim()
|
||||
if (!isValidDomain(normalized)) return reply.code(400).send({ error: 'invalid_domain' })
|
||||
const config = renderServerBlock(normalized, request.user!.id, app.config.port)
|
||||
await app.db.upsertDomain(request.user!.id, normalized, config)
|
||||
return { domain: normalized, verified: false, nginx_config: config }
|
||||
})
|
||||
|
||||
app.post('/api/nginx/regen', { preHandler: requireAuth }, async (request, reply) => {
|
||||
const domain = await app.db.findDomainByUser(request.user!.id)
|
||||
if (domain === undefined) return reply.code(404).send({ error: 'no_domain' })
|
||||
const config = renderServerBlock(domain.domain, request.user!.id, app.config.port)
|
||||
await app.db.upsertDomain(request.user!.id, domain.domain, config)
|
||||
return { domain: domain.domain, nginx_config: config }
|
||||
})
|
||||
|
||||
app.get('/api/admin/domains', { preHandler: requireAdmin }, async () => ({
|
||||
domains: (await app.db.listDomains()).map((d) => ({
|
||||
id: d.id,
|
||||
userId: d.userId,
|
||||
domain: d.domain,
|
||||
verified: d.verified === 1,
|
||||
})),
|
||||
}))
|
||||
|
||||
app.post('/api/admin/domains/:id/verify', { preHandler: requireAdmin }, async (request, reply) => {
|
||||
const { id } = request.params as { id: string }
|
||||
if ((await app.db.findDomainById(id)) === undefined) return reply.code(404).send({ error: 'not_found' })
|
||||
await app.db.setDomainVerified(id, true)
|
||||
return { ok: true }
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user