Guards
serverFn({ guard }) takes one guard or an array.
serverFn({ guard }) takes one guard or an array. The guards run before the input is validated, before the middleware
list and before the handler, so a call that a guard refuses is never validated and never runs its handler. A guard that
throws keeps the status of its error across the wire (HttpError(401) arrives as 401 with its message); a guard that returns
false gives 403. The guards and their composition (all, any, defineGuard) are described in
Guards and request locals in the security guide.
src/auth.tsts
import { defineGuard, HttpError } from "@shadow-js/dusk/server";
declare module "@shadow-js/dusk/server" {
interface DuskLocals {
user: { readonly id: string; readonly role: "reader" | "admin" } | undefined;
}
}
/** Refuses a call with no signed-in user: 401. */
export const requireUser = defineGuard((event) => {
if (event.locals.user === undefined) throw new HttpError(401, "Sign in first");
});
src/server/archive.tsts
import { serverFn } from "@shadow-js/dusk/server";
import { requireUser } from "../auth";
const archived = new Set<string>();
export const archiveNote = serverFn({ guard: requireUser }, async (input: unknown) => {
const id = typeof input === "string" ? input : "";
archived.add(id);
return { archived: id };
});