mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-16 01:56:19 +00:00
164 lines
5.0 KiB
Dart
164 lines
5.0 KiB
Dart
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
|
|
import 'package:syncrow_app/features/auth/model/login_with_email_model.dart';
|
|
import 'package:syncrow_app/features/auth/model/token.dart';
|
|
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
|
import 'package:syncrow_app/navigation/navigation_service.dart';
|
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
|
import 'package:syncrow_app/services/api/authentication_api.dart';
|
|
|
|
part 'auth_state.dart';
|
|
|
|
class AuthCubit extends Cubit<AuthState> {
|
|
AuthCubit() : super(AuthInitial()) {
|
|
getTokenAndValidate();
|
|
}
|
|
|
|
static AuthCubit get(context) => BlocProvider.of(context);
|
|
|
|
final TextEditingController emailController = TextEditingController();
|
|
final TextEditingController passwordController = TextEditingController();
|
|
final loginFormKey = GlobalKey<FormState>();
|
|
bool isPasswordVisible = false;
|
|
|
|
static GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
|
|
|
void changePasswordVisibility() {
|
|
isPasswordVisible = !isPasswordVisible;
|
|
emit(AuthPasswordVisibilityChanged());
|
|
}
|
|
|
|
bool agreeToTerms = false;
|
|
|
|
void changeAgreeToTerms() {
|
|
agreeToTerms = !agreeToTerms;
|
|
emit(AuthAgreeToTermsChanged());
|
|
}
|
|
|
|
static UserModel? user;
|
|
|
|
static Token token = Token.emptyConstructor();
|
|
|
|
/////////////////////////////////////VALIDATORS/////////////////////////////////////
|
|
String? passwordValidator(String? value) {
|
|
if (value != null) {
|
|
if (value.isNotEmpty) {
|
|
if (value.length >= 6) {
|
|
return null;
|
|
//TODO uncomment this code when the password validation is needed
|
|
// if (RegExp(
|
|
// r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$')
|
|
// .hasMatch(value)) {
|
|
// return null;
|
|
// } else {
|
|
// return 'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character';
|
|
// }
|
|
} else {
|
|
return 'Password must be at least 6 characters';
|
|
}
|
|
} else {
|
|
return 'Please enter your password';
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
String? emailAddressValidator(String? value) {
|
|
if (value != null && value.isNotEmpty && value != "") {
|
|
if (checkValidityOfEmail(value)) {
|
|
if (loginFormKey.currentState != null) {
|
|
loginFormKey.currentState!.save();
|
|
}
|
|
return null;
|
|
} else {
|
|
return 'Please enter a valid email';
|
|
}
|
|
} else {
|
|
return 'Email address is required';
|
|
}
|
|
}
|
|
|
|
bool checkValidityOfEmail(String? email) {
|
|
if (email != null) {
|
|
return RegExp(
|
|
r"^[a-zA-Z0-9]+([.!#$%&'*+/=?^_`{|}~-]?[a-zA-Z0-9]+)*@[a-zA-Z0-9]+([.-]?[a-zA-Z0-9]+)*\.[a-zA-Z0-9]{2,}$")
|
|
.hasMatch(email);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////API CALLS/////////////////////////////////////
|
|
login() async {
|
|
emit(AuthLoginLoading());
|
|
try {
|
|
token = await AuthenticationAPI.loginWithEmail(
|
|
model: LoginWithEmailModel(
|
|
email: emailController.text.toLowerCase(),
|
|
password: passwordController.text,
|
|
),
|
|
);
|
|
} catch (failure) {
|
|
emit(AuthLoginError(message: failure.toString()));
|
|
return;
|
|
}
|
|
if (token.accessTokenIsNotEmpty) {
|
|
FlutterSecureStorage storage = const FlutterSecureStorage();
|
|
await storage.write(
|
|
key: Token.loginAccessTokenKey, value: token.accessToken);
|
|
const FlutterSecureStorage().write(
|
|
key: UserModel.userUuidKey,
|
|
value: Token.decodeToken(token.accessToken)['uuid'].toString());
|
|
user = UserModel.fromToken(token);
|
|
emailController.clear();
|
|
passwordController.clear();
|
|
emit(AuthLoginSuccess());
|
|
} else {
|
|
emit(AuthLoginError(message: 'Something went wrong'));
|
|
}
|
|
}
|
|
|
|
logout() async {
|
|
emit(AuthLogoutLoading());
|
|
try {
|
|
FlutterSecureStorage storage = const FlutterSecureStorage();
|
|
await storage.delete(key: Token.loginAccessTokenKey);
|
|
NavigationService.navigatorKey.currentState!
|
|
.popAndPushNamed(Routes.authLogin);
|
|
emit(AuthLogoutSuccess());
|
|
} catch (failure) {
|
|
emit(AuthLogoutError(message: failure.toString()));
|
|
return;
|
|
}
|
|
}
|
|
|
|
getTokenAndValidate() async {
|
|
emit(AuthTokenLoading());
|
|
final value =
|
|
await const FlutterSecureStorage().read(key: Token.loginAccessTokenKey);
|
|
|
|
if (value == null) {
|
|
emit(AuthTokenError(message: "Token not found"));
|
|
return;
|
|
}
|
|
|
|
final tokenData = Token.decodeToken(value);
|
|
|
|
if (tokenData.containsKey('exp')) {
|
|
final exp = tokenData['exp'] ?? 0;
|
|
final currentTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
|
|
|
if (currentTime < exp) {
|
|
emit(AuthTokenSuccess());
|
|
} else {
|
|
emit(AuthTokenError(message: "Token expired"));
|
|
}
|
|
} else {
|
|
emit(AuthTokenError(message: "Something went wrong"));
|
|
}
|
|
}
|
|
}
|