fix(feedback): make the "block" severity tier actually reject
The block level is advertised as "comment is rejected immediately", but every non-approved comment was saved with is_approved = false instead of the submission being refused. moderateText now sets an explicit `blocked: true` on the blocking-violation branch -- branching on the reason string in the route would have been fragile -- and the route 400s with code COMMENT_BLOCKED and stores nothing. Everything else that is not approved (moderate/high, the spam and caps checks, and the "Moderation system error" fallback) deliberately omits the flag and keeps the held-for-moderation path, so a moderation failure still fails safe. Also fixes an adjacent defect that made the tier split unobservable: feedbackService.submitFeedback ignored feedbackData.is_approved entirely and hard-derived is_approved from moderate_comments. So a moderate/high word-filter hit on an event with moderation switched OFF was published immediately -- the route's `feedbackData.is_approved = false` was dead code. Now honoured one-directionally: a caller-supplied false is respected, but nothing a caller passes can RELAX the event's setting. That deliberately leaves the route's reputation.autoApprove -> is_approved = true branch inert rather than letting a trusted guest bypass an event's moderation setting. Refs testplan REPORT.md B11. (cherry picked from commit b1b57b1615aaf02fe76e789a86b7e11933288d77)
This commit is contained in:
@@ -71,8 +71,15 @@ class FeedbackModerationService {
|
||||
// low/moderate/high/block levels — rows stored under it still apply.
|
||||
const isBlocking = (v) => v.severity === 'block' || v.severity === 'severe';
|
||||
if (violations.some(isBlocking)) {
|
||||
// `blocked` is the flag the submit route branches on: the `block`
|
||||
// tier is advertised as "comment is rejected immediately", so it 4xxs
|
||||
// the submission instead of storing it for a moderator. Every other
|
||||
// not-approved outcome (moderate/high, spam checks, and the
|
||||
// moderation-system-error fallback below) deliberately omits it and
|
||||
// keeps the held-for-moderation behaviour.
|
||||
return {
|
||||
approved: false,
|
||||
blocked: true,
|
||||
reason: 'Content contains prohibited words',
|
||||
violations: violations.filter(isBlocking)
|
||||
};
|
||||
|
||||
@@ -645,7 +645,14 @@ class FeedbackService {
|
||||
guest_id: guest_id || null,
|
||||
ip_address,
|
||||
user_agent,
|
||||
is_approved: feedback_type !== 'comment' || !feedbackData.moderate_comments,
|
||||
// The submit route can force a comment into moderation (a
|
||||
// `moderate`/`high` word-filter hit) on an event whose
|
||||
// moderate_comments is off — this line used to ignore that entirely,
|
||||
// so those hits published straight away. A caller-supplied `false` is
|
||||
// honoured; nothing a caller passes can RELAX the event's setting.
|
||||
is_approved: feedbackData.is_approved === false
|
||||
? false
|
||||
: (feedback_type !== 'comment' || !feedbackData.moderate_comments),
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
}).returning('id');
|
||||
|
||||
Reference in New Issue
Block a user