@spinajs/rbac 2.0.485 → 2.0.487
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/lib/cjs/actions.d.ts +18 -2
- package/lib/cjs/actions.d.ts.map +1 -1
- package/lib/cjs/actions.js +193 -13
- package/lib/cjs/actions.js.map +1 -1
- package/lib/cjs/config/rbac.d.ts +35 -1
- package/lib/cjs/config/rbac.d.ts.map +1 -1
- package/lib/cjs/config/rbac.js +39 -4
- package/lib/cjs/config/rbac.js.map +1 -1
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +12 -2
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.d.ts +21 -0
- package/lib/cjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.d.ts.map +1 -0
- package/lib/cjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.js +49 -0
- package/lib/cjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.js.map +1 -0
- package/lib/cjs/models/User.d.ts +20 -1
- package/lib/cjs/models/User.d.ts.map +1 -1
- package/lib/cjs/models/User.js +27 -6
- package/lib/cjs/models/User.js.map +1 -1
- package/lib/cjs/session.d.ts +82 -0
- package/lib/cjs/session.d.ts.map +1 -1
- package/lib/cjs/session.js +105 -1
- package/lib/cjs/session.js.map +1 -1
- package/lib/cjs/util.d.ts +20 -1
- package/lib/cjs/util.d.ts.map +1 -1
- package/lib/cjs/util.js +50 -9
- package/lib/cjs/util.js.map +1 -1
- package/lib/mjs/actions.d.ts +18 -2
- package/lib/mjs/actions.d.ts.map +1 -1
- package/lib/mjs/actions.js +193 -14
- package/lib/mjs/actions.js.map +1 -1
- package/lib/mjs/config/rbac.d.ts +35 -1
- package/lib/mjs/config/rbac.d.ts.map +1 -1
- package/lib/mjs/config/rbac.js +39 -4
- package/lib/mjs/config/rbac.js.map +1 -1
- package/lib/mjs/index.d.ts +1 -0
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +13 -3
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.d.ts +21 -0
- package/lib/mjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.d.ts.map +1 -0
- package/lib/mjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.js +46 -0
- package/lib/mjs/migrations/RBACRegisteredAt_2026_07_28_00_00_00.js.map +1 -0
- package/lib/mjs/models/User.d.ts +20 -1
- package/lib/mjs/models/User.d.ts.map +1 -1
- package/lib/mjs/models/User.js +26 -5
- package/lib/mjs/models/User.js.map +1 -1
- package/lib/mjs/session.d.ts +82 -0
- package/lib/mjs/session.d.ts.map +1 -1
- package/lib/mjs/session.js +99 -0
- package/lib/mjs/session.js.map +1 -1
- package/lib/mjs/util.d.ts +20 -1
- package/lib/mjs/util.d.ts.map +1 -1
- package/lib/mjs/util.js +48 -8
- package/lib/mjs/util.js.map +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +11 -11
package/lib/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kEAA+B;AAC/B,iDAA8C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { OrmMigration, OrmDriver } from '@spinajs/orm';
|
|
2
|
+
/**
|
|
3
|
+
* Adds the missing `RegisteredAt` column to `users`.
|
|
4
|
+
*
|
|
5
|
+
* `UserBase.RegisteredAt` has been declared on the model — and stamped by the
|
|
6
|
+
* `create()` action — since the beginning, but the initial migration never
|
|
7
|
+
* created the column. The ORM writes only columns the table description
|
|
8
|
+
* actually reports, so the value was dropped on every insert without a word:
|
|
9
|
+
* the field read back as null forever and anything distinguishing "account
|
|
10
|
+
* created" from "registration completed" quietly did not work.
|
|
11
|
+
*
|
|
12
|
+
* Nullable on purpose. Existing rows genuinely have no registration instant to
|
|
13
|
+
* backfill with, and inventing one ( CreatedAt, say ) would assert that every
|
|
14
|
+
* account that predates this migration completed registration, which is exactly
|
|
15
|
+
* the claim the column exists to make.
|
|
16
|
+
*/
|
|
17
|
+
export declare class RBACRegisteredAt_2026_07_28_00_00_00 extends OrmMigration {
|
|
18
|
+
up(connection: OrmDriver): Promise<void>;
|
|
19
|
+
down(_connection: OrmDriver): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=RBACRegisteredAt_2026_07_28_00_00_00.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RBACRegisteredAt_2026_07_28_00_00_00.d.ts","sourceRoot":"","sources":["../../../src/migrations/RBACRegisteredAt_2026_07_28_00_00_00.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAa,MAAM,cAAc,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,qBACa,oCAAqC,SAAQ,YAAY;IACvD,EAAE,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxC,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CACzD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RBACRegisteredAt_2026_07_28_00_00_00 = void 0;
|
|
10
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
11
|
+
const orm_1 = require("@spinajs/orm");
|
|
12
|
+
/**
|
|
13
|
+
* Adds the missing `RegisteredAt` column to `users`.
|
|
14
|
+
*
|
|
15
|
+
* `UserBase.RegisteredAt` has been declared on the model — and stamped by the
|
|
16
|
+
* `create()` action — since the beginning, but the initial migration never
|
|
17
|
+
* created the column. The ORM writes only columns the table description
|
|
18
|
+
* actually reports, so the value was dropped on every insert without a word:
|
|
19
|
+
* the field read back as null forever and anything distinguishing "account
|
|
20
|
+
* created" from "registration completed" quietly did not work.
|
|
21
|
+
*
|
|
22
|
+
* Nullable on purpose. Existing rows genuinely have no registration instant to
|
|
23
|
+
* backfill with, and inventing one ( CreatedAt, say ) would assert that every
|
|
24
|
+
* account that predates this migration completed registration, which is exactly
|
|
25
|
+
* the claim the column exists to make.
|
|
26
|
+
*/
|
|
27
|
+
let RBACRegisteredAt_2026_07_28_00_00_00 = class RBACRegisteredAt_2026_07_28_00_00_00 extends orm_1.OrmMigration {
|
|
28
|
+
async up(connection) {
|
|
29
|
+
// Applications that hit this gap already have added the column by hand;
|
|
30
|
+
// running ALTER TABLE against them would fail the whole migration on
|
|
31
|
+
// startup. Checked rather than assumed, because a migration that can only
|
|
32
|
+
// run on a pristine database is a migration that strands everybody who
|
|
33
|
+
// worked around the bug.
|
|
34
|
+
const columns = await connection.tableInfo('users');
|
|
35
|
+
if (columns?.some((c) => c.Name === 'RegisteredAt')) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
await connection.schema().alterTable('users', (table) => {
|
|
39
|
+
table.dateTime('RegisteredAt');
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
43
|
+
async down(_connection) { }
|
|
44
|
+
};
|
|
45
|
+
exports.RBACRegisteredAt_2026_07_28_00_00_00 = RBACRegisteredAt_2026_07_28_00_00_00;
|
|
46
|
+
exports.RBACRegisteredAt_2026_07_28_00_00_00 = RBACRegisteredAt_2026_07_28_00_00_00 = __decorate([
|
|
47
|
+
(0, orm_1.Migration)('default')
|
|
48
|
+
], RBACRegisteredAt_2026_07_28_00_00_00);
|
|
49
|
+
//# sourceMappingURL=RBACRegisteredAt_2026_07_28_00_00_00.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RBACRegisteredAt_2026_07_28_00_00_00.js","sourceRoot":"","sources":["../../../src/migrations/RBACRegisteredAt_2026_07_28_00_00_00.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sDAAsD;AACtD,sCAAkE;AAElE;;;;;;;;;;;;;;GAcG;AAEI,IAAM,oCAAoC,GAA1C,MAAM,oCAAqC,SAAQ,kBAAY;IAC7D,KAAK,CAAC,EAAE,CAAC,UAAqB;QACnC,wEAAwE;QACxE,qEAAqE;QACrE,0EAA0E;QAC1E,uEAAuE;QACvE,yBAAyB;QACzB,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAEpD,IAAI,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC;YACpD,OAAO;QACT,CAAC;QAED,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACtD,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gEAAgE;IACzD,KAAK,CAAC,IAAI,CAAC,WAAsB,IAAkB,CAAC;CAC5D,CAAA;AApBY,oFAAoC;+CAApC,oCAAoC;IADhD,IAAA,eAAS,EAAC,SAAS,CAAC;GACR,oCAAoC,CAoBhD"}
|
package/lib/cjs/models/User.d.ts
CHANGED
|
@@ -65,8 +65,27 @@ export declare enum USER_COMMON_METADATA {
|
|
|
65
65
|
USER_PWD_RESET_START_DATE = "user:pwd_reset:start_date",
|
|
66
66
|
USER_PWD_RESET_WAIT_TIME = "user:pwd_reset:wait_time",
|
|
67
67
|
USER_PWD_RESET_TOKEN = "user:pwd_reset:token",
|
|
68
|
-
USER_PWD_RESET_LAST_ATTEMPT = "user:pwd_reset:last_attempt"
|
|
68
|
+
USER_PWD_RESET_LAST_ATTEMPT = "user:pwd_reset:last_attempt",
|
|
69
|
+
/** Login throttling */
|
|
70
|
+
USER_LOGIN_ATTEMPTS = "user:login:attempts",
|
|
71
|
+
USER_LOGIN_LOCKED_UNTIL = "user:login:locked_until"
|
|
69
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Metadata that decides whether somebody gets INTO an account, and therefore must
|
|
75
|
+
* never travel out of one — not to the account owner and not to an administrator
|
|
76
|
+
* reading the record through the API.
|
|
77
|
+
*
|
|
78
|
+
* `user:pwd_reset:token` is the sharp one: it is a bearer credential for
|
|
79
|
+
* `POST /auth/password/reset`, and the reset can be requested for anybody without
|
|
80
|
+
* being logged in at all. Handing it back in a user payload turns "read a user"
|
|
81
|
+
* into "take over that user". Ban and lockout state are here for a smaller reason
|
|
82
|
+
* — they tell an attacker exactly how much of the throttle they have burned.
|
|
83
|
+
*
|
|
84
|
+
* Applied to {@link UserMetadataBase._hiddenKeys} by the rbac bootstrapper, so it
|
|
85
|
+
* covers every `dehydrateWithRelations` in every package. Keys that a client
|
|
86
|
+
* legitimately needs ( avatar, phone, ... ) are deliberately absent.
|
|
87
|
+
*/
|
|
88
|
+
export declare const USER_SECURITY_METADATA_KEYS: string[];
|
|
70
89
|
/**
|
|
71
90
|
* Base model for users used by auth and ACL system
|
|
72
91
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"User.d.ts","sourceRoot":"","sources":["../../../src/models/User.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAW,SAAS,EAAmF,UAAU,EAAE,mBAAmB,EAAE,gBAAgB,EAAY,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAC9O,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAgB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAMnE,qBAAa,eAAgB,YAAW,UAAU;
|
|
1
|
+
{"version":3,"file":"User.d.ts","sourceRoot":"","sources":["../../../src/models/User.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAW,SAAS,EAAmF,UAAU,EAAE,mBAAmB,EAAE,gBAAgB,EAAY,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAC9O,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAgB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAMnE,qBAAa,eAAgB,YAAW,UAAU;IAChD;;;;;;OAMG;IACI,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE;IAKpF;;;;;;;OAOG;IACI,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG;IAU1F,SAAS,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe,EAAE,WAAW,EAAE,IAAI,GAAG,MAAM;IAMnF,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe;IAcjE,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe;IAKvE,UAAU,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe;IAMrE;;;;OAIG;IACI,YAAY,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe;IAOhE,UAAU,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe,EAAE,KAAK,EAAE,MAAM;IAQ7E,UAAU,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe,EAAE,KAAK,EAAE,MAAM;IAQ7E,SAAS,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,eAAe,EAAE,IAAI,EAAE,MAAM;IAQlF;;;;;;;;;OASG;IACI,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;CAmB7G;AAED;;GAEG;AACH,oBAAY,oBAAoB;IAC9B,6BAA6B;IAC7B,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,eAAe,oBAAoB;IAEnC,wBAAwB;IAExB,WAAW,gBAAgB;IAC3B,UAAU,eAAe;IACzB,uBAAuB,4BAA4B;IAEnD,gBAAgB;IAEhB,cAAc,mBAAmB;IAEjC,qBAAqB;IAGrB,cAAc,mBAAmB;IAEjC,yBAAyB,8BAA8B;IAEvD,wBAAwB,6BAA6B;IAErD,oBAAoB,yBAAyB;IAE7C,2BAA2B,gCAAgC;IAE3D,uBAAuB;IAGvB,mBAAmB,wBAAwB;IAE3C,uBAAuB,4BAA4B;CACpD;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAM,EAAogB,CAAC;AAErjB;;;;GAIG;AACH,qBAEa,QAAS,SAAQ,SAAS,CAAC,QAAQ,CAAC;IAC/C;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,CAAsB;IAEjD,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC;IAE7B,gBAAuB,YAAY,EAAE,eAAe,CAAyB;gBAE1D,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC;IAUhC,EAAE,EAAG,MAAM,CAAC;IAEZ,IAAI,EAAG,MAAM,CAAC;IAEd,KAAK,EAAG,MAAM,CAAC;IAEtB;;OAEG;IACI,QAAQ,EAAG,MAAM,CAAC;IAEzB;;OAEG;IACI,KAAK,EAAG,MAAM,CAAC;IAEtB;;OAEG;IAEI,IAAI,EAAG,MAAM,EAAE,CAAC;IAEvB;;OAEG;IAEI,SAAS,EAAG,QAAQ,CAAC;IAE5B;;OAEG;IAEI,YAAY,EAAG,QAAQ,CAAC;IAE/B;;OAEG;IAEI,SAAS,EAAG,QAAQ,CAAC;IAGrB,WAAW,EAAG,QAAQ,CAAC;IAE9B;;;OAGG;IACI,QAAQ,EAAG,OAAO,CAAC;IAE1B;;;;;OAKG;IAII,QAAQ,EAAG,gBAAgB,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAE3D,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,IAAW,QAAQ,IAAI,OAAO,CAoB7B;IAEM,sBAAsB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,yBAAyB,CAAC,IAAI,CAAC;IAapF,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU;IAO5D;;;;OAIG;IACI,UAAU,CAAC,QAAQ,EAAE,MAAM;IAIlC;;;;;OAKG;IACI,UAAU,CAAC,QAAQ,EAAE,MAAM;IAIlC;;;;;OAKG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM;IAIpC;;;;OAIG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM;IAIpC;;;;OAIG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM;IAIpC;;;;OAIG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM;IAIpC;;;;OAIG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM;IAIpC;;;;OAIG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM;WAItB,UAAU,CAAC,KAAK,EAAE,MAAM;WAMxB,UAAU,CAAC,KAAK,EAAE,MAAM;WAMxB,SAAS,CAAC,IAAI,EAAE,MAAM;IAMpC;;;;;OAKG;WACW,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;CAGxD;AAED;;GAEG;AACH,qBAEa,IAAK,SAAQ,QAAQ;CAAG"}
|
package/lib/cjs/models/User.js
CHANGED
|
@@ -10,7 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
var UserBase_1;
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.User = exports.UserBase = exports.USER_COMMON_METADATA = exports.UserQueryScopes = void 0;
|
|
13
|
+
exports.User = exports.UserBase = exports.USER_SECURITY_METADATA_KEYS = exports.USER_COMMON_METADATA = exports.UserQueryScopes = void 0;
|
|
14
14
|
const luxon_1 = require("luxon");
|
|
15
15
|
const orm_1 = require("@spinajs/orm");
|
|
16
16
|
const di_1 = require("@spinajs/di");
|
|
@@ -41,9 +41,9 @@ class UserQueryScopes {
|
|
|
41
41
|
whereMetadata(key, value) {
|
|
42
42
|
const k = (0, util_1._check_arg)((0, util_1._or)((0, util_1._is_object)((0, util_1._non_nil)()), (0, util_1._is_string)((0, util_1._trim)(), (0, util_1._non_empty)())))(key, 'key');
|
|
43
43
|
const v = (0, util_1._check_arg)((0, util_1._non_nil)())(value, 'value');
|
|
44
|
-
return this.whereExist(
|
|
45
|
-
this.where(
|
|
46
|
-
this.where(
|
|
44
|
+
return this.whereExist('Metadata', function () {
|
|
45
|
+
this.where('Key', k);
|
|
46
|
+
this.where('Value', v);
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
whereUser(userOrEmail) {
|
|
@@ -150,7 +150,28 @@ var USER_COMMON_METADATA;
|
|
|
150
150
|
USER_COMMON_METADATA["USER_PWD_RESET_TOKEN"] = "user:pwd_reset:token";
|
|
151
151
|
// reset password last succesyfull attempt
|
|
152
152
|
USER_COMMON_METADATA["USER_PWD_RESET_LAST_ATTEMPT"] = "user:pwd_reset:last_attempt";
|
|
153
|
+
/** Login throttling */
|
|
154
|
+
// consecutive failed login attempts since the last success
|
|
155
|
+
USER_COMMON_METADATA["USER_LOGIN_ATTEMPTS"] = "user:login:attempts";
|
|
156
|
+
// ISO instant until which authentication is refused for this account
|
|
157
|
+
USER_COMMON_METADATA["USER_LOGIN_LOCKED_UNTIL"] = "user:login:locked_until";
|
|
153
158
|
})(USER_COMMON_METADATA || (exports.USER_COMMON_METADATA = USER_COMMON_METADATA = {}));
|
|
159
|
+
/**
|
|
160
|
+
* Metadata that decides whether somebody gets INTO an account, and therefore must
|
|
161
|
+
* never travel out of one — not to the account owner and not to an administrator
|
|
162
|
+
* reading the record through the API.
|
|
163
|
+
*
|
|
164
|
+
* `user:pwd_reset:token` is the sharp one: it is a bearer credential for
|
|
165
|
+
* `POST /auth/password/reset`, and the reset can be requested for anybody without
|
|
166
|
+
* being logged in at all. Handing it back in a user payload turns "read a user"
|
|
167
|
+
* into "take over that user". Ban and lockout state are here for a smaller reason
|
|
168
|
+
* — they tell an attacker exactly how much of the throttle they have burned.
|
|
169
|
+
*
|
|
170
|
+
* Applied to {@link UserMetadataBase._hiddenKeys} by the rbac bootstrapper, so it
|
|
171
|
+
* covers every `dehydrateWithRelations` in every package. Keys that a client
|
|
172
|
+
* legitimately needs ( avatar, phone, ... ) are deliberately absent.
|
|
173
|
+
*/
|
|
174
|
+
exports.USER_SECURITY_METADATA_KEYS = [USER_COMMON_METADATA.USER_2FA_TOKEN, USER_COMMON_METADATA.USER_PWD_RESET, USER_COMMON_METADATA.USER_PWD_RESET_TOKEN, USER_COMMON_METADATA.USER_PWD_RESET_START_DATE, USER_COMMON_METADATA.USER_PWD_RESET_WAIT_TIME, USER_COMMON_METADATA.USER_PWD_RESET_LAST_ATTEMPT, USER_COMMON_METADATA.USER_BAN_IS_BANNED, USER_COMMON_METADATA.USER_BAN_START_DATE, USER_COMMON_METADATA.USER_BAN_DURATION, USER_COMMON_METADATA.USER_BAN_REASON, USER_COMMON_METADATA.USER_LOGIN_ATTEMPTS, USER_COMMON_METADATA.USER_LOGIN_LOCKED_UNTIL];
|
|
154
175
|
/**
|
|
155
176
|
* Base model for users used by auth and ACL system
|
|
156
177
|
*
|
|
@@ -195,7 +216,7 @@ let UserBase = UserBase_1 = class UserBase extends orm_1.ModelBase {
|
|
|
195
216
|
* Hide meta keys we dont want to show publicly
|
|
196
217
|
*/
|
|
197
218
|
if (base.Metadata) {
|
|
198
|
-
base.Metadata = base.Metadata.filter(m => !UserMetadata_js_1.UserMetadataBase._hiddenKeys.includes(m.Key));
|
|
219
|
+
base.Metadata = base.Metadata.filter((m) => !UserMetadata_js_1.UserMetadataBase._hiddenKeys.includes(m.Key));
|
|
199
220
|
}
|
|
200
221
|
return base;
|
|
201
222
|
}
|
|
@@ -320,7 +341,7 @@ __decorate([
|
|
|
320
341
|
], UserBase.prototype, "LastLoginAt", void 0);
|
|
321
342
|
__decorate([
|
|
322
343
|
(0, orm_1.HasMany)(UserMetadata_js_1.UserMetadataBase, {
|
|
323
|
-
foreignKey:
|
|
344
|
+
foreignKey: 'user_id',
|
|
324
345
|
}),
|
|
325
346
|
__metadata("design:type", orm_1.MetadataRelation)
|
|
326
347
|
], UserBase.prototype, "Metadata", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"User.js","sourceRoot":"","sources":["../../../src/models/User.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,iCAAiC;AACjC,sCAA8O;AAE9O,oCAAiC;AACjC,uDAAmE;AACnE,+BAAoC;AACpC,wCAAwM;AAExM,0DAA8C;AAE9C,MAAa,eAAe;
|
|
1
|
+
{"version":3,"file":"User.js","sourceRoot":"","sources":["../../../src/models/User.ts"],"names":[],"mappings":"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"}
|
package/lib/cjs/session.d.ts
CHANGED
|
@@ -27,6 +27,88 @@ export declare class UserSession implements ISession {
|
|
|
27
27
|
* @param session - the session whose expiry drives the cookie lifetime
|
|
28
28
|
*/
|
|
29
29
|
export declare function sessionCookieMaxAge(session: ISession): number | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Base name of the session cookie, before any `__Host-` / `__Secure-` prefix.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SESSION_COOKIE_BASE_NAME = "ssid";
|
|
34
|
+
/**
|
|
35
|
+
* Everything an application may tune about the session cookie, read from
|
|
36
|
+
* `rbac.session.cookie`. Unknown keys are passed through to express untouched,
|
|
37
|
+
* so `domain`, `path`, `priority`… still work.
|
|
38
|
+
*
|
|
39
|
+
* `httpOnly` and `signed` are deliberately NOT tunable: a session cookie that
|
|
40
|
+
* javascript can read, or that carries no signature, is not a session cookie
|
|
41
|
+
* this package is willing to issue.
|
|
42
|
+
*/
|
|
43
|
+
export interface ISessionCookieConfig {
|
|
44
|
+
/** Base cookie name. Default `ssid`. */
|
|
45
|
+
name?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Emit the cookie as `__Host-<name>`. The prefix is only honored by browsers
|
|
48
|
+
* when the cookie is `Secure`, has `Path=/` and carries no `Domain`, so
|
|
49
|
+
* enabling it forces exactly that and drops any configured `domain`.
|
|
50
|
+
*/
|
|
51
|
+
hostPrefix?: boolean;
|
|
52
|
+
/** Default `true`. Set false ONLY for local http development. */
|
|
53
|
+
secure?: boolean;
|
|
54
|
+
/** Default `strict`. */
|
|
55
|
+
sameSite?: 'strict' | 'lax' | 'none' | boolean;
|
|
56
|
+
[key: string]: unknown;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Name the session cookie is issued and read under.
|
|
60
|
+
*
|
|
61
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
62
|
+
*/
|
|
63
|
+
export declare function sessionCookieName(config?: ISessionCookieConfig): string;
|
|
64
|
+
/**
|
|
65
|
+
* Cookie options for the session cookie.
|
|
66
|
+
*
|
|
67
|
+
* Application configuration is applied FIRST and the security-critical flags
|
|
68
|
+
* last, so a stray `httpOnly: false` in an app config cannot downgrade the
|
|
69
|
+
* cookie — previously every call site spread the config after its own hardening
|
|
70
|
+
* and the config won. `secure` and `sameSite` stay tunable ( http development
|
|
71
|
+
* needs `secure: false` ) but default to the hardened value rather than to
|
|
72
|
+
* whatever the browser assumes.
|
|
73
|
+
*
|
|
74
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
75
|
+
* @param maxAge - cookie lifetime in ms; `undefined` = browser-session cookie
|
|
76
|
+
*/
|
|
77
|
+
export declare function sessionCookieOptions(config?: ISessionCookieConfig, maxAge?: number): Record<string, unknown>;
|
|
78
|
+
/**
|
|
79
|
+
* Session cookie in the shape the http `Coockies` response option accepts.
|
|
80
|
+
*/
|
|
81
|
+
export interface ISessionCookieDescriptor {
|
|
82
|
+
Name: string;
|
|
83
|
+
Value: string;
|
|
84
|
+
Options: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Descriptor of the session cookie carrying an active session, in the shape the
|
|
88
|
+
* http `Coockies` response option accepts.
|
|
89
|
+
*
|
|
90
|
+
* @param session - session whose id and expiration the cookie carries
|
|
91
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
92
|
+
*/
|
|
93
|
+
export declare function sessionCookie(session: ISession, config?: ISessionCookieConfig): ISessionCookieDescriptor;
|
|
94
|
+
/**
|
|
95
|
+
* Descriptor of an already-expired session cookie — clears the session client
|
|
96
|
+
* side on logout.
|
|
97
|
+
*
|
|
98
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
99
|
+
*/
|
|
100
|
+
export declare function clearSessionCookie(config?: ISessionCookieConfig): ISessionCookieDescriptor;
|
|
101
|
+
/**
|
|
102
|
+
* Stable, non-reversible handle for a session id.
|
|
103
|
+
*
|
|
104
|
+
* Session ids must never reach a log file or a response body — a leaked log is
|
|
105
|
+
* then a leaked account. The hash correlates entries across the session's life
|
|
106
|
+
* and identifies a session in the "active devices" API without handing the
|
|
107
|
+
* caller a usable credential for it.
|
|
108
|
+
*
|
|
109
|
+
* @param sessionId - raw session id
|
|
110
|
+
*/
|
|
111
|
+
export declare function hashSessionId(sessionId: string): string;
|
|
30
112
|
/**
|
|
31
113
|
* Session-fixation protection helper. Mints a NEW session id, copies the
|
|
32
114
|
* ownership identity and data across, deletes the old id and persists the new
|
package/lib/cjs/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|
package/lib/cjs/session.js
CHANGED
|
@@ -9,10 +9,16 @@ 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
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.MemorySessionStore = exports.UserSession = void 0;
|
|
12
|
+
exports.MemorySessionStore = exports.SESSION_COOKIE_BASE_NAME = exports.UserSession = void 0;
|
|
13
13
|
exports.sessionCookieMaxAge = sessionCookieMaxAge;
|
|
14
|
+
exports.sessionCookieName = sessionCookieName;
|
|
15
|
+
exports.sessionCookieOptions = sessionCookieOptions;
|
|
16
|
+
exports.sessionCookie = sessionCookie;
|
|
17
|
+
exports.clearSessionCookie = clearSessionCookie;
|
|
18
|
+
exports.hashSessionId = hashSessionId;
|
|
14
19
|
exports.regenerateSession = regenerateSession;
|
|
15
20
|
const luxon_1 = require("luxon");
|
|
21
|
+
const crypto_1 = require("crypto");
|
|
16
22
|
const interfaces_js_1 = require("./interfaces.js");
|
|
17
23
|
const di_1 = require("@spinajs/di");
|
|
18
24
|
const uuid_1 = require("uuid");
|
|
@@ -53,6 +59,104 @@ function sessionCookieMaxAge(session) {
|
|
|
53
59
|
}
|
|
54
60
|
return Math.max(0, Math.floor(session.Expiration.diff(luxon_1.DateTime.now()).milliseconds));
|
|
55
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Base name of the session cookie, before any `__Host-` / `__Secure-` prefix.
|
|
64
|
+
*/
|
|
65
|
+
exports.SESSION_COOKIE_BASE_NAME = 'ssid';
|
|
66
|
+
/** Keys consumed by this module rather than handed to express. */
|
|
67
|
+
const COOKIE_CONTROL_KEYS = ['name', 'hostPrefix'];
|
|
68
|
+
/**
|
|
69
|
+
* Name the session cookie is issued and read under.
|
|
70
|
+
*
|
|
71
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
72
|
+
*/
|
|
73
|
+
function sessionCookieName(config = {}) {
|
|
74
|
+
const base = config.name ?? exports.SESSION_COOKIE_BASE_NAME;
|
|
75
|
+
return config.hostPrefix ? `__Host-${base}` : base;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Cookie options for the session cookie.
|
|
79
|
+
*
|
|
80
|
+
* Application configuration is applied FIRST and the security-critical flags
|
|
81
|
+
* last, so a stray `httpOnly: false` in an app config cannot downgrade the
|
|
82
|
+
* cookie — previously every call site spread the config after its own hardening
|
|
83
|
+
* and the config won. `secure` and `sameSite` stay tunable ( http development
|
|
84
|
+
* needs `secure: false` ) but default to the hardened value rather than to
|
|
85
|
+
* whatever the browser assumes.
|
|
86
|
+
*
|
|
87
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
88
|
+
* @param maxAge - cookie lifetime in ms; `undefined` = browser-session cookie
|
|
89
|
+
*/
|
|
90
|
+
function sessionCookieOptions(config = {}, maxAge) {
|
|
91
|
+
const passthrough = {};
|
|
92
|
+
for (const [key, value] of Object.entries(config)) {
|
|
93
|
+
if (!COOKIE_CONTROL_KEYS.includes(key)) {
|
|
94
|
+
passthrough[key] = value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const options = {
|
|
98
|
+
...passthrough,
|
|
99
|
+
httpOnly: true,
|
|
100
|
+
secure: config.secure ?? true,
|
|
101
|
+
sameSite: config.sameSite ?? 'strict',
|
|
102
|
+
maxAge,
|
|
103
|
+
};
|
|
104
|
+
// A `__Host-` cookie is rejected by the browser unless it is Secure, rooted at
|
|
105
|
+
// `/` and has no Domain. Enforce the whole set rather than emitting a cookie
|
|
106
|
+
// the client will silently drop.
|
|
107
|
+
if (config.hostPrefix) {
|
|
108
|
+
options.secure = true;
|
|
109
|
+
options.path = '/';
|
|
110
|
+
delete options.domain;
|
|
111
|
+
}
|
|
112
|
+
return options;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Descriptor of the session cookie carrying an active session, in the shape the
|
|
116
|
+
* http `Coockies` response option accepts.
|
|
117
|
+
*
|
|
118
|
+
* @param session - session whose id and expiration the cookie carries
|
|
119
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
120
|
+
*/
|
|
121
|
+
function sessionCookie(session, config = {}) {
|
|
122
|
+
return {
|
|
123
|
+
Name: sessionCookieName(config),
|
|
124
|
+
Value: session.SessionId,
|
|
125
|
+
Options: {
|
|
126
|
+
...sessionCookieOptions(config, sessionCookieMaxAge(session)),
|
|
127
|
+
signed: true,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Descriptor of an already-expired session cookie — clears the session client
|
|
133
|
+
* side on logout.
|
|
134
|
+
*
|
|
135
|
+
* @param config - the `rbac.session.cookie` configuration block
|
|
136
|
+
*/
|
|
137
|
+
function clearSessionCookie(config = {}) {
|
|
138
|
+
return {
|
|
139
|
+
Name: sessionCookieName(config),
|
|
140
|
+
Value: '',
|
|
141
|
+
Options: {
|
|
142
|
+
...sessionCookieOptions(config, 0),
|
|
143
|
+
signed: false,
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Stable, non-reversible handle for a session id.
|
|
149
|
+
*
|
|
150
|
+
* Session ids must never reach a log file or a response body — a leaked log is
|
|
151
|
+
* then a leaked account. The hash correlates entries across the session's life
|
|
152
|
+
* and identifies a session in the "active devices" API without handing the
|
|
153
|
+
* caller a usable credential for it.
|
|
154
|
+
*
|
|
155
|
+
* @param sessionId - raw session id
|
|
156
|
+
*/
|
|
157
|
+
function hashSessionId(sessionId) {
|
|
158
|
+
return (0, crypto_1.createHash)('sha256').update(`spinajs:session:${sessionId}`).digest('hex').substring(0, 32);
|
|
159
|
+
}
|
|
56
160
|
/**
|
|
57
161
|
* Session-fixation protection helper. Mints a NEW session id, copies the
|
|
58
162
|
* ownership identity and data across, deletes the old id and persists the new
|
package/lib/cjs/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|
package/lib/cjs/util.d.ts
CHANGED
|
@@ -3,12 +3,31 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @param role - The role for which grants need to be resolved.
|
|
5
5
|
* @param grants - An object containing all roles and their associated grants.
|
|
6
|
+
* @param seen - Roles already visited on this branch; guards against cyclic `$extend`.
|
|
6
7
|
* @returns An object representing the combined grants for the given role and its inherited roles.
|
|
7
8
|
*
|
|
8
9
|
* This function resolves the `$extend` property in the grants object to include
|
|
9
10
|
* permissions from inherited roles, merging them into a single object.
|
|
11
|
+
*
|
|
12
|
+
* Inherited roles are merged first and the role's own grants last, so the role always wins
|
|
13
|
+
* on a conflicting action — the same precedence accesscontrol applies when it resolves
|
|
14
|
+
* `$extend` itself. The result mirrors what `ac.can(role)` answers server-side; it is what
|
|
15
|
+
* gets shipped to clients that rebuild an ACL from it.
|
|
10
16
|
*/
|
|
11
17
|
export declare const _unwindGrants: (role: string, grants: {
|
|
12
18
|
[key: string]: any;
|
|
13
|
-
}) =>
|
|
19
|
+
}, seen?: Set<string>) => {
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Combines already unwound grant sets — eg. one per role of a multi-role user — into a single
|
|
24
|
+
* map, merging per action for the same reason `_unwindGrants` does.
|
|
25
|
+
*
|
|
26
|
+
* @param grants - unwound grant maps; later entries win on a conflicting action
|
|
27
|
+
*/
|
|
28
|
+
export declare const _combineGrants: (...grants: {
|
|
29
|
+
[key: string]: any;
|
|
30
|
+
}[]) => {
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
};
|
|
14
33
|
//# sourceMappingURL=util.d.ts.map
|
package/lib/cjs/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AA6BA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,QAAQ;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAAE,OAAM,GAAG,CAAC,MAAM,CAAa;;CAiBxG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,GAAG,QAAQ;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAAE;;CAEjE,CAAA"}
|
package/lib/cjs/util.js
CHANGED
|
@@ -1,26 +1,67 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._unwindGrants = void 0;
|
|
3
|
+
exports._combineGrants = exports._unwindGrants = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Merges a grants fragment into an accumulator, one resource at a time.
|
|
6
|
+
*
|
|
7
|
+
* A plain object spread merges at the RESOURCE level, so a later fragment that names a
|
|
8
|
+
* resource replaces the whole action map already collected for it. Grants have to merge one
|
|
9
|
+
* level deeper — per action — otherwise a role that adds `create:any` to a resource an
|
|
10
|
+
* inherited role also grants loses that action entirely.
|
|
11
|
+
*
|
|
12
|
+
* `$extend` is bookkeeping for the caller, not a resource, so it never reaches the output.
|
|
13
|
+
*
|
|
14
|
+
* @param base - accumulated grants
|
|
15
|
+
* @param add - fragment to merge in; its actions win on conflict
|
|
16
|
+
* @returns a new object, neither argument is mutated
|
|
17
|
+
*/
|
|
18
|
+
const _mergeResourceGrants = (base, add) => {
|
|
19
|
+
const merged = { ...base };
|
|
20
|
+
for (const [resource, actions] of Object.entries(add)) {
|
|
21
|
+
if (resource === '$extend') {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
merged[resource] = { ...(merged[resource] ?? {}), ...actions };
|
|
25
|
+
}
|
|
26
|
+
return merged;
|
|
27
|
+
};
|
|
4
28
|
/**
|
|
5
29
|
* Recursively unwinds and combines grants for a given role, including inherited roles.
|
|
6
30
|
*
|
|
7
31
|
* @param role - The role for which grants need to be resolved.
|
|
8
32
|
* @param grants - An object containing all roles and their associated grants.
|
|
33
|
+
* @param seen - Roles already visited on this branch; guards against cyclic `$extend`.
|
|
9
34
|
* @returns An object representing the combined grants for the given role and its inherited roles.
|
|
10
35
|
*
|
|
11
36
|
* This function resolves the `$extend` property in the grants object to include
|
|
12
37
|
* permissions from inherited roles, merging them into a single object.
|
|
38
|
+
*
|
|
39
|
+
* Inherited roles are merged first and the role's own grants last, so the role always wins
|
|
40
|
+
* on a conflicting action — the same precedence accesscontrol applies when it resolves
|
|
41
|
+
* `$extend` itself. The result mirrors what `ac.can(role)` answers server-side; it is what
|
|
42
|
+
* gets shipped to clients that rebuild an ACL from it.
|
|
13
43
|
*/
|
|
14
|
-
const _unwindGrants = (role, grants) => {
|
|
44
|
+
const _unwindGrants = (role, grants, seen = new Set()) => {
|
|
45
|
+
// a role reachable twice contributes the same grants both times, so skipping it only
|
|
46
|
+
// stops the recursion from looping forever on a cyclic $extend
|
|
47
|
+
if (seen.has(role)) {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
seen.add(role);
|
|
15
51
|
const roleGrants = grants[role] || {};
|
|
16
52
|
const inheritedRoles = roleGrants['$extend'] || [];
|
|
17
|
-
|
|
18
|
-
return
|
|
19
|
-
return {
|
|
20
|
-
...acc,
|
|
21
|
-
...(0, exports._unwindGrants)(inheritedRole, grants),
|
|
22
|
-
};
|
|
23
|
-
}, roleGrants);
|
|
53
|
+
const inherited = inheritedRoles.reduce((acc, inheritedRole) => _mergeResourceGrants(acc, (0, exports._unwindGrants)(inheritedRole, grants, seen)), {});
|
|
54
|
+
return _mergeResourceGrants(inherited, roleGrants);
|
|
24
55
|
};
|
|
25
56
|
exports._unwindGrants = _unwindGrants;
|
|
57
|
+
/**
|
|
58
|
+
* Combines already unwound grant sets — eg. one per role of a multi-role user — into a single
|
|
59
|
+
* map, merging per action for the same reason `_unwindGrants` does.
|
|
60
|
+
*
|
|
61
|
+
* @param grants - unwound grant maps; later entries win on a conflicting action
|
|
62
|
+
*/
|
|
63
|
+
const _combineGrants = (...grants) => {
|
|
64
|
+
return grants.reduce((acc, g) => _mergeResourceGrants(acc, g), {});
|
|
65
|
+
};
|
|
66
|
+
exports._combineGrants = _combineGrants;
|
|
26
67
|
//# sourceMappingURL=util.js.map
|
package/lib/cjs/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":";;;AACA
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":";;;AACA;;;;;;;;;;;;;GAaG;AACH,MAAM,oBAAoB,GAAG,CAAC,IAA4B,EAAE,GAA2B,EAAE,EAAE;IACvF,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,SAAS;QACb,CAAC;QAED,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;IACnE,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACI,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,MAA8B,EAAE,OAAoB,IAAI,GAAG,EAAE,EAAE,EAAE;IACzG,qFAAqF;IACrF,+DAA+D;IAC/D,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC;IACd,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEf,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,cAAc,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAEnD,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CACnC,CAAC,GAAQ,EAAE,aAAkB,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,EAAE,IAAA,qBAAa,EAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,EACvG,EAAE,CACL,CAAC;IAEF,OAAO,oBAAoB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AACvD,CAAC,CAAA;AAjBY,QAAA,aAAa,iBAiBzB;AAED;;;;;GAKG;AACI,MAAM,cAAc,GAAG,CAAC,GAAG,MAAgC,EAAE,EAAE;IAClE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACvE,CAAC,CAAA;AAFY,QAAA,cAAc,kBAE1B"}
|