feat : auth for new module

This commit is contained in:
MrM
2025-06-03 22:52:21 +03:30
parent ae18a5f648
commit 2b4c019c55
16 changed files with 314 additions and 133 deletions

View File

@@ -5,10 +5,14 @@ class DioErrorHandler {
void handle(DioException error) {
switch (error.response?.statusCode) {
case 401:
_handle401();
_handleGeneric(error);
break;
case 403:
_handle403();
_handleGeneric(error);
break;
case 410:
_handle410();
break;
default:
_handleGeneric(error);
@@ -16,21 +20,22 @@ class DioErrorHandler {
}
//wrong password/user name => "detail": "No active account found with the given credentials" - 401
void _handle401() {
Get.showSnackbar(
_errorSnackBar('نام کاربری یا رمز عبور اشتباه است'),
);
void _handle410() {
Get.showSnackbar(_errorSnackBar('نام کاربری یا رمز عبور اشتباه است'));
}
//wrong captcha => "detail": "Captcha code is incorrect" - 403
void _handle403() {
Get.showSnackbar(
_errorSnackBar('کد امنیتی اشتباه است'),
);
}
void _handle403() {}
void _handleGeneric(DioException error) {
// General error handling
Get.showSnackbar(
_errorSnackBar(
error.response?.data.keys.first == 'is_user'
? 'کاربر با این شماره تلفن وجود ندارد'
: error.response?.data[error.response?.data.keys.first] ??
'خطا در برقراری ارتباط با سرور',
),
);
}
GetSnackBar _errorSnackBar(String message) {

View File

@@ -12,7 +12,7 @@ class DioRemoteManager {
ApiEnvironment env = ApiEnvironment.dam,
]) async {
if (_currentEnv != env) {
_currentClient = DioRemote(env.baseUrl);
_currentClient = DioRemote(baseUrl: env.baseUrl);
await _currentClient?.init();
_currentEnv = env;
}

View File

@@ -1,7 +1,6 @@
import 'package:rasadyar_auth/data/common/constant.dart';
import 'package:rasadyar_auth/data/common/dio_error_handler.dart';
import 'package:rasadyar_auth/data/repositories/auth_repository_imp.dart';
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
import 'package:rasadyar_core/core.dart';
import '../common/dio_manager.dart';
@@ -10,12 +9,16 @@ GetIt diAuth = GetIt.instance;
Future<void> setupAuthDI() async {
diAuth.registerLazySingleton(() => DioRemoteManager());
diAuth.registerLazySingleton<DioRemote>(() => DioRemote());
/* final manager = diAuth.get<DioRemoteManager>();
final dioRemote = await manager.setEnvironment(ApiEnvironment.dam);*/
final manager = diAuth.get<DioRemoteManager>();
final dioRemote = await manager.setEnvironment(ApiEnvironment.dam);
final dioRemote = diAuth.get<DioRemote>();
await dioRemote.init();
diAuth.registerCachedFactory<AuthRepositoryImpl>(
() => AuthRepositoryImpl(dioRemote),
);
diAuth.registerLazySingleton<DioErrorHandler>(() => DioErrorHandler());
}

View File

@@ -19,6 +19,12 @@ class UserLocalModel extends HiveObject {
@HiveField(5)
Module? module;
@HiveField(6)
String? backend;
@HiveField(7)
String? apiKey;
UserLocalModel({
this.username,
this.password,
@@ -26,6 +32,8 @@ class UserLocalModel extends HiveObject {
this.refreshToken,
this.name,
this.module,
this.backend,
this.apiKey,
});
UserLocalModel copyWith({
@@ -35,6 +43,9 @@ class UserLocalModel extends HiveObject {
String? refreshToken,
String? name,
Module? module,
String? backend,
String? apiKey,
}) {
return UserLocalModel(
username: username ?? this.username,
@@ -43,6 +54,8 @@ class UserLocalModel extends HiveObject {
refreshToken: refreshToken ?? this.refreshToken,
name: name ?? this.name,
module: module ?? this.module,
backend: backend ?? this.backend,
apiKey: apiKey ?? this.apiKey,
);
}
}

View File

@@ -23,13 +23,15 @@ class UserLocalModelAdapter extends TypeAdapter<UserLocalModel> {
refreshToken: fields[3] as String?,
name: fields[4] as String?,
module: fields[5] as Module?,
backend: fields[6] as String?,
apiKey: fields[7] as String?,
);
}
@override
void write(BinaryWriter writer, UserLocalModel obj) {
writer
..writeByte(6)
..writeByte(8)
..writeByte(0)
..write(obj.username)
..writeByte(1)
@@ -41,7 +43,11 @@ class UserLocalModelAdapter extends TypeAdapter<UserLocalModel> {
..writeByte(4)
..write(obj.name)
..writeByte(5)
..write(obj.module);
..write(obj.module)
..writeByte(6)
..write(obj.backend)
..writeByte(7)
..write(obj.apiKey);
}
@override

View File

@@ -0,0 +1,18 @@
import 'package:rasadyar_core/core.dart';
part 'user_info_model.freezed.dart';
part 'user_info_model.g.dart';
@freezed
abstract class UserInfoModel with _$UserInfoModel {
const factory UserInfoModel({
bool? isUser,
String? address,
String? backend,
String? apiKey,
}) = _UserInfoModel ;
factory UserInfoModel.fromJson(Map<String, dynamic> json) =>
_$UserInfoModelFromJson(json);
}

View File

@@ -0,0 +1,30 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'user_profile_model.freezed.dart';
part 'user_profile_model.g.dart';
@freezed
abstract class UserProfileModel with _$UserProfileModel {
const factory UserProfileModel({
String? accessToken,
String? expiresIn,
String? scope,
String? expireTime,
String? mobile,
String? fullname,
String? firstname,
String? lastname,
String? city,
String? province,
String? nationalCode,
String? nationalId,
String? birthday,
String? image,
int? baseOrder,
List<String>? role,
}) = _UserProfileModel;
factory UserProfileModel.fromJson(Map<String, dynamic> json) =>
_$UserProfileModelFromJson(json);
}

View File

@@ -1,12 +1,11 @@
import 'package:rasadyar_auth/data/models/response/user_info/user_info_model.dart';
import '../models/response/auth/auth_response_model.dart';
import '../models/response/captcha/captcha_response_model.dart';
import '../models/response/user_profile_model/user_profile_model.dart';
abstract class AuthRepository {
Future<AuthResponseModel?> login({
required Map<String, dynamic> authRequest,
});
Future<UserProfileModel?> login({required Map<String, dynamic> authRequest});
Future<CaptchaResponseModel?> captcha();
@@ -14,10 +13,9 @@ abstract class AuthRepository {
Future<bool> hasAuthenticated();
Future<AuthResponseModel?> loginWithRefreshToken({
required Map<String, dynamic> authRequest,
});
Future<UserInfoModel?> getUserInfo(String phoneNumber);
}

View File

@@ -1,3 +1,5 @@
import 'package:rasadyar_auth/data/models/response/user_info/user_info_model.dart';
import 'package:rasadyar_auth/data/models/response/user_profile_model/user_profile_model.dart';
import 'package:rasadyar_core/core.dart';
import '../models/response/auth/auth_response_model.dart';
@@ -11,13 +13,13 @@ class AuthRepositoryImpl implements AuthRepository {
AuthRepositoryImpl(this._httpClient);
@override
Future<AuthResponseModel?> login({
Future<UserProfileModel?> login({
required Map<String, dynamic> authRequest,
}) async {
var res = await _httpClient.post<AuthResponseModel>(
'$_BASE_URL/login/',
var res = await _httpClient.post<UserProfileModel?>(
'/api/login/',
data: authRequest,
fromJson: AuthResponseModel.fromJson,
fromJson: UserProfileModel.fromJson,
headers: {'Content-Type': 'application/json'},
);
return res.data;
@@ -59,4 +61,19 @@ class AuthRepositoryImpl implements AuthRepository {
return response.data ?? false;
}
@override
Future<UserInfoModel?> getUserInfo(String phoneNumber) async {
var res = await _httpClient.post<UserInfoModel?>(
'https://userbackend.rasadyaar.ir/api/send_otp/',
data: {
"mobile": phoneNumber,
"state": ""
},
fromJson: UserInfoModel.fromJson,
headers: {'Content-Type': 'application/json'},
);
return res.data;
}
}

View File

@@ -8,6 +8,8 @@ class TokenStorageService extends GetxService {
static const String _boxName = 'secureBox';
static const String _accessTokenKey = 'accessToken';
static const String _refreshTokenKey = 'refreshToken';
static const String _baseUrlKey = 'baseUrl';
static const String _apiKey = 'apiKey';
static const String _moduleKey = 'moduleSelected';
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
@@ -15,6 +17,7 @@ class TokenStorageService extends GetxService {
RxnString accessToken = RxnString();
RxnString refreshToken = RxnString();
RxnString baseurl= RxnString();
Rxn<Module> appModule = Rxn(null);
Future<void> init() async {
@@ -34,6 +37,7 @@ class TokenStorageService extends GetxService {
accessToken.value = _localStorage.read<String?>(boxName: _boxName, key: _accessTokenKey);
refreshToken.value = _localStorage.read<String?>(boxName: _boxName, key: _refreshTokenKey);
appModule.value = _localStorage.read<Module?>(boxName: _boxName, key: _moduleKey);
baseurl.value = _localStorage.read<String?>(boxName: _boxName, key: _baseUrlKey);
}
Future<void> saveAccessToken(String token) async {
@@ -59,4 +63,16 @@ class TokenStorageService extends GetxService {
accessToken.value = null;
refreshToken.value = null;
}
Future<void> saveBaseUrl(String url) async {
await _localStorage.save(boxName: _boxName, key: _baseUrlKey, value: url);
baseurl.value = url;
baseurl.refresh();
}
Future<void> saveApiKey(String key) async {
await _localStorage.save(boxName: _boxName, key: _apiKey, value: key);
}
}