diff --git a/package-lock.json b/package-lock.json index efc1a3a5c..7bdbecbd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23373,6 +23373,11 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, + "striptags": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.1.1.tgz", + "integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0=" + }, "style-loader": { "version": "0.21.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", diff --git a/package.json b/package.json index 9a804811f..253e5681a 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "passport-strategy": "^1.0.0", "performance-now": "^2.1.0", "permit": "^0.2.4", + "striptags": "^3.1.1", "subscriptions-transport-ws": "^0.9.12", "tlds": "^1.203.1", "uuid": "^3.3.2" diff --git a/src/core/server/graph/tenant/schema/schema.graphql b/src/core/server/graph/tenant/schema/schema.graphql index 9b808db0d..cbd194806 100644 --- a/src/core/server/graph/tenant/schema/schema.graphql +++ b/src/core/server/graph/tenant/schema/schema.graphql @@ -289,6 +289,27 @@ type Karma { thresholds: KarmaThresholds! } +################################################################################ +## CharCount +################################################################################ + +type CharCount { + """ + enabled when true, enables the character count moderation phase. + """ + enabled: Boolean! + + """ + min is the smallest length of a Comment that may be posted. + """ + min: Int + + """ + max is the largest length of a Comment that may be posted. + """ + max: Int +} + ################################################################################ ## Email ################################################################################ @@ -411,14 +432,9 @@ type Settings { editCommentWindowLength: Int! """ - charCountEnable is true when the character count restriction is enabled. + charCount stores the character count moderation settings. """ - charCountEnable: Boolean! - - """ - charCount is the maximum number of characters a comment may be. - """ - charCount: Int + charCount: CharCount! """ organizationName is the name of the organization. @@ -1104,6 +1120,23 @@ input SettingsKarmaInput { thresholds: SettingsKarmaThresholdsInput } +input SettingsCharCountInput { + """ + enabled when true, enables the character count moderation phase. + """ + enabled: Boolean + + """ + min is the smallest length of a Comment that may be posted. + """ + min: Int + + """ + max is the largest length of a Comment that may be posted. + """ + max: Int +} + """ SettingsInput is the partial type of the Settings type for performing mutations. """ @@ -1195,16 +1228,6 @@ input SettingsInput { """ editCommentWindowLength: Int - """ - charCountEnable is true when the character count restriction is enabled. - """ - charCountEnable: Boolean - - """ - charCount is the maximum number of characters a comment may be. - """ - charCount: Int - """ organizationName is the name of the organization. """ @@ -1240,6 +1263,11 @@ input SettingsInput { handled. """ karma: SettingsKarmaInput + + """ + charCount stores the character count moderation settings. + """ + charCount: SettingsCharCountInput } """ diff --git a/src/core/server/models/settings.ts b/src/core/server/models/settings.ts index 451bfdf7a..cf5a3e2c7 100644 --- a/src/core/server/models/settings.ts +++ b/src/core/server/models/settings.ts @@ -1,5 +1,6 @@ import { GQLAuth, + GQLCharCount, GQLEmail, GQLExternalIntegrations, GQLKarma, @@ -62,8 +63,7 @@ export interface ModerationSettings { closedMessage?: string; disableCommenting: boolean; disableCommentingMessage?: string; - charCountEnable: boolean; - charCount?: number; + charCount: GQLCharCount; } export interface Settings extends ModerationSettings { diff --git a/src/core/server/models/tenant.ts b/src/core/server/models/tenant.ts index f67982e6d..7aebe644b 100644 --- a/src/core/server/models/tenant.ts +++ b/src/core/server/models/tenant.ts @@ -71,7 +71,9 @@ export async function createTenant(db: Db, input: CreateTenantInput) { closedTimeout: 60 * 60 * 24 * 7 * 2, disableCommenting: false, editCommentWindowLength: 30 * 1000, - charCountEnable: false, + charCount: { + enabled: false, + }, wordlist: { suspect: [], banned: [], diff --git a/src/core/server/services/comments/moderation/phases/commentLength.ts b/src/core/server/services/comments/moderation/phases/commentLength.ts index cb51f1c56..c48db49fd 100644 --- a/src/core/server/services/comments/moderation/phases/commentLength.ts +++ b/src/core/server/services/comments/moderation/phases/commentLength.ts @@ -1,3 +1,6 @@ +import striptags from "striptags"; + +import { isNil } from "lodash"; import { GQLACTION_GROUP, GQLACTION_TYPE, @@ -9,28 +12,40 @@ import { IntermediatePhaseResult, } from "talk-server/services/comments/moderation"; -const testCharCount = (settings: Partial, length: number) => - settings.charCountEnable && settings.charCount && length > settings.charCount; +const testCharCount = ( + settings: Partial, + length: number +) => { + // settings.charCount.enable && settings.charCount && length > settings.charCount; + + if (settings.charCount && settings.charCount.enabled) { + if (!isNil(settings.charCount.min)) { + if (length < settings.charCount.min) { + return true; + } + } + if (!isNil(settings.charCount.max)) { + if (length > settings.charCount.max) { + return true; + } + } + } + + return false; +}; export const commentLength: IntermediateModerationPhase = ({ asset, tenant, comment, }): IntermediatePhaseResult | void => { - const length = comment.body ? comment.body.length : 0; + const length = comment.body ? striptags(comment.body).length : 0; - // Check to see if the body is too short, if it is, then complain about it! - if (length < 2) { - // TODO: (wyattjoh) return better error. - throw new Error("comment body too short"); - } - - // Reject if the comment is too long + // Reject if the comment is too long or too short. if ( testCharCount(tenant, length) || (asset.settings && testCharCount(asset.settings, length)) ) { - // Add the flag related to Trust to the comment. return { status: GQLCOMMENT_STATUS.REJECTED, actions: [