fix : login api call

This commit is contained in:
2025-05-17 17:07:44 +03:30
parent 303ff86d85
commit 6843973c4f
12 changed files with 180 additions and 130 deletions

View File

@@ -1,6 +0,0 @@
class UserEntity {
String? token;
String? refreshToken;
UserEntity({this.token, this.refreshToken});
}

View File

@@ -6,7 +6,7 @@ final di = GetIt.instance;
Future<void> setupInjection() async{ Future<void> setupInjection() async{
await setupAuthDI(); await setupAuthDI();
await setupAllProvider(); await setupAllCoreProvider();
} }

View File

@@ -0,0 +1,34 @@
import 'package:rasadyar_auth/auth.dart';
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
import 'package:rasadyar_core/core.dart';
class AuthService extends GetxService {
var tokenService = diAuth.get<TokenStorageService>();
RxBool accessRes = false.obs;
RxBool refAccessRes = false.obs;
@override
void onInit() {
super.onInit();
ever(tokenService.accessToken, (callback) {
iLog('Access token callback: $callback, value: ${tokenService.accessToken.value}');
accessRes.value = (callback != null);
});
// رصد تغییرات refreshToken
ever(tokenService.refreshToken, (callback) {
fLog('Refresh token callback: $callback, value: ${tokenService.refreshToken.value}');
refAccessRes.value = (callback != null);
});
// بررسی اینکه هر دو مقدار دارند
everAll([accessRes, refAccessRes], (_) {
if (accessRes.value && refAccessRes.value) {
fLog('Both accessToken and refreshToken are available: accessToken=${tokenService.accessToken.value}, refreshToken=${tokenService.refreshToken.value}');
} else {
fLog('One or both tokens are missing: accessToken=${tokenService.accessToken.value}, refreshToken=${tokenService.refreshToken.value}');
}
});
}
}

View File

@@ -1,12 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rasadyar_app/presentation/routes/app_pages.dart'; import 'package:rasadyar_app/presentation/routes/app_pages.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
import 'infrastructure/di/di.dart'; import 'infrastructure/di/di.dart';
import 'infrastructure/service/auth_service.dart';
Future<void> main() async { Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await setupInjection(); await setupInjection();
Get.put(AuthService());
runApp(MyApp()); runApp(MyApp());
// runApp(DevicePreview(builder: (context) => ForDevicePreview(),)); // runApp(DevicePreview(builder: (context) => ForDevicePreview(),));

View File

@@ -4,5 +4,4 @@
library; library;
export 'data/services/auth_middelware.dart'; export 'data/services/auth_middelware.dart';
export 'data/services/auth_service.dart';
export 'data/di/auth_di.dart'; export 'data/di/auth_di.dart';

View File

@@ -1,7 +1,6 @@
import 'package:rasadyar_auth/data/common/constant.dart'; import 'package:rasadyar_auth/data/common/constant.dart';
import 'package:rasadyar_auth/data/common/dio_error_handler.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/repositories/auth_repository_imp.dart';
import 'package:rasadyar_auth/data/services/auth_service.dart';
import 'package:rasadyar_auth/data/services/token_storage_service.dart'; import 'package:rasadyar_auth/data/services/token_storage_service.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
@@ -17,7 +16,6 @@ Future<void> setupAuthDI() async {
diAuth.registerCachedFactory<AuthRepositoryImpl>( diAuth.registerCachedFactory<AuthRepositoryImpl>(
() => AuthRepositoryImpl(dioRemote), () => AuthRepositoryImpl(dioRemote),
); );
diAuth.registerLazySingleton<AuthService>(() => AuthService());
diAuth.registerLazySingleton<TokenStorageService>(() => TokenStorageService()); diAuth.registerLazySingleton<TokenStorageService>(() => TokenStorageService());
diAuth.registerLazySingleton<DioErrorHandler>(() => DioErrorHandler()); diAuth.registerLazySingleton<DioErrorHandler>(() => DioErrorHandler());
} }

View File

