@c9up/warden 0.1.8 → 0.1.10

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.
@@ -17,35 +17,81 @@
17
17
  */
18
18
  import { type AuthResult } from "./AuthManager.js";
19
19
  import type { BasePolicy } from "./bouncer/BasePolicy.js";
20
- import { Bouncer } from "./bouncer/Bouncer.js";
21
20
  import type { Ability } from "./bouncer/types.js";
22
21
  import type { ScopeRequestContext } from "./config.js";
23
22
  import type { Scope } from "./rights/types.js";
24
23
  import type { SessionStore } from "./strategies/SessionStrategy.js";
24
+ /**
25
+ * Tokens warden resolves from the container: a service class, or a string/symbol
26
+ * alias (`"bouncer:registry"`). Mirrors Ream's `ServiceToken` without importing
27
+ * it — warden declares the shape so it stays framework-agnostic.
28
+ */
29
+ type ResolvableToken = string | symbol | (abstract new (...args: never[]) => unknown);
30
+ /**
31
+ * Per-request IoC resolver Ream exposes as `ctx.containerResolver` (Adonis
32
+ * idiom). Warden resolves AuthManager / RightsResolver / the bouncer registry
33
+ * through this — reading from the context it is HANDED — so the package never
34
+ * imports `@c9up/ream` at runtime. A host that provides none (non-Ream, or a
35
+ * misconfigured kernel) yields no resolution: guarded routes fail CLOSED.
36
+ */
37
+ interface ContainerResolver {
38
+ make(token: ResolvableToken): unknown;
39
+ }
40
+ /**
41
+ * Agnostic authorization slot — structurally Ream's `Authorizer` interface (and
42
+ * Adonis's bouncer contract): `allows` / `denies` / `authorize`. Typed as the
43
+ * interface, NOT the concrete `Bouncer`, so a real Ream `HttpContext` — whose
44
+ * `bouncer` is this same agnostic shape — is assignable to `WardenContext`
45
+ * without warden importing `@c9up/ream`. `initializeBouncer` fills the slot with
46
+ * a concrete `Bouncer`, which satisfies this contract.
47
+ */
48
+ interface Authorizer {
49
+ allows(ability: string, ...args: unknown[]): Promise<boolean>;
50
+ denies(ability: string, ...args: unknown[]): Promise<boolean>;
51
+ authorize(ability: string, ...args: unknown[]): Promise<void>;
52
+ }
25
53
  export interface WardenContext {
26
54
  request: {
27
- method: string;
28
- url: string;
29
- headers: Record<string, string>;
55
+ /** Ream's `HttpContext` exposes headers as a METHOD, not a property. */
56
+ headers(): Record<string, string>;
30
57
  };
58
+ /**
59
+ * Per-request IoC resolver (Ream's `ctx.containerResolver`). Warden resolves
60
+ * AuthManager + the bouncer registry through it — agnostic, no `@c9up/ream`
61
+ * import. Absent on a non-Ream host → guarded routes fail closed.
62
+ */
63
+ containerResolver?: ContainerResolver;
31
64
  response: {
32
- status: (code: number) => void;
65
+ status: (code: number) => unknown;
33
66
  json: (data: unknown) => void;
34
67
  };
35
- container: {
36
- resolve: (key: string | symbol | (abstract new (...args: never[]) => unknown)) => unknown;
37
- };
38
- /** Session store set by a session middleware upstream. */
39
- session?: SessionStore;
40
- /** Set by the middleware after successful auth. */
41
- auth?: AuthResult;
42
- /** Set by `initializeBouncer` — the per-request authorization entry point. */
43
- bouncer?: Bouncer;
44
- /** The route handler metadata (decorators). */
68
+ /**
69
+ * Matched-route info Ream (like Adonis) exposes the controller class +
70
+ * method under `ctx.route` (`ctx.route.controller` / `ctx.route.action`),
71
+ * NOT top-level. This is the primary source the guard-metadata lookup reads.
72
+ * Absent for inline-function routes. (context7 `/adonisjs/v7-docs`: "access
73
+ * the currently matched route via `ctx.route`".)
74
+ */
45
75
  route?: {
46
76
  controller?: object;
47
77
  action?: string | symbol;
48
78
  };
79
+ /**
80
+ * Top-level controller/action — kept only as a FALLBACK for hosts that
81
+ * expose them flat. Ream uses `ctx.route` (above); the lookup prefers it.
82
+ */
83
+ controller?: object;
84
+ action?: string | symbol;
85
+ /** Session store — set by a session middleware upstream. */
86
+ session?: SessionStore;
87
+ /** Set by the middleware after successful auth (Ream's `auth` slot). */
88
+ auth?: AuthResult;
89
+ /**
90
+ * Per-request authorization entry point — set by `initializeBouncer`. Typed
91
+ * as the agnostic {@link Authorizer} contract (Ream's `ctx.bouncer` slot),
92
+ * filled with a concrete `Bouncer` at runtime.
93
+ */
94
+ bouncer?: Authorizer;
49
95
  }
