added guardian login with views for their assigned childs

This commit is contained in:
2026-09-20 11:11:58 +02:00
parent e4e2b1a4fb
commit 67c935c05b
117 changed files with 4784 additions and 1514 deletions
+23 -18
View File
@@ -10,7 +10,8 @@ import '../../api/marianumconnect/auth/device_token_name.dart';
import '../../api/marianumconnect/auth/token_storage.dart';
import '../../api/marianumconnect/queries/auth_login/auth_login.dart';
import '../../api/marianumconnect/queries/auth_logout/auth_logout.dart';
import '../../model/account_data.dart';
import '../../session/session.dart';
import '../../session/session_manager.dart';
import '../../widget_data/widget_sync.dart';
/// Outcome of a login attempt.
@@ -51,25 +52,17 @@ class LoginController extends ChangeNotifier {
// Demo login: the prefix enters local demo mode, password ignored, no
// network (see DemoMode).
if (DemoMode.matches(user)) {
await AccountData().removeData();
await const MarianumConnectTokenStorage().clear();
await WidgetSync.clear();
await WidgetSync.triggerUpdate();
await AccountData().setDemo(user);
await _discardPreviousAccount();
await SessionManager().signIn(
CredentialSession(username: user, password: 'demo', isDemo: true),
);
_loading = false;
notifyListeners();
return LoginResult.success;
}
try {
await AccountData().removeData();
// Vorherigen Token revoken bevor wir einen neuen anfordern — ein altes
// Account hätte sonst noch einen aktiven Token in api_tokens.
await const MarianumConnectTokenStorage().clear();
// Widget-Snapshot löschen, sonst blitzt nach Account-Wechsel kurz der
// Stundenplan des vorigen Users auf dem Home-Bildschirm.
await WidgetSync.clear();
await WidgetSync.triggerUpdate();
await _discardPreviousAccount();
// AuthLogin = Credential-Probe + Token-Create in einem Call.
// 401 hier heißt: falsches Passwort.
await AuthLogin().run(
@@ -77,7 +70,9 @@ class LoginController extends ChangeNotifier {
password: password,
tokenName: await DeviceTokenName.resolve(),
);
await AccountData().setData(user, password);
await SessionManager().signIn(
CredentialSession(username: user, password: password),
);
// Mint the Nextcloud app password now — it doubles as the Nextcloud
// credential probe: a rejection means 2FA is active (or the NC password
// diverges) and the login must finish interactively in the browser.
@@ -87,7 +82,7 @@ class LoginController extends ChangeNotifier {
return ncReady ? LoginResult.success : LoginResult.nextcloudLoginRequired;
} catch (e) {
log(e.toString());
await AccountData().removeData();
await SessionManager().signOut();
await const MarianumConnectTokenStorage().clear();
final isWrongCredentials = e is AuthException && e.statusCode == 401;
_errorMessage = isWrongCredentials
@@ -100,6 +95,16 @@ class LoginController extends ChangeNotifier {
}
}
/// Vorherigen Token verwerfen, bevor ein neuer angefordert wird, und den
/// Widget-Snapshot löschen — sonst blitzt nach einem Account-Wechsel kurz
/// der Stundenplan des vorigen Users auf dem Home-Bildschirm. Die Session
/// selbst überschreibt signIn vollständig.
Future<void> _discardPreviousAccount() async {
await const MarianumConnectTokenStorage().clear();
await WidgetSync.clear();
await WidgetSync.triggerUpdate();
}
/// Tries to mint the Nextcloud app password with the just-verified password.
/// `false` = Nextcloud rejected the credentials → Login Flow v2 required.
/// Transport/server problems stay non-blocking (like the previous
@@ -107,7 +112,7 @@ class LoginController extends ChangeNotifier {
Future<bool> _prepareNextcloudAppPassword() async {
try {
final appPassword = await GetAppPassword().run();
await AccountData().setAppPassword(appPassword);
await SessionManager().setAppPassword(appPassword);
return true;
} on AuthException {
return false;
@@ -126,7 +131,7 @@ class LoginController extends ChangeNotifier {
} on Object catch (e) {
log('Login rollback: MC logout failed: $e');
}
await AccountData().removeData();
await SessionManager().signOut();
await const MarianumConnectTokenStorage().clear();
_errorMessage =
'Die Anmeldung wurde abgebrochen — dein Konto erfordert die Bestätigung im Browser.';