@shin1ohno/sage 0.3.0 → 0.5.3
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/dist/cli/http-server-with-config.d.ts +38 -0
- package/dist/cli/http-server-with-config.d.ts.map +1 -0
- package/dist/cli/http-server-with-config.js +458 -0
- package/dist/cli/http-server-with-config.js.map +1 -0
- package/dist/cli/http-server.d.ts +74 -0
- package/dist/cli/http-server.d.ts.map +1 -0
- package/dist/cli/http-server.js +407 -0
- package/dist/cli/http-server.js.map +1 -0
- package/dist/cli/jwt-middleware.d.ts +36 -0
- package/dist/cli/jwt-middleware.d.ts.map +1 -0
- package/dist/cli/jwt-middleware.js +99 -0
- package/dist/cli/jwt-middleware.js.map +1 -0
- package/dist/cli/main-entry.d.ts +41 -0
- package/dist/cli/main-entry.d.ts.map +1 -0
- package/dist/cli/main-entry.js +80 -0
- package/dist/cli/main-entry.js.map +1 -0
- package/dist/cli/mcp-handler.d.ts +56 -0
- package/dist/cli/mcp-handler.d.ts.map +1 -0
- package/dist/cli/mcp-handler.js +2189 -0
- package/dist/cli/mcp-handler.js.map +1 -0
- package/dist/cli/parser.d.ts +43 -0
- package/dist/cli/parser.d.ts.map +1 -0
- package/dist/cli/parser.js +162 -0
- package/dist/cli/parser.js.map +1 -0
- package/dist/cli/remote-config-loader.d.ts +85 -0
- package/dist/cli/remote-config-loader.d.ts.map +1 -0
- package/dist/cli/remote-config-loader.js +129 -0
- package/dist/cli/remote-config-loader.js.map +1 -0
- package/dist/cli/secret-auth.d.ts +47 -0
- package/dist/cli/secret-auth.d.ts.map +1 -0
- package/dist/cli/secret-auth.js +165 -0
- package/dist/cli/secret-auth.js.map +1 -0
- package/dist/cli/sse-stream-handler.d.ts +45 -0
- package/dist/cli/sse-stream-handler.d.ts.map +1 -0
- package/dist/cli/sse-stream-handler.js +125 -0
- package/dist/cli/sse-stream-handler.js.map +1 -0
- package/dist/index.js +885 -209
- package/dist/index.js.map +1 -1
- package/dist/integrations/calendar-event-creator.d.ts +152 -0
- package/dist/integrations/calendar-event-creator.d.ts.map +1 -0
- package/dist/integrations/calendar-event-creator.js +507 -0
- package/dist/integrations/calendar-event-creator.js.map +1 -0
- package/dist/integrations/calendar-event-deleter.d.ts +137 -0
- package/dist/integrations/calendar-event-deleter.d.ts.map +1 -0
- package/dist/integrations/calendar-event-deleter.js +378 -0
- package/dist/integrations/calendar-event-deleter.js.map +1 -0
- package/dist/integrations/calendar-event-response.d.ts +213 -0
- package/dist/integrations/calendar-event-response.d.ts.map +1 -0
- package/dist/integrations/calendar-event-response.js +560 -0
- package/dist/integrations/calendar-event-response.js.map +1 -0
- package/dist/integrations/calendar-service.d.ts +66 -1
- package/dist/integrations/calendar-service.d.ts.map +1 -1
- package/dist/integrations/calendar-service.js +223 -0
- package/dist/integrations/calendar-service.js.map +1 -1
- package/dist/oauth/client-store.d.ts +36 -0
- package/dist/oauth/client-store.d.ts.map +1 -0
- package/dist/oauth/client-store.js +104 -0
- package/dist/oauth/client-store.js.map +1 -0
- package/dist/oauth/code-store.d.ts +48 -0
- package/dist/oauth/code-store.d.ts.map +1 -0
- package/dist/oauth/code-store.js +89 -0
- package/dist/oauth/code-store.js.map +1 -0
- package/dist/oauth/index.d.ts +13 -0
- package/dist/oauth/index.d.ts.map +1 -0
- package/dist/oauth/index.js +21 -0
- package/dist/oauth/index.js.map +1 -0
- package/dist/oauth/oauth-handler.d.ts +101 -0
- package/dist/oauth/oauth-handler.d.ts.map +1 -0
- package/dist/oauth/oauth-handler.js +577 -0
- package/dist/oauth/oauth-handler.js.map +1 -0
- package/dist/oauth/oauth-server.d.ts +165 -0
- package/dist/oauth/oauth-server.d.ts.map +1 -0
- package/dist/oauth/oauth-server.js +489 -0
- package/dist/oauth/oauth-server.js.map +1 -0
- package/dist/oauth/pkce.d.ts +48 -0
- package/dist/oauth/pkce.d.ts.map +1 -0
- package/dist/oauth/pkce.js +106 -0
- package/dist/oauth/pkce.js.map +1 -0
- package/dist/oauth/refresh-token-store.d.ts +45 -0
- package/dist/oauth/refresh-token-store.d.ts.map +1 -0
- package/dist/oauth/refresh-token-store.js +98 -0
- package/dist/oauth/refresh-token-store.js.map +1 -0
- package/dist/oauth/token-service.d.ts +46 -0
- package/dist/oauth/token-service.d.ts.map +1 -0
- package/dist/oauth/token-service.js +199 -0
- package/dist/oauth/token-service.js.map +1 -0
- package/dist/oauth/types.d.ts +264 -0
- package/dist/oauth/types.d.ts.map +1 -0
- package/dist/oauth/types.js +37 -0
- package/dist/oauth/types.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Refresh Token Store
|
|
3
|
+
* Requirements: 21.6, 26.3, 26.8
|
|
4
|
+
*
|
|
5
|
+
* Manages refresh token generation, storage, validation, and rotation.
|
|
6
|
+
*/
|
|
7
|
+
import { RefreshToken } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for Refresh Token Store
|
|
10
|
+
*/
|
|
11
|
+
export interface RefreshTokenStoreConfig {
|
|
12
|
+
expirySeconds: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Options for generating a refresh token
|
|
16
|
+
*/
|
|
17
|
+
export interface GenerateRefreshTokenOptions {
|
|
18
|
+
clientId: string;
|
|
19
|
+
userId: string;
|
|
20
|
+
scope: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of validating a refresh token
|
|
24
|
+
*/
|
|
25
|
+
export interface RefreshTokenValidationResult {
|
|
26
|
+
valid: boolean;
|
|
27
|
+
tokenData?: RefreshToken;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Refresh Token Store Interface
|
|
32
|
+
*/
|
|
33
|
+
export interface RefreshTokenStore {
|
|
34
|
+
generateToken(options: GenerateRefreshTokenOptions): Promise<string>;
|
|
35
|
+
validateToken(token: string, clientId: string): Promise<RefreshTokenValidationResult>;
|
|
36
|
+
rotateToken(token: string, clientId: string): Promise<string | null>;
|
|
37
|
+
revokeToken(token: string): Promise<void>;
|
|
38
|
+
revokeAllForClient(clientId: string): Promise<void>;
|
|
39
|
+
cleanup(): Promise<number>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a Refresh Token Store instance
|
|
43
|
+
*/
|
|
44
|
+
export declare function createRefreshTokenStore(config: RefreshTokenStoreConfig): RefreshTokenStore;
|
|
45
|
+
//# sourceMappingURL=refresh-token-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-token-store.d.ts","sourceRoot":"","sources":["../../src/oauth/refresh-token-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;IACtF,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5B;AA6GD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,iBAAiB,CAE1F"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Refresh Token Store
|
|
3
|
+
* Requirements: 21.6, 26.3, 26.8
|
|
4
|
+
*
|
|
5
|
+
* Manages refresh token generation, storage, validation, and rotation.
|
|
6
|
+
*/
|
|
7
|
+
import { randomBytes } from 'crypto';
|
|
8
|
+
/**
|
|
9
|
+
* In-memory Refresh Token Store Implementation
|
|
10
|
+
*/
|
|
11
|
+
class InMemoryRefreshTokenStore {
|
|
12
|
+
tokens = new Map();
|
|
13
|
+
config;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
async generateToken(options) {
|
|
18
|
+
// Generate secure random token
|
|
19
|
+
const token = randomBytes(32).toString('base64url');
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const expiresAt = now + this.config.expirySeconds * 1000;
|
|
22
|
+
const tokenData = {
|
|
23
|
+
token,
|
|
24
|
+
client_id: options.clientId,
|
|
25
|
+
user_id: options.userId,
|
|
26
|
+
scope: options.scope,
|
|
27
|
+
created_at: now,
|
|
28
|
+
expires_at: expiresAt,
|
|
29
|
+
rotated: false,
|
|
30
|
+
};
|
|
31
|
+
this.tokens.set(token, tokenData);
|
|
32
|
+
return token;
|
|
33
|
+
}
|
|
34
|
+
async validateToken(token, clientId) {
|
|
35
|
+
const tokenData = this.tokens.get(token);
|
|
36
|
+
if (!tokenData) {
|
|
37
|
+
return { valid: false, error: 'invalid_grant' };
|
|
38
|
+
}
|
|
39
|
+
// Check if token has been rotated
|
|
40
|
+
if (tokenData.rotated) {
|
|
41
|
+
return { valid: false, error: 'invalid_grant' };
|
|
42
|
+
}
|
|
43
|
+
// Check if token has expired
|
|
44
|
+
if (Date.now() > tokenData.expires_at) {
|
|
45
|
+
this.tokens.delete(token);
|
|
46
|
+
return { valid: false, error: 'invalid_grant' };
|
|
47
|
+
}
|
|
48
|
+
// Verify client_id matches
|
|
49
|
+
if (tokenData.client_id !== clientId) {
|
|
50
|
+
return { valid: false, error: 'invalid_grant' };
|
|
51
|
+
}
|
|
52
|
+
return { valid: true, tokenData };
|
|
53
|
+
}
|
|
54
|
+
async rotateToken(token, clientId) {
|
|
55
|
+
const validationResult = await this.validateToken(token, clientId);
|
|
56
|
+
if (!validationResult.valid || !validationResult.tokenData) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
// Mark old token as rotated (Requirement 26.8)
|
|
60
|
+
const oldTokenData = this.tokens.get(token);
|
|
61
|
+
oldTokenData.rotated = true;
|
|
62
|
+
// Generate new token with same scope
|
|
63
|
+
const newToken = await this.generateToken({
|
|
64
|
+
clientId: validationResult.tokenData.client_id,
|
|
65
|
+
userId: validationResult.tokenData.user_id,
|
|
66
|
+
scope: validationResult.tokenData.scope,
|
|
67
|
+
});
|
|
68
|
+
return newToken;
|
|
69
|
+
}
|
|
70
|
+
async revokeToken(token) {
|
|
71
|
+
this.tokens.delete(token);
|
|
72
|
+
}
|
|
73
|
+
async revokeAllForClient(clientId) {
|
|
74
|
+
for (const [token, data] of this.tokens.entries()) {
|
|
75
|
+
if (data.client_id === clientId) {
|
|
76
|
+
this.tokens.delete(token);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async cleanup() {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
let cleanedCount = 0;
|
|
83
|
+
for (const [token, data] of this.tokens.entries()) {
|
|
84
|
+
if (data.expires_at < now || data.rotated) {
|
|
85
|
+
this.tokens.delete(token);
|
|
86
|
+
cleanedCount++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return cleanedCount;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create a Refresh Token Store instance
|
|
94
|
+
*/
|
|
95
|
+
export function createRefreshTokenStore(config) {
|
|
96
|
+
return new InMemoryRefreshTokenStore(config);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=refresh-token-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-token-store.js","sourceRoot":"","sources":["../../src/oauth/refresh-token-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Token Service
|
|
3
|
+
* Requirements: 21.4, 21.5, 26.6, 26.7, 27.1-27.5
|
|
4
|
+
*
|
|
5
|
+
* Implements JWT access token generation and verification using RS256 signing.
|
|
6
|
+
*/
|
|
7
|
+
import { TokenResponse, VerifyTokenResult } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Token Service Configuration
|
|
10
|
+
*/
|
|
11
|
+
export interface TokenServiceConfig {
|
|
12
|
+
issuer: string;
|
|
13
|
+
privateKey: string;
|
|
14
|
+
publicKey: string;
|
|
15
|
+
accessTokenExpiry: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Access Token Generation Options
|
|
19
|
+
*/
|
|
20
|
+
export interface GenerateAccessTokenOptions {
|
|
21
|
+
clientId: string;
|
|
22
|
+
userId: string;
|
|
23
|
+
scope: string;
|
|
24
|
+
audience: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Token Service Interface
|
|
28
|
+
*/
|
|
29
|
+
export interface TokenService {
|
|
30
|
+
generateAccessToken(options: GenerateAccessTokenOptions): Promise<TokenResponse>;
|
|
31
|
+
verifyAccessToken(token: string, expectedAudience?: string): Promise<VerifyTokenResult>;
|
|
32
|
+
extractTokenFromHeader(header: string | undefined): string | null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a Token Service instance
|
|
36
|
+
*/
|
|
37
|
+
export declare function createTokenService(config: TokenServiceConfig): TokenService;
|
|
38
|
+
/**
|
|
39
|
+
* Generate RSA key pair for JWT signing
|
|
40
|
+
* Requirement: RS256 signing
|
|
41
|
+
*/
|
|
42
|
+
export declare function generateKeyPair(): Promise<{
|
|
43
|
+
privateKey: string;
|
|
44
|
+
publicKey: string;
|
|
45
|
+
}>;
|
|
46
|
+
//# sourceMappingURL=token-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-service.d.ts","sourceRoot":"","sources":["../../src/oauth/token-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAqB,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACjF,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxF,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;CACnE;AAgND;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAE3E;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAc1F"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Token Service
|
|
3
|
+
* Requirements: 21.4, 21.5, 26.6, 26.7, 27.1-27.5
|
|
4
|
+
*
|
|
5
|
+
* Implements JWT access token generation and verification using RS256 signing.
|
|
6
|
+
*/
|
|
7
|
+
import { createSign, createVerify, generateKeyPairSync, randomUUID } from 'crypto';
|
|
8
|
+
/**
|
|
9
|
+
* Parse duration string to seconds
|
|
10
|
+
* Supports: s (seconds), m (minutes), h (hours), d (days), w (weeks)
|
|
11
|
+
*/
|
|
12
|
+
function parseDuration(duration) {
|
|
13
|
+
const match = duration.match(/^(\d+)([smhdw])$/);
|
|
14
|
+
if (!match) {
|
|
15
|
+
throw new Error(`Invalid duration format: ${duration}`);
|
|
16
|
+
}
|
|
17
|
+
const value = parseInt(match[1], 10);
|
|
18
|
+
const unit = match[2];
|
|
19
|
+
switch (unit) {
|
|
20
|
+
case 's':
|
|
21
|
+
return value;
|
|
22
|
+
case 'm':
|
|
23
|
+
return value * 60;
|
|
24
|
+
case 'h':
|
|
25
|
+
return value * 3600;
|
|
26
|
+
case 'd':
|
|
27
|
+
return value * 86400;
|
|
28
|
+
case 'w':
|
|
29
|
+
return value * 604800;
|
|
30
|
+
default:
|
|
31
|
+
throw new Error(`Unknown duration unit: ${unit}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Base64URL encode a string
|
|
36
|
+
*/
|
|
37
|
+
function base64UrlEncode(data) {
|
|
38
|
+
const base64 = typeof data === 'string' ? Buffer.from(data).toString('base64') : data.toString('base64');
|
|
39
|
+
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Base64URL decode a string
|
|
43
|
+
*/
|
|
44
|
+
function base64UrlDecode(data) {
|
|
45
|
+
// Add padding if needed
|
|
46
|
+
const padding = 4 - (data.length % 4);
|
|
47
|
+
const padded = padding < 4 ? data + '='.repeat(padding) : data;
|
|
48
|
+
const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');
|
|
49
|
+
return Buffer.from(base64, 'base64');
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create JWT token using RS256
|
|
53
|
+
*/
|
|
54
|
+
function createJWT(payload, privateKey) {
|
|
55
|
+
// Header
|
|
56
|
+
const header = {
|
|
57
|
+
alg: 'RS256',
|
|
58
|
+
typ: 'JWT',
|
|
59
|
+
};
|
|
60
|
+
// Encode header and payload
|
|
61
|
+
const encodedHeader = base64UrlEncode(JSON.stringify(header));
|
|
62
|
+
const encodedPayload = base64UrlEncode(JSON.stringify(payload));
|
|
63
|
+
// Create signature input
|
|
64
|
+
const signatureInput = `${encodedHeader}.${encodedPayload}`;
|
|
65
|
+
// Sign using RS256
|
|
66
|
+
const sign = createSign('RSA-SHA256');
|
|
67
|
+
sign.update(signatureInput);
|
|
68
|
+
const signature = sign.sign(privateKey);
|
|
69
|
+
// Encode signature
|
|
70
|
+
const encodedSignature = base64UrlEncode(signature);
|
|
71
|
+
return `${signatureInput}.${encodedSignature}`;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Verify JWT token using RS256
|
|
75
|
+
*/
|
|
76
|
+
function verifyJWT(token, publicKey) {
|
|
77
|
+
const parts = token.split('.');
|
|
78
|
+
if (parts.length !== 3) {
|
|
79
|
+
return { valid: false, error: 'Invalid token format' };
|
|
80
|
+
}
|
|
81
|
+
const [encodedHeader, encodedPayload, encodedSignature] = parts;
|
|
82
|
+
try {
|
|
83
|
+
// Decode and verify header
|
|
84
|
+
const header = JSON.parse(base64UrlDecode(encodedHeader).toString());
|
|
85
|
+
if (header.alg !== 'RS256') {
|
|
86
|
+
return { valid: false, error: 'Invalid algorithm' };
|
|
87
|
+
}
|
|
88
|
+
// Verify signature
|
|
89
|
+
const signatureInput = `${encodedHeader}.${encodedPayload}`;
|
|
90
|
+
const signature = base64UrlDecode(encodedSignature);
|
|
91
|
+
const verify = createVerify('RSA-SHA256');
|
|
92
|
+
verify.update(signatureInput);
|
|
93
|
+
const isValid = verify.verify(publicKey, signature);
|
|
94
|
+
if (!isValid) {
|
|
95
|
+
return { valid: false, error: 'Invalid signature' };
|
|
96
|
+
}
|
|
97
|
+
// Decode payload
|
|
98
|
+
const payload = JSON.parse(base64UrlDecode(encodedPayload).toString());
|
|
99
|
+
return { valid: true, payload };
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
return { valid: false, error: error instanceof Error ? error.message : 'Token verification failed' };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Token Service Implementation
|
|
107
|
+
*/
|
|
108
|
+
class TokenServiceImpl {
|
|
109
|
+
config;
|
|
110
|
+
expirySeconds;
|
|
111
|
+
constructor(config) {
|
|
112
|
+
this.config = config;
|
|
113
|
+
this.expirySeconds = parseDuration(config.accessTokenExpiry);
|
|
114
|
+
}
|
|
115
|
+
async generateAccessToken(options) {
|
|
116
|
+
const now = Math.floor(Date.now() / 1000);
|
|
117
|
+
const exp = now + this.expirySeconds;
|
|
118
|
+
const claims = {
|
|
119
|
+
iss: this.config.issuer,
|
|
120
|
+
sub: options.userId,
|
|
121
|
+
aud: options.audience,
|
|
122
|
+
exp,
|
|
123
|
+
iat: now,
|
|
124
|
+
jti: randomUUID(),
|
|
125
|
+
client_id: options.clientId,
|
|
126
|
+
scope: options.scope,
|
|
127
|
+
};
|
|
128
|
+
const accessToken = createJWT(claims, this.config.privateKey);
|
|
129
|
+
return {
|
|
130
|
+
access_token: accessToken,
|
|
131
|
+
token_type: 'Bearer',
|
|
132
|
+
expires_in: this.expirySeconds,
|
|
133
|
+
scope: options.scope,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
async verifyAccessToken(token, expectedAudience) {
|
|
137
|
+
const result = verifyJWT(token, this.config.publicKey);
|
|
138
|
+
if (!result.valid) {
|
|
139
|
+
return { valid: false, error: result.error };
|
|
140
|
+
}
|
|
141
|
+
const payload = result.payload;
|
|
142
|
+
// Verify issuer
|
|
143
|
+
if (payload.iss !== this.config.issuer) {
|
|
144
|
+
return { valid: false, error: 'Invalid issuer' };
|
|
145
|
+
}
|
|
146
|
+
// Verify expiration
|
|
147
|
+
const now = Math.floor(Date.now() / 1000);
|
|
148
|
+
if (payload.exp < now) {
|
|
149
|
+
return { valid: false, error: 'Token expired' };
|
|
150
|
+
}
|
|
151
|
+
// Verify audience if specified
|
|
152
|
+
if (expectedAudience && payload.aud !== expectedAudience) {
|
|
153
|
+
return { valid: false, error: 'Invalid audience' };
|
|
154
|
+
}
|
|
155
|
+
return { valid: true, claims: payload };
|
|
156
|
+
}
|
|
157
|
+
extractTokenFromHeader(header) {
|
|
158
|
+
if (!header) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
const parts = header.split(' ');
|
|
162
|
+
if (parts.length !== 2) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
if (parts[0].toLowerCase() !== 'bearer') {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const token = parts[1];
|
|
169
|
+
if (!token || token.trim() === '') {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
return token;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Create a Token Service instance
|
|
177
|
+
*/
|
|
178
|
+
export function createTokenService(config) {
|
|
179
|
+
return new TokenServiceImpl(config);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Generate RSA key pair for JWT signing
|
|
183
|
+
* Requirement: RS256 signing
|
|
184
|
+
*/
|
|
185
|
+
export async function generateKeyPair() {
|
|
186
|
+
const { privateKey, publicKey } = generateKeyPairSync('rsa', {
|
|
187
|
+
modulusLength: 2048,
|
|
188
|
+
publicKeyEncoding: {
|
|
189
|
+
type: 'spki',
|
|
190
|
+
format: 'pem',
|
|
191
|
+
},
|
|
192
|
+
privateKeyEncoding: {
|
|
193
|
+
type: 'pkcs8',
|
|
194
|
+
format: 'pem',
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
return { privateKey, publicKey };
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=token-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-service.js","sourceRoot":"","sources":["../../src/oauth/token-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.1 Type Definitions
|
|
3
|
+
* Requirements: 21.1-21.6, 22.1-22.5, 23.1-23.9, 24.1-24.8, 25.1-25.10, 26.1-26.9
|
|
4
|
+
*
|
|
5
|
+
* Type definitions for OAuth 2.1 implementation based on:
|
|
6
|
+
* - OAuth 2.1 (draft-ietf-oauth-v2-1-13)
|
|
7
|
+
* - RFC 8414 (Authorization Server Metadata)
|
|
8
|
+
* - RFC 7591 (Dynamic Client Registration)
|
|
9
|
+
* - RFC 9728 (Protected Resource Metadata)
|
|
10
|
+
* - RFC 8707 (Resource Indicators)
|
|
11
|
+
* - RFC 7636 (PKCE)
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Supported OAuth scopes
|
|
15
|
+
* Requirement 22.2
|
|
16
|
+
*/
|
|
17
|
+
export type OAuthScope = 'mcp:read' | 'mcp:write' | 'mcp:admin';
|
|
18
|
+
/**
|
|
19
|
+
* Supported response types
|
|
20
|
+
* Requirement 23.6
|
|
21
|
+
*/
|
|
22
|
+
export type ResponseType = 'code';
|
|
23
|
+
/**
|
|
24
|
+
* Supported grant types
|
|
25
|
+
* Requirement 23.7
|
|
26
|
+
*/
|
|
27
|
+
export type GrantType = 'authorization_code' | 'refresh_token';
|
|
28
|
+
/**
|
|
29
|
+
* Supported code challenge methods
|
|
30
|
+
* Requirement 21.2, 23.8
|
|
31
|
+
*/
|
|
32
|
+
export type CodeChallengeMethod = 'S256';
|
|
33
|
+
/**
|
|
34
|
+
* Supported token endpoint auth methods
|
|
35
|
+
* Requirement 23.9
|
|
36
|
+
*/
|
|
37
|
+
export type TokenEndpointAuthMethod = 'none' | 'client_secret_post';
|
|
38
|
+
/**
|
|
39
|
+
* OAuth Client Registration Request (RFC 7591)
|
|
40
|
+
* Requirement 24.1-24.7
|
|
41
|
+
*/
|
|
42
|
+
export interface ClientRegistrationRequest {
|
|
43
|
+
client_name: string;
|
|
44
|
+
redirect_uris: string[];
|
|
45
|
+
response_types?: ResponseType[];
|
|
46
|
+
grant_types?: GrantType[];
|
|
47
|
+
token_endpoint_auth_method?: TokenEndpointAuthMethod;
|
|
48
|
+
scope?: string;
|
|
49
|
+
contacts?: string[];
|
|
50
|
+
logo_uri?: string;
|
|
51
|
+
client_uri?: string;
|
|
52
|
+
policy_uri?: string;
|
|
53
|
+
tos_uri?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* OAuth Client Metadata (RFC 7591)
|
|
57
|
+
* Requirement 24.6
|
|
58
|
+
*/
|
|
59
|
+
export interface OAuthClient {
|
|
60
|
+
client_id: string;
|
|
61
|
+
client_name: string;
|
|
62
|
+
redirect_uris: string[];
|
|
63
|
+
response_types: ResponseType[];
|
|
64
|
+
grant_types: GrantType[];
|
|
65
|
+
token_endpoint_auth_method: TokenEndpointAuthMethod;
|
|
66
|
+
client_id_issued_at: number;
|
|
67
|
+
client_secret?: string;
|
|
68
|
+
client_secret_expires_at?: number;
|
|
69
|
+
scope?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Authorization Request Parameters
|
|
73
|
+
* Requirement 25.1-25.10
|
|
74
|
+
*/
|
|
75
|
+
export interface AuthorizationRequest {
|
|
76
|
+
response_type: ResponseType;
|
|
77
|
+
client_id: string;
|
|
78
|
+
redirect_uri: string;
|
|
79
|
+
scope?: string;
|
|
80
|
+
state: string;
|
|
81
|
+
code_challenge: string;
|
|
82
|
+
code_challenge_method: CodeChallengeMethod;
|
|
83
|
+
resource?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Authorization Code Data (internal)
|
|
87
|
+
* Requirement 25.9, 25.10
|
|
88
|
+
*/
|
|
89
|
+
export interface AuthorizationCode {
|
|
90
|
+
code: string;
|
|
91
|
+
client_id: string;
|
|
92
|
+
redirect_uri: string;
|
|
93
|
+
scope: string;
|
|
94
|
+
code_challenge: string;
|
|
95
|
+
code_challenge_method: CodeChallengeMethod;
|
|
96
|
+
resource?: string;
|
|
97
|
+
user_id: string;
|
|
98
|
+
created_at: number;
|
|
99
|
+
expires_at: number;
|
|
100
|
+
used: boolean;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Token Request for authorization_code grant
|
|
104
|
+
* Requirement 26.1-26.5
|
|
105
|
+
*/
|
|
106
|
+
export interface TokenRequestAuthorizationCode {
|
|
107
|
+
grant_type: 'authorization_code';
|
|
108
|
+
code: string;
|
|
109
|
+
client_id: string;
|
|
110
|
+
redirect_uri: string;
|
|
111
|
+
code_verifier: string;
|
|
112
|
+
resource?: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Token Request for refresh_token grant
|
|
116
|
+
* Requirement 26.3
|
|
117
|
+
*/
|
|
118
|
+
export interface TokenRequestRefreshToken {
|
|
119
|
+
grant_type: 'refresh_token';
|
|
120
|
+
refresh_token: string;
|
|
121
|
+
client_id: string;
|
|
122
|
+
scope?: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Token Request (union type)
|
|
126
|
+
*/
|
|
127
|
+
export type TokenRequest = TokenRequestAuthorizationCode | TokenRequestRefreshToken;
|
|
128
|
+
/**
|
|
129
|
+
* Token Response
|
|
130
|
+
* Requirement 26.7
|
|
131
|
+
*/
|
|
132
|
+
export interface TokenResponse {
|
|
133
|
+
access_token: string;
|
|
134
|
+
token_type: 'Bearer';
|
|
135
|
+
expires_in: number;
|
|
136
|
+
refresh_token?: string;
|
|
137
|
+
scope?: string;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Access Token Claims (JWT payload)
|
|
141
|
+
* Requirement 26.6, 27.4
|
|
142
|
+
*/
|
|
143
|
+
export interface AccessTokenClaims {
|
|
144
|
+
iss: string;
|
|
145
|
+
sub: string;
|
|
146
|
+
aud: string;
|
|
147
|
+
exp: number;
|
|
148
|
+
iat: number;
|
|
149
|
+
jti: string;
|
|
150
|
+
client_id: string;
|
|
151
|
+
scope: string;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Refresh Token Data (internal)
|
|
155
|
+
* Requirement 21.6, 26.8
|
|
156
|
+
*/
|
|
157
|
+
export interface RefreshToken {
|
|
158
|
+
token: string;
|
|
159
|
+
client_id: string;
|
|
160
|
+
user_id: string;
|
|
161
|
+
scope: string;
|
|
162
|
+
created_at: number;
|
|
163
|
+
expires_at: number;
|
|
164
|
+
rotated: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Protected Resource Metadata (RFC 9728)
|
|
168
|
+
* Requirement 22.1-22.3
|
|
169
|
+
*/
|
|
170
|
+
export interface ProtectedResourceMetadata {
|
|
171
|
+
resource: string;
|
|
172
|
+
authorization_servers: string[];
|
|
173
|
+
scopes_supported?: string[];
|
|
174
|
+
bearer_methods_supported?: string[];
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Authorization Server Metadata (RFC 8414)
|
|
178
|
+
* Requirement 23.1-23.9
|
|
179
|
+
*/
|
|
180
|
+
export interface AuthorizationServerMetadata {
|
|
181
|
+
issuer: string;
|
|
182
|
+
authorization_endpoint: string;
|
|
183
|
+
token_endpoint: string;
|
|
184
|
+
registration_endpoint?: string;
|
|
185
|
+
scopes_supported?: string[];
|
|
186
|
+
response_types_supported: ResponseType[];
|
|
187
|
+
response_modes_supported?: string[];
|
|
188
|
+
grant_types_supported: GrantType[];
|
|
189
|
+
token_endpoint_auth_methods_supported: TokenEndpointAuthMethod[];
|
|
190
|
+
code_challenge_methods_supported: CodeChallengeMethod[];
|
|
191
|
+
service_documentation?: string;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* OAuth Error Response
|
|
195
|
+
*/
|
|
196
|
+
export interface OAuthError {
|
|
197
|
+
error: string;
|
|
198
|
+
error_description?: string;
|
|
199
|
+
error_uri?: string;
|
|
200
|
+
state?: string;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* OAuth Error Codes
|
|
204
|
+
*/
|
|
205
|
+
export type OAuthErrorCode = 'invalid_request' | 'unauthorized_client' | 'access_denied' | 'unsupported_response_type' | 'invalid_scope' | 'server_error' | 'temporarily_unavailable' | 'invalid_client' | 'invalid_grant' | 'unsupported_grant_type' | 'invalid_token' | 'insufficient_scope';
|
|
206
|
+
/**
|
|
207
|
+
* User for authentication
|
|
208
|
+
* Requirement 29.1-29.4
|
|
209
|
+
*/
|
|
210
|
+
export interface OAuthUser {
|
|
211
|
+
id: string;
|
|
212
|
+
username: string;
|
|
213
|
+
passwordHash: string;
|
|
214
|
+
createdAt: number;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* User Session
|
|
218
|
+
*/
|
|
219
|
+
export interface UserSession {
|
|
220
|
+
sessionId: string;
|
|
221
|
+
userId: string;
|
|
222
|
+
createdAt: number;
|
|
223
|
+
expiresAt: number;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* OAuth Configuration
|
|
227
|
+
*/
|
|
228
|
+
export interface OAuthConfig {
|
|
229
|
+
issuer: string;
|
|
230
|
+
accessTokenExpiry: string;
|
|
231
|
+
refreshTokenExpiry: string;
|
|
232
|
+
authorizationCodeExpiry: string;
|
|
233
|
+
allowedRedirectUris: string[];
|
|
234
|
+
scopes: Record<OAuthScope, string>;
|
|
235
|
+
users: OAuthUser[];
|
|
236
|
+
privateKey?: string;
|
|
237
|
+
publicKey?: string;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Scope definitions with descriptions
|
|
241
|
+
*/
|
|
242
|
+
export declare const SCOPE_DEFINITIONS: Record<OAuthScope, string>;
|
|
243
|
+
/**
|
|
244
|
+
* Claude official callback URLs
|
|
245
|
+
* Requirement 24.4, 24.5, 31.1, 31.2
|
|
246
|
+
*/
|
|
247
|
+
export declare const CLAUDE_CALLBACK_URLS: string[];
|
|
248
|
+
/**
|
|
249
|
+
* Default token expiry durations
|
|
250
|
+
*/
|
|
251
|
+
export declare const DEFAULT_TOKEN_EXPIRY: {
|
|
252
|
+
accessToken: string;
|
|
253
|
+
refreshToken: string;
|
|
254
|
+
authorizationCode: string;
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Verify Token Result
|
|
258
|
+
*/
|
|
259
|
+
export interface VerifyTokenResult {
|
|
260
|
+
valid: boolean;
|
|
261
|
+
claims?: AccessTokenClaims;
|
|
262
|
+
error?: string;
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=types.d.ts.map
|