1
0
forked from baron/baron-sso

userfront gateway 분리.

This commit is contained in:
Lectom C Han
2026-01-30 16:14:20 +09:00
parent 35552943d7
commit 1db7ce8f10
8 changed files with 302 additions and 99 deletions

View File

@@ -48,6 +48,12 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
bool _verificationOnly = false;
bool _verificationApproved = false;
String _verificationMessage = '';
String _verificationTitle = '승인 완료';
String _verificationPageTitle = '로그인 승인';
String _verificationActionLabel = '확인';
String _verificationActionPath = '/';
Timer? _verificationRedirectTimer;
bool _noticeHandled = false;
bool _drySendEnabled = false;
@override
@@ -69,6 +75,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
final hasVerificationToken = widget.verificationToken != null || hasTokenParam;
final hasLoginCode = loginIdParam != null && codeParam != null;
_verificationOnly = hasVerificationToken || hasLoginCode || hasShortCodePath;
final notice = uri.queryParameters['notice'];
if (hasShortCodePath) {
final shortCode = uri.pathSegments[1];
@@ -80,6 +87,11 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
_verifyToken(widget.verificationToken ?? uri.queryParameters['t']!);
}
if (!_noticeHandled && notice == 'qr_login_required') {
_noticeHandled = true;
_showInfo('로그인 한 상태여야 QR 스캔으로 로그인 할 수 있습니다');
}
if (!_verificationOnly) {
_tryCookieSession();
}
@@ -360,12 +372,31 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
return AuthTokenStore.usesCookie();
}
void _markVerificationApproved(String message) {
void _markVerificationApproved(
String message, {
String title = '승인 완료',
String pageTitle = '로그인 승인',
String actionLabel = '확인',
String actionPath = '/',
bool autoRedirect = false,
Duration redirectDelay = const Duration(seconds: 2),
}) {
if (!mounted) return;
setState(() {
_verificationApproved = true;
_verificationMessage = message;
_verificationTitle = title;
_verificationPageTitle = pageTitle;
_verificationActionLabel = actionLabel;
_verificationActionPath = actionPath;
});
_verificationRedirectTimer?.cancel();
if (autoRedirect) {
_verificationRedirectTimer = Timer(redirectDelay, () {
if (!mounted) return;
context.go(actionPath);
});
}
}
Widget _buildVerificationResultView() {
@@ -377,9 +408,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
children: [
const Icon(Icons.check_circle_outline, color: Colors.green, size: 72),
const SizedBox(height: 16),
const Text(
'승인 완료',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.green),
Text(
_verificationTitle,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.green),
),
const SizedBox(height: 12),
Text(
@@ -389,8 +420,8 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
),
const SizedBox(height: 24),
FilledButton(
onPressed: () => context.go('/'),
child: const Text('확인'),
onPressed: () => context.go(_verificationActionPath),
child: Text(_verificationActionLabel),
),
],
),
@@ -409,11 +440,20 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
final hasLocalSession = _hasLocalSession();
if (jwt is String && jwt.isNotEmpty) {
if (hasLocalSession) {
_markVerificationApproved("승인되었습니다. 이미 로그인된 브라우저입니다.");
if (hasLocalSession) {
_markVerificationApproved(
"승인 되었습니다. 이 기기는 로그인되어 있는 상태입니다. 원격 창도 로그인이 될 예정입니다",
);
return;
}
_completeLoginFromToken(jwt, provider: provider);
_markVerificationApproved(
"링크로 로그인 되었습니다. 잠시 후 로그인 화면으로 이동합니다.",
title: '링크 로그인 완료',
pageTitle: '링크 로그인',
actionLabel: '로그인 화면으로 이동',
actionPath: '/signin',
autoRedirect: true,
);
return;
}
@@ -451,7 +491,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
if (jwt is String && jwt.isNotEmpty) {
if (hasLocalSession) {
_markVerificationApproved("승인되었습니다. 이미 로그인된 브라우저입니다.");
_markVerificationApproved(
"승인 되었습니다. 이 기기는 로그인되어 있는 상태입니다. 원격 창도 로그인이 될 예정입니다",
);
return;
}
_completeLoginFromToken(jwt, provider: res['provider'] as String?);
@@ -489,7 +531,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
if (jwt is String && jwt.isNotEmpty) {
if (hasLocalSession) {
_markVerificationApproved("승인되었습니다. 이미 로그인된 브라우저입니다.");
_markVerificationApproved(
"승인 되었습니다. 이 기기는 로그인되어 있는 상태입니다. 원격 창도 로그인이 될 예정입니다",
);
return;
}
_completeLoginFromToken(jwt, provider: res['provider'] as String?);
@@ -510,6 +554,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
@override
void dispose() {
_stopQrPolling();
_verificationRedirectTimer?.cancel();
_tabController.dispose();
_linkIdController.dispose();
_passwordLoginIdController.dispose();
@@ -851,7 +896,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
if (_verificationOnly && _verificationApproved) {
return Scaffold(
appBar: AppBar(
title: const Text('로그인 승인'),
title: Text(_verificationPageTitle),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => context.go('/'),