Refactor billing imports, reorganize package scripts and improve action structure
Deleted unnecessary schema files and reorganized their imports into more logical order. Modified the package script structure to align more accurately with standard conventions. Also refactored the team-billing.service file to improve action structure, making it easier to understand and edit. Furthermore, upgraded various dependencies, reflecting their new versions in the lockfile.
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, useState } from 'react';
|
||||
|
||||
export const Captcha = createContext<{
|
||||
token: string;
|
||||
setToken: (token: string) => void;
|
||||
}>({
|
||||
token: '',
|
||||
setToken: (_: string) => {
|
||||
// do nothing
|
||||
return '';
|
||||
},
|
||||
});
|
||||
|
||||
export function CaptchaProvider(props: { children: React.ReactNode }) {
|
||||
const [token, setToken] = useState<string>('');
|
||||
|
||||
return (
|
||||
<Captcha.Provider value={{ token, setToken }}>
|
||||
{props.children}
|
||||
</Captcha.Provider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
'use client';
|
||||
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { Turnstile } from '@marsidev/react-turnstile';
|
||||
|
||||
import { Captcha } from './captcha-provider';
|
||||
|
||||
export function CaptchaTokenSetter(props: { siteKey: string | undefined }) {
|
||||
const { setToken } = useContext(Captcha);
|
||||
|
||||
if (!props.siteKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <Turnstile siteKey={props.siteKey} onSuccess={setToken} />;
|
||||
}
|
||||
3
packages/features/auth/src/captcha/client/index.ts
Normal file
3
packages/features/auth/src/captcha/client/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './captchaTokenSetter';
|
||||
export * from './use-captcha-token';
|
||||
export * from './captcha-provider';
|
||||
@@ -0,0 +1,13 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { Captcha } from './captcha-provider';
|
||||
|
||||
export function useCaptchaToken() {
|
||||
const context = useContext(Captcha);
|
||||
|
||||
if (!context) {
|
||||
throw new Error(`useCaptchaToken must be used within a CaptchaProvider`);
|
||||
}
|
||||
|
||||
return context.token;
|
||||
}
|
||||
1
packages/features/auth/src/captcha/server/index.ts
Normal file
1
packages/features/auth/src/captcha/server/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './verify-captcha';
|
||||
30
packages/features/auth/src/captcha/server/verify-captcha.tsx
Normal file
30
packages/features/auth/src/captcha/server/verify-captcha.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'server-only';
|
||||
|
||||
const verifyEndpoint =
|
||||
'https://challenges.cloudflare.com/turnstile/v0/siteverify';
|
||||
|
||||
const secret = process.env.CAPTCHA_SECRET_TOKEN;
|
||||
|
||||
/**
|
||||
* Verify the CAPTCHA token with the CAPTCHA service
|
||||
* @param token
|
||||
*/
|
||||
export async function verifyCaptchaToken(token: string) {
|
||||
if (!secret) {
|
||||
throw new Error('CAPTCHA_SECRET_TOKEN is not set');
|
||||
}
|
||||
|
||||
const res = await fetch(verifyEndpoint, {
|
||||
method: 'POST',
|
||||
body: `secret=${encodeURIComponent(secret)}&response=${encodeURIComponent(token)}`,
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (!data.success) {
|
||||
throw new Error('Invalid CAPTCHA token');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user