1
0
forked from baron/baron-sso

대시보드 qr 페이지

This commit is contained in:
2026-01-19 15:09:07 +09:00
parent ebfd60f81a
commit 27b8ff2ac1
11 changed files with 338 additions and 21 deletions

View File

@@ -10,6 +10,7 @@ import 'package:qr_flutter/qr_flutter.dart';
import '../../../core/services/audit_service.dart';
import '../../../core/services/web_auth_integration.dart';
import '../../../core/services/auth_proxy_service.dart';
import '../../../core/notifiers/auth_notifier.dart';
class LoginScreen extends ConsumerStatefulWidget {
final String? verificationToken;
@@ -122,7 +123,33 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
if (res['status'] == 'ok' && res['sessionJwt'] != null) {
timer.cancel();
_qrCountdownTimer?.cancel();
_onLoginSuccess(res['sessionJwt']);
final jwt = res['sessionJwt'];
// Create Dummy User & Session for Descope SDK
final dummyUser = DescopeUser(
'unknown', // userId
[], // loginIds
0, // createdAt
'User', // name
null, // picture (Uri?)
'', // email
false, // isVerifiedEmail
'', // phone
false, // isVerifiedPhone
{}, // customAttributes
'', // givenName
'', // middleName
'', // familyName
false, // hasPassword
'enabled', // status
[], // roleNames
[], // ssoAppIds
[], // oauthProviders (List<String>)
);
final session = DescopeSession.fromJwt(jwt, jwt, dummyUser);
Descope.sessionManager.manageSession(session);
_onLoginSuccess(jwt);
}
} catch (e) {
debugPrint("[QR] Polling error: $e");
@@ -148,11 +175,20 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
debugPrint("[Auth] Starting verification for token: $token");
try {
// Use Backend to verify the token (Backend-Driven Flow)
await AuthProxyService.verifyMagicLink(token);
final res = await AuthProxyService.verifyMagicLink(token);
final jwt = res['token'];
debugPrint("[Auth] Verification successful for token: $token");
if (mounted) {
_showSuccessDialog();
if (jwt != null && mounted) {
// Create Dummy User & Session for Descope SDK to log in this tab
final dummyUser = DescopeUser(
'unknown', [], 0, 'User', null, '', false, '', false, {}, '', '', '', false, 'enabled', [], [], [],
);
final session = DescopeSession.fromJwt(jwt, jwt, dummyUser);
Descope.sessionManager.manageSession(session);
// Notify and Go to Dashboard
_onLoginSuccess(jwt);
}
} catch (e) {
debugPrint("[Auth] Verification FAILED for token: $token. Error: $e");
@@ -405,15 +441,25 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
details: "User logged in via Baron SSO",
);
if (WebAuthIntegration.isPopup()) {
WebAuthIntegration.sendLoginSuccess(token);
_showError("Login Successful! You can close this window.");
} else if (_redirectUrl != null && _redirectUrl!.isNotEmpty) {
// 1. Handle Redirect Flow (Redirect to another app)
if (_redirectUrl != null && _redirectUrl!.isNotEmpty) {
final target = "$_redirectUrl?token=$token";
launchUrlString(target, webOnlyWindowName: '_self');
} else {
// Standalone mode: Go to dashboard to act as an auth platform
if (mounted) context.go('/dashboard');
return;
}
// 2. Handle Popup Flow (Send message to opener)
if (WebAuthIntegration.isPopup()) {
WebAuthIntegration.sendLoginSuccess(token);
// If this window was truly a popup for another app, it should close now.
// If it's still here, we allow it to fall through to the dashboard.
}
// 3. Standalone mode: Go to dashboard
// We call notify() to update the router's state, and go() to ensure navigation.
AuthNotifier.instance.notify();
if (mounted) {
context.go('/dashboard');
}
}