From eb4691839718e4cc63b13a99484f47a0d3bc6dba Mon Sep 17 00:00:00 2001 From: Lectom Date: Thu, 21 May 2026 14:33:40 +0900 Subject: [PATCH] fix userfront verify-only approval routing --- userfront-e2e/tests/auth-routing.spec.ts | 33 +++++++++++++++++++ .../auth/presentation/login_screen.dart | 21 +++++++++--- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/userfront-e2e/tests/auth-routing.spec.ts b/userfront-e2e/tests/auth-routing.spec.ts index a9e6b2e2..abd2f5a8 100644 --- a/userfront-e2e/tests/auth-routing.spec.ts +++ b/userfront-e2e/tests/auth-routing.spec.ts @@ -112,6 +112,19 @@ async function mockUserfrontApis( return; } + if ( + path.endsWith('/api/v1/auth/magic-link/verify') || + path.endsWith('/api/v1/auth/login/code/verify') || + path.endsWith('/api/v1/auth/login/code/verify-short') + ) { + await route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ status: 'approved', pendingRef: 'e2e-approved' }), + }); + return; + } + await route.fulfill({ status: 200, contentType: 'application/json', @@ -179,4 +192,24 @@ test.describe('UserFront WASM auth routing', () => { }); expect(approvedRef).toBe('e2e-approve-ref'); }); + + test('verifyOnly 승인 완료 화면의 상단 액션은 signin으로 이동시키지 않는다', async ({ + page, + }) => { + await mockUserfrontApis(page, { sessionStatus: 401 }); + + await page.goto('/ko/l/AB123456'); + + await expect(page).toHaveURL(/\/ko\/l\/AB123456$/); + await page.waitForTimeout(500); + await expect(page).toHaveURL(/\/ko\/l\/AB123456$/); + + await page.locator('flt-glass-pane').click({ + position: { x: 30, y: 28 }, + force: true, + }); + await page.waitForTimeout(300); + + await expect(page).toHaveURL(/\/ko\/l\/AB123456$/); + }); }); diff --git a/userfront/lib/features/auth/presentation/login_screen.dart b/userfront/lib/features/auth/presentation/login_screen.dart index cd059e14..bcce7d15 100644 --- a/userfront/lib/features/auth/presentation/login_screen.dart +++ b/userfront/lib/features/auth/presentation/login_screen.dart @@ -761,6 +761,10 @@ class _LoginScreenState extends ConsumerState VoidCallback? _onVerificationAction; + void _runVerificationExitAction() { + _onVerificationAction?.call(); + } + Widget _buildVerificationResultView() { return Center( child: Padding( @@ -794,7 +798,11 @@ class _LoginScreenState extends ConsumerState FilledButton( onPressed: () { if (_onVerificationAction != null) { - _onVerificationAction!(); + _runVerificationExitAction(); + return; + } + if (_verificationOnly) { + webWindow.close(); return; } final hasLocalSession = @@ -1604,11 +1612,14 @@ class _LoginScreenState extends ConsumerState if (_verificationOnly && _verificationApproved) { return Scaffold( appBar: AppBar( + automaticallyImplyLeading: false, title: Text(_verificationPageTitle), - leading: IconButton( - icon: const Icon(Icons.arrow_back), - onPressed: () => context.go(buildLocalizedHomePath(Uri.base)), - ), + leading: _onVerificationAction == null + ? null + : IconButton( + icon: const Icon(Icons.close), + onPressed: _runVerificationExitAction, + ), actions: const [ThemeToggleButton(compact: true)], ), body: _buildVerificationResultView(),