v1.10.88 품질·보안 개선과 미디어 카탈로그 database 전환을 반영한다.
세션·로그인 제한, ZIP/업로드 스트리밍, CSP 최소 강제와 Report-Only, Playwright 격리 검증을 추가하고 미디어 목록을 reconcile 후 database 모드로 고정한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
93
server/routes/admin/api/settings.patch.js
Normal file
93
server/routes/admin/api/settings.patch.js
Normal file
@@ -0,0 +1,93 @@
|
||||
import { createError, readBody } from 'h3'
|
||||
import { requireAdminSession } from '../../../utils/admin-auth'
|
||||
import { parseAdminSiteSettingsInput } from '../../../utils/admin-site-settings-input'
|
||||
import {
|
||||
getSiteSettings,
|
||||
updateSiteSettingsPartial
|
||||
} from '../../../repositories/content-repository'
|
||||
|
||||
const ALLOWED_SITE_SETTINGS_FIELDS = new Set([
|
||||
'title',
|
||||
'description',
|
||||
'siteUrl',
|
||||
'logoText',
|
||||
'logoUrl',
|
||||
'faviconUrl',
|
||||
'copyrightText',
|
||||
'socialLinks',
|
||||
'showPostUpdatedAt',
|
||||
'postTagLimit',
|
||||
'homeLatestPostLimit',
|
||||
'postListPageSize',
|
||||
'tagPostListPageSize',
|
||||
'featuredPostLimit',
|
||||
'pageSectionItemLimit',
|
||||
'uploadMaxFileCount',
|
||||
'uploadMaxTotalSize',
|
||||
'homeCoverImageUrl',
|
||||
'homeCoverDarkImageUrl',
|
||||
'homeCoverTitle',
|
||||
'homeCoverText',
|
||||
'brandColor',
|
||||
'announcementEnabled',
|
||||
'announcementText',
|
||||
'announcementUrl',
|
||||
'announcementBackgroundColor',
|
||||
'announcementAlignment',
|
||||
'signupBlockedUsernames',
|
||||
'adsTxt',
|
||||
'customHeadCode',
|
||||
'customFooterCode',
|
||||
'adHomeFeedCode',
|
||||
'adHomeInfeedCode',
|
||||
'adSidebarCode',
|
||||
'adPostSidebarCode',
|
||||
'adPostTopCode',
|
||||
'adPostInArticleCode',
|
||||
'adPostBottomCode'
|
||||
])
|
||||
|
||||
/**
|
||||
* 관리자 사이트 설정의 전달된 필드만 수정한다.
|
||||
* @param {import('h3').H3Event} event - 요청 이벤트
|
||||
* @returns {Promise<Object>} 수정된 사이트 설정
|
||||
*/
|
||||
export default defineEventHandler(async (event) => {
|
||||
requireAdminSession(event)
|
||||
const body = await readBody(event)
|
||||
|
||||
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: '사이트 설정 입력 형식이 올바르지 않습니다.'
|
||||
})
|
||||
}
|
||||
|
||||
const fields = Object.keys(body)
|
||||
if (!fields.length || fields.some((field) => !ALLOWED_SITE_SETTINGS_FIELDS.has(field))) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: '수정할 수 없는 사이트 설정 필드가 포함되어 있습니다.'
|
||||
})
|
||||
}
|
||||
|
||||
const currentSettings = await getSiteSettings()
|
||||
const parsedBody = parseAdminSiteSettingsInput({
|
||||
...currentSettings,
|
||||
...body
|
||||
})
|
||||
|
||||
if (!parsedBody.success) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: '사이트 설정 입력 형식이 올바르지 않습니다.'
|
||||
})
|
||||
}
|
||||
|
||||
const validatedPatch = Object.fromEntries(fields.map((field) => [
|
||||
field,
|
||||
parsedBody.data[field]
|
||||
]))
|
||||
|
||||
return updateSiteSettingsPartial(validatedPatch)
|
||||
})
|
||||
Reference in New Issue
Block a user