@porulle/core 0.24.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.
|
@@ -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;AA8B/E,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,KAAK,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;;;;;;;;;OASG;IACH,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/H,4FAA4F;IAC5F,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,gCAAgC;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,oCAAoC;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,GAAG,EAAE,OAAO,CAAC;CACd;AAID,cAAM,UAAU;IAUZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,SAAS,CAAC;IAbpB,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAAqB;gBAEtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,uBAAuB,EAAE,EACrC,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,YAAA;IAUjG,8CAA8C;IAC9C,OAAO,CAAC,IAAI,EAAE,MAAM;IAEpB,kDAAkD;IAClD,WAAW,CAAC,IAAI,EAAE,MAAM;IAExB,4DAA4D;IAC5D,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO;IAEvB,sCAAsC;IACtC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO;IAEvB,wDAAwD;IACxD,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO;IAExB;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO;IAExB;;;OAGG;IACH,IAAI;IAEJ;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM;IAMxB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/interfaces/rest/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -164,18 +164,29 @@ class RouteChain {
|
|
|
164
164
|
try {
|
|
165
165
|
// ─── Auth + Permission Check ─────────────────────────────────
|
|
166
166
|
// .permission() implies .auth() — both are enforced here.
|
|
167
|
-
//
|
|
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
|
-
|
|
170
|
-
|
|
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);
|
|
177
|
+
if (requiredPermission && hasPermission(actor, requiredPermission)) {
|
|
178
|
+
// Authorized. Nothing below applies.
|
|
176
179
|
}
|
|
177
|
-
|
|
178
|
-
|
|
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) {
|
|
179
190
|
return ctx.json({
|
|
180
191
|
error: { code: "FORBIDDEN", message: `Permission '${requiredPermission}' is required.` },
|
|
181
192
|
}, 403);
|
package/package.json
CHANGED
|
@@ -228,20 +228,30 @@ class RouteChain {
|
|
|
228
228
|
try {
|
|
229
229
|
// ─── Auth + Permission Check ─────────────────────────────────
|
|
230
230
|
// .permission() implies .auth() — both are enforced here.
|
|
231
|
-
//
|
|
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.
|
|
232
240
|
const actor = ctx.get("actor") as RouteHandlerContext["actor"];
|
|
233
241
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
+
}
|
|
242
253
|
|
|
243
|
-
|
|
244
|
-
if (!hasPermission(actor as Actor | null, requiredPermission)) {
|
|
254
|
+
if (requiredPermission) {
|
|
245
255
|
return ctx.json({
|
|
246
256
|
error: { code: "FORBIDDEN", message: `Permission '${requiredPermission}' is required.` },
|
|
247
257
|
}, 403);
|