remix-utils
Version:
This package contains simple utility functions to use with [React Router](https://reactrouter.com/).
110 lines (109 loc) • 4.42 kB
TypeScript
/**
* > This depends on `react`, `@oslojs/crypto`, and `@oslojs/encoding`.
*
* The Honeypot middleware allows you to add a honeypot mechanism to your routes, providing a simple yet effective way to protect public forms from spam bots.
*
* To use the Honeypot middleware, first import and configure it:
*
* ```ts
* import { unstable_createHoneypotMiddleware } from "remix-utils/middleware/honeypot";
*
* export const [honeypotMiddleware, getHoneypotInputProps] =
* unstable_createHoneypotMiddleware({
* // Randomize the honeypot field name
* randomizeNameFieldName: false,
* // Default honeypot field name
* nameFieldName: "name__confirm",
* // Optional timestamp field for validation
* validFromFieldName: "from__confirm",
* // Unique seed for encryption (recommended for extra security)
* encryptionSeed: undefined,
*
* onSpam(error) {
* // Handle SpamError here and return a Response
* return new Response("Spam detected", { status: 400 });
* },
* });
* ```
*
* Add the `honeypotMiddleware` to the `unstable_middleware` array in the route where you want to enable spam protection, use it in your `app/root.tsx` file to apply it globally:
*
* ```ts
* import { honeypotMiddleware } from "~/middleware/honeypot";
*
* export const unstable_middleware = [honeypotMiddleware];
* ```
*
* Use the `getHoneypotInputProps` function in your root loader to retrieve the honeypot input properties:
*
* ```ts
* import { getHoneypotInputProps } from "~/middleware/honeypot";
*
* export async function loader({ request }: LoaderFunctionArgs) {
* let honeypotInputProps = await getHoneypotInputProps();
* return json({ honeypotInputProps });
* }
* ```
*
* Wrap your application in the `HoneypotProvider` component to make the honeypot input properties available throughout your app:
*
* ```tsx
* import { HoneypotProvider } from "remix-utils/honeypot/react";
*
* export default function RootComponent() {
* return (
* <HoneypotProvider {...honeypotInputProps}>
* <Outlet />
* </HoneypotProvider>
* );
* }
* ```
*
* In any public form, include the `HoneypotInputs` component to add the honeypot fields:
*
* ```tsx
* import { HoneypotInputs } from "remix-utils/honeypot/react";
*
* function PublicForm() {
* return (
* <Form method="post">
* <HoneypotInputs label="Please leave this field blank" />
* <input type="text" name="name" placeholder="Your Name" />
* <input type="email" name="email" placeholder="Your Email" />
* <button type="submit">Submit</button>
* </Form>
* );
* }
* ```
*
* For requests with a body (e.g., POST, PUT, DELETE) and a content type of `application/x-www-form-urlencoded` or `multipart/form-data`, the middleware validates the honeypot fields. If the request passes the honeypot check, it proceeds to the action handler. If the honeypot check fails, the `onSpam` handler is invoked, allowing you to handle spam requests appropriately.
*
* In your action handlers, you can process the form data as usual, without worrying about spam checks—they are already handled by the middleware:
*
* ```ts
* export async function action({ request }: ActionFunctionArgs) {
* // If this code runs, the honeypot check passed
* let formData = await request.formData();
* let name = formData.get("name");
* let email = formData.get("email");
* // Process the form data
* }
* ```
*
* The honeypot middleware is designed to be lightweight and effective against basic spam bots. For advanced spam protection, consider combining this with other techniques like CAPTCHA or rate limiting.
* @author [Sergio Xalambrí](https://sergiodxa.com)
* @module Middleware/Honeypot
*/
import type { unstable_MiddlewareFunction } from "react-router";
import type { HoneypotConfig, HoneypotInputProps } from "../honeypot.js";
import { SpamError } from "../honeypot.js";
export declare function unstable_createHoneypotMiddleware({ onSpam, ...options }?: unstable_createHoneypotMiddleware.Options): unstable_createHoneypotMiddleware.ReturnType;
export declare namespace unstable_createHoneypotMiddleware {
interface Options extends HoneypotConfig {
onSpam?(error: SpamError): Response;
}
type ReturnType = [
unstable_MiddlewareFunction<Response>,
() => Promise<HoneypotInputProps>
];
}