@stonyx/rest-server 0.2.1-alpha.24 → 0.2.1-alpha.25

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/README.md CHANGED
@@ -81,7 +81,7 @@ Configuration is read from `stonyx/config` under `restServer`:
81
81
  | `enableHealthCheck` | **Boolean** | `true` | Register `GET /health` endpoint (disable via `REST_HEALTH_CHECK_DISABLE=true`) |
82
82
  | `caseSensitiveRoutes` | **Boolean** | `true` | Match route paths case-sensitively. Disable via `REST_CASE_SENSITIVE_ROUTES=false`. See [Route Matching Strictness](#route-matching-strictness) — **disabling this re-opens a security hole**. |
83
83
  | `strictRoutes` | **Boolean** | `true` | Match route paths strictly, so a trailing slash does not match a route registered without one. Disable via `REST_STRICT_ROUTES=false`. See [Route Matching Strictness](#route-matching-strictness) — **disabling this re-opens a security hole**, and note `GET /health/` now 404s. |
84
- | `canonicalRoutes` | **Boolean** | `true` | Reject a request whose raw target is not the canonical path express matched, before your `auth` hook runs. Disable via `REST_CANONICAL_ROUTES=false`. See [Route Matching Strictness](#route-matching-strictness) — **disabling this re-opens a security hole**, and note `GET /route/` at a mount root and **every** absolute-form request target now 404. |
84
+ | `canonicalRoutes` | **Boolean** | `true` | Reject a request whose raw target is not the canonical path express matched, before your `auth` hook runs. Disable via `REST_CANONICAL_ROUTES=false`. See [Route Matching Strictness](#route-matching-strictness) — **disabling this re-opens a security hole**, and note `GET /route/` at a mount root and every absolute-form request target now 404 on the routes this module registers (see the scope limit under [Upgrading](#upgrading-behaviour-changes)). |
85
85
  | `trustProxy` | **Boolean** | `false` | Trust reverse proxy headers (e.g. `X-Forwarded-Proto`). Enable via `REST_TRUST_PROXY=true` when running behind a load balancer such as AWS ALB/ELB to ensure correct protocol detection. |
86
86
  | `statusMap` | **Object** | `{}` | Optional mapping of HTTP status codes to custom messages |
87
87
 
@@ -165,26 +165,45 @@ against `req.originalUrl` — the field express does not normalize:
165
165
  GET /admin 401 401 (hook fires, request blocked)
166
166
  GET /admin/ 200 404 (hook never fired; now a miss)
167
167
  GET http://host/admin 200 404 (absolute-form; hook never fired)
168
- GET http://host/admin/settings 200 404 (absolute-form, and every other route)
168
+ GET http://host/admin/settings 200 404 (absolute-form; every route from a request class)
169
169
  ```
170
170
 
171
171
  The second vector is the one to check first. [RFC 9112
172
172
  §3.2.2](https://www.rfc-editor.org/rfc/rfc9112#section-3.2.2) permits an
173
173
  **absolute-form** request target, express routes it, and it hands your hook the
174
174
  whole URI — `req.originalUrl === "http://host/admin"`. Unlike the mount-root
175
- slash, that affects **every route**, not one edge.
175
+ slash, that affects **every route mounted from a request class**, not one edge.
176
+ The qualifier is a registration-site limit, not a special case for one URL: the
177
+ check runs inside the handlers this module registers, so anything you register
178
+ directly on `RestServer.instance.api` is outside it. In this repo that is
179
+ `/health` alone, and `GET http://host/health` still returns 200 — measured.
176
180
 
177
181
  The target is compared **raw**. It is not parsed, normalized or resolved first:
178
182
  normalizing it would launder exactly the string your hook is exposed to and
179
183
  re-open the absolute-form vector by construction. Only the query string is
180
184
  removed before comparison, so `GET /admin?x=1` still reaches your hook — **strip
181
185
  the query yourself** if your hook compares `req.originalUrl` against a fixed
182
- path, or it will not match. Rejections are indistinguishable from a genuine miss
183
- by design; see [Upgrading](#upgrading-behaviour-changes).
186
+ path, or it will not match (see [Consumer
187
+ Contracts](#consumer-contracts)). Rejections are indistinguishable from a
188
+ genuine miss by design; see [Upgrading](#upgrading-behaviour-changes).
184
189
 
185
190
  Routes registered *with* a literal trailing slash are unaffected — their
186
- canonical target carries the slash. So are param routes, index-mounted route
187
- classes, and query strings on canonical paths.
191
+ canonical target carries the slash. So are index-mounted route classes and
192
+ query strings on canonical paths.
193
+
194
+ **Param routes: "unaffected" means "no regression", not "no residual".**
195
+ `/resource/:id` keeps matching exactly as it did. But percent-encoding is not
196
+ normalized on either side of the comparison — express decodes only
197
+ `req.params`, not `req.path` and not `req.originalUrl` — so `target` and
198
+ `canonical` are *both* the encoded string and this check passes the request
199
+ through by construction. Measured on a hook that authorizes on
200
+ `req.originalUrl` with the query correctly stripped, on a `/:id` route:
201
+ `GET /enc/secret` → 401, `GET /enc/%73ecret` → **200 with the guarded handler
202
+ running unauthenticated**, identically before and after this change. It is a
203
+ residual, not something `canonicalRoutes` introduced, and it is **wider** than
204
+ the two vectors above: `%73` defeats a `req.path` hook as well. Tracked as
205
+ [#56](https://github.com/abofs/stonyx-rest-server/issues/56) — until it ships,
206
+ do not read a param-segment route class as covered on this axis.
188
207
 
189
208
  #### What this does not do
190
209
 
@@ -219,12 +238,19 @@ All three controls change which requests match, so all three are
219
238
  consumer-visible.
220
239
 
221
240
  **Clients or forward proxies sending absolute-form request targets now get 404
222
- on every route.** `GET http://host/admin HTTP/1.1` is a legal request target
223
- ([RFC 9112 §3.2.2](https://www.rfc-editor.org/rfc/rfc9112#section-3.2.2)) and
224
- express used to route it. It is now rejected, on **every** route — for a client
225
- that emits it, this is a total outage, not a partial one, and it is the largest
226
- blast radius in this change. Reverse proxies in normal use (nginx, HAProxy,
227
- AWS ALB) send origin-form and are unaffected; **forward** proxies and
241
+ on every route mounted from a request class.** `GET http://host/admin HTTP/1.1`
242
+ is a legal request target
243
+ ([RFC 9112 §3.2.2](https://www.rfc-editor.org/rfc/rfc9112#section-3.2.2)), and
244
+ express used to route it. It is now rejected on every route this module
245
+ registers for a client that emits it, this is a total outage, not a partial
246
+ one, and it is the largest blast radius in this change. The one carve-out is a
247
+ **registration site**, not a route: the check lives in the handlers mounted from
248
+ your request classes, so anything registered directly on
249
+ `RestServer.instance.api` never reaches it. `GET /health` is the only such route
250
+ in this repo, and `GET http://host/health` still returns 200 — so do not use it
251
+ to confirm the new rejection is live, and do not assume an authorized route you
252
+ registered on `api` yourself is covered. Reverse proxies in normal use (nginx,
253
+ HAProxy, AWS ALB) send origin-form and are unaffected; **forward** proxies and
228
254
  hand-rolled HTTP clients are the exposure. Remediation is
229
255
  `REST_CANONICAL_ROUTES=false`, or fix the client.
230
256
 
@@ -295,6 +321,22 @@ again. They exist as one-line remediations for an existing deployment, not as a
295
321
  configuration to run on. Set the flag to restore service, then fix the client
296
322
  and remove the flag.
297
323
 
324
+ ### Consumer Contracts
325
+
326
+ Three things this module deliberately does **not** do for you. Each is a state
327
+ the framework permits, only your own discipline prevents, and that produces **no
328
+ error and no log** when that discipline lapses — so they are collected here
329
+ rather than left implied by the sections above.
330
+
331
+ | you must | because | symptom if you don't |
332
+ |---|---|---|
333
+ | **Strip the query string** before comparing `req.originalUrl` to a fixed path in an `auth` hook | `canonicalRoutes` compares the query-*stripped* target — a query string is a legitimately variable part of a request target, and rejecting on it would 404 every `?`-carrying request | `GET /admin?x=1` reaches your guarded handler **unauthenticated**, 200, no error, no log. Measured identical before and after `canonicalRoutes` |
334
+ | **Compare param values with the same decoding and casing you look them up with** | express decodes only `req.params`; `req.path` and `req.originalUrl` both stay percent-encoded, and param *values* are never case-normalized | `GET /orders/%73ecret` runs the handler with `id === "secret"` while your hook compared `%73ecret` and did not match — unauthenticated 200. Tracked as [#56](https://github.com/abofs/stonyx-rest-server/issues/56) |
335
+ | **Return `undefined` from `auth()` to mean "authorized"** — never `0` | any integer return is sent as the HTTP status | returning `0` sends a `0` status rather than allowing the request |
336
+
337
+ `test/sample/requests/admin.ts` in this repo is the worked example of a
338
+ correctly-written `originalUrl` hook for the first row.
339
+
298
340
  ### Running Behind a Load Balancer
299
341
 
300
342
  When your application runs behind a reverse proxy or load balancer (e.g. AWS ALB/ELB), the load balancer terminates SSL and forwards requests to your server over HTTP internally. This means Express sees `http` as the protocol even though the original client request used `https`.
@@ -23,13 +23,20 @@ const config = {
23
23
  // stubs `caseSensitiveRoutes` to `undefined` and src/route-matching.ts reads
24
24
  // `!== false`, so AC6 guards the source's read and not this default.
25
25
  // Measured: pin `caseSensitiveRoutes: true` in test/config/environment.ts AND
26
- // invert this line, and the suite reports 28 pass / 0 fail. A naive pin makes
26
+ // invert this line, and the suite reports 34 pass / 0 fail. A naive pin makes
27
27
  // an insecure published default completely invisible to a green suite --
28
28
  // quieter and weaker, which is the outcome pinning was supposed to prevent.
29
+ // Inverting this line ALONE, unpinned, reports 31 pass / 3 fail (#47's AC3,
30
+ // AC4 and AC5; AC6 green).
29
31
  //
30
32
  // The cost of leaving it unpinned is that the suite is ambient-sensitive here
31
- // (`REST_CASE_SENSITIVE_ROUTES=false pnpm test` => 25 pass / 3 fail), but it
32
- // fails LOUDLY, so there is no false green. Closing #43 for this key needs
33
+ // (`REST_CASE_SENSITIVE_ROUTES=false pnpm test` => 31 pass / 3 fail), but it
34
+ // fails LOUDLY, so there is no false green.
35
+ //
36
+ // Every count in this block was re-measured against the 34-test suite at
37
+ // #54's head. PASS totals here move whenever a test is ADDED anywhere in the
38
+ // repo -- the FAIL counts are the load-bearing half. Re-measure, do not
39
+ // adjust by arithmetic, when this block next looks stale. Closing #43 for this key needs
33
40
  // the subprocess-based env isolation this repo does not yet have; any fix
34
41
  // must keep a live assertion on this default.
35
42
  caseSensitiveRoutes: REST_CASE_SENSITIVE_ROUTES !== 'false',
@@ -47,19 +54,21 @@ const config = {
47
54
  // DELIBERATELY NOT PINNED in test/config/environment.ts -- do not "fix" this
48
55
  // as part of abofs/stonyx-rest-server#43. Same trap as the key above, and now
49
56
  // measured for both: pin `strictRoutes: true` in test/config/environment.ts
50
- // AND invert this line to `=== 'true'`, and the suite reports 31 pass /
57
+ // AND invert this line to `=== 'true'`, and the suite reports 34 pass /
51
58
  // 0 fail. A naive pin makes an insecure published default completely
52
59
  // invisible to a green suite.
53
60
  //
54
- // Unpinned, inverting this line alone turns #50's AC1 and AC2 red (29/2).
61
+ // Unpinned, inverting this line alone turns #50's AC1 and AC2 red (32/2).
55
62
  // AC3 stays GREEN under that mutation, because AC3 sets `strictRoutes` on the
56
63
  // config object directly and so guards src/route-matching.ts's READ rather
57
64
  // than this default -- the two assertions cover different halves and neither
58
65
  // subsumes the other.
59
66
  //
60
67
  // The cost is that the suite is ambient-sensitive here
61
- // (`REST_STRICT_ROUTES=false pnpm test` => 29 pass / 2 fail), but it fails
62
- // LOUDLY, so there is no false green. Closing #43 for either key needs
68
+ // (`REST_STRICT_ROUTES=false pnpm test` => 32 pass / 2 fail), but it fails
69
+ // LOUDLY, so there is no false green. All counts in this block re-measured
70
+ // against the 34-test suite at #54's head; the FAIL count is the load-bearing
71
+ // half, since PASS totals move whenever a test is added anywhere. Closing #43 for either key needs
63
72
  // subprocess-based env isolation this repo does not have; any fix must keep a
64
73
  // live assertion on this default.
65
74
  strictRoutes: REST_STRICT_ROUTES !== 'false',
@@ -75,8 +84,13 @@ const config = {
75
84
  // 1. `GET /route/` at a mounted route class's ROOT now returns 404.
76
85
  // 2. Clients or forward proxies emitting an ABSOLUTE-FORM request target
77
86
  // (`GET http://host/admin HTTP/1.1`, RFC 9112 3.2.2) now receive 404 on
78
- // EVERY route. This is the larger blast radius: for such a client it is
79
- // a total outage, not a partial one. Reverse proxies in normal use
87
+ // every route registered through Request.registerCalls(). That is a
88
+ // REGISTRATION-SITE limit, not a carve-out for one URL: /health is
89
+ // registered directly on the parent app (src/main.ts) and still answers
90
+ // 200 to an absolute-form target -- and so would any route a consumer
91
+ // registers on the public RestServer.instance.api itself. This is the
92
+ // larger blast radius: for such a client it is a total outage, not a
93
+ // partial one. Reverse proxies in normal use
80
94
  // (nginx, HAProxy, ALB) send origin-form and are unaffected.
81
95
  // This module emits no request log, so both look like a dropped route.
82
96
  //
@@ -105,8 +119,10 @@ const config = {
105
119
  // guards src/route-matching.ts's READ rather than this default -- the two
106
120
  // assertions cover different halves and neither subsumes the other.
107
121
  // Conversely, weakening the READ to `=== true` reports 33 pass / 1 fail with
108
- // AC2 as the only failure and AC1 fully green. Both measurements are on the
109
- // #54 branch head.
122
+ // AC2 as the only failure and AC1 fully green. All four counts in this block
123
+ // were re-measured on the #54 branch head after the AC1.11/AC1.12 assertions
124
+ // were added; the suite is 34 tests, and the FAIL count is the load-bearing
125
+ // half.
110
126
  //
111
127
  // The cost is that the suite is ambient-sensitive here
112
128
  // (`REST_CANONICAL_ROUTES=false pnpm test` => 32 pass / 2 fail), but it fails
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,OAAO,IAAI,cAAc,EAAE,KAAK,QAAQ,IAAI,eAAe,EAAqB,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAOrI,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AACtG,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,MAAM,GAAG,SAAS,CAAC;AAC3F,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC;AAE9F,MAAM,CAAC,OAAO,OAAO,OAAO;IAC1B,MAAM,CAAC,SAAS,SAAmB;IAEnC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,YAAY;IASlD,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAWrE,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAG,aAAa,CAAC;IACjB,IAAI,CAAC,EAAE,WAAW,CAAC;;IA4B3B,aAAa,IAAI,IAAI;CA4EtB"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,OAAO,IAAI,cAAc,EAAE,KAAK,QAAQ,IAAI,eAAe,EAAqB,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAOrI,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AACtG,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,MAAM,GAAG,SAAS,CAAC;AAC3F,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC;AAE9F,MAAM,CAAC,OAAO,OAAO,OAAO;IAC1B,MAAM,CAAC,SAAS,SAAmB;IAEnC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,YAAY;IASlD,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAWrE,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAG,aAAa,CAAC;IACjB,IAAI,CAAC,EAAE,WAAW,CAAC;;IA4B3B,aAAa,IAAI,IAAI;CA4FtB"}
package/dist/request.js CHANGED
@@ -63,13 +63,24 @@ export default class Request {
63
63
  // bypasses against hooks that authorize on `req.originalUrl`: the
64
64
  // mount-root trailing slash and the absolute-form request target.
65
65
  //
66
- // Two properties of this line are load-bearing, and each has its own
67
- // red-able assertion:
66
+ // Three properties of this line are load-bearing. Each is named with
67
+ // the ONE assertion that turns red when it is removed -- assertion
68
+ // numbers in `test/integration/rest-server-test.ts` AC1, so the claim
69
+ // is checkable rather than a promise that coverage exists somewhere:
68
70
  //
69
- // 1. It runs BEFORE auth, and OUTSIDE `if (this.auth)`. Gating it on
70
- // the hook would leave `GET /public/` at 200 and make a security
71
- // control depend on an unrelated consumer choice.
72
- // 2. It rejects with `next('router')`, NOT sendStatusResponse() or
71
+ // 1. It runs OUTSIDE `if (this.auth)`. Gating it on the hook would
72
+ // leave `GET /public/` at 200 and make a security control depend
73
+ // on an unrelated consumer choice. Killed by AC1.6, which probes
74
+ // a route class with no hook.
75
+ // 2. It runs BEFORE that block, not merely outside it. This is a
76
+ // SEPARATE property from 1 and needs its own probe: AC1.6 is on
77
+ // a hookless class, so it stays green if this line is merely
78
+ // moved BELOW the block. Measured with it moved: the suite was
79
+ // 34 pass / 0 fail while `GET http://HOST/private/failure`
80
+ // answered 505 -- the consumer's hook status, which is the same
81
+ // oracle class as 3, and the hook itself ran on a request this
82
+ // module was about to reject. Killed by AC1.11.
83
+ // 3. It rejects with `next('router')`, NOT sendStatusResponse() or
73
84
  // res.sendStatus(404). Measured: sendStatus returns
74
85
  // `text/plain "Not Found"` while a genuine miss returns
75
86
  // `text/html <pre>Cannot GET ...</pre>` -- a working ORACLE
@@ -79,6 +90,11 @@ export default class Request {
79
90
  // Content-Type, same CSP header). Routing it through
80
91
  // sendStatusResponse() would additionally re-introduce the
81
92
  // oracle for any consumer who sets a 404 in `statusMap`.
93
+ // Killed by AC1.5.
94
+ //
95
+ // Properties 1 and 2 were previously stated here as a single item
96
+ // asserted to have "its own red-able assertion". It did not: only
97
+ // half of it was covered. Do not re-merge them.
82
98
  if (shouldRejectTarget(req))
83
99
  return next('router');
84
100
  // Run auth after route matching so request.params is populated
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"}
@@ -122,7 +122,9 @@ export default function applyRouteMatching(api: Express): void;
122
122
  * hazard here, so do not carry that constraint across.
123
123
  *
124
124
  * The caller must reject with `next('router')`, NOT `res.sendStatus(404)`, and
125
- * must run this whether or not `this.auth` is set -- see src/request.ts.
125
+ * must run this BEFORE `this.auth` as well as outside `if (this.auth)` -- those
126
+ * are two separate properties with two separate assertions (AC1.11 and AC1.6);
127
+ * see src/request.ts.
126
128
  *
127
129
  * Guard polarity is `!== false`, matching both siblings, for the same measured
128
130
  * reason: the secure value is the TRUTHY one, so a plain truthy check fails
@@ -1 +1 @@
1
- {"version":3,"file":"route-matching.d.ts","sourceRoot":"","sources":["../src/route-matching.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,SAAS,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAG7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAe/D"}
1
+ {"version":3,"file":"route-matching.d.ts","sourceRoot":"","sources":["../src/route-matching.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,SAAS,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAG7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAuB/D"}
@@ -127,7 +127,9 @@ export default function applyRouteMatching(api) {
127
127
  * hazard here, so do not carry that constraint across.
128
128
  *
129
129
  * The caller must reject with `next('router')`, NOT `res.sendStatus(404)`, and
130
- * must run this whether or not `this.auth` is set -- see src/request.ts.
130
+ * must run this BEFORE `this.auth` as well as outside `if (this.auth)` -- those
131
+ * are two separate properties with two separate assertions (AC1.11 and AC1.6);
132
+ * see src/request.ts.
131
133
  *
132
134
  * Guard polarity is `!== false`, matching both siblings, for the same measured
133
135
  * reason: the secure value is the TRUTHY one, so a plain truthy check fails
@@ -155,6 +157,14 @@ export function shouldRejectTarget(req) {
155
157
  const target = req.originalUrl.split('?')[0];
156
158
  // At a mount root express reports `req.path === '/'` while the canonical
157
159
  // target is the bare mount segment, so the two are not simply concatenated.
160
+ //
161
+ // `&& req.baseUrl` is load-bearing and is NOT a redundant truthiness guard.
162
+ // A route class named `index` mounts at '/' (src/main.ts `mountRoute()`),
163
+ // and that is the one mount shape where `req.baseUrl` is ''. Without the
164
+ // conjunct, `GET /` compares the raw target '/' against a canonical of '' and
165
+ // the APPLICATION ROOT is rejected. Measured before it had a guard: shipped
166
+ // `GET /` -> 200, conjunct dropped -> 404, suite 34 pass / 0 fail BOTH ways.
167
+ // Killed now by AC1.12, against `test/sample/requests/index.ts`.
158
168
  const canonical = req.path === '/' && req.baseUrl ? req.baseUrl : req.baseUrl + req.path;
159
169
  return target !== canonical;
160
170
  }
@@ -1 +1 @@
1
- {"version":3,"file":"route-matching.js","sourceRoot":"","sources":["../src/route-matching.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,eAAe,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,GAAY;IACrD,IAAI,MAAM,CAAC,UAAU,EAAE,mBAAmB,KAAK,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC;IAC9F,IAAI,MAAM,CAAC,UAAU,EAAE,YAAY,KAAK,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACjF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAmB;IACpD,6EAA6E;IAC7E,4EAA4E;IAC5E,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,eAAe,KAAK,KAAK,CAAC;IAC9D,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5B,oEAAoE;IACpE,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,yEAAyE;IACzE,4EAA4E;IAC5E,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;IAEzF,OAAO,MAAM,KAAK,SAAS,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"route-matching.js","sourceRoot":"","sources":["../src/route-matching.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,eAAe,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,GAAY;IACrD,IAAI,MAAM,CAAC,UAAU,EAAE,mBAAmB,KAAK,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC;IAC9F,IAAI,MAAM,CAAC,UAAU,EAAE,YAAY,KAAK,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACjF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAmB;IACpD,6EAA6E;IAC7E,4EAA4E;IAC5E,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,eAAe,KAAK,KAAK,CAAC;IAC9D,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5B,oEAAoE;IACpE,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,yEAAyE;IACzE,4EAA4E;IAC5E,EAAE;IACF,4EAA4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,iEAAiE;IACjE,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;IAEzF,OAAO,MAAM,KAAK,SAAS,CAAC;AAC9B,CAAC"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "stonyx-async",
5
5
  "stonyx-module"
6
6
  ],
7
- "version": "0.2.1-alpha.24",
7
+ "version": "0.2.1-alpha.25",
8
8
  "description": "Rest Server Module for Stonyx Framework",
9
9
  "repository": {
10
10
  "type": "git",