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 =
|
const verifyEndpoint =
|
||||||
'https://challenges.cloudflare.com/turnstile/v0/siteverify';
|
'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
|
* @name verifyCaptchaToken
|
||||||
* @param token
|
* @description Verify the CAPTCHA token with the CAPTCHA service
|
||||||
|
* @param token - The CAPTCHA token to verify
|
||||||
*/
|
*/
|
||||||
export async function verifyCaptchaToken(token: string) {
|
export async function verifyCaptchaToken(token: string) {
|
||||||
if (!secret) {
|
if (!CAPTCHA_SECRET_TOKEN) {
|
||||||
throw new Error('CAPTCHA_SECRET_TOKEN is not set');
|
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, {
|
const res = await fetch(verifyEndpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: `secret=${encodeURIComponent(secret)}&response=${encodeURIComponent(token)}`,
|
body: formData,
|
||||||
headers: {
|
headers: {
|
||||||
'content-type': 'application/x-www-form-urlencoded',
|
'content-type': 'application/x-www-form-urlencoded',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,13 +13,6 @@ import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-clie
|
|||||||
import { captureException, zodParseFactory } from '../utils';
|
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
|
* @name enhanceAction
|
||||||
* @description Enhance an action with captcha, schema and auth checks
|
* @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;
|
type UserParam = Config['auth'] extends false ? undefined : User;
|
||||||
|
|
||||||
const requireAuth = config.auth ?? true;
|
const requireAuth = config.auth ?? true;
|
||||||
|
|
||||||
let user: UserParam = undefined as UserParam;
|
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) {
|
if (requireAuth) {
|
||||||
// verify the user is authenticated if required
|
// verify the user is authenticated if required
|
||||||
const auth = await requireUser(getSupabaseServerActionClient());
|
const auth = await requireUser(getSupabaseServerActionClient());
|
||||||
@@ -63,35 +72,23 @@ export function enhanceAction<
|
|||||||
user = auth.data as UserParam;
|
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
|
// capture exceptions if required
|
||||||
const shouldCaptureException = config.captureException ?? true;
|
const shouldCaptureException = config.captureException ?? true;
|
||||||
|
|
||||||
|
// if the action should capture exceptions, wrap the action in a try/catch block
|
||||||
if (shouldCaptureException) {
|
if (shouldCaptureException) {
|
||||||
try {
|
try {
|
||||||
|
// pass the data to the action
|
||||||
return await fn(data, user);
|
return await fn(data, user);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// capture the exception
|
||||||
await captureException(error);
|
await captureException(error);
|
||||||
|
|
||||||
|
// re-throw the error
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// pass the data to the action
|
// no need to capture exceptions, just pass the data to the action
|
||||||
return fn(data, user);
|
return fn(data, user);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,12 +19,6 @@ interface HandlerParams<Body> {
|
|||||||
body: 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.
|
* 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.
|
* This function takes a request object as an argument and returns a response object.
|
||||||
*/
|
*/
|
||||||
return async function routeHandler(request: NextRequest) {
|
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
|
// Verify the captcha token if required and setup
|
||||||
if (shouldVerifyCaptcha) {
|
if (shouldVerifyCaptcha) {
|
||||||
|
|||||||
Reference in New Issue
Block a user