@kurdel/auth 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +253 -0
  3. package/lib/domain/auth-context.d.ts +8 -0
  4. package/lib/domain/auth-context.js +2 -0
  5. package/lib/domain/auth-context.js.map +1 -0
  6. package/lib/domain/auth-event-sink-provider.d.ts +7 -0
  7. package/lib/domain/auth-event-sink-provider.js +2 -0
  8. package/lib/domain/auth-event-sink-provider.js.map +1 -0
  9. package/lib/domain/auth-event.d.ts +30 -0
  10. package/lib/domain/auth-event.js +5 -0
  11. package/lib/domain/auth-event.js.map +1 -0
  12. package/lib/domain/auth-strategy-provider.d.ts +9 -0
  13. package/lib/domain/auth-strategy-provider.js +2 -0
  14. package/lib/domain/auth-strategy-provider.js.map +1 -0
  15. package/lib/domain/auth-strategy.d.ts +17 -0
  16. package/lib/domain/auth-strategy.js +2 -0
  17. package/lib/domain/auth-strategy.js.map +1 -0
  18. package/lib/domain/authorization-policy-provider.d.ts +9 -0
  19. package/lib/domain/authorization-policy-provider.js +2 -0
  20. package/lib/domain/authorization-policy-provider.js.map +1 -0
  21. package/lib/domain/authorization-policy.d.ts +6 -0
  22. package/lib/domain/authorization-policy.js +2 -0
  23. package/lib/domain/authorization-policy.js.map +1 -0
  24. package/lib/domain/index.d.ts +7 -0
  25. package/lib/domain/index.js +8 -0
  26. package/lib/domain/index.js.map +1 -0
  27. package/lib/index.d.ts +6 -0
  28. package/lib/index.js +7 -0
  29. package/lib/index.js.map +1 -0
  30. package/lib/infra/in-memory/in-memory-api-key-repository.d.ts +7 -0
  31. package/lib/infra/in-memory/in-memory-api-key-repository.js +10 -0
  32. package/lib/infra/in-memory/in-memory-api-key-repository.js.map +1 -0
  33. package/lib/infra/in-memory/in-memory-auth-user-repository.d.ts +8 -0
  34. package/lib/infra/in-memory/in-memory-auth-user-repository.js +10 -0
  35. package/lib/infra/in-memory/in-memory-auth-user-repository.js.map +1 -0
  36. package/lib/infra/in-memory/in-memory-jwt-repository.d.ts +7 -0
  37. package/lib/infra/in-memory/in-memory-jwt-repository.js +8 -0
  38. package/lib/infra/in-memory/in-memory-jwt-repository.js.map +1 -0
  39. package/lib/infra/in-memory/index.d.ts +3 -0
  40. package/lib/infra/in-memory/index.js +4 -0
  41. package/lib/infra/in-memory/index.js.map +1 -0
  42. package/lib/infra/index.d.ts +1 -0
  43. package/lib/infra/index.js +2 -0
  44. package/lib/infra/index.js.map +1 -0
  45. package/lib/repositories/api-key/api-key-repository.d.ts +30 -0
  46. package/lib/repositories/api-key/api-key-repository.js +2 -0
  47. package/lib/repositories/api-key/api-key-repository.js.map +1 -0
  48. package/lib/repositories/api-key/api-key-usage-recorder.d.ts +4 -0
  49. package/lib/repositories/api-key/api-key-usage-recorder.js +2 -0
  50. package/lib/repositories/api-key/api-key-usage-recorder.js.map +1 -0
  51. package/lib/repositories/api-key/index.d.ts +2 -0
  52. package/lib/repositories/api-key/index.js +3 -0
  53. package/lib/repositories/api-key/index.js.map +1 -0
  54. package/lib/repositories/index.d.ts +3 -0
  55. package/lib/repositories/index.js +4 -0
  56. package/lib/repositories/index.js.map +1 -0
  57. package/lib/repositories/jwt/index.d.ts +1 -0
  58. package/lib/repositories/jwt/index.js +2 -0
  59. package/lib/repositories/jwt/index.js.map +1 -0
  60. package/lib/repositories/jwt/jwt-repository.d.ts +3 -0
  61. package/lib/repositories/jwt/jwt-repository.js +2 -0
  62. package/lib/repositories/jwt/jwt-repository.js.map +1 -0
  63. package/lib/repositories/user/auth-user-repository.d.ts +11 -0
  64. package/lib/repositories/user/auth-user-repository.js +2 -0
  65. package/lib/repositories/user/auth-user-repository.js.map +1 -0
  66. package/lib/repositories/user/index.d.ts +1 -0
  67. package/lib/repositories/user/index.js +2 -0
  68. package/lib/repositories/user/index.js.map +1 -0
  69. package/lib/runtime/auth-module.d.ts +64 -0
  70. package/lib/runtime/auth-module.js +83 -0
  71. package/lib/runtime/auth-module.js.map +1 -0
  72. package/lib/runtime/auth-strategy-registry.d.ts +25 -0
  73. package/lib/runtime/auth-strategy-registry.js +33 -0
  74. package/lib/runtime/auth-strategy-registry.js.map +1 -0
  75. package/lib/runtime/authorization-policy-registry.d.ts +8 -0
  76. package/lib/runtime/authorization-policy-registry.js +16 -0
  77. package/lib/runtime/authorization-policy-registry.js.map +1 -0
  78. package/lib/runtime/create-auth-middleware.d.ts +5 -0
  79. package/lib/runtime/create-auth-middleware.js +89 -0
  80. package/lib/runtime/create-auth-middleware.js.map +1 -0
  81. package/lib/runtime/index.d.ts +4 -0
  82. package/lib/runtime/index.js +5 -0
  83. package/lib/runtime/index.js.map +1 -0
  84. package/lib/strategies/api-key/api-key-strategy.d.ts +22 -0
  85. package/lib/strategies/api-key/api-key-strategy.js +36 -0
  86. package/lib/strategies/api-key/api-key-strategy.js.map +1 -0
  87. package/lib/strategies/api-key/index.d.ts +1 -0
  88. package/lib/strategies/api-key/index.js +2 -0
  89. package/lib/strategies/api-key/index.js.map +1 -0
  90. package/lib/strategies/index.d.ts +2 -0
  91. package/lib/strategies/index.js +3 -0
  92. package/lib/strategies/index.js.map +1 -0
  93. package/lib/strategies/jwt/index.d.ts +2 -0
  94. package/lib/strategies/jwt/index.js +3 -0
  95. package/lib/strategies/jwt/index.js.map +1 -0
  96. package/lib/strategies/jwt/jwt-service.d.ts +50 -0
  97. package/lib/strategies/jwt/jwt-service.js +87 -0
  98. package/lib/strategies/jwt/jwt-service.js.map +1 -0
  99. package/lib/strategies/jwt/jwt-strategy.d.ts +27 -0
  100. package/lib/strategies/jwt/jwt-strategy.js +45 -0
  101. package/lib/strategies/jwt/jwt-strategy.js.map +1 -0
  102. package/lib/tokens.d.ts +11 -0
  103. package/lib/tokens.js +13 -0
  104. package/lib/tokens.js.map +1 -0
  105. package/package.json +56 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Andrii Sorokin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # @kurdel/auth
