forked from baron/baron-sso
다른 탭에 로그인 되어 있는 경우 추가 로그인 요청하지 않고 넘어가도록 개선
This commit is contained in:
@@ -3015,11 +3015,15 @@ func (h *AuthHandler) GetAuthTimeline(c *fiber.Ctx) error {
|
|||||||
if subject != "" && h.Hydra != nil {
|
if subject != "" && h.Hydra != nil {
|
||||||
if sessions, err := h.Hydra.ListConsentSessions(c.Context(), subject, ""); err == nil {
|
if sessions, err := h.Hydra.ListConsentSessions(c.Context(), subject, ""); err == nil {
|
||||||
for _, session := range sessions {
|
for _, session := range sessions {
|
||||||
clientID := strings.TrimSpace(session.Client.ClientID)
|
client := session.Client
|
||||||
|
if client.ClientID == "" && session.ConsentRequest != nil {
|
||||||
|
client = session.ConsentRequest.Client
|
||||||
|
}
|
||||||
|
clientID := strings.TrimSpace(client.ClientID)
|
||||||
if clientID == "" {
|
if clientID == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
name := strings.TrimSpace(session.Client.ClientName)
|
name := strings.TrimSpace(client.ClientName)
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = clientID
|
name = clientID
|
||||||
}
|
}
|
||||||
@@ -3028,6 +3032,8 @@ func (h *AuthHandler) GetAuthTimeline(c *fiber.Ctx) error {
|
|||||||
consentAt = *session.AuthenticatedAt
|
consentAt = *session.AuthenticatedAt
|
||||||
} else if session.RequestedAt != nil {
|
} else if session.RequestedAt != nil {
|
||||||
consentAt = *session.RequestedAt
|
consentAt = *session.RequestedAt
|
||||||
|
} else if session.HandledAt != nil {
|
||||||
|
consentAt = *session.HandledAt
|
||||||
}
|
}
|
||||||
if existing, ok := consentMap[clientID]; ok {
|
if existing, ok := consentMap[clientID]; ok {
|
||||||
if !consentAt.IsZero() && (existing.ConsentAt.IsZero() || consentAt.Before(existing.ConsentAt)) {
|
if !consentAt.IsZero() && (existing.ConsentAt.IsZero() || consentAt.Before(existing.ConsentAt)) {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
|||||||
Timer? _verificationRedirectTimer;
|
Timer? _verificationRedirectTimer;
|
||||||
bool _noticeHandled = false;
|
bool _noticeHandled = false;
|
||||||
bool _drySendEnabled = false;
|
bool _drySendEnabled = false;
|
||||||
|
bool _oidcAutoAcceptTried = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -66,7 +67,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
|||||||
_tabController.addListener(_handleTabSelection);
|
_tabController.addListener(_handleTabSelection);
|
||||||
_drySendEnabled = _parseBoolParam(Uri.base.queryParameters['drySend']) && !AuthProxyService.isProdEnv;
|
_drySendEnabled = _parseBoolParam(Uri.base.queryParameters['drySend']) && !AuthProxyService.isProdEnv;
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
final uri = Uri.base;
|
final uri = Uri.base;
|
||||||
_loginChallenge = widget.loginChallenge ?? uri.queryParameters['login_challenge'];
|
_loginChallenge = widget.loginChallenge ?? uri.queryParameters['login_challenge'];
|
||||||
final loginIdParam = uri.queryParameters['loginId'];
|
final loginIdParam = uri.queryParameters['loginId'];
|
||||||
@@ -95,7 +96,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!_verificationOnly) {
|
if (!_verificationOnly) {
|
||||||
_tryCookieSession();
|
await _attemptOidcAutoAccept();
|
||||||
|
if (!mounted) return;
|
||||||
|
await _tryCookieSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uri.queryParameters.containsKey('redirect_url')) {
|
if (uri.queryParameters.containsKey('redirect_url')) {
|
||||||
@@ -105,7 +108,8 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _tryCookieSession({bool silent = true}) async {
|
Future<void> _tryCookieSession({bool silent = true}) async {
|
||||||
if (AuthTokenStore.getToken() != null) {
|
if (AuthTokenStore.getToken() != null &&
|
||||||
|
(_loginChallenge == null || _loginChallenge!.isEmpty)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final pendingProvider = AuthTokenStore.getPendingProvider();
|
final pendingProvider = AuthTokenStore.getPendingProvider();
|
||||||
@@ -117,7 +121,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
|||||||
AuthTokenStore.clearPendingProvider();
|
AuthTokenStore.clearPendingProvider();
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
await ref.read(profileProvider.notifier).loadProfile();
|
await ref.read(profileProvider.notifier).loadProfile();
|
||||||
_onCookieLoginSuccess(provider);
|
await _onCookieLoginSuccess(provider);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
@@ -126,14 +130,65 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCookieLoginSuccess(String provider) {
|
Future<void> _onCookieLoginSuccess(String provider) async {
|
||||||
debugPrint("[Auth] Cookie-based login success. Provider: $provider");
|
debugPrint("[Auth] Cookie-based login success. Provider: $provider");
|
||||||
AuthNotifier.instance.notify();
|
AuthNotifier.instance.notify();
|
||||||
|
if (_loginChallenge != null && _loginChallenge!.isNotEmpty) {
|
||||||
|
final accepted = await _acceptOidcLoginAndRedirect();
|
||||||
|
if (accepted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
context.go('/');
|
context.go('/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _attemptOidcAutoAccept() async {
|
||||||
|
if (_oidcAutoAcceptTried) return;
|
||||||
|
_oidcAutoAcceptTried = true;
|
||||||
|
if (_loginChallenge == null || _loginChallenge!.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final token = AuthTokenStore.getToken();
|
||||||
|
if (token != null && token.isNotEmpty) {
|
||||||
|
final accepted = await _acceptOidcLoginAndRedirect(token: token);
|
||||||
|
if (accepted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await AuthProxyService.checkCookieSession();
|
||||||
|
AuthTokenStore.setCookieMode(provider: AuthTokenStore.getProvider() ?? 'ory');
|
||||||
|
await _acceptOidcLoginAndRedirect();
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("[Auth] OIDC auto-accept cookie check failed: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> _acceptOidcLoginAndRedirect({String? token}) async {
|
||||||
|
if (_loginChallenge == null || _loginChallenge!.isEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final res = await AuthProxyService.acceptOidcLogin(
|
||||||
|
_loginChallenge!,
|
||||||
|
token: token,
|
||||||
|
);
|
||||||
|
final redirectTo = res['redirectTo'] as String?;
|
||||||
|
if (redirectTo != null && redirectTo.isNotEmpty) {
|
||||||
|
debugPrint("[Auth] OIDC login accepted. Redirecting to: $redirectTo");
|
||||||
|
webWindow.redirectTo(redirectTo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("[Auth] OIDC login auto-accept failed: $e");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void _resetLinkLoginState() {
|
void _resetLinkLoginState() {
|
||||||
_linkPendingRef = null;
|
_linkPendingRef = null;
|
||||||
_lastLinkLoginId = null;
|
_lastLinkLoginId = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user