File tree 11 files changed +97
-2
lines changed
11 files changed +97
-2
lines changed Original file line number Diff line number Diff line change @@ -8,4 +8,5 @@ module.exports = {
8
8
trackingID : 'UA-86112397-1' ,
9
9
} ,
10
10
} ,
11
+ recaptcha : require ( './recaptcha/client' ) ,
11
12
} ;
Original file line number Diff line number Diff line change
1
+ module . exports = {
2
+ development : {
3
+ siteKey : '6LfQGgoUAAAAAANHp6AvQOYD81JU9GnThpiIK7pH' ,
4
+ } ,
5
+ test : {
6
+ siteKey : '6LfQGgoUAAAAAANHp6AvQOYD81JU9GnThpiIK7pH' ,
7
+ } ,
8
+ production : {
9
+ siteKey : '6LeoHAoUAAAAAHKlo43OuPREJb22GLmik2HSaFC1' ,
10
+ } ,
11
+ } ;
Original file line number Diff line number Diff line change
1
+ module . exports = {
2
+ development : {
3
+ secretKey : 'akb48akb48akb48akb48akb48akb48akb48akb48' ,
4
+ } ,
5
+ test : {
6
+ secretKey : 'akb48akb48akb48akb48akb48akb48akb48akb48' ,
7
+ } ,
8
+ production : {
9
+ secretKey : 'akc49akc49akc49akc49akc49akc49akc49akc49' ,
10
+ } ,
11
+ } ;
Original file line number Diff line number Diff line change @@ -18,5 +18,6 @@ if (process.env.TRAVIS) {
18
18
facebook : require ( './passportStrategy/facebook/credential' ) ,
19
19
linkedin : require ( './passportStrategy/linkedin/credential' ) ,
20
20
} ,
21
+ recaptcha : require ( './recaptcha/credential' ) ,
21
22
} ;
22
23
}
Original file line number Diff line number Diff line change 115
115
"react-bootstrap" : " ^0.30.5" ,
116
116
"react-dom" : " ^15.0.2" ,
117
117
"react-ga" : " ^2.1.2" ,
118
+ "react-google-recaptcha" : " ^0.5.4" ,
118
119
"react-helmet" : " ^3.0.2" ,
119
120
"react-intl" : " ^2.1.2" ,
120
121
"react-native" : " ^0.31.0" ,
Original file line number Diff line number Diff line change @@ -8,6 +8,7 @@ import userAPI from '../../api/user';
8
8
import { validateForm } from '../../actions/formActions' ;
9
9
import { pushErrors } from '../../actions/errorActions' ;
10
10
import { Form , FormField , FormFooter } from '../utils/BsForm' ;
11
+ import configs from '../../../../configs/project/client' ;
11
12
12
13
const validate = ( values ) => {
13
14
const errors = { } ;
@@ -24,6 +25,10 @@ const validate = (values) => {
24
25
errors . password = 'Required' ;
25
26
}
26
27
28
+ if ( configs . recaptcha && ! values . recaptcha ) {
29
+ errors . recaptcha = 'Required' ;
30
+ }
31
+
27
32
return errors ;
28
33
} ;
29
34
@@ -90,6 +95,12 @@ class RegisterForm extends Component {
90
95
type = "password"
91
96
placeholder = "Password"
92
97
/>
98
+ < Field
99
+ label = " "
100
+ name = "recaptcha"
101
+ component = { FormField }
102
+ type = "recaptcha"
103
+ />
93
104
< FormFooter >
94
105
< Button
95
106
type = "submit"
Original file line number Diff line number Diff line change @@ -4,6 +4,8 @@ import BsFormGroup from 'react-bootstrap/lib/FormGroup';
4
4
import Col from 'react-bootstrap/lib/Col' ;
5
5
import ControlLabel from 'react-bootstrap/lib/ControlLabel' ;
6
6
import HelpBlock from 'react-bootstrap/lib/HelpBlock' ;
7
+ import Recaptcha from 'react-google-recaptcha' ;
8
+ import configs from '../../../../configs/project/client' ;
7
9
8
10
class BsForm extends Component {
9
11
getChildContext ( ) {
@@ -65,7 +67,20 @@ let BsFormField = ({
65
67
let isShowError = meta && meta . touched && meta . error ;
66
68
67
69
let formControl = null ;
68
- if ( options ) {
70
+ if ( type === 'recaptcha' ) {
71
+ // ref:
72
+ // - <https://github.com/erikras/redux-form/issues/1880>
73
+ /* eslint-disable */
74
+ formControl = configs . recaptcha ? (
75
+ < Recaptcha
76
+ sitekey = { configs . recaptcha [ process . env . NODE_ENV ] . siteKey }
77
+ onChange = { input . onChange }
78
+ />
79
+ ) : (
80
+ < pre > Recaptcha is disabled</ pre >
81
+ ) ;
82
+ /* eslint-enable */
83
+ } else if ( options ) {
69
84
// ref: <https://github.com/erikras/redux-form/issues/1857#issuecomment-249890206>
70
85
formControl = (
71
86
options . map ( ( option ) => (
Original file line number Diff line number Diff line change @@ -8,5 +8,6 @@ export default {
8
8
LOCALE_NOT_SUPPORTED : 'LOCALE_NOT_SUPPORTED' ,
9
9
USER_TOKEN_EXPIRATION : 'USER_TOKEN_EXPIRATION' ,
10
10
ODM_VALIDATION : 'ODM_VALIDATION' ,
11
+ INVALID_RECAPTCHA : 'INVALID_RECAPTCHA' ,
11
12
SOCIAL_AUTH_FAIL : 'SOCIAL_AUTH_FAIL' ,
12
13
} ;
Original file line number Diff line number Diff line change @@ -19,6 +19,12 @@ export default {
19
19
title : 'Database Validation Failed' ,
20
20
detail : 'The data is invalid.' ,
21
21
} ,
22
+ [ ErrorCodes . INVALID_RECAPTCHA ] : {
23
+ code : ErrorCodes . INVALID_RECAPTCHA ,
24
+ status : 400 ,
25
+ title : 'Invalid Recaptcha' ,
26
+ detail : 'The value of recaptcha is invalid.' ,
27
+ } ,
22
28
[ ErrorCodes . STATE_PRE_FETCHING_FAIL ] : {
23
29
code : ErrorCodes . STATE_PRE_FETCHING_FAIL ,
24
30
status : 500 ,
Original file line number Diff line number Diff line change
1
+ import superagent from 'superagent' ;
2
+ import Errors from '../../common/constants/Errors' ;
3
+ import serverConfigs from '../../../configs/project/server' ;
4
+ import clientConfigs from '../../../configs/project/client' ;
5
+
6
+ export default ( req , res , next ) => {
7
+ if ( process . env . NODE_ENV === 'test' || ! clientConfigs . recaptcha ) {
8
+ return next ( ) ;
9
+ }
10
+ superagent
11
+ . post ( 'https://www.google.com/recaptcha/api/siteverify' )
12
+ . type ( 'form' )
13
+ . send ( {
14
+ secret : serverConfigs . recaptcha [ process . env . NODE_ENV ] . secretKey ,
15
+ response : req . body . recaptcha ,
16
+ } )
17
+ . end ( ( err , { body } = { } ) => {
18
+ if ( err ) {
19
+ res . pushError ( Errors . UNKNOWN_EXCEPTION , {
20
+ meta : err ,
21
+ } ) ;
22
+ return res . errors ( ) ;
23
+ }
24
+ if ( ! body . success ) {
25
+ res . pushError ( Errors . INVALID_RECAPTCHA , {
26
+ meta : body [ 'error-codes' ] ,
27
+ } ) ;
28
+ return res . errors ( ) ;
29
+ }
30
+ next ( ) ;
31
+ } ) ;
32
+ } ;
Original file line number Diff line number Diff line change 1
1
import configs from '../../../configs/project/server' ;
2
2
import Roles from '../../common/constants/Roles' ;
3
3
import bodyParser from '../middlewares/bodyParser' ;
4
+ import verifyRecaptcha from '../middlewares/verifyRecaptcha' ;
4
5
import authRequired from '../middlewares/authRequired' ;
5
6
import roleRequired from '../middlewares/roleRequired' ;
6
7
import fileUpload from '../middlewares/fileUpload' ;
@@ -16,7 +17,11 @@ export default ({ app }) => {
16
17
roleRequired ( [ Roles . ADMIN ] ) ,
17
18
userController . list
18
19
) ;
19
- app . post ( '/api/users' , bodyParser . json , userController . create ) ;
20
+ app . post ( '/api/users' ,
21
+ bodyParser . json ,
22
+ verifyRecaptcha ,
23
+ userController . create
24
+ ) ;
20
25
app . post ( '/api/users/login' , bodyParser . json , userController . login ) ;
21
26
app . get ( '/api/users/logout' , userController . logout ) ;
22
27
app . get ( '/api/users/me' , authRequired , userController . show ) ;
You can’t perform that action at this time.
0 commit comments