Compare commits
	
		
			No commits in common. "5e83c9e74e7c2cffb5c7981a0c5e49ec3cf3e764" and "d792f4cbe97b8265215093fdc66db305825c539f" have entirely different histories.
		
	
	
		
			5e83c9e74e
			...
			d792f4cbe9
		
	
		
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: bootstrap.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 15:05:17 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: Fri Nov 11 2022 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'dart:async'; | import 'dart:async'; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,20 +1,12 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: form_field.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 11:52:33 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: 19/08/2022 16:35:39 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| abstract class AppFormField { | abstract class AppFormField { | ||||||
|   static const oldPassword = 'oldPassword'; |  | ||||||
|   static const confirmedPassword = 'confirmedPassword'; |   static const confirmedPassword = 'confirmedPassword'; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,19 +0,0 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP |  | ||||||
| // Please see the AUTHORS file for details. |  | ||||||
| //  |  | ||||||
| // This program is free software: you can redistribute it and/or modify |  | ||||||
| // it under the terms of the GNU General Public License as published by |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or |  | ||||||
| // any later version. |  | ||||||
| //  |  | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
| abstract class AppFormName { |  | ||||||
|   static const editProfile = 'editProfile'; |  | ||||||
| } |  | ||||||
| @ -1,20 +1,12 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| // | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: router.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 11:52:22 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: 19/08/2022 16:39:07 | ||||||
| // any later version. | // ----- | ||||||
| // | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| // |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:example_router/presentation/features/edit_profile/edit_profile_page.dart'; |  | ||||||
| import 'package:example_router/presentation/features/home/home_page.dart'; | import 'package:example_router/presentation/features/home/home_page.dart'; | ||||||
| import 'package:example_router/presentation/features/sign_in/sign_in_page.dart'; | import 'package:example_router/presentation/features/sign_in/sign_in_page.dart'; | ||||||
| import 'package:example_router/presentation/features/sign_up/sign_up_page.dart'; | import 'package:example_router/presentation/features/sign_up/sign_up_page.dart'; | ||||||
| @ -83,14 +75,5 @@ class AppRouter { | |||||||
|         const SubPage(), |         const SubPage(), | ||||||
|       ), |       ), | ||||||
|     ), |     ), | ||||||
|     GoRoute( |  | ||||||
|       path: '/home/edit', |  | ||||||
|       name: EditProfilePage.pageName, |  | ||||||
|       pageBuilder: (context, state) => defaultTransition( |  | ||||||
|         context, |  | ||||||
|         state, |  | ||||||
|         const EditProfilePage(), |  | ||||||
|       ), |  | ||||||
|     ), |  | ||||||
|   ]; |   ]; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: app_bloc_observer.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 12:02:23 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: 19/08/2022 12:02:45 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:flutter/foundation.dart'; | import 'package:flutter/foundation.dart'; | ||||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||||
|  | |||||||
| @ -1,32 +0,0 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP |  | ||||||
| // Please see the AUTHORS file for details. |  | ||||||
| // |  | ||||||
| // This program is free software: you can redistribute it and/or modify |  | ||||||
| // it under the terms of the GNU General Public License as published by |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or |  | ||||||
| // any later version. |  | ||||||
| // |  | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| // |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
| import 'package:example_router/core/constants/form_field.dart'; |  | ||||||
| import 'package:example_router/core/constants/form_name.dart'; |  | ||||||
| import 'package:example_router/core/utils/custom_password.dart'; |  | ||||||
| import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; |  | ||||||
| import 'package:wyatt_form_bloc/wyatt_form_bloc.dart'; |  | ||||||
| 
 |  | ||||||
