Skip to content

Commit a096ddc

Browse files
committed
refactor(cron): Move node-cron to package
1 parent fd09aed commit a096ddc

31 files changed

+1239
-653
lines changed
42.9 KB
Loading
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
title: Custom Adapter
3+
description: Create your own custom captcha adapter for VitNode.
4+
---
5+
6+
If you want to use captcha in your custom form or somewhere else, follow these steps.
7+
8+
## Usage
9+
10+
<Steps>
11+
<Step>
12+
13+
### Activate captcha in route
14+
15+
```ts title="plugins/{plugin_name}/src/routes/example.ts"
16+
import { buildRoute } from "@vitnode/core/api/lib/route";
17+
18+
export const exampleRoute = buildRoute({
19+
pluginId: CONFIG_PLUGIN.pluginId,
20+
route: {
21+
method: "post",
22+
description: "Create a new user",
23+
path: "/sign_up",
24+
withCaptcha: true, // [!code ++]
25+
},
26+
handler: async c => {},
27+
});
28+
```
29+
30+
</Step>
31+
<Step>
32+
33+
### Get config from middleware API
34+
35+
```tsx title="plugins/{plugin_name}/src/app/sing_up/page.tsx"
36+
import { getMiddlewareApi } from "@vitnode/core/lib/api/get-middleware-api"; // [!code ++]
37+
38+
export const SignUpView = async () => {
39+
const { captcha } = await getMiddlewareApi(); // [!code ++]
40+
41+
return <FormSignUp captcha={captcha} />;
42+
};
43+
```
44+
45+
</Step>
46+
<Step>
47+
48+
### Use `useCaptcha` hook
49+
50+
Inside your client component, use the `useCaptcha` hook to handle captcha rendering and validation. Remember to add `div` with `id="vitnode_captcha"` where you want the captcha widget to appear.
51+
52+
```tsx title="plugins/{plugin_name}/src/components/form/sign-up/sign-up.tsx"
53+
"use client";
54+
55+
import { AutoForm } from "@vitnode/core/components/form/auto-form";
56+
57+
export const FormSignUp = ({
58+
captcha, // [!code ++]
59+
}: {
60+
captcha: z.infer<typeof routeMiddlewareSchema>["captcha"]; // [!code ++]
61+
}) => {
62+
// [!code ++]
63+
const { isReady, getToken, onReset } = useCaptcha(captcha);
64+
65+
const onSubmit = async () => {
66+
await mutationApi({
67+
// ...other values,
68+
captchaToken: await getToken(), // [!code ++]
69+
});
70+
71+
// Handle success or error
72+
// [!code ++]
73+
onReset(); // Reset captcha after submission
74+
};
75+
76+
return (
77+
<form onSubmit={onSubmit}>
78+
{/* Render captcha widget */}
79+
{/* [!code ++] */}
80+
<div id="vitnode_captcha" />
81+
82+
<Button disabled={!isReady}>Submit</Button>
83+
</form>
84+
);
85+
};
86+
```
87+
88+
</Step>
89+
<Step>
90+
91+
### Submit form with captcha
92+
93+
```tsx title="plugins/{plugin_name}/src/components/form/sign-up/mutation-api.ts"
94+
"use server";
95+
96+
import type { z } from "zod";
97+
98+
import { fetcher } from "@vitnode/core/lib/fetcher";
99+
100+
export const mutationApi = async ({
101+
captchaToken, // [!code ++]
102+
}: {
103+
// [!code ++]
104+
captchaToken;
105+
}) => {
106+
await fetcher(usersModule, {
107+
path: "/test",
108+
method: "post",
109+
module: "blog",
110+
captchaToken, // [!code ++]
111+
});
112+
};
113+
```
114+
115+
</Step>
116+
</Steps>

apps/docs/content/docs/dev/captcha/index.mdx

Lines changed: 21 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ title: Captcha
33
description: Protect your forms and API call with captcha validation.
44
---
55

6-
## Support
6+
import captchaPreview from "./captcha_preview.png";
7+
8+
import { ImgDocs } from "@/components/fumadocs/img";
9+
10+
<ImgDocs src={captchaPreview} alt="Captcha Preview" />
11+
12+
## Providers
713

814
VitNode supports multiple captcha providers. You can choose the one that fits your needs. Currently, we support:
915

@@ -13,7 +19,11 @@ VitNode supports multiple captcha providers. You can choose the one that fits yo
1319
description="By Cloudflare"
1420
href="/docs/guides/captcha/cloudflare"
1521
/>
16-
<Card title="reCAPTCHA v3" description="By Google" href="/docs/guides/captcha/recaptcha" />
22+
<Card
23+
title="reCAPTCHA v3"
24+
description="By Google"
25+
href="/docs/guides/captcha/recaptcha"
26+
/>
1727
</Cards>
1828

