Files
Eventify-frontend/lib/features/auth/services/auth_service.dart
2026-01-31 15:23:18 +05:30

142 lines
5.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// lib/features/auth/services/auth_service.dart
import 'package:flutter/foundation.dart' show kDebugMode, debugPrint;
import 'package:shared_preferences/shared_preferences.dart';
import '../../../core/api/api_client.dart';
import '../../../core/api/api_endpoints.dart';
import '../../../core/storage/token_storage.dart';
import '../models/user_model.dart';
class AuthService {
final ApiClient _api = ApiClient();
/// LOGIN → returns UserModel
Future<UserModel> login(String username, String password) async {
try {
final res = await _api.post(
ApiEndpoints.login,
body: {
"username": username,
"password": password,
},
requiresAuth: false,
);
final token = res['token'];
if (token == null) {
throw Exception('Token missing from response');
}
final serverUsername = (res['username'] is String && (res['username'] as String).isNotEmpty) ? res['username'] as String : null;
final serverEmail = (res['email'] is String && (res['email'] as String).isNotEmpty) ? res['email'] as String : null;
// savedEmail is the canonical identifier for this account
final savedEmail = serverEmail ?? username;
// candidate display name (server username or email fallback)
final displayCandidate = serverUsername ?? savedEmail;
// save token (TokenStorage stays responsible for token)
await TokenStorage.saveToken(token.toString(), savedEmail);
// persist per-account fields in SharedPreferences
final prefs = await SharedPreferences.getInstance();
// mark current logged-in account
await prefs.setString('current_email', savedEmail);
// always keep a canonical 'email' pointing to current user's email for old callers
await prefs.setString('email', savedEmail);
// save per-account display name (do not overwrite an explicit per-account display name if already set)
final perKey = 'display_name_$savedEmail';
final existingPer = prefs.getString(perKey);
if (existingPer == null || existingPer.trim().isEmpty) {
await prefs.setString(perKey, displayCandidate);
}
// save server-provided email (if any) separately too
if (serverEmail != null) await prefs.setString('server_email', serverEmail);
// Save phone if provided (optional)
if (res['phone_number'] != null) await prefs.setString('phone_number', res['phone_number'].toString());
return UserModel.fromJson(res);
} catch (e) {
if (kDebugMode) debugPrint('AuthService.login error: $e');
rethrow;
}
}
/// REGISTER → returns UserModel
Future<UserModel> register({
required String email,
required String phoneNumber,
required String password,
}) async {
try {
final res = await _api.post(
ApiEndpoints.register,
body: {
"email": email,
"phone_number": phoneNumber,
"password": password,
},
requiresAuth: false,
);
final token = res['token'];
if (token == null) {
throw Exception('Token missing from response');
}
final serverUsername = (res['username'] is String && (res['username'] as String).isNotEmpty) ? res['username'] as String : null;
final serverEmail = (res['email'] is String && (res['email'] as String).isNotEmpty) ? res['email'] as String : null;
final savedEmail = serverEmail ?? email;
final savedUsername = serverUsername ?? savedEmail;
final savedRole = (res['role'] ?? 'user').toString();
final savedPhone = (res['phone_number'] ?? phoneNumber)?.toString();
// Save token + canonical user id for token storage
await TokenStorage.saveToken(token.toString(), savedEmail);
// Persist per-account keys
final prefs = await SharedPreferences.getInstance();
await prefs.setString('current_email', savedEmail);
await prefs.setString('email', savedEmail);
// Set display_name_<email> if not present yet
final perKey = 'display_name_$savedEmail';
final existing = prefs.getString(perKey);
if (existing == null || existing.trim().isEmpty) {
await prefs.setString(perKey, savedUsername);
}
// Optionally save phone/email in prefs
await prefs.setString('server_email', savedEmail);
if (savedPhone != null) await prefs.setString('phone_number', savedPhone);
// Return a simple UserModel (defensive)
return UserModel(
username: savedUsername,
email: savedEmail,
role: savedRole,
token: token.toString(),
phoneNumber: savedPhone,
);
} catch (e) {
if (kDebugMode) debugPrint('AuthService.register error: $e');
rethrow;
}
}
/// Logout clear auth token and current_email (keep per-account display_name entries so they persist)
Future<void> logout() async {
try {
final prefs = await SharedPreferences.getInstance();
// clear token storage (should delete token + auth headers)
await TokenStorage.clear();
// remove current_email marker so no previous account remains current
await prefs.remove('current_email');
// Also remove canonical 'email' pointing to current user
await prefs.remove('email');
// Do not delete display_name_<email> entries — they are per-account and should remain on device.
} catch (e) {
if (kDebugMode) debugPrint('AuthService.logout warning: $e');
}
}
}