@zakyyudha/node-authzkit 1.0.0

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 (120) hide show
  1. package/.eslintrc.cjs +17 -0
  2. package/.prettierrc.json +10 -0
  3. package/.release-it.json +24 -0
  4. package/README.md +221 -0
  5. package/dist/src/classes/Authzkit.d.ts +110 -0
  6. package/dist/src/classes/Authzkit.js +189 -0
  7. package/dist/src/classes/Authzkit.js.map +1 -0
  8. package/dist/src/dashboard/router.d.ts +19 -0
  9. package/dist/src/dashboard/router.js +89 -0
  10. package/dist/src/dashboard/router.js.map +1 -0
  11. package/dist/src/dashboard/routes/permissions.d.ts +3 -0
  12. package/dist/src/dashboard/routes/permissions.js +39 -0
  13. package/dist/src/dashboard/routes/permissions.js.map +1 -0
  14. package/dist/src/dashboard/routes/roles.d.ts +3 -0
  15. package/dist/src/dashboard/routes/roles.js +39 -0
  16. package/dist/src/dashboard/routes/roles.js.map +1 -0
  17. package/dist/src/dashboard/routes/users.d.ts +3 -0
  18. package/dist/src/dashboard/routes/users.js +81 -0
  19. package/dist/src/dashboard/routes/users.js.map +1 -0
  20. package/dist/src/drivers/mongodb/mongo-connection.d.ts +15 -0
  21. package/dist/src/drivers/mongodb/mongo-connection.js +89 -0
  22. package/dist/src/drivers/mongodb/mongo-connection.js.map +1 -0
  23. package/dist/src/drivers/postgres/pg-connection.d.ts +17 -0
  24. package/dist/src/drivers/postgres/pg-connection.js +145 -0
  25. package/dist/src/drivers/postgres/pg-connection.js.map +1 -0
  26. package/dist/src/index.d.ts +19 -0
  27. package/dist/src/index.js +36 -0
  28. package/dist/src/index.js.map +1 -0
  29. package/dist/src/interfaces/Authorizable.d.ts +7 -0
  30. package/dist/src/interfaces/Authorizable.js +3 -0
  31. package/dist/src/interfaces/Authorizable.js.map +1 -0
  32. package/dist/src/interfaces/IAuthzkitConfig.d.ts +18 -0
  33. package/dist/src/interfaces/IAuthzkitConfig.js +3 -0
  34. package/dist/src/interfaces/IAuthzkitConfig.js.map +1 -0
  35. package/dist/src/interfaces/Permission.d.ts +4 -0
  36. package/dist/src/interfaces/Permission.js +3 -0
  37. package/dist/src/interfaces/Permission.js.map +1 -0
  38. package/dist/src/interfaces/Role.d.ts +5 -0
  39. package/dist/src/interfaces/Role.js +3 -0
  40. package/dist/src/interfaces/Role.js.map +1 -0
  41. package/dist/src/middleware/authzMiddleware.d.ts +17 -0
  42. package/dist/src/middleware/authzMiddleware.js +52 -0
  43. package/dist/src/middleware/authzMiddleware.js.map +1 -0
  44. package/dist/src/stores/IAuthzkitStore.d.ts +23 -0
  45. package/dist/src/stores/IAuthzkitStore.js +3 -0
  46. package/dist/src/stores/IAuthzkitStore.js.map +1 -0
  47. package/dist/src/stores/InMemoryAuthzkitStore.d.ts +28 -0
  48. package/dist/src/stores/InMemoryAuthzkitStore.js +83 -0
  49. package/dist/src/stores/InMemoryAuthzkitStore.js.map +1 -0
  50. package/dist/src/stores/MongoAuthzkitStore.d.ts +31 -0
  51. package/dist/src/stores/MongoAuthzkitStore.js +127 -0
  52. package/dist/src/stores/MongoAuthzkitStore.js.map +1 -0
  53. package/dist/src/stores/PgAuthzkitStore.d.ts +31 -0
  54. package/dist/src/stores/PgAuthzkitStore.js +133 -0
  55. package/dist/src/stores/PgAuthzkitStore.js.map +1 -0
  56. package/dist/src/utils/envConfig.d.ts +2 -0
  57. package/dist/src/utils/envConfig.js +68 -0
  58. package/dist/src/utils/envConfig.js.map +1 -0
  59. package/dist/tests/Authzkit.test.d.ts +1 -0
  60. package/dist/tests/Authzkit.test.js +126 -0
  61. package/dist/tests/Authzkit.test.js.map +1 -0
  62. package/dist/tests/MongoAuthzkitStore.test.d.ts +1 -0
  63. package/dist/tests/MongoAuthzkitStore.test.js +161 -0
  64. package/dist/tests/MongoAuthzkitStore.test.js.map +1 -0
  65. package/dist/tests/MongoAuthzkitStoreCustom.test.d.ts +1 -0
  66. package/dist/tests/MongoAuthzkitStoreCustom.test.js +65 -0
  67. package/dist/tests/MongoAuthzkitStoreCustom.test.js.map +1 -0
  68. package/dist/tests/PgAuthzkitStore.test.d.ts +1 -0
  69. package/dist/tests/PgAuthzkitStore.test.js +163 -0
  70. package/dist/tests/PgAuthzkitStore.test.js.map +1 -0
  71. package/dist/tests/PgAuthzkitStoreCustom.test.d.ts +1 -0
  72. package/dist/tests/PgAuthzkitStoreCustom.test.js +74 -0
  73. package/dist/tests/PgAuthzkitStoreCustom.test.js.map +1 -0
  74. package/examples/express-app.ts +65 -0
  75. package/jest.config.js +9 -0
  76. package/package.json +57 -0
  77. package/src/classes/Authzkit.ts +214 -0
  78. package/src/dashboard/router.ts +79 -0
  79. package/src/dashboard/routes/permissions.ts +38 -0
  80. package/src/dashboard/routes/roles.ts +38 -0
  81. package/src/dashboard/routes/users.ts +81 -0
  82. package/src/dashboard/web/README.md +73 -0
  83. package/src/dashboard/web/eslint.config.js +23 -0
  84. package/src/dashboard/web/index.html +13 -0
  85. package/src/dashboard/web/package.json +31 -0
  86. package/src/dashboard/web/pnpm-lock.yaml +2094 -0
  87. package/src/dashboard/web/public/vite.svg +1 -0
  88. package/src/dashboard/web/src/App.css +42 -0
  89. package/src/dashboard/web/src/App.tsx +26 -0
  90. package/src/dashboard/web/src/assets/react.svg +1 -0
  91. package/src/dashboard/web/src/components/Navbar.tsx +53 -0
  92. package/src/dashboard/web/src/index.css +138 -0
  93. package/src/dashboard/web/src/main.tsx +10 -0
  94. package/src/dashboard/web/src/pages/PermissionsPage.tsx +87 -0
  95. package/src/dashboard/web/src/pages/RolesPage.tsx +98 -0
  96. package/src/dashboard/web/src/pages/UsersPage.tsx +146 -0
  97. package/src/dashboard/web/src/services/api.ts +59 -0
  98. package/src/dashboard/web/tsconfig.app.json +28 -0
  99. package/src/dashboard/web/tsconfig.json +7 -0
  100. package/src/dashboard/web/tsconfig.node.json +26 -0
  101. package/src/dashboard/web/vite.config.ts +8 -0
  102. package/src/drivers/mongodb/mongo-connection.ts +98 -0
  103. package/src/drivers/postgres/pg-connection.ts +159 -0
  104. package/src/index.ts +19 -0
  105. package/src/interfaces/Authorizable.ts +8 -0
  106. package/src/interfaces/IAuthzkitConfig.ts +19 -0
  107. package/src/interfaces/Permission.ts +4 -0
  108. package/src/interfaces/Role.ts +5 -0
  109. package/src/middleware/authzMiddleware.ts +60 -0
  110. package/src/stores/IAuthzkitStore.ts +33 -0
  111. package/src/stores/InMemoryAuthzkitStore.ts +101 -0
  112. package/src/stores/MongoAuthzkitStore.ts +171 -0
  113. package/src/stores/PgAuthzkitStore.ts +191 -0
  114. package/src/utils/envConfig.ts +70 -0
  115. package/tests/Authzkit.test.ts +157 -0
  116. package/tests/MongoAuthzkitStore.test.ts +204 -0
  117. package/tests/MongoAuthzkitStoreCustom.test.ts +75 -0
  118. package/tests/PgAuthzkitStore.test.ts +207 -0
  119. package/tests/PgAuthzkitStoreCustom.test.ts +90 -0
  120. package/tsconfig.json +37 -0
