UNPKG

verify-hcaptcha

Version:

A fully typed library to verify hCaptcha.com tokens submitted by users when solving captcha challenges

80 lines (79 loc) 2.9 kB
// src/index.ts import { z } from "zod"; var hCaptchaResponseSchema = z.object({ success: z.boolean(), challenge_ts: z.string().optional(), hostname: z.string().optional(), credit: z.boolean().optional(), "error-codes": z.array( z.union([ /** Secret key is missing. */ z.literal("missing-input-secret"), /** Secret key is invalid. */ z.literal("invalid-input-secret"), /** User response token is missing. */ z.literal("missing-input-response"), /** User response token is invalid. */ z.literal("invalid-input-response"), /** Site key is invalid. */ z.literal("invalid-sitekey"), /** Remote user IP is missing. */ z.literal("missing-remoteip"), /** Remote user IP is invalid. */ z.literal("invalid-remoteip"), /** Request is invalid. */ z.literal("bad-request"), /** User response token is invalid or has already been checked. */ z.literal("invalid-or-already-seen-response"), /** Must use the test site key when using a test verification token. */ z.literal("not-using-dummy-passcode"), /** Must use the test secret key when using a test verification token. */ z.literal("not-using-dummy-secret"), /** The site key is not associated to the secret key. */ z.literal("sitekey-secret-mismatch") ]) ).optional(), score: z.number().optional(), "score-reason": z.array(z.string()).optional() }).transform(({ success, hostname, credit, score, ...rest }) => ({ /** True if the token is valid and meets the specified security criteria (e.g., if the site key is associated to the secret key). */ success, /** UTC timestamp of the challenge in ISO 8601 format (e.g., `2021-10-02T18:12:10.149Z`). */ challengeTimestamp: rest.challenge_ts, /** Hostname of the website where the challenge was solved. */ hostname, /** True if the response will be credited. @deprecated */ credit, /** Error codes. @see {@link https://docs.hcaptcha.com/#siteverify-error-codes-table} */ errorCodes: rest["error-codes"], /** Enterprise-only feature: score for malicious activity. */ score, /** Enterprise-only feature: list of reasons for the malicious activity score. */ scoreReasons: rest["score-reason"] })); async function verifyHcaptchaToken({ token, secretKey, siteKey, remoteIp }) { const form = new URLSearchParams(); form.append("response", token); form.append("secret", secretKey); if (siteKey) { form.append("sitekey", siteKey); } if (remoteIp) { form.append("remoteip", remoteIp); } const response = await fetch("https://api.hcaptcha.com/siteverify", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: form.toString() }); const json = await response.json(); return hCaptchaResponseSchema.parse(json); } export { verifyHcaptchaToken };