@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.
- package/.eslintrc.cjs +17 -0
- package/.prettierrc.json +10 -0
- package/.release-it.json +24 -0
- package/README.md +221 -0
- package/dist/src/classes/Authzkit.d.ts +110 -0
- package/dist/src/classes/Authzkit.js +189 -0
- package/dist/src/classes/Authzkit.js.map +1 -0
- package/dist/src/dashboard/router.d.ts +19 -0
- package/dist/src/dashboard/router.js +89 -0
- package/dist/src/dashboard/router.js.map +1 -0
- package/dist/src/dashboard/routes/permissions.d.ts +3 -0
- package/dist/src/dashboard/routes/permissions.js +39 -0
- package/dist/src/dashboard/routes/permissions.js.map +1 -0
- package/dist/src/dashboard/routes/roles.d.ts +3 -0
- package/dist/src/dashboard/routes/roles.js +39 -0
- package/dist/src/dashboard/routes/roles.js.map +1 -0
- package/dist/src/dashboard/routes/users.d.ts +3 -0
- package/dist/src/dashboard/routes/users.js +81 -0
- package/dist/src/dashboard/routes/users.js.map +1 -0
- package/dist/src/drivers/mongodb/mongo-connection.d.ts +15 -0
- package/dist/src/drivers/mongodb/mongo-connection.js +89 -0
- package/dist/src/drivers/mongodb/mongo-connection.js.map +1 -0
- package/dist/src/drivers/postgres/pg-connection.d.ts +17 -0
- package/dist/src/drivers/postgres/pg-connection.js +145 -0
- package/dist/src/drivers/postgres/pg-connection.js.map +1 -0
- package/dist/src/index.d.ts +19 -0
- package/dist/src/index.js +36 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces/Authorizable.d.ts +7 -0
- package/dist/src/interfaces/Authorizable.js +3 -0
- package/dist/src/interfaces/Authorizable.js.map +1 -0
- package/dist/src/interfaces/IAuthzkitConfig.d.ts +18 -0
- package/dist/src/interfaces/IAuthzkitConfig.js +3 -0
- package/dist/src/interfaces/IAuthzkitConfig.js.map +1 -0
- package/dist/src/interfaces/Permission.d.ts +4 -0
- package/dist/src/interfaces/Permission.js +3 -0
- package/dist/src/interfaces/Permission.js.map +1 -0
- package/dist/src/interfaces/Role.d.ts +5 -0
- package/dist/src/interfaces/Role.js +3 -0
- package/dist/src/interfaces/Role.js.map +1 -0
- package/dist/src/middleware/authzMiddleware.d.ts +17 -0
- package/dist/src/middleware/authzMiddleware.js +52 -0
- package/dist/src/middleware/authzMiddleware.js.map +1 -0
- package/dist/src/stores/IAuthzkitStore.d.ts +23 -0
- package/dist/src/stores/IAuthzkitStore.js +3 -0
- package/dist/src/stores/IAuthzkitStore.js.map +1 -0
- package/dist/src/stores/InMemoryAuthzkitStore.d.ts +28 -0
- package/dist/src/stores/InMemoryAuthzkitStore.js +83 -0
- package/dist/src/stores/InMemoryAuthzkitStore.js.map +1 -0
- package/dist/src/stores/MongoAuthzkitStore.d.ts +31 -0
- package/dist/src/stores/MongoAuthzkitStore.js +127 -0
- package/dist/src/stores/MongoAuthzkitStore.js.map +1 -0
- package/dist/src/stores/PgAuthzkitStore.d.ts +31 -0
- package/dist/src/stores/PgAuthzkitStore.js +133 -0
- package/dist/src/stores/PgAuthzkitStore.js.map +1 -0
- package/dist/src/utils/envConfig.d.ts +2 -0
- package/dist/src/utils/envConfig.js +68 -0
- package/dist/src/utils/envConfig.js.map +1 -0
- package/dist/tests/Authzkit.test.d.ts +1 -0
- package/dist/tests/Authzkit.test.js +126 -0
- package/dist/tests/Authzkit.test.js.map +1 -0
- package/dist/tests/MongoAuthzkitStore.test.d.ts +1 -0
- package/dist/tests/MongoAuthzkitStore.test.js +161 -0
- package/dist/tests/MongoAuthzkitStore.test.js.map +1 -0
- package/dist/tests/MongoAuthzkitStoreCustom.test.d.ts +1 -0
- package/dist/tests/MongoAuthzkitStoreCustom.test.js +65 -0
- package/dist/tests/MongoAuthzkitStoreCustom.test.js.map +1 -0
- package/dist/tests/PgAuthzkitStore.test.d.ts +1 -0
- package/dist/tests/PgAuthzkitStore.test.js +163 -0
- package/dist/tests/PgAuthzkitStore.test.js.map +1 -0
- package/dist/tests/PgAuthzkitStoreCustom.test.d.ts +1 -0
- package/dist/tests/PgAuthzkitStoreCustom.test.js +74 -0
- package/dist/tests/PgAuthzkitStoreCustom.test.js.map +1 -0
- package/examples/express-app.ts +65 -0
- package/jest.config.js +9 -0
- package/package.json +57 -0
- package/src/classes/Authzkit.ts +214 -0
- package/src/dashboard/router.ts +79 -0
- package/src/dashboard/routes/permissions.ts +38 -0
- package/src/dashboard/routes/roles.ts +38 -0
- package/src/dashboard/routes/users.ts +81 -0
- package/src/dashboard/web/README.md +73 -0
- package/src/dashboard/web/eslint.config.js +23 -0
- package/src/dashboard/web/index.html +13 -0
- package/src/dashboard/web/package.json +31 -0
- package/src/dashboard/web/pnpm-lock.yaml +2094 -0
- package/src/dashboard/web/public/vite.svg +1 -0
- package/src/dashboard/web/src/App.css +42 -0
- package/src/dashboard/web/src/App.tsx +26 -0
- package/src/dashboard/web/src/assets/react.svg +1 -0
- package/src/dashboard/web/src/components/Navbar.tsx +53 -0
- package/src/dashboard/web/src/index.css +138 -0
- package/src/dashboard/web/src/main.tsx +10 -0
- package/src/dashboard/web/src/pages/PermissionsPage.tsx +87 -0
- package/src/dashboard/web/src/pages/RolesPage.tsx +98 -0
- package/src/dashboard/web/src/pages/UsersPage.tsx +146 -0
- package/src/dashboard/web/src/services/api.ts +59 -0
- package/src/dashboard/web/tsconfig.app.json +28 -0
- package/src/dashboard/web/tsconfig.json +7 -0
- package/src/dashboard/web/tsconfig.node.json +26 -0
- package/src/dashboard/web/vite.config.ts +8 -0
- package/src/drivers/mongodb/mongo-connection.ts +98 -0
- package/src/drivers/postgres/pg-connection.ts +159 -0
- package/src/index.ts +19 -0
- package/src/interfaces/Authorizable.ts +8 -0
- package/src/interfaces/IAuthzkitConfig.ts +19 -0
- package/src/interfaces/Permission.ts +4 -0
- package/src/interfaces/Role.ts +5 -0
- package/src/middleware/authzMiddleware.ts +60 -0
- package/src/stores/IAuthzkitStore.ts +33 -0
- package/src/stores/InMemoryAuthzkitStore.ts +101 -0
- package/src/stores/MongoAuthzkitStore.ts +171 -0
- package/src/stores/PgAuthzkitStore.ts +191 -0
- package/src/utils/envConfig.ts +70 -0
- package/tests/Authzkit.test.ts +157 -0
- package/tests/MongoAuthzkitStore.test.ts +204 -0
- package/tests/MongoAuthzkitStoreCustom.test.ts +75 -0
- package/tests/PgAuthzkitStore.test.ts +207 -0
- package/tests/PgAuthzkitStoreCustom.test.ts +90 -0
- 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
|
+
};
|
package/.prettierrc.json
ADDED
package/.release-it.json
ADDED
|
@@ -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;
|