import 'package:flutter/foundation.dart'; import '../../../core/network/interceptors/auth_interceptor.dart'; import '../../../core/services/token_storage.dart'; import '../domain/entities/auth_session.dart'; import '../domain/entities/authenticated_user.dart'; import '../domain/entities/login_request.dart'; import '../domain/repositories/auth_repository.dart'; /// 인증 세션을 관리하고 토큰을 보관하는 서비스. class AuthService extends ChangeNotifier { AuthService({ required AuthRepository repository, required TokenStorage tokenStorage, }) : _repository = repository, _tokenStorage = tokenStorage; final AuthRepository _repository; final TokenStorage _tokenStorage; AuthSession? _session; bool _rememberMe = false; /// 현재 로그인된 세션 (없으면 null) AuthSession? get session => _session; /// 사용자가 마지막으로 선택한 자동 로그인 여부 bool get rememberMe => _rememberMe; /// 로그인 후 세션을 저장하고 토큰을 보관한다. Future login(LoginRequest request) async { final session = await _repository.login(request); _rememberMe = request.rememberMe; await _persistSession(session); return session; } /// 저장된 리프레시 토큰으로 세션을 갱신한다. Future refreshSession() async { final refreshToken = await _tokenStorage.readRefreshToken(); if (refreshToken == null || refreshToken.isEmpty) { return null; } final session = await _repository.refresh(refreshToken); await _persistSession(session); return session; } /// 앱 내에서 명시적으로 로그아웃할 때 호출한다. Future clearSession() async { _session = null; _rememberMe = false; await _tokenStorage.clear(); notifyListeners(); } /// 인터셉터에서 사용할 토큰 쌍을 반환한다. Future refreshForInterceptor() async { try { final session = await refreshSession(); if (session == null) { return null; } return TokenPair( accessToken: session.accessToken, refreshToken: session.refreshToken, ); } catch (_) { return null; } } /// 현재 세션의 사용자 정보를 갱신한다. void updateSessionUser(AuthenticatedUser user) { final current = _session; if (current == null) { return; } _session = AuthSession( accessToken: current.accessToken, refreshToken: current.refreshToken, expiresAt: current.expiresAt, user: user, permissions: current.permissions, ); notifyListeners(); } Future _persistSession(AuthSession session) async { _session = session; await _tokenStorage.writeAccessToken(session.accessToken); if (session.hasRefreshToken) { await _tokenStorage.writeRefreshToken(session.refreshToken); } else { await _tokenStorage.writeRefreshToken(null); } notifyListeners(); } }