Deploy: 2026-05-24 23:27:32
This commit is contained in:
66
mobile/lib/features/auth/data/auth_repository.dart
Normal file
66
mobile/lib/features/auth/data/auth_repository.dart
Normal file
@@ -0,0 +1,66 @@
|
||||
import 'dart:convert';
|
||||
import '../../../core/services/api_service.dart';
|
||||
import '../../../core/services/secure_storage_service.dart';
|
||||
import 'models/user_model.dart';
|
||||
|
||||
class AuthRepository {
|
||||
final ApiService _apiService = ApiService();
|
||||
final SecureStorageService _secureStorage = SecureStorageService();
|
||||
|
||||
// English: Perform login by email/password, verify response status, and save JWT token.
|
||||
// Arabic: إجراء تسجيل الدخول عن طريق البريد الإلكتروني وكلمة المرور، والتحقق من حالة الاستجابة، وحفظ رمز التحقق.
|
||||
Future<UserModel> login(String email, String password) async {
|
||||
final response = await _apiService.login(email, password);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final token = data['token'] as String;
|
||||
final userJson = data['user'] as Map<String, dynamic>;
|
||||
|
||||
// English: Store JWT token securely using secure storage.
|
||||
// Arabic: تخزين رمز التحقق بشكل آمن باستخدام التخزين الآمن.
|
||||
await _secureStorage.writeToken(token);
|
||||
|
||||
return UserModel.fromJson(userJson);
|
||||
} else {
|
||||
// English: Handle server error messages securely.
|
||||
// Arabic: معالجة رسائل خطأ الخادم بشكل آمن.
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final errorMessage = data['error'] as String? ?? 'Failed to authenticate';
|
||||
throw Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
// English: Check if a valid JWT token exists and fetch the authenticated user data.
|
||||
// Arabic: التحقق من وجود رمز تحقق صالح وجلب بيانات المستخدم المصادق عليه.
|
||||
Future<UserModel?> getCachedUser() async {
|
||||
final token = await _secureStorage.readToken();
|
||||
if (token == null || token.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final response = await _apiService.getMe(token);
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final userJson = data['user'] as Map<String, dynamic>;
|
||||
return UserModel.fromJson(userJson);
|
||||
} else {
|
||||
// English: Token is likely invalid or expired, clear it.
|
||||
// Arabic: من المحتمل أن يكون الرمز غير صالح أو منتهي الصلاحية، قم بمسحه.
|
||||
await _secureStorage.deleteToken();
|
||||
return null;
|
||||
}
|
||||
} catch (_) {
|
||||
// English: Return null if offline or server is unreachable.
|
||||
// Arabic: إرجاع قيمة فارغة إذا كان الجهاز غير متصل أو تعذر الوصول إلى الخادم.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// English: Clear stored JWT credentials.
|
||||
// Arabic: مسح بيانات اعتماد رمز التحقق المخزنة.
|
||||
Future<void> logout() async {
|
||||
await _secureStorage.deleteToken();
|
||||
}
|
||||
}
|
||||
77
mobile/lib/features/auth/data/models/user_model.dart
Normal file
77
mobile/lib/features/auth/data/models/user_model.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class UserModel extends Equatable {
|
||||
// English: Unique identifier for the user.
|
||||
// Arabic: المعرف الفريد للمستخدم.
|
||||
final int id;
|
||||
|
||||
// English: The ID of the company this user belongs to.
|
||||
// Arabic: معرف الشركة التي ينتمي إليها هذا المستخدم.
|
||||
final int companyId;
|
||||
|
||||
// English: The name of the user.
|
||||
// Arabic: اسم المستخدم.
|
||||
final String name;
|
||||
|
||||
// English: The email address of the user.
|
||||
// Arabic: البريد الإلكتروني للمستخدم.
|
||||
final String email;
|
||||
|
||||
// English: The system role assigned to the user (e.g. admin, staff).
|
||||
// Arabic: دور النظام المعين للمستخدم (مثل مشرف، موظف).
|
||||
final String role;
|
||||
|
||||
// English: Indicator if the user is a super admin (company ID 1).
|
||||
// Arabic: مؤشر ما إذا كان المستخدم مشرفاً عاماً (معرف الشركة 1).
|
||||
final bool isSuperAdmin;
|
||||
|
||||
const UserModel({
|
||||
required this.id,
|
||||
required this.companyId,
|
||||
required this.name,
|
||||
required this.email,
|
||||
required this.role,
|
||||
required this.isSuperAdmin,
|
||||
});
|
||||
|
||||
// English: Factory constructor to create a UserModel instance from JSON mapping.
|
||||
// Arabic: منشئ المصنع لإنشاء نسخة نموذج المستخدم من خريطة جيسون.
|
||||
factory UserModel.fromJson(Map<String, dynamic> json) {
|
||||
// English: Safely parse isSuperAdmin from dynamic input (boolean or integer).
|
||||
// Arabic: تحليل آمن لمؤشر المشرف العام من المدخلات الديناميكية (بولين أو عدد صحيح).
|
||||
final rawSuperAdmin = json['is_super_admin'];
|
||||
bool isSuper = false;
|
||||
if (rawSuperAdmin is bool) {
|
||||
isSuper = rawSuperAdmin;
|
||||
} else if (rawSuperAdmin is int) {
|
||||
isSuper = rawSuperAdmin == 1;
|
||||
} else if (rawSuperAdmin is String) {
|
||||
isSuper = rawSuperAdmin == '1' || rawSuperAdmin.toLowerCase() == 'true';
|
||||
}
|
||||
|
||||
return UserModel(
|
||||
id: json['id'] as int? ?? 0,
|
||||
companyId: json['company_id'] as int? ?? 0,
|
||||
name: json['name'] as String? ?? '',
|
||||
email: json['email'] as String? ?? '',
|
||||
role: json['role'] as String? ?? '',
|
||||
isSuperAdmin: isSuper,
|
||||
);
|
||||
}
|
||||
|
||||
// English: Convert UserModel instance to JSON map for local caching.
|
||||
// Arabic: تحويل نسخة نموذج المستخدم إلى خريطة جيسون للتخزين المؤقت المحلي.
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'company_id': companyId,
|
||||
'name': name,
|
||||
'email': email,
|
||||
'role': role,
|
||||
'is_super_admin': isSuperAdmin,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id, companyId, name, email, role, isSuperAdmin];
|
||||
}
|
||||
Reference in New Issue
Block a user