@@ -85,7 +85,7 @@ export default class Login {
8585 5 * 60 * 1000 ,
8686 ) ;
8787
88- this . server ?. on ( 'request' , ( req , res ) => {
88+ this . server ?. on ( 'request' , async ( req , res ) => {
8989 if ( ! req . url ) {
9090 res . writeHead ( 400 ) ;
9191 res . end ( 'Bad request' ) ;
@@ -95,24 +95,38 @@ export default class Login {
9595 const url = new URL ( req . url , `http://127.0.0.1:${ this . port } ` ) ;
9696
9797 if ( url . pathname === '/callback' ) {
98- const key = url . searchParams . get ( 'key' ) ;
99- const secret = url . searchParams . get ( 'secret' ) ;
100- const error = url . searchParams . get ( 'error' ) ;
101-
102- if ( error ) {
103- clearTimeout ( timeout ) ;
104- this . sendErrorResponse ( res , error ) ;
105- reject ( new Error ( error ) ) ;
106- return ;
107- }
98+ try {
99+ // Try to get credentials from query params (GET) or body (POST)
100+ let key = url . searchParams . get ( 'key' ) ;
101+ let secret = url . searchParams . get ( 'secret' ) ;
102+ let error = url . searchParams . get ( 'error' ) ;
103+
104+ // If not in query params and this is a POST request, parse the body
105+ if ( ! key && ! secret && ! error && req . method === 'POST' ) {
106+ const body = await this . parseRequestBody ( req ) ;
107+ key = body . get ( 'key' ) ;
108+ secret = body . get ( 'secret' ) ;
109+ error = body . get ( 'error' ) ;
110+ }
108111
109- if ( key && secret ) {
110- clearTimeout ( timeout ) ;
111- this . sendSuccessResponse ( res ) ;
112- resolve ( { key, secret } ) ;
113- } else {
112+ if ( error ) {
113+ clearTimeout ( timeout ) ;
114+ this . sendErrorResponse ( res , error ) ;
115+ reject ( new Error ( error ) ) ;
116+ return ;
117+ }
118+
119+ if ( key && secret ) {
120+ clearTimeout ( timeout ) ;
121+ this . sendSuccessResponse ( res ) ;
122+ resolve ( { key, secret } ) ;
123+ } else {
124+ res . writeHead ( 400 ) ;
125+ res . end ( 'Missing credentials' ) ;
126+ }
127+ } catch ( err ) {
114128 res . writeHead ( 400 ) ;
115- res . end ( 'Missing credentials ' ) ;
129+ res . end ( 'Failed to parse request ' ) ;
116130 }
117131 } else {
118132 res . writeHead ( 404 ) ;
@@ -122,6 +136,42 @@ export default class Login {
122136 } ) ;
123137 }
124138
139+ private parseRequestBody (
140+ req : http . IncomingMessage ,
141+ ) : Promise < URLSearchParams > {
142+ return new Promise ( ( resolve , reject ) => {
143+ const chunks : Buffer [ ] = [ ] ;
144+
145+ req . on ( 'data' , ( chunk : Buffer ) => {
146+ chunks . push ( chunk ) ;
147+ } ) ;
148+
149+ req . on ( 'end' , ( ) => {
150+ const body = Buffer . concat ( chunks ) . toString ( ) ;
151+ const contentType = req . headers [ 'content-type' ] || '' ;
152+
153+ if ( contentType . includes ( 'application/json' ) ) {
154+ // Parse JSON body
155+ try {
156+ const json = JSON . parse ( body ) ;
157+ const params = new URLSearchParams ( ) ;
158+ if ( json . key ) params . set ( 'key' , json . key ) ;
159+ if ( json . secret ) params . set ( 'secret' , json . secret ) ;
160+ if ( json . error ) params . set ( 'error' , json . error ) ;
161+ resolve ( params ) ;
162+ } catch {
163+ reject ( new Error ( 'Invalid JSON body' ) ) ;
164+ }
165+ } else {
166+ // Parse URL-encoded body (application/x-www-form-urlencoded)
167+ resolve ( new URLSearchParams ( body ) ) ;
168+ }
169+ } ) ;
170+
171+ req . on ( 'error' , reject ) ;
172+ } ) ;
173+ }
174+
125175 private sendSuccessResponse ( res : http . ServerResponse ) : void {
126176 const html = `<!DOCTYPE html>
127177<html>
0 commit comments