@zvndev/darkmown 2.12.2 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/types/dev.d.ts CHANGED
@@ -1,3 +1,31 @@
1
+ /**
2
+ * The local dev/preview servers bind to loopback, but loopback alone does not
3
+ * keep a website you are visiting out. Two attacks reach it from a browser:
4
+ *
5
+ * - DNS rebinding: `evil.example` re-resolves to 127.0.0.1, after which the
6
+ * page can READ every response (drafts, the dep map, the SSE stream, and
7
+ * `api/*` handlers, which run with the full `process.env`). The browser still
8
+ * sends `Host: evil.example`, so only hostnames that cannot be rebound pass:
9
+ * `localhost`/`*.localhost`, IP literals (a rebinding needs a domain), the
10
+ * bind address, and the `DARKMOWN_ALLOWED_HOSTS` list (a tunnel's domain).
11
+ * - Cross-site requests: any page can fire a simple POST at
12
+ * `http://127.0.0.1:5173/api/x` without reading the reply, so the handler's
13
+ * side effects run. `/api/*` therefore also refuses `Sec-Fetch-Site:
14
+ * cross-site` and an `Origin` that is not loopback, the request's own host,
15
+ * or allow-listed.
16
+ *
17
+ * `DARKMOWN_ALLOWED_HOSTS=*` turns the guard off.
18
+ * @param {{ url?: string, headers: Record<string, string | string[] | undefined> }} req
19
+ * @param {{ bindHost?: string, allowedHosts?: string }} [options]
20
+ * @returns {string | null} why the request is refused, or null to serve it
21
+ */
22
+ export function refuseLocalRequest(req: {
23
+ url?: string;
24
+ headers: Record<string, string | string[] | undefined>;
25
+ }, { bindHost, allowedHosts }?: {
26
+ bindHost?: string;
27
+ allowedHosts?: string;
28
+ }): string | null;
1
29
  /**
2
30
  * Serialize the dev server's rebuilds: at most ONE child build runs at a time.
3
31
  * Every build read-modify-writes the dependency map (`dist/.wd-dev-deps.json`),
package/types/feeds.d.ts CHANGED
@@ -1,16 +1,9 @@
1
- /**
2
- * @typedef {import("./router.js").Route} Route
3
- */
4
- /**
5
- * A route paired with its source file's last-modified date (ISO yyyy-mm-dd),
6
- * ready for a sitemap `<lastmod>`.
7
- * @typedef {object} DatedRoute
8
- * @property {string} loc Absolute URL (`site_url` + route path).
9
- * @property {string} lastmod ISO date (`yyyy-mm-dd`).
10
- */
11
1
  /**
12
2
  * XML-escape a text value for use inside an element or attribute. Covers the
13
- * five predefined XML entities — the same set RSS/sitemap consumers expect.
3
+ * five predefined XML entities — the same set RSS/sitemap consumers expect —
4
+ * and drops the characters XML 1.0 cannot carry at all (C0 controls other than
5
+ * tab/LF/CR, U+FFFE/U+FFFF, lone surrogates): one in a single post title makes
6
+ * the whole feed malformed, and readers reject it outright.
14
7
  * @param {string} value
15
8
  * @returns {string}
16
9
  */
@@ -238,21 +231,6 @@ export const AI_CRAWLER_POLICIES: string[];
238
231
  * ({@link rssItemLimit}).
239
232
  */
240
233
  export const RSS_ITEM_LIMIT: 20;
241
- export type Route = import("./router.js").Route;
242
- /**
243
- * A route paired with its source file's last-modified date (ISO yyyy-mm-dd),
244
- * ready for a sitemap `<lastmod>`.
245
- */
246
- export type DatedRoute = {
247
- /**
248
- * Absolute URL (`site_url` + route path).
249
- */
250
- loc: string;
251
- /**
252
- * ISO date (`yyyy-mm-dd`).
253
- */
254
- lastmod: string;
255
- };
256
234
  /**
257
235
  * An RSS item — a dated post in feed order.
258
236
  */
@@ -268,3 +246,18 @@ export type RssItem = {
268
246
  pubDate: string;
269
247
  description: string;
270
248
  };
249
+ export type Route = import("./router.js").Route;
250
+ /**
251
+ * A route paired with its source file's last-modified date (ISO yyyy-mm-dd),
252
+ * ready for a sitemap `<lastmod>`.
253
+ */
254
+ export type DatedRoute = {
255
+ /**
256
+ * Absolute URL (`site_url` + route path).
257
+ */
258
+ loc: string;
259
+ /**
260
+ * ISO date (`yyyy-mm-dd`).
261
+ */
262
+ lastmod: string;
263
+ };
@@ -51,8 +51,13 @@ export const REACTIVE_CSP: string;
51
51
  */
52
52
  export const STATIC_CSP: string;
53
53
  /**
54
- * Baseline security headers applied to every HTML response, independent of the
54
+ * Baseline security headers applied to every response, independent of the
55
55
  * CSP. CSP is added per-route (static vs reactive) by the helpers below.
56
+ *
57
+ * HSTS is one year WITHOUT `includeSubDomains`/`preload`: those pin every
58
+ * sibling subdomain to HTTPS, which only the domain owner can safely decide.
59
+ * Browsers ignore the header over plain HTTP, so local `serve` is unaffected.
60
+ * Cloudflare custom domains send no HSTS unless the zone enables it.
56
61
  * @type {Record<string, string>}
57
62
  */
58
63
  export const BASE_SECURITY_HEADERS: Record<string, string>;