| abstract class AppForms { |  | ||||||
|   static WyattForm getEditProfileForm() => WyattFormImpl( |  | ||||||
|         [ |  | ||||||
|           FormInput(AuthFormField.email, const Email.pure()), |  | ||||||
|           FormInput(AuthFormField.password, const CustomPassword.pure()), |  | ||||||
|           FormInput(AppFormField.oldPassword, const CustomPassword.pure()), |  | ||||||
|         ], |  | ||||||
|         name: AppFormName.editProfile, |  | ||||||
|       ); |  | ||||||
| } |  | ||||||
| @ -1,19 +1,3 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP |  | ||||||
| // Please see the AUTHORS file for details. |  | ||||||
| //  |  | ||||||
| // This program is free software: you can redistribute it and/or modify |  | ||||||
| // it under the terms of the GNU General Public License as published by |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or |  | ||||||
| // any later version. |  | ||||||
| //  |  | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
| import 'package:example_router/bootstrap.dart'; | import 'package:example_router/bootstrap.dart'; | ||||||
| import 'package:example_router/presentation/features/app/app.dart'; | import 'package:example_router/presentation/features/app/app.dart'; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| // | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: app.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 12:05:38 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: Sat Dec 03 2022 | ||||||
| // any later version. | // ----- | ||||||
| // | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| // |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'dart:async'; | import 'dart:async'; | ||||||
| import 'dart:math'; | import 'dart:math'; | ||||||
| @ -21,7 +14,6 @@ import 'package:example_router/core/constants/form_field.dart'; | |||||||
| import 'package:example_router/core/dependency_injection/get_it.dart'; | import 'package:example_router/core/dependency_injection/get_it.dart'; | ||||||
| import 'package:example_router/core/routes/router.dart'; | import 'package:example_router/core/routes/router.dart'; | ||||||
| import 'package:example_router/core/utils/custom_password.dart'; | import 'package:example_router/core/utils/custom_password.dart'; | ||||||
| import 'package:example_router/core/utils/forms.dart'; |  | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||||
| import 'package:go_router/go_router.dart'; | import 'package:go_router/go_router.dart'; | ||||||
| @ -77,7 +69,7 @@ class App extends StatelessWidget { | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     AuthenticationState<int>? previous; |     AuthenticationState? previous; | ||||||
| 
 | 
 | ||||||
|     final AuthenticationCubit<int> authenticationCubit = |     final AuthenticationCubit<int> authenticationCubit = | ||||||
|         AuthenticationCubit(authenticationRepository: authenticationRepository); |         AuthenticationCubit(authenticationRepository: authenticationRepository); | ||||||
| @ -93,18 +85,29 @@ class App extends StatelessWidget { | |||||||
|       redirect: (context, state) { |       redirect: (context, state) { | ||||||
|         final authState = authenticationCubit.state; |         final authState = authenticationCubit.state; | ||||||
| 
 | 
 | ||||||
|         if (authState.status != previous?.status) { |         if (authState != previous) { | ||||||
|           previous = authState; |           previous = authState; | ||||||
|  |           // Check if current user is logged in | ||||||
|  |           final loggedIn = | ||||||
|  |               authState.status == AuthenticationStatus.authenticated; | ||||||
|  | 
 | ||||||
|           // Checking if current path is onboarding or not |           // Checking if current path is onboarding or not | ||||||
|           final isOnboarding = AppRouter.publicRoutes.contains(state.subloc); |           final isOnboarding = AppRouter.publicRoutes.contains(state.subloc); | ||||||
|           if (authState.status == AuthenticationStatus.unauthenticated) { | 
 | ||||||
|  |           if (!loggedIn) { | ||||||
|             debugPrint('Not logged'); |             debugPrint('Not logged'); | ||||||
|             if (!isOnboarding) { |             if (isOnboarding) { | ||||||
|  |               return null; | ||||||
|  |             } else { | ||||||
|               return '/'; |               return '/'; | ||||||
|             } |             } | ||||||
|           } else if (authState.status == AuthenticationStatus.authenticated) { |           } else { | ||||||
|             debugPrint('Logged'); |             debugPrint('Logged'); | ||||||
|             return '/home'; |             if (isOnboarding) { | ||||||
|  |               return '/home'; | ||||||
|  |             } else { | ||||||
|  |               return null; | ||||||
|  |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         return null; |         return null; | ||||||
| @ -113,13 +116,9 @@ class App extends StatelessWidget { | |||||||
| 
 | 
 | ||||||
|     return MultiRepositoryProvider( |     return MultiRepositoryProvider( | ||||||
|       providers: [ |       providers: [ | ||||||
|         RepositoryProvider<AuthenticationRepository<int>>.value( |         RepositoryProvider<AuthenticationRepository>.value( | ||||||
|           value: authenticationRepository, |           value: authenticationRepository, | ||||||
|         ), |         ), | ||||||
|         RepositoryProvider<FormRepository>( |  | ||||||
|           create: (context) => |  | ||||||
|               FormRepositoryImpl()..registerForm(AppForms.getEditProfileForm()), |  | ||||||
|         ), |  | ||||||
|       ], |       ], | ||||||
|       child: MultiBlocProvider( |       child: MultiBlocProvider( | ||||||
|         providers: [ |         providers: [ | ||||||
|  | |||||||
| @ -1,74 +0,0 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP |  | ||||||
| // Please see the AUTHORS file for details. |  | ||||||
| //  |  | ||||||
| // This program is free software: you can redistribute it and/or modify |  | ||||||
| // it under the terms of the GNU General Public License as published by |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or |  | ||||||
| // any later version. |  | ||||||
| //  |  | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
| import 'package:example_router/core/constants/form_field.dart'; |  | ||||||
| import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; |  | ||||||
| import 'package:wyatt_form_bloc/wyatt_form_bloc.dart'; |  | ||||||
| import 'package:wyatt_type_utils/wyatt_type_utils.dart'; |  | ||||||
| 
 |  | ||||||
| class EditProfileCubit extends FormDataCubitImpl { |  | ||||||
|   final AuthenticationRepository<int> authenticationRepository; |  | ||||||
| 
 |  | ||||||
|   EditProfileCubit( |  | ||||||
|     super._formRepository, |  | ||||||
|     super._formName, { |  | ||||||
|     required this.authenticationRepository, |  | ||||||
|   }) : super(); |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Future<void> submit() async { |  | ||||||
|     emit( |  | ||||||
|       state.copyWith( |  | ||||||
|         status: FormStatus.submissionInProgress, |  | ||||||
|       ), |  | ||||||
|     ); |  | ||||||
|     final user = (await authenticationRepository.getAccount()).ok; |  | ||||||
| 
 |  | ||||||
|     final form = state.form; |  | ||||||
|     final email = form.valueOf<String?>(AuthFormField.email); |  | ||||||
|     final oldPassword = form.valueOf<String?>(AppFormField.oldPassword); |  | ||||||
|     final newPassword = form.valueOf<String?>(AuthFormField.password); |  | ||||||
| 
 |  | ||||||
|     if (email.isNullOrEmpty || |  | ||||||
|         oldPassword.isNullOrEmpty || |  | ||||||
|         newPassword.isNullOrEmpty) { |  | ||||||
|       emit( |  | ||||||
|         state.copyWith( |  | ||||||
|           errorMessage: 'An error occured while retrieving data from the form.', |  | ||||||
|           status: FormStatus.submissionFailure, |  | ||||||
|         ), |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     try { |  | ||||||
|       // await authenticationRepository.signInWithEmailAndPassword( |  | ||||||
|       //   email: user?.email ?? '', |  | ||||||
|       //   password: oldPassword ?? '', |  | ||||||
|       // ); |  | ||||||
|       // await authenticationRepository.reauthenticateWithCredential(); |  | ||||||
|       await authenticationRepository.updateEmail(email: email!); |  | ||||||
|       await authenticationRepository.updatePassword(password: newPassword!); |  | ||||||
|     } on Exception catch (e) { |  | ||||||
|       emit( |  | ||||||
|         state.copyWith( |  | ||||||
|           status: FormStatus.submissionFailure, |  | ||||||
|           errorMessage: e.toString(), |  | ||||||
|         ), |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
|     emit(state.copyWith(status: FormStatus.submissionSuccess)); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP |  | ||||||
| // Please see the AUTHORS file for details. |  | ||||||
| // |  | ||||||
| // This program is free software: you can redistribute it and/or modify |  | ||||||
| // it under the terms of the GNU General Public License as published by |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or |  | ||||||
| // any later version. |  | ||||||
| // |  | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| // |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
| import 'package:example_router/core/constants/form_name.dart'; |  | ||||||
| import 'package:example_router/presentation/features/edit_profile/blocs/edit_profile_cubit.dart'; |  | ||||||
| import 'package:example_router/presentation/features/edit_profile/widgets/edit_profile_form.dart'; |  | ||||||
| import 'package:flutter/material.dart'; |  | ||||||
| import 'package:flutter_bloc/flutter_bloc.dart'; |  | ||||||
| import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; |  | ||||||
| import 'package:wyatt_form_bloc/wyatt_form_bloc.dart'; |  | ||||||
| 
 |  | ||||||
| class EditProfilePage extends StatelessWidget { |  | ||||||
|   const EditProfilePage({Key? key}) : super(key: key); |  | ||||||
| 
 |  | ||||||
|   static String pageName = 'EditProfile'; |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Widget build(BuildContext context) { |  | ||||||
|     return Scaffold( |  | ||||||
|       appBar: AppBar(title: const Text('Edit Profile')), |  | ||||||
|       body: Padding( |  | ||||||
|         padding: const EdgeInsets.all(8), |  | ||||||
|         child: SingleChildScrollView( |  | ||||||
|           child: BlocProvider<EditProfileCubit>( |  | ||||||
|             create: (context) => EditProfileCubit( |  | ||||||
|               context.read<FormRepository>(), |  | ||||||
|               AppFormName.editProfile, |  | ||||||
|               authenticationRepository: |  | ||||||
|                   context.read<AuthenticationRepository<int>>(), |  | ||||||
|             )..dataChanged<String?>( |  | ||||||
|                 AuthFormField.email, |  | ||||||
|                 Email.dirty( |  | ||||||
|                   context |  | ||||||
|                           .read<AuthenticationCubit<int>>() |  | ||||||
|                           .state |  | ||||||
|                           .accountWrapper |  | ||||||
|                           ?.account |  | ||||||
|                           ?.email ?? |  | ||||||
|                       '', |  | ||||||
|                 ), |  | ||||||
|               ), |  | ||||||
|             child: const EditProfileForm(), |  | ||||||
|           ), |  | ||||||
|         ), |  | ||||||
|       ), |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,136 +0,0 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP |  | ||||||
| // Please see the AUTHORS file for details. |  | ||||||
| // |  | ||||||
| // This program is free software: you can redistribute it and/or modify |  | ||||||
| // it under the terms of the GNU General Public License as published by |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or |  | ||||||
| // any later version. |  | ||||||
| // |  | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| // |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
| import 'package:example_router/core/constants/form_field.dart'; |  | ||||||
| import 'package:example_router/core/utils/custom_password.dart'; |  | ||||||
| import 'package:example_router/presentation/features/edit_profile/blocs/edit_profile_cubit.dart'; |  | ||||||
| import 'package:flutter/material.dart'; |  | ||||||
| import 'package:flutter_bloc/flutter_bloc.dart'; |  | ||||||
| import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; |  | ||||||
| import 'package:wyatt_form_bloc/wyatt_form_bloc.dart'; |  | ||||||
| 
 |  | ||||||
| class _EmailInput extends StatelessWidget { |  | ||||||
|   @override |  | ||||||
|   Widget build(BuildContext context) { |  | ||||||
|     return InputBuilderTextController<EditProfileCubit, String?, void>( |  | ||||||
|       field: AuthFormField.email, |  | ||||||
|       builder: ((context, cubit, state, field, input, controller, extra) { |  | ||||||
|         return TextField( |  | ||||||
|           onChanged: (email) => cubit.dataChanged<String?>( |  | ||||||
|               AuthFormField.email, Email.dirty(email)), |  | ||||||
|           keyboardType: TextInputType.emailAddress, |  | ||||||
|           controller: controller, |  | ||||||
|           decoration: InputDecoration( |  | ||||||
|             labelText: 'Email', |  | ||||||
|             helperText: '', |  | ||||||
|             errorText: input.validator.invalid ? 'Invalid email' : null, |  | ||||||
|           ), |  | ||||||
|         ); |  | ||||||
|       }), |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class _OldPasswordInput extends StatelessWidget { |  | ||||||
|   @override |  | ||||||
|   Widget build(BuildContext context) { |  | ||||||
|     return InputBuilder<EditProfileCubit>( |  | ||||||
|       field: AppFormField.oldPassword, |  | ||||||
|       builder: ((context, cubit, state, field, input) { |  | ||||||
|         return TextField( |  | ||||||
|           onChanged: (pwd) => cubit.dataChanged<String?>( |  | ||||||
|               AppFormField.oldPassword, CustomPassword.dirty(pwd)), |  | ||||||
|           obscureText: true, |  | ||||||
|           decoration: InputDecoration( |  | ||||||
|             labelText: 'Old Password', |  | ||||||
|             helperText: '', |  | ||||||
|             errorText: input.validator.invalid ? 'Invalid password' : null, |  | ||||||
|           ), |  | ||||||
|         ); |  | ||||||
|       }), |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class _NewPasswordInput extends StatelessWidget { |  | ||||||
|   @override |  | ||||||
|   Widget build(BuildContext context) { |  | ||||||
|     return InputBuilder<EditProfileCubit>( |  | ||||||
|       field: AuthFormField.password, |  | ||||||
|       builder: ((context, cubit, state, field, input) { |  | ||||||
|         return TextField( |  | ||||||
|           onChanged: (pwd) => cubit.dataChanged<String?>( |  | ||||||
|               AuthFormField.password, CustomPassword.dirty(pwd)), |  | ||||||
|           obscureText: true, |  | ||||||
|           decoration: InputDecoration( |  | ||||||
|             labelText: 'New Password', |  | ||||||
|             helperText: '', |  | ||||||
|             errorText: input.validator.invalid ? 'Invalid password' : null, |  | ||||||
|           ), |  | ||||||
|         ); |  | ||||||
|       }), |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class _EditButton extends StatelessWidget { |  | ||||||
|   @override |  | ||||||
|   Widget build(BuildContext context) { |  | ||||||
|     return SubmitBuilder<EditProfileCubit>( |  | ||||||
|       builder: ((context, cubit, status) { |  | ||||||
|         return status.isSubmissionInProgress |  | ||||||
|             ? const CircularProgressIndicator() |  | ||||||
|             : ElevatedButton( |  | ||||||
|                 onPressed: status.isValidated ? () => cubit.submit() : null, |  | ||||||
|                 child: const Text('Edit profile'), |  | ||||||
|               ); |  | ||||||
|       }), |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class EditProfileForm extends StatelessWidget { |  | ||||||
|   const EditProfileForm({Key? key}) : super(key: key); |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Widget build(BuildContext context) { |  | ||||||
|     return BlocListener<EditProfileCubit, FormDataState>( |  | ||||||
|       listener: (context, state) { |  | ||||||
|         if (state.status == FormStatus.submissionFailure) { |  | ||||||
|           ScaffoldMessenger.of(context) |  | ||||||
|             ..hideCurrentSnackBar() |  | ||||||
|             ..showSnackBar( |  | ||||||
|               SnackBar(content: Text(state.errorMessage ?? 'Edit Failure')), |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|       child: SingleChildScrollView( |  | ||||||
|         child: Column( |  | ||||||
|           crossAxisAlignment: CrossAxisAlignment.center, |  | ||||||
|           children: [ |  | ||||||
|             _EmailInput(), |  | ||||||
|             const SizedBox(height: 8), |  | ||||||
|             _OldPasswordInput(), |  | ||||||
|             const SizedBox(height: 8), |  | ||||||
|             _NewPasswordInput(), |  | ||||||
|             const SizedBox(height: 16), |  | ||||||
|             _EditButton(), |  | ||||||
|           ], |  | ||||||
|         ), |  | ||||||
|       ), |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,20 +1,12 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| // | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: home_page.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 14:38:24 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: Wed Nov 09 2022 | ||||||
| // any later version. | // ----- | ||||||
| // | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| // |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:example_router/presentation/features/edit_profile/edit_profile_page.dart'; |  | ||||||
| import 'package:example_router/presentation/features/sub/sub_page.dart'; | import 'package:example_router/presentation/features/sub/sub_page.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||||
| @ -33,8 +25,7 @@ class HomePage extends StatelessWidget { | |||||||
|         title: const Text('Home'), |         title: const Text('Home'), | ||||||
|         actions: [ |         actions: [ | ||||||
|           IconButton( |           IconButton( | ||||||
|               onPressed: () => |               onPressed: () => context.read<AuthenticationCubit<int>>().signOut(), | ||||||
|                   context.read<AuthenticationCubit<int>>().signOut(), |  | ||||||
|               icon: const Icon(Icons.logout_rounded)) |               icon: const Icon(Icons.logout_rounded)) | ||||||
|         ], |         ], | ||||||
|       ), |       ), | ||||||
| @ -44,8 +35,8 @@ class HomePage extends StatelessWidget { | |||||||
|           child: Column( |           child: Column( | ||||||
|             children: [ |             children: [ | ||||||
|               AuthenticationBuilder<int>( |               AuthenticationBuilder<int>( | ||||||
|                 authenticated: (context, accountWrapper) => Text( |                 authenticated: (context, accountWrapper) => | ||||||
|                     'Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'), |                     Text('Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'), | ||||||
|                 unauthenticated: (context) => |                 unauthenticated: (context) => | ||||||
|                     const Text('Not logged (unauthenticated)'), |                     const Text('Not logged (unauthenticated)'), | ||||||
|                 unknown: (context) => const Text('Not logged (unknown)'), |                 unknown: (context) => const Text('Not logged (unknown)'), | ||||||
| @ -54,13 +45,8 @@ class HomePage extends StatelessWidget { | |||||||
|                 height: 8, |                 height: 8, | ||||||
|               ), |               ), | ||||||
|               ElevatedButton( |               ElevatedButton( | ||||||
|                 onPressed: () => context.pushNamed(SubPage.pageName), |                   onPressed: () => context.pushNamed(SubPage.pageName), | ||||||
|                 child: const Text('Go to sub page'), |                   child: const Text('Go to sub page')), | ||||||
|               ), |  | ||||||
|               ElevatedButton( |  | ||||||
|                 onPressed: () => context.pushNamed(EditProfilePage.pageName), |  | ||||||
|                 child: const Text('Go to edit profile page'), |  | ||||||
|               ), |  | ||||||
|             ], |             ], | ||||||
|           ), |           ), | ||||||
|         ), |         ), | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: sign_in_page.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 12:41:42 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: 19/08/2022 15:26:36 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:example_router/presentation/features/sign_in/widgets/sign_in_form.dart'; | import 'package:example_router/presentation/features/sign_in/widgets/sign_in_form.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: sign_in_form.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 15:24:37 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: Sat Dec 03 2022 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:example_router/core/utils/custom_password.dart'; | import 'package:example_router/core/utils/custom_password.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: sign_up_page.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 12:41:27 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: 19/08/2022 14:58:51 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:example_router/presentation/features/sign_up/widgets/sign_up_form.dart'; | import 'package:example_router/presentation/features/sign_up/widgets/sign_up_form.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: sign_up_form.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 14:41:08 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: Sat Dec 03 2022 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:example_router/core/constants/form_field.dart'; | import 'package:example_router/core/constants/form_field.dart'; | ||||||
| import 'package:example_router/core/utils/custom_password.dart'; | import 'package:example_router/core/utils/custom_password.dart'; | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: sub_page.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 16:10:05 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: Wed Nov 09 2022 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||||
| @ -31,10 +24,7 @@ class SubPage extends StatelessWidget { | |||||||
|         actions: [ |         actions: [ | ||||||
|           IconButton( |           IconButton( | ||||||
|               onPressed: () => context.read<AuthenticationCubit<int>>().signOut(), |               onPressed: () => context.read<AuthenticationCubit<int>>().signOut(), | ||||||
|               icon: const Icon(Icons.logout_rounded)), |               icon: const Icon(Icons.logout_rounded)) | ||||||
|           IconButton( |  | ||||||
|               onPressed: () => context.read<AuthenticationRepository<int>>().refresh(), |  | ||||||
|               icon: const Icon(Icons.refresh)) |  | ||||||
|         ], |         ], | ||||||
|       ), |       ), | ||||||
|       body: const Padding( |       body: const Padding( | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| // Copyright (C) 2022 WYATT GROUP | // Author: Hugo Pointcheval | ||||||
| // Please see the AUTHORS file for details. | // Email: git@pcl.ovh | ||||||
| //  | // ----- | ||||||
| // This program is free software: you can redistribute it and/or modify | // File: welcome_page.dart | ||||||
| // it under the terms of the GNU General Public License as published by | // Created Date: 19/08/2022 12:33:21 | ||||||
| // the Free Software Foundation, either version 3 of the License, or | // Last Modified: Wed Nov 09 2022 | ||||||
| // any later version. | // ----- | ||||||
| //  | // Copyright (c) 2022 | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| //  |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. |  | ||||||
| 
 | 
 | ||||||
| import 'package:example_router/presentation/features/sign_in/sign_in_page.dart'; | import 'package:example_router/presentation/features/sign_in/sign_in_page.dart'; | ||||||
| import 'package:example_router/presentation/features/sign_up/sign_up_page.dart'; | import 'package:example_router/presentation/features/sign_up/sign_up_page.dart'; | ||||||
|  | |||||||
| @ -256,24 +256,3 @@ abstract class GetIdTokenFailureInterface | |||||||
| 
 | 
 | ||||||
|   GetIdTokenFailureInterface.fromCode(super.code) : super.fromCode(); |   GetIdTokenFailureInterface.fromCode(super.code) : super.fromCode(); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| abstract class ReauthenticateFailureInterface |  | ||||||
|     extends AuthenticationFailureInterface { |  | ||||||
|   ReauthenticateFailureInterface(super.code, super.msg); |  | ||||||
| 
 |  | ||||||
|   ReauthenticateFailureInterface.fromCode(super.code) : super.fromCode(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| abstract class UpdateEmailFailureInterface |  | ||||||
|     extends AuthenticationFailureInterface { |  | ||||||
|   UpdateEmailFailureInterface(super.code, super.msg); |  | ||||||
| 
 |  | ||||||
|   UpdateEmailFailureInterface.fromCode(super.code) : super.fromCode(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| abstract class UpdatePasswordFailureInterface |  | ||||||
|     extends AuthenticationFailureInterface { |  | ||||||
|   UpdatePasswordFailureInterface(super.code, super.msg); |  | ||||||
| 
 |  | ||||||
|   UpdatePasswordFailureInterface.fromCode(super.code) : super.fromCode(); |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -277,75 +277,3 @@ class GetIdTokenFailureFirebase extends GetIdTokenFailureInterface { | |||||||
| 
 | 
 | ||||||
|   GetIdTokenFailureFirebase.fromCode(super.code) : super.fromCode(); |   GetIdTokenFailureFirebase.fromCode(super.code) : super.fromCode(); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| class ReauthenticateFailureFirebase extends ReauthenticateFailureInterface { |  | ||||||
|   ReauthenticateFailureFirebase([String? code, String? msg]) |  | ||||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); |  | ||||||
|   ReauthenticateFailureFirebase.fromCode(String code) : super.fromCode(code) { |  | ||||||
|     switch (code) { |  | ||||||
|       case 'user-mismatch': |  | ||||||
|         msg = 'Given credential does not correspond to the user.'; |  | ||||||
|         break; |  | ||||||
|       case 'user-not-found': |  | ||||||
|         msg = 'User is not found, please create an account.'; |  | ||||||
|         break; |  | ||||||
|       case 'invalid-credential': |  | ||||||
|         msg = 'The credential received is malformed or has expired.'; |  | ||||||
|         break; |  | ||||||
|       case 'invalid-email': |  | ||||||
|         msg = 'Email is not valid or badly formatted.'; |  | ||||||
|         break; |  | ||||||
|       case 'wrong-password': |  | ||||||
|         msg = 'Incorrect password, please try again.'; |  | ||||||
|         break; |  | ||||||
|       case 'invalid-verification-code': |  | ||||||
|         msg = 'The credential verification code received is invalid.'; |  | ||||||
|         break; |  | ||||||
|       case 'invalid-verification-id': |  | ||||||
|         msg = 'The credential verification ID received is invalid.'; |  | ||||||
|         break; |  | ||||||
|       default: |  | ||||||
|         this.code = 'unknown'; |  | ||||||
|         msg = 'An unknown error occurred.'; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class UpdateEmailFailureFirebase extends UpdateEmailFailureInterface { |  | ||||||
|   UpdateEmailFailureFirebase([String? code, String? msg]) |  | ||||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); |  | ||||||
|   UpdateEmailFailureFirebase.fromCode(String code) : super.fromCode(code) { |  | ||||||
|     switch (code) { |  | ||||||
|       case 'invalid-email': |  | ||||||
|         msg = 'Email is not valid or badly formatted.'; |  | ||||||
|         break; |  | ||||||
|       case 'email-already-in-use': |  | ||||||
|         msg = 'An account already exists for that email.'; |  | ||||||
|         break; |  | ||||||
|       case 'requires-recent-login': |  | ||||||
|         msg = "User's last sign-in time does not meet the security threshold."; |  | ||||||
|         break; |  | ||||||
|       default: |  | ||||||
|         this.code = 'unknown'; |  | ||||||
|         msg = 'An unknown error occurred.'; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class UpdatePasswordFailureFirebase extends UpdatePasswordFailureInterface { |  | ||||||
|   UpdatePasswordFailureFirebase([String? code, String? msg]) |  | ||||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); |  | ||||||
|   UpdatePasswordFailureFirebase.fromCode(String code) : super.fromCode(code) { |  | ||||||
|     switch (code) { |  | ||||||
|       case 'weak-password': |  | ||||||
|         msg = 'Please enter a stronger password.'; |  | ||||||
|         break; |  | ||||||
|       case 'requires-recent-login': |  | ||||||
|         msg = "User's last sign-in time does not meet the security threshold."; |  | ||||||
|         break; |  | ||||||
|       default: |  | ||||||
|         this.code = 'unknown'; |  | ||||||
|         msg = 'An unknown error occurred.'; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -21,7 +21,6 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart'; | |||||||
| class AuthenticationFirebaseDataSourceImpl | class AuthenticationFirebaseDataSourceImpl | ||||||
|     extends AuthenticationRemoteDataSource { |     extends AuthenticationRemoteDataSource { | ||||||
|   final FirebaseAuth _firebaseAuth; |   final FirebaseAuth _firebaseAuth; | ||||||
|   UserCredential? _latestCreds; |  | ||||||
| 
 | 
 | ||||||
|   AuthenticationFirebaseDataSourceImpl({FirebaseAuth? firebaseAuth}) |   AuthenticationFirebaseDataSourceImpl({FirebaseAuth? firebaseAuth}) | ||||||
|       : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance; |       : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance; | ||||||
| @ -52,7 +51,6 @@ class AuthenticationFirebaseDataSourceImpl | |||||||
|         email: email, |         email: email, | ||||||
|         password: password, |         password: password, | ||||||
|       ); |       ); | ||||||
|       _latestCreds = userCredential; |  | ||||||
|       final user = userCredential.user; |       final user = userCredential.user; | ||||||
|       if (user.isNotNull) { |       if (user.isNotNull) { | ||||||
|         return _mapper(user!); |         return _mapper(user!); | ||||||
| @ -78,7 +76,6 @@ class AuthenticationFirebaseDataSourceImpl | |||||||
|         email: email, |         email: email, | ||||||
|         password: password, |         password: password, | ||||||
|       ); |       ); | ||||||
|       _latestCreds = userCredential; |  | ||||||
|       final user = userCredential.user; |       final user = userCredential.user; | ||||||
|       if (user.isNotNull) { |       if (user.isNotNull) { | ||||||
|         return _mapper(user!); |         return _mapper(user!); | ||||||
| @ -95,7 +92,6 @@ class AuthenticationFirebaseDataSourceImpl | |||||||
|   @override |   @override | ||||||
|   Future<void> signOut() async { |   Future<void> signOut() async { | ||||||
|     try { |     try { | ||||||
|       _latestCreds = null; |  | ||||||
|       await _firebaseAuth.signOut(); |       await _firebaseAuth.signOut(); | ||||||
|     } catch (_) { |     } catch (_) { | ||||||
|       throw SignOutFailureFirebase(); |       throw SignOutFailureFirebase(); | ||||||
| @ -168,7 +164,6 @@ class AuthenticationFirebaseDataSourceImpl | |||||||
|   Future<Account> signInAnonymously() async { |   Future<Account> signInAnonymously() async { | ||||||
|     try { |     try { | ||||||
|       final userCredential = await _firebaseAuth.signInAnonymously(); |       final userCredential = await _firebaseAuth.signInAnonymously(); | ||||||
|       _latestCreds = userCredential; |  | ||||||
|       final user = userCredential.user; |       final user = userCredential.user; | ||||||
|       if (user.isNotNull) { |       if (user.isNotNull) { | ||||||
|         return _mapper(user!); |         return _mapper(user!); | ||||||
| @ -204,60 +199,4 @@ class AuthenticationFirebaseDataSourceImpl | |||||||
|       throw RefreshFailureFirebase(); |       throw RefreshFailureFirebase(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Future<Account> reauthenticateWithCredential() async { |  | ||||||
|     try { |  | ||||||
|       if (_latestCreds?.credential != null) { |  | ||||||
|         await _firebaseAuth.currentUser |  | ||||||
|             ?.reauthenticateWithCredential(_latestCreds!.credential!); |  | ||||||
|       } else { |  | ||||||
|         throw Exception(); // Get caught just after. |  | ||||||
|       } |  | ||||||
|       final user = _firebaseAuth.currentUser; |  | ||||||
|       if (user.isNotNull) { |  | ||||||
|         return _mapper(user!); |  | ||||||
|       } else { |  | ||||||
|         throw Exception(); // Get caught just after. |  | ||||||
|       } |  | ||||||
|     } on FirebaseAuthException catch (e) { |  | ||||||
|       throw ReauthenticateFailureFirebase.fromCode(e.code); |  | ||||||
|     } catch (_) { |  | ||||||
|       throw ReauthenticateFailureFirebase(); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Future<Account> updateEmail({required String email}) async { |  | ||||||
|     try { |  | ||||||
|       await _firebaseAuth.currentUser!.updateEmail(email); |  | ||||||
|       final user = _firebaseAuth.currentUser; |  | ||||||
|       if (user.isNotNull) { |  | ||||||
|         return _mapper(user!); |  | ||||||
|       } else { |  | ||||||
|         throw Exception(); // Get caught just after. |  | ||||||
|       } |  | ||||||
|     } on FirebaseAuthException catch (e) { |  | ||||||
|       throw UpdateEmailFailureFirebase.fromCode(e.code); |  | ||||||
|     } catch (_) { |  | ||||||
|       throw UpdateEmailFailureFirebase(); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Future<Account> updatePassword({required String password}) async { |  | ||||||
|     try { |  | ||||||
|       await _firebaseAuth.currentUser!.updatePassword(password); |  | ||||||
|       final user = _firebaseAuth.currentUser; |  | ||||||
|       if (user.isNotNull) { |  | ||||||
|         return _mapper(user!); |  | ||||||
|       } else { |  | ||||||
|         throw Exception(); // Get caught just after. |  | ||||||
|       } |  | ||||||
|     } on FirebaseAuthException catch (e) { |  | ||||||
|       throw UpdatePasswordFailureFirebase.fromCode(e.code); |  | ||||||
|     } catch (_) { |  | ||||||
|       throw UpdatePasswordFailureFirebase(); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart'; | |||||||
| class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { | class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { | ||||||
|   Pair<Account, String>? _connectedMock; |   Pair<Account, String>? _connectedMock; | ||||||
|   Pair<Account, String>? _registeredMock; |   Pair<Account, String>? _registeredMock; | ||||||
|   DateTime _lastSignInTime = DateTime.now(); |  | ||||||
|   final StreamController<Account?> _streamAccount = StreamController() |   final StreamController<Account?> _streamAccount = StreamController() | ||||||
|     ..add(null); |     ..add(null); | ||||||
| 
 | 
 | ||||||
| @ -119,7 +118,6 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { | |||||||
|     ); |     ); | ||||||
|     _streamAccount.add(mock); |     _streamAccount.add(mock); | ||||||
|     _connectedMock = _connectedMock?.copyWith(left: mock); |     _connectedMock = _connectedMock?.copyWith(left: mock); | ||||||
|     _lastSignInTime = DateTime.now(); |  | ||||||
|     return Future.value(mock); |     return Future.value(mock); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -151,7 +149,6 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { | |||||||
|       } |       } | ||||||
|       _streamAccount.add(_registeredMock!.left); |       _streamAccount.add(_registeredMock!.left); | ||||||
|       _connectedMock = _registeredMock!.copyWith(); |       _connectedMock = _registeredMock!.copyWith(); | ||||||
|       _lastSignInTime = DateTime.now(); |  | ||||||
|       return _registeredMock!.left!; |       return _registeredMock!.left!; | ||||||
|     } |     } | ||||||
|     throw SignInWithCredentialFailureFirebase(); |     throw SignInWithCredentialFailureFirebase(); | ||||||
| @ -196,8 +193,6 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { | |||||||
|     ); |     ); | ||||||
|     _streamAccount.add(mock); |     _streamAccount.add(mock); | ||||||
|     _registeredMock = Pair(mock, password); |     _registeredMock = Pair(mock, password); | ||||||
|     _connectedMock = _registeredMock!.copyWith(); |  | ||||||
|     _lastSignInTime = DateTime.now(); |  | ||||||
|     return Future.value(mock); |     return Future.value(mock); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -209,45 +204,4 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { | |||||||
|     await _randomDelay(); |     await _randomDelay(); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Future<Account> reauthenticateWithCredential() async { |  | ||||||
|     await _randomDelay(); |  | ||||||
|     if (_connectedMock.isNull) { |  | ||||||
|       throw ReauthenticateFailureFirebase(); |  | ||||||
|     } |  | ||||||
|     await refresh(); |  | ||||||
|     _lastSignInTime = DateTime.now(); |  | ||||||
|     return Future.value(_connectedMock?.left); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Future<Account> updateEmail({required String email}) { |  | ||||||
|     final before = DateTime.now().subtract(const Duration(seconds: 10)); |  | ||||||
|     if (_lastSignInTime.isBefore(before)) { |  | ||||||
|       throw UpdateEmailFailureFirebase('requires-recent-login'); |  | ||||||
|     } |  | ||||||
|     final refresh = DateTime.now(); |  | ||||||
|     final mock = (_connectedMock?.left as AccountModel?) |  | ||||||
|         ?.copyWith(lastSignInTime: refresh, email: email); |  | ||||||
|     _connectedMock = _connectedMock?.copyWith(left: mock); |  | ||||||
|     _registeredMock = _registeredMock?.copyWith(left: mock); |  | ||||||
|     _streamAccount.add(mock); |  | ||||||
|     return Future.value(_connectedMock?.left); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   Future<Account> updatePassword({required String password}) { |  | ||||||
|     final before = DateTime.now().subtract(const Duration(seconds: 10)); |  | ||||||
|     if (_lastSignInTime.isBefore(before)) { |  | ||||||
|       throw UpdatePasswordFailureFirebase('requires-recent-login'); |  | ||||||
|     } |  | ||||||
|     final refresh = DateTime.now(); |  | ||||||
|     final mock = (_connectedMock?.left as AccountModel?) |  | ||||||
|         ?.copyWith(lastSignInTime: refresh); |  | ||||||
|     _connectedMock = _connectedMock?.copyWith(left: mock, right: password); |  | ||||||
|     _registeredMock = _registeredMock?.copyWith(left: mock, right: password); |  | ||||||
|     _streamAccount.add(mock); |  | ||||||
|     return Future.value(_connectedMock?.left); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -314,38 +314,4 @@ class AuthenticationRepositoryImpl<T extends Object> | |||||||
|         }, |         }, | ||||||
|         (error) => error, |         (error) => error, | ||||||
|       ); |       ); | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   FutureOrResult<Account> reauthenticateWithCredential() => |  | ||||||
|       Result.tryCatchAsync<Account, AppException, AppException>( |  | ||||||
|         () async { |  | ||||||
|           final account = await _authenticationRemoteDataSource |  | ||||||
|               .reauthenticateWithCredential(); |  | ||||||
|           return account; |  | ||||||
|         }, |  | ||||||
|         (error) => error, |  | ||||||
|       ); |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   FutureOrResult<Account> updateEmail({required String email}) => |  | ||||||
|       Result.tryCatchAsync<Account, AppException, AppException>( |  | ||||||
|         () async { |  | ||||||
|           final account = |  | ||||||
|               await _authenticationRemoteDataSource.updateEmail(email: email); |  | ||||||
|           return account; |  | ||||||
|         }, |  | ||||||
|         (error) => error, |  | ||||||
|       ); |  | ||||||
| 
 |  | ||||||
|   @override |  | ||||||
|   FutureOrResult<Account> updatePassword({required String password}) => |  | ||||||
|       Result.tryCatchAsync<Account, AppException, AppException>( |  | ||||||
|         () async { |  | ||||||
|           final account = await _authenticationRemoteDataSource.updatePassword( |  | ||||||
|             password: password, |  | ||||||
|           ); |  | ||||||
|           return account; |  | ||||||
|         }, |  | ||||||
|         (error) => error, |  | ||||||
|       ); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -48,10 +48,4 @@ abstract class AuthenticationRemoteDataSource extends BaseRemoteDataSource { | |||||||
|   Future<bool> verifyPasswordResetCode({required String code}); |   Future<bool> verifyPasswordResetCode({required String code}); | ||||||
| 
 | 
 | ||||||
|   Future<Account> signInAnonymously(); |   Future<Account> signInAnonymously(); | ||||||
| 
 |  | ||||||
|   Future<Account> updateEmail({required String email}); |  | ||||||
| 
 |  | ||||||
|   Future<Account> updatePassword({required String password}); |  | ||||||
| 
 |  | ||||||
|   Future<Account> reauthenticateWithCredential(); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -84,45 +84,12 @@ abstract class AuthenticationRepository<T> extends BaseRepository { | |||||||
|     required String password, |     required String password, | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   /// {@template update_email} |  | ||||||
|   /// Update or add [email]. |  | ||||||
|   /// |  | ||||||
|   /// Throws a UpdateEmailFailureInterface if |  | ||||||
|   /// an exception occurs. |  | ||||||
|   /// {@endtemplate} |  | ||||||
|   FutureOrResult<Account> updateEmail({ |  | ||||||
|     required String email, |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   /// {@template update_password} |  | ||||||
|   /// Update or add [password]. |  | ||||||
|   /// |  | ||||||
|   /// Throws a UpdatePasswordFailureInterface if |  | ||||||
|   /// an exception occurs. |  | ||||||
|   /// {@endtemplate} |  | ||||||
|   FutureOrResult<Account> updatePassword({ |  | ||||||
|     required String password, |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   /// {@template reauthenticate} |  | ||||||
|   /// Some security-sensitive actions—such as deleting an account,  |  | ||||||
|   /// setting a primary email address, and changing a password—require that  |  | ||||||
|   /// the user has recently signed in. |  | ||||||
|   /// |  | ||||||
|   /// Throws a ReauthenticateFailureInterface if |  | ||||||
|   /// an exception occurs. |  | ||||||
|   /// {@endtemplate} |  | ||||||
|   FutureOrResult<Account> reauthenticateWithCredential(); |  | ||||||
| 
 |  | ||||||
|   /// {@template signout} |   /// {@template signout} | ||||||
|   /// Signs out the current user. |   /// Signs out the current user. | ||||||
|   /// It also clears the cache and the associated data. |   /// It also clears the cache and the associated data. | ||||||
|   /// {@endtemplate} |   /// {@endtemplate} | ||||||
|   FutureOrResult<void> signOut(); |   FutureOrResult<void> signOut(); | ||||||
| 
 | 
 | ||||||
|   /// {@template refresh} |  | ||||||
|   /// Refreshes the current user, if signed in. |  | ||||||
|   /// {@endtemplate} |  | ||||||
|   FutureOrResult<void> refresh(); |   FutureOrResult<void> refresh(); | ||||||
| 
 | 
 | ||||||
|   /// {@template stream_account} |   /// {@template stream_account} | ||||||
|  | |||||||
| @ -48,7 +48,7 @@ class InputBuilderTextController<Cubit extends FormDataCubit, S extends String?, | |||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     final formName = context.read<Cubit>().formName; |     final formName = context.watch<Cubit>().formName; | ||||||
|     final value = |     final value = | ||||||
|         context.read<FormRepository>().accessForm(formName).valueOf<S>(field); |         context.read<FormRepository>().accessForm(formName).valueOf<S>(field); | ||||||
|     _controller |     _controller | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user