Secure by default
Configure accepted hosts and understand the response when a request is refused.
Dusk checks the request before a route runs. Set the host allow-list for your app, then keep the default cross-site request protection and request limits unless a route needs a different policy.
import type { HandlerOptions } from "@shadow-js/dusk/server";
export const options: Omit<HandlerOptions, "manifest"> = {
security: { allowedHosts: ["app.example.com"] },
};
Put these options in src/entry-server.ts. A host allow-list is an application setting; the other checks below have defaults.
| Request | Response | What happens |
|---|---|---|
A host outside allowedHosts |
400 Bad Request |
The handler refuses the request. |
| A URL longer than 8192 characters | 414 URI Too Long |
No route is evaluated. |
| A state-changing request from another site | 403 Forbidden |
CSRF protection refuses the write. |
A write without Origin or same-origin browser headers |
403 Forbidden |
The request does not meet the same-origin policy. |
| A body larger than 1 MiB | 413 Content Too Large |
Body reading stops at the configured limit. |
| An unsupported HTTP method | 501 Not Implemented |
The response lists the supported methods in Allow. |
Accept a valid request#
This API route reads JSON and returns it with a 201 status:
import { json, readJson, type RequestEvent } from "@shadow-js/dusk/server";
export const POST = async (event: RequestEvent) =>
json({ received: await readJson(event.request) }, { status: 201 });
Call it from a page on the same origin:
const response = await fetch("/api/echo", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ message: "Hello" }),
});
console.log(response.status);
console.log(await response.json());
201
{ received: { message: "Hello" } }
An error response ends the request at the first failed check. Production errors keep internal details on the server. Add a Content-Security-Policy when you know which scripts, styles and connections your app needs.
Next: sessions. See Security for configuration properties, body limits and trusted proxy settings.