@spinajs/rbac-http 2.0.480 → 2.0.482

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 (41) hide show
  1. package/lib/cjs/controllers/GrantsController.d.ts +6 -4
  2. package/lib/cjs/controllers/GrantsController.d.ts.map +1 -1
  3. package/lib/cjs/controllers/GrantsController.js +20 -5
  4. package/lib/cjs/controllers/GrantsController.js.map +1 -1
  5. package/lib/cjs/decorators.d.ts +4 -1
  6. package/lib/cjs/decorators.d.ts.map +1 -1
  7. package/lib/cjs/decorators.js +100 -27
  8. package/lib/cjs/decorators.js.map +1 -1
  9. package/lib/cjs/middlewares.d.ts +1 -0
  10. package/lib/cjs/middlewares.d.ts.map +1 -1
  11. package/lib/cjs/middlewares.js +19 -1
  12. package/lib/cjs/middlewares.js.map +1 -1
  13. package/lib/cjs/policies/AllowGuest.d.ts +4 -1
  14. package/lib/cjs/policies/AllowGuest.d.ts.map +1 -1
  15. package/lib/cjs/policies/AllowGuest.js +4 -1
  16. package/lib/cjs/policies/AllowGuest.js.map +1 -1
  17. package/lib/cjs/policies/RbacPolicy.d.ts.map +1 -1
  18. package/lib/cjs/policies/RbacPolicy.js +20 -4
  19. package/lib/cjs/policies/RbacPolicy.js.map +1 -1
  20. package/lib/mjs/controllers/GrantsController.d.ts +6 -4
  21. package/lib/mjs/controllers/GrantsController.d.ts.map +1 -1
  22. package/lib/mjs/controllers/GrantsController.js +21 -6
  23. package/lib/mjs/controllers/GrantsController.js.map +1 -1
  24. package/lib/mjs/decorators.d.ts +4 -1
  25. package/lib/mjs/decorators.d.ts.map +1 -1
  26. package/lib/mjs/decorators.js +100 -27
  27. package/lib/mjs/decorators.js.map +1 -1
  28. package/lib/mjs/middlewares.d.ts +1 -0
  29. package/lib/mjs/middlewares.d.ts.map +1 -1
  30. package/lib/mjs/middlewares.js +20 -2
  31. package/lib/mjs/middlewares.js.map +1 -1
  32. package/lib/mjs/policies/AllowGuest.d.ts +4 -1
  33. package/lib/mjs/policies/AllowGuest.d.ts.map +1 -1
  34. package/lib/mjs/policies/AllowGuest.js +4 -1
  35. package/lib/mjs/policies/AllowGuest.js.map +1 -1
  36. package/lib/mjs/policies/RbacPolicy.d.ts.map +1 -1
  37. package/lib/mjs/policies/RbacPolicy.js +20 -4
  38. package/lib/mjs/policies/RbacPolicy.js.map +1 -1
  39. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  40. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  41. package/package.json +13 -11
@@ -1,5 +1,5 @@
1
1
  import { BaseController, Ok } from '@spinajs/http';
2
- import { AccessControl } from '@spinajs/rbac';
2
+ import { AccessControl, User as RbacUser } from '@spinajs/rbac';
3
3
  import { IGrantsMap } from '../interfaces.js';
4
4
  /**
5
5
  * RBAC grants management.
@@ -10,11 +10,13 @@ export declare class GrantsController extends BaseController {
10
10
  protected AC: AccessControl;
11
11
  /**
12
12
  * Get RBAC grants
13
- * Returns the full RBAC grants object defining roles and their permissions across resources.
13
+ * Returns the RBAC grants for the requesting user's own role(s) only — not
14
+ * the full cross-role matrix, which would leak the entire access-control
15
+ * policy to any authenticated user.
14
16
  * @security cookieAuth
15
- * @returns {IGrantsMap} RBAC grants map keyed by role name
17
+ * @returns {IGrantsMap} RBAC grants map keyed by the caller's role name(s)
16
18
  * @response 401 Unauthorized — valid session cookie required
17
19
  */
18
- getGrants(): Ok<IGrantsMap>;
20
+ getGrants(user: RbacUser): Ok<IGrantsMap>;
19
21
  }
20
22
  //# sourceMappingURL=GrantsController.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GrantsController.d.ts","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,EAAE,EAAU,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;;GAIG;AACH,qBAEa,gBAAiB,SAAQ,cAAc;IAGhD,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;OAMG;IAEI,SAAS,IAAI,EAAE,CAAC,UAAU,CAAC;CAIrC"}
1
+ {"version":3,"file":"GrantsController.d.ts","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,EAAE,EAAU,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIhE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;;GAIG;AACH,qBAEa,gBAAiB,SAAQ,cAAc;IAGhD,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;;;OAQG;IAEI,SAAS,CAAS,IAAI,EAAE,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC;CAc3D"}
@@ -8,12 +8,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  exports.GrantsController = void 0;
13
16
  const http_1 = require("@spinajs/http");
14
17
  const rbac_1 = require("@spinajs/rbac");
15
18
  const di_1 = require("@spinajs/di");
16
19
  const AuthorizedPolicy_js_1 = require("../policies/AuthorizedPolicy.js");
