@@ -78,65 +78,57 @@ export function createProtectedResourceMetadataHandler() {
7878}
7979
8080/**
81- * OAuth 2.1 token endpoint with PKCE support
81+ * OAuth 2.1 token endpoint with PKCE support using oauth2-server
8282 */
83- export function createTokenHandler ( oauthProvider : any ) {
83+ export function createTokenHandler ( oauthServer : any ) {
8484 return async ( req : Request , res : Response ) => {
8585 try {
86- const { grant_type, code, redirect_uri, code_verifier, client_id } = req . body ;
87-
88- if ( grant_type !== "authorization_code" ) {
89- return res . status ( 400 ) . json ( {
90- error : "unsupported_grant_type" ,
91- error_description : "Only authorization_code grant type is supported"
92- } ) ;
93- }
94-
95- if ( ! code || ! redirect_uri || ! code_verifier || ! client_id ) {
96- return res . status ( 400 ) . json ( {
97- error : "invalid_request" ,
98- error_description : "Missing required parameters: code, redirect_uri, code_verifier, client_id"
99- } ) ;
100- }
101- const tokenResult = await oauthProvider . exchangeAuthorizationCode (
102- code ,
103- code_verifier ,
104- client_id ,
105- redirect_uri
106- ) ;
107-
108- if ( ! tokenResult ) {
109- return res . status ( 400 ) . json ( {
110- error : "invalid_grant" ,
111- error_description : "Invalid authorization code or PKCE verification failed"
112- } ) ;
113- }
114-
115- logger . info ( "Token exchange successful" , { client_id, scope : tokenResult . scope } ) ;
86+ const request = new oauthServer . server . Request ( req ) ;
87+ const response = new oauthServer . server . Response ( res ) ;
88+
89+ const token = await oauthServer . server . token ( request , response ) ;
90+
91+ logger . info ( "Token exchange successful" , {
92+ client_id : token . client . id ,
93+ scope : token . scope
94+ } ) ;
11695
11796 res . json ( {
118- access_token : tokenResult . accessToken ,
97+ access_token : token . accessToken ,
11998 token_type : "Bearer" ,
120- expires_in : tokenResult . expiresIn ,
121- scope : tokenResult . scope
99+ expires_in : Math . floor ( ( token . accessTokenExpiresAt . getTime ( ) - Date . now ( ) ) / 1000 ) ,
100+ scope : token . scope
122101 } ) ;
123102
124103 } catch ( error ) {
125104 logger . error ( "Token endpoint error" , {
126105 error : error instanceof Error ? error . message : error
127106 } ) ;
128- res . status ( 500 ) . json ( {
129- error : "server_error" ,
130- error_description : "Failed to process token request"
131- } ) ;
107+
108+ if ( error . name === 'InvalidGrantError' ) {
109+ res . status ( 400 ) . json ( {
110+ error : "invalid_grant" ,
111+ error_description : error . message
112+ } ) ;
113+ } else if ( error . name === 'InvalidRequestError' ) {
114+ res . status ( 400 ) . json ( {
115+ error : "invalid_request" ,
116+ error_description : error . message
117+ } ) ;
118+ } else {
119+ res . status ( 500 ) . json ( {
120+ error : "server_error" ,
121+ error_description : "Failed to process token request"
122+ } ) ;
123+ }
132124 }
133125 } ;
134126}
135127
136128/**
137- * Token introspection endpoint
129+ * Token introspection endpoint using oauth2-server
138130 */
139- export function createIntrospectionHandler ( ) {
131+ export function createIntrospectionHandler ( oauthServer ?: any ) {
140132 return async ( req : Request , res : Response ) => {
141133 try {
142134 const { token } = req . body ;
@@ -148,16 +140,38 @@ export function createIntrospectionHandler() {
148140 } ) ;
149141 }
150142
151- // TODO: Implement actual token introspection
152- // For now, return active=true for any token
153- logger . info ( "Token introspection requested" , { token : token . substring ( 0 , 10 ) + "..." } ) ;
154-
155- res . json ( {
156- active : true ,
157- scope : "read" ,
158- client_id : "mcp-client" ,
159- exp : Math . floor ( Date . now ( ) / 1000 ) + 3600
160- } ) ;
143+ if ( oauthServer ) {
144+ try {
145+ const accessToken = await oauthServer . server . model . getAccessToken ( token ) ;
146+
147+ if ( ! accessToken || accessToken . accessTokenExpiresAt < new Date ( ) ) {
148+ return res . json ( { active : false } ) ;
149+ }
150+
151+ logger . info ( "Token introspection requested" , {
152+ token : token . substring ( 0 , 10 ) + "..." ,
153+ client_id : accessToken . client . id
154+ } ) ;
155+
156+ res . json ( {
157+ active : true ,
158+ scope : accessToken . scope ,
159+ client_id : accessToken . client . id ,
160+ exp : Math . floor ( accessToken . accessTokenExpiresAt . getTime ( ) / 1000 )
161+ } ) ;
162+ } catch ( error ) {
163+ res . json ( { active : false } ) ;
164+ }
165+ } else {
166+ // Fallback for gateway mode
167+ logger . info ( "Token introspection requested" , { token : token . substring ( 0 , 10 ) + "..." } ) ;
168+ res . json ( {
169+ active : true ,
170+ scope : "read" ,
171+ client_id : "mcp-client" ,
172+ exp : Math . floor ( Date . now ( ) / 1000 ) + 3600
173+ } ) ;
174+ }
161175
162176 } catch ( error ) {
163177 logger . error ( "Token introspection error" , {
0 commit comments