@porulle/core 0.23.0 → 0.24.1

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.
Files changed (40) hide show
  1. package/dist/auth/identity-free-routes.d.ts +51 -0
  2. package/dist/auth/identity-free-routes.d.ts.map +1 -0
  3. package/dist/auth/identity-free-routes.js +49 -0
  4. package/dist/auth/middleware.d.ts.map +1 -1
  5. package/dist/auth/middleware.js +6 -0
  6. package/dist/auth/permissions.d.ts +7 -0
  7. package/dist/auth/permissions.d.ts.map +1 -1
  8. package/dist/auth/permissions.js +23 -3
  9. package/dist/config/types.d.ts +15 -0
  10. package/dist/config/types.d.ts.map +1 -1
  11. package/dist/index.d.ts +4 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -2
  14. package/dist/interfaces/rest/customer-portal.d.ts.map +1 -1
  15. package/dist/interfaces/rest/customer-portal.js +14 -2
  16. package/dist/interfaces/rest/router.d.ts +10 -1
  17. package/dist/interfaces/rest/router.d.ts.map +1 -1
  18. package/dist/interfaces/rest/router.js +22 -6
  19. package/dist/interfaces/rest/utils.d.ts +3 -8
  20. package/dist/interfaces/rest/utils.d.ts.map +1 -1
  21. package/dist/interfaces/rest/utils.js +8 -7
  22. package/dist/kernel/error-mapper.d.ts.map +1 -1
  23. package/dist/kernel/error-mapper.js +1 -0
  24. package/dist/kernel/errors.d.ts +5 -0
  25. package/dist/kernel/errors.d.ts.map +1 -1
  26. package/dist/kernel/errors.js +9 -0
  27. package/dist/modules/cart/service.d.ts.map +1 -1
  28. package/dist/modules/cart/service.js +4 -4
  29. package/package.json +3 -3
  30. package/src/auth/identity-free-routes.ts +86 -0
  31. package/src/auth/middleware.ts +7 -0
  32. package/src/auth/permissions.ts +30 -2
  33. package/src/config/types.ts +15 -0
  34. package/src/index.ts +10 -1
  35. package/src/interfaces/rest/customer-portal.ts +23 -3
  36. package/src/interfaces/rest/router.ts +36 -8
  37. package/src/interfaces/rest/utils.ts +16 -11
  38. package/src/kernel/error-mapper.ts +1 -0
  39. package/src/kernel/errors.ts +8 -0
  40. package/src/modules/cart/service.ts +9 -5
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Routes that read no actor, so `authMiddleware` need not resolve one.
3
+ *
4
+ * THE DEFAULT IS TO RESOLVE. A route absent from this list keeps its actor,
5
+ * because the failure mode of the opposite default is silent: a route that
6
+ * stops receiving an actor does not throw, it 401s, or takes an anonymous
7
+ * branch and answers.
8
+ *
9
+ * Matching is EXACT on method and path — no patterns, no prefixes. A pattern is
10
+ * how one entry silently widens to cover a route that does need an identity,
11
+ * and this list is small enough that the cost of exactness is a line per route.
12
+ * A route with a path parameter therefore cannot be listed at all, which is the
13
+ * intended limit rather than an oversight.
14
+ *
15
+ * Entries are the routes whose handlers were read and shown to consult neither
16
+ * `c.get("actor")` nor anything derived from it. `/api/carts` and the rest of
17
+ * `PUBLIC_ROUTES` in `interfaces/rest/route-coverage.ts` are NOT here: they are
18
+ * public in the sense of needing no permission, and they still need the
19
+ * organization the anonymous actor carries. Public and identity-free are
20
+ * different properties and this list is the second one.
21
+ */
22
+ export type IdentityFreeRoute = {
23
+ method: string;
24
+ path: string;
25
+ justification: string;
26
+ };
27
+ export declare const IDENTITY_FREE_ROUTES: readonly IdentityFreeRoute[];
28
+ /**
29
+ * An app declares its own with `auth.identityFreeRoutes: ["POST /api/payments/notify"]`.
30
+ *
31
+ * Additive only: a config entry can never remove one of the defaults above, so
32
+ * the narrowest thing an app can do to this set is widen it, and the widening
33
+ * is visible in its own configuration file.
34
+ *
35
+ * The routes that want this are app-local by nature — a signed payment notify,
36
+ * a tracked click-out — and they have no session, taking their organization
37
+ * from the payload they verified rather than from a resolver, which is what
38
+ * core's own `POST /api/payments/webhook` already does.
39
+ *
40
+ * WHAT AN ENTRY COSTS: `authMiddleware` is followed by the wrapper that opens
41
+ * the plugin database scope FROM THE RESOLVED ACTOR. A route listed here gets
42
+ * no actor, so it gets no scope, and every plugin read and write on that
43
+ * request runs with no organization predicate while the handler still answers
44
+ * normally. Such a route must open its own scope.
45
+ */
46
+ export declare function isIdentityFreeRoute(method: string, path: string, config?: {
47
+ auth?: {
48
+ identityFreeRoutes?: readonly string[];
49
+ };
50
+ }): boolean;
51
+ //# sourceMappingURL=identity-free-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-free-routes.d.ts","sourceRoot":"","sources":["../../src/auth/identity-free-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAmB5D,CAAC;AAWF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAA;CAAE,GAC7D,OAAO,CAMT"}
@@ -0,0 +1,49 @@
1
+ export const IDENTITY_FREE_ROUTES = [
2
+ {
3
+ method: "GET",
4
+ path: "/api/health",
5
+ justification: "A liveness probe for load balancers; the handler issues its own SELECT 1 and reads no actor.",
6
+ },
7
+ {
8
+ method: "GET",
9
+ path: "/api/doc",
10
+ justification: "The generated OpenAPI document is built from config and the route table, never from the caller.",
11
+ },
12
+ {
13
+ method: "GET",
14
+ path: "/api/doc-ext",
15
+ justification: "The enriched OpenAPI document, same handler shape as /api/doc.",
16
+ },
17
+ ];
18
+ const DEFAULT_KEYS = new Set(IDENTITY_FREE_ROUTES.map((route) => `${route.method} ${route.path}`));
19
+ function normalize(entry) {
20
+ const [method = "", ...rest] = entry.trim().split(/\s+/);
21
+ return `${method.toUpperCase()} ${rest.join(" ")}`;
22
+ }
23
+ /**
24
+ * An app declares its own with `auth.identityFreeRoutes: ["POST /api/payments/notify"]`.
25
+ *
26
+ * Additive only: a config entry can never remove one of the defaults above, so
27
+ * the narrowest thing an app can do to this set is widen it, and the widening
28
+ * is visible in its own configuration file.
29
+ *
30
+ * The routes that want this are app-local by nature — a signed payment notify,
31
+ * a tracked click-out — and they have no session, taking their organization
32
+ * from the payload they verified rather than from a resolver, which is what
33
+ * core's own `POST /api/payments/webhook` already does.
34
+ *
35
+ * WHAT AN ENTRY COSTS: `authMiddleware` is followed by the wrapper that opens
36
+ * the plugin database scope FROM THE RESOLVED ACTOR. A route listed here gets
37
+ * no actor, so it gets no scope, and every plugin read and write on that
38
+ * request runs with no organization predicate while the handler still answers
39
+ * normally. Such a route must open its own scope.
40
+ */
41
+ export function isIdentityFreeRoute(method, path, config) {
42
+ const key = `${method.toUpperCase()} ${path}`;
43
+ if (DEFAULT_KEYS.has(key))
44
+ return true;
45
+ const declared = config?.auth?.identityFreeRoutes;
46
+ if (!declared)
47
+ return false;
48
+ return declared.some((entry) => normalize(entry) === key);
49
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAa/C,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAK1D,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACrB,iBAAiB,CAiNnB"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAc/C,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAK1D,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACrB,iBAAiB,CAuNnB"}
@@ -2,6 +2,7 @@ import { getCustomerPermissions, resolveActor } from "./actor.js";
2
2
  import { DEFAULT_ORG_ID } from "./org.js";
