feat: 增强维护模式和审计页面功能,优化构建流程
All checks were successful
docker-images / resolve-build-targets (push) Successful in 4s
ui-regression / playwright-regression (push) Successful in 5m55s
docker-images / build-and-push (admin) (push) Successful in 54s
docker-images / build-and-push (backend) (push) Successful in 4s
docker-images / build-and-push (frontend) (push) Successful in 1m8s
docker-images / submit-indexnow (push) Successful in 15s
All checks were successful
docker-images / resolve-build-targets (push) Successful in 4s
ui-regression / playwright-regression (push) Successful in 5m55s
docker-images / build-and-push (admin) (push) Successful in 54s
docker-images / build-and-push (backend) (push) Successful in 4s
docker-images / build-and-push (frontend) (push) Successful in 1m8s
docker-images / submit-indexnow (push) Successful in 15s
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { createServer } from 'node:http'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { createHash, randomUUID } from 'node:crypto'
|
||||
|
||||
const PORT = Number(process.env.PLAYWRIGHT_MOCK_PORT || 5159)
|
||||
const FRONTEND_ORIGIN =
|
||||
@@ -777,6 +777,8 @@ function createSiteSettings() {
|
||||
description: '适合文章阅读时循环播放的轻氛围曲。',
|
||||
},
|
||||
],
|
||||
maintenance_mode_enabled: false,
|
||||
maintenance_access_code: null,
|
||||
ai_enabled: true,
|
||||
paragraph_comments_enabled: true,
|
||||
comment_verification_mode: 'captcha',
|
||||
@@ -837,6 +839,13 @@ function createSiteSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
function maintenanceAccessTokenFromSecret(secret) {
|
||||
return createHash('sha256')
|
||||
.update('termi-maintenance-access:v1:')
|
||||
.update(String(secret))
|
||||
.digest('hex')
|
||||
}
|
||||
|
||||
function parseHeadingAndDescription(markdown, fallbackTitle = 'Untitled') {
|
||||
const normalized = String(markdown || '').replace(/\r\n/g, '\n').trim()
|
||||
const titleMatch = normalized.match(/^#\s+(.+)$/m)
|
||||
@@ -1941,6 +1950,46 @@ const server = createServer(async (req, res) => {
|
||||
return
|
||||
}
|
||||
|
||||
if (pathname === '/api/site_settings/maintenance/status' && req.method === 'POST') {
|
||||
const { json: payload } = await parseRequest(req)
|
||||
const enabled = Boolean(state.site_settings.maintenance_mode_enabled)
|
||||
const secret = normalizeText(state.site_settings.maintenance_access_code)
|
||||
const expectedToken = secret ? maintenanceAccessTokenFromSecret(secret) : null
|
||||
const accessToken =
|
||||
normalizeText(payload.accessToken) ||
|
||||
normalizeText(payload.access_token)
|
||||
|
||||
json(res, 200, {
|
||||
maintenance_mode_enabled: enabled,
|
||||
access_granted: !enabled || Boolean(expectedToken && accessToken === expectedToken),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (pathname === '/api/site_settings/maintenance/verify' && req.method === 'POST') {
|
||||
const { json: payload } = await parseRequest(req)
|
||||
const enabled = Boolean(state.site_settings.maintenance_mode_enabled)
|
||||
const secret = normalizeText(state.site_settings.maintenance_access_code)
|
||||
const code = normalizeText(payload.code)
|
||||
|
||||
if (!enabled) {
|
||||
json(res, 200, {
|
||||
maintenance_mode_enabled: false,
|
||||
access_granted: true,
|
||||
access_token: null,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const accessGranted = Boolean(secret && code && code === secret)
|
||||
json(res, 200, {
|
||||
maintenance_mode_enabled: true,
|
||||
access_granted: accessGranted,
|
||||
access_token: accessGranted ? maintenanceAccessTokenFromSecret(secret) : null,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (pathname === '/api/site_settings/home' && req.method === 'GET') {
|
||||
json(res, 200, getHomePayload())
|
||||
return
|
||||
@@ -2686,6 +2735,8 @@ const server = createServer(async (req, res) => {
|
||||
techStack: 'tech_stack',
|
||||
musicPlaylist: 'music_playlist',
|
||||
aiEnabled: 'ai_enabled',
|
||||
maintenanceModeEnabled: 'maintenance_mode_enabled',
|
||||
maintenanceAccessCode: 'maintenance_access_code',
|
||||
paragraphCommentsEnabled: 'paragraph_comments_enabled',
|
||||
commentVerificationMode: 'comment_verification_mode',
|
||||
commentTurnstileEnabled: 'comment_turnstile_enabled',
|
||||
|
||||
Reference in New Issue
Block a user