diff --git a/dev/u-wave-dev-server b/dev/u-wave-dev-server index 409f282e..6aee341c 100755 --- a/dev/u-wave-dev-server +++ b/dev/u-wave-dev-server @@ -8,7 +8,7 @@ const explain = require('explain-error'); const announce = require('u-wave-announce'); const ytSource = require('u-wave-source-youtube'); const scSource = require('u-wave-source-soundcloud'); -const recaptchaTestKeys = require('recaptcha-test-keys'); +const hcaptchaTestKeys = require('hcaptcha-test-keys'); const debug = require('debug')('uwave:dev-server'); const dotenv = require('dotenv'); diff --git a/package.json b/package.json index 96d57c99..9d0693d8 100644 --- a/package.json +++ b/package.json @@ -67,9 +67,9 @@ "eslint": "^7.2.0", "eslint-config-airbnb-base": "^14.2.0", "eslint-plugin-import": "^2.20.0", + "hcaptcha-test-keys": "^1.0.0", "mocha": "^8.0.1", "nodemon": "^2.0.2", - "recaptcha-test-keys": "^1.0.0", "sinon": "^9.0.0", "u-wave-announce": "^0.4.0" }, diff --git a/src/HttpApi.js b/src/HttpApi.js index eaa1f358..20754c66 100644 --- a/src/HttpApi.js +++ b/src/HttpApi.js @@ -104,11 +104,17 @@ class UwaveHttpApi extends Router { } if (options.recaptcha && !options.recaptcha.secret) { - throw new TypeError('ReCaptcha validation is enabled, but "options.recaptcha.secret" is ' - + 'not set. Please set "options.recaptcha.secret" to your ReCaptcha ' - + 'secret, or disable ReCaptcha validation by setting "options.recaptcha" ' + throw new TypeError('hCaptcha validation is enabled, but "options.recaptcha.secret" is ' + + 'not set. Please set "options.recaptcha.secret" to your hCaptcha ' + + 'secret, or disable hCaptcha validation by setting "options.recaptcha" ' + 'to "false".'); } + if (options.recaptcha && options.recaptcha.secret + && !options.recaptcha.secret.startsWith('0x')) { + throw new Error('hCaptcha validation is enabled, but "options.recaptcha.secret" does not ' + + 'look like an hCaptcha secret key. Please use the secret listed on ' + + 'https://dashboard.hcaptcha.com/welcome.'); + } if (options.onError != null && typeof options.onError !== 'function') { throw new TypeError('"options.onError" must be a function.'); diff --git a/src/controllers/authenticate.js b/src/controllers/authenticate.js index 89c5240d..2526f036 100644 --- a/src/controllers/authenticate.js +++ b/src/controllers/authenticate.js @@ -215,15 +215,15 @@ async function getSocketToken(req) { async function verifyCaptcha(responseString, options) { if (!options.recaptcha) { - debug('ReCaptcha validation is disabled'); + debug('hCaptcha validation is disabled'); return null; } if (!responseString) { - throw new Error('ReCaptcha validation failed. Please try again.'); + throw new Error('hCaptcha validation failed. Please try again.'); } - debug('recaptcha: sending siteverify request'); - const response = await fetch('https://www.google.com/recaptcha/api/siteverify', { + debug('hcaptcha: sending siteverify request'); + const response = await fetch('https://www.hcaptcha.com/siteverify', { method: 'post', headers: { 'content-type': 'application/x-www-form-urlencoded', @@ -237,10 +237,10 @@ async function verifyCaptcha(responseString, options) { const body = await response.json(); if (!body.success) { - debug('recaptcha: validation failure', body); - throw new Error('ReCaptcha validation failed. Please try again.'); + debug('hcaptcha: validation failure', body); + throw new Error('hCaptcha validation failed. Please try again.'); } else { - debug('recaptcha: ok'); + debug('hcaptcha: ok'); } return null;