@@ -137,8 +137,16 @@ async function startServer() {
137137 } ) ;
138138
139139 app . get ( '/login' , function ( req , res ) {
140+ // Store redirect URL for webapp integration (redirect back after OAuth)
141+ if ( req . query . redirect ) {
142+ req . session . authRedirect = req . query . redirect ;
143+ }
144+
140145 if ( req . session . userId ) {
141- res . redirect ( '/dashboard' ) ;
146+ // Already logged in - redirect to stored URL or dashboard
147+ const redirectUrl = req . session . authRedirect || '/dashboard' ;
148+ delete req . session . authRedirect ;
149+ res . redirect ( redirectUrl ) ;
142150 } else {
143151 // TODO use `code`, too (https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps)
144152 const redirectUri = isProduction
@@ -214,14 +222,36 @@ async function startServer() {
214222 } ) ;
215223 }
216224 req . session . userId = user . _id . toString ( ) ;
217- res . redirect ( '/dashboard' ) ;
225+
226+ // Redirect to stored URL (webapp) or default to dashboard
227+ const redirectUrl = req . session . authRedirect || '/dashboard' ;
228+ delete req . session . authRedirect ;
229+ res . redirect ( redirectUrl ) ;
218230 } catch ( e ) {
219231 console . error ( 'GitHub OAuth error:' , e ) ;
220- res . redirect ( '/' ) ;
232+ // On error, redirect to stored error URL or home
233+ const errorRedirect = req . session . authRedirect
234+ ? `${ req . session . authRedirect } ?error=oauth_failed`
235+ : '/' ;
236+ delete req . session . authRedirect ;
237+ res . redirect ( errorRedirect ) ;
221238 }
222239 } ) ;
223240
224- // API Authentication endpoints (for webapp compatibility)
241+ // ============================================================================
242+ // API Authentication Endpoints
243+ // ============================================================================
244+ // Webapp Integration Pattern:
245+ // 1. Webapp redirects browser to /login?redirect=<webapp-callback-url>
246+ // 2. OAuth flow completes, user redirected back to webapp callback
247+ // 3. Webapp calls GET /api/auth/session to get sessionId
248+ // 4. Webapp sets sessionId as httpOnly cookie
249+ // 5. Subsequent requests: proxy converts cookie to SESSION header
250+ //
251+ // Deprecated endpoints (remove after webapp migration complete):
252+ // - POST /api/auth/logout -> use GET /user/logout or GET /api/user/logout
253+ // ============================================================================
254+
225255 app . get ( '/api/auth/status' , async function ( req , res ) {
226256 if ( ! req . session . userId ) {
227257 return res . status ( 401 ) . json ( { authenticated : false } ) ;
@@ -259,6 +289,7 @@ async function startServer() {
259289 }
260290 } ) ;
261291
292+ // @deprecated - Use GET /api/user/logout instead (webapp uses this)
262293 app . post ( '/api/auth/logout' , function ( req , res ) {
263294 req . session . destroy ( err => {
264295 if ( err ) {
@@ -269,6 +300,33 @@ async function startServer() {
269300 } ) ;
270301 } ) ;
271302
303+ // Logout endpoints for webapp compatibility
304+ // Webapp proxy intercepts /user/logout to clear httpOnly cookie
305+ const logoutHandler = function ( req , res ) {
306+ req . session . destroy ( err => {
307+ if ( err ) {
308+ console . error ( 'Session destruction error:' , err ) ;
309+ return res . status ( 500 ) . json ( { error : 'Failed to logout' } ) ;
310+ }
311+ res . json ( { success : true } ) ;
312+ } ) ;
313+ } ;
314+ app . get ( '/user/logout' , logoutHandler ) ;
315+ app . get ( '/api/user/logout' , logoutHandler ) ;
316+
317+ // Session endpoint for webapp - returns sessionId for httpOnly cookie setup
318+ // Used after OAuth callback redirects back to webapp
319+ app . get ( '/api/auth/session' , function ( req , res ) {
320+ if ( ! req . session . userId ) {
321+ return res . status ( 401 ) . json ( { authenticated : false } ) ;
322+ }
323+ // Return the session ID so webapp can set it as httpOnly cookie
324+ res . json ( {
325+ authenticated : true ,
326+ sessionId : req . sessionID ,
327+ } ) ;
328+ } ) ;
329+
272330 app . get ( '/v1/user' , async function ( req , res ) {
273331 if ( ! req . session . userId ) {
274332 return res . status ( 401 ) . end ( ) ;
0 commit comments