@nitrostack/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +80 -0
- package/dist/auth/api-key.d.ts +118 -0
- package/dist/auth/api-key.d.ts.map +1 -0
- package/dist/auth/api-key.js +168 -0
- package/dist/auth/api-key.js.map +1 -0
- package/dist/auth/client.d.ts +151 -0
- package/dist/auth/client.d.ts.map +1 -0
- package/dist/auth/client.js +330 -0
- package/dist/auth/client.js.map +1 -0
- package/dist/auth/index.d.ts +31 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +46 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +95 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +260 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/pkce.d.ts +53 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +105 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/quick-setup.d.ts +94 -0
- package/dist/auth/quick-setup.d.ts.map +1 -0
- package/dist/auth/quick-setup.js +210 -0
- package/dist/auth/quick-setup.js.map +1 -0
- package/dist/auth/secure-secret.d.ts +136 -0
- package/dist/auth/secure-secret.d.ts.map +1 -0
- package/dist/auth/secure-secret.js +182 -0
- package/dist/auth/secure-secret.js.map +1 -0
- package/dist/auth/server-integration.d.ts +97 -0
- package/dist/auth/server-integration.d.ts.map +1 -0
- package/dist/auth/server-integration.js +182 -0
- package/dist/auth/server-integration.js.map +1 -0
- package/dist/auth/server-metadata.d.ts +51 -0
- package/dist/auth/server-metadata.d.ts.map +1 -0
- package/dist/auth/server-metadata.js +106 -0
- package/dist/auth/server-metadata.js.map +1 -0
- package/dist/auth/simple-jwt.d.ts +174 -0
- package/dist/auth/simple-jwt.d.ts.map +1 -0
- package/dist/auth/simple-jwt.js +162 -0
- package/dist/auth/simple-jwt.js.map +1 -0
- package/dist/auth/token-store.d.ts +104 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/auth/token-store.js +205 -0
- package/dist/auth/token-store.js.map +1 -0
- package/dist/auth/token-validation.d.ts +59 -0
- package/dist/auth/token-validation.d.ts.map +1 -0
- package/dist/auth/token-validation.js +241 -0
- package/dist/auth/token-validation.js.map +1 -0
- package/dist/auth/types.d.ts +215 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +6 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/core/apikey-module.d.ts +69 -0
- package/dist/core/apikey-module.d.ts.map +1 -0
- package/dist/core/apikey-module.js +114 -0
- package/dist/core/apikey-module.js.map +1 -0
- package/dist/core/app-decorator.d.ts +59 -0
- package/dist/core/app-decorator.d.ts.map +1 -0
- package/dist/core/app-decorator.js +322 -0
- package/dist/core/app-decorator.js.map +1 -0
- package/dist/core/builders.d.ts +50 -0
- package/dist/core/builders.d.ts.map +1 -0
- package/dist/core/builders.js +139 -0
- package/dist/core/builders.js.map +1 -0
- package/dist/core/component.d.ts +111 -0
- package/dist/core/component.d.ts.map +1 -0
- package/dist/core/component.js +228 -0
- package/dist/core/component.js.map +1 -0
- package/dist/core/config-module.d.ts +62 -0
- package/dist/core/config-module.d.ts.map +1 -0
- package/dist/core/config-module.js +94 -0
- package/dist/core/config-module.js.map +1 -0
- package/dist/core/decorators/cache.decorator.d.ts +61 -0
- package/dist/core/decorators/cache.decorator.d.ts.map +1 -0
- package/dist/core/decorators/cache.decorator.js +115 -0
- package/dist/core/decorators/cache.decorator.js.map +1 -0
- package/dist/core/decorators/health-check.decorator.d.ts +80 -0
- package/dist/core/decorators/health-check.decorator.d.ts.map +1 -0
- package/dist/core/decorators/health-check.decorator.js +153 -0
- package/dist/core/decorators/health-check.decorator.js.map +1 -0
- package/dist/core/decorators/rate-limit.decorator.d.ts +63 -0
- package/dist/core/decorators/rate-limit.decorator.d.ts.map +1 -0
- package/dist/core/decorators/rate-limit.decorator.js +129 -0
- package/dist/core/decorators/rate-limit.decorator.js.map +1 -0
- package/dist/core/decorators.d.ts +190 -0
- package/dist/core/decorators.d.ts.map +1 -0
- package/dist/core/decorators.js +170 -0
- package/dist/core/decorators.js.map +1 -0
- package/dist/core/di/container.d.ts +64 -0
- package/dist/core/di/container.d.ts.map +1 -0
- package/dist/core/di/container.js +105 -0
- package/dist/core/di/container.js.map +1 -0
- package/dist/core/di/injectable.decorator.d.ts +62 -0
- package/dist/core/di/injectable.decorator.d.ts.map +1 -0
- package/dist/core/di/injectable.decorator.js +66 -0
- package/dist/core/di/injectable.decorator.js.map +1 -0
- package/dist/core/errors.d.ts +54 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +87 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events/event-emitter.d.ts +50 -0
- package/dist/core/events/event-emitter.d.ts.map +1 -0
- package/dist/core/events/event-emitter.js +94 -0
- package/dist/core/events/event-emitter.js.map +1 -0
- package/dist/core/events/event.decorator.d.ts +48 -0
- package/dist/core/events/event.decorator.d.ts.map +1 -0
- package/dist/core/events/event.decorator.js +72 -0
- package/dist/core/events/event.decorator.js.map +1 -0
- package/dist/core/events/log-emitter.d.ts +14 -0
- package/dist/core/events/log-emitter.d.ts.map +1 -0
- package/dist/core/events/log-emitter.js +20 -0
- package/dist/core/events/log-emitter.js.map +1 -0
- package/dist/core/filters/exception-filter.decorator.d.ts +40 -0
- package/dist/core/filters/exception-filter.decorator.d.ts.map +1 -0
- package/dist/core/filters/exception-filter.decorator.js +54 -0
- package/dist/core/filters/exception-filter.decorator.js.map +1 -0
- package/dist/core/filters/exception-filter.interface.d.ts +39 -0
- package/dist/core/filters/exception-filter.interface.d.ts.map +1 -0
- package/dist/core/filters/exception-filter.interface.js +2 -0
- package/dist/core/filters/exception-filter.interface.js.map +1 -0
- package/dist/core/guards/apikey.guard.d.ts +22 -0
- package/dist/core/guards/apikey.guard.d.ts.map +1 -0
- package/dist/core/guards/apikey.guard.js +11 -0
- package/dist/core/guards/apikey.guard.js.map +1 -0
- package/dist/core/guards/guard.interface.d.ts +18 -0
- package/dist/core/guards/guard.interface.d.ts.map +1 -0
- package/dist/core/guards/guard.interface.js +2 -0
- package/dist/core/guards/guard.interface.js.map +1 -0
- package/dist/core/guards/jwt.guard.d.ts +18 -0
- package/dist/core/guards/jwt.guard.d.ts.map +1 -0
- package/dist/core/guards/jwt.guard.js +2 -0
- package/dist/core/guards/jwt.guard.js.map +1 -0
- package/dist/core/guards/oauth.guard.d.ts +35 -0
- package/dist/core/guards/oauth.guard.d.ts.map +1 -0
- package/dist/core/guards/oauth.guard.js +2 -0
- package/dist/core/guards/oauth.guard.js.map +1 -0
- package/dist/core/guards/use-guards.decorator.d.ts +25 -0
- package/dist/core/guards/use-guards.decorator.d.ts.map +1 -0
- package/dist/core/guards/use-guards.decorator.js +32 -0
- package/dist/core/guards/use-guards.decorator.js.map +1 -0
- package/dist/core/health/health-checks.resource.d.ts +14 -0
- package/dist/core/health/health-checks.resource.d.ts.map +1 -0
- package/dist/core/health/health-checks.resource.js +29 -0
- package/dist/core/health/health-checks.resource.js.map +1 -0
- package/dist/core/index.d.ts +57 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +59 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/interceptors/interceptor.decorator.d.ts +37 -0
- package/dist/core/interceptors/interceptor.decorator.d.ts.map +1 -0
- package/dist/core/interceptors/interceptor.decorator.js +51 -0
- package/dist/core/interceptors/interceptor.decorator.js.map +1 -0
- package/dist/core/interceptors/interceptor.interface.d.ts +31 -0
- package/dist/core/interceptors/interceptor.interface.d.ts.map +1 -0
- package/dist/core/interceptors/interceptor.interface.js +2 -0
- package/dist/core/interceptors/interceptor.interface.js.map +1 -0
- package/dist/core/jwt-module.d.ts +51 -0
- package/dist/core/jwt-module.d.ts.map +1 -0
- package/dist/core/jwt-module.js +52 -0
- package/dist/core/jwt-module.js.map +1 -0
- package/dist/core/logger.d.ts +18 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +53 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/middleware/middleware.decorator.d.ts +39 -0
- package/dist/core/middleware/middleware.decorator.d.ts.map +1 -0
- package/dist/core/middleware/middleware.decorator.js +53 -0
- package/dist/core/middleware/middleware.decorator.js.map +1 -0
- package/dist/core/middleware/middleware.interface.d.ts +29 -0
- package/dist/core/middleware/middleware.interface.d.ts.map +1 -0
- package/dist/core/middleware/middleware.interface.js +2 -0
- package/dist/core/middleware/middleware.interface.js.map +1 -0
- package/dist/core/module.d.ts +93 -0
- package/dist/core/module.d.ts.map +1 -0
- package/dist/core/module.js +87 -0
- package/dist/core/module.js.map +1 -0
- package/dist/core/oauth-module.d.ts +123 -0
- package/dist/core/oauth-module.d.ts.map +1 -0
- package/dist/core/oauth-module.js +324 -0
- package/dist/core/oauth-module.js.map +1 -0
- package/dist/core/pipes/pipe.decorator.d.ts +64 -0
- package/dist/core/pipes/pipe.decorator.d.ts.map +1 -0
- package/dist/core/pipes/pipe.decorator.js +85 -0
- package/dist/core/pipes/pipe.decorator.js.map +1 -0
- package/dist/core/pipes/pipe.interface.d.ts +41 -0
- package/dist/core/pipes/pipe.interface.d.ts.map +1 -0
- package/dist/core/pipes/pipe.interface.js +2 -0
- package/dist/core/pipes/pipe.interface.js.map +1 -0
- package/dist/core/prompt.d.ts +46 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +76 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/resource.d.ts +47 -0
- package/dist/core/resource.d.ts.map +1 -0
- package/dist/core/resource.js +90 -0
- package/dist/core/resource.js.map +1 -0
- package/dist/core/server.d.ts +129 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +617 -0
- package/dist/core/server.js.map +1 -0
- package/dist/core/tool.d.ts +108 -0
- package/dist/core/tool.d.ts.map +1 -0
- package/dist/core/tool.js +241 -0
- package/dist/core/tool.js.map +1 -0
- package/dist/core/transports/discovery-http-server.d.ts +19 -0
- package/dist/core/transports/discovery-http-server.d.ts.map +1 -0
- package/dist/core/transports/discovery-http-server.js +54 -0
- package/dist/core/transports/discovery-http-server.js.map +1 -0
- package/dist/core/transports/http-server.d.ts +108 -0
- package/dist/core/transports/http-server.d.ts.map +1 -0
- package/dist/core/transports/http-server.js +293 -0
- package/dist/core/transports/http-server.js.map +1 -0
- package/dist/core/transports/streamable-http.d.ts +177 -0
- package/dist/core/transports/streamable-http.d.ts.map +1 -0
- package/dist/core/transports/streamable-http.js +1287 -0
- package/dist/core/transports/streamable-http.js.map +1 -0
- package/dist/core/types.d.ts +195 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/widgets/widget-examples.resource.d.ts +17 -0
- package/dist/core/widgets/widget-examples.resource.d.ts.map +1 -0
- package/dist/core/widgets/widget-examples.resource.js +28 -0
- package/dist/core/widgets/widget-examples.resource.js.map +1 -0
- package/dist/core/widgets/widget-registry.d.ts +56 -0
- package/dist/core/widgets/widget-registry.d.ts.map +1 -0
- package/dist/core/widgets/widget-registry.js +75 -0
- package/dist/core/widgets/widget-registry.js.map +1 -0
- package/dist/testing/index.d.ts +103 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +161 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/ui-next/index.d.ts +31 -0
- package/dist/ui-next/index.d.ts.map +1 -0
- package/dist/ui-next/index.js +687 -0
- package/dist/ui-next/index.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Validation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Validates Bearer tokens using either:
|
|
5
|
+
* 1. Token Introspection (RFC 7662)
|
|
6
|
+
* 2. JWT validation with JWKS (RFC 7517, RFC 7519)
|
|
7
|
+
*
|
|
8
|
+
* Note: Uses dynamic import for 'jose' to avoid ES module issues
|
|
9
|
+
*/
|
|
10
|
+
// Lazy-load jose to avoid ES module import issues
|
|
11
|
+
let jose = null;
|
|
12
|
+
async function getJose() {
|
|
13
|
+
if (!jose) {
|
|
14
|
+
jose = await import('jose');
|
|
15
|
+
}
|
|
16
|
+
return jose;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* In-memory cache for token introspection results
|
|
20
|
+
* Reduces load on authorization server
|
|
21
|
+
*/
|
|
22
|
+
const tokenCache = new Map();
|
|
23
|
+
/**
|
|
24
|
+
* Validate a Bearer token
|
|
25
|
+
*
|
|
26
|
+
* @param token - The access token to validate
|
|
27
|
+
* @param config - Auth configuration
|
|
28
|
+
* @returns Validation result with token introspection data
|
|
29
|
+
*/
|
|
30
|
+
export async function validateToken(token, config) {
|
|
31
|
+
// Check cache first
|
|
32
|
+
const cached = getFromCache(token);
|
|
33
|
+
if (cached) {
|
|
34
|
+
return { valid: true, introspection: cached };
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
let introspection;
|
|
38
|
+
if (config.tokenIntrospectionEndpoint) {
|
|
39
|
+
// Method 1: Token Introspection (RFC 7662)
|
|
40
|
+
introspection = await introspectToken(token, config);
|
|
41
|
+
}
|
|
42
|
+
else if (config.jwksUri) {
|
|
43
|
+
// Method 2: JWT validation with JWKS
|
|
44
|
+
introspection = await validateJWT(token, config);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return {
|
|
48
|
+
valid: false,
|
|
49
|
+
error: 'No token validation method configured. Set tokenIntrospectionEndpoint or jwksUri.',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (!introspection.active) {
|
|
53
|
+
return { valid: false, error: 'Token is not active' };
|
|
54
|
+
}
|
|
55
|
+
// Validate audience (CRITICAL for security)
|
|
56
|
+
if (!validateAudience(introspection, config.audience)) {
|
|
57
|
+
return {
|
|
58
|
+
valid: false,
|
|
59
|
+
error: 'Token audience mismatch. Token not intended for this resource.',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Cache the result
|
|
63
|
+
cacheToken(token, introspection, config.tokenCacheSeconds || 300);
|
|
64
|
+
return { valid: true, introspection };
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return { valid: false, error: error instanceof Error ? error.message : String(error) };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Introspect token using OAuth 2.0 Token Introspection (RFC 7662)
|
|
72
|
+
*
|
|
73
|
+
* @internal - Exported for testing
|
|
74
|
+
*/
|
|
75
|
+
export async function introspectToken(token, config) {
|
|
76
|
+
if (!config.tokenIntrospectionEndpoint) {
|
|
77
|
+
throw new Error('Token introspection endpoint not configured');
|
|
78
|
+
}
|
|
79
|
+
// Prepare request with client authentication
|
|
80
|
+
const params = new URLSearchParams();
|
|
81
|
+
params.append('token', token);
|
|
82
|
+
params.append('token_type_hint', 'access_token');
|
|
83
|
+
const headers = {
|
|
84
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
85
|
+
'Accept': 'application/json',
|
|
86
|
+
};
|
|
87
|
+
// Client authentication (if configured)
|
|
88
|
+
if (config.tokenIntrospectionClientId && config.tokenIntrospectionClientSecret) {
|
|
89
|
+
const credentials = Buffer.from(`${config.tokenIntrospectionClientId}:${config.tokenIntrospectionClientSecret}`).toString('base64');
|
|
90
|
+
headers['Authorization'] = `Basic ${credentials}`;
|
|
91
|
+
}
|
|
92
|
+
const response = await fetch(config.tokenIntrospectionEndpoint, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers,
|
|
95
|
+
body: params.toString(),
|
|
96
|
+
});
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
throw new Error(`Token introspection failed: ${response.status} ${response.statusText}`);
|
|
99
|
+
}
|
|
100
|
+
const result = await response.json();
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validate JWT using JWKS
|
|
105
|
+
*
|
|
106
|
+
* @internal - Exported for testing
|
|
107
|
+
*/
|
|
108
|
+
export async function validateJWT(token, config) {
|
|
109
|
+
if (!config.jwksUri) {
|
|
110
|
+
throw new Error('JWKS URI not configured');
|
|
111
|
+
}
|
|
112
|
+
// Fetch JWKS
|
|
113
|
+
const joseLib = await getJose();
|
|
114
|
+
const JWKS = joseLib.createRemoteJWKSet(new URL(config.jwksUri));
|
|
115
|
+
// Verify JWT
|
|
116
|
+
const { payload } = await joseLib.jwtVerify(token, JWKS, {
|
|
117
|
+
issuer: config.issuer,
|
|
118
|
+
audience: config.audience,
|
|
119
|
+
});
|
|
120
|
+
// Convert JWT payload to TokenIntrospection format
|
|
121
|
+
const introspection = {
|
|
122
|
+
active: true,
|
|
123
|
+
scope: typeof payload.scope === 'string' ? payload.scope : undefined,
|
|
124
|
+
client_id: typeof payload.client_id === 'string' ? payload.client_id : payload.azp,
|
|
125
|
+
username: typeof payload.username === 'string' ? payload.username : undefined,
|
|
126
|
+
token_type: 'Bearer',
|
|
127
|
+
exp: payload.exp,
|
|
128
|
+
iat: payload.iat,
|
|
129
|
+
nbf: payload.nbf,
|
|
130
|
+
sub: payload.sub,
|
|
131
|
+
aud: Array.isArray(payload.aud) ? payload.aud : payload.aud ? [payload.aud] : undefined,
|
|
132
|
+
iss: payload.iss,
|
|
133
|
+
jti: typeof payload.jti === 'string' ? payload.jti : undefined,
|
|
134
|
+
};
|
|
135
|
+
return introspection;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Validate token audience (RFC 8707)
|
|
139
|
+
*
|
|
140
|
+
* CRITICAL: This prevents confused deputy attacks
|
|
141
|
+
* Token MUST be issued specifically for this resource
|
|
142
|
+
*
|
|
143
|
+
* @param introspection - Token introspection result
|
|
144
|
+
* @param expectedAudience - Expected audience value(s)
|
|
145
|
+
* @returns true if audience is valid
|
|
146
|
+
*/
|
|
147
|
+
export function validateAudience(introspection, expectedAudience) {
|
|
148
|
+
if (!expectedAudience) {
|
|
149
|
+
// If no audience expected, skip validation
|
|
150
|
+
// (Not recommended for production)
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
const expected = Array.isArray(expectedAudience) ? expectedAudience : [expectedAudience];
|
|
154
|
+
const tokenAud = Array.isArray(introspection.aud)
|
|
155
|
+
? introspection.aud
|
|
156
|
+
: introspection.aud
|
|
157
|
+
? [introspection.aud]
|
|
158
|
+
: [];
|
|
159
|
+
// Token audience must include at least one expected audience
|
|
160
|
+
return expected.some((aud) => tokenAud.includes(aud));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Validate scopes
|
|
164
|
+
*
|
|
165
|
+
* @param introspection - Token introspection result
|
|
166
|
+
* @param requiredScopes - Scopes required for the operation
|
|
167
|
+
* @returns true if token has all required scopes
|
|
168
|
+
*/
|
|
169
|
+
export function validateScopes(introspection, requiredScopes) {
|
|
170
|
+
if (!requiredScopes || requiredScopes.length === 0) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
if (!introspection.scope) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const tokenScopes = introspection.scope.split(' ');
|
|
177
|
+
return requiredScopes.every((scope) => tokenScopes.includes(scope));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Extract Bearer token from Authorization header
|
|
181
|
+
*/
|
|
182
|
+
export function extractBearerToken(authHeader) {
|
|
183
|
+
if (!authHeader) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
187
|
+
return match ? match[1] : null;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Check if token is expired
|
|
191
|
+
*/
|
|
192
|
+
export function isTokenExpired(introspection) {
|
|
193
|
+
if (!introspection.exp) {
|
|
194
|
+
return false; // No expiration set
|
|
195
|
+
}
|
|
196
|
+
const now = Math.floor(Date.now() / 1000);
|
|
197
|
+
return introspection.exp < now;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Cache token introspection result
|
|
201
|
+
*/
|
|
202
|
+
function cacheToken(token, result, seconds) {
|
|
203
|
+
const expiresAt = Date.now() + seconds * 1000;
|
|
204
|
+
tokenCache.set(token, { result, expiresAt });
|
|
205
|
+
// Clean up cache periodically
|
|
206
|
+
if (tokenCache.size > 1000) {
|
|
207
|
+
cleanupCache();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get token from cache if valid
|
|
212
|
+
*/
|
|
213
|
+
function getFromCache(token) {
|
|
214
|
+
const cached = tokenCache.get(token);
|
|
215
|
+
if (!cached) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
if (Date.now() > cached.expiresAt) {
|
|
219
|
+
tokenCache.delete(token);
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
return cached.result;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Remove expired entries from cache
|
|
226
|
+
*/
|
|
227
|
+
function cleanupCache() {
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
for (const [token, cached] of tokenCache.entries()) {
|
|
230
|
+
if (now > cached.expiresAt) {
|
|
231
|
+
tokenCache.delete(token);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Clear token cache (useful for testing)
|
|
237
|
+
*/
|
|
238
|
+
export function clearTokenCache() {
|
|
239
|
+
tokenCache.clear();
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=token-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-validation.js","sourceRoot":"","sources":["../../src/auth/token-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication Types for NitroStack
|
|
3
|
+
* Based on OAuth 2.1 and MCP Authorization Specification
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* OAuth 2.1 Token Response
|
|
7
|
+
*/
|
|
8
|
+
export interface TokenResponse {
|
|
9
|
+
access_token: string;
|
|
10
|
+
token_type: 'Bearer';
|
|
11
|
+
expires_in?: number;
|
|
12
|
+
refresh_token?: string;
|
|
13
|
+
scope?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Token introspection result
|
|
17
|
+
*/
|
|
18
|
+
export interface TokenIntrospection {
|
|
19
|
+
active: boolean;
|
|
20
|
+
scope?: string;
|
|
21
|
+
client_id?: string;
|
|
22
|
+
username?: string;
|
|
23
|
+
token_type?: string;
|
|
24
|
+
exp?: number;
|
|
25
|
+
iat?: number;
|
|
26
|
+
nbf?: number;
|
|
27
|
+
sub?: string;
|
|
28
|
+
aud?: string | string[];
|
|
29
|
+
iss?: string;
|
|
30
|
+
jti?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Protected Resource Metadata (RFC 9728)
|
|
34
|
+
*/
|
|
35
|
+
export interface ProtectedResourceMetadata {
|
|
36
|
+
resource: string;
|
|
37
|
+
authorization_servers: string[];
|
|
38
|
+
scopes_supported?: string[];
|
|
39
|
+
bearer_methods_supported?: ('header' | 'body' | 'query')[];
|
|
40
|
+
resource_signing_alg_values_supported?: string[];
|
|
41
|
+
resource_encryption_alg_values_supported?: string[];
|
|
42
|
+
resource_encryption_enc_values_supported?: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Authorization Server Metadata (RFC 8414)
|
|
46
|
+
*/
|
|
47
|
+
export interface AuthorizationServerMetadata {
|
|
48
|
+
issuer: string;
|
|
49
|
+
authorization_endpoint: string;
|
|
50
|
+
token_endpoint: string;
|
|
51
|
+
jwks_uri?: string;
|
|
52
|
+
registration_endpoint?: string;
|
|
53
|
+
scopes_supported?: string[];
|
|
54
|
+
response_types_supported: string[];
|
|
55
|
+
response_modes_supported?: string[];
|
|
56
|
+
grant_types_supported?: string[];
|
|
57
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
58
|
+
revocation_endpoint?: string;
|
|
59
|
+
revocation_endpoint_auth_methods_supported?: string[];
|
|
60
|
+
introspection_endpoint?: string;
|
|
61
|
+
introspection_endpoint_auth_methods_supported?: string[];
|
|
62
|
+
code_challenge_methods_supported: string[];
|
|
63
|
+
service_documentation?: string;
|
|
64
|
+
ui_locales_supported?: string[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Dynamic Client Registration Request (RFC 7591)
|
|
68
|
+
*/
|
|
69
|
+
export interface ClientRegistrationRequest {
|
|
70
|
+
redirect_uris: string[];
|
|
71
|
+
token_endpoint_auth_method?: string;
|
|
72
|
+
grant_types?: string[];
|
|
73
|
+
response_types?: string[];
|
|
74
|
+
client_name?: string;
|
|
75
|
+
client_uri?: string;
|
|
76
|
+
logo_uri?: string;
|
|
77
|
+
scope?: string;
|
|
78
|
+
contacts?: string[];
|
|
79
|
+
tos_uri?: string;
|
|
80
|
+
policy_uri?: string;
|
|
81
|
+
jwks_uri?: string;
|
|
82
|
+
software_id?: string;
|
|
83
|
+
software_version?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Dynamic Client Registration Response
|
|
87
|
+
*/
|
|
88
|
+
export interface ClientRegistrationResponse {
|
|
89
|
+
client_id: string;
|
|
90
|
+
client_secret?: string;
|
|
91
|
+
client_id_issued_at?: number;
|
|
92
|
+
client_secret_expires_at?: number;
|
|
93
|
+
redirect_uris: string[];
|
|
94
|
+
token_endpoint_auth_method?: string;
|
|
95
|
+
grant_types?: string[];
|
|
96
|
+
response_types?: string[];
|
|
97
|
+
client_name?: string;
|
|
98
|
+
client_uri?: string;
|
|
99
|
+
logo_uri?: string;
|
|
100
|
+
scope?: string;
|
|
101
|
+
contacts?: string[];
|
|
102
|
+
tos_uri?: string;
|
|
103
|
+
policy_uri?: string;
|
|
104
|
+
jwks_uri?: string;
|
|
105
|
+
software_id?: string;
|
|
106
|
+
software_version?: string;
|
|
107
|
+
registration_client_uri?: string;
|
|
108
|
+
registration_access_token?: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* PKCE (Proof Key for Code Exchange) parameters
|
|
112
|
+
*/
|
|
113
|
+
export interface PKCEParams {
|
|
114
|
+
code_verifier: string;
|
|
115
|
+
code_challenge: string;
|
|
116
|
+
code_challenge_method: 'S256' | 'plain';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Authorization request parameters
|
|
120
|
+
*/
|
|
121
|
+
export interface AuthorizationRequest {
|
|
122
|
+
response_type: 'code';
|
|
123
|
+
client_id: string;
|
|
124
|
+
redirect_uri: string;
|
|
125
|
+
scope?: string;
|
|
126
|
+
state: string;
|
|
127
|
+
code_challenge: string;
|
|
128
|
+
code_challenge_method: 'S256' | 'plain';
|
|
129
|
+
resource?: string;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Token request parameters
|
|
133
|
+
*/
|
|
134
|
+
export interface TokenRequest {
|
|
135
|
+
grant_type: 'authorization_code' | 'refresh_token' | 'client_credentials';
|
|
136
|
+
code?: string;
|
|
137
|
+
redirect_uri?: string;
|
|
138
|
+
client_id: string;
|
|
139
|
+
client_secret?: string;
|
|
140
|
+
code_verifier?: string;
|
|
141
|
+
refresh_token?: string;
|
|
142
|
+
resource?: string;
|
|
143
|
+
scope?: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* OAuth 2.1 Error Response
|
|
147
|
+
*/
|
|
148
|
+
export interface OAuth2Error {
|
|
149
|
+
error: string;
|
|
150
|
+
error_description?: string;
|
|
151
|
+
error_uri?: string;
|
|
152
|
+
state?: string;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* WWW-Authenticate Challenge (RFC 6750)
|
|
156
|
+
*/
|
|
157
|
+
export interface WWWAuthenticateChallenge {
|
|
158
|
+
scheme: 'Bearer';
|
|
159
|
+
realm?: string;
|
|
160
|
+
scope?: string;
|
|
161
|
+
error?: string;
|
|
162
|
+
error_description?: string;
|
|
163
|
+
resource_metadata?: string;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Auth configuration for MCP Server
|
|
167
|
+
*/
|
|
168
|
+
export interface McpAuthConfig {
|
|
169
|
+
resourceUri: string;
|
|
170
|
+
authorizationServers: string[];
|
|
171
|
+
scopesSupported?: string[];
|
|
172
|
+
tokenIntrospectionEndpoint?: string;
|
|
173
|
+
tokenIntrospectionClientId?: string;
|
|
174
|
+
tokenIntrospectionClientSecret?: string;
|
|
175
|
+
jwksUri?: string;
|
|
176
|
+
audience?: string;
|
|
177
|
+
issuer?: string;
|
|
178
|
+
requireHttps?: boolean;
|
|
179
|
+
tokenCacheSeconds?: number;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Auth configuration for MCP Client
|
|
183
|
+
*/
|
|
184
|
+
export interface McpAuthClientConfig {
|
|
185
|
+
clientId?: string;
|
|
186
|
+
clientSecret?: string;
|
|
187
|
+
authorizationServerUrl: string;
|
|
188
|
+
redirectUri?: string;
|
|
189
|
+
scopes?: string[];
|
|
190
|
+
resource?: string;
|
|
191
|
+
autoRegister?: boolean;
|
|
192
|
+
registrationMetadata?: Partial<ClientRegistrationRequest>;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Stored token information
|
|
196
|
+
*/
|
|
197
|
+
export interface StoredToken {
|
|
198
|
+
access_token: string;
|
|
199
|
+
token_type: 'Bearer';
|
|
200
|
+
expires_at: number;
|
|
201
|
+
refresh_token?: string;
|
|
202
|
+
scope?: string;
|
|
203
|
+
resource?: string;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Auth context passed to handlers
|
|
207
|
+
*/
|
|
208
|
+
export interface AuthContext {
|
|
209
|
+
authenticated: boolean;
|
|
210
|
+
tokenInfo?: TokenIntrospection;
|
|
211
|
+
scopes: string[];
|
|
212
|
+
clientId?: string;
|
|
213
|
+
subject?: string;
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
/**
|
|
3
|
+
* API Key Module Configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface ApiKeyModuleConfig {
|
|
6
|
+
/** Array of valid API keys (or env var names to read from) */
|
|
7
|
+
keys?: string[];
|
|
8
|
+
/** Environment variable prefix to read keys from (e.g., 'API_KEY' reads API_KEY_1, API_KEY_2, etc.) */
|
|
9
|
+
keysEnvPrefix?: string;
|
|
10
|
+
/** If true, keys are stored as SHA-256 hashes */
|
|
11
|
+
hashed?: boolean;
|
|
12
|
+
/** Header name to extract API key from (default: 'x-api-key') */
|
|
13
|
+
headerName?: string;
|
|
14
|
+
/** Metadata field name in MCP requests (default: 'apiKey') */
|
|
15
|
+
metadataField?: string;
|
|
16
|
+
/** Custom validation function */
|
|
17
|
+
customValidation?: (key: string) => Promise<boolean> | boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* API Key Module - Enable API key authentication in your MCP server
|
|
21
|
+
*
|
|
22
|
+
* Import this module to indicate your server uses API key authentication.
|
|
23
|
+
* Then use @UseGuards(ApiKeyGuard) on your tools to protect them.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { McpApplicationFactory, ApiKeyModule } from 'nitrostack';
|
|
28
|
+
* import { AppModule } from './app.module.js';
|
|
29
|
+
*
|
|
30
|
+
* async function bootstrap() {
|
|
31
|
+
* const app = await McpApplicationFactory.create(AppModule, {
|
|
32
|
+
* // Enable API key authentication
|
|
33
|
+
* apiKey: ApiKeyModule.forRoot({
|
|
34
|
+
* keysEnvPrefix: 'API_KEY', // Reads API_KEY_1, API_KEY_2, etc.
|
|
35
|
+
* headerName: 'x-api-key',
|
|
36
|
+
* }),
|
|
37
|
+
* });
|
|
38
|
+
* await app.start();
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare class ApiKeyModule {
|
|
43
|
+
private static config;
|
|
44
|
+
/**
|
|
45
|
+
* Configure API Key module for the application
|
|
46
|
+
*/
|
|
47
|
+
static forRoot(config: ApiKeyModuleConfig): ApiKeyModuleConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Get current API Key configuration
|
|
50
|
+
*/
|
|
51
|
+
static getConfig(): ApiKeyModuleConfig;
|
|
52
|
+
/**
|
|
53
|
+
* Get valid API keys from config or environment
|
|
54
|
+
*/
|
|
55
|
+
static getKeys(): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Validate an API key
|
|
58
|
+
*/
|
|
59
|
+
static validate(key: string): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Hash an API key (SHA-256)
|
|
62
|
+
*/
|
|
63
|
+
static hashKey(key: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Generate a secure API key
|
|
66
|
+
*/
|
|
67
|
+
static generateKey(prefix?: string): string;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=apikey-module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apikey-module.d.ts","sourceRoot":"","sources":["../../src/core/apikey-module.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,uGAAuG;IACvG,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,iCAAiC;IACjC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAChE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,MAAM,CAKnB;IAEF;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB;IAK9D;;OAEG;IACH,MAAM,CAAC,SAAS,IAAI,kBAAkB;IAItC;;OAEG;IACH,MAAM,CAAC,OAAO,IAAI,MAAM,EAAE;IA6B1B;;OAEG;WACU,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BpD;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAInC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,GAAE,MAAa,GAAG,MAAM;CAKlD"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
/**
|
|
4
|
+
* API Key Module - Enable API key authentication in your MCP server
|
|
5
|
+
*
|
|
6
|
+
* Import this module to indicate your server uses API key authentication.
|
|
7
|
+
* Then use @UseGuards(ApiKeyGuard) on your tools to protect them.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { McpApplicationFactory, ApiKeyModule } from 'nitrostack';
|
|
12
|
+
* import { AppModule } from './app.module.js';
|
|
13
|
+
*
|
|
14
|
+
* async function bootstrap() {
|
|
15
|
+
* const app = await McpApplicationFactory.create(AppModule, {
|
|
16
|
+
* // Enable API key authentication
|
|
17
|
+
* apiKey: ApiKeyModule.forRoot({
|
|
18
|
+
* keysEnvPrefix: 'API_KEY', // Reads API_KEY_1, API_KEY_2, etc.
|
|
19
|
+
* headerName: 'x-api-key',
|
|
20
|
+
* }),
|
|
21
|
+
* });
|
|
22
|
+
* await app.start();
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class ApiKeyModule {
|
|
27
|
+
static config = {
|
|
28
|
+
keysEnvPrefix: 'API_KEY',
|
|
29
|
+
headerName: 'x-api-key',
|
|
30
|
+
metadataField: 'apiKey',
|
|
31
|
+
hashed: false,
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Configure API Key module for the application
|
|
35
|
+
*/
|
|
36
|
+
static forRoot(config) {
|
|
37
|
+
this.config = { ...this.config, ...config };
|
|
38
|
+
return this.config;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get current API Key configuration
|
|
42
|
+
*/
|
|
43
|
+
static getConfig() {
|
|
44
|
+
return this.config;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get valid API keys from config or environment
|
|
48
|
+
*/
|
|
49
|
+
static getKeys() {
|
|
50
|
+
const keys = [];
|
|
51
|
+
// Add keys from config
|
|
52
|
+
if (this.config.keys && this.config.keys.length > 0) {
|
|
53
|
+
keys.push(...this.config.keys);
|
|
54
|
+
}
|
|
55
|
+
// Read from environment variables
|
|
56
|
+
if (this.config.keysEnvPrefix) {
|
|
57
|
+
let i = 1;
|
|
58
|
+
while (true) {
|
|
59
|
+
const envKey = `${this.config.keysEnvPrefix}_${i}`;
|
|
60
|
+
const value = process.env[envKey];
|
|
61
|
+
if (!value)
|
|
62
|
+
break;
|
|
63
|
+
keys.push(value);
|
|
64
|
+
i++;
|
|
65
|
+
}
|
|
66
|
+
// Also check for non-numbered version
|
|
67
|
+
const singleKey = process.env[this.config.keysEnvPrefix];
|
|
68
|
+
if (singleKey && !keys.includes(singleKey)) {
|
|
69
|
+
keys.push(singleKey);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return keys;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validate an API key
|
|
76
|
+
*/
|
|
77
|
+
static async validate(key) {
|
|
78
|
+
const keys = this.getKeys();
|
|
79
|
+
if (keys.length === 0) {
|
|
80
|
+
return false; // No keys configured
|
|
81
|
+
}
|
|
82
|
+
let isValid = false;
|
|
83
|
+
if (this.config.hashed) {
|
|
84
|
+
// Compare hashed values
|
|
85
|
+
const hashedKey = this.hashKey(key);
|
|
86
|
+
isValid = keys.includes(hashedKey);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// Direct comparison
|
|
90
|
+
isValid = keys.includes(key);
|
|
91
|
+
}
|
|
92
|
+
// Custom validation
|
|
93
|
+
if (this.config.customValidation) {
|
|
94
|
+
const customValid = await this.config.customValidation(key);
|
|
95
|
+
isValid = isValid && customValid;
|
|
96
|
+
}
|
|
97
|
+
return isValid;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Hash an API key (SHA-256)
|
|
101
|
+
*/
|
|
102
|
+
static hashKey(key) {
|
|
103
|
+
return crypto.createHash('sha256').update(key).digest('hex');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Generate a secure API key
|
|
107
|
+
*/
|
|
108
|
+
static generateKey(prefix = 'sk') {
|
|
109
|
+
const randomBytes = crypto.randomBytes(32);
|
|
110
|
+
const key = randomBytes.toString('base64url');
|
|
111
|
+
return `${prefix}_${key}`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=apikey-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apikey-module.js","sourceRoot":"","sources":["../../src/core/apikey-module.ts"],"names":[],"mappings":"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"}
|