From e8cf3239fd5d74b3c1224eccac9a7f2cd4d082f3 Mon Sep 17 00:00:00 2001 From: Wesley Finck Date: Thu, 16 Oct 2025 17:00:25 -0700 Subject: [PATCH] feat: implement cookie-based token storage for app password login Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) --- .../http/controllers/LoginWithAppPasswordController.ts | 10 +++++++++- .../infrastructure/http/factories/ControllerFactory.ts | 1 + .../features/auth/components/loginForm/LoginForm.tsx | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/modules/user/infrastructure/http/controllers/LoginWithAppPasswordController.ts b/src/modules/user/infrastructure/http/controllers/LoginWithAppPasswordController.ts index e449bed0..4e2cfac6 100644 --- a/src/modules/user/infrastructure/http/controllers/LoginWithAppPasswordController.ts +++ b/src/modules/user/infrastructure/http/controllers/LoginWithAppPasswordController.ts @@ -1,10 +1,12 @@ import { Controller } from '../../../../../shared/infrastructure/http/Controller'; import { Request, Response } from 'express'; import { LoginWithAppPasswordUseCase } from '../../../application/use-cases/LoginWithAppPasswordUseCase'; +import { CookieService } from '../../../../../shared/infrastructure/http/services/CookieService'; export class LoginWithAppPasswordController extends Controller { constructor( private loginWithAppPasswordUseCase: LoginWithAppPasswordUseCase, + private cookieService: CookieService, ) { super(); } @@ -26,10 +28,16 @@ export class LoginWithAppPasswordController extends Controller { return this.badRequest(res, result.error.message); } - return this.ok(res, { + // Set tokens in httpOnly cookies + this.cookieService.setTokens(res, { accessToken: result.value.accessToken, refreshToken: result.value.refreshToken, }); + + return this.ok(res, { + success: true, + message: 'Logged in successfully', + }); } catch (error: any) { return this.fail(res, error.message || 'Unknown error'); } diff --git a/src/shared/infrastructure/http/factories/ControllerFactory.ts b/src/shared/infrastructure/http/factories/ControllerFactory.ts index 7d31c7d4..67020e44 100644 --- a/src/shared/infrastructure/http/factories/ControllerFactory.ts +++ b/src/shared/infrastructure/http/factories/ControllerFactory.ts @@ -75,6 +75,7 @@ export class ControllerFactory { // User controllers loginWithAppPasswordController: new LoginWithAppPasswordController( useCases.loginWithAppPasswordUseCase, + cookieService, ), logoutController: new LogoutController( useCases.logoutUseCase, diff --git a/src/webapp/features/auth/components/loginForm/LoginForm.tsx b/src/webapp/features/auth/components/loginForm/LoginForm.tsx index 5a8ec224..40be9ae8 100644 --- a/src/webapp/features/auth/components/loginForm/LoginForm.tsx +++ b/src/webapp/features/auth/components/loginForm/LoginForm.tsx @@ -110,7 +110,7 @@ export default function LoginForm() { appPassword: form.values.appPassword, }); - // Refresh auth state to fetch user profile with new tokens + // Refresh auth state to fetch user profile with new tokens (cookies are set automatically) await refreshAuth(); if (isExtensionLogin) { -- 2.51.2