# @wrnexus/helpers Safe convenience helpers for common WrNexus application flows. The package uses standard `Context`, `URL`, and `Response` values and has no runtime dependency beyond `@wrnexus/core`. ## Installation ```bash bun add @wrnexus/helpers ``` The package is private, so the machine must be authenticated to the `wrnexus` npm organization. ## Usage ### Redirect an unauthenticated forward-auth request The gateway calls an SSO verifier on a different URL from the original application. These helpers reconstruct the original URL from the gateway headers and safely place it in the login redirect: ```ts import type { Context } from "@wrnexus/core"; import { redirectToLogin } from "@wrnexus/helpers"; export const GET = async (ctx: Context) => { if (await hasValidSession(ctx)) { return new Response(null, { status: 204 }); } return redirectToLogin(ctx, "/login", { allowedHosts: ["admin.localhost:3000", "reports.localhost:3000"], }); }; ``` This creates a response such as: ```text Location: http://sso.localhost:3000/login?returnTo=http%3A%2F%2Fadmin.localhost%3A3000%2F ``` Always list the application hosts that are valid redirect destinations. Forwarded host headers are rejected when `allowedHosts` is absent or does not match, preventing an open redirect. The SSO hostname is the login destination, not an `allowedHosts` entry. For example, when protecting `admin.localhost:3000`, keep `admin.localhost:3000` in the allowlist even though the verifier runs at `sso.localhost:3000`. WRNexus preserves both hosts across a nested gateway request. ### Support dynamic tenant domains ```ts import type { Context } from "@wrnexus/core"; import { getOriginalRequestOrigin, redirectToLogin } from "@wrnexus/helpers"; export const GET = async (ctx: Context) => { const allowedHosts = (host: string) => host === "example.test" || host.endsWith(".example.test"); console.info("Authentication requested by", getOriginalRequestOrigin(ctx, { allowedHosts })); return redirectToLogin(ctx, "https://auth.example.test/login", { allowedHosts, returnToParam: "continue", status: 303, }); }; ``` ## API - `getOriginalRequestUrl(ctx, options): URL` — reconstruct the gateway URL. - `getOriginalRequestOrigin(ctx, options): string` — return only its origin. - `getOriginalRequestPath(ctx): string` — return its path and query string. - `getOriginalRequestMethod(ctx): string` — return its HTTP method. - `redirectToLogin(ctx, loginUrl, options): Response` — create a login redirect with an encoded `returnTo` parameter. For direct requests without gateway headers, URL helpers use `ctx.url`.