50
96
  type WardenNext = () => Promise<void> | void;
51
97
  /**
@@ -78,5 +124,15 @@ export interface BouncerRegistry {
78
124
  * including for guests — matching AdonisJS's `initialize_bouncer_middleware`.
79
125
  */
80
126
  export declare function initializeBouncer(ctx: WardenContext, next: WardenNext): Promise<void>;
127
+ /**
128
+ * Default export — the Adonis-style class form Ream's lazy middleware resolver
129
+ * expects (`new mod.default().handle(ctx, next)`). Without it the documented
130
+ * `router.use([() => import('@c9up/warden/middleware')])` crashes with
131
+ * `new undefined()`. The named `wardenMiddleware` / `initializeBouncer` stay for
132
+ * direct registration `router.use([wardenMiddleware])`.
133
+ */
134
+ export default class WardenMiddleware {
135
+ handle(ctx: WardenContext, next: WardenNext): Promise<void>;
136
+ }
81
137
  export {};
82
138
  //# sourceMappingURL=middleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAEN,KAAK,UAAU,EAGf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAcpE,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAAC;IACF,QAAQ,EAAE;QACT,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAC/B,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;KAC9B,CAAC;IACF,SAAS,EAAE;QACV,OAAO,EAAE,CACR,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,KAC/D,OAAO,CAAC;KACb,CAAC;IACF,4DAA4D;IAC5D,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,mDAAmD;IACnD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,KAAK,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACzB,CAAC;CACF;AAED,KAAK,UAAU,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE7C;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,iBAwH1E;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,iBAmB3E"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -17,21 +17,56 @@
17
17
  */
18
18
  import { AuthManager, sanitizePayload, } from "./AuthManager.js";
19
19
  import { Bouncer } from "./bouncer/Bouncer.js";
20
+ import { WardenError } from "./errors.js";
20
21
  import { getGuardMetadata, getPermissionMetadata, getRequireMfaMetadata, getRoleMetadata, } from "./Guard.js";
21
22
  import { RightsResolver } from "./rights/RightsResolver.js";
22
23
  function hasVerifyWithContext(strategy) {
23
24
  return (typeof strategy.verifyWithContext === "function");
24
25
  }