20
+ const decorators_js_1 = require("../decorators.js");
17
21
  /**
18
22
  * RBAC grants management.
19
23
  * Provides access to the current RBAC access-control grants configuration.
@@ -22,13 +26,23 @@ const AuthorizedPolicy_js_1 = require("../policies/AuthorizedPolicy.js");
22
26
  let GrantsController = class GrantsController extends http_1.BaseController {
23
27
  /**
24
28
  * Get RBAC grants
25
- * Returns the full RBAC grants object defining roles and their permissions across resources.
29
+ * Returns the RBAC grants for the requesting user's own role(s) only — not
30
+ * the full cross-role matrix, which would leak the entire access-control
31
+ * policy to any authenticated user.
26
32
  * @security cookieAuth
27
- * @returns {IGrantsMap} RBAC grants map keyed by role name
33
+ * @returns {IGrantsMap} RBAC grants map keyed by the caller's role name(s)
28
34
  * @response 401 Unauthorized — valid session cookie required
29
35
  */
30
- getGrants() {
31
- return new http_1.Ok(this.AC.getGrants());
36
+ getGrants(user) {
37
+ const allGrants = this.AC.getGrants();
38
+ const roles = user?.Role ?? [];
39
+ const filtered = {};
40
+ for (const role of roles) {
41
+ if (allGrants[role]) {
42
+ filtered[role] = allGrants[role];
43
+ }
44
+ }
45
+ return new http_1.Ok(filtered);
32
46
  }
33
47
  };
34
48
  exports.GrantsController = GrantsController;
@@ -38,8 +52,9 @@ __decorate([
38
52
  ], GrantsController.prototype, "AC", void 0);
39
53
  __decorate([
40
54
  (0, http_1.Get)(),
55
+ __param(0, (0, decorators_js_1.User)()),
41
56
  __metadata("design:type", Function),
42
- __metadata("design:paramtypes", []),
57
+ __metadata("design:paramtypes", [rbac_1.User]),
43
58
  __metadata("design:returntype", http_1.Ok)
44
59
  ], GrantsController.prototype, "getGrants", null);
45
60
  exports.GrantsController = GrantsController = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"GrantsController.js","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,wCAA0E;AAC1E,wCAA8C;AAC9C,oCAAyC;AACzC,yEAAmE;AAGnE;;;;GAIG;AAGI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,qBAAc;IAKhD;;;;;;OAMG;IAEI,SAAS;QACZ,OAAO,IAAI,SAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,CAAC;CAEJ,CAAA;AAjBY,4CAAgB;AAGf;IADT,IAAA,eAAU,EAAC,oBAAa,CAAC;8BACZ,oBAAa;4CAAC;AAUrB;IADN,IAAA,UAAG,GAAE;;;oCACc,SAAE;iDAErB;2BAfQ,gBAAgB;IAF5B,IAAA,eAAQ,EAAC,QAAQ,CAAC;IAClB,IAAA,aAAM,EAAC,sCAAgB,CAAC;GACZ,gBAAgB,CAiB5B"}
