This commit is contained in:
tamakyi
2026-10-19 01:11:28 +08:00
parent 84f8afe8b1
commit bd613a6f5a
15 changed files with 68 additions and 11 deletions
+1
View File
@@ -778,6 +778,7 @@ var enDict = map[string]string{
"admin.flash.moderationStrictnessUpdated": "Moderation strictness updated",
"admin.flash.moderationStrictnessInvalid": "Invalid moderation strictness value, nothing was saved",
"admin.flash.strictnessLocked": "Moderation strictness is locked at the highest level during a restriction and restored afterwards",
// Vote management: owner visible (P1)
"vote.err.invalidID": "Invalid vote ID",
+1
View File
@@ -778,6 +778,7 @@ var jaDict = map[string]string{
"admin.flash.moderationStrictnessUpdated": "審核の厳格度を更新しました",
"admin.flash.moderationStrictnessInvalid": "審核の厳格度の値が不正なため、保存しませんでした",
"admin.flash.strictnessLocked": "措置期間中はモデレーション強度が最高に固定されます。解除後に元の設定へ戻ります",
// 投票管理:所有者に表示(P1)
"vote.err.invalidID": "無効な投票 ID",
+1
View File
@@ -778,6 +778,7 @@ var zhCNDict = map[string]string{
"admin.flash.moderationStrictnessUpdated": "审核严格度已更新",
"admin.flash.moderationStrictnessInvalid": "审核严格度取值无效,未保存",
"admin.flash.strictnessLocked": "处置期间审核严格度已锁定为最高档,解除后自动恢复你的原设置",
// 投票管理:箱主可见(P1)
"vote.err.invalidID": "无效的投票 ID",
+1
View File
@@ -778,6 +778,7 @@ var zhTWDict = map[string]string{
"admin.flash.moderationStrictnessUpdated": "審核嚴格度已更新",
"admin.flash.moderationStrictnessInvalid": "審核嚴格度取值無效,未儲存",
"admin.flash.strictnessLocked": "處置期間審核嚴格度已鎖定為最高檔,解除後自動恢復你的原設定",
// 投票管理:箱主可見(P1)
"vote.err.invalidID": "無效的投票 ID",
+1 -1
View File
@@ -275,7 +275,7 @@ func SendMessage(ctx context.Context, cache cache.Cache) {
// 内容安全检测(仅文本)
// 统一守卫:与提问 / 投票共用同一份档位判定,箱主的「审核严格度」决定放行与否。
if content != "" {
if _, err := moderation.Check(ctx.Request().Context(), moderation.StrictnessFor(pageUser.ModerationStrictness), ctx.Lang(), content); err != nil {
if _, err := moderation.Check(ctx.Request().Context(), moderation.EffectiveStrictness(ctx.Request().Context(), pageUser.ID, pageUser.ModerationStrictness), ctx.Lang(), content); err != nil {
// 审核拦截:就地重渲染会话页,回填已输入内容并展示拦截原因。
// 不复用 SetErrorFlash + Redirect:那会导致输入框内容在刷新后丢失(用户已确认的无提示+内容消失问题)。
renderConversation(ctx, domain, token, content, err)
@@ -16,6 +16,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/tamakyi/TamaBox/internal/conf"
"github.com/tamakyi/TamaBox/internal/db"
"github.com/tamakyi/TamaBox/internal/i18n"
"github.com/tamakyi/TamaBox/internal/security/censor"
)
@@ -35,6 +36,24 @@ func StrictnessFor(raw string) censor.Strictness {
return censor.ParseStrictness(conf.Security.DefaultModerationStrictness)
}
// EffectiveStrictness 返回账号**实际生效**的审核档位,是内容审核应当使用的入口。
//
// 处于处置期(L1–L4)的账号一律强制 strict,忽略账号自身设置:
// 限制期内允许保留 lax / standard,等于给了箱主一个免审通道 —— 一边被限制、
// 一边把门槛调到最低,是明显可被利用的组合。
//
// 处置查询失败时**回退账号自身设置**,而不是"失败即强制 strict":
// DB 抖动时反向兜底会让全站突然加严,正常用户的提交被大面积误拒,
// 影响面远大于「漏放一个受控账号」。
func EffectiveStrictness(ctx context.Context, userID uint, raw string) censor.Strictness {
if userID != 0 {
if level, _, err := db.Restrictions.ActiveLevel(ctx, userID); err == nil && level != "" {
return censor.StrictnessStrict
}
}
return StrictnessFor(raw)
}
// Check 执行一次内容审核,并按箱主严格度裁决是否放行。
//
// 这是提问 / 投票 / 私聊三类场景**唯一**应当使用的审核入口。