@kurdel/auth-db 0.1.0-beta.4 → 0.1.0-beta.6
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/README.md +192 -96
- package/lib/api-key-hasher.d.ts +15 -0
- package/lib/api-key-hasher.js +6 -0
- package/lib/api-key-hasher.js.map +1 -1
- package/lib/auth-database-module.d.ts +28 -0
- package/lib/auth-database-module.js +23 -0
- package/lib/auth-database-module.js.map +1 -1
- package/lib/auth-database-tables.d.ts +26 -0
- package/lib/auth-database-tables.js +28 -1
- package/lib/auth-database-tables.js.map +1 -1
- package/lib/database-api-key-repository.d.ts +29 -0
- package/lib/database-api-key-repository.js +29 -0
- package/lib/database-api-key-repository.js.map +1 -1
- package/lib/database-api-key-service.d.ts +33 -0
- package/lib/database-api-key-service.js +33 -0
- package/lib/database-api-key-service.js.map +1 -1
- package/lib/database-api-key-usage-recorder.d.ts +25 -1
- package/lib/database-api-key-usage-recorder.js +25 -1
- package/lib/database-api-key-usage-recorder.js.map +1 -1
- package/lib/database-auth-event-sink-provider.d.ts +8 -0
- package/lib/database-auth-event-sink-provider.js +15 -0
- package/lib/database-auth-event-sink-provider.js.map +1 -0
- package/lib/database-auth-event-store.d.ts +28 -1
- package/lib/database-auth-event-store.js +37 -1
- package/lib/database-auth-event-store.js.map +1 -1
- package/lib/database-auth-user-repository.d.ts +28 -0
- package/lib/database-auth-user-repository.js +28 -0
- package/lib/database-auth-user-repository.js.map +1 -1
- package/lib/database-jwt-session-repository.d.ts +27 -1
- package/lib/database-jwt-session-repository.js +27 -1
- package/lib/database-jwt-session-repository.js.map +1 -1
- package/lib/database-jwt-session-service.d.ts +55 -1
- package/lib/database-jwt-session-service.js +182 -1
- package/lib/database-jwt-session-service.js.map +1 -1
- package/lib/database-password-credential-repository.d.ts +27 -0
- package/lib/database-password-credential-repository.js +27 -0
- package/lib/database-password-credential-repository.js.map +1 -1
- package/lib/database-password-service.d.ts +31 -0
- package/lib/database-password-service.js +31 -0
- package/lib/database-password-service.js.map +1 -1
- package/lib/database-user-service.d.ts +47 -13
- package/lib/database-user-service.js +273 -190
- package/lib/database-user-service.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/tokens.d.ts +8 -0
- package/lib/tokens.js +8 -0
- package/lib/tokens.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,102 +1,170 @@
|
|
|
1
1
|
# @kurdel/auth-db
|
|
2
2
|
|
|
3
|
-
Database-backed
|
|
4
|
-
|
|
5
|
-
The package keeps authentication strategies storage-agnostic while providing
|
|
6
|
-
standard implementations over Kurdel's `Database` contract.
|
|
7
|
-
|
|
8
|
-
`DatabaseAuthUserRepository` resolves the current user and roles, while
|
|
9
|
-
`DatabaseApiKeyRepository` resolves safe credential metadata including its
|
|
10
|
-
stable ID. After a strategy succeeds, this data is available through
|
|
11
|
-
`ctx.auth.user` and `ctx.auth.credential`; raw API keys are never exposed in the
|
|
12
|
-
authentication context.
|
|
13
|
-
|
|
14
|
-
The package also provides `DatabaseUserService` and `DatabaseApiKeyService` for
|
|
15
|
-
administrative workflows. They create, list, update, and delete users, manage
|
|
16
|
-
role assignments, and issue, list, or revoke API keys. `AuthDatabaseModule`
|
|
17
|
-
registers both services as `AUTH_DB_TOKENS.UserService` and
|
|
18
|
-
`AUTH_DB_TOKENS.ApiKeyService`.
|
|
19
|
-
|
|
20
|
-
The module also exposes `DatabaseJwtSessionRepository` and
|
|
21
|
-
`DatabaseJwtSessionService`. Applications can create a server-side session,
|
|
22
|
-
place its ID in the JWT `jti` claim, configure that repository on `JwtStrategy`,
|
|
23
|
-
and revoke the session before the signed token expires. Session creation and
|
|
24
|
-
revocation are transactional and emit sanitized audit events when auditing is
|
|
25
|
-
enabled.
|
|
26
|
-
|
|
27
|
-
Password authentication uses a separate `password_credentials` table rather
|
|
28
|
-
than adding secrets to the user profile. `DatabasePasswordCredentialRepository`
|
|
29
|
-
resolves credentials by case-insensitive email, while
|
|
30
|
-
`DatabasePasswordService.set()` hashes and upserts a user's password.
|
|
31
|
-
`AuthDatabaseModule` wires both to `PasswordAuthenticationService` and uses
|
|
32
|
-
`ScryptPasswordHasher` by default. Applications can replace it with
|
|
33
|
-
`passwordHasher` in the module configuration.
|
|
34
|
-
|
|
35
|
-
User listings support status and text filters, stable sorting, and offset
|
|
36
|
-
pagination. `DatabaseUserService` also provides transactional bulk status,
|
|
37
|
-
role, and deletion operations; role lifecycle management with usage counts;
|
|
38
|
-
and dashboard statistics for users, credentials, and recent authentication
|
|
39
|
-
failures. `DatabaseAuthEventStore.listPage()` exposes global or per-user audit
|
|
40
|
-
history with type, date range, and offset filters while the existing `list()`
|
|
41
|
-
method remains available for simple queries.
|
|
42
|
-
|
|
43
|
-
Applications may also model authorization as roles containing permissions.
|
|
44
|
-
`DatabaseUserService.listPermissions()` exposes the application-owned catalog,
|
|
45
|
-
and `setRolePermissions()` replaces a role's assignments transactionally.
|
|
46
|
-
`DatabaseAuthUserRepository` resolves the union of permissions from every
|
|
47
|
-
current role into `AuthUser.permissions`. The application schema must provide
|
|
48
|
-
`permissions` and `role_permissions` tables; the runnable sample contains the
|
|
49
|
-
corresponding migration and seed data.
|
|
50
|
-
|
|
51
|
-
`DatabaseApiKeyUsageRecorder` updates `last_used_at` after successful
|
|
52
|
-
authentication. `AuthDatabaseModule` exposes it through
|
|
53
|
-
`AUTH_TOKENS.ApiKeyUsageRecorder`, ready to pass to `ApiKeyStrategy` as its
|
|
54
|
-
`usage` option.
|
|
55
|
-
|
|
56
|
-
Database audit persistence is opt-in because applications own their schema:
|
|
3
|
+
Database-backed infrastructure for `@kurdel/auth`.
|
|
57
4
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
5
|
+
The package provides reusable implementations of the repositories and
|
|
6
|
+
application services defined by `@kurdel/auth` on top of Kurdel's `Database`
|
|
7
|
+
abstraction. Authentication strategies remain storage-agnostic while
|
|
8
|
+
applications own their database schema and migrations.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Database-backed authentication repositories
|
|
13
|
+
- User, role and permission management
|
|
14
|
+
- API key lifecycle management
|
|
15
|
+
- JWT session persistence and revocation
|
|
16
|
+
- Refresh token rotation
|
|
17
|
+
- Password credential storage
|
|
18
|
+
- Authentication audit persistence
|
|
19
|
+
- SQLite and PostgreSQL support
|
|
20
|
+
|
|
21
|
+
## Registered services
|
|
22
|
+
|
|
23
|
+
`AuthDatabaseModule` registers the following infrastructure:
|
|
24
|
+
|
|
25
|
+
| Token | Implementation |
|
|
26
|
+
|-------|----------------|
|
|
27
|
+
| `AUTH_TOKENS.UserRepository` | `DatabaseAuthUserRepository` |
|
|
28
|
+
| `AUTH_TOKENS.ApiKeyRepository` | `DatabaseApiKeyRepository` |
|
|
29
|
+
| `AUTH_TOKENS.JwtSessionRepository` | `DatabaseJwtSessionRepository` |
|
|
30
|
+
| `AUTH_TOKENS.PasswordCredentialRepository` | `DatabasePasswordCredentialRepository` |
|
|
31
|
+
| `AUTH_TOKENS.ApiKeyUsageRecorder` | `DatabaseApiKeyUsageRecorder` |
|
|
32
|
+
| `AUTH_TOKENS.PasswordAuthenticationService` | `PasswordAuthenticationService` |
|
|
33
|
+
| `AUTH_DB_TOKENS.UserService` | `DatabaseUserService` |
|
|
34
|
+
| `AUTH_DB_TOKENS.ApiKeyService` | `DatabaseApiKeyService` |
|
|
35
|
+
| `AUTH_DB_TOKENS.JwtSessionService` | `DatabaseJwtSessionService` |
|
|
36
|
+
| `AUTH_DB_TOKENS.PasswordService` | `DatabasePasswordService` |
|
|
37
|
+
|
|
38
|
+
When audit persistence is enabled, the module also registers:
|
|
61
39
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
authorization events. The application must provide the configured
|
|
66
|
-
`auth_events` table; the runnable sample includes a migration with the expected
|
|
67
|
-
columns and indexes.
|
|
40
|
+
| Token | Implementation |
|
|
41
|
+
|-------|----------------|
|
|
42
|
+
| `AUTH_DB_TOKENS.EventStore` | `DatabaseAuthEventStore` |
|
|
68
43
|
|
|
69
|
-
|
|
70
|
-
`Database.transaction` callback. If audit persistence fails, the credential
|
|
71
|
-
mutation is rolled back and the service returns the original error. User
|
|
72
|
-
creation, role replacement, profile updates, and deletion use the same
|
|
73
|
-
transaction API for their multi-statement operations.
|
|
44
|
+
## Usage
|
|
74
45
|
|
|
75
46
|
```ts
|
|
76
|
-
import {
|
|
77
|
-
import { AuthDatabaseModule } from '@kurdel/auth-db';
|
|
47
|
+
import { apiKeyStrategy, AuthModule, jwtStrategy } from '@kurdel/auth';
|
|
48
|
+
import { AuthDatabaseModule, databaseAuthEventSink } from '@kurdel/auth-db';
|
|
78
49
|
|
|
79
50
|
const modules = [
|
|
80
|
-
new AuthDatabaseModule(),
|
|
51
|
+
new AuthDatabaseModule({ audit: true }),
|
|
52
|
+
|
|
81
53
|
new AuthModule({
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
name: 'api-key',
|
|
85
|
-
useFactory: ioc =>
|
|
86
|
-
new ApiKeyStrategy({
|
|
87
|
-
header: 'x-api-key',
|
|
88
|
-
credentials: ioc.get(AUTH_TOKENS.ApiKeyRepository),
|
|
89
|
-
users: ioc.get(AUTH_TOKENS.UserRepository),
|
|
90
|
-
usage: ioc.get(AUTH_TOKENS.ApiKeyUsageRecorder),
|
|
91
|
-
}),
|
|
92
|
-
},
|
|
93
|
-
],
|
|
54
|
+
events: databaseAuthEventSink(),
|
|
55
|
+
strategies: [apiKeyStrategy({ usage: true }), jwtStrategy({ sessions: true })],
|
|
94
56
|
}),
|
|
95
57
|
];
|
|
96
58
|
```
|
|
97
59
|
|
|
98
|
-
|
|
99
|
-
|
|
60
|
+
`databaseAuthEventSink()` connects `AuthModule` to the event store registered by
|
|
61
|
+
`AuthDatabaseModule({ audit: true })` without exposing its internal DI token.
|
|
62
|
+
|
|
63
|
+
## User management
|
|
64
|
+
|
|
65
|
+
`DatabaseUserService` provides transactional user administration.
|
|
66
|
+
|
|
67
|
+
Features include:
|
|
68
|
+
|
|
69
|
+
- create, update and delete users
|
|
70
|
+
- paginated user listing
|
|
71
|
+
- bulk status updates
|
|
72
|
+
- bulk role assignment
|
|
73
|
+
- bulk deletion
|
|
74
|
+
- role lifecycle management
|
|
75
|
+
- permission assignment
|
|
76
|
+
- dashboard statistics
|
|
77
|
+
|
|
78
|
+
Applications may model authorization as roles containing permissions.
|
|
79
|
+
`DatabaseAuthUserRepository` resolves the union of permissions from all
|
|
80
|
+
assigned roles into `AuthUser.permissions`.
|
|
81
|
+
|
|
82
|
+
## API keys
|
|
83
|
+
|
|
84
|
+
`DatabaseApiKeyService` manages the complete lifecycle of API keys.
|
|
85
|
+
|
|
86
|
+
It supports:
|
|
87
|
+
|
|
88
|
+
- issuing new keys
|
|
89
|
+
- listing key metadata and status history
|
|
90
|
+
- revoking keys
|
|
91
|
+
- expiration
|
|
92
|
+
- usage tracking
|
|
93
|
+
|
|
94
|
+
Only SHA-256 hashes are persisted. Raw API keys are returned only during
|
|
95
|
+
creation and are never stored.
|
|
96
|
+
|
|
97
|
+
`DatabaseApiKeyUsageRecorder` automatically updates `last_used_at` after
|
|
98
|
+
successful authentication.
|
|
99
|
+
|
|
100
|
+
## JWT sessions
|
|
101
|
+
|
|
102
|
+
`DatabaseJwtSessionService` manages server-side JWT sessions referenced by the
|
|
103
|
+
JWT `jti` claim.
|
|
104
|
+
|
|
105
|
+
It provides:
|
|
106
|
+
|
|
107
|
+
- `create()`
|
|
108
|
+
- `createRefreshable()`
|
|
109
|
+
- `refresh()`
|
|
110
|
+
- `list()`
|
|
111
|
+
- `revoke()`
|
|
112
|
+
- `revokeAll()`
|
|
113
|
+
|
|
114
|
+
Refresh tokens are stored only as SHA-256 hashes and rotated atomically on
|
|
115
|
+
every successful refresh.
|
|
116
|
+
|
|
117
|
+
Applications are free to choose independent lifetimes for access tokens and
|
|
118
|
+
refresh tokens.
|
|
119
|
+
|
|
120
|
+
`DatabaseJwtSessionRepository` resolves persisted session metadata used by
|
|
121
|
+
`JwtStrategy` to detect revoked sessions.
|
|
122
|
+
|
|
123
|
+
## Password authentication
|
|
124
|
+
|
|
125
|
+
Passwords are stored separately from user profiles.
|
|
126
|
+
|
|
127
|
+
The package provides:
|
|
128
|
+
|
|
129
|
+
- `DatabasePasswordCredentialRepository`
|
|
130
|
+
- `DatabasePasswordService`
|
|
131
|
+
- `PasswordAuthenticationService`
|
|
132
|
+
|
|
133
|
+
`DatabasePasswordService` hashes and stores passwords using
|
|
134
|
+
`ScryptPasswordHasher` by default.
|
|
135
|
+
|
|
136
|
+
Applications may replace the hasher:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
new AuthDatabaseModule({
|
|
140
|
+
passwordHasher: customHasher,
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Authentication audit
|
|
145
|
+
|
|
146
|
+
Audit persistence is optional.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
new AuthDatabaseModule({
|
|
150
|
+
audit: true,
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
When enabled:
|
|
155
|
+
|
|
156
|
+
- `DatabaseAuthEventStore` is registered
|
|
157
|
+
- management services persist audit events
|
|
158
|
+
- the same store can be passed to `AuthModule.events`
|
|
159
|
+
|
|
160
|
+
Authentication events are stored in the application's `auth_events` table.
|
|
161
|
+
|
|
162
|
+
API key creation, revocation and audit persistence execute within the same
|
|
163
|
+
database transaction.
|
|
164
|
+
|
|
165
|
+
## Configuration
|
|
166
|
+
|
|
167
|
+
Applications may customize table names and hashing implementations.
|
|
100
168
|
|
|
101
169
|
```ts
|
|
102
170
|
new AuthDatabaseModule({
|
|
@@ -104,22 +172,50 @@ new AuthDatabaseModule({
|
|
|
104
172
|
users: 'application_users',
|
|
105
173
|
apiKeys: 'application_api_keys',
|
|
106
174
|
},
|
|
107
|
-
|
|
175
|
+
|
|
176
|
+
apiKeyHasher: customApiKeyHasher,
|
|
177
|
+
passwordHasher: customPasswordHasher,
|
|
108
178
|
});
|
|
109
179
|
```
|
|
110
180
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
181
|
+
## Database schema
|
|
182
|
+
|
|
183
|
+
By default the package expects the following tables:
|
|
184
|
+
|
|
185
|
+
- `users`
|
|
186
|
+
- `roles`
|
|
187
|
+
- `user_roles`
|
|
188
|
+
- `permissions`
|
|
189
|
+
- `role_permissions`
|
|
190
|
+
- `api_keys`
|
|
191
|
+
- `jwt_sessions`
|
|
192
|
+
- `jwt_refresh_tokens`
|
|
193
|
+
- `password_credentials`
|
|
194
|
+
- `auth_events`
|
|
195
|
+
|
|
196
|
+
Applications own the schema and migrations.
|
|
197
|
+
|
|
198
|
+
See `sample/auth-db` for a complete runnable example including migrations and
|
|
199
|
+
seed data.
|
|
200
|
+
|
|
201
|
+
## Architecture
|
|
202
|
+
|
|
203
|
+
`@kurdel/auth-db` is an infrastructure package.
|
|
204
|
+
|
|
205
|
+
Its responsibilities are:
|
|
206
|
+
|
|
207
|
+
- resolve persisted authentication data
|
|
208
|
+
- manage authentication-related entities
|
|
209
|
+
- persist authentication audit events
|
|
210
|
+
- integrate authentication with relational databases
|
|
211
|
+
|
|
212
|
+
It does **not** implement authentication strategies.
|
|
213
|
+
|
|
214
|
+
Authentication strategies remain part of `@kurdel/auth`, while this package
|
|
215
|
+
provides the storage layer they depend on.
|
|
120
216
|
|
|
121
217
|
See the [`@kurdel/auth` documentation](../auth/README.md) for route protection,
|
|
122
|
-
authentication
|
|
218
|
+
authentication middleware, and custom authentication strategies.
|
|
123
219
|
|
|
124
220
|
## License
|
|
125
221
|
|
package/lib/api-key-hasher.d.ts
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## ApiKeyHasher
|
|
3
|
+
*
|
|
4
|
+
* Computes deterministic hashes of API keys for secure storage
|
|
5
|
+
* and lookup.
|
|
6
|
+
*
|
|
7
|
+
* Implementations must always produce the same hash for the same
|
|
8
|
+
* input key.
|
|
9
|
+
*/
|
|
1
10
|
export interface ApiKeyHasher {
|
|
2
11
|
hash(key: string): string;
|
|
3
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* SHA-256 implementation of {@link ApiKeyHasher}.
|
|
15
|
+
*
|
|
16
|
+
* Produces hexadecimal SHA-256 digests suitable for database
|
|
17
|
+
* storage and credential lookup.
|
|
18
|
+
*/
|
|
4
19
|
export declare class Sha256ApiKeyHasher implements ApiKeyHasher {
|
|
5
20
|
hash(key: string): string;
|
|
6
21
|
}
|
package/lib/api-key-hasher.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* SHA-256 implementation of {@link ApiKeyHasher}.
|
|
4
|
+
*
|
|
5
|
+
* Produces hexadecimal SHA-256 digests suitable for database
|
|
6
|
+
* storage and credential lookup.
|
|
7
|
+
*/
|
|
2
8
|
export class Sha256ApiKeyHasher {
|
|
3
9
|
hash(key) {
|
|
4
10
|
return crypto.createHash('sha256').update(key).digest('hex');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-key-hasher.js","sourceRoot":"","sources":["../src/api-key-hasher.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"api-key-hasher.js","sourceRoot":"","sources":["../src/api-key-hasher.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAejC;;;;;GAKG;AACH,MAAM,OAAO,kBAAkB;IAC7B,IAAI,CAAC,GAAW;QACd,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;CACF"}
|
|
@@ -2,6 +2,11 @@ import { type PasswordHasher } from '@kurdel/auth';
|
|
|
2
2
|
import { ModulePriority, type AppModule, type ProviderConfig } from '@kurdel/core/app';
|
|
3
3
|
import { type ApiKeyHasher } from './api-key-hasher.js';
|
|
4
4
|
import type { AuthDatabaseTables } from './auth-database-tables.js';
|
|
5
|
+
/**
|
|
6
|
+
* ## AuthDatabaseModuleConfig
|
|
7
|
+
*
|
|
8
|
+
* Configures database-backed authentication services.
|
|
9
|
+
*/
|
|
5
10
|
export interface AuthDatabaseModuleConfig {
|
|
6
11
|
tables?: Partial<AuthDatabaseTables>;
|
|
7
12
|
apiKeyHasher?: ApiKeyHasher;
|
|
@@ -9,6 +14,29 @@ export interface AuthDatabaseModuleConfig {
|
|
|
9
14
|
/** Enables persistence of sanitized authentication audit events. */
|
|
10
15
|
audit?: boolean;
|
|
11
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* ## AuthDatabaseModule
|
|
19
|
+
*
|
|
20
|
+
* Integrates `@kurdel/auth` with a relational database.
|
|
21
|
+
*
|
|
22
|
+
* Provides:
|
|
23
|
+
* - authentication repositories
|
|
24
|
+
* - application services
|
|
25
|
+
* - password authentication
|
|
26
|
+
* - JWT session persistence
|
|
27
|
+
* - API key management
|
|
28
|
+
* - optional authentication audit storage
|
|
29
|
+
*
|
|
30
|
+
* Responsibilities:
|
|
31
|
+
* - register database-backed auth infrastructure
|
|
32
|
+
* - expose public DI services
|
|
33
|
+
* - configure hashing implementations
|
|
34
|
+
*
|
|
35
|
+
* Non-responsibilities:
|
|
36
|
+
* - database migrations
|
|
37
|
+
* - runtime authentication pipeline
|
|
38
|
+
* - authorization policies
|
|
39
|
+
*/
|
|
12
40
|
export declare class AuthDatabaseModule implements AppModule {
|
|
13
41
|
readonly priority = ModulePriority.User;
|
|
14
42
|
readonly imports: {
|
|
@@ -13,6 +13,29 @@ import { DatabasePasswordCredentialRepository } from './database-password-creden
|
|
|
13
13
|
import { DatabasePasswordService } from './database-password-service.js';
|
|
14
14
|
import { DatabaseUserService } from './database-user-service.js';
|
|
15
15
|
import { AUTH_DB_TOKENS } from './tokens.js';
|
|
16
|
+
/**
|
|
17
|
+
* ## AuthDatabaseModule
|
|
18
|
+
*
|
|
19
|
+
* Integrates `@kurdel/auth` with a relational database.
|
|
20
|
+
*
|
|
21
|
+
* Provides:
|
|
22
|
+
* - authentication repositories
|
|
23
|
+
* - application services
|
|
24
|
+
* - password authentication
|
|
25
|
+
* - JWT session persistence
|
|
26
|
+
* - API key management
|
|
27
|
+
* - optional authentication audit storage
|
|
28
|
+
*
|
|
29
|
+
* Responsibilities:
|
|
30
|
+
* - register database-backed auth infrastructure
|
|
31
|
+
* - expose public DI services
|
|
32
|
+
* - configure hashing implementations
|
|
33
|
+
*
|
|
34
|
+
* Non-responsibilities:
|
|
35
|
+
* - database migrations
|
|
36
|
+
* - runtime authentication pipeline
|
|
37
|
+
* - authorization policies
|
|
38
|
+
*/
|
|
16
39
|
export class AuthDatabaseModule {
|
|
17
40
|
constructor(config = {}) {
|
|
18
41
|
this.priority = ModulePriority.User;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-database-module.js","sourceRoot":"","sources":["../src/auth-database-module.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,6BAA6B,EAC7B,oBAAoB,GAErB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAuC,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,EAAE,kBAAkB,EAAqB,MAAM,qBAAqB,CAAC;AAE5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,oCAAoC,EAAE,MAAM,8CAA8C,CAAC;AACpG,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-database-module.js","sourceRoot":"","sources":["../src/auth-database-module.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## AuthDatabaseTables
|
|
3
|
+
*
|
|
4
|
+
* Names of all database tables used by `@kurdel/auth-db`.
|
|
5
|
+
*
|
|
6
|
+
* Applications may override these names to integrate with an
|
|
7
|
+
* existing database schema.
|
|
8
|
+
*/
|
|
1
9
|
export interface AuthDatabaseTables {
|
|
2
10
|
users: string;
|
|
3
11
|
roles: string;
|
|
@@ -6,8 +14,26 @@ export interface AuthDatabaseTables {
|
|
|
6
14
|
rolePermissions: string;
|
|
7
15
|
apiKeys: string;
|
|
8
16
|
jwtSessions: string;
|
|
17
|
+
jwtRefreshTokens: string;
|
|
9
18
|
passwordCredentials: string;
|
|
10
19
|
authEvents: string;
|
|
11
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Default table names used by `@kurdel/auth-db`.
|
|
23
|
+
*/
|
|
12
24
|
export declare const DEFAULT_AUTH_DATABASE_TABLES: Readonly<AuthDatabaseTables>;
|
|
25
|
+
export declare class InvalidDatabaseTableNameError extends Error {
|
|
26
|
+
readonly identifier: string;
|
|
27
|
+
constructor(identifier: string);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolves the effective table mapping.
|
|
31
|
+
*
|
|
32
|
+
* User-provided table names override the defaults.
|
|
33
|
+
*
|
|
34
|
+
* All identifiers are validated to ensure they are safe for
|
|
35
|
+
* interpolation into SQL statements.
|
|
36
|
+
*
|
|
37
|
+
* @throws Error If any table name is not a valid SQL identifier.
|
|
38
|
+
*/
|
|
13
39
|
export declare function resolveAuthDatabaseTables(tables?: Partial<AuthDatabaseTables>): AuthDatabaseTables;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default table names used by `@kurdel/auth-db`.
|
|
3
|
+
*/
|
|
1
4
|
export const DEFAULT_AUTH_DATABASE_TABLES = {
|
|
2
5
|
users: 'users',
|
|
3
6
|
roles: 'roles',
|
|
@@ -6,17 +9,41 @@ export const DEFAULT_AUTH_DATABASE_TABLES = {
|
|
|
6
9
|
rolePermissions: 'role_permissions',
|
|
7
10
|
apiKeys: 'api_keys',
|
|
8
11
|
jwtSessions: 'jwt_sessions',
|
|
12
|
+
jwtRefreshTokens: 'jwt_refresh_tokens',
|
|
9
13
|
passwordCredentials: 'password_credentials',
|
|
10
14
|
authEvents: 'auth_events',
|
|
11
15
|
};
|
|
16
|
+
export class InvalidDatabaseTableNameError extends Error {
|
|
17
|
+
constructor(identifier) {
|
|
18
|
+
super(`Invalid auth database table name '${identifier}'`);
|
|
19
|
+
this.identifier = identifier;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolves the effective table mapping.
|
|
24
|
+
*
|
|
25
|
+
* User-provided table names override the defaults.
|
|
26
|
+
*
|
|
27
|
+
* All identifiers are validated to ensure they are safe for
|
|
28
|
+
* interpolation into SQL statements.
|
|
29
|
+
*
|
|
30
|
+
* @throws Error If any table name is not a valid SQL identifier.
|
|
31
|
+
*/
|
|
12
32
|
export function resolveAuthDatabaseTables(tables = {}) {
|
|
13
33
|
const resolved = { ...DEFAULT_AUTH_DATABASE_TABLES, ...tables };
|
|
14
34
|
Object.values(resolved).forEach(assertSqlIdentifier);
|
|
15
35
|
return resolved;
|
|
16
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Ensures that a table name is a valid SQL identifier.
|
|
39
|
+
*
|
|
40
|
+
* SQL identifiers cannot be bound as query parameters.
|
|
41
|
+
* Therefore every configured table name is validated before being
|
|
42
|
+
* interpolated into SQL statements.
|
|
43
|
+
*/
|
|
17
44
|
function assertSqlIdentifier(identifier) {
|
|
18
45
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {
|
|
19
|
-
throw new
|
|
46
|
+
throw new InvalidDatabaseTableNameError(identifier);
|
|
20
47
|
}
|
|
21
48
|
}
|
|
22
49
|
//# sourceMappingURL=auth-database-tables.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-database-tables.js","sourceRoot":"","sources":["../src/auth-database-tables.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-database-tables.js","sourceRoot":"","sources":["../src/auth-database-tables.ts"],"names":[],"mappings":"AAqBA;;GAEG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAiC;IACxE,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,YAAY;IACvB,WAAW,EAAE,aAAa;IAC1B,eAAe,EAAE,kBAAkB;IACnC,OAAO,EAAE,UAAU;IACnB,WAAW,EAAE,cAAc;IAC3B,gBAAgB,EAAE,oBAAoB;IACtC,mBAAmB,EAAE,sBAAsB;IAC3C,UAAU,EAAE,aAAa;CAC1B,CAAC;AAEF,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IACtD,YAAqB,UAAkB;QACrC,KAAK,CAAC,qCAAqC,UAAU,GAAG,CAAC,CAAC;QADvC,eAAU,GAAV,UAAU,CAAQ;IAEvC,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CACvC,SAAsC,EAAE;IAExC,MAAM,QAAQ,GAAG,EAAE,GAAG,4BAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IAChE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,UAAkB;IAC7C,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,6BAA6B,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC;AACH,CAAC"}
|
|
@@ -2,10 +2,39 @@ import type { ApiKeyCredential, ApiKeyRepository } from '@kurdel/auth';
|
|
|
2
2
|
import type { Database } from '@kurdel/db';
|
|
3
3
|
import type { ApiKeyHasher } from './api-key-hasher.js';
|
|
4
4
|
import { type AuthDatabaseTables } from './auth-database-tables.js';
|
|
5
|
+
/**
|
|
6
|
+
* ## DatabaseApiKeyRepository
|
|
7
|
+
*
|
|
8
|
+
* Repository that resolves persisted API key credentials for
|
|
9
|
+
* authentication.
|
|
10
|
+
*
|
|
11
|
+
* Responsibilities:
|
|
12
|
+
* - locate API key credentials by plaintext API key
|
|
13
|
+
* - resolve credential metadata required for authentication
|
|
14
|
+
*
|
|
15
|
+
* Guarantees:
|
|
16
|
+
* - hashes incoming API keys before querying the database
|
|
17
|
+
* - never exposes or returns stored key hashes
|
|
18
|
+
* - remains database-agnostic (SQLite/PostgreSQL)
|
|
19
|
+
*
|
|
20
|
+
* Non-responsibilities:
|
|
21
|
+
* - API key issuance
|
|
22
|
+
* - API key revocation
|
|
23
|
+
* - usage recording
|
|
24
|
+
* - authorization policy evaluation
|
|
25
|
+
* - HTTP request handling
|
|
26
|
+
*/
|
|
5
27
|
export declare class DatabaseApiKeyRepository implements ApiKeyRepository {
|
|
6
28
|
private readonly db;
|
|
7
29
|
private readonly hasher;
|
|
8
30
|
private readonly tables;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new database-backed API key repository.
|
|
33
|
+
*
|
|
34
|
+
* @param db Database abstraction used for credential lookups.
|
|
35
|
+
* @param hasher Hashing strategy used to derive lookup hashes.
|
|
36
|
+
* @param tables Optional table name overrides.
|
|
37
|
+
*/
|
|
9
38
|
constructor(db: Database, hasher: ApiKeyHasher, tables?: Partial<AuthDatabaseTables>);
|
|
10
39
|
findByKey(key: string): Promise<ApiKeyCredential | null>;
|
|
11
40
|
}
|
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
import { resolveAuthDatabaseTables } from './auth-database-tables.js';
|
|
2
|
+
/**
|
|
3
|
+
* ## DatabaseApiKeyRepository
|
|
4
|
+
*
|
|
5
|
+
* Repository that resolves persisted API key credentials for
|
|
6
|
+
* authentication.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* - locate API key credentials by plaintext API key
|
|
10
|
+
* - resolve credential metadata required for authentication
|
|
11
|
+
*
|
|
12
|
+
* Guarantees:
|
|
13
|
+
* - hashes incoming API keys before querying the database
|
|
14
|
+
* - never exposes or returns stored key hashes
|
|
15
|
+
* - remains database-agnostic (SQLite/PostgreSQL)
|
|
16
|
+
*
|
|
17
|
+
* Non-responsibilities:
|
|
18
|
+
* - API key issuance
|
|
19
|
+
* - API key revocation
|
|
20
|
+
* - usage recording
|
|
21
|
+
* - authorization policy evaluation
|
|
22
|
+
* - HTTP request handling
|
|
23
|
+
*/
|
|
2
24
|
export class DatabaseApiKeyRepository {
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new database-backed API key repository.
|
|
27
|
+
*
|
|
28
|
+
* @param db Database abstraction used for credential lookups.
|
|
29
|
+
* @param hasher Hashing strategy used to derive lookup hashes.
|
|
30
|
+
* @param tables Optional table name overrides.
|
|
31
|
+
*/
|
|
3
32
|
constructor(db, hasher, tables = {}) {
|
|
4
33
|
this.db = db;
|
|
5
34
|
this.hasher = hasher;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database-api-key-repository.js","sourceRoot":"","sources":["../src/database-api-key-repository.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,yBAAyB,EAA2B,MAAM,2BAA2B,CAAC;AAS/F,MAAM,OAAO,wBAAwB;IAGnC,YACmB,EAAY,EACZ,MAAoB,EACrC,SAAsC,EAAE;QAFvB,OAAE,GAAF,EAAE,CAAU;QACZ,WAAM,GAAN,MAAM,CAAc;QAGrC,IAAI,CAAC,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;YAChC,GAAG,EAAE;gBACH,wCAAwC;gBACxC,QAAQ,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;gBAC7B,qBAAqB;aACtB,CAAC,IAAI,CAAC,GAAG,CAAC;YACX,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChC,CAAC,CAA6B,CAAC;QAChC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,MAAM,EAAE,MAAM,CAAC,OAAO;YACtB,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,QAAQ;YACnC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;SACvE,CAAC;IACJ,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"database-api-key-repository.js","sourceRoot":"","sources":["../src/database-api-key-repository.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,yBAAyB,EAA2B,MAAM,2BAA2B,CAAC;AAS/F;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,wBAAwB;IAGnC;;;;;;OAMG;IACH,YACmB,EAAY,EACZ,MAAoB,EACrC,SAAsC,EAAE;QAFvB,OAAE,GAAF,EAAE,CAAU;QACZ,WAAM,GAAN,MAAM,CAAc;QAGrC,IAAI,CAAC,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;YAChC,GAAG,EAAE;gBACH,wCAAwC;gBACxC,QAAQ,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;gBAC7B,qBAAqB;aACtB,CAAC,IAAI,CAAC,GAAG,CAAC;YACX,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChC,CAAC,CAA6B,CAAC;QAChC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,MAAM,EAAE,MAAM,CAAC,OAAO;YACtB,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,QAAQ;YACnC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;SACvE,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -37,12 +37,45 @@ export declare class ApiKeyNotFoundError extends Error {
|
|
|
37
37
|
readonly apiKeyId: string;
|
|
38
38
|
constructor(userId: number, apiKeyId: string);
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* ## DatabaseApiKeyService
|
|
42
|
+
*
|
|
43
|
+
* Application service responsible for issuing, listing and revoking
|
|
44
|
+
* database-backed API keys.
|
|
45
|
+
*
|
|
46
|
+
* Responsibilities:
|
|
47
|
+
* - issue API keys for active users
|
|
48
|
+
* - list API keys owned by a user
|
|
49
|
+
* - revoke existing API keys
|
|
50
|
+
* - publish API key lifecycle audit events
|
|
51
|
+
*
|
|
52
|
+
* Guarantees:
|
|
53
|
+
* - only active users can receive new API keys
|
|
54
|
+
* - API keys are persisted atomically using database transactions
|
|
55
|
+
* - plaintext API keys are returned only during creation
|
|
56
|
+
* - remains database-agnostic (SQLite/PostgreSQL)
|
|
57
|
+
*
|
|
58
|
+
* Non-responsibilities:
|
|
59
|
+
* - API key authentication
|
|
60
|
+
* - API key hash verification
|
|
61
|
+
* - authorization policy evaluation
|
|
62
|
+
* - HTTP request handling
|
|
63
|
+
*/
|
|
40
64
|
export declare class DatabaseApiKeyService {
|
|
41
65
|
private readonly db;
|
|
42
66
|
private readonly hasher;
|
|
43
67
|
private readonly events?;
|
|
44
68
|
private readonly now;
|
|
45
69
|
private readonly tables;
|
|
70
|
+
/**
|
|
71
|
+
* Creates a new database-backed API key management service.
|
|
72
|
+
*
|
|
73
|
+
* @param db Database abstraction used for persistence.
|
|
74
|
+
* @param hasher Hashing strategy used before storing API keys.
|
|
75
|
+
* @param tables Optional table name overrides.
|
|
76
|
+
* @param events Optional authentication audit event sink.
|
|
77
|
+
* @param now Clock provider used for timestamps and testing.
|
|
78
|
+
*/
|
|
46
79
|
constructor(db: Database, hasher: ApiKeyHasher, tables?: Partial<AuthDatabaseTables>, events?: TransactionalAuthEventSink | undefined, now?: () => Date);
|
|
47
80
|
list(userId: number): Promise<ApiKeyMetadata[]>;
|
|
48
81
|
create(input: CreateApiKeyInput): Promise<CreatedApiKey>;
|