@boardlink/server
v0.1.3
Published
Thin HTTP wrapper over @boardlink/core: POST /:board -> normalized logbook.
Maintainers
Readme
@boardlink/server
A thin, zero-dependency HTTP wrapper over @boardlink/core:
POST /:board returns a normalized logbook. Run it as a standalone Node server or embed the handler
in an existing framework.
npm install @boardlink/serverStandalone server (also exposes a boardlink-server bin):
PORT=8787 npx boardlink-server # POST /kilter | /tension | /moonboardEmbed the handler:
import { handleBoardRequest } from "@boardlink/server";
const { status, body } = await handleBoardRequest("kilter", await req.json());Deploying safely
This endpoint proxies real board credentials, and each success response carries a session
token that is equivalent to a long-lived login. Treat the server as a credential custodian:
Never run it auth-less in public. An open
POST /:boardis a credential-testing proxy for anyone on the internet. Pass anauthpredicate (checks a header/mTLS/allowlist; runs before the body is read) and arateLimit(fixed window, keyed on the socket address):import { createBoardServer } from "@boardlink/server"; createBoardServer({ auth: (req) => req.headers["x-api-key"] === process.env.API_KEY, rateLimit: { windowMs: 60_000, max: 30 }, cors: true, }).listen(8787);rateLimitkeys onreq.socket.remoteAddress(not the spoofablex-forwarded-for). Behind a proxy, rate-limit at the proxy or embedhandleBoardRequestin your own framework.Put TLS in front. Terminate TLS at a reverse proxy; never send credentials or tokens over plaintext HTTP.
rawis stripped by default. Backend records can carry unaudited fields (UUIDs, gym/location data). Responses omit each ascent'srawunless you opt in withincludeRaw: true.The token is sensitive. The success response is sent with
Cache-Control: no-store. Keep the token server-side, encrypted at rest, never in logs, error reports,localStorage, or JS-readable cookies. This library never logs it.
See docs/security.md for the
full threat model (including prompt-injection via untrusted free-text fields).
Full docs live in the repository README.
License
MIT