1
+ {"version":3,"file":"GrantsController.js","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,wCAA0E;AAC1E,wCAAgE;AAChE,oCAAyC;AACzC,yEAAmE;AACnE,oDAAwC;AAGxC;;;;GAIG;AAGI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,qBAAc;IAKhD;;;;;;;;OAQG;IAEI,SAAS,CAAS,IAAc;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,SAAS,EAAgB,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAE/B,MAAM,QAAQ,GAAe,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,SAAE,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;CAEJ,CAAA;AA7BY,4CAAgB;AAGf;IADT,IAAA,eAAU,EAAC,oBAAa,CAAC;8BACZ,oBAAa;4CAAC;AAYrB;IADN,IAAA,UAAG,GAAE;IACY,WAAA,IAAA,oBAAI,GAAE,CAAA;;qCAAO,WAAQ;oCAAG,SAAE;iDAY3C;2BA3BQ,gBAAgB;IAF5B,IAAA,eAAQ,EAAC,QAAQ,CAAC;IAClB,IAAA,aAAM,EAAC,sCAAgB,CAAC;GACZ,gBAAgB,CA6B5B"}
@@ -10,7 +10,10 @@ export declare function setRbacMetadata(target: any, callback: (meta: IRbacDescr
10
10
  * Assign resource for controller
11
11
  *
12
12
  * @param resource - name of resource
13
- * @param permission - default permission
13
+ * @param permission - default permission. When omitted, the base controller's
14
+ * permission is kept ( `readOwn` if there is nothing to
15
+ * inherit ), so renaming a resource in a subclass does not
16
+ * silently change what it grants.
14
17
  */
15
18
  export declare function Resource(resource: string, permission?: PermissionType[]): any;
16
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkC,MAAM,iBAAiB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C;;;GAGG;AACH,eAAO,MAAM,yBAAyB,eAAiD,CAAC;AAExF,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,QAerF;AAqBD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAE,cAAc,EAAgB,OAKpF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,GAAE,cAAc,EAAgB,OAapE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,0GAalC;AAED;;GAEG;AACH,wBAAgB,IAAI,0GAEnB;AAED;;GAEG;AACH,wBAAgB,WAAW,0GAE1B;AAED,wBAAgB,OAAO,0GAEtB"}
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkC,MAAM,iBAAiB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C;;;GAGG;AACH,eAAO,MAAM,yBAAyB,eAAiD,CAAC;AAuFxF,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,QAMrF;AAYD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,OAevE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,GAAE,cAAc,EAAgB,OAgBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,0GAalC;AAED;;GAEG;AACH,wBAAgB,IAAI,0GAEnB;AAED;;GAEG;AACH,wBAAgB,WAAW,0GAE1B;AAED,wBAAgB,OAAO,0GAEtB"}
@@ -10,36 +10,94 @@ exports.FromSession = FromSession;
10
10
  exports.Session = Session;
11
11
  const http_1 = require("@spinajs/http");
12
12
  const RbacPolicy_js_1 = require("./policies/RbacPolicy.js");
13
+ const di_1 = require("@spinajs/di");
13
14
  /**
14
15
  * Global symbol so external packages (e.g. http-swagger) can read the RBAC
15
16
  * descriptor via Reflect metadata without importing rbac-http.
16
17
  */
17
18
  exports.ACL_CONTROLLER_DESCRIPTOR = Symbol.for('ACL_CONTROLLER_DESCRIPTOR_SYMBOL');
18
- function setRbacMetadata(target, callback) {
19
- let metadata = Reflect.getMetadata(exports.ACL_CONTROLLER_DESCRIPTOR, target.prototype || target);
20
- if (!metadata) {
21
- metadata = {
22
- Resource: '',
23
- Routes: new Map(),
24
- Permission: ['readOwn'],
25
- };
26
- Reflect.defineMetadata(exports.ACL_CONTROLLER_DESCRIPTOR, metadata, target.prototype || target);
19
+ /**
20
+ * Permission a controller gets when neither it nor any ancestor declares one
21
+ * ( eg. a controller using route level `@Permission` only ).
22
+ */
23
+ const DEFAULT_CONTROLLER_PERMISSION = ['readOwn'];
24
+ /**
25
+ * NOTE: `Permission` starts EMPTY here, unlike the documented default, and
26
+ * `rbacDescriptor()` fills the default in afterwards. The collapse in
27
+ * `getInheritedDescriptor` seeds itself with this object and CONCATENATES
28
+ * arrays, so seeding `['readOwn']` would make every subclass inherit
29
+ * `['readOwn', ...parent permission]` - granting more than the parent, which is
30
+ * the one direction a permission list must never drift in.
31
+ */
32
+ function createDefaultRbacDescriptor() {
33
+ return {
34
+ Resource: '',
35
+ Routes: new Map(),
36
+ Permission: [],
37
+ };
38
+ }
39
+ /**
40
+ * The descriptor OWNED by the decorated class, pre-populated with everything it
41
+ * inherits.
42
+ *
43
+ * `Reflect.getMetadata` walks the prototype chain, so a controller subclass used
44
+ * to find - and mutate - its parent's descriptor: an application declaring
45
+ * `@Resource` on a subclass rewrote the ACL resource and permissions of the
46
+ * package controller it extends. `getInheritedDescriptor` stores own metadata
47
+ * per class instead, keyed by identity.
48
+ *
49
+ * Stored on the prototype ( `target.prototype || target` covers both the class
50
+ * and the member decorator forms ) because that is where RbacPolicy and
51
+ * http-swagger reach it from, off a controller INSTANCE.
52
+ */
53
+ function rbacDescriptor(target) {
54
+ const controller = target.prototype || target;
55
+ // True only for the very first decorator that touches THIS class, since
56
+ // getInheritedDescriptor stores own metadata as soon as it is called.
57
+ const isFirstDecorator = !Reflect.getOwnMetadata(exports.ACL_CONTROLLER_DESCRIPTOR, controller);
58
+ // Decided BEFORE the collapse, and on the existence of an ancestor descriptor
59
+ // rather than on the collapsed value: an empty permission list is a
60
+ // declaration ( eg. `@Resource('r', [])` grants nothing ), so a subclass that
61
+ // inherits one must keep it. Standing the default in whenever the list came
62
+ // out empty would hand that subclass readOwn - MORE than its base grants.
63
+ const inherits = hasInheritedDescriptor(controller);
64
+ const metadata = (0, di_1.getInheritedDescriptor)(controller, exports.ACL_CONTROLLER_DESCRIPTOR, createDefaultRbacDescriptor);
65
+ // Nothing to inherit - see createDefaultRbacDescriptor for why the default
66
+ // cannot simply be part of the seed. Only on creation, so that a later
67
+ // decorator cannot refill a list this class deliberately emptied.
68
+ if (isFirstDecorator && !inherits) {
69
+ metadata.Permission = [...DEFAULT_CONTROLLER_PERMISSION];
27
70
  }
71
+ return metadata;
72
+ }
73
+ /**
74
+ * True when something ABOVE `controller` in the prototype chain owns an ACL
75
+ * descriptor - ie. when the collapse has a real ancestor to take values from.
76
+ *
77
+ * Mirrors the walk inside `getInheritedDescriptor`, starting one level up
78
+ * because `controller`'s own descriptor is what the caller is about to create.
79
+ * Keyed by identity, never by class name, and undecorated classes in between
80
+ * are simply passed over since they own no metadata.
81
+ */
82
+ function hasInheritedDescriptor(controller) {
83
+ let current = Object.getPrototypeOf(controller);
84
+ while (current && current !== Object.prototype && current !== Function.prototype) {
85
+ if (Reflect.getOwnMetadata(exports.ACL_CONTROLLER_DESCRIPTOR, current)) {
86
+ return true;
87
+ }
88
+ current = Object.getPrototypeOf(current);
89
+ }
90
+ return false;
91
+ }
92
+ function setRbacMetadata(target, callback) {
93
+ const metadata = rbacDescriptor(target);
28
94
  if (callback) {
29
95
  callback(metadata);
30
96
  }
31
97
  }
32
98
  function descriptor(callback) {
33
99
  return (target, propertyKey, indexOrDescriptor) => {
34
- let metadata = Reflect.getMetadata(exports.ACL_CONTROLLER_DESCRIPTOR, target.prototype || target);
35
- if (!metadata) {
36
- metadata = {
37
- Resource: '',
38
- Routes: new Map(),
39
- Permission: ['readOwn'],
40
- };
41
- Reflect.defineMetadata(exports.ACL_CONTROLLER_DESCRIPTOR, metadata, target.prototype || target);
42
- }
100
+ const metadata = rbacDescriptor(target);
43
101
  if (callback) {
44
102
  callback(metadata, target, propertyKey, indexOrDescriptor);
45
103
  }
@@ -49,12 +107,24 @@ function descriptor(callback) {
49
107
  * Assign resource for controller
50
108
  *
51
109
  * @param resource - name of resource
52
- * @param permission - default permission
110
+ * @param permission - default permission. When omitted, the base controller's
111
+ * permission is kept ( `readOwn` if there is nothing to
112
+ * inherit ), so renaming a resource in a subclass does not
113
+ * silently change what it grants.
53
114
  */
54
- function Resource(resource, permission = ['readOwn']) {
115
+ function Resource(resource, permission) {
55
116
  return descriptor((metadata) => {
56
117
  metadata.Resource = resource;
57
- metadata.Permission = permission;
118
+ // ASSIGNED, never merged, and only when the argument was actually passed.
119
+ // Assigning is what lets an application NARROW a package controller -
120
+ // concatenating would grant the union of both lists, and a longer
121
+ // permission list grants more. Omitting the argument says nothing about
122
+ // permissions, so whatever was collapsed from the base controller stands.
123
+ // Copied because the array belongs to the call site, which is free to keep
124
+ // mutating it.
125
+ if (permission) {
126
+ metadata.Permission = [...permission];
127
+ }
58
128
  });
59
129
  }
60
130
  /**
@@ -66,12 +136,15 @@ function Resource(resource, permission = ['readOwn']) {
66
136
  function Permission(permission = ['readOwn']) {
67
137
  return descriptor((metadata, target, propertyKey) => {
68
138
  if (propertyKey) {
69
- if (!metadata.Routes.has(propertyKey)) {
70
- const route = {
71
- Permission: permission,
72
- };
73
- metadata.Routes.set(propertyKey, route);
74
- }
139
+ // Always set, never guarded by `has()`: routes are inherited per member
140
+ // name now, so a guard would make a subclass's @Permission on an inherited
141
+ // route silently do nothing and leave the package controller's permission
142
+ // in force. Setting a FRESH entry is also what keeps the inherited entries
143
+ // - which the collapse shares by reference with the parent - from being
144
+ // rewritten here.
145
+ metadata.Routes.set(propertyKey, {
146
+ Permission: permission,
147
+ });
75
148
  }
76
149
  (0, http_1.Policy)(RbacPolicy_js_1.RbacPolicy)(target, propertyKey, undefined);
77
150
  });
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import * as express from 'express';
4
4
  import { Request as sRequest, ServerMiddleware } from '@spinajs/http';
5
5
  export declare class RbacMiddleware extends ServerMiddleware {
6
6
  protected CoockieSecret: string;
7
+ protected SessionCookieConfig: any;
7
8
  protected SessionProvider: SessionProvider;
8
9
  resolve(): Promise<void>;
9
10
  before(): (req: sRequest, res: express.Response, next: express.NextFunction) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../src/middlewares.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,eAAe,EAAQ,MAAM,eAAe,CAAC;AAEhE,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtE,qBACa,cAAe,SAAQ,gBAAgB;IAElD,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC;IAGhC,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAE9B,OAAO;IAMb,MAAM,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,KAAK,IAAI;IA0CpF,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,GAAG,IAAI;CAGpG"}
1
+ {"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../src/middlewares.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,eAAe,EAA6B,MAAM,eAAe,CAAC;AAErF,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtE,qBACa,cAAe,SAAQ,gBAAgB;IAElD,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC;IAGhC,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC;IAGnC,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAE9B,OAAO;IAMb,MAAM,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,KAAK,IAAI;IAyDpF,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,GAAG,IAAI;CAGpG"}
@@ -56,7 +56,7 @@ let RbacMiddleware = class RbacMiddleware extends http_1.ServerMiddleware {
56
56
  }
57
57
  }
58
58
  before() {
59
- return async (req, _res, next) => {
59
+ return async (req, res, next) => {
60
60
  try {
61
61
  let session = null;
62
62
  if (req.cookies?.ssid) {
@@ -83,6 +83,20 @@ let RbacMiddleware = class RbacMiddleware extends http_1.ServerMiddleware {
83
83
  req.storage.ActiveRole = sessionActiveRole && req.storage.User.Role.includes(sessionActiveRole)
84
84
  ? sessionActiveRole
85
85
  : req.storage.User.Role?.[0];
86
+ // Sliding renewal: touch the session on every authenticated request.
87
+ // The store recomputes Expiration via the configured strategy and
88
+ // returns true only when it actually changed (sliding modes); under
89
+ // absolute expiration it returns false and performs no write, so we
90
+ // leave the cookie untouched.
91
+ const renewed = await this.SessionProvider.touch(session);
92
+ if (renewed) {
93
+ res.cookie('ssid', session.SessionId, {
94
+ signed: true,
95
+ httpOnly: true,
96
+ maxAge: (0, rbac_1.sessionCookieMaxAge)(session),
97
+ ...this.SessionCookieConfig,
98
+ });
99
+ }
86
100
  }
87
101
  else {
88
102
  req.storage.User = di_1.DI.resolve('RbacGuestUserFactory');
@@ -104,6 +118,10 @@ __decorate([
104
118
  (0, configuration_1.Config)('http.cookie.secret'),
105
119
  __metadata("design:type", String)
106
120
  ], RbacMiddleware.prototype, "CoockieSecret", void 0);
121
+ __decorate([
122
+ (0, configuration_1.Config)('rbac.session.cookie', {}),
123
+ __metadata("design:type", Object)
124
+ ], RbacMiddleware.prototype, "SessionCookieConfig", void 0);
107
125
  __decorate([
108
126
  (0, di_1.Autoinject)(),
109
127
  __metadata("design:type", rbac_1.SessionProvider)
@@ -1 +1 @@
1
- {"version":3,"file":"middlewares.js","sourceRoot":"","sources":["../../src/middlewares.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wCAAgE;AAChE,oCAAyD;AACzD,4BAA0B;AAE1B,0DAAgD;AAChD,qDAAuC;AACvC,wCAAsE;AAG/D,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,uBAAgB;IAO3C,KAAK,CAAC,OAAO;QAClB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,gHAAgH,CAAC,CAAC;QACpI,CAAC;IACH,CAAC;IAEM,MAAM;QACX,OAAO,KAAK,EAAE,GAAa,EAAE,IAAsB,EAAE,IAA0B,EAAE,EAAE;YACjF,IAAI,CAAC;gBACH,IAAI,OAAO,GAAoB,IAAI,CAAC;gBACpC,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;oBACtB,MAAM,IAAI,GAAmB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;oBAC7E,IAAI,IAAI,EAAE,CAAC;wBACT,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACrD,CAAC;gBACH,CAAC;gBAED,IAAI,OAAO,EAAE,CAAC;oBACZ;;;uBAGG;oBACH,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,MAAM,OAAE,CAAC,OAAO,CAAO,iBAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;oBACzF,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;oBAE9B,kEAAkE;oBAClE,oEAAoE;oBACpE,qEAAqE;oBACrE,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAuB,CAAC;oBAChF,IAAI,gBAAgB,EAAE,CAAC;wBACrB,GAAG,CAAC,OAAO,CAAC,YAAY,GAAG,MAAM,OAAE,CAAC,OAAO,CAAO,iBAAiB,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAC3F,CAAC;oBAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAuB,CAAC;oBAC/E,GAAG,CAAC,OAAO,CAAC,UAAU,GAAG,iBAAiB,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;wBAC7F,CAAC,CAAC,iBAAiB;wBACnB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,OAAE,CAAC,OAAO,CAAO,sBAAsB,CAAC,CAAC;oBAC5D,GAAG,CAAC,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACtD,CAAC;gBAED,IAAI,EAAE,CAAC;YACT,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IACM,KAAK;QACV,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA1DY,wCAAc;AAEf;IADT,IAAA,sBAAM,EAAC,oBAAoB,CAAC;;qDACG;AAGtB;IADT,IAAA,eAAU,GAAE;8BACc,sBAAe;uDAAC;yBALhC,cAAc;IAD1B,IAAA,eAAU,EAAC,uBAAgB,CAAC;GAChB,cAAc,CA0D1B"}
1
+ {"version":3,"file":"middlewares.js","sourceRoot":"","sources":["../../src/middlewares.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wCAAqF;AACrF,oCAAyD;AACzD,4BAA0B;AAE1B,0DAAgD;AAChD,qDAAuC;AACvC,wCAAsE;AAG/D,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,uBAAgB;IAU3C,KAAK,CAAC,OAAO;QAClB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,gHAAgH,CAAC,CAAC;QACpI,CAAC;IACH,CAAC;IAEM,MAAM;QACX,OAAO,KAAK,EAAE,GAAa,EAAE,GAAqB,EAAE,IAA0B,EAAE,EAAE;YAChF,IAAI,CAAC;gBACH,IAAI,OAAO,GAAoB,IAAI,CAAC;gBACpC,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;oBACtB,MAAM,IAAI,GAAmB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;oBAC7E,IAAI,IAAI,EAAE,CAAC;wBACT,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACrD,CAAC;gBACH,CAAC;gBAED,IAAI,OAAO,EAAE,CAAC;oBACZ;;;uBAGG;oBACH,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,MAAM,OAAE,CAAC,OAAO,CAAO,iBAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;oBACzF,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;oBAE9B,kEAAkE;oBAClE,oEAAoE;oBACpE,qEAAqE;oBACrE,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAuB,CAAC;oBAChF,IAAI,gBAAgB,EAAE,CAAC;wBACrB,GAAG,CAAC,OAAO,CAAC,YAAY,GAAG,MAAM,OAAE,CAAC,OAAO,CAAO,iBAAiB,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAC3F,CAAC;oBAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAuB,CAAC;oBAC/E,GAAG,CAAC,OAAO,CAAC,UAAU,GAAG,iBAAiB,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;wBAC7F,CAAC,CAAC,iBAAiB;wBACnB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;oBAE/B,qEAAqE;oBACrE,kEAAkE;oBAClE,oEAAoE;oBACpE,oEAAoE;oBACpE,8BAA8B;oBAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAC1D,IAAI,OAAO,EAAE,CAAC;wBACZ,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE;4BACpC,MAAM,EAAE,IAAI;4BACZ,QAAQ,EAAE,IAAI;4BACd,MAAM,EAAE,IAAA,0BAAmB,EAAC,OAAO,CAAC;4BACpC,GAAG,IAAI,CAAC,mBAAmB;yBAC5B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,OAAE,CAAC,OAAO,CAAO,sBAAsB,CAAC,CAAC;oBAC5D,GAAG,CAAC,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACtD,CAAC;gBAED,IAAI,EAAE,CAAC;YACT,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IACM,KAAK;QACV,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA5EY,wCAAc;AAEf;IADT,IAAA,sBAAM,EAAC,oBAAoB,CAAC;;qDACG;AAGtB;IADT,IAAA,sBAAM,EAAC,qBAAqB,EAAE,EAAE,CAAC;;2DACC;AAGzB;IADT,IAAA,eAAU,GAAE;8BACc,sBAAe;uDAAC;yBARhC,cAAc;IAD1B,IAAA,eAAU,EAAC,uBAAgB,CAAC;GAChB,cAAc,CA4E1B"}
@@ -1,6 +1,9 @@
1
1
  import { BasePolicy, IController, IRoute, Request as sRequest } from '@spinajs/http';
2
2
  /**
3
- * Policy to block guests
3
+ * Policy that ALLOWS guest users through. Access is only refused when the
4
+ * request has no user/session at all, or when the guest account itself has
5
+ * been globally disabled (IsActive === false). Use BlockGuest for the opposite
6
+ * behavior (reject guests, require a real logged-in user).
4
7
  */
5
8
  export declare class AllowGuest extends BasePolicy {
6
9
  isEnabled(_action: IRoute, _instance: IController): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"AllowGuest.d.ts","sourceRoot":"","sources":["../../../src/policies/AllowGuest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGrF;;GAEG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACjC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO;IAKrD,OAAO,CAAC,GAAG,EAAE,QAAQ;CAenC"}
1
+ {"version":3,"file":"AllowGuest.d.ts","sourceRoot":"","sources":["../../../src/policies/AllowGuest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGrF;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACjC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO;IAKrD,OAAO,CAAC,GAAG,EAAE,QAAQ;CAenC"}
@@ -4,7 +4,10 @@ exports.AllowGuest = void 0;
4
4
  const http_1 = require("@spinajs/http");
5
5
  const exceptions_1 = require("@spinajs/exceptions");
6
6
  /**
7
- * Policy to block guests
7
+ * Policy that ALLOWS guest users through. Access is only refused when the
8
+ * request has no user/session at all, or when the guest account itself has
9
+ * been globally disabled (IsActive === false). Use BlockGuest for the opposite
10
+ * behavior (reject guests, require a real logged-in user).
8
11
  */
9
12
  class AllowGuest extends http_1.BasePolicy {
10
13
  isEnabled(_action, _instance) {
@@ -1 +1 @@
1
- {"version":3,"file":"AllowGuest.js","sourceRoot":"","sources":["../../../src/policies/AllowGuest.ts"],"names":[],"mappings":";;;AAAA,wCAAqF;AACrF,oDAAsE;AAEtE;;GAEG;AACH,MAAa,UAAW,SAAQ,iBAAU;IACjC,SAAS,CAAC,OAAe,EAAE,SAAsB;QACtD,0BAA0B;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAa;QAChC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,IAAI,iCAAoB,CAAC,oCAAoC,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,oDAAoD;YACpD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,IAAI,sBAAS,CAAC,2BAA2B,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF;AArBD,gCAqBC"}
1
+ {"version":3,"file":"AllowGuest.js","sourceRoot":"","sources":["../../../src/policies/AllowGuest.ts"],"names":[],"mappings":";;;AAAA,wCAAqF;AACrF,oDAAsE;AAEtE;;;;;GAKG;AACH,MAAa,UAAW,SAAQ,iBAAU;IACjC,SAAS,CAAC,OAAe,EAAE,SAAsB;QACtD,0BAA0B;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAa;QAChC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,IAAI,iCAAoB,CAAC,oCAAoC,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,oDAAoD;YACpD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,IAAI,sBAAS,CAAC,2BAA2B,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF;AArBD,gCAqBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RbacPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/RbacPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAe,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKlG,OAAO,EAAkB,IAAI,EAAE,MAAM,eAAe,CAAC;AAErD;;GAEG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACxC,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;;IAQrB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO;IAKrD,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW;CA0B1E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAG7G;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQvG;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQ3G"}
1
+ {"version":3,"file":"RbacPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/RbacPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAe,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKlG,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC;;GAEG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACxC,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;;IAQrB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO;IAKrD,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW;CA4C1E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAG7G;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQvG;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQ3G"}
@@ -22,12 +22,28 @@ class RbacPolicy extends http_1.BasePolicy {
22
22
  }
23
23
  async execute(req, action, instance) {
24
24
  const descriptor = Reflect.getMetadata(decorators_js_1.ACL_CONTROLLER_DESCRIPTOR, instance);
25
+ // Guard BEFORE dereferencing: RbacPolicy applied to a route/controller with
26
+ // no ACL metadata (e.g. @Policy(RbacPolicy) without @Resource/@Permission)
27
+ // must produce the descriptive server error, not a raw TypeError 500 from
28
+ // reading `.Permission` / `.Routes` off undefined.
29
+ if (!descriptor) {
30
+ throw new http_1.ServerError(`no route permission or resources assigned`);
31
+ }
25
32
  let permission = descriptor.Permission ?? [];
26
33
  if (descriptor.Routes.has(String(action.Method))) {
27
- //req.storage.PermissionScope = descriptor.Routes.get(action.Method).Permission;
28
- if (req.headers['x-permission-scope']) {
29
- req.storage.PermissionScope = req.headers['x-permission-scope'] ?? null;
30
- }
34
+ // SECURITY: PermissionScope must NEVER be taken from a client-supplied
35
+ // header. The ORM rbac query middleware uses PermissionScope to decide
36
+ // which own/any grant to enforce and, on a scope it does not recognise or
37
+ // that does not match the query type, it SKIPS row-level enforcement
38
+ // entirely. Letting the client set it therefore allowed any authenticated
39
+ // user holding only *Own grants to send `x-permission-scope: <anything>`
40
+ // and read/update/delete every row (owner-field WHERE restriction never
41
+ // applied). With no scope set, the middleware falls back to the correct
42
+ // query-derived scope (QUERY_TO_PERMISSION), which is the secure default.
43
+ //
44
+ // If a route ever needs an explicit scope it must be derived server-side
45
+ // from the route's declared permission, not from the request, e.g.:
46
+ // req.storage.PermissionScope = descriptor.Routes.get(String(action.Method))!.Permission?.[0];
31
47
  permission = descriptor.Routes.get(String(action.Method)).Permission ?? [];
32
48
  }
33
49
  // check if route has its own permission
@@ -1 +1 @@
1
- {"version":3,"file":"RbacPolicy.js","sourceRoot":"","sources":["../../../src/policies/RbacPolicy.ts"],"names":[],"mappings":";;;AAqDA,kDAGC;AAED,kDAQC;AAED,oDAQC;AA3ED,wCAAkG;AAClG,oDAAsE;AACtE,oDAA6D;AAE7D,oCAAiC;AAGjC;;GAEG;AACH,MAAa,UAAW,SAAQ,iBAAU;IAGxC;QACE,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,EAAE,GAAG,OAAE,CAAC,GAAG,CAAC,eAAe,CAAE,CAAC;IACrC,CAAC;IAEM,SAAS,CAAC,OAAe,EAAE,SAAsB;QACtD,0BAA0B;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAa,EAAE,MAAc,EAAE,QAAqB;QACvE,MAAM,UAAU,GAAoB,OAAO,CAAC,WAAW,CAAC,yCAAyB,EAAE,QAAQ,CAAC,CAAC;QAC7F,IAAI,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;QAE7C,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACjD,gFAAgF;YAChF,IAAI,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;gBACtC,GAAG,CAAC,OAAO,CAAC,eAAe,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAmB,IAAI,IAAI,CAAC;YAC5F,CAAC;YACD,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAE,CAAC,UAAU,IAAI,EAAE,CAAC;QAC9E,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,kBAAW,CAAC,2CAA2C,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7G,MAAM,IAAI,iCAAoB,CAAC,oCAAoC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,oBAAoB,CAAC,GAAG,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;YACtF,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAClE,MAAM,IAAI,sBAAS,CAAC,WAAW,SAAS,6BAA6B,UAAU,iBAAiB,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzH,CAAC;IACH,CAAC;CACF;AAxCD,gCAwCC;AAED,SAAgB,mBAAmB,CAAC,IAAuB,EAAE,QAAgB,EAAE,UAAkB;IAC/F,MAAM,EAAE,GAAG,OAAE,CAAC,GAAG,CAAgB,eAAe,CAAE,CAAC;IACnD,OAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAS,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED,SAAgB,mBAAmB,CAAC,IAAU,EAAE,QAAgB,EAAE,UAAkB;IAClF,MAAM,EAAE,GAAG,OAAE,CAAC,GAAG,CAAgB,eAAe,CAAE,CAAC;IAEnD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAS,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC1D,CAAC;AAED,SAAgB,oBAAoB,CAAC,GAAa,EAAE,QAAgB,EAAE,UAAkB;IACtF,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GAAG,OAAE,CAAC,GAAG,CAAgB,eAAe,CAAE,CAAC;IACnD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;IACxF,OAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,CAAS,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"RbacPolicy.js","sourceRoot":"","sources":["../../../src/policies/RbacPolicy.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { BaseController, Ok } from '@spinajs/http';
2
- import { AccessControl } from '@spinajs/rbac';
2
+ import { AccessControl, User as RbacUser } from '@spinajs/rbac';
3
3
  import { IGrantsMap } from '../interfaces.js';
4
4
  /**
5
5
  * RBAC grants management.
@@ -10,11 +10,13 @@ export declare class GrantsController extends BaseController {
10
10
  protected AC: AccessControl;
11
11
  /**
12
12
  * Get RBAC grants
13
- * Returns the full RBAC grants object defining roles and their permissions across resources.
13
+ * Returns the RBAC grants for the requesting user's own role(s) only — not
14
+ * the full cross-role matrix, which would leak the entire access-control
15
+ * policy to any authenticated user.
14
16
  * @security cookieAuth
15
- * @returns {IGrantsMap} RBAC grants map keyed by role name
17
+ * @returns {IGrantsMap} RBAC grants map keyed by the caller's role name(s)
16
18
  * @response 401 Unauthorized — valid session cookie required
17
19
  */
18
- getGrants(): Ok<IGrantsMap>;
20
+ getGrants(user: RbacUser): Ok<IGrantsMap>;
19
21
  }
20
22
  //# sourceMappingURL=GrantsController.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GrantsController.d.ts","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,EAAE,EAAU,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;;GAIG;AACH,qBAEa,gBAAiB,SAAQ,cAAc;IAGhD,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;OAMG;IAEI,SAAS,IAAI,EAAE,CAAC,UAAU,CAAC;CAIrC"}
1
+ {"version":3,"file":"GrantsController.d.ts","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,EAAE,EAAU,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIhE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;;GAIG;AACH,qBAEa,gBAAiB,SAAQ,cAAc;IAGhD,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;;;OAQG;IAEI,SAAS,CAAS,IAAI,EAAE,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC;CAc3D"}
@@ -7,10 +7,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
10
13
  import { BaseController, BasePath, Get, Ok, Policy } from '@spinajs/http';
11
- import { AccessControl } from '@spinajs/rbac';
14
+ import { AccessControl, User as RbacUser } from '@spinajs/rbac';
12
15
  import { Autoinject } from '@spinajs/di';
13
16
  import { AuthorizedPolicy } from '../policies/AuthorizedPolicy.js';
17
+ import { User } from '../decorators.js';
14
18
  /**
15
19
  * RBAC grants management.
16
20
  * Provides access to the current RBAC access-control grants configuration.
@@ -19,13 +23,23 @@ import { AuthorizedPolicy } from '../policies/AuthorizedPolicy.js';
19
23
  let GrantsController = class GrantsController extends BaseController {
20
24
  /**
21
25
  * Get RBAC grants
22
- * Returns the full RBAC grants object defining roles and their permissions across resources.
26
+ * Returns the RBAC grants for the requesting user's own role(s) only — not
27
+ * the full cross-role matrix, which would leak the entire access-control
28
+ * policy to any authenticated user.
23
29
  * @security cookieAuth
24
- * @returns {IGrantsMap} RBAC grants map keyed by role name
30
+ * @returns {IGrantsMap} RBAC grants map keyed by the caller's role name(s)
25
31
  * @response 401 Unauthorized — valid session cookie required
26
32
  */
27
- getGrants() {
28
- return new Ok(this.AC.getGrants());
33
+ getGrants(user) {
34
+ const allGrants = this.AC.getGrants();
35
+ const roles = user?.Role ?? [];
36
+ const filtered = {};
37
+ for (const role of roles) {
38
+ if (allGrants[role]) {
39
+ filtered[role] = allGrants[role];
40
+ }
41
+ }
42
+ return new Ok(filtered);
29
43
  }
30
44
  };
31
45
  __decorate([
@@ -34,8 +48,9 @@ __decorate([
34
48
  ], GrantsController.prototype, "AC", void 0);
35
49
  __decorate([
36
50
  Get(),
51
+ __param(0, User()),
37
52
  __metadata("design:type", Function),
38
- __metadata("design:paramtypes", []),
53
+ __metadata("design:paramtypes", [RbacUser]),
39
54
  __metadata("design:returntype", Ok)
40
55
  ], GrantsController.prototype, "getGrants", null);
41
56
  GrantsController = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"GrantsController.js","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE;;;;GAIG;AAGI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,cAAc;IAKhD;;;;;;OAMG;IAEI,SAAS;QACZ,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,CAAC;CAEJ,CAAA;AAda;IADT,UAAU,CAAC,aAAa,CAAC;8BACZ,aAAa;4CAAC;AAUrB;IADN,GAAG,EAAE;;;oCACc,EAAE;iDAErB;AAfQ,gBAAgB;IAF5B,QAAQ,CAAC,QAAQ,CAAC;IAClB,MAAM,CAAC,gBAAgB,CAAC;GACZ,gBAAgB,CAiB5B"}
1
+ {"version":3,"file":"GrantsController.js","sourceRoot":"","sources":["../../../src/controllers/GrantsController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC;;;;GAIG;AAGI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,cAAc;IAKhD;;;;;;;;OAQG;IAEI,SAAS,CAAS,IAAc;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,SAAS,EAAgB,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAE/B,MAAM,QAAQ,GAAe,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;CAEJ,CAAA;AA1Ba;IADT,UAAU,CAAC,aAAa,CAAC;8BACZ,aAAa;4CAAC;AAYrB;IADN,GAAG,EAAE;IACY,WAAA,IAAI,EAAE,CAAA;;qCAAO,QAAQ;oCAAG,EAAE;iDAY3C;AA3BQ,gBAAgB;IAF5B,QAAQ,CAAC,QAAQ,CAAC;IAClB,MAAM,CAAC,gBAAgB,CAAC;GACZ,gBAAgB,CA6B5B"}
@@ -10,7 +10,10 @@ export declare function setRbacMetadata(target: any, callback: (meta: IRbacDescr
10
10
  * Assign resource for controller
11
11
  *
12
12
  * @param resource - name of resource
13
- * @param permission - default permission
13
+ * @param permission - default permission. When omitted, the base controller's
14
+ * permission is kept ( `readOwn` if there is nothing to
15
+ * inherit ), so renaming a resource in a subclass does not
16
+ * silently change what it grants.
14
17
  */
15
18
  export declare function Resource(resource: string, permission?: PermissionType[]): any;
16
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkC,MAAM,iBAAiB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C;;;GAGG;AACH,eAAO,MAAM,yBAAyB,eAAiD,CAAC;AAExF,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,QAerF;AAqBD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAE,cAAc,EAAgB,OAKpF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,GAAE,cAAc,EAAgB,OAapE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,0GAalC;AAED;;GAEG;AACH,wBAAgB,IAAI,0GAEnB;AAED;;GAEG;AACH,wBAAgB,WAAW,0GAE1B;AAED,wBAAgB,OAAO,0GAEtB"}
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkC,MAAM,iBAAiB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C;;;GAGG;AACH,eAAO,MAAM,yBAAyB,eAAiD,CAAC;AAuFxF,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,QAMrF;AAYD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,OAevE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,GAAE,cAAc,EAAgB,OAgBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,0GAalC;AAED;;GAEG;AACH,wBAAgB,IAAI,0GAEnB;AAED;;GAEG;AACH,wBAAgB,WAAW,0GAE1B;AAED,wBAAgB,OAAO,0GAEtB"}