41 lines
1.3 KiB
JavaScript
41 lines
1.3 KiB
JavaScript
import 'server-only';
|
|
import { getSiteIntegrations } from '../payload/index.js';
|
|
/**
|
|
* Verifies a Turnstile token with Cloudflare, server-side only.
|
|
*
|
|
* The secret comes from the SiteIntegrations global (editor-managed, per the
|
|
* plugin's "secrets in the panel" model), read via the Local API which bypasses
|
|
* access control. `server-only` guarantees this never reaches the browser
|
|
* bundle, keeping the secret off the client.
|
|
*
|
|
* Returns false on any failure (missing secret/token, network error, rejected
|
|
* challenge) — callers treat false as "do not trust this submission".
|
|
*/ export async function verifyTurnstile({ ip, payload, token }) {
|
|
if (!token) {
|
|
return false;
|
|
}
|
|
const integrations = await getSiteIntegrations(payload);
|
|
const secret = integrations.turnstileSecretKey;
|
|
if (!secret) {
|
|
return false;
|
|
}
|
|
const body = new URLSearchParams({
|
|
response: token,
|
|
secret
|
|
});
|
|
if (ip) {
|
|
body.append('remoteip', ip);
|
|
}
|
|
try {
|
|
const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
|
|
body,
|
|
method: 'POST'
|
|
});
|
|
const data = await res.json();
|
|
return data.success;
|
|
} catch {
|
|
return false;
|
|
}
|
|
} //# sourceMappingURL=verify.js.map
|
|
|
|
//# sourceMappingURL=verify.js.map
|