@stratal/framework 0.0.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.
- package/LICENSE +21 -0
- package/README.md +88 -0
- package/dist/auth/auth.module.d.ts +37 -0
- package/dist/auth/auth.module.d.ts.map +1 -0
- package/dist/auth/auth.module.js +74 -0
- package/dist/auth/auth.module.js.map +1 -0
- package/dist/auth/auth.tokens.d.ts +5 -0
- package/dist/auth/auth.tokens.d.ts.map +1 -0
- package/dist/auth/auth.tokens.js +5 -0
- package/dist/auth/auth.tokens.js.map +1 -0
- package/dist/auth/errors/auth-errors.d.ts +74 -0
- package/dist/auth/errors/auth-errors.d.ts.map +1 -0
- package/dist/auth/errors/auth-errors.js +122 -0
- package/dist/auth/errors/auth-errors.js.map +1 -0
- package/dist/auth/errors/index.d.ts +5 -0
- package/dist/auth/errors/index.d.ts.map +1 -0
- package/dist/auth/errors/index.js +5 -0
- package/dist/auth/errors/index.js.map +1 -0
- package/dist/auth/errors/invalid-token.error.d.ts +5 -0
- package/dist/auth/errors/invalid-token.error.d.ts.map +1 -0
- package/dist/auth/errors/invalid-token.error.js +7 -0
- package/dist/auth/errors/invalid-token.error.js.map +1 -0
- package/dist/auth/errors/token-required.error.d.ts +5 -0
- package/dist/auth/errors/token-required.error.d.ts.map +1 -0
- package/dist/auth/errors/token-required.error.js +7 -0
- package/dist/auth/errors/token-required.error.js.map +1 -0
- package/dist/auth/errors/verification-failed.error.d.ts +5 -0
- package/dist/auth/errors/verification-failed.error.d.ts.map +1 -0
- package/dist/auth/errors/verification-failed.error.js +7 -0
- package/dist/auth/errors/verification-failed.error.js.map +1 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +7 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware/auth-context.middleware.d.ts +12 -0
- package/dist/auth/middleware/auth-context.middleware.d.ts.map +1 -0
- package/dist/auth/middleware/auth-context.middleware.js +28 -0
- package/dist/auth/middleware/auth-context.middleware.js.map +1 -0
- package/dist/auth/middleware/index.d.ts +3 -0
- package/dist/auth/middleware/index.d.ts.map +1 -0
- package/dist/auth/middleware/index.js +3 -0
- package/dist/auth/middleware/index.js.map +1 -0
- package/dist/auth/middleware/session-verification.middleware.d.ts +18 -0
- package/dist/auth/middleware/session-verification.middleware.d.ts.map +1 -0
- package/dist/auth/middleware/session-verification.middleware.js +48 -0
- package/dist/auth/middleware/session-verification.middleware.js.map +1 -0
- package/dist/auth/services/auth.service.d.ts +32 -0
- package/dist/auth/services/auth.service.d.ts.map +1 -0
- package/dist/auth/services/auth.service.js +62 -0
- package/dist/auth/services/auth.service.js.map +1 -0
- package/dist/auth/services/index.d.ts +2 -0
- package/dist/auth/services/index.d.ts.map +1 -0
- package/dist/auth/services/index.js +2 -0
- package/dist/auth/services/index.js.map +1 -0
- package/dist/auth/utils/auth-helpers.d.ts +11 -0
- package/dist/auth/utils/auth-helpers.d.ts.map +1 -0
- package/dist/auth/utils/auth-helpers.js +31 -0
- package/dist/auth/utils/auth-helpers.js.map +1 -0
- package/dist/auth/utils/better-auth-error-handler.d.ts +11 -0
- package/dist/auth/utils/better-auth-error-handler.d.ts.map +1 -0
- package/dist/auth/utils/better-auth-error-handler.js +95 -0
- package/dist/auth/utils/better-auth-error-handler.js.map +1 -0
- package/dist/auth/utils/index.d.ts +3 -0
- package/dist/auth/utils/index.d.ts.map +1 -0
- package/dist/auth/utils/index.js +3 -0
- package/dist/auth/utils/index.js.map +1 -0
- package/dist/context/auth-context.d.ts +35 -0
- package/dist/context/auth-context.d.ts.map +1 -0
- package/dist/context/auth-context.js +65 -0
- package/dist/context/auth-context.js.map +1 -0
- package/dist/context/errors/context-not-initialized.error.d.ts +5 -0
- package/dist/context/errors/context-not-initialized.error.d.ts.map +1 -0
- package/dist/context/errors/context-not-initialized.error.js +7 -0
- package/dist/context/errors/context-not-initialized.error.js.map +1 -0
- package/dist/context/errors/index.d.ts +4 -0
- package/dist/context/errors/index.d.ts.map +1 -0
- package/dist/context/errors/index.js +4 -0
- package/dist/context/errors/index.js.map +1 -0
- package/dist/context/errors/user-not-authenticated.error.d.ts +5 -0
- package/dist/context/errors/user-not-authenticated.error.d.ts.map +1 -0
- package/dist/context/errors/user-not-authenticated.error.js +7 -0
- package/dist/context/errors/user-not-authenticated.error.js.map +1 -0
- package/dist/context/errors/user-not-authorized.error.d.ts +5 -0
- package/dist/context/errors/user-not-authorized.error.d.ts.map +1 -0
- package/dist/context/errors/user-not-authorized.error.js +7 -0
- package/dist/context/errors/user-not-authorized.error.js.map +1 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +3 -0
- package/dist/context/index.js.map +1 -0
- package/dist/database/custom-pg-types.d.ts +21 -0
- package/dist/database/custom-pg-types.d.ts.map +1 -0
- package/dist/database/custom-pg-types.js +41 -0
- package/dist/database/custom-pg-types.js.map +1 -0
- package/dist/database/database.helpers.d.ts +18 -0
- package/dist/database/database.helpers.d.ts.map +1 -0
- package/dist/database/database.helpers.js +27 -0
- package/dist/database/database.helpers.js.map +1 -0
- package/dist/database/database.module.d.ts +21 -0
- package/dist/database/database.module.d.ts.map +1 -0
- package/dist/database/database.module.js +62 -0
- package/dist/database/database.module.js.map +1 -0
- package/dist/database/database.service.d.ts +18 -0
- package/dist/database/database.service.d.ts.map +1 -0
- package/dist/database/database.service.js +2 -0
- package/dist/database/database.service.js.map +1 -0
- package/dist/database/database.tokens.d.ts +6 -0
- package/dist/database/database.tokens.d.ts.map +1 -0
- package/dist/database/database.tokens.js +8 -0
- package/dist/database/database.tokens.js.map +1 -0
- package/dist/database/decorators/inject-db.decorator.d.ts +3 -0
- package/dist/database/decorators/inject-db.decorator.d.ts.map +1 -0
- package/dist/database/decorators/inject-db.decorator.js +6 -0
- package/dist/database/decorators/inject-db.decorator.js.map +1 -0
- package/dist/database/errors/database-config.error.d.ts +5 -0
- package/dist/database/errors/database-config.error.d.ts.map +1 -0
- package/dist/database/errors/database-config.error.js +8 -0
- package/dist/database/errors/database-config.error.js.map +1 -0
- package/dist/database/errors/database-error.d.ts +14 -0
- package/dist/database/errors/database-error.d.ts.map +1 -0
- package/dist/database/errors/database-error.js +20 -0
- package/dist/database/errors/database-error.js.map +1 -0
- package/dist/database/errors/foreign-key-constraint.error.d.ts +14 -0
- package/dist/database/errors/foreign-key-constraint.error.d.ts.map +1 -0
- package/dist/database/errors/foreign-key-constraint.error.js +19 -0
- package/dist/database/errors/foreign-key-constraint.error.js.map +1 -0
- package/dist/database/errors/from-zenstack-error.d.ts +22 -0
- package/dist/database/errors/from-zenstack-error.d.ts.map +1 -0
- package/dist/database/errors/from-zenstack-error.js +114 -0
- package/dist/database/errors/from-zenstack-error.js.map +1 -0
- package/dist/database/errors/index.d.ts +8 -0
- package/dist/database/errors/index.d.ts.map +1 -0
- package/dist/database/errors/index.js +8 -0
- package/dist/database/errors/index.js.map +1 -0
- package/dist/database/errors/invalid-error-code-range.error.d.ts +12 -0
- package/dist/database/errors/invalid-error-code-range.error.d.ts.map +1 -0
- package/dist/database/errors/invalid-error-code-range.error.js +14 -0
- package/dist/database/errors/invalid-error-code-range.error.js.map +1 -0
- package/dist/database/errors/record-not-found.error.d.ts +15 -0
- package/dist/database/errors/record-not-found.error.d.ts.map +1 -0
- package/dist/database/errors/record-not-found.error.js +20 -0
- package/dist/database/errors/record-not-found.error.js.map +1 -0
- package/dist/database/errors/unique-constraint.error.d.ts +15 -0
- package/dist/database/errors/unique-constraint.error.d.ts.map +1 -0
- package/dist/database/errors/unique-constraint.error.js +20 -0
- package/dist/database/errors/unique-constraint.error.js.map +1 -0
- package/dist/database/event-types.d.ts +144 -0
- package/dist/database/event-types.d.ts.map +1 -0
- package/dist/database/event-types.js +13 -0
- package/dist/database/event-types.js.map +1 -0
- package/dist/database/index.d.ts +10 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +10 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/plugins/error-handler.plugin.d.ts +21 -0
- package/dist/database/plugins/error-handler.plugin.d.ts.map +1 -0
- package/dist/database/plugins/error-handler.plugin.js +24 -0
- package/dist/database/plugins/error-handler.plugin.js.map +1 -0
- package/dist/database/plugins/event-emitter.plugin.d.ts +37 -0
- package/dist/database/plugins/event-emitter.plugin.d.ts.map +1 -0
- package/dist/database/plugins/event-emitter.plugin.js +43 -0
- package/dist/database/plugins/event-emitter.plugin.js.map +1 -0
- package/dist/database/plugins/index.d.ts +4 -0
- package/dist/database/plugins/index.d.ts.map +1 -0
- package/dist/database/plugins/index.js +4 -0
- package/dist/database/plugins/index.js.map +1 -0
- package/dist/database/plugins/schema-switcher.plugin.d.ts +32 -0
- package/dist/database/plugins/schema-switcher.plugin.d.ts.map +1 -0
- package/dist/database/plugins/schema-switcher.plugin.js +27 -0
- package/dist/database/plugins/schema-switcher.plugin.js.map +1 -0
- package/dist/database/types.d.ts +51 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +2 -0
- package/dist/database/types.js.map +1 -0
- package/dist/factory/factory.d.ts +56 -0
- package/dist/factory/factory.d.ts.map +1 -0
- package/dist/factory/factory.js +86 -0
- package/dist/factory/factory.js.map +1 -0
- package/dist/factory/index.d.ts +3 -0
- package/dist/factory/index.d.ts.map +1 -0
- package/dist/factory/index.js +3 -0
- package/dist/factory/index.js.map +1 -0
- package/dist/factory/sequence.d.ts +38 -0
- package/dist/factory/sequence.d.ts.map +1 -0
- package/dist/factory/sequence.js +54 -0
- package/dist/factory/sequence.js.map +1 -0
- package/dist/guards/auth.guard.d.ts +33 -0
- package/dist/guards/auth.guard.d.ts.map +1 -0
- package/dist/guards/auth.guard.js +99 -0
- package/dist/guards/auth.guard.js.map +1 -0
- package/dist/guards/index.d.ts +3 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/guards/index.js +5 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/rbac/adapters/custom-zenstack-adapter.d.ts +61 -0
- package/dist/rbac/adapters/custom-zenstack-adapter.d.ts.map +1 -0
- package/dist/rbac/adapters/custom-zenstack-adapter.js +159 -0
- package/dist/rbac/adapters/custom-zenstack-adapter.js.map +1 -0
- package/dist/rbac/adapters/index.d.ts +2 -0
- package/dist/rbac/adapters/index.d.ts.map +1 -0
- package/dist/rbac/adapters/index.js +2 -0
- package/dist/rbac/adapters/index.js.map +1 -0
- package/dist/rbac/constants.d.ts +8 -0
- package/dist/rbac/constants.d.ts.map +1 -0
- package/dist/rbac/constants.js +8 -0
- package/dist/rbac/constants.js.map +1 -0
- package/dist/rbac/errors/index.d.ts +2 -0
- package/dist/rbac/errors/index.d.ts.map +1 -0
- package/dist/rbac/errors/index.js +2 -0
- package/dist/rbac/errors/index.js.map +1 -0
- package/dist/rbac/errors/insufficient-permissions.error.d.ts +14 -0
- package/dist/rbac/errors/insufficient-permissions.error.d.ts.map +1 -0
- package/dist/rbac/errors/insufficient-permissions.error.js +19 -0
- package/dist/rbac/errors/insufficient-permissions.error.js.map +1 -0
- package/dist/rbac/index.d.ts +9 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +8 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/rbac.module.d.ts +26 -0
- package/dist/rbac/rbac.module.d.ts.map +1 -0
- package/dist/rbac/rbac.module.js +62 -0
- package/dist/rbac/rbac.module.js.map +1 -0
- package/dist/rbac/services/casbin-enforcer.service.d.ts +37 -0
- package/dist/rbac/services/casbin-enforcer.service.d.ts.map +1 -0
- package/dist/rbac/services/casbin-enforcer.service.js +86 -0
- package/dist/rbac/services/casbin-enforcer.service.js.map +1 -0
- package/dist/rbac/services/casbin.service.d.ts +37 -0
- package/dist/rbac/services/casbin.service.d.ts.map +1 -0
- package/dist/rbac/services/casbin.service.js +174 -0
- package/dist/rbac/services/casbin.service.js.map +1 -0
- package/dist/rbac/services/index.d.ts +3 -0
- package/dist/rbac/services/index.d.ts.map +1 -0
- package/dist/rbac/services/index.js +3 -0
- package/dist/rbac/services/index.js.map +1 -0
- package/dist/rbac/tokens.d.ts +10 -0
- package/dist/rbac/tokens.d.ts.map +1 -0
- package/dist/rbac/tokens.js +10 -0
- package/dist/rbac/tokens.js.map +1 -0
- package/dist/rbac/types.d.ts +12 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +2 -0
- package/dist/rbac/types.js.map +1 -0
- package/package.json +118 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { inject } from 'tsyringe';
|
|
14
|
+
import { Transient, DI_TOKENS } from 'stratal/di';
|
|
15
|
+
import { RBAC_TOKENS } from '../tokens';
|
|
16
|
+
import { CasbinEnforcerService } from './casbin-enforcer.service';
|
|
17
|
+
/**
|
|
18
|
+
* CasbinService
|
|
19
|
+
*
|
|
20
|
+
* Request-scoped service that provides the full Casbin RBAC API.
|
|
21
|
+
* Uses AuthContext to get the current user.
|
|
22
|
+
*/
|
|
23
|
+
let CasbinService = class CasbinService {
|
|
24
|
+
context;
|
|
25
|
+
enforcerService;
|
|
26
|
+
constructor(context, enforcerService) {
|
|
27
|
+
this.context = context;
|
|
28
|
+
this.enforcerService = enforcerService;
|
|
29
|
+
}
|
|
30
|
+
async getEnforcer() {
|
|
31
|
+
return this.enforcerService.getEnforcer();
|
|
32
|
+
}
|
|
33
|
+
// ==================== USER-ROLE MANAGEMENT ====================
|
|
34
|
+
async addRoleForUser(userId, role) {
|
|
35
|
+
const enforcer = await this.getEnforcer();
|
|
36
|
+
const added = await enforcer.addRoleForUser(userId, role);
|
|
37
|
+
if (added)
|
|
38
|
+
await enforcer.savePolicy();
|
|
39
|
+
return added;
|
|
40
|
+
}
|
|
41
|
+
async deleteRoleForUser(userId, role) {
|
|
42
|
+
const enforcer = await this.getEnforcer();
|
|
43
|
+
const deleted = await enforcer.deleteRoleForUser(userId, role);
|
|
44
|
+
if (deleted)
|
|
45
|
+
await enforcer.savePolicy();
|
|
46
|
+
return deleted;
|
|
47
|
+
}
|
|
48
|
+
async deleteRolesForUser(userId) {
|
|
49
|
+
const enforcer = await this.getEnforcer();
|
|
50
|
+
const deleted = await enforcer.deleteRolesForUser(userId);
|
|
51
|
+
if (deleted)
|
|
52
|
+
await enforcer.savePolicy();
|
|
53
|
+
return deleted;
|
|
54
|
+
}
|
|
55
|
+
async getRolesForUser(userId) {
|
|
56
|
+
const enforcer = await this.getEnforcer();
|
|
57
|
+
return enforcer.getRolesForUser(userId);
|
|
58
|
+
}
|
|
59
|
+
async getImplicitRolesForUser(userId) {
|
|
60
|
+
const enforcer = await this.getEnforcer();
|
|
61
|
+
return enforcer.getImplicitRolesForUser(userId);
|
|
62
|
+
}
|
|
63
|
+
async getUsersForRole(role) {
|
|
64
|
+
const enforcer = await this.getEnforcer();
|
|
65
|
+
return enforcer.getUsersForRole(role);
|
|
66
|
+
}
|
|
67
|
+
async getImplicitUsersForRole(role) {
|
|
68
|
+
const enforcer = await this.getEnforcer();
|
|
69
|
+
return enforcer.getImplicitUsersForRole(role);
|
|
70
|
+
}
|
|
71
|
+
async hasRoleForUser(userId, role) {
|
|
72
|
+
const enforcer = await this.getEnforcer();
|
|
73
|
+
return enforcer.hasRoleForUser(userId, role);
|
|
74
|
+
}
|
|
75
|
+
// ==================== ROLE HIERARCHY MANAGEMENT ====================
|
|
76
|
+
async addRoleInheritance(childRole, parentRole) {
|
|
77
|
+
const enforcer = await this.getEnforcer();
|
|
78
|
+
const added = await enforcer.addGroupingPolicy(childRole, parentRole);
|
|
79
|
+
if (added)
|
|
80
|
+
await enforcer.savePolicy();
|
|
81
|
+
return added;
|
|
82
|
+
}
|
|
83
|
+
async deleteRoleInheritance(childRole, parentRole) {
|
|
84
|
+
const enforcer = await this.getEnforcer();
|
|
85
|
+
const deleted = await enforcer.removeGroupingPolicy(childRole, parentRole);
|
|
86
|
+
if (deleted)
|
|
87
|
+
await enforcer.savePolicy();
|
|
88
|
+
return deleted;
|
|
89
|
+
}
|
|
90
|
+
// ==================== USER/ROLE DELETION ====================
|
|
91
|
+
async deleteUser(userId) {
|
|
92
|
+
const enforcer = await this.getEnforcer();
|
|
93
|
+
const deleted = await enforcer.deleteUser(userId);
|
|
94
|
+
if (deleted)
|
|
95
|
+
await enforcer.savePolicy();
|
|
96
|
+
return deleted;
|
|
97
|
+
}
|
|
98
|
+
async deleteRole(role) {
|
|
99
|
+
const enforcer = await this.getEnforcer();
|
|
100
|
+
const deleted = await enforcer.deleteRole(role);
|
|
101
|
+
if (deleted)
|
|
102
|
+
await enforcer.savePolicy();
|
|
103
|
+
return deleted;
|
|
104
|
+
}
|
|
105
|
+
// ==================== CONVENIENCE METHODS ====================
|
|
106
|
+
async getCurrentUserRoles() {
|
|
107
|
+
const userId = this.context.getUserId();
|
|
108
|
+
if (!userId)
|
|
109
|
+
return [];
|
|
110
|
+
return this.getImplicitRolesForUser(userId);
|
|
111
|
+
}
|
|
112
|
+
async currentUserHasRole(role) {
|
|
113
|
+
const roles = await this.getCurrentUserRoles();
|
|
114
|
+
return roles.includes(role);
|
|
115
|
+
}
|
|
116
|
+
async setRolesForUser(userId, roles) {
|
|
117
|
+
const enforcer = await this.getEnforcer();
|
|
118
|
+
await enforcer.deleteRolesForUser(userId);
|
|
119
|
+
for (const role of roles) {
|
|
120
|
+
await enforcer.addRoleForUser(userId, role);
|
|
121
|
+
}
|
|
122
|
+
await enforcer.savePolicy();
|
|
123
|
+
}
|
|
124
|
+
// ==================== PERMISSION CHECKING ====================
|
|
125
|
+
async hasPermission(userId, scope, action) {
|
|
126
|
+
const enforcer = await this.getEnforcer();
|
|
127
|
+
return enforcer.enforce(userId, scope, action);
|
|
128
|
+
}
|
|
129
|
+
async currentUserHasPermission(scope, action) {
|
|
130
|
+
const userId = this.context.getUserId();
|
|
131
|
+
if (!userId)
|
|
132
|
+
return false;
|
|
133
|
+
return this.hasPermission(userId, scope, action);
|
|
134
|
+
}
|
|
135
|
+
async hasAnyPermission(userId, scopes, action) {
|
|
136
|
+
const enforcer = await this.getEnforcer();
|
|
137
|
+
const requests = scopes.map(scope => [userId, scope, action]);
|
|
138
|
+
const results = await enforcer.batchEnforce(requests);
|
|
139
|
+
return results.some(allowed => allowed);
|
|
140
|
+
}
|
|
141
|
+
async currentUserHasAnyPermission(scopes, action) {
|
|
142
|
+
const userId = this.context.getUserId();
|
|
143
|
+
if (!userId)
|
|
144
|
+
return false;
|
|
145
|
+
return this.hasAnyPermission(userId, scopes, action);
|
|
146
|
+
}
|
|
147
|
+
// ==================== CASBIN.JS FRONTEND SUPPORT ====================
|
|
148
|
+
async getPermissionsForUserAsCasbinJs(userId) {
|
|
149
|
+
const enforcer = await this.getEnforcer();
|
|
150
|
+
const permissions = await enforcer.getImplicitPermissionsForUser(userId);
|
|
151
|
+
const result = {};
|
|
152
|
+
for (const [_role, resource, action] of permissions) {
|
|
153
|
+
result[action] ??= [];
|
|
154
|
+
if (!result[action].includes(resource)) {
|
|
155
|
+
result[action].push(resource);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
async getCurrentUserPermissionsAsCasbinJs() {
|
|
161
|
+
const userId = this.context.getUserId();
|
|
162
|
+
if (!userId)
|
|
163
|
+
return {};
|
|
164
|
+
return this.getPermissionsForUserAsCasbinJs(userId);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
CasbinService = __decorate([
|
|
168
|
+
Transient(RBAC_TOKENS.CasbinService),
|
|
169
|
+
__param(0, inject(DI_TOKENS.AuthContext)),
|
|
170
|
+
__param(1, inject(CasbinEnforcerService)),
|
|
171
|
+
__metadata("design:paramtypes", [Function, CasbinEnforcerService])
|
|
172
|
+
], CasbinService);
|
|
173
|
+
export { CasbinService };
|
|
174
|
+
//# sourceMappingURL=casbin.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"casbin.service.js","sourceRoot":"","sources":["../../../src/rbac/services/casbin.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rbac/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rbac/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RBAC DI Tokens
|
|
3
|
+
*/
|
|
4
|
+
export declare const RBAC_TOKENS: {
|
|
5
|
+
/** Request-scoped Casbin service with auto context resolution */
|
|
6
|
+
readonly CasbinService: symbol;
|
|
7
|
+
/** RBAC module options (model, policies, hierarchy) */
|
|
8
|
+
readonly Options: symbol;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/rbac/tokens.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB,iEAAiE;;IAEjE,uDAAuD;;CAE/C,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RBAC DI Tokens
|
|
3
|
+
*/
|
|
4
|
+
export const RBAC_TOKENS = {
|
|
5
|
+
/** Request-scoped Casbin service with auto context resolution */
|
|
6
|
+
CasbinService: Symbol.for('CasbinService'),
|
|
7
|
+
/** RBAC module options (model, policies, hierarchy) */
|
|
8
|
+
Options: Symbol.for('RbacModuleOptions'),
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/rbac/tokens.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC;IAC1C,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC;CAChC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for the RBAC module
|
|
3
|
+
*/
|
|
4
|
+
export interface RbacModuleOptions {
|
|
5
|
+
/** Casbin PERM model string */
|
|
6
|
+
model: string;
|
|
7
|
+
/** Default policies: [role, resource, action][] */
|
|
8
|
+
defaultPolicies?: readonly (readonly [string, string, string])[];
|
|
9
|
+
/** Role hierarchy: [childRole, parentRole][] */
|
|
10
|
+
roleHierarchy?: readonly (readonly [string, string])[];
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,eAAe,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAA;IAChE,gDAAgD;IAChD,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAA;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stratal/framework",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Temitayo Fadojutimi",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/strataljs/stratal.git",
|
|
10
|
+
"directory": "packages/framework"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public",
|
|
14
|
+
"provenance": false
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./auth": {
|
|
27
|
+
"types": "./dist/auth/index.d.ts",
|
|
28
|
+
"import": "./dist/auth/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./context": {
|
|
31
|
+
"types": "./dist/context/index.d.ts",
|
|
32
|
+
"import": "./dist/context/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./database": {
|
|
35
|
+
"types": "./dist/database/index.d.ts",
|
|
36
|
+
"import": "./dist/database/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./factory": {
|
|
39
|
+
"types": "./dist/factory/index.d.ts",
|
|
40
|
+
"import": "./dist/factory/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./guards": {
|
|
43
|
+
"types": "./dist/guards/index.d.ts",
|
|
44
|
+
"import": "./dist/guards/index.js"
|
|
45
|
+
},
|
|
46
|
+
"./rbac": {
|
|
47
|
+
"types": "./dist/rbac/index.d.ts",
|
|
48
|
+
"import": "./dist/rbac/index.js"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "yarn prebuild && tsc -p tsconfig.build.json",
|
|
53
|
+
"clean": "rm -rf dist",
|
|
54
|
+
"prebuild": "yarn clean",
|
|
55
|
+
"generate": "zenstack generate --schema=test/schema.zmodel -o test/zenstack",
|
|
56
|
+
"generate:types": "wrangler types -c test/wrangler.jsonc",
|
|
57
|
+
"pretest": "yarn generate && yarn generate:types",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"test:watch": "vitest",
|
|
60
|
+
"test:e2e": "vitest run --project e2e",
|
|
61
|
+
"test:coverage": "vitest run --coverage",
|
|
62
|
+
"test:db": "docker compose -f test/docker-compose.yml up -d",
|
|
63
|
+
"typecheck": "yarn tsc --noEmit",
|
|
64
|
+
"lint": "npx eslint .",
|
|
65
|
+
"lint:fix": "npx eslint --fix ."
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"postgres-array": "^3.0.4"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"@better-auth/core": "^1.0.0",
|
|
72
|
+
"@faker-js/faker": "^10.3.0",
|
|
73
|
+
"@zenstackhq/better-auth": "^3.0.0",
|
|
74
|
+
"@zenstackhq/orm": "^3.0.0",
|
|
75
|
+
"better-auth": "^1.4.9",
|
|
76
|
+
"casbin": "^5.41.0",
|
|
77
|
+
"pg": "^8.0.0",
|
|
78
|
+
"stratal": "0.0.4"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"@better-auth/core": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"@faker-js/faker": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"@zenstackhq/better-auth": {
|
|
88
|
+
"optional": true
|
|
89
|
+
},
|
|
90
|
+
"better-auth": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"casbin": {
|
|
94
|
+
"optional": true
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"devDependencies": {
|
|
98
|
+
"@better-auth/core": "^1.5.0",
|
|
99
|
+
"@cloudflare/vitest-pool-workers": "^0.12.18",
|
|
100
|
+
"@cloudflare/workers-types": "4.20260301.1",
|
|
101
|
+
"@faker-js/faker": "^10.3.0",
|
|
102
|
+
"@stratal/testing": "workspace:^",
|
|
103
|
+
"@types/node": "^22.19.13",
|
|
104
|
+
"@types/pg": "^8.18.0",
|
|
105
|
+
"@vitest/coverage-istanbul": "3.2.4",
|
|
106
|
+
"@zenstackhq/better-auth": "^3.4.1",
|
|
107
|
+
"@zenstackhq/cli": "^3.4.1",
|
|
108
|
+
"@zenstackhq/orm": "^3.4.1",
|
|
109
|
+
"better-auth": "^1.5.0",
|
|
110
|
+
"casbin": "^5.49.0",
|
|
111
|
+
"pg": "^8.19.0",
|
|
112
|
+
"reflect-metadata": "^0.2.2",
|
|
113
|
+
"stratal": "workspace:*",
|
|
114
|
+
"typescript": "^5.9.3",
|
|
115
|
+
"vitest": "~3.2.0",
|
|
116
|
+
"wrangler": "^4.69.0"
|
|
117
|
+
}
|
|
118
|
+
}
|