Skip to content

Commit

Permalink
Merge branch 'feature/recaptcha-integration' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
gocreating committed Oct 24, 2016
2 parents e44eb0b + 90ceb05 commit 5655a29
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 2 deletions.
1 change: 1 addition & 0 deletions configs/project/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ module.exports = {
trackingID: 'UA-86112397-1',
},
},
recaptcha: require('./recaptcha/client'),
};
11 changes: 11 additions & 0 deletions configs/project/recaptcha/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
development: {
siteKey: '6LfQGgoUAAAAAANHp6AvQOYD81JU9GnThpiIK7pH',
},
test: {
siteKey: '6LfQGgoUAAAAAANHp6AvQOYD81JU9GnThpiIK7pH',
},
production: {
siteKey: '6LeoHAoUAAAAAHKlo43OuPREJb22GLmik2HSaFC1',
},
};
11 changes: 11 additions & 0 deletions configs/project/recaptcha/credential.tmpl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
development: {
secretKey: 'akb48akb48akb48akb48akb48akb48akb48akb48',
},
test: {
secretKey: 'akb48akb48akb48akb48akb48akb48akb48akb48',
},
production: {
secretKey: 'akc49akc49akc49akc49akc49akc49akc49akc49',
},
};
1 change: 1 addition & 0 deletions configs/project/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ if (process.env.TRAVIS) {
facebook: require('./passportStrategy/facebook/credential'),
linkedin: require('./passportStrategy/linkedin/credential'),
},
recaptcha: require('./recaptcha/credential'),
};
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
"react-bootstrap": "^0.30.5",
"react-dom": "^15.0.2",
"react-ga": "^2.1.2",
"react-google-recaptcha": "^0.5.4",
"react-helmet": "^3.0.2",
"react-intl": "^2.1.2",
"react-native": "^0.31.0",
Expand Down
11 changes: 11 additions & 0 deletions src/common/components/forms/RegisterForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import userAPI from '../../api/user';
import { validateForm } from '../../actions/formActions';
import { pushErrors } from '../../actions/errorActions';
import { Form, FormField, FormFooter } from '../utils/BsForm';
import configs from '../../../../configs/project/client';

const validate = (values) => {
const errors = {};
Expand All @@ -24,6 +25,10 @@ const validate = (values) => {
errors.password = 'Required';
}

if (configs.recaptcha && !values.recaptcha) {
errors.recaptcha = 'Required';
}

return errors;
};

Expand Down Expand Up @@ -90,6 +95,12 @@ class RegisterForm extends Component {
type="password"
placeholder="Password"
/>
<Field
label=" "
name="recaptcha"
component={FormField}
type="recaptcha"
/>
<FormFooter>
<Button
type="submit"
Expand Down
17 changes: 16 additions & 1 deletion src/common/components/utils/BsForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import BsFormGroup from 'react-bootstrap/lib/FormGroup';
import Col from 'react-bootstrap/lib/Col';
import ControlLabel from 'react-bootstrap/lib/ControlLabel';
import HelpBlock from 'react-bootstrap/lib/HelpBlock';
import Recaptcha from 'react-google-recaptcha';
import configs from '../../../../configs/project/client';

class BsForm extends Component {
getChildContext() {
Expand Down Expand Up @@ -65,7 +67,20 @@ let BsFormField = ({
let isShowError = meta && meta.touched && meta.error;

let formControl = null;
if (options) {
if (type === 'recaptcha') {
// ref:
// - <https://github.com/erikras/redux-form/issues/1880>
/* eslint-disable */
formControl = configs.recaptcha ? (
<Recaptcha
sitekey={configs.recaptcha[process.env.NODE_ENV].siteKey}
onChange={input.onChange}
/>
) : (
<pre>Recaptcha is disabled</pre>
);
/* eslint-enable */
} else if (options) {
// ref: <https://github.com/erikras/redux-form/issues/1857#issuecomment-249890206>
formControl = (
options.map((option) => (
Expand Down
1 change: 1 addition & 0 deletions src/common/constants/ErrorCodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export default {
LOCALE_NOT_SUPPORTED: 'LOCALE_NOT_SUPPORTED',
USER_TOKEN_EXPIRATION: 'USER_TOKEN_EXPIRATION',
ODM_VALIDATION: 'ODM_VALIDATION',
INVALID_RECAPTCHA: 'INVALID_RECAPTCHA',
SOCIAL_AUTH_FAIL: 'SOCIAL_AUTH_FAIL',
};
6 changes: 6 additions & 0 deletions src/common/constants/Errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export default {
title: 'Database Validation Failed',
detail: 'The data is invalid.',
},
[ErrorCodes.INVALID_RECAPTCHA]: {
code: ErrorCodes.INVALID_RECAPTCHA,
status: 400,
title: 'Invalid Recaptcha',
detail: 'The value of recaptcha is invalid.',
},
[ErrorCodes.STATE_PRE_FETCHING_FAIL]: {
code: ErrorCodes.STATE_PRE_FETCHING_FAIL,
status: 500,
Expand Down
32 changes: 32 additions & 0 deletions src/server/middlewares/verifyRecaptcha.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import superagent from 'superagent';
import Errors from '../../common/constants/Errors';
import serverConfigs from '../../../configs/project/server';
import clientConfigs from '../../../configs/project/client';

export default (req, res, next) => {
if (process.env.NODE_ENV === 'test' || !clientConfigs.recaptcha) {
return next();
}
superagent
.post('https://www.google.com/recaptcha/api/siteverify')
.type('form')
.send({
secret: serverConfigs.recaptcha[process.env.NODE_ENV].secretKey,
response: req.body.recaptcha,
})
.end((err, { body } = {}) => {
if (err) {
res.pushError(Errors.UNKNOWN_EXCEPTION, {
meta: err,
});
return res.errors();
}
if (!body.success) {
res.pushError(Errors.INVALID_RECAPTCHA, {
meta: body['error-codes'],
});
return res.errors();
}
next();
});
};
7 changes: 6 additions & 1 deletion src/server/routes/api.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import configs from '../../../configs/project/server';
import Roles from '../../common/constants/Roles';
import bodyParser from '../middlewares/bodyParser';
import verifyRecaptcha from '../middlewares/verifyRecaptcha';
import authRequired from '../middlewares/authRequired';
import roleRequired from '../middlewares/roleRequired';
import fileUpload from '../middlewares/fileUpload';
Expand All @@ -16,7 +17,11 @@ export default ({ app }) => {
roleRequired([Roles.ADMIN]),
userController.list
);
app.post('/api/users', bodyParser.json, userController.create);
app.post('/api/users',
bodyParser.json,
verifyRecaptcha,
userController.create
);
app.post('/api/users/login', bodyParser.json, userController.login);
app.get('/api/users/logout', userController.logout);
app.get('/api/users/me', authRequired, userController.show);
Expand Down

0 comments on commit 5655a29

Please sign in to comment.