summaryrefslogtreecommitdiff
path: root/src/misc
diff options
context:
space:
mode:
authorMeiMei <30769358+mei23@users.noreply.github.com>2021-02-06 11:46:47 +0900
committerGitHub <noreply@github.com>2021-02-06 11:46:47 +0900
commit0e45f10d99589348cc95bd044e9d06bc8dc1a10a (patch)
tree9f0c0546840d4354ec2f86eddb7da9d9a8ec3c59 /src/misc
parentdiscordapp.com → discord.com (#7140) (diff)
downloadsharkey-0e45f10d99589348cc95bd044e9d06bc8dc1a10a.tar.gz
sharkey-0e45f10d99589348cc95bd044e9d06bc8dc1a10a.tar.bz2
sharkey-0e45f10d99589348cc95bd044e9d06bc8dc1a10a.zip
Improve captcha (#7138)
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/captcha.ts56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/misc/captcha.ts b/src/misc/captcha.ts
new file mode 100644
index 0000000000..87ec143ca8
--- /dev/null
+++ b/src/misc/captcha.ts
@@ -0,0 +1,56 @@
+import fetch from 'node-fetch';
+import { URLSearchParams } from 'url';
+import { getAgentByUrl } from './fetch';
+import config from '../config';
+
+export async function verifyRecaptcha(secret: string, response: string) {
+ const result = await getCaptchaResponse('https://www.recaptcha.net/recaptcha/api/siteverify', secret, response).catch(e => {
+ throw `recaptcha-request-failed: ${e}`;
+ });
+
+ if (result.success !== true) {
+ const errorCodes = result['error-codes'] ? result['error-codes']?.join(', ') : '';
+ throw `recaptcha-failed: ${errorCodes}`;
+ }
+}
+
+export async function verifyHcaptcha(secret: string, response: string) {
+ const result = await getCaptchaResponse('https://hcaptcha.com/siteverify', secret, response).catch(e => {
+ throw `hcaptcha-request-failed: ${e}`;
+ });
+
+ if (result.success !== true) {
+ const errorCodes = result['error-codes'] ? result['error-codes']?.join(', ') : '';
+ throw `hcaptcha-failed: ${errorCodes}`;
+ }
+}
+
+type CaptchaResponse = {
+ success: boolean;
+ 'error-codes'?: string[];
+};
+
+async function getCaptchaResponse(url: string, secret: string, response: string): Promise<CaptchaResponse> {
+ const params = new URLSearchParams({
+ secret,
+ response
+ });
+
+ const res = await fetch(url, {
+ method: 'POST',
+ body: params,
+ headers: {
+ 'User-Agent': config.userAgent
+ },
+ timeout: 10 * 1000,
+ agent: getAgentByUrl
+ }).catch(e => {
+ throw `${e.message || e}`;
+ });
+
+ if (!res.ok) {
+ throw `${res.status}`;
+ }
+
+ return await res.json() as CaptchaResponse;
+}