3
3
  import { isCredentialRejection } from "./auth-failure.js";
4
4
  import { isStrictOrgResolution } from "./strict-org-resolution.js";
5
+ import { isIdentityFreeRoute } from "./identity-free-routes.js";
5
6
  function emptyToNull(value) {
6
7
  return value == null || value === "" ? null : value;
7
8
  }
@@ -13,6 +14,11 @@ const LEGACY_STORE_RESOLVER_WARN_COOLDOWN_MS = 60_000;
13
14
  let lastLegacyStoreResolverWarnAt = 0;
14
15
  export function authMiddleware(auth, config) {
15
16
  return async (c, next) => {
17
+ if (isIdentityFreeRoute(c.req.method, c.req.path, config)) {
18
+ c.set("actor", null);
19
+ await next();
20
+ return;
21
+ }
16
22
  // Resolve the default org from config, falling back to deprecated constant
17
23
  const defaultOrgId = config.auth?.defaultOrganizationId ?? DEFAULT_ORG_ID;
18
24
  // Test-only actor injection: requires NODE_ENV === "test" AND an explicit
@@ -1,4 +1,11 @@
1
1
  import type { Actor } from "./types.js";
2
+ export declare const AUTHENTICATION_REQUIRED_MESSAGE = "Authentication required.";
3
+ /**
4
+ * True when the request carried no credential at all. An API key actor
5
+ * (`type: "api_key"`) DID present one, whatever its referenceId, so it keeps
6
+ * 403 — telling it to authenticate would be a lie it cannot act on.
7
+ */
8
+ export declare function isUnauthenticatedActor(actor: Pick<Actor, "type" | "userId"> | null): boolean;
2
9
  export declare function hasPermission(actor: Actor | null, required: string): boolean;
3
10
  export declare function assertPermission(actor: Actor | null, required: string): void;
4
11
  export declare function assertOwnership(actor: Actor | null, resourceOwnerId: string | null): void;
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/auth/permissions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAO5E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAO5E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAWzF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAI,GAAG,MAAM,CAQzE"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/auth/permissions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,eAAO,MAAM,+BAA+B,6BAA6B,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG,IAAI,GAC3C,OAAO,CAET;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAO5E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAa5E;AAQD,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAWzF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAI,GAAG,MAAM,CAQzE"}
@@ -1,4 +1,13 @@
1
- import { CommerceForbiddenError } from "../kernel/errors.js";
1
+ import { CommerceForbiddenError, CommerceUnauthorizedError, } from "../kernel/errors.js";
2
+ export const AUTHENTICATION_REQUIRED_MESSAGE = "Authentication required.";
3
+ /**
4
+ * True when the request carried no credential at all. An API key actor
5
+ * (`type: "api_key"`) DID present one, whatever its referenceId, so it keeps
6
+ * 403 — telling it to authenticate would be a lie it cannot act on.
7
+ */
8
+ export function isUnauthenticatedActor(actor) {
9
+ return actor === null || (actor.type === "user" && actor.userId === null);
10
+ }
2
11
  export function hasPermission(actor, required) {
3
12
  if (!actor)
4
13
  return false;
@@ -12,10 +21,21 @@ export function hasPermission(actor, required) {
12
21
  export function assertPermission(actor, required) {
13
22
  if (hasPermission(actor, required))
14
23
  return;
15
- if (!actor)
16
- throw new CommerceForbiddenError("Authentication required.");
24
+ // `actor === null` is redundant at runtime — the predicate already covers it —
25
+ // and load-bearing at compile time: a boolean predicate narrows nothing, and
26
+ // the message below reads `actor.role`. Written this way rather than as a cast
27
+ // so it cannot start lying if the predicate changes.
28
+ if (actor === null || isUnauthenticatedActor(actor)) {
29
+ throw new CommerceUnauthorizedError(AUTHENTICATION_REQUIRED_MESSAGE);
30
+ }
17
31
  throw new CommerceForbiddenError(`Permission "${required}" is required. Your role "${actor.role}" does not include this permission.`);
18
32
  }
33
+ // NOT given the unauthenticated predicate, and the omission is deliberate.
34
+ // `auth-permissions.test.ts` pins this refusal as 403 for a STAFF actor with a
35
+ // null userId — a shape `resolveActor` cannot produce — so whether that means
36
+ // "anonymous" or "a synthetic actor whose identity is broken" has to be decided
37
+ // before the status can be. It is carded; no route reaches here with an
38
+ // anonymous actor today.
19
39
  export function assertOwnership(actor, resourceOwnerId) {
20
40
  if (!actor) {
21
41
  throw new CommerceForbiddenError("Authentication required.");
@@ -195,6 +195,21 @@ export interface AuthConfig {
195
195
  * ```
196
196
  */
197
197
  storeResolver?: (request: Request) => string | null | Promise<string | null>;
198
+ /**
199
+ * Routes this app serves that read no actor, as `"<METHOD> <exact path>"` —
200
+ * e.g. `["POST /api/payments/notify", "GET /api/out/:token"]`. Matching is
201
+ * exact; there are no globs, because a glob is how one entry silently widens
202
+ * to cover a route that does need an identity.
203
+ *
204
+ * Additive to core's own list, and it can never remove one. Core's defaults
205
+ * are in `auth/identity-free-routes.ts` with the evidence for each.
206
+ *
207
+ * The route then resolves NO actor, which also means it gets no plugin
208
+ * database scope — that scope is derived from the actor. Such a route must
209
+ * open its own, the way a signed webhook builds its actor from the payload it
210
+ * verified. Listing a route that reads `c.get("actor")` will not fail loudly.
211
+ */
212
+ identityFreeRoutes?: readonly string[];
198
213
  /**
199
214
  * Governs two layers, and its default differs between them.
200
215
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEhG,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACrC,WAAW,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;IACnC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACrC,WAAW,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;IACnC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACrC,WAAW,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;IACnC;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACnC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACnC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,6NAA6N;IAC7N,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,sDAAsD;IACtD,SAAS,CAAC,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,mCAAmC;QACnC,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF;;;;;OAKG;IACH,aAAa,CAAC,EAAE;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC;IACrC,0FAA0F;IAC1F,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;OAWG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC9D,OAAO,CAAC,EAAE;QACR,OAAO,EAAE,OAAO,CAAC;QACjB,qEAAqE;QACrE,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC/B,CAAC;IACF,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACvC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IACrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7E;;;;;;;;;;;;;OAaG;IACH,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,SAAS,CAAC,EAAE;QACV,wFAAwF;QACxF,OAAO,EAAE,CAAC,MAAM,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/F,wFAAwF;QACxF,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACxG,8BAA8B;QAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,uDAAuD;QACvD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,4FAA4F;QAC5F,oBAAoB,CAAC,EAAE;YACrB,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;YAC9C,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;SAC/C,CAAC;KACH,CAAC;IACF;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC7B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QACN,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,YAAY,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,gBAAgB,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,eAAe,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,oBAAoB,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,mBAAmB,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;KAC5C,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE;QACN,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,WAAW,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;KACpC,CAAC;CACH;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,cAAc,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC;CAC/D;AAED,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,wBAAwB,CAAC;IAC/C,KAAK,CAAC,EAAE;QACN,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,WAAW,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,kBAAkB,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,iBAAiB,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,QAAQ,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;KACtC,CAAC;IACF;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE;QACN,WAAW,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;KACpC,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,kBAAkB,CAAC,EAAE;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,cAAc,KACnB,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QACR,QAAQ,EAAE,YAAY,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC;IACF,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,yBAAyB,EAAE,aAAa,CAAC;IAC1D,KAAK,CAAC,EAAE;QACN,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB;;;;WAIG;QACH,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,KAAK,EAAE;YACV,QAAQ,EAAE,MAAM,CAAC;YACjB,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACnB,CAAC;IACF,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,eAAe,CAAC;QAC1B,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;QACzB,eAAe,CAAC,EAAE,kBAAkB,CAAC;QACrC,OAAO,CAAC,EAAE;YACR,OAAO,EAAE,OAAO,CAAC;YACjB,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC;KACH,CAAC;IACF;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C;;;OAGG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAClF,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACnE;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,+BAA+B;IAC/B,UAAU,CAAC,EAAE;QACX,yDAAyD;QACzD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,2DAA2D;QAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,2DAA2D;QAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,oDAAoD;QACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,kEAAkE;QAClE,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE;QACT,GAAG,CAAC,EAAE;YACJ,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACnC,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;CAAG;AAE5D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;IACF,OAAO,EAAE;QACP,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvC,6EAA6E;QAC7E,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;KAClC,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB"}
package/dist/index.d.ts CHANGED
@@ -21,7 +21,9 @@ export { createSystemActor } from "./auth/system-actor.js";
21
21
  export { OrganizationService } from "./modules/organization/service.js";
22
22
  export { createScopedDb } from "./kernel/database/scoped-db.js";
23
23
  export type { ScopedOrganizationId } from "./kernel/database/scoped-db.js";
24
- export { assertOwnership, assertPermission, requireUserId } from "./auth/permissions.js";
24
+ export { IDENTITY_FREE_ROUTES, isIdentityFreeRoute } from "./auth/identity-free-routes.js";
25
+ export type { IdentityFreeRoute } from "./auth/identity-free-routes.js";
26
+ export { AUTHENTICATION_REQUIRED_MESSAGE, assertOwnership, assertPermission, isUnauthenticatedActor, requireUserId, } from "./auth/permissions.js";
25
27
  export type { AccessResult, AccessContext, AccessFn, WhereClause } from "./auth/access.js";
26
28
  export { accessOR, accessAND, conditional, isAdmin, isAuthenticated, isDocumentOwner, publicAccess, denyAll, } from "./auth/access.js";
27
29
  export { HookRegistry } from "./kernel/hooks/registry.js";
@@ -52,7 +54,7 @@ export { defineModule } from "./kernel/module/index.js";
52
54
  export type { AppModule, ModuleDeps, ServiceMap } from "./kernel/module/index.js";
53
55
  export { toHttpError, type HttpErrorResponse } from "./kernel/http-error.js";
54
56
  export { withTiming } from "./kernel/service-timing.js";
55
- export { CommerceNotFoundError, CommerceValidationError, CommerceForbiddenError, CommerceReauthRequiredError, CommerceConflictError, CommerceInvalidTransitionError, OrgResolutionError, } from "./kernel/errors.js";
57
+ export { CommerceNotFoundError, CommerceValidationError, CommerceForbiddenError, CommerceUnauthorizedError, CommerceReauthRequiredError, CommerceConflictError, CommerceInvalidTransitionError, OrgResolutionError, } from "./kernel/errors.js";
56
58
  export { mapErrorToStatus } from "./kernel/error-mapper.js";
57
59
  export { canTransition, assertTransition, orderStateMachine, extendOrderStateMachine, } from "./kernel/state-machine/machine.js";
58
60
  export type { PaymentAdapter, PaymentCapture, PaymentIntent, PaymentRefund, PaymentWebhookEvent, } from "./modules/payments/adapter.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -14,7 +14,8 @@ export { resolveOrgId, resolveOrgIdForCommerce, ensureDefaultOrg, DEFAULT_ORG_ID
14
14
  export { createSystemActor } from "./auth/system-actor.js";
15
15
  export { OrganizationService } from "./modules/organization/service.js";
16
16
  export { createScopedDb } from "./kernel/database/scoped-db.js";
17
- export { assertOwnership, assertPermission, requireUserId } from "./auth/permissions.js";
17
+ export { IDENTITY_FREE_ROUTES, isIdentityFreeRoute } from "./auth/identity-free-routes.js";
18
+ export { AUTHENTICATION_REQUIRED_MESSAGE, assertOwnership, assertPermission, isUnauthenticatedActor, requireUserId, } from "./auth/permissions.js";
18
19
  export { accessOR, accessAND, conditional, isAdmin, isAuthenticated, isDocumentOwner, publicAccess, denyAll, } from "./auth/access.js";
19
20
  export { HookRegistry } from "./kernel/hooks/registry.js";
20
21
  export { runBeforeHooks, runAfterHooks } from "./kernel/hooks/executor.js";
@@ -32,7 +33,7 @@ export { Ok, Err, PluginErr } from "./kernel/result.js";
32
33
  export { defineModule } from "./kernel/module/index.js";
33
34
  export { toHttpError } from "./kernel/http-error.js";
34
35
  export { withTiming } from "./kernel/service-timing.js";
35
- export { CommerceNotFoundError, CommerceValidationError, CommerceForbiddenError, CommerceReauthRequiredError, CommerceConflictError, CommerceInvalidTransitionError, OrgResolutionError, } from "./kernel/errors.js";
36
+ export { CommerceNotFoundError, CommerceValidationError, CommerceForbiddenError, CommerceUnauthorizedError, CommerceReauthRequiredError, CommerceConflictError, CommerceInvalidTransitionError, OrgResolutionError, } from "./kernel/errors.js";
36
37
  export { mapErrorToStatus } from "./kernel/error-mapper.js";
37
38
  export { canTransition, assertTransition, orderStateMachine, extendOrderStateMachine, } from "./kernel/state-machine/machine.js";
38
39
  export { defineChannelConnector } from "./modules/channels/adapter.js";
@@ -1 +1 @@
1
- {"version":3,"file":"customer-portal.d.ts","sourceRoot":"","sources":["../../../src/interfaces/rest/customer-portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAkBzC,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,gCA2RxD"}
1
+ {"version":3,"file":"customer-portal.d.ts","sourceRoot":"","sources":["../../../src/interfaces/rest/customer-portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAQtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAkBzC,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,gCA0SxD"}
@@ -1,13 +1,25 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
- import { assertPermission, requireUserId } from "../../auth/permissions.js";
2
+ import { AUTHENTICATION_REQUIRED_MESSAGE, assertPermission, isUnauthenticatedActor, requireUserId, } from "../../auth/permissions.js";
3
3
  import { getProfileRoute, listAddressesRoute, listCustomerOrdersRoute, getCustomerOrderRoute, getOrderTrackingRoute, getOrderDownloadsRoute, listCoursesRoute, deleteAddressRoute, reorderRoute, updateProfileRoute, createAddressRoute, } from "./schemas/customer-portal.js";
4
4
  import { isUUID, mapErrorToStatus, markRoutePermissionGuard } from "./utils.js";
5
5
  export function createCustomerPortalRoutes(kernel) {
6
6
  const router = new OpenAPIHono();
7
+ // Two refusals, because two different callers are being turned away and one
8
+ // answer cannot serve both. The second clause is also what makes the
9
+ // `AuthenticatedActor` cast below true: every route under this guard reads
10
+ // `actor.userId` as a string.
7
11
  router.use("*", markRoutePermissionGuard(async (c, next) => {
8
12
  const actor = c.get("actor");
13
+ if (isUnauthenticatedActor(actor)) {
14
+ return c.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
15
+ }
9
16
  if (!actor?.userId) {
10
- return c.json({ error: { code: "FORBIDDEN", message: "Authentication required." } }, 401);
17
+ return c.json({
18
+ error: {
19
+ code: "FORBIDDEN",
20
+ message: "The customer portal requires a signed-in user, not an API key.",
21
+ },
22
+ }, 403);
11
23
  }
12
24
  await next();
13
25
  }));
@@ -35,7 +35,16 @@ export interface RouteHandlerContext {
35
35
  query: Record<string, unknown>;
36
36
  /** Path parameters, auto-extracted from {id} segments. */
37
37
  params: Record<string, string>;
38
- /** Authenticated actor. Guaranteed non-null if .auth() or .permission() was called. */
38
+ /**
39
+ * Authenticated actor. Guaranteed non-null if .auth() or .permission() was called.
40
+ *
41
+ * Structural rather than `Actor` ON PURPOSE. This is the published plugin
42
+ * API: plugins outside this repository cast it to their own shapes, and
43
+ * three call sites in `plugin-layaway` alone read it as
44
+ * `{ userId: string } & Record<string, unknown>` — a cast TypeScript refuses
45
+ * against a closed `Actor`. Narrowing it is a breaking change to a published
46
+ * contract, not a tidy-up, and it belongs to a card that migrates the callers.
47
+ */
39
48
  actor: {
40
49
  userId: string | null;
41
50
  role: string;
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/interfaces/rest/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/interfaces/rest/router.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,7 @@ import { ErrorSchema } from "./schemas/shared.js";
30
30
  import { mapErrorToResponse, mapErrorToStatus, markRoutePermissionGuard } from "./utils.js";
31
31
  import { createScopedDb } from "../../kernel/database/scoped-db.js";
32
32
  import { resolveOrgIdForCommerce } from "../../auth/org.js";
33
- import { hasPermission } from "../../auth/permissions.js";
33
+ import { AUTHENTICATION_REQUIRED_MESSAGE, hasPermission, isUnauthenticatedActor, } from "../../auth/permissions.js";
34
34
  // ─── Shared OpenAPI Error Responses ──────────────────────────────────────────
35
35
  const errorResponses = {
36
36
  400: { content: { "application/json": { schema: ErrorSchema } }, description: "Bad request." },
@@ -164,13 +164,29 @@ class RouteChain {
164
164
  try {
165
165
  // ─── Auth + Permission Check ─────────────────────────────────
166
166
  // .permission() implies .auth() — both are enforced here.
167
- // Order: auth first (401), then permission (403).
167
+ //
168
+ // A GRANTED PERMISSION WINS BEFORE THE CLASS IS DECIDED, and the order
169
+ // matters: an actor can hold a permission without holding an identity.
170
+ // A storefront widget posting search signals carries only a publishable
171
+ // key, so it rides the anonymous actor the store resolver builds and is
172
+ // authorized by that actor's permissions. Asking "is this caller
173
+ // anonymous?" first refuses it 401 before anyone looks at what it may
174
+ // do — which broke a working flow. The class question only arises on a
175
+ // REFUSAL, which is also the order `requirePerm` uses.
168
176
  const actor = ctx.get("actor");
169
- if ((requireAuth || requiredPermission) && !actor) {
170
- return ctx.json({ error: { code: "UNAUTHORIZED", message: "Authentication required." } }, 401);
177
+ if (requiredPermission && hasPermission(actor, requiredPermission)) {
178
+ // Authorized. Nothing below applies.
171
179
  }
172
- if (requiredPermission) {
173
- if (!hasPermission(actor, requiredPermission)) {
180
+ else {
181
+ // `RouteHandlerContext["actor"]` is deliberately structural — see its
182
+ // declaration — but the middleware only ever sets a real `Actor`. Read
183
+ // the two identity fields through that type here rather than narrowing
184
+ // the published one, which breaks every plugin that casts it.
185
+ const identity = actor;
186
+ if ((requireAuth || requiredPermission) && isUnauthenticatedActor(identity)) {
187
+ return ctx.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
188
+ }
189
+ if (requiredPermission) {
174
190
  return ctx.json({
175
191
  error: { code: "FORBIDDEN", message: `Permission '${requiredPermission}' is required.` },
176
192
  }, 403);
@@ -4,6 +4,7 @@ export declare const ROUTE_PERMISSION_GUARD: unique symbol;
4
4
  export declare function markRoutePermissionGuard<T>(handler: T, methods?: readonly string[]): T;
5
5
  export declare function markPublicRoute<T>(handler: T, methods?: readonly string[]): T;
6
6
  type PermissionContext = {
7
+ get(key: "actor"): Pick<Actor, "type" | "userId" | "permissions"> | null;
7
8
  get(key: string): unknown;
8
9
  json(data: unknown, status: number): unknown;
9
10
  req: {
@@ -43,14 +44,8 @@ export { mapErrorToStatus };
43
44
  * Returns 401 if no actor, 403 if permission denied.
44
45
  * Usage: router.post("/", requirePerm("webhooks:manage"), handler);
45
46
  */
46
- export declare function requirePerm(permission: string): (c: {
47
- get(key: string): unknown;
48
- json(data: unknown, status: number): unknown;
49
- }, next: () => Promise<void>) => Promise<unknown>;
50
- export declare function requireAnyPerm(permissions: readonly string[]): (c: {
51
- get(key: string): unknown;
52
- json(data: unknown, status: number): unknown;
53
- }, next: () => Promise<void>) => Promise<unknown>;
47
+ export declare function requirePerm(permission: string): (c: PermissionContext, next: () => Promise<void>) => Promise<unknown>;
48
+ export declare function requireAnyPerm(permissions: readonly string[]): (c: PermissionContext, next: () => Promise<void>) => Promise<unknown>;
54
49
  export declare function requireMethodPerm(methods: readonly string[], permission: string): (c: PermissionContext, next: () => Promise<void>) => Promise<unknown>;
55
50
  export declare function isRoutePermissionGuard(handler: unknown, method?: string): boolean;
56
51
  export declare function parseSort(value?: string): {
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/interfaces/rest/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,eAAO,MAAM,sBAAsB,eAAyC,CAAC;AAM7E,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,CAKtF;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,CAE7E;AAED,KAAK,iBAAiB,GAAG;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7C,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,SAAS,EAAE;QACT,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;CACH,CAAC;AAIF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAOA;AAED,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAQxD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAO/F;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,OACf;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC,sBAmBpI;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,OAC9B;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC,sBAkBpI;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,OAEjD,iBAAiB,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC,sBAQ1E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAIjF;AAED,wBAAgB,SAAS,CACvB,KAAK,CAAC,EAAE,MAAM,GAEZ;IACF,KAAK,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;IAC1C,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B,GACG,SAAS,CASZ;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/interfaces/rest/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAMjD,eAAO,MAAM,sBAAsB,eAAyC,CAAC;AAM7E,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,CAKtF;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,CAE7E;AAED,KAAK,iBAAiB,GAAG;IACvB,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC;IACzE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7C,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,SAAS,EAAE;QACT,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;CACH,CAAC;AAIF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAOA;AAED,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAQxD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAO/F;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,OACf,iBAAiB,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC,sBAmB1E;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,OAC9B,iBAAiB,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC,sBAkB1E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,OAEjD,iBAAiB,QAAQ,MAAM,OAAO,CAAC,IAAI,CAAC,sBAQ1E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAIjF;AAED,wBAAgB,SAAS,CACvB,KAAK,CAAC,EAAE,MAAM,GAEZ;IACF,KAAK,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;IAC1C,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B,GACG,SAAS,CASZ;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7C"}
@@ -1,5 +1,6 @@
1
1
  import { mapErrorToStatus } from "../../kernel/error-mapper.js";
2
2
  import { toCommerceError } from "../../kernel/errors.js";
3
+ import { AUTHENTICATION_REQUIRED_MESSAGE, isUnauthenticatedActor, } from "../../auth/permissions.js";
3
4
  export const ROUTE_PERMISSION_GUARD = Symbol("porulle.routePermissionGuard");
4
5
  export function markRoutePermissionGuard(handler, methods) {
5
6
  if (typeof handler === "function") {
@@ -48,10 +49,7 @@ export { mapErrorToStatus };
48
49
  export function requirePerm(permission) {
49
50
  const middleware = async (c, next) => {
50
51
  const actor = c.get("actor");
51
- if (!actor) {
52
- return c.json({ error: { code: "UNAUTHORIZED", message: "Authentication required." } }, 401);
53
- }
54
- const perms = actor.permissions ?? [];
52
+ const perms = actor?.permissions ?? [];
55
53
  if (perms.includes(permission) || perms.includes("*:*")) {
56
54
  await next();
57
55
  return;
@@ -62,6 +60,9 @@ export function requirePerm(permission) {
62
60
  await next();
63
61
  return;
64
62
  }
63
+ if (isUnauthenticatedActor(actor)) {
64
+ return c.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
65
+ }
65
66
  return c.json({ error: { code: "FORBIDDEN", message: `Permission '${permission}' is required.` } }, 403);
66
67
  };
67
68
  return markRoutePermissionGuard(middleware);
@@ -73,13 +74,13 @@ export function requireAnyPerm(permissions) {
73
74
  const allowed = permissions.some((permission) => granted.includes(permission) ||
74
75
  granted.includes("*:*") ||
75
76
  granted.includes(`${permission.split(":")[0]}:*`));
76
- if (!actor) {
77
- return c.json({ error: { code: "UNAUTHORIZED", message: "Authentication required." } }, 401);
78
- }
79
77
  if (allowed) {
80
78
  await next();
81
79
  return;
82
80
  }
81
+ if (isUnauthenticatedActor(actor)) {
82
+ return c.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
83
+ }
83
84
  return c.json({ error: { code: "FORBIDDEN", message: `One of these permissions is required: ${permissions.join(", ")}.` } }, 403);
84
85
  };
85
86
  return markRoutePermissionGuard(middleware);
@@ -1 +1 @@
1
- {"version":3,"file":"error-mapper.d.ts","sourceRoot":"","sources":["../../src/kernel/error-mapper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAgBnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAGrE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACnD,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAaD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,OAAO,EACf,MAAM,CAAC,EAAE,MAAM,GACd,YAAY,CA8Ed"}
1
+ {"version":3,"file":"error-mapper.d.ts","sourceRoot":"","sources":["../../src/kernel/error-mapper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAiBnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAGrE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACnD,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAaD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,OAAO,EACf,MAAM,CAAC,EAAE,MAAM,GACd,YAAY,CA8Ed"}
@@ -4,6 +4,7 @@ const statusByCode = {
4
4
  NOT_FOUND: 404,
5
5
  VALIDATION_FAILED: 422,
6
6
  FORBIDDEN: 403,
7
+ UNAUTHORIZED: 401,
7
8
  REAUTH_REQUIRED: 401,
8
9
  CSRF_ORIGIN_REJECTED: 403,
9
10
  CONFLICT: 409,
@@ -47,6 +47,11 @@ export declare class CommerceForbiddenError extends Error implements CommerceErr
47
47
  code: "FORBIDDEN";
48
48
  constructor(message: string, details?: unknown | undefined);
49
49
  }
50
+ export declare class CommerceUnauthorizedError extends Error implements CommerceError {
51
+ details?: unknown | undefined;
52
+ code: "UNAUTHORIZED";
53
+ constructor(message: string, details?: unknown | undefined);
54
+ }
50
55
  export declare class CommerceCsrfError extends Error implements CommerceError {
51
56
  details?: unknown | undefined;
52
57
  code: "CSRF_ORIGIN_REJECTED";
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/kernel/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,aAAa;IAIhE,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,OAAO,CAAC,EAAE,OAAO;IAJ1B,IAAI,EAAG,mBAAmB,CAAU;gBAElC,OAAO,EAAE,MAAM,EACR,WAAW,CAAC,EAAE,UAAU,EAAE,YAAA,EAC1B,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;mEACmE;AACnE,eAAO,MAAM,kCAAkC,+CACD,CAAC;AAE/C;;;qBAGqB;AACrB,qBAAa,oCAAqC,SAAQ,KAAM,YAAW,aAAa;IAI7E,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,4BAA4B,CAAU;gBAE3C,OAAO,GAAE,MAA2C,EAC7C,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;;;;;;GAMG;AACH,qBAAa,2BAA4B,SAAQ,KAAM,YAAW,aAAa;IAIpE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,iBAAiB,CAAU;gBAEhC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,KAAM,YAAW,aAAa;IAI/D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,iBAAkB,SAAQ,KAAM,YAAW,aAAa;IAI1D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,sBAAsB,CAAU;gBAErC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,UAAU,CAAU;gBAEzB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,8BAA+B,SAAQ,KAAM,YAAW,aAAa;IAIvE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,oBAAoB,CAAU;gBAEnC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,kBAAmB,SAAQ,KAAM,YAAW,aAAa;IAI3D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,uBAAuB,CAAU;gBAEtC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAGtE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAgB7D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/kernel/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,aAAa;IAIhE,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,OAAO,CAAC,EAAE,OAAO;IAJ1B,IAAI,EAAG,mBAAmB,CAAU;gBAElC,OAAO,EAAE,MAAM,EACR,WAAW,CAAC,EAAE,UAAU,EAAE,YAAA,EAC1B,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;mEACmE;AACnE,eAAO,MAAM,kCAAkC,+CACD,CAAC;AAE/C;;;qBAGqB;AACrB,qBAAa,oCAAqC,SAAQ,KAAM,YAAW,aAAa;IAI7E,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,4BAA4B,CAAU;gBAE3C,OAAO,GAAE,MAA2C,EAC7C,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;;;;;;GAMG;AACH,qBAAa,2BAA4B,SAAQ,KAAM,YAAW,aAAa;IAIpE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,iBAAiB,CAAU;gBAEhC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,sBAAuB,SAAQ,KAAM,YAAW,aAAa;IAI/D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,WAAW,CAAU;gBAE1B,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,yBAA0B,SAAQ,KAAM,YAAW,aAAa;IAEvC,OAAO,CAAC,EAAE,OAAO;IADrD,IAAI,EAAG,cAAc,CAAU;gBACnB,OAAO,EAAE,MAAM,EAAS,OAAO,CAAC,EAAE,OAAO,YAAA;CAItD;AAED,qBAAa,iBAAkB,SAAQ,KAAM,YAAW,aAAa;IAI1D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,sBAAsB,CAAU;gBAErC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,qBAAsB,SAAQ,KAAM,YAAW,aAAa;IAI9D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,UAAU,CAAU;gBAEzB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,8BAA+B,SAAQ,KAAM,YAAW,aAAa;IAIvE,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,oBAAoB,CAAU;gBAEnC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,kBAAmB,SAAQ,KAAM,YAAW,aAAa;IAI3D,OAAO,CAAC,EAAE,OAAO;IAH1B,IAAI,EAAG,uBAAuB,CAAU;gBAEtC,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAGtE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAgB7D"}
@@ -59,6 +59,15 @@ export class CommerceForbiddenError extends Error {
59
59
  this.name = "CommerceForbiddenError";
60
60
  }
61
61
  }
62
+ export class CommerceUnauthorizedError extends Error {
63
+ details;
64
+ code = "UNAUTHORIZED";
65
+ constructor(message, details) {
66
+ super(message);
67
+ this.details = details;
68
+ this.name = "CommerceUnauthorizedError";
69
+ }
70
+ }
62
71
  export class CommerceCsrfError extends Error {
63
72
  details;
64
73
  code = "CSRF_ORIGIN_REJECTED";
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/cart/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/cart/service.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { resolveOrgIdForCommerce } from "../../auth/org.js";
2
- import { assertPermission } from "../../auth/permissions.js";
3
- import { CommerceForbiddenError, CommerceNotFoundError, CommerceValidationError, toCommerceError, } from "../../kernel/errors.js";
2
+ import { AUTHENTICATION_REQUIRED_MESSAGE, assertPermission, isUnauthenticatedActor, } from "../../auth/permissions.js";
3
+ import { CommerceForbiddenError, CommerceNotFoundError, CommerceUnauthorizedError, CommerceValidationError, toCommerceError, } from "../../kernel/errors.js";
4
4
  import { runAfterHooks, runBeforeHooks } from "../../kernel/hooks/executor.js";
5
5
  import { createHookContext } from "../../kernel/hooks/create-context.js";
6
6
  import { Err, Ok } from "../../kernel/result.js";
@@ -553,8 +553,8 @@ export class CartService {
553
553
  if (actor && actor.permissions.includes("*:*"))
554
554
  return;
555
555
  if (cart.customerId != null) {
556
- if (!actor) {
557
- throw new CommerceForbiddenError("Authentication required to read customer cart.");
556
+ if (isUnauthenticatedActor(actor)) {
557
+ throw new CommerceUnauthorizedError(AUTHENTICATION_REQUIRED_MESSAGE);
558
558
  }
559
559
  const profileId = await this.resolveActorCustomerId(actor, ctx);
560
560
  if (profileId !== cart.customerId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porulle/core",
3
- "version": "0.23.0",
3
+ "version": "0.24.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -62,8 +62,8 @@
62
62
  "eslint": "^9.39.1",
63
63
  "typescript": "5.9.2",
64
64
  "vitest": "^3.2.4",
65
- "@porulle/eslint-config": "0.1.0",
66
- "@porulle/typescript-config": "0.1.0"
65
+ "@porulle/typescript-config": "0.1.0",
66
+ "@porulle/eslint-config": "0.1.0"
67
67
  },
68
68
  "publishConfig": {
69
69
  "access": "public"
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Routes that read no actor, so `authMiddleware` need not resolve one.
3
+ *
4
+ * THE DEFAULT IS TO RESOLVE. A route absent from this list keeps its actor,
5
+ * because the failure mode of the opposite default is silent: a route that
6
+ * stops receiving an actor does not throw, it 401s, or takes an anonymous
7
+ * branch and answers.
8
+ *
9
+ * Matching is EXACT on method and path — no patterns, no prefixes. A pattern is
10
+ * how one entry silently widens to cover a route that does need an identity,
11
+ * and this list is small enough that the cost of exactness is a line per route.
12
+ * A route with a path parameter therefore cannot be listed at all, which is the
13
+ * intended limit rather than an oversight.
14
+ *
15
+ * Entries are the routes whose handlers were read and shown to consult neither
16
+ * `c.get("actor")` nor anything derived from it. `/api/carts` and the rest of
17
+ * `PUBLIC_ROUTES` in `interfaces/rest/route-coverage.ts` are NOT here: they are
18
+ * public in the sense of needing no permission, and they still need the
19
+ * organization the anonymous actor carries. Public and identity-free are
20
+ * different properties and this list is the second one.
21
+ */
22
+ export type IdentityFreeRoute = {
23
+ method: string;
24
+ path: string;
25
+ justification: string;
26
+ };
27
+
28
+ export const IDENTITY_FREE_ROUTES: readonly IdentityFreeRoute[] = [
29
+ {
30
+ method: "GET",
31
+ path: "/api/health",
32
+ justification:
33
+ "A liveness probe for load balancers; the handler issues its own SELECT 1 and reads no actor.",
34
+ },
35
+ {
36
+ method: "GET",
37
+ path: "/api/doc",
38
+ justification:
39
+ "The generated OpenAPI document is built from config and the route table, never from the caller.",
40
+ },
41
+ {
42
+ method: "GET",
43
+ path: "/api/doc-ext",
44
+ justification:
45
+ "The enriched OpenAPI document, same handler shape as /api/doc.",
46
+ },
47
+ ];
48
+
49
+ const DEFAULT_KEYS = new Set(
50
+ IDENTITY_FREE_ROUTES.map((route) => `${route.method} ${route.path}`),
51
+ );
52
+
53
+ function normalize(entry: string): string {
54
+ const [method = "", ...rest] = entry.trim().split(/\s+/);
55
+ return `${method.toUpperCase()} ${rest.join(" ")}`;
56
+ }
57
+
58
+ /**
59
+ * An app declares its own with `auth.identityFreeRoutes: ["POST /api/payments/notify"]`.
60
+ *
61
+ * Additive only: a config entry can never remove one of the defaults above, so
62
+ * the narrowest thing an app can do to this set is widen it, and the widening
63
+ * is visible in its own configuration file.
64
+ *
65
+ * The routes that want this are app-local by nature — a signed payment notify,
66
+ * a tracked click-out — and they have no session, taking their organization
67
+ * from the payload they verified rather than from a resolver, which is what
68
+ * core's own `POST /api/payments/webhook` already does.
69
+ *
70
+ * WHAT AN ENTRY COSTS: `authMiddleware` is followed by the wrapper that opens
71
+ * the plugin database scope FROM THE RESOLVED ACTOR. A route listed here gets
72
+ * no actor, so it gets no scope, and every plugin read and write on that
73
+ * request runs with no organization predicate while the handler still answers
74
+ * normally. Such a route must open its own scope.
75
+ */
76
+ export function isIdentityFreeRoute(
77
+ method: string,
78
+ path: string,
79
+ config?: { auth?: { identityFreeRoutes?: readonly string[] } },
80
+ ): boolean {
81
+ const key = `${method.toUpperCase()} ${path}`;
82
+ if (DEFAULT_KEYS.has(key)) return true;
83
+ const declared = config?.auth?.identityFreeRoutes;
84
+ if (!declared) return false;
85
+ return declared.some((entry) => normalize(entry) === key);
86
+ }
@@ -6,6 +6,7 @@ import { getCustomerPermissions, resolveActor } from "./actor.js";
6
6
  import { DEFAULT_ORG_ID } from "./org.js";
7
7
  import { isCredentialRejection } from "./auth-failure.js";
8
8
  import { isStrictOrgResolution } from "./strict-org-resolution.js";
9
+ import { isIdentityFreeRoute } from "./identity-free-routes.js";
9
10
 
10
11
  function emptyToNull(value: string | null | undefined): string | null {
11
12
  return value == null || value === "" ? null : value;
@@ -24,6 +25,12 @@ export function authMiddleware(
24
25
  config: CommerceConfig,
25
26
  ): MiddlewareHandler {
26
27
  return async (c, next) => {
28
+ if (isIdentityFreeRoute(c.req.method, c.req.path, config)) {
29
+ c.set("actor", null);
30
+ await next();
31
+ return;
32
+ }
33
+
27
34
  // Resolve the default org from config, falling back to deprecated constant
28
35
  const defaultOrgId = config.auth?.defaultOrganizationId ?? DEFAULT_ORG_ID;
29
36
 
@@ -1,6 +1,22 @@
1
- import { CommerceForbiddenError } from "../kernel/errors.js";
1
+ import {
2
+ CommerceForbiddenError,
3
+ CommerceUnauthorizedError,
4
+ } from "../kernel/errors.js";
2
5
  import type { Actor } from "./types.js";
3
6
 
7
+ export const AUTHENTICATION_REQUIRED_MESSAGE = "Authentication required.";
8
+
9
+ /**
10
+ * True when the request carried no credential at all. An API key actor
11
+ * (`type: "api_key"`) DID present one, whatever its referenceId, so it keeps
12
+ * 403 — telling it to authenticate would be a lie it cannot act on.
13
+ */
14
+ export function isUnauthenticatedActor(
15
+ actor: Pick<Actor, "type" | "userId"> | null,
16
+ ): boolean {
17
+ return actor === null || (actor.type === "user" && actor.userId === null);
18
+ }
19
+
4
20
  export function hasPermission(actor: Actor | null, required: string): boolean {
5
21
  if (!actor) return false;
6
22
  if (actor.permissions.includes("*:*")) return true;
@@ -12,13 +28,25 @@ export function hasPermission(actor: Actor | null, required: string): boolean {
12
28
 
13
29
  export function assertPermission(actor: Actor | null, required: string): void {
14
30
  if (hasPermission(actor, required)) return;
15
- if (!actor) throw new CommerceForbiddenError("Authentication required.");
31
+ // `actor === null` is redundant at runtime — the predicate already covers it —
32
+ // and load-bearing at compile time: a boolean predicate narrows nothing, and
33
+ // the message below reads `actor.role`. Written this way rather than as a cast
34
+ // so it cannot start lying if the predicate changes.
35
+ if (actor === null || isUnauthenticatedActor(actor)) {
36
+ throw new CommerceUnauthorizedError(AUTHENTICATION_REQUIRED_MESSAGE);
37
+ }
16
38
 
17
39
  throw new CommerceForbiddenError(
18
40
  `Permission "${required}" is required. Your role "${actor.role}" does not include this permission.`,
19
41
  );
20
42
  }
21
43
 
44
+ // NOT given the unauthenticated predicate, and the omission is deliberate.
45
+ // `auth-permissions.test.ts` pins this refusal as 403 for a STAFF actor with a
46
+ // null userId — a shape `resolveActor` cannot produce — so whether that means
47
+ // "anonymous" or "a synthetic actor whose identity is broken" has to be decided
48
+ // before the status can be. It is carded; no route reaches here with an
49
+ // anonymous actor today.
22
50
  export function assertOwnership(actor: Actor | null, resourceOwnerId: string | null): void {
23
51
  if (!actor) {
24
52
  throw new CommerceForbiddenError("Authentication required.");
@@ -199,6 +199,21 @@ export interface AuthConfig {
199
199
  * ```
200
200
  */
201
201
  storeResolver?: (request: Request) => string | null | Promise<string | null>;
202
+ /**
203
+ * Routes this app serves that read no actor, as `"<METHOD> <exact path>"` —
204
+ * e.g. `["POST /api/payments/notify", "GET /api/out/:token"]`. Matching is
205
+ * exact; there are no globs, because a glob is how one entry silently widens
206
+ * to cover a route that does need an identity.
207
+ *
208
+ * Additive to core's own list, and it can never remove one. Core's defaults
209
+ * are in `auth/identity-free-routes.ts` with the evidence for each.
210
+ *
211
+ * The route then resolves NO actor, which also means it gets no plugin
212
+ * database scope — that scope is derived from the actor. Such a route must
213
+ * open its own, the way a signed webhook builds its actor from the payload it
214
+ * verified. Listing a route that reads `c.get("actor")` will not fail loudly.
215
+ */
216
+ identityFreeRoutes?: readonly string[];
202
217
  /**
203
218
  * Governs two layers, and its default differs between them.
204
219
  *
package/src/index.ts CHANGED
@@ -42,7 +42,15 @@ export { createSystemActor } from "./auth/system-actor.js";
42
42
  export { OrganizationService } from "./modules/organization/service.js";
43
43
  export { createScopedDb } from "./kernel/database/scoped-db.js";
44
44
  export type { ScopedOrganizationId } from "./kernel/database/scoped-db.js";
45
- export { assertOwnership, assertPermission, requireUserId } from "./auth/permissions.js";
45
+ export { IDENTITY_FREE_ROUTES, isIdentityFreeRoute } from "./auth/identity-free-routes.js";
46
+ export type { IdentityFreeRoute } from "./auth/identity-free-routes.js";
47
+ export {
48
+ AUTHENTICATION_REQUIRED_MESSAGE,
49
+ assertOwnership,
50
+ assertPermission,
51
+ isUnauthenticatedActor,
52
+ requireUserId,
53
+ } from "./auth/permissions.js";
46
54
  export type { AccessResult, AccessContext, AccessFn, WhereClause } from "./auth/access.js";
47
55
  export {
48
56
  accessOR,
@@ -127,6 +135,7 @@ export {
127
135
  CommerceNotFoundError,
128
136
  CommerceValidationError,
129
137
  CommerceForbiddenError,
138
+ CommerceUnauthorizedError,
130
139
  CommerceReauthRequiredError,
131
140
  CommerceConflictError,
132
141
  CommerceInvalidTransitionError,
@@ -1,6 +1,11 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
2
  import type { Kernel } from "../../runtime/kernel.js";
3
- import { assertPermission, requireUserId } from "../../auth/permissions.js";
3
+ import {
4
+ AUTHENTICATION_REQUIRED_MESSAGE,
5
+ assertPermission,
6
+ isUnauthenticatedActor,
7
+ requireUserId,
8
+ } from "../../auth/permissions.js";
4
9
  import type { Actor } from "../../auth/types.js";
5
10
  import type { AppEnv } from "./utils.js";
6
11
  import {
@@ -23,14 +28,29 @@ type AuthenticatedActor = Actor & { userId: string };
23
28
  export function createCustomerPortalRoutes(kernel: Kernel) {
24
29
  const router = new OpenAPIHono<AppEnv>();
25
30
 
31
+ // Two refusals, because two different callers are being turned away and one
32
+ // answer cannot serve both. The second clause is also what makes the
33
+ // `AuthenticatedActor` cast below true: every route under this guard reads
34
+ // `actor.userId` as a string.
26
35
  router.use("*", markRoutePermissionGuard(async (c, next) => {
27
36
  const actor = c.get("actor") as Actor | null;
28
- if (!actor?.userId) {
37
+ if (isUnauthenticatedActor(actor)) {
29
38
  return c.json(
30
- { error: { code: "FORBIDDEN", message: "Authentication required." } },
39
+ { error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } },
31
40
  401,
32
41
  );
33
42
  }
43
+ if (!actor?.userId) {
44
+ return c.json(
45
+ {
46
+ error: {
47
+ code: "FORBIDDEN",
48
+ message: "The customer portal requires a signed-in user, not an API key.",
49
+ },
50
+ },
51
+ 403,
52
+ );
53
+ }
34
54
  await next();
35
55
  }));
36
56
 
@@ -33,7 +33,11 @@ import type { CommerceConfig } from "../../config/types.js";
33
33
  import type { PluginRouteRegistration } from "../../kernel/plugin/manifest.js";
34
34
  import { createScopedDb } from "../../kernel/database/scoped-db.js";
35
35
  import { resolveOrgIdForCommerce } from "../../auth/org.js";
36
- import { hasPermission } from "../../auth/permissions.js";
36
+ import {
37
+ AUTHENTICATION_REQUIRED_MESSAGE,
38
+ hasPermission,
39
+ isUnauthenticatedActor,
40
+ } from "../../auth/permissions.js";
37
41
  import type { Actor } from "../../auth/types.js";
38
42
 
39
43
  // ─── Shared OpenAPI Error Responses ──────────────────────────────────────────
@@ -63,7 +67,16 @@ export interface RouteHandlerContext {
63
67
  query: Record<string, unknown>;
64
68
  /** Path parameters, auto-extracted from {id} segments. */
65
69
  params: Record<string, string>;
66
- /** Authenticated actor. Guaranteed non-null if .auth() or .permission() was called. */
70
+ /**
71
+ * Authenticated actor. Guaranteed non-null if .auth() or .permission() was called.
72
+ *
73
+ * Structural rather than `Actor` ON PURPOSE. This is the published plugin
74
+ * API: plugins outside this repository cast it to their own shapes, and
75
+ * three call sites in `plugin-layaway` alone read it as
76
+ * `{ userId: string } & Record<string, unknown>` — a cast TypeScript refuses
77
+ * against a closed `Actor`. Narrowing it is a breaking change to a published
78
+ * contract, not a tidy-up, and it belongs to a card that migrates the callers.
79
+ */
67
80
  actor: { userId: string | null; role: string; permissions: string[]; vendorId?: string | null; [key: string]: unknown } | null;
68
81
  /** Resolved organization ID. Derived from actor.organizationId or the deployment config. */
69
82
  orgId: string;
@@ -215,15 +228,30 @@ class RouteChain {
215
228
  try {
216
229
  // ─── Auth + Permission Check ─────────────────────────────────
217
230
  // .permission() implies .auth() — both are enforced here.
218
- // Order: auth first (401), then permission (403).
231
+ //
232
+ // A GRANTED PERMISSION WINS BEFORE THE CLASS IS DECIDED, and the order
233
+ // matters: an actor can hold a permission without holding an identity.
234
+ // A storefront widget posting search signals carries only a publishable
235
+ // key, so it rides the anonymous actor the store resolver builds and is
236
+ // authorized by that actor's permissions. Asking "is this caller
237
+ // anonymous?" first refuses it 401 before anyone looks at what it may
238
+ // do — which broke a working flow. The class question only arises on a
239
+ // REFUSAL, which is also the order `requirePerm` uses.
219
240
  const actor = ctx.get("actor") as RouteHandlerContext["actor"];
220
241
 
221
- if ((requireAuth || requiredPermission) && !actor) {
222
- return ctx.json({ error: { code: "UNAUTHORIZED", message: "Authentication required." } }, 401);
223
- }
242
+ if (requiredPermission && hasPermission(actor as Actor | null, requiredPermission)) {
243
+ // Authorized. Nothing below applies.
244
+ } else {
245
+ // `RouteHandlerContext["actor"]` is deliberately structural — see its
246
+ // declaration — but the middleware only ever sets a real `Actor`. Read
247
+ // the two identity fields through that type here rather than narrowing
248
+ // the published one, which breaks every plugin that casts it.
249
+ const identity = actor as Pick<Actor, "type" | "userId"> | null;
250
+ if ((requireAuth || requiredPermission) && isUnauthenticatedActor(identity)) {
251
+ return ctx.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
252
+ }
224
253
 
225
- if (requiredPermission) {
226
- if (!hasPermission(actor as Actor | null, requiredPermission)) {
254
+ if (requiredPermission) {
227
255
  return ctx.json({
228
256
  error: { code: "FORBIDDEN", message: `Permission '${requiredPermission}' is required.` },
229
257
  }, 403);
@@ -2,6 +2,10 @@ import type { CommerceError } from "../../kernel/errors.js";
2
2
  import { mapErrorToStatus } from "../../kernel/error-mapper.js";
3
3
  import { toCommerceError } from "../../kernel/errors.js";
4
4
  import type { Actor } from "../../auth/types.js";
5
+ import {
6
+ AUTHENTICATION_REQUIRED_MESSAGE,
7
+ isUnauthenticatedActor,
8
+ } from "../../auth/permissions.js";
5
9
 
6
10
  export const ROUTE_PERMISSION_GUARD = Symbol("porulle.routePermissionGuard");
7
11
 
@@ -21,6 +25,7 @@ export function markPublicRoute<T>(handler: T, methods?: readonly string[]): T {
21
25
  }
22
26
 
23
27
  type PermissionContext = {
28
+ get(key: "actor"): Pick<Actor, "type" | "userId" | "permissions"> | null;
24
29
  get(key: string): unknown;
25
30
  json(data: unknown, status: number): unknown;
26
31
  req: { method: string };
@@ -84,12 +89,9 @@ export { mapErrorToStatus };
84
89
  * Usage: router.post("/", requirePerm("webhooks:manage"), handler);
85
90
  */
86
91
  export function requirePerm(permission: string) {
87
- const middleware = async (c: { get(key: string): unknown; json(data: unknown, status: number): unknown }, next: () => Promise<void>) => {
88
- const actor = c.get("actor") as { permissions?: string[] } | null;
89
- if (!actor) {
90
- return c.json({ error: { code: "UNAUTHORIZED", message: "Authentication required." } }, 401);
91
- }
92
- const perms = actor.permissions ?? [];
92
+ const middleware = async (c: PermissionContext, next: () => Promise<void>) => {
93
+ const actor = c.get("actor");
94
+ const perms = actor?.permissions ?? [];
93
95
  if (perms.includes(permission) || perms.includes("*:*")) {
94
96
  await next();
95
97
  return;
@@ -100,27 +102,30 @@ export function requirePerm(permission: string) {
100
102
  await next();
101
103
  return;
102
104
  }
105
+ if (isUnauthenticatedActor(actor)) {
106
+ return c.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
107
+ }
103
108
  return c.json({ error: { code: "FORBIDDEN", message: `Permission '${permission}' is required.` } }, 403);
104
109
  };
105
110
  return markRoutePermissionGuard(middleware);
106
111
  }
107
112
 
108
113
  export function requireAnyPerm(permissions: readonly string[]) {
109
- const middleware = async (c: { get(key: string): unknown; json(data: unknown, status: number): unknown }, next: () => Promise<void>) => {
110
- const actor = c.get("actor") as { permissions?: string[] } | null;
114
+ const middleware = async (c: PermissionContext, next: () => Promise<void>) => {
115
+ const actor = c.get("actor");
111
116
  const granted = actor?.permissions ?? [];
112
117
  const allowed = permissions.some((permission) =>
113
118
  granted.includes(permission) ||
114
119
  granted.includes("*:*") ||
115
120
  granted.includes(`${permission.split(":")[0]}:*`),
116
121
  );
117
- if (!actor) {
118
- return c.json({ error: { code: "UNAUTHORIZED", message: "Authentication required." } }, 401);
119
- }
120
122
  if (allowed) {
121
123
  await next();
122
124
  return;
123
125
  }
126
+ if (isUnauthenticatedActor(actor)) {
127
+ return c.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
128
+ }
124
129
  return c.json({ error: { code: "FORBIDDEN", message: `One of these permissions is required: ${permissions.join(", ")}.` } }, 403);
125
130
  };
126
131
  return markRoutePermissionGuard(middleware);
@@ -7,6 +7,7 @@ const statusByCode: Record<string, ContentfulStatusCode> = {
7
7
  NOT_FOUND: 404,
8
8
  VALIDATION_FAILED: 422,
9
9
  FORBIDDEN: 403,
10
+ UNAUTHORIZED: 401,
10
11
  REAUTH_REQUIRED: 401,
11
12
  CSRF_ORIGIN_REJECTED: 403,
12
13
  CONFLICT: 409,
@@ -81,6 +81,14 @@ export class CommerceForbiddenError extends Error implements CommerceError {
81
81
  }
82
82
  }
83
83
 
84
+ export class CommerceUnauthorizedError extends Error implements CommerceError {
85
+ code = "UNAUTHORIZED" as const;
86
+ constructor(message: string, public details?: unknown) {
87
+ super(message);
88
+ this.name = "CommerceUnauthorizedError";
89
+ }
90
+ }
91
+
84
92
  export class CommerceCsrfError extends Error implements CommerceError {
85
93
  code = "CSRF_ORIGIN_REJECTED" as const;
86
94
  constructor(
@@ -1,10 +1,16 @@
1
1
  import { resolveOrgIdForCommerce } from "../../auth/org.js";
2
- import { assertOwnership, assertPermission } from "../../auth/permissions.js";
2
+ import {
3
+ AUTHENTICATION_REQUIRED_MESSAGE,
4
+ assertOwnership,
5
+ assertPermission,
6
+ isUnauthenticatedActor,
7
+ } from "../../auth/permissions.js";
3
8
  import type { Actor } from "../../auth/types.js";
4
9
  import type { CommerceConfig } from "../../config/types.js";
5
10
  import {
6
11
  CommerceForbiddenError,
7
12
  CommerceNotFoundError,
13
+ CommerceUnauthorizedError,
8
14
  CommerceValidationError,
9
15
  toCommerceError,
10
16
  } from "../../kernel/errors.js";
@@ -896,10 +902,8 @@ export class CartService {
896
902
  if (actor && actor.permissions.includes("*:*")) return;
897
903
 
898
904
  if (cart.customerId != null) {
899
- if (!actor) {
900
- throw new CommerceForbiddenError(
901
- "Authentication required to read customer cart.",
902
- );
905
+ if (isUnauthenticatedActor(actor)) {
906
+ throw new CommerceUnauthorizedError(AUTHENTICATION_REQUIRED_MESSAGE);
903
907
  }
904
908
  const profileId = await this.resolveActorCustomerId(actor, ctx);
905
909
  if (profileId !== cart.customerId) {