69 lines
2.5 KiB
Dart
69 lines
2.5 KiB
Dart
import 'dart:developer';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import '../../api/errors/auth_exception.dart';
|
|
import '../../api/errors/error_mapper.dart';
|
|
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 '../../model/account_data.dart';
|
|
import '../../widget_data/widget_sync.dart';
|
|
|
|
/// Owns the login flow's transient state (loading, last error) so it can be
|
|
/// driven from a thin Stateful view and unit-tested without a widget tree.
|
|
class LoginController extends ChangeNotifier {
|
|
bool _loading = false;
|
|
String? _errorMessage;
|
|
String? _errorDetails;
|
|
|
|
bool get loading => _loading;
|
|
String? get errorMessage => _errorMessage;
|
|
String? get errorDetails => _errorDetails;
|
|
|
|
/// Returns `true` when the credential probe succeeded. The view should
|
|
/// then transition the AccountBloc to `loggedIn`.
|
|
Future<bool> submit(String username, String password) async {
|
|
if (_loading) return false;
|
|
_loading = true;
|
|
_errorMessage = null;
|
|
_errorDetails = null;
|
|
notifyListeners();
|
|
|
|
final user = username.trim().toLowerCase();
|
|
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();
|
|
// AuthLogin = Credential-Probe + Token-Create in einem Call.
|
|
// 401 hier heißt: falsches Passwort.
|
|
await AuthLogin().run(
|
|
username: user,
|
|
password: password,
|
|
tokenName: await DeviceTokenName.resolve(),
|
|
);
|
|
await AccountData().setData(user, password);
|
|
_loading = false;
|
|
notifyListeners();
|
|
return true;
|
|
} catch (e) {
|
|
log(e.toString());
|
|
await AccountData().removeData();
|
|
await const MarianumConnectTokenStorage().clear();
|
|
final isWrongCredentials = e is AuthException && e.statusCode == 401;
|
|
_errorMessage = isWrongCredentials
|
|
? 'Benutzername oder Passwort falsch.'
|
|
: errorToUserMessage(e);
|
|
_errorDetails = errorToTechnicalDetails(e);
|
|
_loading = false;
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
}
|
|
}
|