0

I want to validate my registration page and i am using Joi validation every thing working fine except google recaptcha.

Here is code for form validation snippet,

var UserSchema = Joi.object().keys({
    name: Joi.string().required(),
    username: Joi.string().alphanum().min(4).max(30).required(),
    email: Joi.string().email().required(),
    mobile: Joi.string().required(),
    password: Joi.string().regex(/^[a-zA-Z0-9]{8,30}$/),
    confirmationPassword: Joi.any().valid(Joi.ref('password')).required(),
    access_token: [Joi.string(), Joi.number()],
    recaptcha : Joi.string()    
});

Post request for registration page,

router.route('/register')
    .get(isNotAuthenticated, (req, res) => {
        res.render('register');
    })
    .post(async (req, res, next) => {
        try {
            const data = Joi.validate(req.body, UserSchema);
            if (data.error) {
                req.flash("error", "Enter Valid data");
                console.log(data.error);
                res.redirect('/register');
                return;
            }
            const user = await User.findOne({ username: data.value.username });
            if (user) {
                req.flash('error', 'Username already taken');
                res.redirect('/register');
                return;
            }
            if (req.body.captcha === undefined ||
                req.body.captcha === '' ||
                req.body.captcha === null) {
                res.redirect('/register');
                return;
            }
            const secretKey = '';
            const verifyUrl = `https://google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${req.body.captcha}&remoteip=${req.connection.remoteAddress}`;
            request(verifyUrl, async (err, response, body) => {
                try{
                    body = JSON.parse(body);
                    console.log(body);
                    if (body.success !== undefined && !body.success) {
                        res.redirect('/register');
                        return;
                    } else {
                        const newUser = await new User(data.value);
                        console.log('newUser', newUser);
                        await newUser.save();
                    }
                }catch(e){
                    throw e;
                }

            });  
            req.flash('success', 'Please check your email.');
            res.redirect('/login');
        } catch (error) {
            next(error);
        }
    });

When i click on submit i got error message in console that { ValidationError: "g-recaptcha-response" is not allowed

Nikhil Savaliya
  • 2,138
  • 4
  • 24
  • 45
  • Please do not make password rules. Especially ensuring only alphanumeric ASCII... See [Reference - Password Validation](https://stackoverflow.com/questions/48345922) for more info. – ctwheels Jan 30 '18 at 15:01
  • it's not relevant to password @ctwheels – Nikhil Savaliya Jan 31 '18 at 03:30
  • On the contrary, it's very relevant as your password regex is only allowing combinations of 62 characters. – ctwheels Jan 31 '18 at 14:09
  • Have you actually inspected the request body before you validate it? Clearly `g-recaptcha-response` is being added to it and you're perhaps not aware? – Ankh Feb 01 '18 at 08:04
  • Joi validator was validating whole body, not accepting `g-recaptcha-response` and now i solved it – Nikhil Savaliya Feb 01 '18 at 08:40

1 Answers1

0

You could access g-recaptcha-response using bracket notation. So in your Joi schema the property should look something like this:

["g-recaptcha-response"]: Joi.string().required();
ToN
  • 26
  • 1
  • 6