replaced account data singleton with a session model
This commit is contained in:
@@ -13,10 +13,11 @@ import '../../../api/marianumconnect/marianumconnect_endpoint.dart';
|
||||
import '../../../api/marianumconnect/queries/telemetry_heartbeat/telemetry_device_id.dart';
|
||||
import '../../../background/widget_background_task.dart';
|
||||
import '../../../extensions/date_time.dart';
|
||||
import '../../../model/account_data.dart';
|
||||
import '../../../model/endpoint_data.dart';
|
||||
import '../../../push/push_registration_store.dart';
|
||||
import '../../../push/push_registration_type.dart';
|
||||
import '../../../session/session.dart';
|
||||
import '../../../session/session_manager.dart';
|
||||
import '../../../state/app/modules/account/bloc/account_bloc.dart';
|
||||
import '../../../state/app/modules/settings/bloc/settings_cubit.dart';
|
||||
import '../../../utils/clipboard_helper.dart';
|
||||
@@ -44,7 +45,8 @@ class _DiagnosticsPageState extends State<DiagnosticsPage> {
|
||||
Future<List<_Section>> _collect() async {
|
||||
final settings = context.read<SettingsCubit>().val();
|
||||
final accountStatus = context.read<AccountBloc>().state.status;
|
||||
final account = AccountData();
|
||||
final session = SessionManager().current;
|
||||
final nextcloud = session?.nextcloud;
|
||||
const tokens = MarianumConnectTokenStorage();
|
||||
final push = PushRegistrationStore();
|
||||
|
||||
@@ -101,13 +103,17 @@ class _DiagnosticsPageState extends State<DiagnosticsPage> {
|
||||
title: 'Sitzung',
|
||||
rows: await rows({
|
||||
'Status': () async => accountStatus.name,
|
||||
'Benutzer': () async =>
|
||||
account.isPopulated() ? account.getUsername() : null,
|
||||
'Demo-Modus': () async => account.isDemo,
|
||||
'Login Flow v2': () async => account.usesLoginFlow,
|
||||
'App-Passwort (Dateien)': () async => account.hasAppPassword(),
|
||||
'App-Passwort (Talk)': () async => account.hasAppPasswordTalk(),
|
||||
'Session-Epoche': () async => account.sessionEpoch,
|
||||
'Benutzer': () async => switch (session) {
|
||||
CredentialSession(:final username) => username,
|
||||
null => null,
|
||||
},
|
||||
'Demo-Modus': () async => session?.isDemo ?? false,
|
||||
'Login Flow v2': () async => nextcloud?.usesLoginFlow ?? false,
|
||||
'App-Passwort (Dateien)': () async =>
|
||||
nextcloud?.hasAppPassword ?? false,
|
||||
'App-Passwort (Talk)': () async =>
|
||||
nextcloud?.hasAppPasswordTalk ?? false,
|
||||
'Session-Epoche': () async => SessionManager().sessionEpoch,
|
||||
'MC-Token-ID': tokens.readTokenId,
|
||||
'MC-Token läuft ab': tokens.readExpiresAt,
|
||||
}),
|
||||
|
||||
@@ -4,10 +4,10 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../../api/marianumcloud/cloud_users/cloud_users_actions.dart';
|
||||
import '../../../../api/marianumconnect/queries/auth_logout/auth_logout.dart';
|
||||
import '../../../../model/account_data.dart';
|
||||
import '../../../../push/push_registration.dart';
|
||||
import '../../../../routing/app_routes.dart';
|
||||
import '../../../../session/session_lifecycle.dart';
|
||||
import '../../../../session/session_manager.dart';
|
||||
import '../../../../state/app/modules/account/bloc/account_bloc.dart';
|
||||
import '../../../../state/app/modules/account/bloc/account_state.dart';
|
||||
import '../../../../widget/app_progress_indicator.dart';
|
||||
@@ -84,13 +84,17 @@ class _AccountSectionState extends State<AccountSection> {
|
||||
setState(() => _avatarBusy = false);
|
||||
if (!ok) return;
|
||||
|
||||
invalidateAvatarCache(id: AccountData().getUsername(), isGroup: false);
|
||||
invalidateAvatarCache(
|
||||
id: SessionManager().requireNextcloud().username,
|
||||
isGroup: false,
|
||||
);
|
||||
setState(() => _avatarVersion++);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final username = AccountData().getUsername();
|
||||
final nextcloud = SessionManager().requireNextcloud();
|
||||
final username = nextcloud.username;
|
||||
final displayName = _displayName;
|
||||
final theme = Theme.of(context);
|
||||
|
||||
@@ -175,7 +179,7 @@ class _AccountSectionState extends State<AccountSection> {
|
||||
// Nur für Login-Flow-Konten (2FA) sichtbar — Passwort-Konten heilen
|
||||
// sich still über das App-Passwort-Minting und sollen von dem ganzen
|
||||
// Flow-Mechanismus nichts mitbekommen.
|
||||
if (!AccountData().isDemo && AccountData().usesLoginFlow)
|
||||
if (!SessionManager().isDemo && nextcloud.usesLoginFlow)
|
||||
AsyncListTile(
|
||||
leading: const Icon(Icons.cloud_sync_outlined),
|
||||
title: const Text('Nextcloud neu verbinden'),
|
||||
@@ -203,7 +207,7 @@ class _AccountSectionState extends State<AccountSection> {
|
||||
|
||||
Future<void> _showLogoutDialog(BuildContext context) async {
|
||||
// Flip AccountBloc state only after the dialog fully closes: doing it from
|
||||
// inside removeData (the previous approach) raced AsyncDialogAction's
|
||||
// inside the sign-out (the previous approach) raced AsyncDialogAction's
|
||||
// pop(true) against the listener's popUntil(isFirst) and could leave the
|
||||
// navigator in an inconsistent state.
|
||||
final confirmed = await showDialog<bool>(
|
||||
@@ -219,14 +223,8 @@ class _AccountSectionState extends State<AccountSection> {
|
||||
context.read<AccountBloc>().setStatus(AccountStatus.loggedOut);
|
||||
}
|
||||
|
||||
// Ordered teardown: unregister push at Nextcloud + proxy and revoke the app
|
||||
// password (while Nextcloud credentials are still available), THEN revoke the
|
||||
// MC bearer token, and finally wipe local credentials. Each step is
|
||||
// best-effort so an offline logout still reaches a clean local state.
|
||||
Future<void> _performLogout() async {
|
||||
await PushRegistration().logoutCleanup();
|
||||
await AuthLogout().run();
|
||||
await AccountData().removeData();
|
||||
await SessionLifecycle.signOut();
|
||||
_cachedDisplayName = null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user