@aooth/arbac-core 0.1.70 → 0.1.72

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/index.cjs CHANGED
@@ -99,9 +99,8 @@ var Arbac = class {
99
99
  };
100
100
  const userEval = await this.evaluateForRoles(res, user.roles, userAttrs, user.id);
101
101
  if (!user.attenuate) return userEval;
102
- const claimRoles = user.attenuate.roles;
103
- const claimAttrs = user.attenuate.attrs;
104
- const credRoles = claimRoles ? user.roles.filter((r) => claimRoles.includes(r)) : user.roles;
102
+ const { roles: claimRoles, attrs: claimAttrs, allowUnheldRoles } = user.attenuate;
103
+ const credRoles = !claimRoles ? user.roles : allowUnheldRoles ? [...new Set(claimRoles)].filter((r) => Object.hasOwn(this.roles, r) && !!this.roles[r]) : user.roles.filter((r) => claimRoles.includes(r));
105
104
  const credAttrs = claimAttrs ? async () => ({
106
105
  ...await userAttrs(),
107
106
  ...claimAttrs
package/dist/index.d.cts CHANGED
@@ -101,12 +101,17 @@ declare class Arbac<TUserAttrs extends object, TScope extends object> {
101
101
  *
102
102
  * `roles: []` → no roles (deny-all, fail-closed). An OMITTED `roles` key
103
103
  * → keep all the user's roles (attrs-only narrowing). A claimed role the
104
- * user lacks is dropped by the intersection (fail-closed). Absent
105
- * `attenuate` → a single evaluation, byte-for-byte today's behavior.
104
+ * user lacks is dropped by the intersection (fail-closed) — unless
105
+ * `allowUnheldRoles` is set: then the claimed roles are evaluated as
106
+ * given ("view as" — an unknown role id still contributes nothing), and
107
+ * the outcome is still intersected with the full-authority pass, so an
108
+ * unheld role can never widen beyond the user. Absent `attenuate` → a
109
+ * single evaluation, byte-for-byte today's behavior.
106
110
  */
107
111
  attenuate?: {
108
112
  roles?: string[];
109
113
  attrs?: Partial<TUserAttrs>;
114
+ allowUnheldRoles?: boolean;
110
115
  };
111
116
  }): Promise<TArbacEvalResult<TScope>>;
112
117
  /**
package/dist/index.d.mts CHANGED
@@ -101,12 +101,17 @@ declare class Arbac<TUserAttrs extends object, TScope extends object> {
101
101
  *
102
102
  * `roles: []` → no roles (deny-all, fail-closed). An OMITTED `roles` key
103
103
  * → keep all the user's roles (attrs-only narrowing). A claimed role the
104
- * user lacks is dropped by the intersection (fail-closed). Absent
105
- * `attenuate` → a single evaluation, byte-for-byte today's behavior.
104
+ * user lacks is dropped by the intersection (fail-closed) — unless
105
+ * `allowUnheldRoles` is set: then the claimed roles are evaluated as
106
+ * given ("view as" — an unknown role id still contributes nothing), and
107
+ * the outcome is still intersected with the full-authority pass, so an
108
+ * unheld role can never widen beyond the user. Absent `attenuate` → a
109
+ * single evaluation, byte-for-byte today's behavior.
106
110
  */
107
111
  attenuate?: {
108
112
  roles?: string[];
109
113
  attrs?: Partial<TUserAttrs>;
114
+ allowUnheldRoles?: boolean;
110
115
  };
111
116
  }): Promise<TArbacEvalResult<TScope>>;
112
117
  /**
package/dist/index.mjs CHANGED
@@ -98,9 +98,8 @@ var Arbac = class {
98
98
  };
99
99
  const userEval = await this.evaluateForRoles(res, user.roles, userAttrs, user.id);
100
100
  if (!user.attenuate) return userEval;
101
- const claimRoles = user.attenuate.roles;
102
- const claimAttrs = user.attenuate.attrs;
103
- const credRoles = claimRoles ? user.roles.filter((r) => claimRoles.includes(r)) : user.roles;
101
+ const { roles: claimRoles, attrs: claimAttrs, allowUnheldRoles } = user.attenuate;
102
+ const credRoles = !claimRoles ? user.roles : allowUnheldRoles ? [...new Set(claimRoles)].filter((r) => Object.hasOwn(this.roles, r) && !!this.roles[r]) : user.roles.filter((r) => claimRoles.includes(r));
104
103
  const credAttrs = claimAttrs ? async () => ({
105
104
  ...await userAttrs(),
106
105
  ...claimAttrs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aooth/arbac-core",
3
- "version": "0.1.70",
3
+ "version": "0.1.72",
4
4
  "description": "Advanced Role-Based Access Control (ARBAC) engine",
5
5
  "keywords": [
6
6
  "access-control",