2
+
3
+ Storage-agnostic authentication strategies and authorization middleware for
4
+ Kurdel applications.
5
+
6
+ The package authenticates incoming requests, resolves the current application
7
+ user, and exposes the result through `HttpContext`. Persistence is supplied by
8
+ the application or by adapters such as `@kurdel/auth-db`.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @kurdel/auth
14
+ ```
15
+
16
+ ## Configure authentication
17
+
18
+ Register one or more named strategies with `AuthModule`. A strategy instance
19
+ can be supplied directly or created from the application container:
20
+
21
+ ```ts
22
+ import { ApiKeyStrategy, AUTH_TOKENS, AuthModule } from '@kurdel/auth';
23
+
24
+ const auth = new AuthModule({
25
+ strategies: [
26
+ {
27
+ name: 'api-key',
28
+ useFactory: ioc =>
29
+ new ApiKeyStrategy({
30
+ header: 'x-api-key',
31
+ credentials: ioc.get(AUTH_TOKENS.ApiKeyRepository),
32
+ users: ioc.get(AUTH_TOKENS.UserRepository),
33
+ usage: ioc.get(AUTH_TOKENS.ApiKeyUsageRecorder),
34
+ }),
35
+ },
36
+ ],
37
+ });
38
+ ```
39
+
40
+ `AuthModule` registers the authentication middleware automatically. Strategy
41
+ names are application-defined and are referenced by route metadata.
42
+
43
+ ## Protect routes
44
+
45
+ Set `auth.strategy` to require authentication. Add `roles` when at least one of
46
+ the listed roles is required:
47
+
48
+ ```ts
49
+ import { Controller, Ok, route, type HttpContext } from '@kurdel/core/http';
50
+
51
+ export class AccountController extends Controller {
52
+ readonly routes = {
53
+ profile: route({
54
+ method: 'GET',
55
+ path: '/profile',
56
+ auth: { strategy: 'api-key' },
57
+ })(this.profile),
58
+ admin: route({
59
+ method: 'GET',
60
+ path: '/admin',
61
+ auth: { strategy: 'api-key', roles: ['admin'] },
62
+ })(this.admin),
63
+ health: route({
64
+ method: 'GET',
65
+ path: '/health',
66
+ auth: { public: true },
67
+ })(this.health),
68
+ };
69
+
70
+ async profile(ctx: HttpContext) {
71
+ return Ok({ user: ctx.auth?.user });
72
+ }
73
+
74
+ async admin(ctx: HttpContext) {
75
+ return Ok({ authenticatedWith: ctx.auth?.strategy });
76
+ }
77
+
78
+ async health() {
79
+ return Ok({ status: 'up' });
80
+ }
81
+ }
82
+ ```
83
+
84
+ Controller-level authentication can define defaults for every route. Route
85
+ metadata may override those defaults, and `{ public: true }` makes an
86
+ individual route public.
87
+
88
+ Authentication failures return `401 Unauthorized`. An authenticated user who
89
+ does not have any required role receives `403 Forbidden`. Referencing an
90
+ unregistered strategy is treated as an application configuration error and
91
+ returns `500 Internal Server Error`.
92
+
93
+ ## Authorization policies
94
+
95
+ Named policies handle application-specific access rules that cannot be
96
+ expressed by roles alone. Register them alongside strategies:
97
+
98
+ ```ts
99
+ const auth = new AuthModule({
100
+ strategies: [/* ... */],
101
+ policies: [
102
+ {
103
+ name: 'manage-users',
104
+ use: {
105
+ authorize: (auth, ctx) =>
106
+ auth.credential?.type === 'api-key' &&
107
+ auth.user.roles.includes('admin') &&
108
+ ctx.req.method !== 'TRACE',
109
+ },
110
+ },
111
+ ],
112
+ });
113
+ ```
114
+
115
+ Reference policies from route metadata:
116
+
117
+ ```ts
118
+ route({
119
+ method: 'POST',
120
+ path: '/users',
121
+ auth: {
122
+ strategy: 'api-key',
123
+ policies: ['manage-users'],
124
+ },
125
+ })(this.createUser);
126
+ ```
127
+
128
+ A policy receives the complete `AuthContext` and current `HttpContext`, and may
129
+ return a boolean or a promise. When several policies are listed, every policy
130
+ must grant access. Policies and `roles` may be combined; both checks must then
131
+ succeed. A rejected policy returns `403 Forbidden`, while an unknown policy is
132
+ reported as an application configuration error.
133
+
134
+ Policy providers also support `useFactory`, allowing policies to resolve
135
+ application services from the dependency container.
136
+
137
+ ## Security events
138
+
139
+ Configure an event sink to observe sanitized authentication and authorization
140
+ activity:
141
+
142
+ ```ts
143
+ new AuthModule({
144
+ events: {
145
+ useFactory: ioc => ioc.get(APP_TOKENS.AuthEventSink),
146
+ },
147
+ strategies: [/* ... */],
148
+ });
149
+ ```
150
+
151
+ The package reports successful and failed authentication plus authorization
152
+ denials. API-key management services may additionally report credential issue
153
+ and revocation events. Events contain timestamps, strategy names, user and
154
+ credential identifiers, safe reason codes, and policy names. Raw API keys,
155
+ JWTs, credential hashes, headers, and request bodies are never part of the
156
+ event contract.
157
+
158
+ Without configuration, `AuthModule` uses `NoopAuthEventSink`. Applications may
159
+ provide an instance or a factory-backed sink. Sink failures are propagated so
160
+ operators can choose an appropriate durable or failure-tolerant implementation
161
+ instead of having audit loss silently hidden by the framework.
162
+
163
+ ## Authentication context
164
+
165
+ After successful authentication, middleware attaches an `AuthContext` to
166
+ `ctx.auth`:
167
+
168
+ ```ts
169
+ interface AuthContext {
170
+ user: AuthUser;
171
+ strategy: string;
172
+ credential?: {
173
+ type: string;
174
+ id?: string;
175
+ };
176
+ claims?: Record<string, unknown>;
177
+ }
178
+ ```
179
+
180
+ - `user` is the current application identity and its current roles.
181
+ - `strategy` is the registered name selected by route metadata.
182
+ - `credential` identifies the credential kind and, when available, its stable
183
+ identifier. It never contains the raw API key or JWT.
184
+ - `claims` contains verified strategy-specific claims, such as a JWT payload.
185
+
186
+ `ctx.user` remains available as an alias of `ctx.auth.user` for compatibility.
187
+ New code that needs authentication metadata should use `ctx.auth`.
188
+
189
+ The built-in API-key strategy exposes `credential.type` as `api-key` and uses
190
+ the repository credential ID when one exists. The JWT strategy exposes
191
+ `credential.type` as `jwt`, uses the `jti` claim as its optional ID, and places
192
+ the verified payload in `claims`.
193
+
194
+ ## User and credential repositories
195
+
196
+ Authentication strategies do not own user data. Both built-in strategies load
197
+ the current identity from `AuthUserRepository`, making the repository the
198
+ source of truth for current roles and disabled users:
199
+
200
+ ```ts
201
+ interface AuthUserRepository {
202
+ findById(id: string | number): Promise<AuthUser | null>;
203
+ }
204
+ ```
205
+
206
+ `ApiKeyStrategy` additionally requires an `ApiKeyRepository`. Its
207
+ implementation must return `null` for unknown credentials and describe known
208
+ credentials without returning their raw secret. Revoked and expired API keys
209
+ are rejected before the user is authenticated.
210
+
211
+ Applications may provide an `ApiKeyUsageRecorder` to capture successful use of
212
+ credentials with stable IDs. The strategy records usage only after the key is
213
+ accepted and its current user is resolved; rejected, expired, revoked, and
214
+ orphaned credentials are never recorded.
215
+
216
+ For database-backed implementations, use `@kurdel/auth-db`. Applications may
217
+ also implement these interfaces for another database, an external identity
218
+ service, or an in-memory test setup.
219
+
220
+ ## Custom strategies
221
+
222
+ Implement `AuthStrategy` to support another authentication mechanism:
223
+
224
+ ```ts
225
+ import type { AuthStrategy, AuthenticationResult } from '@kurdel/auth';
226
+ import type { HttpRequest } from '@kurdel/common';
227
+
228
+ class SessionStrategy implements AuthStrategy {
229
+ async authenticate(req: HttpRequest): Promise<AuthenticationResult | null> {
230
+ const session = await loadSession(req);
231
+ if (!session) return null;
232
+
233
+ return {
234
+ user: session.user,
235
+ credential: { type: 'session', id: session.id },
236
+ };
237
+ }
238
+ }
239
+ ```
240
+
241
+ A strategy returns `null` when the request cannot be authenticated. On
242
+ success, it returns the user and optional safe credential metadata or verified
243
+ claims. The middleware adds the registered strategy name to the final context.
244
+
245
+ ## Database integration
246
+
247
+ See [`@kurdel/auth-db`](../auth-db/README.md) for reusable database repository
248
+ adapters and [`sample/auth-db`](../../sample/auth-db/README.md) for a runnable
249
+ SQLite application with API-key authentication and a React administration UI.
250
+
251
+ ## License
252
+
253
+ MIT © Andrii Sorokin
@@ -0,0 +1,8 @@
1
+ import type { AuthCredential, AuthUser } from '@kurdel/common';
2
+ export type { AuthContext, AuthCredential } from '@kurdel/common';
3
+ /** Data produced by a strategy before middleware attaches the strategy name. */
4
+ export interface AuthenticationResult<TUser extends AuthUser = AuthUser> {
5
+ user: TUser;
6
+ credential?: AuthCredential;
7
+ claims?: Record<string, unknown>;
8
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auth-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-context.js","sourceRoot":"","sources":["../../src/domain/auth-context.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { Container } from '@kurdel/ioc';
2
+ import type { AuthEventSink } from './auth-event.js';
3
+ export type AuthEventSinkProvider = {
4
+ use: AuthEventSink;
5
+ } | {
6
+ useFactory: (container: Container) => AuthEventSink;
7
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auth-event-sink-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-event-sink-provider.js","sourceRoot":"","sources":["../../src/domain/auth-event-sink-provider.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import type { AuthCredential, AuthUser } from '@kurdel/common';
2
+ type AuthEventBase = {
3
+ occurredAt: Date;
4
+ userId?: AuthUser['id'];
5
+ credential?: AuthCredential;
6
+ };
7
+ export type AuthEvent = (AuthEventBase & {
8
+ type: 'authentication.succeeded';
9
+ strategy: string;
10
+ }) | (AuthEventBase & {
11
+ type: 'authentication.failed';
12
+ strategy: string;
13
+ reason: 'invalid-credential';
14
+ }) | (AuthEventBase & {
15
+ type: 'authorization.denied';
16
+ strategy?: string;
17
+ reason: 'missing-role' | 'missing-authentication' | 'policy-rejected';
18
+ policy?: string;
19
+ }) | (AuthEventBase & {
20
+ type: 'api-key.issued' | 'api-key.revoked';
21
+ });
22
+ /** Receives sanitized authentication and authorization lifecycle events. */
23
+ export interface AuthEventSink {
24
+ report(event: AuthEvent): Promise<void> | void;
25
+ }
26
+ /** Default sink used when an application does not configure event reporting. */
27
+ export declare class NoopAuthEventSink implements AuthEventSink {
28
+ report(_event: AuthEvent): void;
29
+ }
30
+ export {};
@@ -0,0 +1,5 @@
1
+ /** Default sink used when an application does not configure event reporting. */
2
+ export class NoopAuthEventSink {
3
+ report(_event) { }
4
+ }
5
+ //# sourceMappingURL=auth-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-event.js","sourceRoot":"","sources":["../../src/domain/auth-event.ts"],"names":[],"mappings":"AAiCA,gFAAgF;AAChF,MAAM,OAAO,iBAAiB;IAC5B,MAAM,CAAC,MAAiB,IAAS,CAAC;CACnC"}
@@ -0,0 +1,9 @@
1
+ import type { Container } from '@kurdel/ioc';
2
+ import type { AuthStrategy } from '../domain/index.js';
3
+ export type AuthStrategyProvider = {
4
+ name: string;
5
+ use: AuthStrategy;
6
+ } | {
7
+ name: string;
8
+ useFactory: (c: Container) => AuthStrategy;
9
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auth-strategy-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-strategy-provider.js","sourceRoot":"","sources":["../../src/domain/auth-strategy-provider.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import type { HttpRequest } from '@kurdel/common';
2
+ import type { AuthenticationResult } from './auth-context.js';
3
+ /**
4
+ * ## AuthStrategy
5
+ *
6
+ * A pluggable authentication mechanism.
7
+ * Each strategy decides how to extract and validate credentials
8
+ * from the incoming HTTP request.
9
+ *
10
+ * The strategy:
11
+ * - returns an AuthenticationResult on success
12
+ * - returns null if authentication fails
13
+ * - must NOT throw on invalid credentials
14
+ */
15
+ export interface AuthStrategy {
16
+ authenticate(req: HttpRequest): Promise<AuthenticationResult | null>;
17
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auth-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-strategy.js","sourceRoot":"","sources":["../../src/domain/auth-strategy.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { Container } from '@kurdel/ioc';
2
+ import type { AuthorizationPolicy } from './authorization-policy.js';
3
+ export type AuthorizationPolicyProvider = {
4
+ name: string;
5
+ use: AuthorizationPolicy;
6
+ } | {
7
+ name: string;
8
+ useFactory: (container: Container) => AuthorizationPolicy;
9
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=authorization-policy-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization-policy-provider.js","sourceRoot":"","sources":["../../src/domain/authorization-policy-provider.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { AuthContext } from '@kurdel/common';
2
+ import type { HttpContext } from '@kurdel/core/http';
3
+ /** Performs an application-specific authorization check for a request. */
4
+ export interface AuthorizationPolicy {
5
+ authorize(auth: Readonly<AuthContext>, ctx: HttpContext): boolean | Promise<boolean>;
6
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=authorization-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization-policy.js","sourceRoot":"","sources":["../../src/domain/authorization-policy.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export * from './auth-context.js';
2
+ export * from './auth-event.js';
3
+ export * from './auth-event-sink-provider.js';
4
+ export * from './auth-strategy-provider.js';
5
+ export * from './auth-strategy.js';
6
+ export * from './authorization-policy.js';
7
+ export * from './authorization-policy-provider.js';
@@ -0,0 +1,8 @@
1
+ export * from './auth-context.js';
2
+ export * from './auth-event.js';
3
+ export * from './auth-event-sink-provider.js';
4
+ export * from './auth-strategy-provider.js';
5
+ export * from './auth-strategy.js';
6
+ export * from './authorization-policy.js';
7
+ export * from './authorization-policy-provider.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './domain/index.js';
2
+ export * from './infra/index.js';
3
+ export * from './repositories/index.js';
4
+ export * from './runtime/index.js';
5
+ export * from './strategies/index.js';
6
+ export * from './tokens.js';
package/lib/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './domain/index.js';
2
+ export * from './infra/index.js';
3
+ export * from './repositories/index.js';
4
+ export * from './runtime/index.js';
5
+ export * from './strategies/index.js';
6
+ export * from './tokens.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,aAAa,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { ApiKeyCredential, ApiKeyRepository } from '../../repositories/index.js';
2
+ /** In-memory credential source intended for tests, demos and bootstrap code. */
3
+ export declare class InMemoryApiKeyRepository implements ApiKeyRepository {
4
+ private readonly keys;
5
+ constructor(keys: Record<string, ApiKeyCredential>);
6
+ findByKey(key: string): ApiKeyCredential | null;
7
+ }
@@ -0,0 +1,10 @@
1
+ /** In-memory credential source intended for tests, demos and bootstrap code. */
2
+ export class InMemoryApiKeyRepository {
3
+ constructor(keys) {
4
+ this.keys = keys;
5
+ }
6
+ findByKey(key) {
7
+ return this.keys[key] ?? null;
8
+ }
9
+ }
10
+ //# sourceMappingURL=in-memory-api-key-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-api-key-repository.js","sourceRoot":"","sources":["../../../src/infra/in-memory/in-memory-api-key-repository.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,MAAM,OAAO,wBAAwB;IACnC,YAA6B,IAAsC;QAAtC,SAAI,GAAJ,IAAI,CAAkC;IAAG,CAAC;IAEvE,SAAS,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { AuthUser } from '@kurdel/common';
2
+ import type { AuthUserRepository } from '../../repositories/index.js';
3
+ /** In-memory identity source intended for tests, demos and bootstrap code. */
4
+ export declare class InMemoryAuthUserRepository implements AuthUserRepository {
5
+ private readonly users;
6
+ constructor(users: AuthUser[]);
7
+ findById(id: string | number): AuthUser | null;
8
+ }
@@ -0,0 +1,10 @@
1
+ /** In-memory identity source intended for tests, demos and bootstrap code. */
2
+ export class InMemoryAuthUserRepository {
3
+ constructor(users) {
4
+ this.users = users;
5
+ }
6
+ findById(id) {
7
+ return this.users.find(user => user.id === id) ?? null;
8
+ }
9
+ }
10
+ //# sourceMappingURL=in-memory-auth-user-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-auth-user-repository.js","sourceRoot":"","sources":["../../../src/infra/in-memory/in-memory-auth-user-repository.ts"],"names":[],"mappings":"AAIA,8EAA8E;AAC9E,MAAM,OAAO,0BAA0B;IACrC,YAA6B,KAAiB;QAAjB,UAAK,GAAL,KAAK,CAAY;IAAG,CAAC;IAElD,QAAQ,CAAC,EAAmB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IACzD,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { AuthUser } from '@kurdel/common';
2
+ import type { JwtRepository } from '../../repositories/index.js';
3
+ import { InMemoryAuthUserRepository } from './in-memory-auth-user-repository.js';
4
+ /** @deprecated Use InMemoryAuthUserRepository. */
5
+ export declare class InMemoryJwtRepository extends InMemoryAuthUserRepository implements JwtRepository {
6
+ constructor(users: AuthUser[]);
7
+ }
@@ -0,0 +1,8 @@
1
+ import { InMemoryAuthUserRepository } from './in-memory-auth-user-repository.js';
2
+ /** @deprecated Use InMemoryAuthUserRepository. */
3
+ export class InMemoryJwtRepository extends InMemoryAuthUserRepository {
4
+ constructor(users) {
5
+ super(users);
6
+ }
7
+ }
8
+ //# sourceMappingURL=in-memory-jwt-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-jwt-repository.js","sourceRoot":"","sources":["../../../src/infra/in-memory/in-memory-jwt-repository.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AAEjF,kDAAkD;AAClD,MAAM,OAAO,qBACX,SAAQ,0BAA0B;IAElC,YAAY,KAAiB;QAC3B,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export * from './in-memory-api-key-repository.js';
2
+ export * from './in-memory-auth-user-repository.js';
3
+ export * from './in-memory-jwt-repository.js';
@@ -0,0 +1,4 @@
1
+ export * from './in-memory-api-key-repository.js';
2
+ export * from './in-memory-auth-user-repository.js';
3
+ export * from './in-memory-jwt-repository.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infra/in-memory/index.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './in-memory/index.js';
@@ -0,0 +1,2 @@
1
+ export * from './in-memory/index.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/infra/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,30 @@
1
+ export interface ApiKeyCredential {
2
+ /** Stable credential identifier, when the backing store exposes one. */
3
+ id?: string;
4
+ /** Stable identity resolved after credential validation. */
5
+ userId: string | number;
6
+ /** Revoked credentials must never authenticate. */
7
+ revoked?: boolean;
8
+ /** Optional absolute expiry time. */
9
+ expiresAt?: Date;
10
+ }
11
+ /**
12
+ * ## ApiKeyRepository
13
+ *
14
+ * Abstraction for retrieving credential metadata by API key.
15
+ *
16
+ * A repository implementation may:
17
+ * - load records from an in-memory map
18
+ * - query a database
19
+ * - read from Redis or any other KV store
20
+ * - call an external authentication service
21
+ *
22
+ * Strategies depend only on this interface, not on the storage details.
23
+ */
24
+ export interface ApiKeyRepository {
25
+ /**
26
+ * Returns credential metadata associated with the given API key.
27
+ * If the key is unknown, must return `null`.
28
+ */
29
+ findByKey(key: string): Promise<ApiKeyCredential | null> | ApiKeyCredential | null;
30
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=api-key-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-repository.js","sourceRoot":"","sources":["../../../src/repositories/api-key/api-key-repository.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ /** Persists successful API-key usage without coupling strategies to storage. */
2
+ export interface ApiKeyUsageRecorder {
3
+ recordUsage(credentialId: string, usedAt: Date): Promise<void> | void;
4
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=api-key-usage-recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-usage-recorder.js","sourceRoot":"","sources":["../../../src/repositories/api-key/api-key-usage-recorder.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from './api-key-repository.js';
2
+ export * from './api-key-usage-recorder.js';
@@ -0,0 +1,3 @@
1
+ export * from './api-key-repository.js';
2
+ export * from './api-key-usage-recorder.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/repositories/api-key/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './api-key/index.js';
2
+ export * from './jwt/index.js';
3
+ export * from './user/index.js';