11import type { Request , Response } from "express" ;
22import OAuth2Server from "@node-oauth/oauth2-server" ;
3- import { getConfig } from "../config.ts" ;
43import { logger } from "../logger.ts" ;
54
65/**
@@ -12,7 +11,7 @@ import { logger } from "../logger.ts";
1211export function createAuthorizationServerMetadataHandler ( ) {
1312 return ( req : Request , res : Response ) => {
1413 try {
15- const config = getConfig ( ) ;
14+ // ...existing code...
1615 const baseUrl = `${ req . protocol } ://${ req . get ( "host" ) } ` ;
1716
1817 const metadata = {
@@ -52,7 +51,6 @@ export function createAuthorizationServerMetadataHandler() {
5251export function createProtectedResourceMetadataHandler ( ) {
5352 return ( req : Request , res : Response ) => {
5453 try {
55- const config = getConfig ( ) ;
5654 const baseUrl = `${ req . protocol } ://${ req . get ( "host" ) } ` ;
5755
5856 const metadata = {
@@ -79,196 +77,3 @@ export function createProtectedResourceMetadataHandler() {
7977 }
8078 } ;
8179}
82-
83- /**
84- * OAuth 2.0 Authorization endpoint
85- */
86- export function createAuthorizeHandler ( oauthServer : OAuth2Server ) {
87- return async ( req : Request , res : Response ) => {
88- try {
89- logger . debug ( "Authorization request received" , {
90- query : req . query ,
91- method : req . method ,
92- } ) ;
93-
94- // Real OAuth implementation: Check for authenticated user
95- // In a real implementation, this would:
96- // 1. Check if user has valid session/cookie
97- // 2. If not authenticated, redirect to login page
98- // 3. After login, show consent page
99- // 4. Only then proceed with authorization
100-
101- // For now, this implementation requires external authentication
102- // The user must be authenticated before reaching this endpoint
103- const userId = req . headers [ "x-user-id" ] as string ;
104- const username = req . headers [ "x-username" ] as string ;
105-
106- if ( ! userId || ! username ) {
107- logger . warn ( "Missing user authentication headers" ) ;
108- return res . status ( 401 ) . json ( {
109- error : "access_denied" ,
110- error_description : "User must be authenticated before authorization" ,
111- } ) ;
112- }
113-
114- const user = {
115- id : userId ,
116- username : username ,
117- } ;
118-
119- logger . debug ( "User authenticated, proceeding with authorization" , {
120- userId : user . id ,
121- } ) ;
122-
123- // Use the OAuth2Server authorize method
124- const request = new ( OAuth2Server as any ) . Request ( req ) ;
125- const response = new ( OAuth2Server as any ) . Response ( res ) ;
126-
127- const authorizationCode = await oauthServer . authorize ( request , response , {
128- authenticateHandler : {
129- handle : async ( ) => {
130- logger . debug ( "Authenticate handler called" ) ;
131- return user ;
132- } ,
133- } ,
134- } ) ;
135-
136- logger . info ( "Authorization code granted" , {
137- clientId : authorizationCode . client . id ,
138- userId : user . id ,
139- } ) ;
140-
141- // Redirect back to client with authorization code
142- const redirectUri = req . query . redirect_uri as string ;
143- const state = req . query . state as string ;
144-
145- if ( redirectUri ) {
146- const url = new URL ( redirectUri ) ;
147- url . searchParams . set ( "code" , authorizationCode . authorizationCode ) ;
148- if ( state ) url . searchParams . set ( "state" , state ) ;
149-
150- logger . info ( "Redirecting to client" , { redirectUrl : url . toString ( ) } ) ;
151- res . redirect ( url . toString ( ) ) ;
152- } else {
153- // Fallback - return as JSON
154- res . json ( {
155- authorization_code : authorizationCode . authorizationCode ,
156- state,
157- } ) ;
158- }
159- } catch ( error ) {
160- logger . error ( "Authorization endpoint error" , {
161- error : error instanceof Error ? error . message : error ,
162- stack : error instanceof Error ? error . stack : undefined ,
163- } ) ;
164-
165- res . status ( 400 ) . json ( {
166- error : "server_error" ,
167- error_description :
168- error instanceof Error
169- ? error . message
170- : "Failed to process authorization request" ,
171- } ) ;
172- }
173- } ;
174- }
175-
176- /**
177- * OAuth 2.0 Token endpoint
178- */
179- export function createTokenHandler ( oauthServer : OAuth2Server ) {
180- return async ( req : Request , res : Response ) => {
181- try {
182- const request = new ( OAuth2Server as any ) . Request ( req ) ;
183- const response = new ( OAuth2Server as any ) . Response ( res ) ;
184-
185- const token = await oauthServer . token ( request , response ) ;
186-
187- logger . info ( "Access token granted" , {
188- clientId : token . client . id ,
189- userId : token . user ?. id ,
190- scope : token . scope ,
191- } ) ;
192-
193- res . json ( {
194- access_token : token . accessToken ,
195- token_type : "Bearer" ,
196- expires_in : Math . floor (
197- ( token . accessTokenExpiresAt ! . getTime ( ) - Date . now ( ) ) / 1000 ,
198- ) ,
199- scope : Array . isArray ( token . scope ) ? token . scope . join ( " " ) : token . scope ,
200- refresh_token : token . refreshToken ,
201- } ) ;
202- } catch ( error ) {
203- logger . error ( "Token endpoint error" , {
204- error : error instanceof Error ? error . message : error ,
205- } ) ;
206-
207- res . status ( 400 ) . json ( {
208- error : "invalid_request" ,
209- error_description :
210- error instanceof Error ? error . message : "Token request failed" ,
211- } ) ;
212- }
213- } ;
214- }
215-
216- /**
217- * Token introspection endpoint
218- */
219- export function createIntrospectionHandler ( oauthServer : OAuth2Server ) {
220- return async ( req : Request , res : Response ) => {
221- try {
222- const request = new ( OAuth2Server as any ) . Request ( req ) ;
223- const response = new ( OAuth2Server as any ) . Response ( res ) ;
224-
225- const token = await oauthServer . authenticate ( request , response ) ;
226-
227- logger . info ( "Token introspection successful" , {
228- clientId : token . client . id ,
229- userId : token . user ?. id ,
230- scope : token . scope ,
231- } ) ;
232-
233- res . json ( {
234- active : true ,
235- scope : Array . isArray ( token . scope ) ? token . scope . join ( " " ) : token . scope ,
236- client_id : token . client . id ,
237- username : token . user ?. username ,
238- sub : token . user ?. id ,
239- exp : Math . floor ( ( token . accessTokenExpiresAt ?. getTime ( ) || 0 ) / 1000 ) ,
240- } ) ;
241- } catch ( error ) {
242- logger . debug ( "Token introspection failed" , {
243- error : error instanceof Error ? error . message : error ,
244- } ) ;
245-
246- res . json ( { active : false } ) ;
247- }
248- } ;
249- }
250-
251- /**
252- * Token revocation endpoint
253- */
254- export function createRevocationHandler ( oauthServer : OAuth2Server ) {
255- return async ( req : Request , res : Response ) => {
256- try {
257- const request = new ( OAuth2Server as any ) . Request ( req ) ;
258- const response = new ( OAuth2Server as any ) . Response ( res ) ;
259-
260- await oauthServer . revoke ( request , response ) ;
261-
262- logger . info ( "Token revoked successfully" ) ;
263- res . status ( 200 ) . send ( ) ;
264- } catch ( error ) {
265- logger . error ( "Token revocation error" , {
266- error : error instanceof Error ? error . message : error ,
267- } ) ;
268- res . status ( 400 ) . json ( {
269- error : "invalid_request" ,
270- error_description : "Failed to revoke token" ,
271- } ) ;
272- }
273- } ;
274- }
0 commit comments