1+ import { Request , Response } from "express" ;
2+ import { OAuthClientInformationFull , OAuthClientMetadataSchema , OAuthClientRegistrationError } from "../../../shared/auth.js" ;
3+ import crypto from 'node:crypto' ;
4+ import bodyParser from 'body-parser' ;
5+
6+ async function handler ( requestBody : unknown ) : Promise < OAuthClientInformationFull | OAuthClientRegistrationError > {
7+ let clientMetadata ;
8+ try {
9+ clientMetadata = OAuthClientMetadataSchema . parse ( requestBody ) ;
10+ } catch ( error ) {
11+ return { error : "invalid_client_metadata" , error_description : String ( error ) } ;
12+ }
13+
14+ // Implement RFC 7591 dynamic client registration
15+ const clientId = crypto . randomUUID ( ) ;
16+ const clientSecret = clientMetadata . token_endpoint_auth_method !== 'none'
17+ ? crypto . randomBytes ( 32 ) . toString ( 'hex' )
18+ : undefined ;
19+ const clientIdIssuedAt = Math . floor ( Date . now ( ) / 1000 ) ;
20+
21+ const clientInfo : OAuthClientInformationFull = {
22+ ...clientMetadata ,
23+ client_id : clientId ,
24+ client_secret : clientSecret ,
25+ client_id_issued_at : clientIdIssuedAt ,
26+ client_secret_expires_at : 0 // Set to 0 for non-expiring secret
27+ } ;
28+
29+ // TODO: Store client information securely
30+
31+ return clientInfo ;
32+ }
33+
34+ export const clientRegistrationHandler = ( req : Request , res : Response ) => bodyParser . json ( ) ( req , res , ( err ) => {
35+ if ( err === undefined ) {
36+ handler ( req . body ) . then ( ( result ) => {
37+ if ( "error" in result ) {
38+ res . status ( 400 ) . json ( result ) ;
39+ } else {
40+ res . status ( 201 ) . json ( result ) ;
41+ }
42+ } , ( error ) => {
43+ console . error ( "Uncaught error in client registration handler:" , error ) ;
44+ res . status ( 500 ) . end ( "Internal Server Error" ) ;
45+ } ) ;
46+ }
47+ } ) ;
0 commit comments