import 'package:dio/dio.dart'; import '../../../errors/auth_exception.dart'; import '../../auth/token_storage.dart'; import '../../marianumconnect_api.dart'; import '../../marianumconnect_query.dart'; /// Probes that the stored bearer token still maps to the given credentials. /// Server returns 200 only when the credentials belong to the user that the /// token was issued for — a password rotation on that user's account flips /// it to 401 even if the token itself would still be accepted. /// /// Bypasses the shared dio singleton so the auth interceptor doesn't kick in /// and obscure a real 401 with a silent re-login. class AuthVerify extends MarianumConnectQuery { final MarianumConnectTokenStorage _tokenStorage; AuthVerify({ MarianumConnectTokenStorage tokenStorage = const MarianumConnectTokenStorage(), Dio? dio, }) : _tokenStorage = tokenStorage, super(dio: dio ?? MarianumConnectApi.plainDio()); /// Throws [AuthException] on 401 (credentials no longer match the token's /// user, token missing, or token rejected), other [AppException]s on /// network/server errors. Completes silently on success. Future run({ required String username, required String password, }) async { final options = await _tokenStorage.requireBearerOptions('AuthVerify'); return guard(() async { await dio.post( endpoint('auth/verify'), data: {'username': username, 'password': password}, options: options, ); }); } }