import 'package:dio/dio.dart'; import '../../auth/token_storage.dart'; import '../../errors/marianumconnect_error.dart'; import '../../marianumconnect_endpoint.dart'; import 'auth_login_response.dart'; /// Performs the Marianum-Connect bearer login. Used both by the foreground /// login flow and by the auth interceptor's silent re-auth on 401. Does *not* /// run through the shared dio instance — that one has the interceptor, which /// would attempt to re-auth us into a loop if our credentials are wrong. class AuthLogin { static const Duration _connectTimeout = Duration(seconds: 10); static const Duration _receiveTimeout = Duration(seconds: 15); final MarianumConnectTokenStorage _tokenStorage; final Dio _dio; AuthLogin({ MarianumConnectTokenStorage tokenStorage = const MarianumConnectTokenStorage(), Dio? dio, }) : _tokenStorage = tokenStorage, _dio = dio ?? Dio( BaseOptions( connectTimeout: _connectTimeout, receiveTimeout: _receiveTimeout, sendTimeout: _connectTimeout, responseType: ResponseType.json, contentType: 'application/json', ), ); Future run({ required String username, required String password, required String tokenName, }) async { try { final response = await _dio.post>( MarianumConnectEndpoint.resolve('auth/login'), data: { 'username': username, 'password': password, 'tokenName': tokenName, }, ); final payload = AuthLoginResponse.fromJson(response.data!); await _tokenStorage.write( token: payload.token, tokenId: payload.tokenId, expiresAt: payload.expiresAt, ); return payload; } on DioException catch (e) { throw mapMarianumConnectError(e); } } }