migrated timetable integration from WebUntis to the MarianumConnect API, implementing a Dio-based client with bearer token authentication, background session validation, and auto-refresh logic.

This commit is contained in:
2026-05-23 17:32:42 +02:00
parent 2858f910c9
commit 93b9929f8f
106 changed files with 2739 additions and 2624 deletions
@@ -0,0 +1,45 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
/// Persists the Marianum-Connect bearer token in the platform keystore. Kept
/// separate from `AccountData` because the username/password live on (Nextcloud
/// + MHSL still need them) while the MC token is short-lived and per-endpoint.
class MarianumConnectTokenStorage {
static const _tokenKey = 'mc_bearer_token';
static const _tokenIdKey = 'mc_token_id';
static const _expiresAtKey = 'mc_token_expires_at';
final FlutterSecureStorage _storage;
const MarianumConnectTokenStorage([
this._storage = const FlutterSecureStorage(),
]);
Future<String?> readToken() => _storage.read(key: _tokenKey);
Future<String?> readTokenId() => _storage.read(key: _tokenIdKey);
Future<DateTime?> readExpiresAt() async {
final raw = await _storage.read(key: _expiresAtKey);
if (raw == null || raw.isEmpty) return null;
return DateTime.tryParse(raw);
}
Future<void> write({
required String token,
required String tokenId,
required DateTime? expiresAt,
}) async {
await _storage.write(key: _tokenKey, value: token);
await _storage.write(key: _tokenIdKey, value: tokenId);
await _storage.write(
key: _expiresAtKey,
value: expiresAt?.toIso8601String() ?? '',
);
}
Future<void> clear() async {
await _storage.delete(key: _tokenKey);
await _storage.delete(key: _tokenIdKey);
await _storage.delete(key: _expiresAtKey);
}
}