logout working
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user