@shin1ohno/sage 0.2.4 → 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 +85 -10
- package/dist/integrations/calendar-service.d.ts.map +1 -1
- package/dist/integrations/calendar-service.js +317 -35
- 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/manifest.json +12 -20
- package/package.json +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Client Store
|
|
3
|
+
* Requirements: 24.1-24.8
|
|
4
|
+
*
|
|
5
|
+
* Manages OAuth client registration and storage for Dynamic Client Registration (RFC 7591).
|
|
6
|
+
*/
|
|
7
|
+
import { randomBytes } from 'crypto';
|
|
8
|
+
import { CLAUDE_CALLBACK_URLS, } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Validate redirect URIs against allowed list
|
|
11
|
+
* Requirement 24.3, 24.4, 24.5
|
|
12
|
+
*/
|
|
13
|
+
function validateRedirectUris(uris, allowedUris) {
|
|
14
|
+
if (!uris || uris.length === 0) {
|
|
15
|
+
return { valid: false, error: 'redirect_uris is required' };
|
|
16
|
+
}
|
|
17
|
+
for (const uri of uris) {
|
|
18
|
+
// Check if URI is in Claude official URLs (always allowed)
|
|
19
|
+
if (CLAUDE_CALLBACK_URLS.includes(uri)) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
// Check if URI is in allowed list
|
|
23
|
+
if (!allowedUris.includes(uri) && !allowedUris.includes('*')) {
|
|
24
|
+
return { valid: false, error: `redirect_uri not allowed: ${uri}` };
|
|
25
|
+
}
|
|
26
|
+
// Validate URI format
|
|
27
|
+
try {
|
|
28
|
+
const parsed = new URL(uri);
|
|
29
|
+
// Require HTTPS for non-localhost URIs
|
|
30
|
+
if (parsed.protocol !== 'https:' && parsed.hostname !== 'localhost') {
|
|
31
|
+
return { valid: false, error: `redirect_uri must use HTTPS: ${uri}` };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { valid: false, error: `Invalid redirect_uri format: ${uri}` };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { valid: true };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* In-memory Client Store Implementation
|
|
42
|
+
*/
|
|
43
|
+
class InMemoryClientStore {
|
|
44
|
+
clients = new Map();
|
|
45
|
+
config;
|
|
46
|
+
constructor(config) {
|
|
47
|
+
this.config = config;
|
|
48
|
+
}
|
|
49
|
+
async registerClient(request) {
|
|
50
|
+
// Validate client_name
|
|
51
|
+
if (!request.client_name || request.client_name.trim() === '') {
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
error: 'invalid_client_metadata',
|
|
55
|
+
errorDescription: 'client_name is required',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Validate redirect_uris (Requirement 24.3)
|
|
59
|
+
const uriValidation = validateRedirectUris(request.redirect_uris, this.config.allowedRedirectUris);
|
|
60
|
+
if (!uriValidation.valid) {
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
error: 'invalid_redirect_uri',
|
|
64
|
+
errorDescription: uriValidation.error,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Generate client_id
|
|
68
|
+
const clientId = `sage_${randomBytes(16).toString('hex')}`;
|
|
69
|
+
// Create client metadata
|
|
70
|
+
const client = {
|
|
71
|
+
client_id: clientId,
|
|
72
|
+
client_name: request.client_name,
|
|
73
|
+
redirect_uris: request.redirect_uris,
|
|
74
|
+
response_types: request.response_types || ['code'],
|
|
75
|
+
grant_types: request.grant_types || ['authorization_code', 'refresh_token'],
|
|
76
|
+
token_endpoint_auth_method: request.token_endpoint_auth_method || 'none',
|
|
77
|
+
client_id_issued_at: Math.floor(Date.now() / 1000),
|
|
78
|
+
};
|
|
79
|
+
// Store client
|
|
80
|
+
this.clients.set(clientId, client);
|
|
81
|
+
return { success: true, client };
|
|
82
|
+
}
|
|
83
|
+
async getClient(clientId) {
|
|
84
|
+
return this.clients.get(clientId) || null;
|
|
85
|
+
}
|
|
86
|
+
async deleteClient(clientId) {
|
|
87
|
+
return this.clients.delete(clientId);
|
|
88
|
+
}
|
|
89
|
+
async isValidRedirectUri(clientId, redirectUri) {
|
|
90
|
+
const client = await this.getClient(clientId);
|
|
91
|
+
if (!client) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
// Requirement 30.5: Exact match validation
|
|
95
|
+
return client.redirect_uris.includes(redirectUri);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create a Client Store instance
|
|
100
|
+
*/
|
|
101
|
+
export function createClientStore(config) {
|
|
102
|
+
return new InMemoryClientStore(config);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=client-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-store.js","sourceRoot":"","sources":["../../src/oauth/client-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Authorization Code Store
|
|
3
|
+
* Requirements: 25.9, 25.10, 26.4
|
|
4
|
+
*
|
|
5
|
+
* Manages authorization code generation, storage, and validation.
|
|
6
|
+
*/
|
|
7
|
+
import { AuthorizationCode, CodeChallengeMethod } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for Authorization Code Store
|
|
10
|
+
*/
|
|
11
|
+
export interface AuthorizationCodeStoreConfig {
|
|
12
|
+
expirySeconds: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Options for generating an authorization code
|
|
16
|
+
*/
|
|
17
|
+
export interface GenerateCodeOptions {
|
|
18
|
+
clientId: string;
|
|
19
|
+
redirectUri: string;
|
|
20
|
+
scope: string;
|
|
21
|
+
codeChallenge: string;
|
|
22
|
+
codeChallengeMethod: CodeChallengeMethod;
|
|
23
|
+
userId: string;
|
|
24
|
+
resource?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Result of validating an authorization code
|
|
28
|
+
*/
|
|
29
|
+
export interface CodeValidationResult {
|
|
30
|
+
valid: boolean;
|
|
31
|
+
codeData?: AuthorizationCode;
|
|
32
|
+
error?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Authorization Code Store Interface
|
|
36
|
+
*/
|
|
37
|
+
export interface AuthorizationCodeStore {
|
|
38
|
+
generateCode(options: GenerateCodeOptions): Promise<string>;
|
|
39
|
+
validateCode(code: string, clientId: string): Promise<CodeValidationResult>;
|
|
40
|
+
consumeCode(code: string, clientId: string): Promise<CodeValidationResult>;
|
|
41
|
+
revokeCode(code: string): Promise<void>;
|
|
42
|
+
cleanup(): Promise<number>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create an Authorization Code Store instance
|
|
46
|
+
*/
|
|
47
|
+
export declare function createAuthorizationCodeStore(config: AuthorizationCodeStoreConfig): AuthorizationCodeStore;
|
|
48
|
+
//# sourceMappingURL=code-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-store.d.ts","sourceRoot":"","sources":["../../src/oauth/code-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC5E,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3E,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5B;AAkGD;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,4BAA4B,GACnC,sBAAsB,CAExB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Authorization Code Store
|
|
3
|
+
* Requirements: 25.9, 25.10, 26.4
|
|
4
|
+
*
|
|
5
|
+
* Manages authorization code generation, storage, and validation.
|
|
6
|
+
*/
|
|
7
|
+
import { randomBytes } from 'crypto';
|
|
8
|
+
/**
|
|
9
|
+
* In-memory Authorization Code Store Implementation
|
|
10
|
+
*/
|
|
11
|
+
class InMemoryAuthorizationCodeStore {
|
|
12
|
+
codes = new Map();
|
|
13
|
+
config;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
async generateCode(options) {
|
|
18
|
+
// Generate secure random code
|
|
19
|
+
const code = randomBytes(32).toString('base64url');
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const expiresAt = now + this.config.expirySeconds * 1000;
|
|
22
|
+
const codeData = {
|
|
23
|
+
code,
|
|
24
|
+
client_id: options.clientId,
|
|
25
|
+
redirect_uri: options.redirectUri,
|
|
26
|
+
scope: options.scope,
|
|
27
|
+
code_challenge: options.codeChallenge,
|
|
28
|
+
code_challenge_method: options.codeChallengeMethod,
|
|
29
|
+
resource: options.resource,
|
|
30
|
+
user_id: options.userId,
|
|
31
|
+
created_at: now,
|
|
32
|
+
expires_at: expiresAt,
|
|
33
|
+
used: false,
|
|
34
|
+
};
|
|
35
|
+
this.codes.set(code, codeData);
|
|
36
|
+
return code;
|
|
37
|
+
}
|
|
38
|
+
async validateCode(code, clientId) {
|
|
39
|
+
const codeData = this.codes.get(code);
|
|
40
|
+
if (!codeData) {
|
|
41
|
+
return { valid: false, error: 'invalid_grant' };
|
|
42
|
+
}
|
|
43
|
+
// Check if code has been used
|
|
44
|
+
if (codeData.used) {
|
|
45
|
+
return { valid: false, error: 'invalid_grant' };
|
|
46
|
+
}
|
|
47
|
+
// Check if code has expired
|
|
48
|
+
if (Date.now() > codeData.expires_at) {
|
|
49
|
+
this.codes.delete(code);
|
|
50
|
+
return { valid: false, error: 'invalid_grant' };
|
|
51
|
+
}
|
|
52
|
+
// Verify client_id matches
|
|
53
|
+
if (codeData.client_id !== clientId) {
|
|
54
|
+
return { valid: false, error: 'invalid_grant' };
|
|
55
|
+
}
|
|
56
|
+
return { valid: true, codeData };
|
|
57
|
+
}
|
|
58
|
+
async consumeCode(code, clientId) {
|
|
59
|
+
const validationResult = await this.validateCode(code, clientId);
|
|
60
|
+
if (!validationResult.valid) {
|
|
61
|
+
return validationResult;
|
|
62
|
+
}
|
|
63
|
+
// Mark code as used (Requirement 25.10: one-time use)
|
|
64
|
+
const codeData = this.codes.get(code);
|
|
65
|
+
codeData.used = true;
|
|
66
|
+
return validationResult;
|
|
67
|
+
}
|
|
68
|
+
async revokeCode(code) {
|
|
69
|
+
this.codes.delete(code);
|
|
70
|
+
}
|
|
71
|
+
async cleanup() {
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
let cleanedCount = 0;
|
|
74
|
+
for (const [code, data] of this.codes.entries()) {
|
|
75
|
+
if (data.expires_at < now || data.used) {
|
|
76
|
+
this.codes.delete(code);
|
|
77
|
+
cleanedCount++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return cleanedCount;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create an Authorization Code Store instance
|
|
85
|
+
*/
|
|
86
|
+
export function createAuthorizationCodeStore(config) {
|
|
87
|
+
return new InMemoryAuthorizationCodeStore(config);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=code-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-store.js","sourceRoot":"","sources":["../../src/oauth/code-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.1 Module Exports
|
|
3
|
+
* Requirements: 21-31
|
|
4
|
+
*/
|
|
5
|
+
export * from './types.js';
|
|
6
|
+
export { generateCodeVerifier, generateCodeChallenge, verifyCodeChallenge, isValidCodeVerifier, isValidCodeChallenge } from './pkce.js';
|
|
7
|
+
export { createTokenService, generateKeyPair, TokenService } from './token-service.js';
|
|
8
|
+
export { createAuthorizationCodeStore, AuthorizationCodeStore } from './code-store.js';
|
|
9
|
+
export { createRefreshTokenStore, RefreshTokenStore } from './refresh-token-store.js';
|
|
10
|
+
export { createClientStore, ClientStore } from './client-store.js';
|
|
11
|
+
export { OAuthServer, createOAuthServer, OAuthServerConfig } from './oauth-server.js';
|
|
12
|
+
export { OAuthHandler, createOAuthHandler, OAuthHandlerConfig } from './oauth-handler.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGxI,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvF,OAAO,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGvF,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGtF,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.1 Module Exports
|
|
3
|
+
* Requirements: 21-31
|
|
4
|
+
*/
|
|
5
|
+
// Types
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
// PKCE
|
|
8
|
+
export { generateCodeVerifier, generateCodeChallenge, verifyCodeChallenge, isValidCodeVerifier, isValidCodeChallenge } from './pkce.js';
|
|
9
|
+
// Token Service
|
|
10
|
+
export { createTokenService, generateKeyPair } from './token-service.js';
|
|
11
|
+
// Authorization Code Store
|
|
12
|
+
export { createAuthorizationCodeStore } from './code-store.js';
|
|
13
|
+
// Refresh Token Store
|
|
14
|
+
export { createRefreshTokenStore } from './refresh-token-store.js';
|
|
15
|
+
// Client Store
|
|
16
|
+
export { createClientStore } from './client-store.js';
|
|
17
|
+
// OAuth Server
|
|
18
|
+
export { OAuthServer, createOAuthServer } from './oauth-server.js';
|
|
19
|
+
// OAuth Handler
|
|
20
|
+
export { OAuthHandler, createOAuthHandler } from './oauth-handler.js';
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,OAAO;AACP,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAExI,gBAAgB;AAChB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAgB,MAAM,oBAAoB,CAAC;AAEvF,2BAA2B;AAC3B,OAAO,EAAE,4BAA4B,EAA0B,MAAM,iBAAiB,CAAC;AAEvF,sBAAsB;AACtB,OAAO,EAAE,uBAAuB,EAAqB,MAAM,0BAA0B,CAAC;AAEtF,eAAe;AACf,OAAO,EAAE,iBAAiB,EAAe,MAAM,mBAAmB,CAAC;AAEnE,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAqB,MAAM,mBAAmB,CAAC;AAEtF,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAsB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth HTTP Handler
|
|
3
|
+
* Requirements: 22-31 (OAuth 2.1 HTTP Endpoints)
|
|
4
|
+
*
|
|
5
|
+
* Handles OAuth HTTP endpoints including metadata, DCR, authorization, and token endpoints.
|
|
6
|
+
*/
|
|
7
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
8
|
+
import { OAuthServer, OAuthServerConfig } from './oauth-server.js';
|
|
9
|
+
/**
|
|
10
|
+
* OAuth Handler Configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface OAuthHandlerConfig extends OAuthServerConfig {
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* OAuth Handler Class
|
|
16
|
+
*/
|
|
17
|
+
export declare class OAuthHandler {
|
|
18
|
+
private server;
|
|
19
|
+
constructor(server: OAuthServer, _config: OAuthHandlerConfig);
|
|
20
|
+
/**
|
|
21
|
+
* Handle an HTTP request
|
|
22
|
+
*/
|
|
23
|
+
handleRequest(req: IncomingMessage, res: ServerResponse): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Handle Protected Resource Metadata (RFC 9728)
|
|
26
|
+
* Requirement 22.1-22.3
|
|
27
|
+
*/
|
|
28
|
+
private handleProtectedResourceMetadata;
|
|
29
|
+
/**
|
|
30
|
+
* Handle Authorization Server Metadata (RFC 8414)
|
|
31
|
+
* Requirement 23.1-23.9
|
|
32
|
+
*/
|
|
33
|
+
private handleAuthorizationServerMetadata;
|
|
34
|
+
/**
|
|
35
|
+
* Handle Dynamic Client Registration (RFC 7591)
|
|
36
|
+
* Requirement 24.1-24.8
|
|
37
|
+
*/
|
|
38
|
+
private handleClientRegistration;
|
|
39
|
+
/**
|
|
40
|
+
* Handle Authorization Endpoint (GET)
|
|
41
|
+
* Requirement 25.1-25.10
|
|
42
|
+
*/
|
|
43
|
+
private handleAuthorization;
|
|
44
|
+
/**
|
|
45
|
+
* Handle Authorization Submit (POST)
|
|
46
|
+
* Requirement 25.9, 25.10, 28.4, 28.5
|
|
47
|
+
*/
|
|
48
|
+
private handleAuthorizationSubmit;
|
|
49
|
+
/**
|
|
50
|
+
* Handle Login Page (GET)
|
|
51
|
+
* Requirement 29.1
|
|
52
|
+
*/
|
|
53
|
+
private handleLoginPage;
|
|
54
|
+
/**
|
|
55
|
+
* Handle Login Submit (POST)
|
|
56
|
+
* Requirement 29.1-29.5
|
|
57
|
+
*/
|
|
58
|
+
private handleLoginSubmit;
|
|
59
|
+
/**
|
|
60
|
+
* Handle Token Endpoint (POST)
|
|
61
|
+
* Requirement 26.1-26.9
|
|
62
|
+
*/
|
|
63
|
+
private handleToken;
|
|
64
|
+
/**
|
|
65
|
+
* Handle authorization_code grant
|
|
66
|
+
* Requirement 26.2, 26.4, 26.5
|
|
67
|
+
*/
|
|
68
|
+
private handleAuthorizationCodeGrant;
|
|
69
|
+
/**
|
|
70
|
+
* Handle refresh_token grant
|
|
71
|
+
* Requirement 26.3, 26.8
|
|
72
|
+
*/
|
|
73
|
+
private handleRefreshTokenGrant;
|
|
74
|
+
/**
|
|
75
|
+
* Read request body
|
|
76
|
+
*/
|
|
77
|
+
private readBody;
|
|
78
|
+
/**
|
|
79
|
+
* Render login page HTML
|
|
80
|
+
* Requirement 29.1
|
|
81
|
+
*/
|
|
82
|
+
private renderLoginPage;
|
|
83
|
+
/**
|
|
84
|
+
* Render consent page HTML
|
|
85
|
+
* Requirement 28.1-28.4
|
|
86
|
+
*/
|
|
87
|
+
private renderConsentPage;
|
|
88
|
+
/**
|
|
89
|
+
* Render error page HTML
|
|
90
|
+
*/
|
|
91
|
+
private renderErrorPage;
|
|
92
|
+
/**
|
|
93
|
+
* Escape HTML special characters
|
|
94
|
+
*/
|
|
95
|
+
private escapeHtml;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Create an OAuth Handler instance
|
|
99
|
+
*/
|
|
100
|
+
export declare function createOAuthHandler(config: OAuthHandlerConfig): Promise<OAuthHandler>;
|
|
101
|
+
//# sourceMappingURL=oauth-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-handler.d.ts","sourceRoot":"","sources":["../../src/oauth/oauth-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGnE;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;CAE5D;AA0DD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB;IAK5D;;OAEG;IACG,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAwDhF;;;OAGG;IACH,OAAO,CAAC,+BAA+B;IAMvC;;;OAGG;IACH,OAAO,CAAC,iCAAiC;IAMzC;;;OAGG;YACW,wBAAwB;IA6BtC;;;OAGG;YACW,mBAAmB;IAmFjC;;;OAGG;YACW,yBAAyB;IAsDvC;;;OAGG;YACW,eAAe;IAM7B;;;OAGG;YACW,iBAAiB;IAyC/B;;;OAGG;YACW,WAAW;IAmBzB;;;OAGG;YACW,4BAA4B;IA+C1C;;;OAGG;YACW,uBAAuB;IAyCrC;;OAEG;IACH,OAAO,CAAC,QAAQ;IAWhB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAyCvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiDzB;;OAEG;IACH,OAAO,CAAC,eAAe;IA0BvB;;OAEG;IACH,OAAO,CAAC,UAAU;CAQnB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAI1F"}
|