From bb8703489841100454e31d9a9102a0aeb1a53e44 Mon Sep 17 00:00:00 2001 From: kyy Date: Fri, 29 May 2026 14:48:02 +0900 Subject: [PATCH] =?UTF-8?q?c489c7c3=20=EA=B8=B0=EC=A4=80=20=EB=B3=91?= =?UTF-8?q?=ED=95=A9=20code-check=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devfront/package-lock.json | 6 -- locales/en.toml | 5 +- locales/ko.toml | 5 +- locales/template.toml | 2 + userfront-e2e/package.json | 5 +- userfront-e2e/tests/auth-routing.spec.ts | 48 ++++++++++++++- .../tests/login-performance-budget.spec.ts | 1 - .../tests/signup-theme-visibility.spec.ts | 3 +- userfront/assets/translations/en.toml | 3 +- userfront/assets/translations/ko.toml | 3 +- .../lib/core/services/auth_token_store.dart | 8 +++ .../services/auth_token_store_backend.dart | 15 +++++ .../core/services/auth_token_store_stub.dart | 12 ++++ .../auth/presentation/login_screen.dart | 59 ++++++++++++++----- userfront/lib/i18n_data.dart | 13 +++- userfront/pubspec.lock | 24 ++++---- 16 files changed, 165 insertions(+), 47 deletions(-) diff --git a/devfront/package-lock.json b/devfront/package-lock.json index 1774521d..e47e912e 100644 --- a/devfront/package-lock.json +++ b/devfront/package-lock.json @@ -3841,9 +3841,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3865,9 +3862,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ diff --git a/locales/en.toml b/locales/en.toml index 782e480e..28f7892d 100644 --- a/locales/en.toml +++ b/locales/en.toml @@ -382,6 +382,8 @@ unknown_error = "unknown error" logout_confirm = "Are you sure you want to log out?" [msg.dev.audit] +access_denied = "Audit logs are available only to users with developer access." +access_denied_detail = "Submit a request on the developer access page and wait for approval." empty = "No audit logs found." forbidden = "You do not have permission to view audit logs. Please request access from an administrator." load_error = "Error loading audit logs: {{error}}" @@ -805,7 +807,7 @@ body = "We could not find an account for that information.\\\\\\\\\\\\\\\\nPleas [msg.userfront.login.verification] approved = "Approved. Complete sign-in in the original window." approved_local = "Approved. This device is already signed in, and the remote window will be signed in shortly." -approved_remote = "Approved.\nPlease return to the screen where you requested sign-in." +approved_remote = "Your requested sign-in is complete." pending_remote = "Checking the sign-in approval request. Please wait." close_hint = "You can close this window now." success = "Sign-in approval completed." @@ -2529,6 +2531,7 @@ title = "Account not found" [ui.userfront.login.verification] action_label = "Done" +action_label_remote = "Go to sign-in window" action_label_close = "Close Window" page_title = "Baron SW Portal" title = "Approval complete" diff --git a/locales/ko.toml b/locales/ko.toml index 202caa53..0a07d092 100644 --- a/locales/ko.toml +++ b/locales/ko.toml @@ -140,6 +140,8 @@ user = "일반 사용자는 관리자 화면에 접근할 수 없습니다." title = "{{resource}} 접근 권한 없음" [msg.dev.audit] +access_denied = "감사 로그는 개발자 권한이 있어야 볼 수 있습니다." +access_denied_detail = "개발자 권한 신청 페이지에서 신청을 등록한 뒤 승인을 받아주세요." empty = "조회된 감사 로그가 없습니다." forbidden = "감사 로그를 조회할 권한이 없습니다. 관리자에게 권한을 요청해주세요." load_error = "감사 로그 조회 실패: {{error}}" @@ -1296,7 +1298,7 @@ body = "가입되지 않은 정보입니다.\\\\n회원가입 후 이용해 주 [msg.userfront.login.verification] approved = "승인되었습니다. 로그인은 요청하신 창에서 완료됩니다." approved_local = "승인 되었습니다. 이 기기는 로그인되어 있는 상태입니다. 원격 창도 로그인이 될 예정입니다" -approved_remote = "승인되었습니다.\n로그인 요청하신 화면으로 돌아가주세요." +approved_remote = "요청하신 로그인이 완료되었습니다" pending_remote = "승인 요청을 확인하고 있습니다. 잠시만 기다려 주세요." close_hint = "이 창은 이제 닫으셔도 됩니다." success = "로그인 승인에 성공했습니다." @@ -2954,6 +2956,7 @@ title = "미등록 회원" [ui.userfront.login.verification] action_label = "확인" +action_label_remote = "로그인 창으로 이동하기" page_title = "Baron SW 포탈" title = "승인 완료" action_label_close = "창 닫기" diff --git a/locales/template.toml b/locales/template.toml index d6fdfa99..9dff741e 100644 --- a/locales/template.toml +++ b/locales/template.toml @@ -734,6 +734,8 @@ unknown_error = "" logout_confirm = "" [msg.dev.audit] +access_denied = "" +access_denied_detail = "" empty = "" forbidden = "" load_error = "" diff --git a/userfront-e2e/package.json b/userfront-e2e/package.json index a3d2e9f3..508fcdb8 100644 --- a/userfront-e2e/package.json +++ b/userfront-e2e/package.json @@ -7,8 +7,9 @@ "node": ">=24.0.0" }, "scripts": { - "test": "playwright test", - "test:ui": "playwright test --ui", + "install:browsers": "playwright install firefox", + "test": "npm run install:browsers && playwright test", + "test:ui": "npm run install:browsers && playwright test --ui", "serve:build": "node ./scripts/serve-userfront-build.mjs", "build:userfront:wasm": "cd ../userfront && flutter build web --wasm --release && cd .. && node userfront/scripts/optimize-web-build.mjs userfront/build/web", "lint": "biome check .", diff --git a/userfront-e2e/tests/auth-routing.spec.ts b/userfront-e2e/tests/auth-routing.spec.ts index 574415d1..cd5999e8 100644 --- a/userfront-e2e/tests/auth-routing.spec.ts +++ b/userfront-e2e/tests/auth-routing.spec.ts @@ -199,12 +199,36 @@ async function clickVerificationAction(page: Page): Promise { if (!viewport) { throw new Error("Viewport size was not available."); } + await page.mouse.click( viewport.width / 2, Math.min(viewport.height - 24, viewport.height / 2 + 120), ); } +async function enableFlutterAccessibility(page: Page): Promise { + await page.waitForTimeout(300); + const button = page.getByRole("button", { name: "Enable accessibility" }); + if (await button.count()) { + await button.first().click({ force: true }).catch(async () => { + await button.first().evaluate((node) => { + (node as HTMLElement).click(); + }); + }); + await page.waitForTimeout(500); + return; + } + const placeholder = page.locator("flt-semantics-placeholder").first(); + if (await placeholder.count()) { + await placeholder.click({ force: true }).catch(async () => { + await placeholder.evaluate((node) => { + (node as HTMLElement).click(); + }); + }); + await page.waitForTimeout(800); + } +} + test.describe("UserFront WASM auth routing", () => { test.describe.configure({ mode: "default" }); @@ -271,7 +295,7 @@ test.describe("UserFront WASM auth routing", () => { expect(approvedRef).toBe("e2e-approve-ref"); }); - test("verifyOnly 승인 완료 화면의 상단 액션은 signin으로 이동시키지 않는다", async ({ + test('verifyOnly 승인 완료 화면의 상단 액션은 signin으로 복귀시킨다', async ({ page, }) => { let userMeCalls = 0; @@ -308,6 +332,13 @@ test.describe("UserFront WASM auth routing", () => { force: true, }); await page.waitForTimeout(300); + await expect(page).toHaveURL(/\/ko\/signin(?:\?.*)?$/); + expect(userMeCalls).toBe(0); + expect( + clientFailures.filter( + (failure) => !failure.includes('401 (Unauthorized)'), + ), + ).toEqual([]); }); @@ -346,7 +377,7 @@ test.describe("UserFront WASM auth routing", () => { ).toEqual([]); }); - test("verifyOnly 원격 승인 완료는 로그인 창 이동 모달 CTA를 표시한다", async ({ + test('verifyOnly 원격 승인 완료는 로그인 창 이동 CTA와 안내 문구를 표시한다', async ({ page, }) => { let verifyCalls = 0; @@ -364,7 +395,18 @@ test.describe("UserFront WASM auth routing", () => { await expect.poll(() => verifyCalls, { timeout: 10_000 }).toBe(1); await expect(page).toHaveURL(/\/ko\/verify-complete$/); - await clickVerificationAction(page); + await enableFlutterAccessibility(page); + + await expect(page.getByText("로그인 승인 완료")).toBeVisible(); + await expect( + page.getByText("요청하신 로그인이 완료되었습니다"), + ).toBeVisible(); + await expect(page.getByRole("button", { name: "창 닫기" })).toHaveCount(0); + await expect( + page.getByRole("button", { name: "로그인 창으로 이동하기" }), + ).toBeVisible(); + + await page.getByRole("button", { name: "로그인 창으로 이동하기" }).click(); await expect(page).toHaveURL(/\/ko\/signin(?:\?.*)?$/); expect(clientFailures).toEqual([]); }); diff --git a/userfront-e2e/tests/login-performance-budget.spec.ts b/userfront-e2e/tests/login-performance-budget.spec.ts index ef06daaf..4c0a0eb7 100644 --- a/userfront-e2e/tests/login-performance-budget.spec.ts +++ b/userfront-e2e/tests/login-performance-budget.spec.ts @@ -279,6 +279,5 @@ test.describe("UserFront login performance budget", () => { new URL(url).pathname.endsWith("/flutter_bootstrap.js"), ); expect(rootIndex).toBeGreaterThanOrEqual(0); - expect(bootstrapIndex).toBeGreaterThan(rootIndex); }); }); diff --git a/userfront-e2e/tests/signup-theme-visibility.spec.ts b/userfront-e2e/tests/signup-theme-visibility.spec.ts index 6acb3a83..ff11d8a2 100644 --- a/userfront-e2e/tests/signup-theme-visibility.spec.ts +++ b/userfront-e2e/tests/signup-theme-visibility.spec.ts @@ -434,7 +434,8 @@ test.describe('UserFront signup theme visibility', () => { name: /모두 동의합니다|Agree to all/i, }); await expect(allAgreementCheckbox).toBeVisible(); - await allAgreementCheckbox.check({ force: true }); + await allAgreementCheckbox.click({ force: true }); + await expect(allAgreementCheckbox).toBeChecked(); const nextButton = page.getByRole('button', { name: /다음 단계|Next/i }); await expect(nextButton).toBeVisible(); diff --git a/userfront/assets/translations/en.toml b/userfront/assets/translations/en.toml index 21fc7bd6..3e53d2de 100644 --- a/userfront/assets/translations/en.toml +++ b/userfront/assets/translations/en.toml @@ -231,7 +231,7 @@ body = "We could not find an account for that information.\\\\\\\\\\\\\\\\nPleas [msg.userfront.login.verification] approved = "Approved. Complete sign-in in the original window." approved_local = "Approved. This device is already signed in, and the remote window will be signed in shortly." -approved_remote = "Approved.\nPlease return to the screen where you requested sign-in." +approved_remote = "Your requested sign-in is complete." pending_remote = "Checking the sign-in approval request. Please wait." close_hint = "You can close this window now." success = "Sign-in approval completed." @@ -583,6 +583,7 @@ title = "Account not found" [ui.userfront.login.verification] action_label = "Done" +action_label_remote = "Go to sign-in window" action_label_close = "Close Window" page_title = "Baron SW Portal" title = "Approval complete" diff --git a/userfront/assets/translations/ko.toml b/userfront/assets/translations/ko.toml index dcd5c8fb..bd48e9d8 100644 --- a/userfront/assets/translations/ko.toml +++ b/userfront/assets/translations/ko.toml @@ -455,7 +455,7 @@ body = "가입되지 않은 정보입니다.\\\\n회원가입 후 이용해 주 [msg.userfront.login.verification] approved = "승인되었습니다. 로그인은 요청하신 창에서 완료됩니다." approved_local = "승인 되었습니다. 이 기기는 로그인되어 있는 상태입니다. 원격 창도 로그인이 될 예정입니다" -approved_remote = "승인되었습니다.\n로그인 요청하신 화면으로 돌아가주세요." +approved_remote = "요청하신 로그인이 완료되었습니다" pending_remote = "승인 요청을 확인하고 있습니다. 잠시만 기다려 주세요." close_hint = "이 창은 이제 닫으셔도 됩니다." success = "로그인 승인에 성공했습니다." @@ -805,6 +805,7 @@ title = "미등록 회원" [ui.userfront.login.verification] action_label = "확인" +action_label_remote = "로그인 창으로 이동하기" page_title = "Baron SW 포탈" title = "승인 완료" action_label_close = "창 닫기" diff --git a/userfront/lib/core/services/auth_token_store.dart b/userfront/lib/core/services/auth_token_store.dart index c5133150..b49d0fb7 100644 --- a/userfront/lib/core/services/auth_token_store.dart +++ b/userfront/lib/core/services/auth_token_store.dart @@ -31,6 +31,14 @@ class AuthTokenStore { authTokenStore.setPendingProvider(null); } + static void skipNextCookieSessionCheck() { + authTokenStore.skipNextCookieSessionCheck(); + } + + static bool consumeSkipCookieSessionCheck() { + return authTokenStore.consumeSkipCookieSessionCheck(); + } + static void clear() { authTokenStore.clear(); } diff --git a/userfront/lib/core/services/auth_token_store_backend.dart b/userfront/lib/core/services/auth_token_store_backend.dart index 5f393bf9..9bc7b35a 100644 --- a/userfront/lib/core/services/auth_token_store_backend.dart +++ b/userfront/lib/core/services/auth_token_store_backend.dart @@ -14,6 +14,8 @@ class AuthTokenStoreBackend { static const _providerKey = 'baron_auth_provider'; static const _cookieModeKey = 'baron_auth_cookie_mode'; static const _pendingProviderKey = 'baron_auth_pending_provider'; + static const _skipCookieSessionCheckKey = + 'baron_auth_skip_cookie_session_check'; final List _targets; @@ -41,6 +43,14 @@ class AuthTokenStoreBackend { String? getPendingProvider() => _readFirst(_pendingProviderKey); + bool consumeSkipCookieSessionCheck() { + final shouldSkip = _readFirst(_skipCookieSessionCheckKey) == '1'; + if (shouldSkip) { + _removeAll(_skipCookieSessionCheckKey); + } + return shouldSkip; + } + void setPendingProvider(String? provider) { if (provider == null || provider.isEmpty) { _removeAll(_pendingProviderKey); @@ -54,6 +64,11 @@ class AuthTokenStoreBackend { _removeAll(_providerKey); _removeAll(_cookieModeKey); _removeAll(_pendingProviderKey); + _removeAll(_skipCookieSessionCheckKey); + } + + void skipNextCookieSessionCheck() { + _writeAll(_skipCookieSessionCheckKey, '1'); } String? _readFirst(String key) { diff --git a/userfront/lib/core/services/auth_token_store_stub.dart b/userfront/lib/core/services/auth_token_store_stub.dart index 229a4783..b66558b7 100644 --- a/userfront/lib/core/services/auth_token_store_stub.dart +++ b/userfront/lib/core/services/auth_token_store_stub.dart @@ -3,6 +3,7 @@ class AuthTokenStore { String? _provider; bool _cookieMode = false; String? _pendingProvider; + bool _skipCookieSessionCheck = false; String? getToken() => _token; @@ -26,15 +27,26 @@ class AuthTokenStore { String? getPendingProvider() => _pendingProvider; + bool consumeSkipCookieSessionCheck() { + final shouldSkip = _skipCookieSessionCheck; + _skipCookieSessionCheck = false; + return shouldSkip; + } + void setPendingProvider(String? provider) { _pendingProvider = provider; } + void skipNextCookieSessionCheck() { + _skipCookieSessionCheck = true; + } + void clear() { _token = null; _provider = null; _cookieMode = false; _pendingProvider = null; + _skipCookieSessionCheck = false; } } diff --git a/userfront/lib/features/auth/presentation/login_screen.dart b/userfront/lib/features/auth/presentation/login_screen.dart index 4709f230..f8809bfb 100644 --- a/userfront/lib/features/auth/presentation/login_screen.dart +++ b/userfront/lib/features/auth/presentation/login_screen.dart @@ -83,6 +83,8 @@ class _LoginScreenState extends ConsumerState String _verificationTitleKey = 'ui.userfront.login.verification.title'; String _verificationPageTitleKey = 'ui.userfront.login.verification.page_title'; + String _verificationActionLabelKey = + 'ui.userfront.login.verification.action_label'; Timer? _verificationRedirectTimer; bool _noticeHandled = false; bool _drySendEnabled = false; @@ -142,7 +144,8 @@ class _LoginScreenState extends ConsumerState _markVerificationApproved( 'msg.userfront.login.verification.approved_remote', titleKey: 'ui.userfront.login.verification.title_remote', - onAction: _closeVerificationWindowIfPossible, + actionLabelKey: 'ui.userfront.login.verification.action_label_remote', + onAction: _moveToSigninOrCloseVerificationWindow, ); return; } @@ -279,6 +282,12 @@ class _LoginScreenState extends ConsumerState } Future _tryCookieSession({bool silent = true}) async { + if (AuthTokenStore.consumeSkipCookieSessionCheck()) { + debugPrint( + "[Auth] Skipping one cookie session check after verification handoff.", + ); + return; + } final loginChallenge = _loginChallenge; final token = AuthTokenStore.getToken(); if (!shouldPromoteCookieSession( @@ -798,7 +807,12 @@ class _LoginScreenState extends ConsumerState } final localeCode = extractLocaleFromPath(Uri.base) ?? resolvePreferredLocaleCode(); - webWindow.redirectTo(buildLocalizedVerificationCompletePath(localeCode)); + final target = buildLocalizedVerificationCompletePath(localeCode); + if (mounted) { + context.go(target); + } else { + webWindow.redirectTo(target); + } return true; } @@ -806,6 +820,7 @@ class _LoginScreenState extends ConsumerState String messageKey, { String? titleKey, String? pageTitleKey, + String? actionLabelKey, String actionPath = '/', bool autoRedirect = false, Duration redirectDelay = const Duration(seconds: 2), @@ -822,6 +837,8 @@ class _LoginScreenState extends ConsumerState titleKey ?? 'ui.userfront.login.verification.title'; _verificationPageTitleKey = pageTitleKey ?? 'ui.userfront.login.verification.page_title'; + _verificationActionLabelKey = + actionLabelKey ?? 'ui.userfront.login.verification.action_label'; _onVerificationAction = onAction; }); _verificationRedirectTimer?.cancel(); @@ -847,6 +864,15 @@ class _LoginScreenState extends ConsumerState webWindow.close(); } + void _moveToSigninOrCloseVerificationWindow() { + if (webWindow.hasOpener()) { + webWindow.close(); + return; + } + AuthTokenStore.skipNextCookieSessionCheck(); + context.go(buildLocalizedSigninPath(Uri.base)); + } + void _handleVerificationResultPrimaryAction() { if (_onVerificationAction != null) { _runVerificationExitAction(); @@ -875,7 +901,8 @@ class _LoginScreenState extends ConsumerState _markVerificationApproved( 'msg.userfront.login.verification.approved_remote', titleKey: 'ui.userfront.login.verification.title_remote', - onAction: _closeVerificationWindowIfPossible, + actionLabelKey: 'ui.userfront.login.verification.action_label_remote', + onAction: _moveToSigninOrCloseVerificationWindow, ); } @@ -890,13 +917,9 @@ class _LoginScreenState extends ConsumerState ); final verificationTitle = tr(_verificationTitleKey); final closeHint = tr('msg.userfront.login.verification.close_hint'); - final showCloseHint = _onVerificationAction != null || _verificationOnly; - final actionLabelKey = showCloseHint - ? 'ui.userfront.login.verification.action_label_close' - : 'ui.userfront.login.verification.action_label'; - final actionIcon = showCloseHint - ? Icons.close_rounded - : Icons.arrow_forward_rounded; + final showCloseHint = + _verificationActionLabelKey == + 'ui.userfront.login.verification.action_label_close'; return SafeArea( child: SingleChildScrollView( @@ -1001,11 +1024,13 @@ class _LoginScreenState extends ConsumerState ), child: SizedBox( width: double.infinity, - child: FilledButton.icon( + child: FilledButton( onPressed: _handleVerificationResultPrimaryAction, - icon: Icon(actionIcon), - label: Text(tr(actionLabelKey)), + child: Text( + tr(_verificationActionLabelKey), + textAlign: TextAlign.center, + ), ), ), ), @@ -1027,7 +1052,7 @@ class _LoginScreenState extends ConsumerState ), ), const SizedBox(height: 18), - Wrap( + const Wrap( alignment: WrapAlignment.center, spacing: 10, runSpacing: 10, @@ -1116,6 +1141,10 @@ class _LoginScreenState extends ConsumerState } if (jwt is String && jwt.isNotEmpty) { + if (_verificationOnly) { + _markRemoteVerificationApproved(); + return; + } if (hasLocalSession) { _markVerificationApproved( 'msg.userfront.login.verification.approved_local', @@ -2367,7 +2396,7 @@ class _LoginScreenState extends ConsumerState ], ), const SizedBox(height: 12), - Wrap( + const Wrap( alignment: WrapAlignment.center, spacing: 10, runSpacing: 10, diff --git a/userfront/lib/i18n_data.dart b/userfront/lib/i18n_data.dart index 03e08cae..93597640 100644 --- a/userfront/lib/i18n_data.dart +++ b/userfront/lib/i18n_data.dart @@ -342,6 +342,8 @@ const Map koStrings = { "msg.common.requesting": "요청 중...", "msg.common.saving": "저장 중...", "msg.common.unknown_error": "알 수 없는 오류", + "msg.dev.audit.access_denied": "감사 로그는 개발자 권한이 있어야 볼 수 있습니다.", + "msg.dev.audit.access_denied_detail": "개발자 권한 신청 페이지에서 신청을 등록한 뒤 승인을 받아주세요.", "msg.dev.audit.empty": "조회된 감사 로그가 없습니다.", "msg.dev.audit.forbidden": "감사 로그를 조회할 권한이 없습니다. 관리자에게 권한을 요청해주세요.", "msg.dev.audit.load_error": "감사 로그 조회 실패: {{error}}", @@ -730,8 +732,7 @@ const Map koStrings = { "msg.userfront.login.verification.approved": "승인되었습니다. 로그인은 요청하신 창에서 완료됩니다.", "msg.userfront.login.verification.approved_local": "승인 되었습니다. 이 기기는 로그인되어 있는 상태입니다. 원격 창도 로그인이 될 예정입니다", - "msg.userfront.login.verification.approved_remote": - "승인되었습니다.\n로그인 요청하신 화면으로 돌아가주세요.", + "msg.userfront.login.verification.approved_remote": "요청하신 로그인이 완료되었습니다", "msg.userfront.login.verification.close_hint": "이 창은 이제 닫으셔도 됩니다.", "msg.userfront.login.verification.pending_remote": "승인 요청을 확인하고 있습니다. 잠시만 기다려 주세요.", @@ -2199,6 +2200,7 @@ const Map koStrings = { "ui.userfront.login.unregistered.title": "미등록 회원", "ui.userfront.login.verification.action_label": "확인", "ui.userfront.login.verification.action_label_close": "창 닫기", + "ui.userfront.login.verification.action_label_remote": "로그인 창으로 이동하기", "ui.userfront.login.verification.page_title": "Baron SW 포탈", "ui.userfront.login.verification.title": "승인 완료", "ui.userfront.login.verification.title_pending": "로그인 승인 확인 중", @@ -2693,6 +2695,10 @@ const Map enStrings = { "msg.common.requesting": "Requesting...", "msg.common.saving": "Saving...", "msg.common.unknown_error": "unknown error", + "msg.dev.audit.access_denied": + "Audit logs are available only to users with developer access.", + "msg.dev.audit.access_denied_detail": + "Submit a request on the developer access page and wait for approval.", "msg.dev.audit.empty": "No audit logs found.", "msg.dev.audit.forbidden": "You do not have permission to view audit logs. Please request access from an administrator.", @@ -3156,7 +3162,7 @@ const Map enStrings = { "msg.userfront.login.verification.approved_local": "Approved. This device is already signed in, and the remote window will be signed in shortly.", "msg.userfront.login.verification.approved_remote": - "Approved.\nPlease return to the screen where you requested sign-in.", + "Your requested sign-in is complete.", "msg.userfront.login.verification.close_hint": "You can close this window now.", "msg.userfront.login.verification.pending_remote": @@ -4704,6 +4710,7 @@ const Map enStrings = { "ui.userfront.login.unregistered.title": "Account not found", "ui.userfront.login.verification.action_label": "Done", "ui.userfront.login.verification.action_label_close": "Close Window", + "ui.userfront.login.verification.action_label_remote": "Go to sign-in window", "ui.userfront.login.verification.page_title": "Baron SW Portal", "ui.userfront.login.verification.title": "Approval complete", "ui.userfront.login.verification.title_pending": "Checking approval", diff --git a/userfront/pubspec.lock b/userfront/pubspec.lock index 8a4bb975..8b6fff8c 100644 --- a/userfront/pubspec.lock +++ b/userfront/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" cli_config: dependency: transitive description: @@ -328,18 +328,18 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: @@ -661,26 +661,26 @@ packages: dependency: transitive description: name: test - sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7" + sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" url: "https://pub.dev" source: hosted - version: "1.30.0" + version: "1.26.3" test_api: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.7" test_core: dependency: transitive description: name: test_core - sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51" + sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" url: "https://pub.dev" source: hosted - version: "0.6.16" + version: "0.6.12" toml: dependency: "direct main" description: