- signInWithPhoneNumber: calls POST /auth/send-otp, stores pending phone - verifyOTP: calls POST /auth/phone with phone+code, saves token - linkWithOTP: calls POST /auth/verify-phone (authenticated) with phone+code - AuthBloc._linkWithPhoneNumber: replaced Firebase PhoneVerificationService with repository call Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
127 lines
3.8 KiB
Dart
127 lines
3.8 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:equatable/equatable.dart';
|
|
import 'package:user_repository/user_repository.dart';
|
|
|
|
part 'auth_event.dart';
|
|
part 'auth_state.dart';
|
|
|
|
class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|
final UserRepository _userRepository;
|
|
|
|
AuthBloc({required UserRepository userRepository})
|
|
: _userRepository = userRepository,
|
|
super(AuthStateInitial()) {
|
|
on<AuthEventLoginOAuth>(_onAuthEventLoginOAuth);
|
|
on<AuthEventVerifyOAuth>(_onAuthEventVerifyOAuth);
|
|
on<AuthEventAddEmailAndPassword>(_onAuthEventAddEmailAndPassword);
|
|
on<AuthEventUpdatePassword>(_updatePassword);
|
|
on<LinkWithPhoneNumber>(_linkWithPhoneNumber);
|
|
on<LinkWithPhoneNumberOtp>(_linkWithPhoneNumberOtp);
|
|
}
|
|
|
|
void _onAuthEventLoginOAuth(
|
|
AuthEventLoginOAuth event, Emitter<AuthState> emit) async {
|
|
emit(AuthStateProcess());
|
|
try {
|
|
await _userRepository.signInWithPhoneNumber(event.phone);
|
|
|
|
emit(const AuthStateVerifyOAuth(false));
|
|
} catch (e) {
|
|
emit(const AuthStateFailure());
|
|
}
|
|
}
|
|
|
|
void _onAuthEventVerifyOAuth(
|
|
AuthEventVerifyOAuth event, Emitter<AuthState> emit) async {
|
|
emit(AuthStateProcess());
|
|
try {
|
|
final bool isVerified = await _userRepository.verifyOTP(event.code);
|
|
|
|
if (isVerified) {
|
|
emit(AuthStateSuccess());
|
|
} else {
|
|
emit(const AuthStateVerifyOAuth(true));
|
|
}
|
|
} catch (e) {
|
|
emit(const AuthStateFailure());
|
|
}
|
|
}
|
|
|
|
void _onAuthEventAddEmailAndPassword(
|
|
AuthEventAddEmailAndPassword event, Emitter<AuthState> emit) async {
|
|
emit(AuthStateProcess());
|
|
try {
|
|
final String? error = await _userRepository.addEmailAndPassword(
|
|
event.email, event.password);
|
|
if (error == null) {
|
|
emit(AuthStateSuccess());
|
|
} else {
|
|
if (error == 'requires-recent-login') {
|
|
emit(AuthStateRequiresRecentLogin());
|
|
} else if (error == 'email-already-in-use') {
|
|
emit(AuthStateEmailAlreadyInUse());
|
|
} else {
|
|
emit(const AuthStateFailure());
|
|
}
|
|
}
|
|
} catch (e) {
|
|
emit(const AuthStateFailure());
|
|
}
|
|
}
|
|
|
|
void _updatePassword(
|
|
AuthEventUpdatePassword event, Emitter<AuthState> emit) async {
|
|
emit(AuthStateProcess());
|
|
try {
|
|
final error = await _userRepository.updatePassword(
|
|
event.actualPassword, event.password);
|
|
if (error == null) {
|
|
emit(AuthStateSuccess());
|
|
} else {
|
|
switch (error) {
|
|
case UpdatePassworErros.credentialsWrong:
|
|
emit(const AuthStateFailure(message: "Contrasena incorrecta"));
|
|
break;
|
|
case UpdatePassworErros.userNotFound:
|
|
emit(const AuthStateFailure(message: "Usuario no encontrado"));
|
|
break;
|
|
case UpdatePassworErros.unknown:
|
|
emit(const AuthStateFailure(message: "Error inesperado."));
|
|
break;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
emit(const AuthStateFailure(message: "Error inesperado."));
|
|
}
|
|
}
|
|
|
|
void _linkWithPhoneNumber(
|
|
LinkWithPhoneNumber event, Emitter<AuthState> emit) async {
|
|
emit(AuthStateProcess());
|
|
try {
|
|
await _userRepository.signInWithPhoneNumber(event.phoneNumber);
|
|
emit(const AuthStateVerifyOAuth(false));
|
|
} catch (e) {
|
|
emit(AuthStateFailure(message: "Error al enviar código. $e"));
|
|
}
|
|
}
|
|
|
|
void _linkWithPhoneNumberOtp(
|
|
LinkWithPhoneNumberOtp event, Emitter<AuthState> emit) async {
|
|
emit(AuthStateProcess());
|
|
try {
|
|
final bool isVerified = await _userRepository.linkWithOTP(
|
|
event.phoneNumber, '', event.code);
|
|
if (isVerified) {
|
|
emit(AuthStateSuccess());
|
|
} else {
|
|
emit(const AuthStateVerifyOAuth(true));
|
|
}
|
|
} catch (e) {
|
|
emit(AuthStateFailure(message: "Error inesperado. $e"));
|
|
}
|
|
}
|
|
}
|