logout working

This commit is contained in:
gitea
2026-02-15 18:18:02 +01:00
parent fb96745975
commit c24076a61c
4 changed files with 308 additions and 106 deletions
+74 -3
View File
@@ -12,18 +12,52 @@ class ApiUser {
final String id;
final String? email;
final String? displayName;
final String? avatarUrl;
const ApiUser({required this.id, this.email, this.displayName});
const ApiUser({
required this.id,
this.email,
this.displayName,
this.avatarUrl,
});
ApiUser copyWith({
String? id,
String? email,
String? displayName,
String? avatarUrl,
}) {
return ApiUser(
id: id ?? this.id,
email: email ?? this.email,
displayName: displayName ?? this.displayName,
avatarUrl: avatarUrl ?? this.avatarUrl,
);
}
factory ApiUser.fromJson(Map<String, dynamic> json) {
final metadata = json['user_metadata'] as Map<String, dynamic>?;
final avatar = json['avatar_url'] as String?;
final avatarTrimmed = avatar?.trim();
return ApiUser(
id: json['id'] as String? ?? '',
email: json['email'] as String?,
displayName: json['display_name'] as String? ??
metadata?['display_name'] as String?,
avatarUrl: (avatarTrimmed != null && avatarTrimmed.isNotEmpty)
? avatarTrimmed
: null,
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
if (email != null) 'email': email,
if (displayName != null) 'display_name': displayName,
if (avatarUrl != null) 'avatar_url': avatarUrl,
};
}
}
/// Auth service that uses the backend REST API (login, token storage).
@@ -58,6 +92,9 @@ class ApiAuthService {
final ok = await _fetchSession();
if (!ok) await logout();
}
if (_token != null && currentUser.value != null) {
await _refreshProfile();
}
}
Future<bool> _fetchSession() async {
@@ -81,6 +118,37 @@ class ApiAuthService {
}
}
/// GET /api/auth/profile — fetches profile (display_name, email, avatar_url) and updates currentUser.
Future<void> _refreshProfile() async {
if (_token == null) return;
try {
final uri = Uri.parse('$apiBaseUrl/api/auth/profile');
final res = await http.get(
uri,
headers: {'Authorization': 'Bearer $_token'},
);
if (res.statusCode != 200) return;
final data = jsonDecode(res.body) as Map<String, dynamic>;
final id = data['id'] as String? ?? currentUser.value?.id ?? '';
final displayName = data['display_name'] as String?;
final email = data['email'] as String?;
final avatarUrl = data['avatar_url'] as String?;
final trimmedAvatar = avatarUrl?.trim();
final newUser = (currentUser.value ?? ApiUser(id: id)).copyWith(
displayName: displayName ?? currentUser.value?.displayName,
email: email ?? currentUser.value?.email,
avatarUrl: (trimmedAvatar != null && trimmedAvatar.isNotEmpty)
? trimmedAvatar
: currentUser.value?.avatarUrl,
);
currentUser.value = newUser;
final prefs = await _prefs;
await prefs.setString(_userKey, jsonEncode(newUser.toJson()));
} catch (_) {
// Keep existing user if profile fetch fails
}
}
/// Returns the current Bearer token for API requests, or null if not logged in.
String? get token => _token;
@@ -126,6 +194,7 @@ class ApiAuthService {
final prefs = await _prefs;
await prefs.setString(_tokenKey, _token!);
await prefs.setString(_userKey, jsonEncode(userJson));
await _refreshProfile();
return null;
} catch (e) {
return connectionErrorMessage(e);
@@ -170,17 +239,19 @@ class ApiAuthService {
final prefs = await _prefs;
await prefs.setString(_tokenKey, _token!);
await prefs.setString(_userKey, jsonEncode(userJson));
await _refreshProfile();
return null;
} catch (e) {
return connectionErrorMessage(e);
}
}
/// Clears session (token + user) and persists. Call this to log out.
Future<void> logout() async {
_token = null;
currentUser.value = null;
final prefs = await _prefs;
await prefs.remove(_tokenKey);
await prefs.remove(_userKey);
_token = null;
currentUser.value = null;
}
}