@yuva-devlab/auth-server 0.0.0-stage → 0.3.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/LICENSE +21 -0
- package/dist/index.cjs +426 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +310 -0
- package/dist/index.d.ts +310 -0
- package/dist/index.js +404 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -3
- package/README.md +0 -3
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/auth-server/src/constants/auth.constants.ts
|
|
3
|
+
* @description Centralized constants and header keys for server-side authentication.
|
|
4
|
+
* @module @yuva-devlab/auth-server
|
|
5
|
+
*/
|
|
6
|
+
/** Standard Authorization HTTP header name (lowercase for case-insensitive lookup) */
|
|
7
|
+
declare const DEFAULT_AUTH_HEADER = "authorization";
|
|
8
|
+
/** Standard machine-to-machine API key HTTP header name */
|
|
9
|
+
declare const DEFAULT_API_KEY_HEADER = "x-api-key";
|
|
10
|
+
/** Standard Bearer token prefix */
|
|
11
|
+
declare const DEFAULT_BEARER_PREFIX = "Bearer ";
|
|
12
|
+
/** Default cache time-to-live for fetched RS256 JWKS public keys (1 hour) */
|
|
13
|
+
declare const DEFAULT_JWKS_CACHE_TTL_MS = 3600000;
|
|
14
|
+
/** Default cache time-to-live for validated M2M API keys (5 minutes) */
|
|
15
|
+
declare const DEFAULT_API_KEY_CACHE_TTL_MS = 300000;
|
|
16
|
+
/** Default public endpoints bypassing mandatory authentication */
|
|
17
|
+
declare const DEFAULT_PUBLIC_PATHS: readonly string[];
|
|
18
|
+
/** HTTP Status Code for unauthenticated requests */
|
|
19
|
+
declare const HTTP_STATUS_UNAUTHORIZED = 401;
|
|
20
|
+
/** HTTP Status Code for unauthorized / forbidden role requests */
|
|
21
|
+
declare const HTTP_STATUS_FORBIDDEN = 403;
|
|
22
|
+
/** HTTP Status Code returned when an application is deactivated or killed */
|
|
23
|
+
declare const HTTP_STATUS_SERVICE_UNAVAILABLE = 503;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @file packages/auth-server/src/types/auth.types.ts
|
|
27
|
+
* @description Type definitions and contracts for server authentication, JWKS, and app lifecycle.
|
|
28
|
+
* @module @yuva-devlab/auth-server
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Operational state of an application on the DevLab platform.
|
|
32
|
+
*/
|
|
33
|
+
declare enum AppStatus {
|
|
34
|
+
/** Application is fully operational and serving traffic */
|
|
35
|
+
ACTIVE = "ACTIVE",
|
|
36
|
+
/** Application has been administratively disabled / deactivated (Kill-Switch triggered) */
|
|
37
|
+
INACTIVE = "INACTIVE",
|
|
38
|
+
/** Application is undergoing scheduled maintenance */
|
|
39
|
+
MAINTENANCE = "MAINTENANCE"
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Authenticated user profile representation.
|
|
43
|
+
*/
|
|
44
|
+
interface AuthUser {
|
|
45
|
+
/** Canonical user UUID */
|
|
46
|
+
readonly id: string;
|
|
47
|
+
/** Primary user email address */
|
|
48
|
+
readonly email?: string;
|
|
49
|
+
/** Granted role slugs */
|
|
50
|
+
readonly roles: readonly string[];
|
|
51
|
+
/** Tenant isolation partition ID */
|
|
52
|
+
readonly tenantId?: string;
|
|
53
|
+
/** Arbitrary profile metadata */
|
|
54
|
+
readonly metadata?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Machine-to-machine API key credential.
|
|
58
|
+
*/
|
|
59
|
+
interface ApiKey {
|
|
60
|
+
/** Primary API key UUID */
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** Secure key string */
|
|
63
|
+
readonly key: string;
|
|
64
|
+
/** Human-readable key name or description */
|
|
65
|
+
readonly name: string;
|
|
66
|
+
/** Scoped roles granted to this key */
|
|
67
|
+
readonly roles: readonly string[];
|
|
68
|
+
/** Tenant ID partition */
|
|
69
|
+
readonly tenantId?: string;
|
|
70
|
+
/** Active status flag */
|
|
71
|
+
readonly isEnabled: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Evaluated authentication context attached to inbound requests.
|
|
75
|
+
*/
|
|
76
|
+
interface AuthContext {
|
|
77
|
+
/** Whether the request carries valid credentials */
|
|
78
|
+
readonly authenticated: boolean;
|
|
79
|
+
/** Authenticated user if authenticated via session/JWT */
|
|
80
|
+
readonly user?: AuthUser;
|
|
81
|
+
/** Authenticated API key if authenticated via machine credential */
|
|
82
|
+
readonly apiKey?: ApiKey;
|
|
83
|
+
/** Consolidated roles granted across user or API key */
|
|
84
|
+
readonly roles: readonly string[];
|
|
85
|
+
/** Whether the host application is currently active on the platform */
|
|
86
|
+
readonly isAppActive: boolean;
|
|
87
|
+
/** Detailed app status */
|
|
88
|
+
readonly appStatus?: AppStatus;
|
|
89
|
+
/** Tenant partition ID */
|
|
90
|
+
readonly tenantId?: string;
|
|
91
|
+
/** Distributed trace request identifier */
|
|
92
|
+
readonly requestId?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Configuration for verifying RS256 JWTs against a remote JWKS endpoint.
|
|
96
|
+
*/
|
|
97
|
+
interface JwksConfig {
|
|
98
|
+
/** JWKS endpoint URI exposing JSON Web Keys */
|
|
99
|
+
readonly jwksUri: string;
|
|
100
|
+
/** Expected audience claim */
|
|
101
|
+
readonly audience?: string;
|
|
102
|
+
/** Expected issuer claim */
|
|
103
|
+
readonly issuer?: string;
|
|
104
|
+
/** In-memory cache duration for public keys in milliseconds */
|
|
105
|
+
readonly cacheTtlMs?: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Decoded JWT claims payload.
|
|
109
|
+
*/
|
|
110
|
+
/**
|
|
111
|
+
* Result of validating a Machine-to-Machine API key against the DevLab Portal.
|
|
112
|
+
*/
|
|
113
|
+
interface ApiKeyValidationResult {
|
|
114
|
+
/** Whether the API key is active, valid, and unexpired */
|
|
115
|
+
readonly valid: boolean;
|
|
116
|
+
/** Primary API key UUID */
|
|
117
|
+
readonly keyId?: string;
|
|
118
|
+
/** Name assigned to this machine key */
|
|
119
|
+
readonly name?: string;
|
|
120
|
+
/** Target application slug this key belongs to */
|
|
121
|
+
readonly appId?: string;
|
|
122
|
+
/** Target application display name */
|
|
123
|
+
readonly appName?: string;
|
|
124
|
+
/** Scopes and permissions granted to this key */
|
|
125
|
+
readonly scopes?: readonly string[];
|
|
126
|
+
/** Allowed requests per minute limit */
|
|
127
|
+
readonly rateLimitRpm?: number;
|
|
128
|
+
/** Human-readable rejection reason if invalid */
|
|
129
|
+
readonly reason?: string;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Configuration options for Machine-to-Machine API key validation.
|
|
133
|
+
*/
|
|
134
|
+
interface M2mConfig {
|
|
135
|
+
/** Base URL of the authentication server / identity provider */
|
|
136
|
+
readonly authUrl?: string;
|
|
137
|
+
/** Legacy alias for authUrl */
|
|
138
|
+
readonly portalUrl?: string;
|
|
139
|
+
/** In-memory cache duration for validated API keys in milliseconds */
|
|
140
|
+
readonly cacheTtlMs?: number;
|
|
141
|
+
/** Expected client or application identifier */
|
|
142
|
+
readonly requiredClientId?: string;
|
|
143
|
+
/** Legacy alias for requiredClientId */
|
|
144
|
+
readonly requiredAppId?: string;
|
|
145
|
+
/** Required operational scopes that must be granted to the API key */
|
|
146
|
+
readonly requiredScopes?: readonly string[];
|
|
147
|
+
}
|
|
148
|
+
interface JwtPayload {
|
|
149
|
+
readonly sub: string;
|
|
150
|
+
readonly iss?: string;
|
|
151
|
+
readonly aud?: string | readonly string[];
|
|
152
|
+
readonly exp?: number;
|
|
153
|
+
readonly nbf?: number;
|
|
154
|
+
readonly iat?: number;
|
|
155
|
+
readonly email?: string;
|
|
156
|
+
readonly name?: string;
|
|
157
|
+
readonly role?: string;
|
|
158
|
+
readonly roles?: readonly string[];
|
|
159
|
+
readonly tenantId?: string;
|
|
160
|
+
readonly tenant_id?: string;
|
|
161
|
+
readonly tenant_slug?: string;
|
|
162
|
+
readonly tenant_name?: string;
|
|
163
|
+
readonly apps?: readonly string[];
|
|
164
|
+
readonly appId?: string;
|
|
165
|
+
readonly [key: string]: unknown;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @file packages/auth-server/src/token/jwt-validator.ts
|
|
170
|
+
* @description RS256 JWKS validator providing cryptographic signature verification and claims checking.
|
|
171
|
+
* @module @yuva-devlab/auth-server
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Validates JWT access tokens against an in-memory cached JWKS public key set.
|
|
176
|
+
*/
|
|
177
|
+
declare class JwksValidator {
|
|
178
|
+
private readonly jwksUri;
|
|
179
|
+
private readonly audience?;
|
|
180
|
+
private readonly issuer?;
|
|
181
|
+
private readonly cacheTtlMs;
|
|
182
|
+
private keyCache;
|
|
183
|
+
private jwksSetCache;
|
|
184
|
+
constructor(config?: Partial<JwksConfig>);
|
|
185
|
+
parseUnverified(token: string): {
|
|
186
|
+
header: Record<string, unknown>;
|
|
187
|
+
payload: JwtPayload;
|
|
188
|
+
rawHeader: string;
|
|
189
|
+
rawPayload: string;
|
|
190
|
+
signature: string;
|
|
191
|
+
};
|
|
192
|
+
private fetchJwks;
|
|
193
|
+
private resolveKeyObject;
|
|
194
|
+
verifyToken(token: string): Promise<JwtPayload>;
|
|
195
|
+
clearKeyCache(): void;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @file packages/auth-server/src/token/m2m-validator.ts
|
|
200
|
+
* @description In-memory cached Machine-to-Machine API key validator introspecting the auth provider.
|
|
201
|
+
* @module @yuva-devlab/auth-server
|
|
202
|
+
*/
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Validates machine-to-machine API keys against central authentication server with in-memory caching.
|
|
206
|
+
*/
|
|
207
|
+
declare class M2mApiKeyValidator {
|
|
208
|
+
private readonly authUrl?;
|
|
209
|
+
private readonly cacheTtlMs;
|
|
210
|
+
private readonly requiredClientId?;
|
|
211
|
+
private readonly requiredScopes?;
|
|
212
|
+
private readonly keyCache;
|
|
213
|
+
constructor(config?: Partial<M2mConfig>);
|
|
214
|
+
validateKey(rawKey: string): Promise<ApiKeyValidationResult>;
|
|
215
|
+
private enforceKeyConstraints;
|
|
216
|
+
clearCache(): void;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @file packages/auth-server/src/guards/auth-guards.ts
|
|
221
|
+
* @description Authorization assertions and scope/role enforcement guards.
|
|
222
|
+
* @module @yuva-devlab/auth-server
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Asserts that the request is authenticated with an active user session and optional role requirements.
|
|
227
|
+
*
|
|
228
|
+
* @param ctx - Inbound request auth context
|
|
229
|
+
* @param requiredRoles - Optional list of required roles (user must possess at least one)
|
|
230
|
+
* @returns Authenticated AuthUser
|
|
231
|
+
* @throws UnauthorizedError if not authenticated as a user
|
|
232
|
+
* @throws ForbiddenError if user lacks the required roles
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* const user = requireUser(ctx, ["admin", "operator"]);
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
declare function requireUser(ctx: AuthContext, requiredRoles?: readonly string[]): AuthUser;
|
|
240
|
+
/**
|
|
241
|
+
* Asserts that the request is authenticated via a machine-to-machine API key.
|
|
242
|
+
*
|
|
243
|
+
* @param ctx - Inbound request auth context
|
|
244
|
+
* @returns Authenticated ApiKey
|
|
245
|
+
* @throws UnauthorizedError if not authenticated via an API key
|
|
246
|
+
*/
|
|
247
|
+
declare function requireApiKey(ctx: AuthContext): ApiKey;
|
|
248
|
+
/**
|
|
249
|
+
* Asserts that the authenticated context (user or API key) possesses a specific operational scope.
|
|
250
|
+
*
|
|
251
|
+
* @param ctx - Inbound request auth context
|
|
252
|
+
* @param scope - Required scope or permission string
|
|
253
|
+
* @throws ForbiddenError if scope is missing
|
|
254
|
+
*/
|
|
255
|
+
declare function requireScope(ctx: AuthContext, scope: string): void;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @file packages/auth-server/src/middleware/auth-middleware.ts
|
|
259
|
+
* @description Universal HTTP middleware providing platform kill-switch enforcement and credential validation.
|
|
260
|
+
* @module @yuva-devlab/auth-server
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Minimal HTTP request and response interfaces for framework neutrality (Express, Fastify, Node http).
|
|
265
|
+
*/
|
|
266
|
+
interface GenericHttpRequest {
|
|
267
|
+
url?: string;
|
|
268
|
+
method?: string;
|
|
269
|
+
headers: Record<string, string | string[] | undefined>;
|
|
270
|
+
authContext?: AuthContext;
|
|
271
|
+
}
|
|
272
|
+
interface GenericHttpResponse {
|
|
273
|
+
statusCode?: number;
|
|
274
|
+
setHeader(name: string, value: string): void;
|
|
275
|
+
end(body?: string): void;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Creates a kill-switch middleware that intercepts all traffic if an application is deactivated.
|
|
279
|
+
*
|
|
280
|
+
* @param getAppStatus - Callback returning current platform status of the application
|
|
281
|
+
* @returns Middleware function returning true if allowed to proceed, false if blocked (503)
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const killSwitch = createAppKillSwitchMiddleware(() => appState.status);
|
|
286
|
+
* const allowed = await killSwitch(req, res);
|
|
287
|
+
* if (!allowed) return;
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
declare function createAppKillSwitchMiddleware(getAppStatus: () => Promise<AppStatus> | AppStatus): (req: GenericHttpRequest, res: GenericHttpResponse) => Promise<boolean>;
|
|
291
|
+
/**
|
|
292
|
+
* Options configuring request authentication middleware.
|
|
293
|
+
*/
|
|
294
|
+
interface CreateAuthMiddlewareOptions {
|
|
295
|
+
/** Whitelisted public endpoints bypassing authentication */
|
|
296
|
+
publicPaths?: readonly string[];
|
|
297
|
+
/** Function resolving an API key against store */
|
|
298
|
+
validateApiKey?: (key: string) => Promise<AuthContext | null>;
|
|
299
|
+
/** Function resolving a Bearer session token against JWKS or session store */
|
|
300
|
+
validateToken?: (token: string) => Promise<AuthContext | null>;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Universal authentication middleware verifying API keys and Bearer tokens.
|
|
304
|
+
*
|
|
305
|
+
* @param options - Configuration options
|
|
306
|
+
* @returns Middleware handler
|
|
307
|
+
*/
|
|
308
|
+
declare function createAuthMiddleware(options: CreateAuthMiddlewareOptions): (req: GenericHttpRequest, res: GenericHttpResponse) => Promise<boolean>;
|
|
309
|
+
|
|
310
|
+
export { type ApiKey, type ApiKeyValidationResult, AppStatus, type AuthContext, type AuthUser, type CreateAuthMiddlewareOptions, DEFAULT_API_KEY_CACHE_TTL_MS, DEFAULT_API_KEY_HEADER, DEFAULT_AUTH_HEADER, DEFAULT_BEARER_PREFIX, DEFAULT_JWKS_CACHE_TTL_MS, DEFAULT_PUBLIC_PATHS, type GenericHttpRequest, type GenericHttpResponse, HTTP_STATUS_FORBIDDEN, HTTP_STATUS_SERVICE_UNAVAILABLE, HTTP_STATUS_UNAUTHORIZED, type JwksConfig, JwksValidator, type JwtPayload, M2mApiKeyValidator, type M2mConfig, createAppKillSwitchMiddleware, createAuthMiddleware, requireApiKey, requireScope, requireUser };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file packages/auth-server/src/constants/auth.constants.ts
|
|
3
|
+
* @description Centralized constants and header keys for server-side authentication.
|
|
4
|
+
* @module @yuva-devlab/auth-server
|
|
5
|
+
*/
|
|
6
|
+
/** Standard Authorization HTTP header name (lowercase for case-insensitive lookup) */
|
|
7
|
+
declare const DEFAULT_AUTH_HEADER = "authorization";
|
|
8
|
+
/** Standard machine-to-machine API key HTTP header name */
|
|
9
|
+
declare const DEFAULT_API_KEY_HEADER = "x-api-key";
|
|
10
|
+
/** Standard Bearer token prefix */
|
|
11
|
+
declare const DEFAULT_BEARER_PREFIX = "Bearer ";
|
|
12
|
+
/** Default cache time-to-live for fetched RS256 JWKS public keys (1 hour) */
|
|
13
|
+
declare const DEFAULT_JWKS_CACHE_TTL_MS = 3600000;
|
|
14
|
+
/** Default cache time-to-live for validated M2M API keys (5 minutes) */
|
|
15
|
+
declare const DEFAULT_API_KEY_CACHE_TTL_MS = 300000;
|
|
16
|
+
/** Default public endpoints bypassing mandatory authentication */
|
|
17
|
+
declare const DEFAULT_PUBLIC_PATHS: readonly string[];
|
|
18
|
+
/** HTTP Status Code for unauthenticated requests */
|
|
19
|
+
declare const HTTP_STATUS_UNAUTHORIZED = 401;
|
|
20
|
+
/** HTTP Status Code for unauthorized / forbidden role requests */
|
|
21
|
+
declare const HTTP_STATUS_FORBIDDEN = 403;
|
|
22
|
+
/** HTTP Status Code returned when an application is deactivated or killed */
|
|
23
|
+
declare const HTTP_STATUS_SERVICE_UNAVAILABLE = 503;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @file packages/auth-server/src/types/auth.types.ts
|
|
27
|
+
* @description Type definitions and contracts for server authentication, JWKS, and app lifecycle.
|
|
28
|
+
* @module @yuva-devlab/auth-server
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Operational state of an application on the DevLab platform.
|
|
32
|
+
*/
|
|
33
|
+
declare enum AppStatus {
|
|
34
|
+
/** Application is fully operational and serving traffic */
|
|
35
|
+
ACTIVE = "ACTIVE",
|
|
36
|
+
/** Application has been administratively disabled / deactivated (Kill-Switch triggered) */
|
|
37
|
+
INACTIVE = "INACTIVE",
|
|
38
|
+
/** Application is undergoing scheduled maintenance */
|
|
39
|
+
MAINTENANCE = "MAINTENANCE"
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Authenticated user profile representation.
|
|
43
|
+
*/
|
|
44
|
+
interface AuthUser {
|
|
45
|
+
/** Canonical user UUID */
|
|
46
|
+
readonly id: string;
|
|
47
|
+
/** Primary user email address */
|
|
48
|
+
readonly email?: string;
|
|
49
|
+
/** Granted role slugs */
|
|
50
|
+
readonly roles: readonly string[];
|
|
51
|
+
/** Tenant isolation partition ID */
|
|
52
|
+
readonly tenantId?: string;
|
|
53
|
+
/** Arbitrary profile metadata */
|
|
54
|
+
readonly metadata?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Machine-to-machine API key credential.
|
|
58
|
+
*/
|
|
59
|
+
interface ApiKey {
|
|
60
|
+
/** Primary API key UUID */
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** Secure key string */
|
|
63
|
+
readonly key: string;
|
|
64
|
+
/** Human-readable key name or description */
|
|
65
|
+
readonly name: string;
|
|
66
|
+
/** Scoped roles granted to this key */
|
|
67
|
+
readonly roles: readonly string[];
|
|
68
|
+
/** Tenant ID partition */
|
|
69
|
+
readonly tenantId?: string;
|
|
70
|
+
/** Active status flag */
|
|
71
|
+
readonly isEnabled: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Evaluated authentication context attached to inbound requests.
|
|
75
|
+
*/
|
|
76
|
+
interface AuthContext {
|
|
77
|
+
/** Whether the request carries valid credentials */
|
|
78
|
+
readonly authenticated: boolean;
|
|
79
|
+
/** Authenticated user if authenticated via session/JWT */
|
|
80
|
+
readonly user?: AuthUser;
|
|
81
|
+
/** Authenticated API key if authenticated via machine credential */
|
|
82
|
+
readonly apiKey?: ApiKey;
|
|
83
|
+
/** Consolidated roles granted across user or API key */
|
|
84
|
+
readonly roles: readonly string[];
|
|
85
|
+
/** Whether the host application is currently active on the platform */
|
|
86
|
+
readonly isAppActive: boolean;
|
|
87
|
+
/** Detailed app status */
|
|
88
|
+
readonly appStatus?: AppStatus;
|
|
89
|
+
/** Tenant partition ID */
|
|
90
|
+
readonly tenantId?: string;
|
|
91
|
+
/** Distributed trace request identifier */
|
|
92
|
+
readonly requestId?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Configuration for verifying RS256 JWTs against a remote JWKS endpoint.
|
|
96
|
+
*/
|
|
97
|
+
interface JwksConfig {
|
|
98
|
+
/** JWKS endpoint URI exposing JSON Web Keys */
|
|
99
|
+
readonly jwksUri: string;
|
|
100
|
+
/** Expected audience claim */
|
|
101
|
+
readonly audience?: string;
|
|
102
|
+
/** Expected issuer claim */
|
|
103
|
+
readonly issuer?: string;
|
|
104
|
+
/** In-memory cache duration for public keys in milliseconds */
|
|
105
|
+
readonly cacheTtlMs?: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Decoded JWT claims payload.
|
|
109
|
+
*/
|
|
110
|
+
/**
|
|
111
|
+
* Result of validating a Machine-to-Machine API key against the DevLab Portal.
|
|
112
|
+
*/
|
|
113
|
+
interface ApiKeyValidationResult {
|
|
114
|
+
/** Whether the API key is active, valid, and unexpired */
|
|
115
|
+
readonly valid: boolean;
|
|
116
|
+
/** Primary API key UUID */
|
|
117
|
+
readonly keyId?: string;
|
|
118
|
+
/** Name assigned to this machine key */
|
|
119
|
+
readonly name?: string;
|
|
120
|
+
/** Target application slug this key belongs to */
|
|
121
|
+
readonly appId?: string;
|
|
122
|
+
/** Target application display name */
|
|
123
|
+
readonly appName?: string;
|
|
124
|
+
/** Scopes and permissions granted to this key */
|
|
125
|
+
readonly scopes?: readonly string[];
|
|
126
|
+
/** Allowed requests per minute limit */
|
|
127
|
+
readonly rateLimitRpm?: number;
|
|
128
|
+
/** Human-readable rejection reason if invalid */
|
|
129
|
+
readonly reason?: string;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Configuration options for Machine-to-Machine API key validation.
|
|
133
|
+
*/
|
|
134
|
+
interface M2mConfig {
|
|
135
|
+
/** Base URL of the authentication server / identity provider */
|
|
136
|
+
readonly authUrl?: string;
|
|
137
|
+
/** Legacy alias for authUrl */
|
|
138
|
+
readonly portalUrl?: string;
|
|
139
|
+
/** In-memory cache duration for validated API keys in milliseconds */
|
|
140
|
+
readonly cacheTtlMs?: number;
|
|
141
|
+
/** Expected client or application identifier */
|
|
142
|
+
readonly requiredClientId?: string;
|
|
143
|
+
/** Legacy alias for requiredClientId */
|
|
144
|
+
readonly requiredAppId?: string;
|
|
145
|
+
/** Required operational scopes that must be granted to the API key */
|
|
146
|
+
readonly requiredScopes?: readonly string[];
|
|
147
|
+
}
|
|
148
|
+
interface JwtPayload {
|
|
149
|
+
readonly sub: string;
|
|
150
|
+
readonly iss?: string;
|
|
151
|
+
readonly aud?: string | readonly string[];
|
|
152
|
+
readonly exp?: number;
|
|
153
|
+
readonly nbf?: number;
|
|
154
|
+
readonly iat?: number;
|
|
155
|
+
readonly email?: string;
|
|
156
|
+
readonly name?: string;
|
|
157
|
+
readonly role?: string;
|
|
158
|
+
readonly roles?: readonly string[];
|
|
159
|
+
readonly tenantId?: string;
|
|
160
|
+
readonly tenant_id?: string;
|
|
161
|
+
readonly tenant_slug?: string;
|
|
162
|
+
readonly tenant_name?: string;
|
|
163
|
+
readonly apps?: readonly string[];
|
|
164
|
+
readonly appId?: string;
|
|
165
|
+
readonly [key: string]: unknown;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @file packages/auth-server/src/token/jwt-validator.ts
|
|
170
|
+
* @description RS256 JWKS validator providing cryptographic signature verification and claims checking.
|
|
171
|
+
* @module @yuva-devlab/auth-server
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Validates JWT access tokens against an in-memory cached JWKS public key set.
|
|
176
|
+
*/
|
|
177
|
+
declare class JwksValidator {
|
|
178
|
+
private readonly jwksUri;
|
|
179
|
+
private readonly audience?;
|
|
180
|
+
private readonly issuer?;
|
|
181
|
+
private readonly cacheTtlMs;
|
|
182
|
+
private keyCache;
|
|
183
|
+
private jwksSetCache;
|
|
184
|
+
constructor(config?: Partial<JwksConfig>);
|
|
185
|
+
parseUnverified(token: string): {
|
|
186
|
+
header: Record<string, unknown>;
|
|
187
|
+
payload: JwtPayload;
|
|
188
|
+
rawHeader: string;
|
|
189
|
+
rawPayload: string;
|
|
190
|
+
signature: string;
|
|
191
|
+
};
|
|
192
|
+
private fetchJwks;
|
|
193
|
+
private resolveKeyObject;
|
|
194
|
+
verifyToken(token: string): Promise<JwtPayload>;
|
|
195
|
+
clearKeyCache(): void;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @file packages/auth-server/src/token/m2m-validator.ts
|
|
200
|
+
* @description In-memory cached Machine-to-Machine API key validator introspecting the auth provider.
|
|
201
|
+
* @module @yuva-devlab/auth-server
|
|
202
|
+
*/
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Validates machine-to-machine API keys against central authentication server with in-memory caching.
|
|
206
|
+
*/
|
|
207
|
+
declare class M2mApiKeyValidator {
|
|
208
|
+
private readonly authUrl?;
|
|
209
|
+
private readonly cacheTtlMs;
|
|
210
|
+
private readonly requiredClientId?;
|
|
211
|
+
private readonly requiredScopes?;
|
|
212
|
+
private readonly keyCache;
|
|
213
|
+
constructor(config?: Partial<M2mConfig>);
|
|
214
|
+
validateKey(rawKey: string): Promise<ApiKeyValidationResult>;
|
|
215
|
+
private enforceKeyConstraints;
|
|
216
|
+
clearCache(): void;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @file packages/auth-server/src/guards/auth-guards.ts
|
|
221
|
+
* @description Authorization assertions and scope/role enforcement guards.
|
|
222
|
+
* @module @yuva-devlab/auth-server
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Asserts that the request is authenticated with an active user session and optional role requirements.
|
|
227
|
+
*
|
|
228
|
+
* @param ctx - Inbound request auth context
|
|
229
|
+
* @param requiredRoles - Optional list of required roles (user must possess at least one)
|
|
230
|
+
* @returns Authenticated AuthUser
|
|
231
|
+
* @throws UnauthorizedError if not authenticated as a user
|
|
232
|
+
* @throws ForbiddenError if user lacks the required roles
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* const user = requireUser(ctx, ["admin", "operator"]);
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
declare function requireUser(ctx: AuthContext, requiredRoles?: readonly string[]): AuthUser;
|
|
240
|
+
/**
|
|
241
|
+
* Asserts that the request is authenticated via a machine-to-machine API key.
|
|
242
|
+
*
|
|
243
|
+
* @param ctx - Inbound request auth context
|
|
244
|
+
* @returns Authenticated ApiKey
|
|
245
|
+
* @throws UnauthorizedError if not authenticated via an API key
|
|
246
|
+
*/
|
|
247
|
+
declare function requireApiKey(ctx: AuthContext): ApiKey;
|
|
248
|
+
/**
|
|
249
|
+
* Asserts that the authenticated context (user or API key) possesses a specific operational scope.
|
|
250
|
+
*
|
|
251
|
+
* @param ctx - Inbound request auth context
|
|
252
|
+
* @param scope - Required scope or permission string
|
|
253
|
+
* @throws ForbiddenError if scope is missing
|
|
254
|
+
*/
|
|
255
|
+
declare function requireScope(ctx: AuthContext, scope: string): void;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @file packages/auth-server/src/middleware/auth-middleware.ts
|
|
259
|
+
* @description Universal HTTP middleware providing platform kill-switch enforcement and credential validation.
|
|
260
|
+
* @module @yuva-devlab/auth-server
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Minimal HTTP request and response interfaces for framework neutrality (Express, Fastify, Node http).
|
|
265
|
+
*/
|
|
266
|
+
interface GenericHttpRequest {
|
|
267
|
+
url?: string;
|
|
268
|
+
method?: string;
|
|
269
|
+
headers: Record<string, string | string[] | undefined>;
|
|
270
|
+
authContext?: AuthContext;
|
|
271
|
+
}
|
|
272
|
+
interface GenericHttpResponse {
|
|
273
|
+
statusCode?: number;
|
|
274
|
+
setHeader(name: string, value: string): void;
|
|
275
|
+
end(body?: string): void;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Creates a kill-switch middleware that intercepts all traffic if an application is deactivated.
|
|
279
|
+
*
|
|
280
|
+
* @param getAppStatus - Callback returning current platform status of the application
|
|
281
|
+
* @returns Middleware function returning true if allowed to proceed, false if blocked (503)
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const killSwitch = createAppKillSwitchMiddleware(() => appState.status);
|
|
286
|
+
* const allowed = await killSwitch(req, res);
|
|
287
|
+
* if (!allowed) return;
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
declare function createAppKillSwitchMiddleware(getAppStatus: () => Promise<AppStatus> | AppStatus): (req: GenericHttpRequest, res: GenericHttpResponse) => Promise<boolean>;
|
|
291
|
+
/**
|
|
292
|
+
* Options configuring request authentication middleware.
|
|
293
|
+
*/
|
|
294
|
+
interface CreateAuthMiddlewareOptions {
|
|
295
|
+
/** Whitelisted public endpoints bypassing authentication */
|
|
296
|
+
publicPaths?: readonly string[];
|
|
297
|
+
/** Function resolving an API key against store */
|
|
298
|
+
validateApiKey?: (key: string) => Promise<AuthContext | null>;
|
|
299
|
+
/** Function resolving a Bearer session token against JWKS or session store */
|
|
300
|
+
validateToken?: (token: string) => Promise<AuthContext | null>;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Universal authentication middleware verifying API keys and Bearer tokens.
|
|
304
|
+
*
|
|
305
|
+
* @param options - Configuration options
|
|
306
|
+
* @returns Middleware handler
|
|
307
|
+
*/
|
|
308
|
+
declare function createAuthMiddleware(options: CreateAuthMiddlewareOptions): (req: GenericHttpRequest, res: GenericHttpResponse) => Promise<boolean>;
|
|
309
|
+
|
|
310
|
+
export { type ApiKey, type ApiKeyValidationResult, AppStatus, type AuthContext, type AuthUser, type CreateAuthMiddlewareOptions, DEFAULT_API_KEY_CACHE_TTL_MS, DEFAULT_API_KEY_HEADER, DEFAULT_AUTH_HEADER, DEFAULT_BEARER_PREFIX, DEFAULT_JWKS_CACHE_TTL_MS, DEFAULT_PUBLIC_PATHS, type GenericHttpRequest, type GenericHttpResponse, HTTP_STATUS_FORBIDDEN, HTTP_STATUS_SERVICE_UNAVAILABLE, HTTP_STATUS_UNAUTHORIZED, type JwksConfig, JwksValidator, type JwtPayload, M2mApiKeyValidator, type M2mConfig, createAppKillSwitchMiddleware, createAuthMiddleware, requireApiKey, requireScope, requireUser };
|