From 4f3829a67c32a85fb57c65b3704e08d64f76d92f Mon Sep 17 00:00:00 2001 From: Brian Kruger Date: Wed, 27 Jul 2016 14:29:45 -0700 Subject: [PATCH 1/2] Add ability to force email and real name fields via env file. TODO: apply these changes to frontend ui as well. --- .env.SAMPLE | 6 ++++++ README.md | 7 ++++++- deploy/apex/webpack.config.es6.js | 9 +++++++++ packages/frontend/src/ui/postCommentForm.js | 4 ++-- packages/lambda/src/queueComment/index.js | 7 +++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/.env.SAMPLE b/.env.SAMPLE index 8ff6652..0d8bfc2 100644 --- a/.env.SAMPLE +++ b/.env.SAMPLE @@ -19,3 +19,9 @@ STAGE=prod # A Slack webhook to send notifications to (optional) #SLACK=https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ +# Require author email address - string is error message to display. +#REQEMAIL='Email is required.' + +# Require author name - string is error message to display. +#REQNAME='Name is required.' + diff --git a/README.md b/README.md index 1e14d66..5ca3ff0 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,12 @@ STAGE=prod # A Slack webhook to send notifications to (optional) #SLACK=https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ -``` + +# Require author email address - string is error message to display. +#REQEMAIL='Email is required.' + +# Require author name - string is error message to display. +#REQNAME='Name is required.' We use [dotenv](https://github.com/motdotla/dotenv) so it is also possible to configure the project by setting environment variables. diff --git a/deploy/apex/webpack.config.es6.js b/deploy/apex/webpack.config.es6.js index eeebdcb..b24de58 100644 --- a/deploy/apex/webpack.config.es6.js +++ b/deploy/apex/webpack.config.es6.js @@ -37,6 +37,15 @@ if (process.env.SLACK) { defines['process.env.SLACK'] = `'${process.env.SLACK}'` } +if (process.env.REQEMAIL) { + defines['process.env.REQEMAIL'] = `'${process.env.REQEMAIL}'` +} + +if (process.env.REQNAME) { + defines['process.env.REQNAME'] = `'${process.env.REQNAME}'` +} + + export default { entry: { [lambdaDirNames['QueueComment']]: [ diff --git a/packages/frontend/src/ui/postCommentForm.js b/packages/frontend/src/ui/postCommentForm.js index d6b636b..1e2209e 100644 --- a/packages/frontend/src/ui/postCommentForm.js +++ b/packages/frontend/src/ui/postCommentForm.js @@ -175,7 +175,7 @@ export default class PostCommentForm extends Component { } Date: Thu, 15 Sep 2016 18:13:08 -0700 Subject: [PATCH 2/2] add frontend validation before lambda post added content length and (mostly) blank post checking added bonus - comment box counter --- .env.SAMPLE | 6 +++++ deploy/apex/webpack.config.es6.js | 7 ++++++ packages/frontend/package.json | 1 + packages/frontend/src/actions/comments.js | 4 +++ packages/frontend/src/ui/comments.css | 7 ++++++ packages/frontend/src/ui/postCommentForm.js | 28 ++++++++++++++++++--- packages/frontend/webpack.config.js | 9 ++++++- packages/lambda/src/queueComment/index.js | 8 ++++++ 8 files changed, 66 insertions(+), 4 deletions(-) diff --git a/.env.SAMPLE b/.env.SAMPLE index 0d8bfc2..01d4fe5 100644 --- a/.env.SAMPLE +++ b/.env.SAMPLE @@ -25,3 +25,9 @@ STAGE=prod # Require author name - string is error message to display. #REQNAME='Name is required.' +# Size limit of post in bytes +#SIZELIMIT=4096 + +# Disallow empty content (spaces only, etc.) - string is error message to display. +#DISALLOW_EMPTY='You need to actually use words.' + diff --git a/deploy/apex/webpack.config.es6.js b/deploy/apex/webpack.config.es6.js index b24de58..e15c49a 100644 --- a/deploy/apex/webpack.config.es6.js +++ b/deploy/apex/webpack.config.es6.js @@ -45,6 +45,13 @@ if (process.env.REQNAME) { defines['process.env.REQNAME'] = `'${process.env.REQNAME}'` } +if (process.env.SIZELIMIT) { + defines['process.env.SIZELIMIT'] = `'${process.env.SIZELIMIT}'` +} + +if (process.env.DISALLOW_EMPTY) { + defines['process.env.DISALLOW_EMPTY'] = `'${process.env.DISALLOW_EMPTY}'` +} export default { entry: { diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 9ae8f78..3c19525 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -78,6 +78,7 @@ "react-measure": "0.3.5", "react-motion": "0.4.2", "react-project": "0.0.30", + "react-redux": "4.4.5", "react-router": "2.0.0", "react-router-redux": "4.0.2", "react-spinner": "0.2.6", diff --git a/packages/frontend/src/actions/comments.js b/packages/frontend/src/actions/comments.js index 823cbc3..94822ac 100644 --- a/packages/frontend/src/actions/comments.js +++ b/packages/frontend/src/actions/comments.js @@ -25,6 +25,10 @@ export const FORM_FIELDS = [ const websiteUrl = __CONFIG__.websiteUrl const apiUrl = __CONFIG__.apiUrl const apiKey = __CONFIG__.apiKey +const authorNameRequired = __CONFIG__.authorNameRequired +const authorEmailRequired = __CONFIG__.authorEmailRequired +const contentSizeLimit = __CONFIG__.contentSizeLimit +const disallowEmptyContent = __CONFIG__.disallowEmptyContent class ValidationError extends Error { constructor (data) { diff --git a/packages/frontend/src/ui/comments.css b/packages/frontend/src/ui/comments.css index 26f9e24..5663dbb 100644 --- a/packages/frontend/src/ui/comments.css +++ b/packages/frontend/src/ui/comments.css @@ -97,6 +97,13 @@ } } +.commentCounter { + font-size: 13px; + color: gray; + text-decoration: none; + padding-left: 10px; +} + .previewWrapper { overflow-y: hidden; } diff --git a/packages/frontend/src/ui/postCommentForm.js b/packages/frontend/src/ui/postCommentForm.js index 1e2209e..3e838c9 100644 --- a/packages/frontend/src/ui/postCommentForm.js +++ b/packages/frontend/src/ui/postCommentForm.js @@ -16,6 +16,7 @@ import { errorMessage, postCommentFormHeader, markdownNote, + commentCounter, previewWrapper, preview, spinnerButton, @@ -27,15 +28,34 @@ import { } from './comments.css' import { FORM_NAME, FORM_FIELDS } from '../actions/comments' +const authorNameRequired = __CONFIG__.authorNameRequired +const authorEmailRequired = __CONFIG__.authorEmailRequired +const contentSizeLimit = __CONFIG__.contentSizeLimit +const disallowEmptyContent = __CONFIG__.disallowEmptyContent + +let contentRegex = /\w+/ + function validate (values) { const errors = {} - const { commentContent, authorEmail, authorUrl } = values + const { commentContent, authorName, authorEmail, authorUrl } = values if (!commentContent) { errors.commentContent = 'Required' } if (commentContent && commentContent.length < 3) { errors.commentContent = 'Must be at least 3 characters' } + if (commentContent && contentSizeLimit && (commentContent.length > parseInt(contentSizeLimit))) { + errors.commentContent = 'Comment has exceeded content length of: ' + parseInt(contentSizeLimit) + ' characters.' + } + if (commentContent && disallowEmptyContent && !commentContent.match(contentRegex)) { + errors.commentContent = disallowEmptyContent + } + if (authorNameRequired && !authorName) { + errors.authorName = authorNameRequired + } + if (authorEmailRequired && !authorEmail) { + errors.authorEmail = authorEmailRequired + } if (authorEmail && !isEmail(authorEmail)) { errors.authorEmail = 'Email format not valid' } @@ -138,6 +158,7 @@ export default class PostCommentForm extends Component { date: new Date(), commentContent: commentContent.value, } + const length = commentContent.value ? commentContent.value.length : 0 return (
Add your comment + {length} { @@ -69,7 +72,11 @@ function modifyClient (webpackConfig) { '__CONFIG__': JSON.stringify({ apiUrl, websiteUrl, - apiKey + apiKey, + authorNameRequired, + authorEmailRequired, + contentSizeLimit, + disallowEmptyContent }) })) webpackConfig.plugins = plugins diff --git a/packages/lambda/src/queueComment/index.js b/packages/lambda/src/queueComment/index.js index 81f7fe2..d238d82 100644 --- a/packages/lambda/src/queueComment/index.js +++ b/packages/lambda/src/queueComment/index.js @@ -15,8 +15,10 @@ dotenv.config({ silent: true }) const hmac = jwa('HS256') const { REQEMAIL: authorEmailRequired, REQNAME: authorNameRequired } = process.env +const { SIZELIMIT: contentSizeLimit, DISALLOW_EMPTY: disallowEmptyContent } = process.env let akismet = null +let contentRegex = /\w+/ class ValidationError extends Error { constructor (data) { @@ -57,6 +59,12 @@ function validate (payload) { if (commentContent && commentContent.length < 3) { errors.commentContent = 'Must be at least 3 characters' } + if (commentContent && contentSizeLimit && (commentContent.length > parseInt(contentSizeLimit))) { + errors.commentContent = 'Comment has exceeded content length of: ' + parseInt(contentSizeLimit) + ' characters.' + } + if (commentContent && disallowEmptyContent && !commentContent.match(contentRegex)) { + errors.commentContent = disallowEmptyContent + } if (authorNameRequired && !authorName) { errors.authorName = authorNameRequired }