1929
If you need more providers, feel free to open a **Feature Request** on our [GitHub repository](https://github.com/aXenDeveloper/vitnode/issues) :)
@@ -38,9 +48,9 @@ export const exampleRoute = buildRoute({
3848
method: "post",
3949
description: "Create a new user",
4050
path: "/sign_up",
41-
withCaptcha: true // [!code ++]
51+
withCaptcha: true, // [!code ++]
4252
},
43-
handler: async (c) => {}
53+
handler: async c => {},
4454
});
4555
```
4656

@@ -74,7 +84,7 @@ Get the `captcha` config from the props and pass it to the `AutoForm` component.
7484
import { AutoForm } from "@vitnode/core/components/form/auto-form";
7585

7686
export const FormSignUp = ({
77-
captcha // [!code ++]
87+
captcha, // [!code ++]
7888
}: {
7989
captcha: z.infer<typeof routeMiddlewareSchema>["captcha"]; // [!code ++]
8090
}) => {
@@ -106,23 +116,23 @@ In your form submission handler, you can get the `captchaToken` from the form su
106116

107117
import {
108118
AutoForm,
109-
type AutoFormOnSubmit // [!code ++]
119+
type AutoFormOnSubmit, // [!code ++]
110120
} from "@vitnode/core/components/form/auto-form";
111121

112122
export const FormSignUp = ({
113-
captcha
123+
captcha,
114124
}: {
115125
captcha: z.infer<typeof routeMiddlewareSchema>["captcha"];
116126
}) => {
117127
const onSubmit: AutoFormOnSubmit<typeof formSchema> = async (
118128
values,
119129
form,
120-
{ captchaToken } // [!code ++]
130+
{ captchaToken }, // [!code ++]
121131
) => {
122132
// Call your mutation API with captcha token
123133
await mutationApi({
124134
...values,
125-
captchaToken // [!code ++]
135+
captchaToken, // [!code ++]
126136
});
127137

128138
// Handle success or error
@@ -159,8 +169,8 @@ z.infer<typeof zodSignUpSchema> & { captchaToken: string }) => {
159169
module: "users",
160170
captchaToken, // [!code ++]
161171
args: {
162-
body: input
163-
}
172+
body: input,
173+
},
164174
});
165175

166176
if (res.status !== 201) {
@@ -175,115 +185,3 @@ z.infer<typeof zodSignUpSchema> & { captchaToken: string }) => {
175185

176186
</Step>
177187
</Steps>
178-
179-
## Custom Usage
180-
181-
If you want to use captcha in your custom form or somewhere else, follow these steps.
182-
183-
<Steps>
184-
<Step>
185-
186-
### Activate captcha in route
187-
188-
```ts title="plugins/{plugin_name}/src/routes/example.ts"
189-
import { buildRoute } from "@vitnode/core/api/lib/route";
190-
191-
export const exampleRoute = buildRoute({
192-
pluginId: CONFIG_PLUGIN.pluginId,
193-
route: {
194-
method: "post",
195-
description: "Create a new user",
196-
path: "/sign_up",
197-
withCaptcha: true // [!code ++]
198-
},
199-
handler: async (c) => {}
200-
});
201-
```
202-
203-
</Step>
204-
<Step>
205-
206-
### Get config from middleware API
207-
208-
```tsx title="plugins/{plugin_name}/src/app/sing_up/page.tsx"
209-
import { getMiddlewareApi } from "@vitnode/core/lib/api/get-middleware-api"; // [!code ++]
210-
211-
export const SignUpView = async () => {
212-
const { captcha } = await getMiddlewareApi(); // [!code ++]
213-
214-
return <FormSignUp captcha={captcha} />;
215-
};
216-
```
217-
218-
</Step>
219-
<Step>
220-
221-
### Use `useCaptcha` hook
222-
223-
Inside your client component, use the `useCaptcha` hook to handle captcha rendering and validation. Remember to add `div` with `id="vitnode_captcha"` where you want the captcha widget to appear.
224-
225-
```tsx title="plugins/{plugin_name}/src/components/form/sign-up/sign-up.tsx"
226-
"use client";
227-
228-
import { AutoForm } from "@vitnode/core/components/form/auto-form";
229-
230-
export const FormSignUp = ({
231-
captcha // [!code ++]
232-
}: {
233-
captcha: z.infer<typeof routeMiddlewareSchema>["captcha"]; // [!code ++]
234-
}) => {
235-
// [!code ++]
236-
const { isReady, getToken, onReset } = useCaptcha(captcha);
237-
238-
const onSubmit = async () => {
239-
await mutationApi({
240-
// ...other values,
241-
captchaToken: await getToken() // [!code ++]
242-
});
243-
244-
// Handle success or error
245-
// [!code ++]
246-
onReset(); // Reset captcha after submission
247-
};
248-
249-
return (
250-
<form onSubmit={onSubmit}>
251-
{/* Render captcha widget */}
252-
{/* [!code ++] */}
253-
<div id="vitnode_captcha" />
254-
255-
<Button disabled={!isReady}>Submit</Button>
256-
</form>
257-
);
258-
};
259-
```
260-
261-
</Step>
262-
<Step>
263-
264-
### Submit form with captcha
265-
266-
```tsx title="plugins/{plugin_name}/src/components/form/sign-up/mutation-api.ts"
267-
"use server";
268-
269-
import type { z } from "zod";
270-
271-
import { fetcher } from "@vitnode/core/lib/fetcher";
272-
273-
export const mutationApi = async ({
274-
captchaToken // [!code ++]
275-
}: {
276-
// [!code ++]
277-
captchaToken;
278-
}) => {
279-
await fetcher(usersModule, {
280-
path: "/test",
281-
method: "post",
282-
module: "blog",
283-
captchaToken // [!code ++]
284-
});
285-
};
286-
```
287-
288-
</Step>
289-
</Steps>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"title": "Captcha",
3+
"pages": ["...", "custom-adapter"]
4+
}

0 commit comments

Comments
 (0)