@@ -10,9 +10,8 @@ class AuthMiddleware extends GetMiddleware {
@override @override
RouteSettings? redirect(String? route) { RouteSettings? redirect(String? route) {
eLog('redirect'); final refreshToken = tokenService.refreshToken.value;
final refreshToken = tokenService.getRefreshToken(); final accessToken = tokenService.accessToken.value;
final accessToken = tokenService.getAccessToken();
if (refreshToken == null || accessToken == null) { if (refreshToken == null || accessToken == null) {
return RouteSettings(name: AuthPaths.moduleList); return RouteSettings(name: AuthPaths.moduleList);

View File

@@ -1,9 +0,0 @@
import 'package:rasadyar_core/core.dart';
class AuthService extends GetxService{
Future<void> initService() async {
}
}

View File

@@ -2,14 +2,18 @@ import 'dart:convert';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
class TokenStorageService extends GetxService { class TokenStorageService extends GetxService {
static const String _boxName = 'secureBox'; static const String _boxName = 'secureBox';
static const String _accessTokenKey = 'accessToken'; static const String _accessTokenKey = 'accessToken';
static const String _refreshTokenKey = 'refreshToken'; static const String _refreshTokenKey = 'refreshToken';
final FlutterSecureStorage _secureStorage = FlutterSecureStorage(); final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
final HiveLocalStorage _localStorage = diCore.get<HiveLocalStorage>(); final HiveLocalStorage _localStorage = diCore.get<HiveLocalStorage>();
RxnString accessToken = RxnString();
RxnString refreshToken = RxnString();
RxnString tsss = RxnString();
Future<void> init() async { Future<void> init() async {
final String? encryptedKey = await _secureStorage.read(key: 'hive_enc_key'); final String? encryptedKey = await _secureStorage.read(key: 'hive_enc_key');
final encryptionKey = final encryptionKey =
@@ -29,26 +33,40 @@ class TokenStorageService extends GetxService {
_boxName, _boxName,
encryptionCipher: HiveAesCipher(encryptionKey), encryptionCipher: HiveAesCipher(encryptionKey),
); );
accessToken.value = _localStorage.read<String?>(
boxName: _boxName,
key: _accessTokenKey,
);
refreshToken.value = _localStorage.read<String?>(
boxName: _boxName,
key: _refreshTokenKey,
);
} }
Future<void> saveAccessToken(String token) async => await _localStorage.save( Future<void> saveAccessToken(String token) async {
boxName: _boxName, await _localStorage.save(
key: _accessTokenKey, boxName: _boxName,
value: token, key: _accessTokenKey,
); value: token,
);
Future<void> saveRefreshToken(String token) async => await _localStorage.save( accessToken.value = token;
boxName: _boxName, accessToken.refresh();
key: _refreshTokenKey, }
value: token,
);
String? getAccessToken() =>
_localStorage.read<String?>(boxName: _boxName, key: _accessTokenKey);
String? getRefreshToken() =>
_localStorage.read<String?>(boxName: _boxName, key: _refreshTokenKey);
Future<void> deleteTokens() async => await _localStorage.clear(_boxName);
Future<void> saveRefreshToken(String token) async {
await _localStorage.save(
boxName: _boxName,
key: _refreshTokenKey,
value: token,
);
refreshToken.value = token;
refreshToken.refresh();
}
Future<void> deleteTokens() async {
await _localStorage.clear(_boxName);
accessToken.value = null;
refreshToken.value = null;
}
} }

View File

@@ -38,6 +38,7 @@ class AuthLogic extends GetxController {
Rx<OtpStatus> otpStatus = OtpStatus.init.obs; Rx<OtpStatus> otpStatus = OtpStatus.init.obs;
RxInt secondsRemaining = 120.obs; RxInt secondsRemaining = 120.obs;
int wsd = 120;
Timer? _timer; Timer? _timer;
AuthRepositoryImpl authRepository = diAuth.get<AuthRepositoryImpl>(); AuthRepositoryImpl authRepository = diAuth.get<AuthRepositoryImpl>();
@@ -111,7 +112,7 @@ class AuthLogic extends GetxController {
isLoading.value = true; isLoading.value = true;
await safeCall<AuthResponseModel?>( await safeCall<AuthResponseModel?>(
call: () => authRepository.login(authRequest: loginRequestModel.toJson()), call: () => authRepository.login(authRequest: loginRequestModel.toJson()),
onSuccess: (result) async{ onSuccess: (result) async {
await tokenStorageService.saveRefreshToken(result!.refresh!); await tokenStorageService.saveRefreshToken(result!.refresh!);
await tokenStorageService.saveAccessToken(result!.access!); await tokenStorageService.saveAccessToken(result!.access!);
//Get.offAndToNamed(Routes.home); //Get.offAndToNamed(Routes.home);
@@ -125,4 +126,9 @@ class AuthLogic extends GetxController {
); );
isLoading.value = false; isLoading.value = false;
} }
adder() {
tokenStorageService.tsss.value = (wsd++).toString();
}
} }

View File

@@ -38,7 +38,8 @@ class AuthPage extends GetView<AuthLogic> {
), ),
), ),
TextSpan( TextSpan(
recognizer: TapGestureRecognizer()..onTap = () {}, recognizer: TapGestureRecognizer()
..onTap = () {},
text: 'حریم خصوصی', text: 'حریم خصوصی',
style: AppFonts.yekan14.copyWith( style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal, color: AppColor.blueNormal,
@@ -55,22 +56,22 @@ class AuthPage extends GetView<AuthLogic> {
children: [ children: [
TextSpan( TextSpan(
recognizer: recognizer:
TapGestureRecognizer() TapGestureRecognizer()
..onTap = () { ..onTap = () {
if (controller.authType.value == AuthType.otp) { if (controller.authType.value == AuthType.otp) {
controller.authType.value = AuthType.useAndPass; controller.authType.value = AuthType.useAndPass;
if (controller.otpStatus.value != if (controller.otpStatus.value !=
OtpStatus.init) { OtpStatus.init) {
controller.otpStatus.value = OtpStatus.init; controller.otpStatus.value = OtpStatus.init;
} }
} else { } else {
controller.authType.value = AuthType.otp; controller.authType.value = AuthType.otp;
} }
}, },
text: text:
controller.authType.value == AuthType.otp controller.authType.value == AuthType.otp
? 'ورود با رمز ثابت' ? 'ورود با رمز ثابت'
: 'ورود با رمز یکبار مصرف', : 'ورود با رمز یکبار مصرف',
style: AppFonts.yekan14.copyWith( style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal, color: AppColor.blueNormal,
@@ -94,84 +95,88 @@ class AuthPage extends GetView<AuthLogic> {
child: Column( child: Column(
children: [ children: [
ObxValue( ObxValue(
(phoneController) => RTextField( (phoneController) =>
label: 'نام کاربری', RTextField(
maxLength: 11, label: 'نام کاربری',
maxLines: 1, maxLength: 11,
controller: phoneController.value, maxLines: 1,
keyboardType: TextInputType.number, controller: phoneController.value,
initText: phoneController.value.text, keyboardType: TextInputType.number,
onChanged: (value) { initText: phoneController.value.text,
phoneController.value.text = value; onChanged: (value) {
phoneController.refresh(); phoneController.value.text = value;
}, phoneController.refresh();
prefixIcon: Padding( },
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8), prefixIcon: Padding(
child: vecWidget(Assets.vecCallSvg), padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
), child: vecWidget(Assets.vecCallSvg),
suffixIcon: ),
phoneController.value.text.trim().isNotEmpty suffixIcon:
phoneController.value.text
.trim()
.isNotEmpty
? clearButton(() { ? clearButton(() {
phoneController.value.clear(); phoneController.value.clear();
phoneController.refresh(); phoneController.refresh();
}) })
: null, : null,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return '⚠️ شماره موبایل را وارد کنید'; return '⚠️ شماره موبایل را وارد کنید';
} }
/*else if (value.length < 11) { /*else if (value.length < 11) {
return '⚠️ شماره موبایل باید 11 رقم باشد'; return '⚠️ شماره موبایل باید 11 رقم باشد';
}*/ }*/
return null; return null;
}, },
style: AppFonts.yekan13, style: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith( errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal, color: AppColor.redNormal,
), ),
labelStyle: AppFonts.yekan13, labelStyle: AppFonts.yekan13,
boxConstraints: const BoxConstraints( boxConstraints: const BoxConstraints(
maxHeight: 40, maxHeight: 40,
minHeight: 40, minHeight: 40,
maxWidth: 40, maxWidth: 40,
minWidth: 40, minWidth: 40,
), ),
), ),
controller.phoneNumberController, controller.phoneNumberController,
), ),
const SizedBox(height: 26), const SizedBox(height: 26),
ObxValue( ObxValue(
(passwordController) => RTextField( (passwordController) =>
label: 'رمز عبور', RTextField(
filled: false, label: 'رمز عبور',
controller: passwordController.value, filled: false,
variant: RTextFieldVariant.password, controller: passwordController.value,
initText: passwordController.value.text, variant: RTextFieldVariant.password,
onChanged: (value) { initText: passwordController.value.text,
passwordController.refresh(); onChanged: (value) {
}, passwordController.refresh();
validator: (value) { },
if (value == null || value.isEmpty) { validator: (value) {
return '⚠️ رمز عبور را وارد کنید'; if (value == null || value.isEmpty) {
} return '⚠️ رمز عبور را وارد کنید';
return null; }
}, return null;
style: AppFonts.yekan13, },
errorStyle: AppFonts.yekan13.copyWith( style: AppFonts.yekan13,
color: AppColor.redNormal, errorStyle: AppFonts.yekan13.copyWith(
), color: AppColor.redNormal,
labelStyle: AppFonts.yekan13, ),
prefixIcon: Padding( labelStyle: AppFonts.yekan13,
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8), prefixIcon: Padding(
child: vecWidget(Assets.vecKeySvg), padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
), child: vecWidget(Assets.vecKeySvg),
boxConstraints: const BoxConstraints( ),
maxHeight: 34, boxConstraints: const BoxConstraints(
minHeight: 34, maxHeight: 34,
maxWidth: 34, minHeight: 34,
minWidth: 34, maxWidth: 34,
), minWidth: 34,
), ),
),
controller.passwordController, controller.passwordController,
), ),
SizedBox(height: 26), SizedBox(height: 26),
@@ -188,13 +193,16 @@ class AuthPage extends GetView<AuthLogic> {
height: 48, height: 48,
); );
}, controller.isLoading), }, controller.isLoading),
FloatingActionButton(onPressed: () {
controller.adder();
}, child: Icon(Icons.add),)
], ],
), ),
), ),
); );
} }
/* /*
Widget sendCodeForm() { Widget sendCodeForm() {
return ObxValue((data) { return ObxValue((data) {
return Form( return Form(

View File

@@ -4,7 +4,7 @@ import 'package:rasadyar_core/infrastructure/local/hive_local_storage.dart';
final diCore = GetIt.instance; final diCore = GetIt.instance;
Future<void> setupAllProvider() async { Future<void> setupAllCoreProvider() async {
await _setUpLogger(); await _setUpLogger();
await _setupLocalStorage(); await _setupLocalStorage();
await _setupRemote(); await _setupRemote();