安全加固 + 结构清理:修注入/串写/竞态,DOMPurify 上线,后端补事务与 handler 测试
后端: - ORDER BY 白名单(sanitizeOrder)堵住 ?order= SQL 注入,补回归测试 - 登录限速(每 IP 10 次失败/10 分钟 429)、TLS/反代下 Secure cookie、NewAPI 构造器 - Delete/setTags/MergeTags/DeleteTag 包事务;Archive 去 500 篇上限 - 列表接口裁剪:不传 content_md,长文 content_html 截 600,新增 content_len;health 探 DB 前端: - EditorView 路由复用串写修复(RouterView :key + sync watch 回写原文章) - v-html 出口统一过 DOMPurify(sanitizeHtml),stripTags 改 DOMParser - 列表竞态防护(Home/Tag/Posts 请求序号)、TagView 分页修复 - 侧栏接口 30s 缓存去重;one:unauthorized 监听器泄漏修复 - 删 styles.css 498 行重复块;移除 tailwind/marked/vue-tsc 死依赖;CommandPalette a11y 语义
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { site } from '../site'
|
||||
import { relativeDate, stripTags, minutesLabel } from '../utils'
|
||||
import { relativeDate, stripTags, minutesLabel, sanitizeHtml } from '../utils'
|
||||
|
||||
const props = defineProps({
|
||||
post: { type: Object, required: true }
|
||||
@@ -12,7 +12,7 @@ const isShort = computed(() => props.post.kind === 'short')
|
||||
// 时间线里短文不铺全文,超过 5 行折叠;长文只显示摘要
|
||||
const body = computed(() => {
|
||||
if (!isShort.value) return props.post.summary || stripTags(props.post.content_html || '')
|
||||
return props.post.content_html || ''
|
||||
return sanitizeHtml(props.post.content_html)
|
||||
})
|
||||
|
||||
// 长文没写摘要时,从正文里截一段纯文本
|
||||
|
||||
@@ -9,10 +9,7 @@ const tags = ref([])
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const [posts, tagData] = await Promise.all([
|
||||
publicApi.posts({ size: 5 }),
|
||||
publicApi.tags()
|
||||
])
|
||||
const [posts, tagData] = await Promise.all([publicApi.latest(), publicApi.tags()])
|
||||
latest.value = posts.items || []
|
||||
tags.value = (tagData.tags || []).slice(0, 12)
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user