Refactor CAPTCHA setup verification
Eliminated constant verification of CAPTCHA setup across different modules and refactored the CAPTCHA token verification process. This commit relies on config parameters to decide whether to verify CAPTCHA or not, instead of environment variables. It also reforms the token submission to CAPTCHA service for consistency and clarity.
This commit is contained in:
@@ -3,20 +3,26 @@ import 'server-only';
|
||||
const verifyEndpoint =
|
||||
'https://challenges.cloudflare.com/turnstile/v0/siteverify';
|
||||
|
||||
const secret = process.env.CAPTCHA_SECRET_TOKEN;
|
||||
const CAPTCHA_SECRET_TOKEN = process.env.CAPTCHA_SECRET_TOKEN;
|
||||
|
||||
/**
|
||||
* Verify the CAPTCHA token with the CAPTCHA service
|
||||
* @param token
|
||||
* @name verifyCaptchaToken
|
||||
* @description Verify the CAPTCHA token with the CAPTCHA service
|
||||
* @param token - The CAPTCHA token to verify
|
||||
*/
|
||||
export async function verifyCaptchaToken(token: string) {
|
||||
if (!secret) {
|
||||
if (!CAPTCHA_SECRET_TOKEN) {
|
||||
throw new Error('CAPTCHA_SECRET_TOKEN is not set');
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('secret', CAPTCHA_SECRET_TOKEN);
|
||||
formData.append('response', token);
|
||||
|
||||
const res = await fetch(verifyEndpoint, {
|
||||
method: 'POST',
|
||||
body: `secret=${encodeURIComponent(secret)}&response=${encodeURIComponent(token)}`,
|
||||
body: formData,
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
|
||||
@@ -13,13 +13,6 @@ import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-clie
|
||||
import { captureException, zodParseFactory } from '../utils';
|
||||
|
||||
/**
|
||||
* @name IS_CAPTCHA_SETUP
|
||||
* @description Check if the CAPTCHA is setup
|
||||
*/
|
||||
const IS_CAPTCHA_SETUP = !!process.env.CAPTCHA_SECRET_TOKEN;
|
||||
|
||||
/**
|
||||
*
|
||||
* @name enhanceAction
|
||||
* @description Enhance an action with captcha, schema and auth checks
|
||||
*/
|
||||
@@ -48,9 +41,25 @@ export function enhanceAction<
|
||||
type UserParam = Config['auth'] extends false ? undefined : User;
|
||||
|
||||
const requireAuth = config.auth ?? true;
|
||||
|
||||
let user: UserParam = undefined as UserParam;
|
||||
|
||||
// validate the schema passed in the config if it exists
|
||||
const data = config.schema
|
||||
? zodParseFactory(config.schema)(params)
|
||||
: params;
|
||||
|
||||
// by default, the CAPTCHA token is not required
|
||||
const verifyCaptcha = config.captcha ?? false;
|
||||
|
||||
// verify the CAPTCHA token. It will throw an error if the token is invalid.
|
||||
if (verifyCaptcha) {
|
||||
const token = (data as Args & { captchaToken: string }).captchaToken;
|
||||
|
||||
// Verify the CAPTCHA token. It will throw an error if the token is invalid.
|
||||
await verifyCaptchaToken(token);
|
||||
}
|
||||
|
||||
// verify the user is authenticated if required
|
||||
if (requireAuth) {
|
||||
// verify the user is authenticated if required
|
||||
const auth = await requireUser(getSupabaseServerActionClient());
|
||||
@@ -63,35 +72,23 @@ export function enhanceAction<
|
||||
user = auth.data as UserParam;
|
||||
}
|
||||
|
||||
// validate the schema
|
||||
const data = config.schema
|
||||
? zodParseFactory(config.schema)(params)
|
||||
: params;
|
||||
|
||||
// verify captcha unless it's explicitly disabled
|
||||
// verify the captcha token if required
|
||||
const verifyCaptcha = config.captcha ?? IS_CAPTCHA_SETUP;
|
||||
|
||||
if (verifyCaptcha) {
|
||||
const token = (data as Args & { captchaToken: string }).captchaToken;
|
||||
|
||||
// Verify the CAPTCHA token. It will throw an error if the token is invalid.
|
||||
await verifyCaptchaToken(token);
|
||||
}
|
||||
|
||||
// capture exceptions if required
|
||||
const shouldCaptureException = config.captureException ?? true;
|
||||
|
||||
// if the action should capture exceptions, wrap the action in a try/catch block
|
||||
if (shouldCaptureException) {
|
||||
try {
|
||||
// pass the data to the action
|
||||
return await fn(data, user);
|
||||
} catch (error) {
|
||||
// capture the exception
|
||||
await captureException(error);
|
||||
|
||||
// re-throw the error
|
||||
throw error;
|
||||
}
|
||||
} else {
|
||||
// pass the data to the action
|
||||
// no need to capture exceptions, just pass the data to the action
|
||||
return fn(data, user);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,12 +19,6 @@ interface HandlerParams<Body> {
|
||||
body: Body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name IS_CAPTCHA_SETUP
|
||||
* @description Check if the CAPTCHA is setup
|
||||
*/
|
||||
const IS_CAPTCHA_SETUP = !!process.env.CAPTCHA_SECRET_TOKEN;
|
||||
|
||||
/**
|
||||
* Enhanced route handler function.
|
||||
*
|
||||
@@ -69,7 +63,8 @@ export const enhanceRouteHandler = <
|
||||
* This function takes a request object as an argument and returns a response object.
|
||||
*/
|
||||
return async function routeHandler(request: NextRequest) {
|
||||
const shouldVerifyCaptcha = params?.captcha ?? IS_CAPTCHA_SETUP;
|
||||
// Check if the captcha token should be verified
|
||||
const shouldVerifyCaptcha = params?.captcha ?? false;
|
||||
|
||||
// Verify the captcha token if required and setup
|
||||
if (shouldVerifyCaptcha) {
|
||||
|
||||
Reference in New Issue
Block a user