@porulle/core 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/identity-free-routes.d.ts +51 -0
- package/dist/auth/identity-free-routes.d.ts.map +1 -0
- package/dist/auth/identity-free-routes.js +49 -0
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +6 -0
- package/dist/auth/permissions.d.ts +7 -0
- package/dist/auth/permissions.d.ts.map +1 -1
- package/dist/auth/permissions.js +23 -3
- package/dist/config/types.d.ts +15 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/interfaces/rest/customer-portal.d.ts.map +1 -1
- package/dist/interfaces/rest/customer-portal.js +14 -2
- package/dist/interfaces/rest/router.d.ts +10 -1
- package/dist/interfaces/rest/router.d.ts.map +1 -1
- package/dist/interfaces/rest/router.js +8 -3
- package/dist/interfaces/rest/utils.d.ts +3 -8
- package/dist/interfaces/rest/utils.d.ts.map +1 -1
- package/dist/interfaces/rest/utils.js +8 -7
- package/dist/kernel/error-mapper.d.ts.map +1 -1
- package/dist/kernel/error-mapper.js +1 -0
- package/dist/kernel/errors.d.ts +5 -0
- package/dist/kernel/errors.d.ts.map +1 -1
- package/dist/kernel/errors.js +9 -0
- package/dist/modules/cart/service.d.ts.map +1 -1
- package/dist/modules/cart/service.js +4 -4
- package/package.json +3 -3
- package/src/auth/identity-free-routes.ts +86 -0
- package/src/auth/middleware.ts +7 -0
- package/src/auth/permissions.ts +30 -2
- package/src/config/types.ts +15 -0
- package/src/index.ts +10 -1
- package/src/interfaces/rest/customer-portal.ts +23 -3
- package/src/interfaces/rest/router.ts +22 -4
- package/src/interfaces/rest/utils.ts +16 -11
- package/src/kernel/error-mapper.ts +1 -0
- package/src/kernel/errors.ts +8 -0
- 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;
|
|
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"}
|
package/dist/auth/middleware.js
CHANGED
|
@@ -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":"
|
|
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"}
|
package/dist/auth/permissions.js
CHANGED
|
@@ -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
|
-
|
|
16
|
-
|
|
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.");
|
package/dist/config/types.d.ts
CHANGED
|
@@ -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 {
|
|
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";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EACV,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACpG,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAK1F,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACxG,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,
|
|
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 {
|
|
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;
|
|
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({
|
|
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
|
-
/**
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAe,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAGnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;
|
|
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." },
|
|
@@ -166,8 +166,13 @@ class RouteChain {
|
|
|
166
166
|
// .permission() implies .auth() — both are enforced here.
|
|
167
167
|
// Order: auth first (401), then permission (403).
|
|
168
168
|
const actor = ctx.get("actor");
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
// `RouteHandlerContext["actor"]` is deliberately structural — see its
|
|
170
|
+
// declaration — but the middleware only ever sets a real `Actor`. Read
|
|
171
|
+
// the two identity fields through that type here rather than narrowing
|
|
172
|
+
// the published one, which breaks every plugin that casts it.
|
|
173
|
+
const identity = actor;
|
|
174
|
+
if ((requireAuth || requiredPermission) && isUnauthenticatedActor(identity)) {
|
|
175
|
+
return ctx.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
|
|
171
176
|
}
|
|
172
177
|
if (requiredPermission) {
|
|
173
178
|
if (!hasPermission(actor, requiredPermission)) {
|
|
@@ -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
|
-
|
|
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;
|
|
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
|
-
|
|
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;
|
|
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"}
|
package/dist/kernel/errors.d.ts
CHANGED
|
@@ -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"}
|
package/dist/kernel/errors.js
CHANGED
|
@@ -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":"
|
|
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 (
|
|
557
|
-
throw new
|
|
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.
|
|
3
|
+
"version": "0.24.0",
|
|
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/
|
|
66
|
-
"@porulle/
|
|
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
|
+
}
|
package/src/auth/middleware.ts
CHANGED
|
@@ -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
|
|
package/src/auth/permissions.ts
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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.");
|
package/src/config/types.ts
CHANGED
|
@@ -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 {
|
|
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 {
|
|
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 (
|
|
37
|
+
if (isUnauthenticatedActor(actor)) {
|
|
29
38
|
return c.json(
|
|
30
|
-
{ error: { code: "
|
|
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 {
|
|
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
|
-
/**
|
|
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;
|
|
@@ -218,8 +231,13 @@ class RouteChain {
|
|
|
218
231
|
// Order: auth first (401), then permission (403).
|
|
219
232
|
const actor = ctx.get("actor") as RouteHandlerContext["actor"];
|
|
220
233
|
|
|
221
|
-
|
|
222
|
-
|
|
234
|
+
// `RouteHandlerContext["actor"]` is deliberately structural — see its
|
|
235
|
+
// declaration — but the middleware only ever sets a real `Actor`. Read
|
|
236
|
+
// the two identity fields through that type here rather than narrowing
|
|
237
|
+
// the published one, which breaks every plugin that casts it.
|
|
238
|
+
const identity = actor as Pick<Actor, "type" | "userId"> | null;
|
|
239
|
+
if ((requireAuth || requiredPermission) && isUnauthenticatedActor(identity)) {
|
|
240
|
+
return ctx.json({ error: { code: "UNAUTHORIZED", message: AUTHENTICATION_REQUIRED_MESSAGE } }, 401);
|
|
223
241
|
}
|
|
224
242
|
|
|
225
243
|
if (requiredPermission) {
|
|
@@ -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:
|
|
88
|
-
const actor = c.get("actor")
|
|
89
|
-
|
|
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:
|
|
110
|
-
const actor = c.get("actor")
|
|
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);
|
package/src/kernel/errors.ts
CHANGED
|
@@ -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 {
|
|
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 (
|
|
900
|
-
throw new
|
|
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) {
|