package/.eslintrc.cjs ADDED
@@ -0,0 +1,17 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ plugins: ['@typescript-eslint'],
4
+ extends: [
5
+ 'eslint:recommended',
6
+ 'plugin:@typescript-eslint/recommended',
7
+ ],
8
+ env: {
9
+ node: true,
10
+ es2022: true,
11
+ },
12
+ rules: {
13
+ '@typescript-eslint/no-explicit-any': 'off', // Common in early dev
14
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
15
+ },
16
+ ignorePatterns: ['dist/', 'node_modules/', 'dashboard/web/', 'src/dashboard/web/'],
17
+ };
@@ -0,0 +1,10 @@
1
+ {
2
+ "printWidth": 100,
3
+ "tabWidth": 2,
4
+ "useTabs": false,
5
+ "semi": true,
6
+ "singleQuote": true,
7
+ "trailingComma": "es5",
8
+ "bracketSpacing": true,
9
+ "arrowParens": "always"
10
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "git": {
3
+ "commit": true,
4
+ "tag": true,
5
+ "push": true,
6
+ "commitMessage": "chore: release v${version}"
7
+ },
8
+ "github": {
9
+ "release": true
10
+ },
11
+ "npm": {
12
+ "publish": true,
13
+ "publishArgs": [
14
+ "--access public"
15
+ ]
16
+ },
17
+ "hooks": {
18
+ "before:init": [
19
+ "npm run lint",
20
+ "npm test"
21
+ ],
22
+ "after:bump": "npm run build"
23
+ }
24
+ }
package/README.md ADDED
@@ -0,0 +1,221 @@
1
+
2
+ # node-authzkit
3
+
4
+ `node-authzkit` is a TypeScript library for Node.js that provides role and permission management. It allows you to define roles and permissions, assign them to "authorizable" entities (like users), and easily check for access rights.
5
+
6
+ ## Features
7
+
8
+ - **Role and Permission Definition:** Programmatically define permissions and roles with associated permissions.
9
+ - **Assignment:** Assign roles and direct permissions to any entity that implements the `Authorizable` interface.
10
+ - **Revocation:** Revoke roles and direct permissions.
11
+ - **Access Checks:** Convenient methods to check if an entity has a specific role or permission (either directly or via an assigned role).
12
+ - **Multiple Backends:** Supports In-Memory, MongoDB, and PostgreSQL storages out of the box.
13
+ - **Dynamic Configuration:** Customize database connection details and collection/table names via configuration.
14
+ - **Express.js Middleware:** Includes an Express.js middleware for easy route protection based on roles and permissions.
15
+ - **Dashboard:** Comes with a built-in dashboard for managing roles and permissions (source code included).
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pnpm install node-authzkit
21
+ # or npm install node-authzkit
22
+ # or yarn add node-authzkit
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ### 1. Initialize Authzkit
28
+
29
+ First, initialize the `Authzkit` singleton. You can provide a custom store, or it will default to `InMemoryAuthzkitStore`.
30
+
31
+ ```typescript
32
+ // src/main.ts
33
+ import { Authzkit, InMemoryAuthzkitStore } from 'node-authzkit';
34
+
35
+ const authzkit = Authzkit.getInstance(new InMemoryAuthzkitStore());
36
+
37
+ // Or, if you don't provide a store, it defaults to InMemoryAuthzkitStore
38
+ // const authzkit = Authzkit.getInstance();
39
+
40
+ export default authzkit;
41
+ ```
42
+
43
+ ### 2. persistence with MongoDB or PostgreSQL
44
+
45
+ You use `IAuthzkitConfig` to configure connection details and custom table/collection names.
46
+
47
+ **MongoDB Example:**
48
+
49
+ ```typescript
50
+ import { Authzkit, MongoConnection, MongoAuthzkitStore, IAuthzkitConfig } from 'node-authzkit';
51
+
52
+ const config: IAuthzkitConfig = {
53
+ connection: {
54
+ type: 'mongodb',
55
+ uri: 'mongodb://localhost:27017',
56
+ database: 'my_app_db'
57
+ },
58
+ models: { // Optional custom collection names
59
+ users: 'users',
60
+ roles: 'app_roles',
61
+ permissions: 'app_permissions'
62
+ }
63
+ };
64
+
65
+ async function init() {
66
+ const mongoConnection = MongoConnection.getInstance(config);
67
+ await mongoConnection.connect();
68
+
69
+ const store = new MongoAuthzkitStore(mongoConnection);
70
+ const authzkit = Authzkit.getInstance(store);
71
+ }
72
+ ```
73
+
74
+ **PostgreSQL Example:**
75
+
76
+ ```typescript
77
+ import { Authzkit, PgConnection, PgAuthzkitStore, IAuthzkitConfig } from 'node-authzkit';
78
+
79
+ const config: IAuthzkitConfig = {
80
+ connection: {
81
+ type: 'postgres',
82
+ uri: 'postgresql://user:pass@localhost:5432/my_app_db'
83
+ }
84
+ };
85
+
86
+ async function init() {
87
+ const pgConnection = PgConnection.getInstance(config);
88
+ await pgConnection.connect();
89
+ await pgConnection.initSchema(); // Creates tables if they don't exist
90
+
91
+ const store = new PgAuthzkitStore(pgConnection);
92
+ const authzkit = Authzkit.getInstance(store);
93
+ }
94
+ ```
95
+
96
+ ### 3. Usage
97
+
98
+ ```typescript
99
+ // Define
100
+ await authzkit.definePermission('edit_posts');
101
+ await authzkit.defineRole('editor', ['edit_posts']);
102
+
103
+ // Assign
104
+ const user = { id: 123 }; // Authorizable entity
105
+ await authzkit.assignRole(user, 'editor');
106
+
107
+ // Check
108
+ if (await authzkit.hasPermission(user, 'edit_posts')) {
109
+ console.log('User can edit posts');
110
+ }
111
+ ```
112
+
113
+ ### 4. Express Middleware
114
+
115
+ ```typescript
116
+ import { authorize } from 'node-authzkit';
117
+
118
+ app.post('/posts', authorize('edit_posts'), (req, res) => {
119
+ // ...
120
+ });
121
+ ```
122
+
123
+ ## Dashboard
124
+
125
+ This project includes a built-in dashboard to manage Roles, Permissions, and User Assignments visually.
126
+
127
+ ### Integration in Express
128
+
129
+ You can easily mount the dashboard into your existing Express application.
130
+
131
+ 1. **Install dependencies:**
132
+ The dashboard requires `express` and `basic-auth`.
133
+ ```bash
134
+ pnpm install express basic-auth
135
+ ```
136
+
137
+ 2. **Mount the Router:**
138
+ ```typescript
139
+ import express from 'express';
140
+ import { Authzkit, InMemoryAuthzkitStore, createDashboardRouter } from 'node-authzkit';
141
+
142
+ const app = express();
143
+ const authzkit = Authzkit.getInstance(new InMemoryAuthzkitStore());
144
+
145
+ // Mount the dashboard at /authzkit
146
+ app.use('/authzkit', createDashboardRouter({
147
+ authzkit, // Optional, defaults to singleton
148
+ secret: 'supersecret', // Password for Basic Auth (User: admin)
149
+ username: 'admin' // Optional, defaults to 'admin'
150
+ }));
151
+
152
+ app.listen(3000);
153
+ ```
154
+
155
+ 3. **Access:**
156
+ Go to `http://localhost:3000/authzkit/` and log in with the credentials you configured.
157
+
158
+ ### Using Environment Variables
159
+
160
+ You can configure `node-authzkit` stores using environment variables.
161
+
162
+ 1. **Set Environment Variables:**
163
+ ```bash
164
+ # For MongoDB
165
+ AUTHZKIT_CONNECTION_TYPE=mongodb
166
+ AUTHZKIT_CONNECTION_URI=mongodb://localhost:27017/mydb
167
+ AUTHZKIT_DB_NAME=mydb
168
+
169
+ # For PostgreSQL
170
+ AUTHZKIT_CONNECTION_TYPE=postgres
171
+ AUTHZKIT_CONNECTION_URI=postgresql://user:pass@localhost:5432/mydb
172
+
173
+ # For Dashboard Auth (Optional override)
174
+ AUTHZKIT_DASHBOARD_USERNAME=adminuser
175
+ AUTHZKIT_DASHBOARD_SECRET=mysecretpassword
176
+ ```
177
+
178
+ 2. **Load Configuration:**
179
+ ```typescript
180
+ import { loadConfigFromEnv, MongoConnection, PgConnection, Authzkit, MongoAuthzkitStore, PgAuthzkitStore } from 'node-authzkit';
181
+
182
+ const config = loadConfigFromEnv();
183
+
184
+ if (config) {
185
+ if (config.connection.type === 'mongodb') {
186
+ const conn = MongoConnection.getInstance(config);
187
+ await conn.connect();
188
+ Authzkit.getInstance(new MongoAuthzkitStore(conn));
189
+ } else if (config.connection.type === 'postgres') {
190
+ const conn = PgConnection.getInstance(config);
191
+ await conn.connect();
192
+ Authzkit.getInstance(new PgAuthzkitStore(conn));
193
+ }
194
+ }
195
+ ```
196
+
197
+ ## API Documentation
198
+
199
+ ### `Authzkit` Class
200
+
201
+ The main singleton class.
202
+
203
+ - `static getInstance(store?: IAuthzkitStore): Authzkit`
204
+ - `definePermission(name: string, guard_name?: string): Promise<Permission>`
205
+ - `defineRole(name: string, permissions: string[], guard_name?: string): Promise<Role>`
206
+ - `deletePermission(name: string): Promise<void>`
207
+ - `deleteRole(name: string): Promise<void>`
208
+ - `assignRole(authorizable: Authorizable, roleName: string): Promise<void>`
209
+ - `assignPermission(authorizable: Authorizable, permissionName: string): Promise<void>`
210
+ - `revokeRole(authorizable: Authorizable, roleName: string): Promise<void>`
211
+ - `revokePermission(authorizable: Authorizable, permissionName: string): Promise<void>`
212
+ - `hasRole(authorizable: Authorizable, roleName: string): Promise<boolean>`
213
+ - `hasPermission(authorizable: Authorizable, permissionName: string): Promise<boolean>`
214
+ - `getRoles(): Promise<Role[]>`
215
+ - `getPermissions(): Promise<Permission[]>`
216
+ - `getUserRoles(authorizable: Authorizable): Promise<Set<string>>`
217
+ - `getUserPermissions(authorizable: Authorizable): Promise<Set<string>>`
218
+
219
+ ## License
220
+
221
+ ISC
@@ -0,0 +1,110 @@
1
+ import { Authorizable } from '../interfaces/Authorizable';
2
+ import { Permission } from '../interfaces/Permission';
3
+ import { Role } from '../interfaces/Role';
4
+ import { IAuthzkitStore } from '../stores/IAuthzkitStore';
5
+ export declare class Authzkit {
6
+ private static instance;
7
+ private store;
8
+ private constructor();
9
+ /**
10
+ * Returns the singleton instance of Authzkit.
11
+ * Optionally accepts a store implementation to use. If no store is provided,
12
+ * an `InMemoryAuthzkitStore` will be used by default.
13
+ */
14
+ static getInstance(store?: IAuthzkitStore): Authzkit;
15
+ /**
16
+ * Defines a new permission.
17
+ * @param name The name of the permission.
18
+ * @param guard_name Optional guard name.
19
+ */
20
+ definePermission(name: string, guard_name?: string): Promise<Permission>;
21
+ /**
22
+ * Retrieves all defined permissions.
23
+ * @returns An array of Permission objects.
24
+ */
25
+ getPermissions(): Promise<Permission[]>;
26
+ /**
27
+ * Retrieves all defined roles.
28
+ * @returns An array of Role objects.
29
+ */
30
+ getRoles(): Promise<Role[]>;
31
+ /**
32
+ * Defines a new role with associated permissions.
33
+ * @param name The name of the role.
34
+ * @param permissions An array of permission names.
35
+ * @param guard_name Optional guard name.
36
+ */
37
+ defineRole(name: string, permissions?: string[], guard_name?: string): Promise<Role>;
38
+ /**
39
+ * Deletes a permission.
40
+ * @param name The name of the permission to delete.
41
+ */
42
+ deletePermission(name: string): Promise<void>;
43
+ /**
44
+ * Deletes a role.
45
+ * @param name The name of the role to delete.
46
+ */
47
+ deleteRole(name: string): Promise<void>;
48
+ /**
49
+ * Retrieves roles assigned to a user.
50
+ * @param authorizable The user for whom to retrieve roles.
51
+ * @returns A Promise resolving to a Set of role names.
52
+ */
53
+ getUserRoles(authorizable: Authorizable): Promise<Set<string>>;
54
+ /**
55
+ * Retrieves permissions assigned directly to a user.
56
+ * @param authorizable The user for whom to retrieve permissions.
57
+ * @returns A Promise resolving to a Set of permission names.
58
+ */
59
+ getUserPermissions(authorizable: Authorizable): Promise<Set<string>>;
60
+ /**
61
+ * Assigns a role to an authorizable entity.
62
+ * @param authorizable The entity to assign the role to.
63
+ * @param roleName The name of the role to assign.
64
+ */
65
+ assignRole(authorizable: Authorizable, roleName: string): Promise<void>;
66
+ /**
67
+ * Assigns a direct permission to an authorizable entity.
68
+ * @param authorizable The entity to assign the permission to.
69
+ * @param permissionName The name of the permission to assign.
70
+ */
71
+ assignPermission(authorizable: Authorizable, permissionName: string): Promise<void>;
72
+ /**
73
+ * Revokes a role from an authorizable entity.
74
+ * @param authorizable The entity to revoke the role from.
75
+ * @param roleName The name of the role to revoke.
76
+ */
77
+ revokeRole(authorizable: Authorizable, roleName: string): Promise<void>;
78
+ /**
79
+ * Revokes a direct permission from an authorizable entity.
80
+ * @param authorizable The entity to revoke the permission from.
81
+ * @param permissionName The name of the permission to revoke.
82
+ */
83
+ revokePermission(authorizable: Authorizable, permissionName: string): Promise<void>;
84
+ /**
85
+ * Checks if an authorizable entity has a given role.
86
+ * @param authorizable The entity to check.
87
+ * @param roleName The name of the role to check for.
88
+ * @returns True if the entity has the role, false otherwise.
89
+ */
90
+ hasRole(authorizable: Authorizable, roleName: string): Promise<boolean>;
91
+ /**
92
+ * Checks if an authorizable entity has a given permission, either directly or through a role.
93
+ * @param authorizable The entity to check.
94
+ * @param permissionName The name of the permission to check for.
95
+ * @returns True if the entity has the permission, false otherwise.
96
+ */
97
+ hasPermission(authorizable: Authorizable, permissionName: string): Promise<boolean>;
98
+ /**
99
+ * Checks if a role has a specific permission.
100
+ * @param roleName The name of the role.
101
+ * @param permissionName The name of the permission.
102
+ * @returns True if the role has the permission, false otherwise.
103
+ */
104
+ roleHasPermission(roleName: string, permissionName: string): Promise<boolean>;
105
+ /**
106
+ * Resets all defined permissions, roles, and assigned user roles/permissions.
107
+ * Useful for testing.
108
+ */
109
+ reset(): Promise<void>;
110
+ }
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Authzkit = void 0;
4
+ const InMemoryAuthzkitStore_1 = require("../stores/InMemoryAuthzkitStore");
5
+ class Authzkit {
6
+ static instance;
7
+ store;
8
+ constructor(store) {
9
+ this.store = store || new InMemoryAuthzkitStore_1.InMemoryAuthzkitStore();
10
+ }
11
+ /**
12
+ * Returns the singleton instance of Authzkit.
13
+ * Optionally accepts a store implementation to use. If no store is provided,
14
+ * an `InMemoryAuthzkitStore` will be used by default.
15
+ */
16
+ static getInstance(store) {
17
+ if (!Authzkit.instance) {
18
+ Authzkit.instance = new Authzkit(store);
19
+ }
20
+ return Authzkit.instance;
21
+ }
22
+ /**
23
+ * Defines a new permission.
24
+ * @param name The name of the permission.
25
+ * @param guard_name Optional guard name.
26
+ */
27
+ async definePermission(name, guard_name) {
28
+ if (await this.store.hasPermission(name)) {
29
+ throw new Error(`Permission '${name}' already exists.`);
30
+ }
31
+ const permission = { name, guard_name };
32
+ await this.store.setPermission(permission);
33
+ return permission;
34
+ }
35
+ /**
36
+ * Retrieves all defined permissions.
37
+ * @returns An array of Permission objects.
38
+ */
39
+ async getPermissions() {
40
+ return await this.store.getPermissions();
41
+ }
42
+ /**
43
+ * Retrieves all defined roles.
44
+ * @returns An array of Role objects.
45
+ */
46
+ async getRoles() {
47
+ return await this.store.getRoles();
48
+ }
49
+ /**
50
+ * Defines a new role with associated permissions.
51
+ * @param name The name of the role.
52
+ * @param permissions An array of permission names.
53
+ * @param guard_name Optional guard name.
54
+ */
55
+ async defineRole(name, permissions = [], guard_name) {
56
+ if (await this.store.hasRole(name)) {
57
+ throw new Error(`Role '${name}' already exists.`);
58
+ }
59
+ // Ensure all provided permissions exist
60
+ for (const pName of permissions) {
61
+ if (!(await this.store.hasPermission(pName))) {
62
+ throw new Error(`Permission '${pName}' not found when defining role '${name}'.`);
63
+ }
64
+ }
65
+ const role = { name, permissions, guard_name }; // Store permission names
66
+ await this.store.setRole(role);
67
+ return role;
68
+ }
69
+ /**
70
+ * Deletes a permission.
71
+ * @param name The name of the permission to delete.
72
+ */
73
+ async deletePermission(name) {
74
+ await this.store.deletePermission(name);
75
+ }
76
+ /**
77
+ * Deletes a role.
78
+ * @param name The name of the role to delete.
79
+ */
80
+ async deleteRole(name) {
81
+ await this.store.deleteRole(name);
82
+ }
83
+ /**
84
+ * Retrieves roles assigned to a user.
85
+ * @param authorizable The user for whom to retrieve roles.
86
+ * @returns A Promise resolving to a Set of role names.
87
+ */
88
+ async getUserRoles(authorizable) {
89
+ return await this.store.getUserRoles(authorizable.id);
90
+ }
91
+ /**
92
+ * Retrieves permissions assigned directly to a user.
93
+ * @param authorizable The user for whom to retrieve permissions.
94
+ * @returns A Promise resolving to a Set of permission names.
95
+ */
96
+ async getUserPermissions(authorizable) {
97
+ return await this.store.getUserPermissions(authorizable.id);
98
+ }
99
+ /**
100
+ * Assigns a role to an authorizable entity.
101
+ * @param authorizable The entity to assign the role to.
102
+ * @param roleName The name of the role to assign.
103
+ */
104
+ async assignRole(authorizable, roleName) {
105
+ if (!(await this.store.hasRole(roleName))) {
106
+ throw new Error(`Role '${roleName}' not found.`);
107
+ }
108
+ await this.store.addUserRole(authorizable.id, roleName);
109
+ }
110
+ /**
111
+ * Assigns a direct permission to an authorizable entity.
112
+ * @param authorizable The entity to assign the permission to.
113
+ * @param permissionName The name of the permission to assign.
114
+ */
115
+ async assignPermission(authorizable, permissionName) {
116
+ if (!(await this.store.hasPermission(permissionName))) {
117
+ throw new Error(`Permission '${permissionName}' not found.`);
118
+ }
119
+ await this.store.addUserPermission(authorizable.id, permissionName);
120
+ }
121
+ /**
122
+ * Revokes a role from an authorizable entity.
123
+ * @param authorizable The entity to revoke the role from.
124
+ * @param roleName The name of the role to revoke.
125
+ */
126
+ async revokeRole(authorizable, roleName) {
127
+ await this.store.removeUserRole(authorizable.id, roleName);
128
+ }
129
+ /**
130
+ * Revokes a direct permission from an authorizable entity.
131
+ * @param authorizable The entity to revoke the permission from.
132
+ * @param permissionName The name of the permission to revoke.
133
+ */
134
+ async revokePermission(authorizable, permissionName) {
135
+ await this.store.removeUserPermission(authorizable.id, permissionName);
136
+ }
137
+ /**
138
+ * Checks if an authorizable entity has a given role.
139
+ * @param authorizable The entity to check.
140
+ * @param roleName The name of the role to check for.
141
+ * @returns True if the entity has the role, false otherwise.
142
+ */
143
+ async hasRole(authorizable, roleName) {
144
+ return await this.store.hasUserRole(authorizable.id, roleName);
145
+ }
146
+ /**
147
+ * Checks if an authorizable entity has a given permission, either directly or through a role.
148
+ * @param authorizable The entity to check.
149
+ * @param permissionName The name of the permission to check for.
150
+ * @returns True if the entity has the permission, false otherwise.
151
+ */
152
+ async hasPermission(authorizable, permissionName) {
153
+ // Check direct permissions from store
154
+ if (await this.store.hasUserPermission(authorizable.id, permissionName)) {
155
+ return true;
156
+ }
157
+ // Check permissions via roles
158
+ const roles = await this.store.getUserRoles(authorizable.id);
159
+ if (roles) {
160
+ for (const roleName of roles) {
161
+ const role = await this.store.getRole(roleName);
162
+ // Check if the role has the permission
163
+ if (role && role.permissions.includes(permissionName)) {
164
+ return true;
165
+ }
166
+ }
167
+ }
168
+ return false;
169
+ }
170
+ /**
171
+ * Checks if a role has a specific permission.
172
+ * @param roleName The name of the role.
173
+ * @param permissionName The name of the permission.
174
+ * @returns True if the role has the permission, false otherwise.
175
+ */
176
+ async roleHasPermission(roleName, permissionName) {
177
+ const role = await this.store.getRole(roleName);
178
+ return role ? role.permissions.includes(permissionName) : false;
179
+ }
180
+ /**
181
+ * Resets all defined permissions, roles, and assigned user roles/permissions.
182
+ * Useful for testing.
183
+ */
184
+ async reset() {
185
+ await this.store.reset();
186
+ }
187
+ }
188
+ exports.Authzkit = Authzkit;
189
+ //# sourceMappingURL=Authzkit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Authzkit.js","sourceRoot":"","sources":["../../../src/classes/Authzkit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Router } from 'express';
2
+ import { Authzkit } from '../classes/Authzkit';
3
+ export interface DashboardOptions {
4
+ /**
5
+ * Authzkit instance to use. If not provided, uses the singleton.
6
+ */
7
+ authzkit?: Authzkit;
8
+ /**
9
+ * Secret password for Basic Auth.
10
+ * If not provided, checks AUTHZKIT_DASHBOARD_SECRET env var.
11
+ * If neither is present, dashboard will not be accessible (returns 500 configuration error or 401).
12
+ */
13
+ secret?: string;
14
+ /**
15
+ * Usersname for Basic Auth. Defaults to 'admin'.
16
+ */
17
+ username?: string;
18
+ }
19
+ export declare function createDashboardRouter(options?: DashboardOptions): Router;