26
+ /**
27
+ * Resolve a token from the request's IoC resolver (`ctx.containerResolver`,
28
+ * Adonis idiom). Returns undefined when no resolver is present or the token is
29
+ * unbound — callers decide fail-open (the bouncer registry) vs fail-closed (the
30
+ * AuthManager gate in `wardenMiddleware`). No `@c9up/ream` import: warden reads
31
+ * only from the context Ream hands it.
32
+ */
33
+ function resolveFromCtx(ctx, token) {
34
+ try {
35
+ return ctx.containerResolver?.make(token);
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ }
41
+ /**
42
+ * Bridge Ream's ctx to the `resolveScope` hook's `ScopeRequestContext`, which
43
+ * takes headers as a plain object (a snapshot) — keeps the app-facing hook
44
+ * contract stable while warden reads Ream's `headers()` method internally.
45
+ */
46
+ function toScopeContext(ctx) {
47
+ return { request: { headers: ctx.request.headers() }, auth: ctx.auth };
48
+ }
25
49
  /**
26
50
  * Ream auth middleware — resolves AuthManager from the container,
27
51
  * reads `@Guard`/`@Permission`/`@Role` metadata from the route handler,
28
52
  * and authenticates + authorizes the request.
29
53
  */
30
54
  export async function wardenMiddleware(ctx, next) {
31
- const auth = ctx.container.resolve(AuthManager);
55
+ const resolvedAuth = resolveFromCtx(ctx, AuthManager);
56
+ if (!(resolvedAuth instanceof AuthManager)) {
57
+ // Fail CLOSED — a missing AuthManager (WardenProvider not registered, or
58
+ // no `ctx.containerResolver` on a non-Ream host) must never silently let
59
+ // a guarded request through.
60
+ throw new WardenError("AUTH_NOT_REGISTERED", "AuthManager is not registered in the container — add WardenProvider to your providers list.");
61
+ }
62
+ const auth = resolvedAuth;
32
63
  // Read guard metadata from the route handler (if declared via decorators).
33
- const controller = ctx.route?.controller;
34
- const action = ctx.route?.action;
64
+ // Ream (like Adonis) exposes the controller/method under `ctx.route`; fall
65
+ // back to top-level only for hosts that expose them flat. Reading the wrong
66
+ // place silently yields `[]` guards → guarded routes treated as public
67
+ // (fail-open) — the exact bug this precedence prevents.
68
+ const controller = ctx.route?.controller ?? ctx.controller;
69
+ const action = ctx.route?.action ?? ctx.action;
35
70
  const strategies = controller && action ? getGuardMetadata(controller, action) : [];
36
71
  // No guard on this route — pass through (public endpoint).
37
72
  if (strategies.length === 0) {
@@ -43,7 +78,8 @@ export async function wardenMiddleware(ctx, next) {
43
78
  // 2. API key header — reads the header name from the ApiKeyStrategy config
44
79
  // (defaults to 'x-api-key' if no ApiKeyStrategy is registered)
45
80
  // 3. Cookie/session (Session strategy — handled by the strategy itself via context)
46
- const authHeader = ctx.request.headers.authorization ?? "";
81
+ const headers = ctx.request.headers();
82
+ const authHeader = headers.authorization ?? "";
47
83
  const bearerToken = authHeader.startsWith("Bearer ")
48
84
  ? authHeader.slice(7)
49
85
  : "";
@@ -61,7 +97,7 @@ export async function wardenMiddleware(ctx, next) {
61
97
  // declared with `headerName: "X-Custom-Key"` would never match the
62
98
  // incoming `x-custom-key` key without this normalisation — auth
63
99
  // would silently fail even with the right header on the wire.
64
- const apiKey = ctx.request.headers[apiKeyHeader.toLowerCase()] ?? "";
100
+ const apiKey = headers[apiKeyHeader.toLowerCase()] ?? "";
65
101
  const hasSessionStrategy = strategies.some((s) => s === "session");
66
102
  if (!bearerToken && !apiKey && !hasSessionStrategy) {
67
103
  ctx.response.status(401);
@@ -150,7 +186,7 @@ export async function initializeBouncer(ctx, next) {
150
186
  const registry = isBouncerRegistry(candidate) ? candidate : undefined;
151
187
  const user = ctx.auth?.user ?? null;
152
188
  const scope = registry?.resolveScope
153
- ? await registry.resolveScope(ctx)
189
+ ? await registry.resolveScope(toScopeContext(ctx))
154
190
  : "global";
155
191
  ctx.bouncer = new Bouncer(user, registry?.abilities, registry?.policies, {
156
192
  scope,
@@ -158,14 +194,9 @@ export async function initializeBouncer(ctx, next) {
158
194
  });
159
195
  await next();
160
196
  }
161
- /** Resolve a container token, returning undefined instead of throwing when absent. */
197
+ /** Resolve a container token from the request resolver, returning undefined instead of throwing when absent. */
162
198
  function tryResolve(ctx, token) {
163
- try {
164
- return ctx.container.resolve(token);
165
- }
166
- catch {
167
- return undefined;
168
- }
199
+ return resolveFromCtx(ctx, token);
169
200
  }
170
201
  /** Structural guard — the registry is a plain object carrying ability/policy tables. */
171
202
  function isBouncerRegistry(value) {
@@ -183,7 +214,9 @@ function isBouncerRegistry(value) {
183
214
  async function resolveRequestScope(ctx) {
184
215
  const candidate = tryResolve(ctx, "bouncer:registry");
185
216
  const registry = isBouncerRegistry(candidate) ? candidate : undefined;
186
- return registry?.resolveScope ? await registry.resolveScope(ctx) : "global";
217
+ return registry?.resolveScope
218
+ ? await registry.resolveScope(toScopeContext(ctx))
219
+ : "global";
187
220
  }
188
221
  /**
189
222
  * Try each declared strategy in order — session strategies via
@@ -271,4 +304,16 @@ async function checkAuthorization(auth, user, controller, action, scope) {
271
304
  }
272
305
  return null;
273
306
  }
307
+ /**
308
+ * Default export — the Adonis-style class form Ream's lazy middleware resolver
309
+ * expects (`new mod.default().handle(ctx, next)`). Without it the documented
310
+ * `router.use([() => import('@c9up/warden/middleware')])` crashes with
311
+ * `new undefined()`. The named `wardenMiddleware` / `initializeBouncer` stay for
312
+ * direct registration `router.use([wardenMiddleware])`.
313
+ */
314
+ export default class WardenMiddleware {
315
+ handle(ctx, next) {
316
+ return wardenMiddleware(ctx, next);
317
+ }
318
+ }
274
319
  //# sourceMappingURL=middleware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/warden",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Warden — Authentication & authorization for the Ream framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -45,7 +45,7 @@
45
45
  }
46
46
  },
47
47
  "peerDependencies": {
48
- "@c9up/ream": "^0.1.0"
48
+ "@c9up/ream": "^0.1.10"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "@c9up/ream": {
package/src/middleware.ts CHANGED
@@ -26,6 +26,7 @@ import type { BasePolicy } from "./bouncer/BasePolicy.js";
26
26
  import { Bouncer } from "./bouncer/Bouncer.js";
27
27
  import type { Ability } from "./bouncer/types.js";
28
28
  import type { ScopeRequestContext } from "./config.js";
29
+ import { WardenError } from "./errors.js";
29
30
  import {
30
31
  getGuardMetadata,
31
32
  getPermissionMetadata,
@@ -48,32 +49,107 @@ function hasVerifyWithContext(
48
49
  );
49
50
  }
50
51
 
52
+ /**
53
+ * Tokens warden resolves from the container: a service class, or a string/symbol
54
+ * alias (`"bouncer:registry"`). Mirrors Ream's `ServiceToken` without importing
55
+ * it — warden declares the shape so it stays framework-agnostic.
56
+ */
57
+ type ResolvableToken =
58
+ | string
59
+ | symbol
60
+ | (abstract new (...args: never[]) => unknown);
61
+
62
+ /**
63
+ * Per-request IoC resolver Ream exposes as `ctx.containerResolver` (Adonis
64
+ * idiom). Warden resolves AuthManager / RightsResolver / the bouncer registry
65
+ * through this — reading from the context it is HANDED — so the package never
66
+ * imports `@c9up/ream` at runtime. A host that provides none (non-Ream, or a
67
+ * misconfigured kernel) yields no resolution: guarded routes fail CLOSED.
68
+ */
69
+ interface ContainerResolver {
70
+ make(token: ResolvableToken): unknown;
71
+ }
72
+
73
+ /**
74
+ * Agnostic authorization slot — structurally Ream's `Authorizer` interface (and
75
+ * Adonis's bouncer contract): `allows` / `denies` / `authorize`. Typed as the
76
+ * interface, NOT the concrete `Bouncer`, so a real Ream `HttpContext` — whose
77
+ * `bouncer` is this same agnostic shape — is assignable to `WardenContext`
78
+ * without warden importing `@c9up/ream`. `initializeBouncer` fills the slot with
79
+ * a concrete `Bouncer`, which satisfies this contract.
80
+ */
81
+ interface Authorizer {
82
+ allows(ability: string, ...args: unknown[]): Promise<boolean>;
83
+ denies(ability: string, ...args: unknown[]): Promise<boolean>;
84
+ authorize(ability: string, ...args: unknown[]): Promise<void>;
85
+ }
86
+
51
87
  export interface WardenContext {
52
88
  request: {
53
- method: string;
54
- url: string;
55
- headers: Record<string, string>;
89
+ /** Ream's `HttpContext` exposes headers as a METHOD, not a property. */
90
+ headers(): Record<string, string>;
56
91
  };
92
+ /**
93
+ * Per-request IoC resolver (Ream's `ctx.containerResolver`). Warden resolves
94
+ * AuthManager + the bouncer registry through it — agnostic, no `@c9up/ream`
95
+ * import. Absent on a non-Ream host → guarded routes fail closed.
96
+ */
97
+ containerResolver?: ContainerResolver;
57
98
  response: {
58
- status: (code: number) => void;
99
+ status: (code: number) => unknown;
59
100
  json: (data: unknown) => void;
60
101
  };
61
- container: {
62
- resolve: (
63
- key: string | symbol | (abstract new (...args: never[]) => unknown),
64
- ) => unknown;
65
- };
66
- /** Session store set by a session middleware upstream. */
67
- session?: SessionStore;
68
- /** Set by the middleware after successful auth. */
69
- auth?: AuthResult;
70
- /** Set by `initializeBouncer` — the per-request authorization entry point. */
71
- bouncer?: Bouncer;
72
- /** The route handler metadata (decorators). */
102
+ /**
103
+ * Matched-route info — Ream (like Adonis) exposes the controller class +
104
+ * method under `ctx.route` (`ctx.route.controller` / `ctx.route.action`),
105
+ * NOT top-level. This is the primary source the guard-metadata lookup reads.
106
+ * Absent for inline-function routes. (context7 `/adonisjs/v7-docs`: "access
107
+ * the currently matched route via `ctx.route`".)
108
+ */
73
109
  route?: {
74
110
  controller?: object;
75
111
  action?: string | symbol;
76
112
  };
113
+ /**
114
+ * Top-level controller/action — kept only as a FALLBACK for hosts that
115
+ * expose them flat. Ream uses `ctx.route` (above); the lookup prefers it.
116
+ */
117
+ controller?: object;
118
+ action?: string | symbol;
119
+ /** Session store — set by a session middleware upstream. */
120
+ session?: SessionStore;
121
+ /** Set by the middleware after successful auth (Ream's `auth` slot). */
122
+ auth?: AuthResult;
123
+ /**
124
+ * Per-request authorization entry point — set by `initializeBouncer`. Typed
125
+ * as the agnostic {@link Authorizer} contract (Ream's `ctx.bouncer` slot),
126
+ * filled with a concrete `Bouncer` at runtime.
127
+ */
128
+ bouncer?: Authorizer;
129
+ }
130
+
131
+ /**
132
+ * Resolve a token from the request's IoC resolver (`ctx.containerResolver`,
133
+ * Adonis idiom). Returns undefined when no resolver is present or the token is
134
+ * unbound — callers decide fail-open (the bouncer registry) vs fail-closed (the
135
+ * AuthManager gate in `wardenMiddleware`). No `@c9up/ream` import: warden reads
136
+ * only from the context Ream hands it.
137
+ */
138
+ function resolveFromCtx(ctx: WardenContext, token: ResolvableToken): unknown {
139
+ try {
140
+ return ctx.containerResolver?.make(token);
141
+ } catch {
142
+ return undefined;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Bridge Ream's ctx to the `resolveScope` hook's `ScopeRequestContext`, which
148
+ * takes headers as a plain object (a snapshot) — keeps the app-facing hook
149
+ * contract stable while warden reads Ream's `headers()` method internally.
150
+ */
151
+ function toScopeContext(ctx: WardenContext): ScopeRequestContext {
152
+ return { request: { headers: ctx.request.headers() }, auth: ctx.auth };
77
153
  }
78
154
 
79
155
  type WardenNext = () => Promise<void> | void;
@@ -84,11 +160,25 @@ type WardenNext = () => Promise<void> | void;
84
160
  * and authenticates + authorizes the request.
85
161
  */
86
162
  export async function wardenMiddleware(ctx: WardenContext, next: WardenNext) {
87
- const auth = ctx.container.resolve(AuthManager) as AuthManager;
163
+ const resolvedAuth = resolveFromCtx(ctx, AuthManager);
164
+ if (!(resolvedAuth instanceof AuthManager)) {
165
+ // Fail CLOSED — a missing AuthManager (WardenProvider not registered, or
166
+ // no `ctx.containerResolver` on a non-Ream host) must never silently let
167
+ // a guarded request through.
168
+ throw new WardenError(
169
+ "AUTH_NOT_REGISTERED",
170
+ "AuthManager is not registered in the container — add WardenProvider to your providers list.",
171
+ );
172
+ }
173
+ const auth = resolvedAuth;
88
174
 
89
175
  // Read guard metadata from the route handler (if declared via decorators).
90
- const controller = ctx.route?.controller;
91
- const action = ctx.route?.action;
176
+ // Ream (like Adonis) exposes the controller/method under `ctx.route`; fall
177
+ // back to top-level only for hosts that expose them flat. Reading the wrong
178
+ // place silently yields `[]` guards → guarded routes treated as public
179
+ // (fail-open) — the exact bug this precedence prevents.
180
+ const controller = ctx.route?.controller ?? ctx.controller;
181
+ const action = ctx.route?.action ?? ctx.action;
92
182
  const strategies =
93
183
  controller && action ? getGuardMetadata(controller, action) : [];
94
184
 
@@ -103,7 +193,8 @@ export async function wardenMiddleware(ctx: WardenContext, next: WardenNext) {
103
193
  // 2. API key header — reads the header name from the ApiKeyStrategy config
104
194
  // (defaults to 'x-api-key' if no ApiKeyStrategy is registered)
105
195
  // 3. Cookie/session (Session strategy — handled by the strategy itself via context)
106
- const authHeader = ctx.request.headers.authorization ?? "";
196
+ const headers = ctx.request.headers();
197
+ const authHeader = headers.authorization ?? "";
107
198
  const bearerToken = authHeader.startsWith("Bearer ")
108
199
  ? authHeader.slice(7)
109
200
  : "";
@@ -120,7 +211,7 @@ export async function wardenMiddleware(ctx: WardenContext, next: WardenNext) {
120
211
  // declared with `headerName: "X-Custom-Key"` would never match the
121
212
  // incoming `x-custom-key` key without this normalisation — auth
122
213
  // would silently fail even with the right header on the wire.
123
- const apiKey = ctx.request.headers[apiKeyHeader.toLowerCase()] ?? "";
214
+ const apiKey = headers[apiKeyHeader.toLowerCase()] ?? "";
124
215
 
125
216
  const hasSessionStrategy = strategies.some((s) => s === "session");
126
217
  if (!bearerToken && !apiKey && !hasSessionStrategy) {
@@ -240,7 +331,7 @@ export async function initializeBouncer(ctx: WardenContext, next: WardenNext) {
240
331
 
241
332
  const user = ctx.auth?.user ?? null;
242
333
  const scope: Scope = registry?.resolveScope
243
- ? await registry.resolveScope(ctx)
334
+ ? await registry.resolveScope(toScopeContext(ctx))
244
335
  : "global";
245
336
 
246
337
  ctx.bouncer = new Bouncer(user, registry?.abilities, registry?.policies, {
@@ -250,16 +341,9 @@ export async function initializeBouncer(ctx: WardenContext, next: WardenNext) {
250
341
  await next();
251
342
  }
252
343
 
253
- /** Resolve a container token, returning undefined instead of throwing when absent. */
254
- function tryResolve(
255
- ctx: WardenContext,
256
- token: string | (abstract new (...args: never[]) => unknown),
257
- ): unknown {
258
- try {
259
- return ctx.container.resolve(token);
260
- } catch {
261
- return undefined;
262
- }
344
+ /** Resolve a container token from the request resolver, returning undefined instead of throwing when absent. */
345
+ function tryResolve(ctx: WardenContext, token: ResolvableToken): unknown {
346
+ return resolveFromCtx(ctx, token);
263
347
  }
264
348
 
265
349
  /** Structural guard — the registry is a plain object carrying ability/policy tables. */
@@ -281,7 +365,9 @@ function isBouncerRegistry(value: unknown): value is BouncerRegistry {
281
365
  async function resolveRequestScope(ctx: WardenContext): Promise<Scope> {
282
366
  const candidate = tryResolve(ctx, "bouncer:registry");
283
367
  const registry = isBouncerRegistry(candidate) ? candidate : undefined;
284
- return registry?.resolveScope ? await registry.resolveScope(ctx) : "global";
368
+ return registry?.resolveScope
369
+ ? await registry.resolveScope(toScopeContext(ctx))
370
+ : "global";
285
371
  }
286
372
 
287
373
  /**
@@ -390,3 +476,16 @@ async function checkAuthorization(
390
476
  }
391
477
  return null;
392
478
  }
479
+
480
+ /**
481
+ * Default export — the Adonis-style class form Ream's lazy middleware resolver
482
+ * expects (`new mod.default().handle(ctx, next)`). Without it the documented
483
+ * `router.use([() => import('@c9up/warden/middleware')])` crashes with
484
+ * `new undefined()`. The named `wardenMiddleware` / `initializeBouncer` stay for
485
+ * direct registration `router.use([wardenMiddleware])`.
486
+ */
487
+ export default class WardenMiddleware {
488
+ handle(ctx: WardenContext, next: WardenNext): Promise<void> {
489
+ return wardenMiddleware(ctx, next);
490
+ }
491
+ }