diff --git a/lib/recaptcha.js b/lib/recaptcha.js index 17f2555..65c6e6b 100644 --- a/lib/recaptcha.js +++ b/lib/recaptcha.js @@ -1,165 +1,8 @@ -/*! - * node-recaptcha - * Copyright(c) 2010 Michael Hampton - * MIT Licensed - */ -/** - * Module dependencies. - */ +var v1 = require('./v1'); +var v2 = require('./v2'); -var http = require('http'), - querystring = require('querystring'); +exports.Recaptcha = v1.Recaptcha; -/** - * Constants. - */ - -var API_HOST = 'www.google.com', - API_END_POINT = '/recaptcha/api/verify', - SCRIPT_SRC = API_HOST + '/recaptcha/api/challenge', - NOSCRIPT_SRC = API_HOST + '/recaptcha/api/noscript'; - -/** - * Initialize Recaptcha with given `public_key`, `private_key` and optionally - * `data`. - * - * The `data` argument should have the following keys and values: - * - * remoteip: The IP of the client who submitted the form. - * challenge: The value of `recaptcha_challenge_field` from the Recaptcha - * form. - * response: The value of `recaptcha_response_field` from the Recaptcha - * form. - * - * @param {String} public_key Your Recaptcha public key. - * @param {String} private_key Your Recaptcha private key. - * @param {Object} data The Recaptcha data to be verified. See above for - * format. (optional) - * @param {Boolean} secure Flag for using https connections to load client-facing things. (optional) - * @api public - */ - -var Recaptcha = exports.Recaptcha = function Recaptcha(public_key, private_key, data, secure) { - this.public_key = public_key; - this.private_key = private_key; - if (typeof(data) == 'boolean'){ - this.data = undefined; - this.is_secure = data; - } - else { - this.data = data; - this.is_secure = secure; - } - - return this; -} - -/** - * Render the Recaptcha fields as HTML. - * - * If there was an error during `verify` and the selected Recaptcha theme - * supports it, it will be displayed. - * - * @api public - */ - -Recaptcha.prototype.toHTML = function() { - var query_string = 'k=' + this.public_key; - if (this.error_code) { - query_string += '&error=' + this.error_code; - } - - var script_src = (this.is_secure ? "https://" : "http://") + SCRIPT_SRC + '?' + query_string; - var noscript_src = (this.is_secure ? "https://" : "http://") + NOSCRIPT_SRC + '?' + query_string; - - return '' + - ''; -}; - -/** - * Verify the Recaptcha response. - * - * Example usage: - * - * var recaptcha = new Recaptcha('PUBLIC_KEY', 'PRIVATE_KEY', data); - * recaptcha.verify(function(success, error_code) { - * if (success) { - * // data was valid. Continue onward. - * } - * else { - * // data was invalid, redisplay the form using - * // recaptcha.toHTML(). - * } - * }); - * - * @param {Function} callback - * @api public - */ - -Recaptcha.prototype.verify = function(callback) { - var self = this; - - // See if we can declare this invalid without even contacting Recaptcha. - if (typeof(this.data) === 'undefined') { - this.error_code = 'verify-params-incorrect'; - return callback(false, 'verify-params-incorrect'); - } - if (!('remoteip' in this.data && - 'challenge' in this.data && - 'response' in this.data)) - { - this.error_code = 'verify-params-incorrect'; - return callback(false, 'verify-params-incorrect'); - } - if (this.data.response === '') { - this.error_code = 'incorrect-captcha-sol'; - return callback(false, 'incorrect-captcha-sol'); - } - - // Add the private_key to the request. - this.data['privatekey'] = this.private_key; - var data_qs = querystring.stringify(this.data); - - var req_options = { - host: API_HOST, - path: API_END_POINT, - port: 80, - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': data_qs.length - } - }; - - var request = http.request(req_options, function(response) { - var body = ''; - - response.on('error', function(err) { - self.error_code = 'recaptcha-not-reachable'; - callback(false, 'recaptcha-not-reachable'); - }); - - response.on('data', function(chunk) { - body += chunk; - }); - - response.on('end', function() { - var success, error_code, parts; - - parts = body.split('\n'); - success = parts[0]; - error_code = parts[1]; - - if (success !== 'true') { - self.error_code = error_code; - } - return callback(success === 'true', error_code); - }); - }); - request.write(data_qs, 'utf8'); - request.end(); -}; +exports.v1 = exports.RecaptchaV1 = v1.Recaptcha; +exports.v2 = exports.RecaptchaV2 = v2.Recaptcha; diff --git a/lib/v1.js b/lib/v1.js new file mode 100644 index 0000000..17f2555 --- /dev/null +++ b/lib/v1.js @@ -0,0 +1,165 @@ +/*! + * node-recaptcha + * Copyright(c) 2010 Michael Hampton + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var http = require('http'), + querystring = require('querystring'); + +/** + * Constants. + */ + +var API_HOST = 'www.google.com', + API_END_POINT = '/recaptcha/api/verify', + SCRIPT_SRC = API_HOST + '/recaptcha/api/challenge', + NOSCRIPT_SRC = API_HOST + '/recaptcha/api/noscript'; + +/** + * Initialize Recaptcha with given `public_key`, `private_key` and optionally + * `data`. + * + * The `data` argument should have the following keys and values: + * + * remoteip: The IP of the client who submitted the form. + * challenge: The value of `recaptcha_challenge_field` from the Recaptcha + * form. + * response: The value of `recaptcha_response_field` from the Recaptcha + * form. + * + * @param {String} public_key Your Recaptcha public key. + * @param {String} private_key Your Recaptcha private key. + * @param {Object} data The Recaptcha data to be verified. See above for + * format. (optional) + * @param {Boolean} secure Flag for using https connections to load client-facing things. (optional) + * @api public + */ + +var Recaptcha = exports.Recaptcha = function Recaptcha(public_key, private_key, data, secure) { + this.public_key = public_key; + this.private_key = private_key; + if (typeof(data) == 'boolean'){ + this.data = undefined; + this.is_secure = data; + } + else { + this.data = data; + this.is_secure = secure; + } + + return this; +} + +/** + * Render the Recaptcha fields as HTML. + * + * If there was an error during `verify` and the selected Recaptcha theme + * supports it, it will be displayed. + * + * @api public + */ + +Recaptcha.prototype.toHTML = function() { + var query_string = 'k=' + this.public_key; + if (this.error_code) { + query_string += '&error=' + this.error_code; + } + + var script_src = (this.is_secure ? "https://" : "http://") + SCRIPT_SRC + '?' + query_string; + var noscript_src = (this.is_secure ? "https://" : "http://") + NOSCRIPT_SRC + '?' + query_string; + + return '' + + ''; +}; + +/** + * Verify the Recaptcha response. + * + * Example usage: + * + * var recaptcha = new Recaptcha('PUBLIC_KEY', 'PRIVATE_KEY', data); + * recaptcha.verify(function(success, error_code) { + * if (success) { + * // data was valid. Continue onward. + * } + * else { + * // data was invalid, redisplay the form using + * // recaptcha.toHTML(). + * } + * }); + * + * @param {Function} callback + * @api public + */ + +Recaptcha.prototype.verify = function(callback) { + var self = this; + + // See if we can declare this invalid without even contacting Recaptcha. + if (typeof(this.data) === 'undefined') { + this.error_code = 'verify-params-incorrect'; + return callback(false, 'verify-params-incorrect'); + } + if (!('remoteip' in this.data && + 'challenge' in this.data && + 'response' in this.data)) + { + this.error_code = 'verify-params-incorrect'; + return callback(false, 'verify-params-incorrect'); + } + if (this.data.response === '') { + this.error_code = 'incorrect-captcha-sol'; + return callback(false, 'incorrect-captcha-sol'); + } + + // Add the private_key to the request. + this.data['privatekey'] = this.private_key; + var data_qs = querystring.stringify(this.data); + + var req_options = { + host: API_HOST, + path: API_END_POINT, + port: 80, + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': data_qs.length + } + }; + + var request = http.request(req_options, function(response) { + var body = ''; + + response.on('error', function(err) { + self.error_code = 'recaptcha-not-reachable'; + callback(false, 'recaptcha-not-reachable'); + }); + + response.on('data', function(chunk) { + body += chunk; + }); + + response.on('end', function() { + var success, error_code, parts; + + parts = body.split('\n'); + success = parts[0]; + error_code = parts[1]; + + if (success !== 'true') { + self.error_code = error_code; + } + return callback(success === 'true', error_code); + }); + }); + request.write(data_qs, 'utf8'); + request.end(); +}; diff --git a/lib/v2.js b/lib/v2.js new file mode 100644 index 0000000..da9e291 --- /dev/null +++ b/lib/v2.js @@ -0,0 +1,154 @@ +/*! + * node-recaptcha + * Recaptcha v2 + * From: https://github.com/hgGeorg/node-recaptcha/blob/master/lib/recaptcha.js + */ + +/** + * Module dependencies. + */ + +var https = require('https'), + querystring = require('querystring'); + +/** + * Constants. + */ + +var API_HOST = 'www.google.com', + API_END_POINT = '/recaptcha/api/siteverify' + +/** + * Initialize Recaptcha with given `public_key`, `private_key` and optionally + * `data`. + * + * The `data` argument should have the following keys and values: + * + * remoteip: The IP of the client who submitted the form. + * challenge: The value of `recaptcha_challenge_field` from the Recaptcha + * form. + * response: The value of `recaptcha_response_field` from the Recaptcha + * form. + * + * @param {String} public_key Your Recaptcha public key. + * @param {String} private_key Your Recaptcha private key. + * @param {Object} data The Recaptcha data to be verified. See above for + * format. (optional) + * @param {Boolean} secure Flag for using https connections to load client-facing things. (optional) + * @api public + */ + +var Recaptcha = exports.Recaptcha = function Recaptcha(public_key, private_key, data, secure) { + this.public_key = public_key; + this.private_key = private_key; + if (typeof(data) == 'boolean'){ + this.data = undefined; + this.is_secure = data; + } + else { + this.data = data; + this.is_secure = secure; + } + + return this; +} + +/** + * Render the Recaptcha fields as HTML. + * + * If there was an error during `verify` and the selected Recaptcha theme + * supports it, it will be displayed. + * + * @api public + */ + +Recaptcha.prototype.toHTML = function() { + return "" + + "
" + + ""; +}; + +/** + * Verify the Recaptcha response. + * + * Example usage: + * + * var recaptcha = new Recaptcha('PUBLIC_KEY', 'PRIVATE_KEY', data); + * recaptcha.verify(function(success, error_code) { + * if (success) { + * // data was valid. Continue onward. + * } + * else { + * // data was invalid, redisplay the form using + * // recaptcha.toHTML(). + * } + * }); + * + * @param {Function} callback + * @api public + */ + +Recaptcha.prototype.verify = function(callback) { + var self = this; + + // See if we can declare this invalid without even contacting Recaptcha. + if (typeof(this.data) === 'undefined') { + this.error_code = 'verify-params-incorrect'; + return callback('verify-params-incorrect', false); + } + if (!('remoteip' in this.data && + 'response' in this.data)) + { + this.error_code = 'verify-params-incorrect'; + return callback(false, 'verify-params-incorrect'); + } + if (this.data.response === '') { + this.error_code = 'incorrect-captcha-sol'; + return callback('incorrect-captcha-sol', false); + } + + // Add the private_key to the request. + this.data['secret'] = this.private_key; + var data_qs = querystring.stringify(this.data); + + var req_options = { + host: API_HOST, + path: API_END_POINT, + port: 443, + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': data_qs.length + } + }; + + var request = https.request(req_options, function(response) { + var body = ''; + + response.on('error', function(err) { + self.error_code = 'recaptcha-not-reachable'; + callback('recaptcha-not-reachable', false); + }); + + response.on('data', function(chunk) { + body += chunk; + }); + + response.on('end', function() { + var result = JSON.parse(body); + return callback(result["error-codes"], result.success); + }); + }); + request.write(data_qs, 'utf8'); + request.end(); +};