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{
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:rasadyar_app/presentation/routes/app_pages.dart';
import 'package:rasadyar_core/core.dart';
import 'infrastructure/di/di.dart';
import 'infrastructure/service/auth_service.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await setupInjection();
Get.put(AuthService());
runApp(MyApp());
// runApp(DevicePreview(builder: (context) => ForDevicePreview(),));

View File

@@ -4,5 +4,4 @@
library;
export 'data/services/auth_middelware.dart';
export 'data/services/auth_service.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/dio_error_handler.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_core/core.dart';
@@ -17,7 +16,6 @@ Future<void> setupAuthDI() async {
diAuth.registerCachedFactory<AuthRepositoryImpl>(
() => AuthRepositoryImpl(dioRemote),
);
diAuth.registerLazySingleton<AuthService>(() => AuthService());
diAuth.registerLazySingleton<TokenStorageService>(() => TokenStorageService());
diAuth.registerLazySingleton<DioErrorHandler>(() => DioErrorHandler());
}

View File

@@ -10,9 +10,8 @@ class AuthMiddleware extends GetMiddleware {
@override
RouteSettings? redirect(String? route) {
eLog('redirect');
final refreshToken = tokenService.getRefreshToken();
final accessToken = tokenService.getAccessToken();
final refreshToken = tokenService.refreshToken.value;
final accessToken = tokenService.accessToken.value;
if (refreshToken == null || accessToken == null) {
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';
class TokenStorageService extends GetxService {
static const String _boxName = 'secureBox';
static const String _accessTokenKey = 'accessToken';
static const String _refreshTokenKey = 'refreshToken';
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
final HiveLocalStorage _localStorage = diCore.get<HiveLocalStorage>();
RxnString accessToken = RxnString();
RxnString refreshToken = RxnString();
RxnString tsss = RxnString();
Future<void> init() async {
final String? encryptedKey = await _secureStorage.read(key: 'hive_enc_key');
final encryptionKey =
@@ -29,26 +33,40 @@ class TokenStorageService extends GetxService {
_boxName,
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(
boxName: _boxName,
key: _accessTokenKey,
value: token,
);
Future<void> saveRefreshToken(String token) async => await _localStorage.save(
boxName: _boxName,
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> saveAccessToken(String token) async {
await _localStorage.save(
boxName: _boxName,
key: _accessTokenKey,
value: token,
);
accessToken.value = token;
accessToken.refresh();
}
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;
RxInt secondsRemaining = 120.obs;
int wsd = 120;
Timer? _timer;
AuthRepositoryImpl authRepository = diAuth.get<AuthRepositoryImpl>();
@@ -111,7 +112,7 @@ class AuthLogic extends GetxController {
isLoading.value = true;
await safeCall<AuthResponseModel?>(
call: () => authRepository.login(authRequest: loginRequestModel.toJson()),
onSuccess: (result) async{
onSuccess: (result) async {
await tokenStorageService.saveRefreshToken(result!.refresh!);
await tokenStorageService.saveAccessToken(result!.access!);
//Get.offAndToNamed(Routes.home);
@@ -125,4 +126,9 @@ class AuthLogic extends GetxController {
);
isLoading.value = false;
}
adder() {
tokenStorageService.tsss.value = (wsd++).toString();
}
}

View File

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

View File

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