mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-04-30 10:46:55 +00:00
port FriendlyCaptcha to the new captcha infrastructure
This commit is contained in:
parent
b5ff784b1c
commit
5781e99861
1 changed files with 31 additions and 6 deletions
|
@ -11,7 +11,7 @@ import { MiMeta } from '@/models/Meta.js';
|
||||||
import Logger from '@/logger.js';
|
import Logger from '@/logger.js';
|
||||||
import { LoggerService } from './LoggerService.js';
|
import { LoggerService } from './LoggerService.js';
|
||||||
|
|
||||||
export const supportedCaptchaProviders = ['none', 'hcaptcha', 'mcaptcha', 'recaptcha', 'turnstile', 'testcaptcha'] as const;
|
export const supportedCaptchaProviders = ['none', 'hcaptcha', 'mcaptcha', 'recaptcha', 'turnstile', 'fc', 'testcaptcha'] as const;
|
||||||
export type CaptchaProvider = typeof supportedCaptchaProviders[number];
|
export type CaptchaProvider = typeof supportedCaptchaProviders[number];
|
||||||
|
|
||||||
export const captchaErrorCodes = {
|
export const captchaErrorCodes = {
|
||||||
|
@ -43,6 +43,10 @@ export type CaptchaSetting = {
|
||||||
siteKey: string | null;
|
siteKey: string | null;
|
||||||
secretKey: string | null;
|
secretKey: string | null;
|
||||||
}
|
}
|
||||||
|
fc: {
|
||||||
|
siteKey: string | null;
|
||||||
|
secretKey: string | null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CaptchaError extends Error {
|
export class CaptchaError extends Error {
|
||||||
|
@ -141,7 +145,7 @@ export class CaptchaService {
|
||||||
@bindThis
|
@bindThis
|
||||||
public async verifyFriendlyCaptcha(secret: string, response: string | null | undefined): Promise<void> {
|
public async verifyFriendlyCaptcha(secret: string, response: string | null | undefined): Promise<void> {
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
throw new Error('frc-failed: no response provided');
|
throw new CaptchaError(captchaErrorCodes.noResponseProvided, 'frc-failed: no response provided');
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.httpRequestService.send('https://api.friendlycaptcha.com/api/v1/siteverify', {
|
const result = await this.httpRequestService.send('https://api.friendlycaptcha.com/api/v1/siteverify', {
|
||||||
|
@ -153,17 +157,17 @@ export class CaptchaService {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
}, { throwErrorWhenResponseNotOk: false });
|
||||||
|
|
||||||
if (result.status !== 200) {
|
if (result.status !== 200) {
|
||||||
throw new Error('frc-failed: frc didn\'t return 200 OK');
|
throw new CaptchaError(captchaErrorCodes.requestFailed, `frc-request-failed: ${result.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const resp = await result.json() as CaptchaResponse;
|
const resp = await result.json() as CaptchaResponse;
|
||||||
|
|
||||||
if (resp.success !== true) {
|
if (resp.success !== true) {
|
||||||
const errorCodes = resp['errors'] ? resp['errors'].join(', ') : '';
|
const errorCodes = resp['errors'] ? resp['errors'].join(', ') : '';
|
||||||
throw new Error(`frc-failed: ${errorCodes}`);
|
throw new CaptchaError(captchaErrorCodes.verificationFailed, `frc-failed: ${errorCodes}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,6 +257,10 @@ export class CaptchaService {
|
||||||
provider = 'testcaptcha';
|
provider = 'testcaptcha';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case meta.enableFC: {
|
||||||
|
provider = 'fc';
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
provider = 'none';
|
provider = 'none';
|
||||||
break;
|
break;
|
||||||
|
@ -278,6 +286,10 @@ export class CaptchaService {
|
||||||
siteKey: meta.turnstileSiteKey,
|
siteKey: meta.turnstileSiteKey,
|
||||||
secretKey: meta.turnstileSecretKey,
|
secretKey: meta.turnstileSecretKey,
|
||||||
},
|
},
|
||||||
|
fc: {
|
||||||
|
siteKey: meta.fcSiteKey,
|
||||||
|
secretKey: meta.fcSecretKey,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,6 +370,14 @@ export class CaptchaService {
|
||||||
await this.verifyTestcaptcha(params.captchaResult);
|
await this.verifyTestcaptcha(params.captchaResult);
|
||||||
await this.updateMeta(provider, params);
|
await this.updateMeta(provider, params);
|
||||||
},
|
},
|
||||||
|
fc: async () => {
|
||||||
|
if (!params?.secret || !params.captchaResult) {
|
||||||
|
throw new CaptchaError(captchaErrorCodes.invalidParameters, 'frc-failed: secret and captureResult are required');
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.verifyFriendlyCaptcha(params.captchaResult, params.captchaResult);
|
||||||
|
await this.updateMeta(provider, params);
|
||||||
|
},
|
||||||
}[provider];
|
}[provider];
|
||||||
|
|
||||||
return operation()
|
return operation()
|
||||||
|
@ -390,7 +410,7 @@ export class CaptchaService {
|
||||||
('enableMcaptcha' | 'mcaptchaSitekey' | 'mcaptchaSecretKey' | 'mcaptchaInstanceUrl') |
|
('enableMcaptcha' | 'mcaptchaSitekey' | 'mcaptchaSecretKey' | 'mcaptchaInstanceUrl') |
|
||||||
('enableRecaptcha' | 'recaptchaSiteKey' | 'recaptchaSecretKey') |
|
('enableRecaptcha' | 'recaptchaSiteKey' | 'recaptchaSecretKey') |
|
||||||
('enableTurnstile' | 'turnstileSiteKey' | 'turnstileSecretKey') |
|
('enableTurnstile' | 'turnstileSiteKey' | 'turnstileSecretKey') |
|
||||||
('enableTestcaptcha')
|
('enableTestcaptcha' | 'enableFC' | 'fcSiteKey' | 'fcSecretKey')
|
||||||
>
|
>
|
||||||
> = {
|
> = {
|
||||||
enableHcaptcha: provider === 'hcaptcha',
|
enableHcaptcha: provider === 'hcaptcha',
|
||||||
|
@ -398,6 +418,7 @@ export class CaptchaService {
|
||||||
enableRecaptcha: provider === 'recaptcha',
|
enableRecaptcha: provider === 'recaptcha',
|
||||||
enableTurnstile: provider === 'turnstile',
|
enableTurnstile: provider === 'turnstile',
|
||||||
enableTestcaptcha: provider === 'testcaptcha',
|
enableTestcaptcha: provider === 'testcaptcha',
|
||||||
|
enableFC: provider === 'fc',
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateIfNotUndefined = <K extends keyof typeof metaPartial>(key: K, value: typeof metaPartial[K]) => {
|
const updateIfNotUndefined = <K extends keyof typeof metaPartial>(key: K, value: typeof metaPartial[K]) => {
|
||||||
|
@ -427,6 +448,10 @@ export class CaptchaService {
|
||||||
updateIfNotUndefined('turnstileSecretKey', params?.secret);
|
updateIfNotUndefined('turnstileSecretKey', params?.secret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'fc': {
|
||||||
|
updateIfNotUndefined('fcSiteKey', params?.sitekey);
|
||||||
|
updateIfNotUndefined('fcSecretKey', params?.secret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.metaService.update(metaPartial);
|
await this.metaService.update(metaPartial);
|
||||||
|
|
Loading…
Add table
Reference in a new issue