feat(registration): added email verification, feat(diary): fixed moderation request, feat(oauth): fixed email and phone verification

This commit is contained in:
misha
2025-12-25 16:31:52 +03:00
parent 99659f7ea1
commit 0ead14bca5
18 changed files with 148 additions and 165 deletions

View File

@@ -1,15 +1,26 @@
import 'dart:developer';
import 'package:eatvio_app/core/app_router.dart';
import 'package:eatvio_app/core/firebase_api.dart';
import 'package:eatvio_app/core/prefs.dart';
import 'package:eatvio_app/core/prefs_keys.dart';
import 'package:eatvio_app/core/routing/route_constants.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/core/utils/toasts.dart';
import 'package:eatvio_app/features/auth/presentation/bloc/auth_cubit/auth_state.dart';
import 'package:eatvio_app/features/auth/repositories/auth_repository.dart';
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:go_router/go_router.dart';
class AuthCubit extends Cubit<AuthState> {
final AuthRepository authRepository;
final ProfileRepository profileRepository;
final FirebaseApi firebaseApi;
final Prefs prefs;
AuthCubit({required this.authRepository}) : super(const AuthState());
AuthCubit({required this.authRepository, required this.prefs, required this.profileRepository, required this.firebaseApi}) : super(const AuthState());
Future<bool> getTokenByCredentials(String email, String password) async {
emit(const AuthState.loading());
@@ -25,4 +36,32 @@ class AuthCubit extends Cubit<AuthState> {
return false;
}
}
Future<void> initializeUser() async {
await registerAnonymousPushToken();
if (await TokenStorage.haveTokenInStorage()) {
final profile = await profileRepository.getMyProfile();
if (profile.emailVerifiedAt != null) {
await registerPushToken();
AppRouter.navigatorKey.currentContext?.go(RouteConstants.feedScreen);
return;
}
AppRouter.navigatorKey.currentContext?.go(RouteConstants.verifyEmailScreen);
} else {
await registerAnonymousPushToken();
FlutterNativeSplash.remove();
}
}
Future<void> registerAnonymousPushToken() async {
final hasAnonymousTokenBeenSent = prefs.getBool(PrefsKeys.hasAnonymousTokenBeenSent) ?? false;
if (!hasAnonymousTokenBeenSent) {
await firebaseApi.registerAnonymousPushToken();
prefs.setBool(PrefsKeys.hasAnonymousTokenBeenSent, true);
}
}
Future<void> registerPushToken() async {
await firebaseApi.registerPushToken();
}
}

View File

@@ -126,8 +126,10 @@ class OAuthCubit extends Cubit<OAuthState> with RegistrationDateCacheMixin {
try {
emit(const OAuthState.loading());
log('OAuthCubit: Requesting verification code for email: $email, phone: $phone');
final response = await authRepository.requestOAuthVerification(email: email, phone: phone);
log('OAuthCubit: Verification code requested successfully, masked email: ${response.email}');
final response = await authRepository.requestOAuthVerification(email: null, phone: phone);
if (response != null) {
log('OAuthCubit: Verification code requested successfully, masked email: ${response.email}');
}
// Сбрасываем состояние после успешного запроса кода
emit(const OAuthState());
return response;

View File

@@ -28,7 +28,6 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:url_launcher/url_launcher.dart';
@@ -232,9 +231,8 @@ class _AuthScreenState extends State<AuthScreen> {
final bool useMobileLayout = shortestSide < 600;
if (!useMobileLayout) isFocused = true;
final s = S.of(context);
FlutterNativeSplash.remove();
return BlocProvider<AuthCubit>(
create: (BuildContext context) => authCubit,
create: (BuildContext context) => authCubit..initializeUser(),
child: BlocBuilder<AuthCubit, AuthState>(
builder: (BuildContext context, AuthState state) {
return Scaffold(

View File

@@ -623,10 +623,10 @@ class _RegisterViaSocialScreenState extends State<RegisterViaSocialScreen> {
// Показываем диалог для ввода кода
final displayText = response.email;
_showVerificationCodeDialog(context, type, displayText);
} else {
if (context.mounted) {
showErrorToast('Не удалось отправить код верификации');
}
} else if ((emailController.text.isEmpty || phoneController.text.isEmpty) && context.mounted) {
showErrorToast('Пожалуйста, заполните все поля');
} else if (context.mounted) {
showErrorToast('Не удалось отправить код верификации');
}
} catch (e) {
if (context.mounted) {