aboutsummaryrefslogtreecommitdiff
path: root/src/integrations/hcaptcha.ts
blob: 78ff356c925a5b940a88e912630952206450e54b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { Either, type IEither } from '@emprespresso/pengueno';

export interface HCaptchaResponse {
    success: boolean;
    challenge_ts?: string;
    hostname?: string;
    'error-codes'?: string[];
}

export async function verifyHCaptcha(token: string, secret: string): Promise<IEither<Error, boolean>> {
    try {
        const response = await fetch('https://hcaptcha.com/siteverify', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                secret,
                response: token,
            }),
        });

        if (!response.ok) {
            return Either.left(new Error(`hCaptcha verification failed: ${response.statusText}`));
        }

        const result = (await response.json()) as HCaptchaResponse;
        return Either.right(result.success);
    } catch (err) {
        return Either.left(err instanceof Error ? err : new Error(String(err)));
    }
}