Files
Client/lib/api/marianumconnect/auth/session_validator.dart
T

40 lines
1.5 KiB
Dart

import 'dart:developer';
import '../../../model/account_data.dart';
import '../../errors/auth_exception.dart';
import '../queries/auth_logout/auth_logout.dart';
import '../queries/auth_verify/auth_verify.dart';
import 'token_storage.dart';
/// Background credential probe — a server-side password rotation forces a
/// re-login on the next cold start even when the bearer token would still
/// be accepted.
class SessionValidator {
static Future<void> probeStored({
required Future<void> Function() onInvalidated,
}) async {
if (!AccountData().isPopulated()) return;
// AuthVerify uses its own dio (bypassing the demo interceptor), so a demo
// session must be skipped here or its missing token would 401 into a logout.
if (AccountData().isDemo) return;
final username = AccountData().getUsername();
final password = AccountData().getPassword();
final epoch = AccountData().sessionEpoch;
try {
await AuthVerify().run(username: username, password: password);
} on AuthException catch (e) {
if (e.statusCode != 401) return;
// The probed account already signed out; the 401 must not sign out
// whoever logged in meanwhile.
if (!AccountData().isCurrentSession(epoch)) return;
log('MC: stored credentials rejected — forcing re-login');
await AuthLogout().run();
await const MarianumConnectTokenStorage().clear();
await AccountData().removeData();
await onInvalidated();
} catch (e) {
log('MC: background credential check failed (transient): $e');
}
}
}