diff --git a/packages/wyatt_authentication_bloc/example/firebase.json b/packages/wyatt_authentication_bloc/example/firebase.json
index cdcf8e18..c8738c2c 100644
--- a/packages/wyatt_authentication_bloc/example/firebase.json
+++ b/packages/wyatt_authentication_bloc/example/firebase.json
@@ -8,6 +8,7 @@
},
"ui": {
"enabled": true
- }
+ },
+ "singleProjectMode": true
}
}
diff --git a/packages/wyatt_authentication_bloc/example/ios/Runner.xcodeproj/project.pbxproj b/packages/wyatt_authentication_bloc/example/ios/Runner.xcodeproj/project.pbxproj
index 11d0d0ad..85497888 100644
--- a/packages/wyatt_authentication_bloc/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/wyatt_authentication_bloc/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 50;
+ objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -200,6 +200,7 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@@ -236,6 +237,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
diff --git a/packages/wyatt_authentication_bloc/example/lib/bootstrap.dart b/packages/wyatt_authentication_bloc/example/lib/bootstrap.dart
index 8cf305fd..05ee6358 100644
--- a/packages/wyatt_authentication_bloc/example/lib/bootstrap.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/bootstrap.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/core/constants/form_field.dart b/packages/wyatt_authentication_bloc/example/lib/core/constants/form_field.dart
index 917131da..d111abaf 100644
--- a/packages/wyatt_authentication_bloc/example/lib/core/constants/form_field.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/core/constants/form_field.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/core/constants/form_name.dart b/packages/wyatt_authentication_bloc/example/lib/core/constants/form_name.dart
index b41b7335..1ff68488 100644
--- a/packages/wyatt_authentication_bloc/example/lib/core/constants/form_name.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/core/constants/form_name.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/core/dependency_injection/get_it.dart b/packages/wyatt_authentication_bloc/example/lib/core/dependency_injection/get_it.dart
index 2528fa87..1490523f 100644
--- a/packages/wyatt_authentication_bloc/example/lib/core/dependency_injection/get_it.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/core/dependency_injection/get_it.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,49 +14,20 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-import 'package:example_router/bootstrap.dart';
import 'package:example_router/firebase_options.dart';
import 'package:get_it/get_it.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
-import 'package:wyatt_type_utils/wyatt_type_utils.dart';
final getIt = GetIt.I;
abstract class GetItInitializer {
static Future init() async {
- getIt
- ..registerLazySingleton(
- MockSettings.isEnable()
- ? () => AuthenticationMockDataSourceImpl(registeredAccounts: [
- Pair(
- AccountModel(
- uid: '1',
- emailVerified: true,
- isAnonymous: false,
- providerId: 'wyatt',
- email: 'toto@test.fr',
- ),
- 'toto1234',
- ),
- Pair(
- AccountModel(
- uid: '2',
- emailVerified: false,
- isAnonymous: false,
- providerId: 'wyatt',
- email: 'tata@test.fr',
- ),
- 'tata1234',
- ),
- ])
- : () => AuthenticationFirebaseDataSourceImpl(
- firebaseAuth: FirebaseAuth.instance,
- googleSignIn: GoogleSignIn(
- clientId: DefaultFirebaseOptions.ios.iosClientId)),
- )
- ..registerLazySingleton>(
- () => AuthenticationCacheDataSourceImpl(),
- );
+ getIt.registerLazySingleton>(
+ () => AuthenticationFirebaseDataSourceImpl(
+ firebaseAuth: FirebaseAuth.instance,
+ googleSignIn:
+ GoogleSignIn(clientId: DefaultFirebaseOptions.ios.iosClientId)),
+ );
await getIt.allReady();
}
diff --git a/packages/wyatt_authentication_bloc/example/lib/core/routes/router.dart b/packages/wyatt_authentication_bloc/example/lib/core/routes/router.dart
index 657d3917..51297a01 100644
--- a/packages/wyatt_authentication_bloc/example/lib/core/routes/router.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/core/routes/router.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-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/sign_in/sign_in_page.dart';
import 'package:example_router/presentation/features/sign_up/sign_up_page.dart';
@@ -83,14 +82,5 @@ class AppRouter {
const SubPage(),
),
),
- GoRoute(
- path: '/home/edit',
- name: EditProfilePage.pageName,
- pageBuilder: (context, state) => defaultTransition(
- context,
- state,
- const EditProfilePage(),
- ),
- ),
];
}
diff --git a/packages/wyatt_authentication_bloc/example/lib/core/utils/app_bloc_observer.dart b/packages/wyatt_authentication_bloc/example/lib/core/utils/app_bloc_observer.dart
index 1a25acfd..abc209cb 100644
--- a/packages/wyatt_authentication_bloc/example/lib/core/utils/app_bloc_observer.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/core/utils/app_bloc_observer.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/core/utils/custom_password.dart b/packages/wyatt_authentication_bloc/example/lib/core/utils/custom_password.dart
index d80b6d3e..a7e1c7c8 100644
--- a/packages/wyatt_authentication_bloc/example/lib/core/utils/custom_password.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/core/utils/custom_password.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/core/utils/forms.dart b/packages/wyatt_authentication_bloc/example/lib/core/utils/forms.dart
index abfc6857..49fdfa9a 100644
--- a/packages/wyatt_authentication_bloc/example/lib/core/utils/forms.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/core/utils/forms.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/main.dart b/packages/wyatt_authentication_bloc/example/lib/main.dart
index ddc4cb52..a7967932 100644
--- a/packages/wyatt_authentication_bloc/example/lib/main.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/main.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/main_firebase.dart b/packages/wyatt_authentication_bloc/example/lib/main_firebase.dart
index d53f0050..62ee35ec 100644
--- a/packages/wyatt_authentication_bloc/example/lib/main_firebase.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/main_firebase.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/app/app.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/app/app.dart
index 9fa89f49..1264aa73 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/app/app.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/app/app.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -15,41 +15,39 @@
// along with this program. If not, see .
import 'dart:async';
-import 'dart:math';
import 'package:example_router/core/constants/form_field.dart';
import 'package:example_router/core/dependency_injection/get_it.dart';
import 'package:example_router/core/routes/router.dart';
import 'package:example_router/core/utils/custom_password.dart';
import 'package:example_router/core/utils/forms.dart';
+import 'package:example_router/presentation/features/authentication/authentication_cubit.dart';
+import 'package:example_router/presentation/features/sign_in/blocs/custom_sign_in_cubit.dart';
import 'package:example_router/presentation/features/sign_up/blocs/custom_sign_up_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
-import 'package:wyatt_architecture/wyatt_architecture.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';
-FutureOrResult onAccountChanges(
- AuthenticationRepository repo,
- AuthChangeEvent? authEvent,
-) async {
- final id = Random().nextInt(1000);
- final token =
- await repo.getIdentityToken().fold((value) => value, (error) => 'null');
+// FutureOrResult onAccountChanges(
+// AuthenticationRepository repo,
+// AuthChangeEvent? authEvent,
+// ) async {
+// final id = Random().nextInt(1000);
+// final token =
+// await repo.getIdentityToken().fold((value) => value, (error) => 'null');
- debugPrint(
- 'onAccountChanges: ${authEvent?.account}, type: ${authEvent.runtimeType}, token: $token, generatedId: $id');
- return Ok(id);
-}
+// debugPrint(
+// 'onAccountChanges: ${authEvent?.account}, type: ${authEvent.runtimeType}, token: $token, generatedId: $id');
+// return Ok(id);
+// }
class App extends StatelessWidget {
final AuthenticationRepository authenticationRepository =
AuthenticationRepositoryImpl(
- authenticationCacheDataSource: getIt>(),
- authenticationRemoteDataSource: getIt(),
- onAuthChange: onAccountChanges,
+ authenticationRemoteDataSource:
+ getIt>(),
customPasswordValidator: const CustomPassword.pure(),
extraSignUpInputs: [
FormInput(
@@ -66,8 +64,7 @@ class App extends StatelessWidget {
Widget build(BuildContext context) {
AuthenticationState? previous;
- final AuthenticationCubit authenticationCubit =
- AuthenticationCubit(authenticationRepository: authenticationRepository);
+ final AuthenticationCubit authenticationCubit = ExampleAuthenticationCubit(authenticationRepository: authenticationRepository);
final GoRouter router = GoRouter(
initialLocation: '/',
@@ -119,7 +116,7 @@ class App extends StatelessWidget {
),
),
BlocProvider>(
- create: (_) => SignInCubit(
+ create: (_) => CustomSignInCubit(
authenticationRepository: authenticationRepository,
),
),
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/local/authentication_cache_data_source_impl.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/authentication/authentication_cubit.dart
similarity index 50%
rename from packages/wyatt_authentication_bloc/lib/src/data/data_sources/local/authentication_cache_data_source_impl.dart
rename to packages/wyatt_authentication_bloc/example/lib/presentation/features/authentication/authentication_cubit.dart
index abcb673a..869be269 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/local/authentication_cache_data_source_impl.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/authentication/authentication_cubit.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -18,49 +18,35 @@ import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
-class AuthenticationCacheDataSourceImpl
- extends AuthenticationCacheDataSource {
- AuthenticationCacheDataSourceImpl();
- Account? _account;
- T? _data;
+class ExampleAuthenticationCubit extends AuthenticationCubit {
+ ExampleAuthenticationCubit({required super.authenticationRepository});
@override
- Future storeAccount(Account? account) async {
- _account = account;
+ FutureOrResult onReauthenticate(
+ Result result) async {
+ print('onReauthenticate');
+
+ return const Ok(1);
}
@override
- Future storeData(T? data) async {
- _data = data;
+ FutureOrResult onRefresh(Result result) {
+ print('onRefresh');
+
+ return const Ok(1);
}
@override
- Future loadAccount() async {
- if (_account.isNotNull) {
- return _account!;
- }
- throw ClientException('Cached account is invalid');
+ FutureOrResult onSignInFromCache(SessionWrapper wrapper) {
+ print('onSignInFromCache');
+
+ return const Ok(1);
}
@override
- Future loadData() async {
- if (_data.isNotNull) {
- return _data!;
- }
- throw ClientException('Cached data is invalid');
- }
+ FutureOrResult onSignOut() {
+ print('onSignOut');
- @override
- Future destroy() async {
- _data = null;
- _account = null;
- }
-
- @override
- Future> load() async {
- if (_account.isNull) {
- throw ClientException('Cached account is invalid');
- }
- return AccountWrapperModel(_account, _data);
+ return const Ok(null);
}
}
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/blocs/edit_profile_cubit.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/blocs/edit_profile_cubit.dart
deleted file mode 100644
index c92aa597..00000000
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/blocs/edit_profile_cubit.dart
+++ /dev/null
@@ -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 .
-
-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 authenticationRepository;
-
- EditProfileCubit(
- super._formRepository,
- super._formName, {
- required this.authenticationRepository,
- }) : super();
-
- @override
- Future submit() async {
- emit(
- state.copyWith(
- status: FormStatus.submissionInProgress,
- ),
- );
- final user = (await authenticationRepository.getAccount()).ok;
-
- final form = state.form;
- final email = form.valueOf(AuthFormField.email);
- final oldPassword = form.valueOf(AppFormField.oldPassword);
- final newPassword = form.valueOf(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));
- }
-}
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/edit_profile_page.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/edit_profile_page.dart
deleted file mode 100644
index a557d338..00000000
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/edit_profile_page.dart
+++ /dev/null
@@ -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 .
-
-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(
- create: (context) => EditProfileCubit(
- context.read(),
- AppFormName.editProfile,
- authenticationRepository:
- context.read>(),
- )..dataChanged(
- AuthFormField.email,
- Email.dirty(
- context
- .read>()
- .state
- .accountWrapper
- ?.account
- ?.email ??
- '',
- ),
- ),
- child: const EditProfileForm(),
- ),
- ),
- ),
- );
- }
-}
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/widgets/edit_profile_form.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/widgets/edit_profile_form.dart
deleted file mode 100644
index 726e51a4..00000000
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/edit_profile/widgets/edit_profile_form.dart
+++ /dev/null
@@ -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 .
-
-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(
- field: AuthFormField.email,
- builder: ((context, cubit, state, field, input, controller, extra) {
- return TextField(
- onChanged: (email) => cubit.dataChanged(
- 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(
- field: AppFormField.oldPassword,
- builder: ((context, cubit, state, field, input) {
- return TextField(
- onChanged: (pwd) => cubit.dataChanged(
- 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(
- field: AuthFormField.password,
- builder: ((context, cubit, state, field, input) {
- return TextField(
- onChanged: (pwd) => cubit.dataChanged(
- 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(
- 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(
- 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(),
- ],
- ),
- ),
- );
- }
-}
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/home/home_page.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/home/home_page.dart
index a015690b..a66a38a0 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/home/home_page.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/home/home_page.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-import 'package:example_router/presentation/features/edit_profile/edit_profile_page.dart';
import 'package:example_router/presentation/features/sub/sub_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -30,7 +29,7 @@ class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
- title: const Text('Home'),
+ title: Text('Home | ${context.account, int>()?.email}'),
actions: [
IconButton(
onPressed: () =>
@@ -44,8 +43,8 @@ class HomePage extends StatelessWidget {
child: Column(
children: [
AuthenticationBuilder(
- authenticated: (context, accountWrapper) => Text(
- 'Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'),
+ authenticated: (context, sessionWrapper) => Text(
+ 'Logged as ${sessionWrapper.session?.account.email} | GeneratedId is ${sessionWrapper.session?.data}'),
unauthenticated: (context) =>
const Text('Not logged (unauthenticated)'),
unknown: (context) => const Text('Not logged (unknown)'),
@@ -57,10 +56,10 @@ class HomePage extends StatelessWidget {
onPressed: () => context.pushNamed(SubPage.pageName),
child: const Text('Go to sub page'),
),
- ElevatedButton(
- onPressed: () => context.pushNamed(EditProfilePage.pageName),
- child: const Text('Go to edit profile page'),
- ),
+ // ElevatedButton(
+ // onPressed: () => context.pushNamed(EditProfilePage.pageName),
+ // child: const Text('Go to edit profile page'),
+ // ),
],
),
),
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/blocs/custom_sign_in_cubit.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/blocs/custom_sign_in_cubit.dart
new file mode 100644
index 00000000..882cfd35
--- /dev/null
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/blocs/custom_sign_in_cubit.dart
@@ -0,0 +1,48 @@
+// Copyright (C) 2023 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 .
+
+import 'package:wyatt_architecture/src/domain/usecases/usecase.dart';
+import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart';
+import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
+import 'package:wyatt_type_utils/src/either/either_base.dart';
+import 'package:wyatt_form_bloc/src/domain/form/wyatt_form.dart';
+
+class CustomSignInCubit extends SignInCubit {
+ CustomSignInCubit({
+ required super.authenticationRepository,
+ });
+
+ @override
+ FutureOrResult onSignInWithEmailAndPassword(Result result, WyattForm form) {
+ print('onSignInWithEmailAndPassword');
+
+ return const Ok(1);
+ }
+
+ @override
+ FutureOrResult onSignInAnonymously(Result result, WyattForm form) {
+ print('onSignInAnonymously');
+
+ return const Ok(1);
+ }
+
+ @override
+ FutureOrResult onSignInWithGoogle(Result result, WyattForm form) {
+ print('onSignInWithGoogle');
+
+ return const Ok(1);
+ }
+}
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/sign_in_page.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/sign_in_page.dart
index 19dfd0b6..5ac3770b 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/sign_in_page.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/sign_in_page.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/widgets/sign_in_form.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/widgets/sign_in_form.dart
index f0e1dfa9..bf39991c 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/widgets/sign_in_form.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_in/widgets/sign_in_form.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/blocs/custom_sign_up_cubit.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/blocs/custom_sign_up_cubit.dart
index 7e5f1e6d..d49e6056 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/blocs/custom_sign_up_cubit.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/blocs/custom_sign_up_cubit.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,33 +14,34 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-import 'dart:async';
-import 'package:example_router/core/constants/form_field.dart';
-import 'package:flutter/foundation.dart';
import 'package:wyatt_architecture/wyatt_architecture.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 CustomSignUpCubit extends SignUpCubit{
+class CustomSignUpCubit extends SignUpCubit {
CustomSignUpCubit({
required super.authenticationRepository,
});
-
+
@override
- FutureOrResult onSignUpWithEmailAndPassword(
- Result result, WyattForm form) async {
- if (result.isOk) {
- await Future.delayed(const Duration(seconds: 3));
- const id = -1;
- final confirmedPassword =
- form.valueOf(AppFormField.confirmedPassword);
+ FutureOrResult onSignUpWithEmailAndPassword(Result result, WyattForm form) async {
+ // if (result.isOk) {
+ // await Future.delayed(const Duration(seconds: 3));
+ // const id = -1;
+ // final confirmedPassword =
+ // form.valueOf(AppFormField.confirmedPassword);
- debugPrint(
- 'onSignUpSuccess: ${result.ok}, generatedId: $id, intFormData: $confirmedPassword');
- return const Ok(id);
- }
- return const Ok(null);
+ // debugPrint(
+ // 'onSignUpSuccess: ${result.ok}, generatedId: $id, intFormData: $confirmedPassword');
+ // return const Ok(id);
+ // }
+ // return const Ok(null);
+ print('onSignUpWithEmailAndPassword');
+
+ return const Ok(1);
}
+
+
}
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/sign_up_page.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/sign_up_page.dart
index ff232348..2f0f6ce5 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/sign_up_page.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/sign_up_page.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/widgets/sign_up_form.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/widgets/sign_up_form.dart
index a4f44a48..23b9884d 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/widgets/sign_up_form.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sign_up/widgets/sign_up_form.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sub/sub_page.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sub/sub_page.dart
index a5c8a6b6..9cdfad53 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/sub/sub_page.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/sub/sub_page.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/example/lib/presentation/features/welcome/welcome_page.dart b/packages/wyatt_authentication_bloc/example/lib/presentation/features/welcome/welcome_page.dart
index 10d5c0cc..29e97aa4 100644
--- a/packages/wyatt_authentication_bloc/example/lib/presentation/features/welcome/welcome_page.dart
+++ b/packages/wyatt_authentication_bloc/example/lib/presentation/features/welcome/welcome_page.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/constants/form_field.dart b/packages/wyatt_authentication_bloc/lib/src/core/constants/form_field.dart
index 295cfc2f..aa1ed36a 100644
--- a/packages/wyatt_authentication_bloc/lib/src/core/constants/form_field.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/core/constants/form_field.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+/// Default authentication form fields name
abstract class AuthFormField {
+ /// Email field: `wyattEmailField`
static const email = 'wyattEmailField';
+ /// Password field: `wyattPasswordField`
static const password = 'wyattPasswordField';
}
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/constants/form_name.dart b/packages/wyatt_authentication_bloc/lib/src/core/constants/form_name.dart
index af623e70..3eca89e0 100644
--- a/packages/wyatt_authentication_bloc/lib/src/core/constants/form_name.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/core/constants/form_name.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,8 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+/// Default authentication form name
abstract class AuthFormName {
+ /// Sign Up form: `wyattSignUpForm`
static const String signUpForm = 'wyattSignUpForm';
+ /// Sign In form: `wyattSignInForm`
static const String signInForm = 'wyattSignInForm';
+ /// Password reset form: `wyattPasswordResetForm`
static const String passwordResetForm = 'wyattPasswordResetForm';
}
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/core.dart b/packages/wyatt_authentication_bloc/lib/src/core/core.dart
index 2d4165fc..da22baa1 100644
--- a/packages/wyatt_authentication_bloc/lib/src/core/core.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/core/core.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -18,3 +18,5 @@ export 'constants/form_field.dart';
export 'constants/form_name.dart';
export 'enums/enums.dart';
export 'exceptions/exceptions.dart';
+export 'extensions/build_context_extension.dart';
+export 'utils/custom_routine.dart';
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/enums/authentication_status.dart b/packages/wyatt_authentication_bloc/lib/src/core/enums/authentication_status.dart
index 11386588..b88a7407 100644
--- a/packages/wyatt_authentication_bloc/lib/src/core/enums/authentication_status.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/core/enums/authentication_status.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,8 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+/// Different authentication status
enum AuthenticationStatus {
+ /// At the application launch.
unknown,
+ /// When the user is logged
authenticated,
+ /// When the user is not logged
unauthenticated,
}
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/enums/enums.dart b/packages/wyatt_authentication_bloc/lib/src/core/enums/enums.dart
index db37d714..de021091 100644
--- a/packages/wyatt_authentication_bloc/lib/src/core/enums/enums.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/core/enums/enums.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions.dart b/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions.dart
index f60c915e..e10faebe 100644
--- a/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -18,6 +18,7 @@ import 'package:wyatt_architecture/wyatt_architecture.dart';
part 'exceptions_firebase.dart';
+/// Base exception used in Wyatt Authentication
abstract class AuthenticationFailureInterface extends AppException
implements Exception {
AuthenticationFailureInterface(this.code, this.msg);
@@ -249,13 +250,9 @@ abstract class SignOutFailureInterface extends AuthenticationFailureInterface {
SignOutFailureInterface.fromCode(super.code) : super.fromCode();
}
-abstract class GetIdTokenFailureInterface
- extends AuthenticationFailureInterface {
- GetIdTokenFailureInterface(super.code, super.msg);
-
- GetIdTokenFailureInterface.fromCode(super.code) : super.fromCode();
-}
-
+/// {@template reauthenticate_failure}
+/// Thrown during the reauthentication process if a failure occurs.
+/// {@endtemplate}
abstract class ReauthenticateFailureInterface
extends AuthenticationFailureInterface {
ReauthenticateFailureInterface(super.code, super.msg);
@@ -263,6 +260,9 @@ abstract class ReauthenticateFailureInterface
ReauthenticateFailureInterface.fromCode(super.code) : super.fromCode();
}
+/// {@template update_email_failure}
+/// Thrown during the email modification process if a failure occurs.
+/// {@endtemplate}
abstract class UpdateEmailFailureInterface
extends AuthenticationFailureInterface {
UpdateEmailFailureInterface(super.code, super.msg);
@@ -270,6 +270,9 @@ abstract class UpdateEmailFailureInterface
UpdateEmailFailureInterface.fromCode(super.code) : super.fromCode();
}
+/// {@template update_password_failure}
+/// Thrown during the password modification process if a failure occurs.
+/// {@endtemplate}
abstract class UpdatePasswordFailureInterface
extends AuthenticationFailureInterface {
UpdatePasswordFailureInterface(super.code, super.msg);
@@ -277,9 +280,22 @@ abstract class UpdatePasswordFailureInterface
UpdatePasswordFailureInterface.fromCode(super.code) : super.fromCode();
}
+/// {@template model_parsing_failure}
+/// Thrown during the model parsing process if a failure occurs.
+/// {@endtemplate}
abstract class ModelParsingFailureInterface
extends AuthenticationFailureInterface {
ModelParsingFailureInterface(super.code, super.msg);
ModelParsingFailureInterface.fromCode(super.code) : super.fromCode();
}
+
+/// {@template delete_account_failure}
+/// Thrown during the account deletion if a failure occurs.
+/// {@endtemplate}
+abstract class DeleteAccountFailureInterface
+ extends AuthenticationFailureInterface {
+ DeleteAccountFailureInterface(super.code, super.msg);
+
+ DeleteAccountFailureInterface.fromCode(super.code) : super.fromCode();
+}
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions_firebase.dart b/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions_firebase.dart
index 58e3c409..7b17e606 100644
--- a/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions_firebase.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/core/exceptions/exceptions_firebase.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
part of 'exceptions.dart';
+/// {@macro apply_action_code_failure}
class ApplyActionCodeFailureFirebase extends ApplyActionCodeFailureInterface {
ApplyActionCodeFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
@@ -41,6 +42,7 @@ class ApplyActionCodeFailureFirebase extends ApplyActionCodeFailureInterface {
}
}
+/// {@macro sign_up_with_email_and_password_failure}
class SignUpWithEmailAndPasswordFailureFirebase
extends SignUpWithEmailAndPasswordFailureInterface {
SignUpWithEmailAndPasswordFailureFirebase([String? code, String? msg])
@@ -70,6 +72,7 @@ class SignUpWithEmailAndPasswordFailureFirebase
}
}
+/// {@macro fetch_sign_in_methods_failure}
class FetchSignInMethodsForEmailFailureFirebase
extends FetchSignInMethodsForEmailFailureInterface {
FetchSignInMethodsForEmailFailureFirebase([String? code, String? msg])
@@ -87,6 +90,7 @@ class FetchSignInMethodsForEmailFailureFirebase
}
}
+/// {@macro sign_in_anonymously_failure}
class SignInAnonymouslyFailureFirebase
extends SignInAnonymouslyFailureInterface {
SignInAnonymouslyFailureFirebase([String? code, String? msg])
@@ -104,6 +108,7 @@ class SignInAnonymouslyFailureFirebase
}
}
+/// {@macro sign_in_with_credential_failure}
class SignInWithCredentialFailureFirebase
extends SignInWithCredentialFailureInterface {
SignInWithCredentialFailureFirebase([String? code, String? msg])
@@ -142,6 +147,7 @@ class SignInWithCredentialFailureFirebase
}
}
+/// {@macro sign_in_with_google_failure}
class SignInWithGoogleFailureFirebase
extends SignInWithCredentialFailureFirebase
implements SignInWithGoogleFailureInterface {
@@ -149,6 +155,7 @@ class SignInWithGoogleFailureFirebase
SignInWithGoogleFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro sign_in_with_facebook_failure}
class SignInWithFacebookFailureFirebase
extends SignInWithCredentialFailureFirebase
implements SignInWithFacebookFailureInterface {
@@ -156,12 +163,14 @@ class SignInWithFacebookFailureFirebase
SignInWithFacebookFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro sign_in_with_apple_failure}
class SignInWithAppleFailureFirebase extends SignInWithCredentialFailureFirebase
implements SignInWithAppleFailureInterface {
SignInWithAppleFailureFirebase([super.code, super.msg]);
SignInWithAppleFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro sign_in_with_twitter_failure}
class SignInWithTwitterFailureFirebase
extends SignInWithCredentialFailureFirebase
implements SignInWithAppleFailureInterface {
@@ -169,6 +178,7 @@ class SignInWithTwitterFailureFirebase
SignInWithTwitterFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro sign_in_with_email_link_failure}
class SignInWithEmailLinkFailureFirebase
extends SignInWithEmailLinkFailureInterface {
SignInWithEmailLinkFailureFirebase([String? code, String? msg])
@@ -192,6 +202,7 @@ class SignInWithEmailLinkFailureFirebase
}
}
+/// {@macro sign_in_with_email_and_password_failure}
class SignInWithEmailAndPasswordFailureFirebase
extends SignInWithEmailAndPasswordFailureInterface {
SignInWithEmailAndPasswordFailureFirebase([String? code, String? msg])
@@ -218,6 +229,7 @@ class SignInWithEmailAndPasswordFailureFirebase
}
}
+/// {@macro send_email_verification_failure}
class SendEmailVerificationFailureFirebase
extends SendEmailVerificationFailureInterface {
SendEmailVerificationFailureFirebase([String? code, String? msg])
@@ -226,6 +238,7 @@ class SendEmailVerificationFailureFirebase
SendEmailVerificationFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro send_password_reset_email_failure}
class SendPasswordResetEmailFailureFirebase
extends SendPasswordResetEmailFailureInterface {
SendPasswordResetEmailFailureFirebase([String? code, String? msg])
@@ -233,6 +246,7 @@ class SendPasswordResetEmailFailureFirebase
SendPasswordResetEmailFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro send_sign_in_link_email_failure}
class SendSignInLinkEmailFailureFirebase
extends SendSignInLinkEmailFailureInterface {
SendSignInLinkEmailFailureFirebase([String? code, String? msg])
@@ -241,6 +255,7 @@ class SendSignInLinkEmailFailureFirebase
SendSignInLinkEmailFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro confirm_password_reset_failure}
class ConfirmPasswordResetFailureFirebase
extends ConfirmPasswordResetFailureInterface {
ConfirmPasswordResetFailureFirebase([String? code, String? msg])
@@ -249,6 +264,7 @@ class ConfirmPasswordResetFailureFirebase
ConfirmPasswordResetFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro verify_password_reset_code_failure}
class VerifyPasswordResetCodeFailureFirebase
extends VerifyPasswordResetCodeFailureInterface {
VerifyPasswordResetCodeFailureFirebase([String? code, String? msg])
@@ -258,12 +274,14 @@ class VerifyPasswordResetCodeFailureFirebase
: super.fromCode();
}
+/// {@macro refresh_failure}
class RefreshFailureFirebase extends RefreshFailureInterface {
RefreshFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
RefreshFailureFirebase.fromCode(super.code) : super.fromCode();
}
+/// {@macro sign_out_failure}
class SignOutFailureFirebase extends SignOutFailureInterface {
SignOutFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
@@ -271,13 +289,7 @@ class SignOutFailureFirebase extends SignOutFailureInterface {
SignOutFailureFirebase.fromCode(super.code) : super.fromCode();
}
-class GetIdTokenFailureFirebase extends GetIdTokenFailureInterface {
- GetIdTokenFailureFirebase([String? code, String? msg])
- : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
-
- GetIdTokenFailureFirebase.fromCode(super.code) : super.fromCode();
-}
-
+/// {@macro reauthenticate_failure}
class ReauthenticateFailureFirebase extends ReauthenticateFailureInterface {
ReauthenticateFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
@@ -311,6 +323,7 @@ class ReauthenticateFailureFirebase extends ReauthenticateFailureInterface {
}
}
+/// {@macro update_email_failure}
class UpdateEmailFailureFirebase extends UpdateEmailFailureInterface {
UpdateEmailFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
@@ -332,6 +345,7 @@ class UpdateEmailFailureFirebase extends UpdateEmailFailureInterface {
}
}
+/// {@macro update_password_failure}
class UpdatePasswordFailureFirebase extends UpdatePasswordFailureInterface {
UpdatePasswordFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
@@ -350,9 +364,27 @@ class UpdatePasswordFailureFirebase extends UpdatePasswordFailureInterface {
}
}
+/// {@macro model_parsing_failure}
class ModelParsingFailureFirebase extends ModelParsingFailureInterface {
ModelParsingFailureFirebase([String? code, String? msg])
: super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
ModelParsingFailureFirebase.fromCode(super.code) : super.fromCode();
}
+
+/// {@macro delete_account_failure}
+class DeleteAccountFailureFirebase extends DeleteAccountFailureInterface {
+ DeleteAccountFailureFirebase([String? code, String? msg])
+ : super(code ?? 'unknown', msg ?? 'An unknown error occurred.');
+
+ DeleteAccountFailureFirebase.fromCode(String code) : super.fromCode(code) {
+ switch (code) {
+ 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.';
+ }
+ }
+}
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/extensions/build_context_extension.dart b/packages/wyatt_authentication_bloc/lib/src/core/extensions/build_context_extension.dart
new file mode 100644
index 00000000..c7753da4
--- /dev/null
+++ b/packages/wyatt_authentication_bloc/lib/src/core/extensions/build_context_extension.dart
@@ -0,0 +1,42 @@
+// Copyright (C) 2023 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 .
+
+import 'package:flutter/widgets.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/session.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/session_wrapper.dart';
+import 'package:wyatt_authentication_bloc/src/features/authentication/cubit/authentication_cubit.dart';
+
+/// Extension that helps to quickly access useful resources like wrapper,
+/// session, account or data.
+extension BuildContextExtension on BuildContext {
+ /// Returns session wrapper
+ SessionWrapper? wrapper, Data>() =>
+ watch().currentSession();
+
+ /// Returns session
+ Session? session, Data>() =>
+ watch().currentSession()?.session;
+
+ /// Returns account
+ Account? account, Data>() =>
+ watch().currentSession()?.session?.account;
+
+ /// Returns associated data
+ Data? data, Data>() =>
+ watch().currentSession()?.session?.data;
+}
diff --git a/packages/wyatt_authentication_bloc/lib/src/core/utils/custom_routine.dart b/packages/wyatt_authentication_bloc/lib/src/core/utils/custom_routine.dart
new file mode 100644
index 00000000..db8b4265
--- /dev/null
+++ b/packages/wyatt_authentication_bloc/lib/src/core/utils/custom_routine.dart
@@ -0,0 +1,62 @@
+// ignore_for_file: public_member_api_docs, sort_constructors_first
+// Copyright (C) 2023 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 .
+
+import 'dart:async';
+
+import 'package:wyatt_architecture/wyatt_architecture.dart';
+import 'package:wyatt_type_utils/wyatt_type_utils.dart';
+
+/// Calls on each cubit action of this package.
+///
+/// Useful to register custom logic on pre-implemented logic.
+class CustomRoutine {
+ const CustomRoutine({
+ required this.routine,
+ required this.attachedLogic,
+ required this.onError,
+ required this.onSuccess,
+ });
+
+ final FutureOr> Function() routine;
+ final FutureOr> Function(
+ Result routineResult,
+ ) attachedLogic;
+ final void Function(AppException? exception) onError;
+ final void Function(R result, Data? data) onSuccess;
+
+ FutureOr call() async {
+ final result = await routine.call();
+
+ // Call custom logic
+ final customRoutineResult = await attachedLogic.call(result);
+
+ // Check for errors
+ if (result.isErr) {
+ onError.call(result.err);
+
+ return;
+ }
+ if (customRoutineResult.isErr) {
+ onError.call(customRoutineResult.err);
+
+ return;
+ }
+
+ // If no error
+ return onSuccess.call(result.ok as Input, customRoutineResult.ok);
+ }
+}
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/data.dart b/packages/wyatt_authentication_bloc/lib/src/data/data.dart
index 35d3fdd1..581cd9c5 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/data.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/data/data.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/data_sources.dart b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/data_sources.dart
index 24eff56f..65cebddf 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/data_sources.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/data_sources.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,6 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-export 'local/authentication_cache_data_source_impl.dart';
export 'remote/authentication_firebase_data_source_impl.dart';
-export 'remote/authentication_mock_data_source_impl.dart';
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart
index 5bc23a2d..2d75d36a 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -16,33 +16,109 @@
import 'dart:async';
+import 'package:firebase_auth/firebase_auth.dart';
+import 'package:google_sign_in/google_sign_in.dart';
import 'package:rxdart/subjects.dart';
-import 'package:wyatt_authentication_bloc/src/data/models/account_model_firebase.dart';
-import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
+import 'package:wyatt_authentication_bloc/src/core/exceptions/exceptions.dart';
+import 'package:wyatt_authentication_bloc/src/data/models/models.dart';
+import 'package:wyatt_authentication_bloc/src/domain/data_sources/remote/authentication_remote_data_source.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/authentication_change_event/authentication_change_event.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/session_wrapper.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
-class AuthenticationFirebaseDataSourceImpl
- extends AuthenticationRemoteDataSource {
+class AuthenticationFirebaseDataSourceImpl
+ extends AuthenticationRemoteDataSource {
AuthenticationFirebaseDataSourceImpl({
FirebaseAuth? firebaseAuth,
GoogleSignIn? googleSignIn,
}) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
_googleSignIn = googleSignIn ?? GoogleSignIn() {
- // _accountStream = StreamController();
- _accountStream = BehaviorSubject();
+ _latestCredentials = BehaviorSubject();
+ _sessionStream = BehaviorSubject();
+
// Check for account in memory (persistence)
- final currentAccount = (_firebaseAuth.currentUser != null)
- ? AccountModelFirebase.fromFirebaseUser(_firebaseAuth.currentUser)
- : null;
- _accountStream.add(currentAccount);
+ _checkForCachedAccount();
}
- late StreamController _accountStream;
+ late StreamController> _sessionStream;
+ late StreamController _latestCredentials;
final FirebaseAuth _firebaseAuth;
final GoogleSignIn _googleSignIn;
- UserCredential? _latestCreds;
+ Future _checkForCachedAccount() async {
+ final currentUser = _firebaseAuth.currentUser;
+
+ if (currentUser == null) {
+ _sessionStream
+ .add(const SessionWrapper(event: UnknownAuthenticationEvent()));
+ return;
+ }
+
+ final jwt = await currentUser.getIdToken(true);
+ final currentAccount = AccountModel.fromFirebaseUser(
+ currentUser,
+ accessToken: jwt,
+ );
+ _sessionStream.add(
+ SessionWrapper(event: SignedInFromCacheEvent(account: currentAccount)),
+ );
+ return;
+ }
+
+ Account _addToStream(
+ UserCredential userCredential,
+ AuthenticationChangeEvent Function(Account account) eventBuilder,
+ ) {
+ final account = AccountModel.fromFirebaseUserCredential(userCredential);
+
+ _latestCredentials.add(userCredential);
+
+ return account;
+ }
+
+ // Stream related methods ===================================================
+
+ /// {@macro add_session}
+ @override
+ void addSession(SessionWrapper wrapper) {
+ _sessionStream.add(wrapper);
+ }
+
+ /// {@macro session_stream}
+ @override
+ Stream> sessionStream() =>
+ _sessionStream.stream.asBroadcastStream();
+
+ // SignUp/SignIn methods ====================================================
+
+ /// {@macro signup_pwd}
+ @override
+ Future signUpWithEmailAndPassword({
+ required String email,
+ required String password,
+ }) async {
+ try {
+ final userCredential = await _firebaseAuth.createUserWithEmailAndPassword(
+ email: email,
+ password: password,
+ );
+
+ return _addToStream(
+ userCredential,
+ (account) => SignedUpEvent(
+ account: account,
+ ),
+ );
+ } on FirebaseAuthException catch (e) {
+ throw SignUpWithEmailAndPasswordFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw SignUpWithEmailAndPasswordFailureFirebase();
+ }
+ }
+
+ /// {@macro signin_pwd}
@override
Future signInWithEmailAndPassword({
required String email,
@@ -53,11 +129,13 @@ class AuthenticationFirebaseDataSourceImpl
email: email,
password: password,
);
- _latestCreds = userCredential;
- final account =
- AccountModelFirebase.fromFirebaseUserCredential(userCredential);
- _accountStream.add(account);
- return account;
+
+ return _addToStream(
+ userCredential,
+ (account) => SignedInEvent(
+ account: account,
+ ),
+ );
} on FirebaseAuthException catch (e) {
throw SignInWithEmailAndPasswordFailureFirebase.fromCode(e.code);
} catch (_) {
@@ -65,107 +143,18 @@ class AuthenticationFirebaseDataSourceImpl
}
}
- /// {@macro signup}
- @override
- Future signUp({
- required String email,
- required String password,
- }) async {
- try {
- final userCredential = await _firebaseAuth.createUserWithEmailAndPassword(
- email: email,
- password: password,
- );
- _latestCreds = userCredential;
- final account =
- AccountModelFirebase.fromFirebaseUserCredential(userCredential);
- _accountStream.add(account);
- return account;
- } on FirebaseAuthException catch (e) {
- throw SignUpWithEmailAndPasswordFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw SignUpWithEmailAndPasswordFailureFirebase();
- }
- }
-
- @override
- Future signOut() async {
- try {
- _latestCreds = null;
- await _firebaseAuth.signOut();
- _accountStream.add(null);
- } catch (_) {
- throw SignOutFailureFirebase();
- }
- }
-
- @override
- Future getIdentityToken() async {
- try {
- final token = await _firebaseAuth.currentUser?.getIdToken();
- if (token.isNotNull) {
- return token!;
- } else {
- throw Exception(); // Get caught just after.
- }
- } on FirebaseAuthException catch (e) {
- throw GetIdTokenFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw GetIdTokenFailureFirebase();
- }
- }
-
- @override
- Stream streamAccount() => _accountStream.stream.asBroadcastStream();
-
- @override
- Future confirmPasswordReset({
- required String code,
- required String newPassword,
- }) async {
- try {
- await _firebaseAuth.confirmPasswordReset(
- code: code,
- newPassword: newPassword,
- );
- } on FirebaseAuthException catch (e) {
- throw ConfirmPasswordResetFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw ConfirmPasswordResetFailureFirebase();
- }
- }
-
- @override
- Future sendEmailVerification() async {
- try {
- await _firebaseAuth.currentUser!.sendEmailVerification();
- } on FirebaseAuthException catch (e) {
- throw SendEmailVerificationFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw SendEmailVerificationFailureFirebase();
- }
- }
-
- @override
- Future sendPasswordResetEmail({required String email}) async {
- try {
- await _firebaseAuth.sendPasswordResetEmail(email: email);
- } on FirebaseAuthException catch (e) {
- throw SendPasswordResetEmailFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw SendPasswordResetEmailFailureFirebase();
- }
- }
-
+ /// {@macro signin_anom}
@override
Future signInAnonymously() async {
try {
final userCredential = await _firebaseAuth.signInAnonymously();
- _latestCreds = userCredential;
- final account =
- AccountModelFirebase.fromFirebaseUserCredential(userCredential);
- _accountStream.add(account);
- return account;
+
+ return _addToStream(
+ userCredential,
+ (account) => SignedInEvent(
+ account: account,
+ ),
+ );
} on FirebaseAuthException catch (e) {
throw SignInAnonymouslyFailureFirebase.fromCode(e.code);
} catch (_) {
@@ -173,6 +162,7 @@ class AuthenticationFirebaseDataSourceImpl
}
}
+ /// {@macro signin_google}
@override
Future signInWithGoogle() async {
try {
@@ -192,11 +182,12 @@ class AuthenticationFirebaseDataSourceImpl
final userCredential =
await _firebaseAuth.signInWithCredential(credential);
- _latestCreds = userCredential;
- final account =
- AccountModelFirebase.fromFirebaseUserCredential(userCredential);
- _accountStream.add(account);
- return account;
+ return _addToStream(
+ userCredential,
+ (account) => SignedInEvent(
+ account: account,
+ ),
+ );
} on FirebaseAuthException catch (e) {
throw SignInWithGoogleFailureFirebase.fromCode(e.code);
} catch (_) {
@@ -204,6 +195,147 @@ class AuthenticationFirebaseDataSourceImpl
}
}
+ /// {@macro signout}
+ @override
+ Future signOut() async {
+ try {
+ _latestCredentials.add(null);
+ await _firebaseAuth.signOut();
+ } catch (_) {
+ throw SignOutFailureFirebase();
+ }
+ }
+
+ // Account management methods ===============================================
+
+ /// {@macro refresh}
+ @override
+ Future refresh() async {
+ try {
+ final jwt = await _firebaseAuth.currentUser?.getIdToken(true);
+ final account = AccountModel.fromFirebaseUser(
+ _firebaseAuth.currentUser,
+ accessToken: jwt,
+ );
+
+ return account;
+ } on FirebaseAuthException catch (e) {
+ throw RefreshFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw RefreshFailureFirebase();
+ }
+ }
+
+ /// {@macro reauthenticate}
+ @override
+ Future reauthenticate() async {
+ final latestCreds =
+ await _latestCredentials.stream.asBroadcastStream().last;
+ try {
+ if (latestCreds?.credential != null) {
+ await _firebaseAuth.currentUser
+ ?.reauthenticateWithCredential(latestCreds!.credential!);
+ } else {
+ throw Exception(); // Get caught just after.
+ }
+
+ final account = AccountModel.fromFirebaseUser(_firebaseAuth.currentUser);
+
+ return account;
+ } on FirebaseAuthException catch (e) {
+ throw ReauthenticateFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw ReauthenticateFailureFirebase();
+ }
+ }
+
+ /// {@macro update_email}
+ @override
+ Future updateEmail({required String email}) async {
+ try {
+ await _firebaseAuth.currentUser!.updateEmail(email);
+ final account = AccountModel.fromFirebaseUser(_firebaseAuth.currentUser);
+
+ return account;
+ } on FirebaseAuthException catch (e) {
+ throw UpdateEmailFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw UpdateEmailFailureFirebase();
+ }
+ }
+
+ /// {@macro update_password}
+ @override
+ Future updatePassword({required String password}) async {
+ try {
+ await _firebaseAuth.currentUser!.updatePassword(password);
+ final account = AccountModel.fromFirebaseUser(_firebaseAuth.currentUser);
+
+ return account;
+ } on FirebaseAuthException catch (e) {
+ throw UpdatePasswordFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw UpdatePasswordFailureFirebase();
+ }
+ }
+
+ /// {@macro delete}
+ @override
+ Future delete() async {
+ try {
+ await _firebaseAuth.currentUser!.delete();
+ } on FirebaseAuthException catch (e) {
+ throw DeleteAccountFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw DeleteAccountFailureFirebase();
+ }
+ }
+
+ // Email related stuff ======================================================
+
+ /// {@macro send_email_verification}
+ @override
+ Future sendEmailVerification() async {
+ try {
+ await _firebaseAuth.currentUser!.sendEmailVerification();
+ } on FirebaseAuthException catch (e) {
+ throw SendEmailVerificationFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw SendEmailVerificationFailureFirebase();
+ }
+ }
+
+ /// {@macro send_password_reset_email}
+ @override
+ Future sendPasswordResetEmail({required String email}) async {
+ try {
+ await _firebaseAuth.sendPasswordResetEmail(email: email);
+ } on FirebaseAuthException catch (e) {
+ throw SendPasswordResetEmailFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw SendPasswordResetEmailFailureFirebase();
+ }
+ }
+
+ /// {@macro confirm_password_reset}
+ @override
+ Future confirmPasswordReset({
+ required String code,
+ required String newPassword,
+ }) async {
+ try {
+ await _firebaseAuth.confirmPasswordReset(
+ code: code,
+ newPassword: newPassword,
+ );
+ } on FirebaseAuthException catch (e) {
+ throw ConfirmPasswordResetFailureFirebase.fromCode(e.code);
+ } catch (_) {
+ throw ConfirmPasswordResetFailureFirebase();
+ }
+ }
+
+ /// {@macro verify_password_reset_code}
@override
Future verifyPasswordResetCode({required String code}) async {
try {
@@ -215,68 +347,4 @@ class AuthenticationFirebaseDataSourceImpl
throw VerifyPasswordResetCodeFailureFirebase();
}
}
-
- @override
- Future refresh() async {
- try {
- await _firebaseAuth.currentUser!.reload();
- final account =
- AccountModelFirebase.fromFirebaseUser(_firebaseAuth.currentUser);
- _accountStream.add(account);
- } on FirebaseAuthException catch (e) {
- throw RefreshFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw RefreshFailureFirebase();
- }
- }
-
- @override
- Future reauthenticateWithCredential() async {
- try {
- if (_latestCreds?.credential != null) {
- await _firebaseAuth.currentUser
- ?.reauthenticateWithCredential(_latestCreds!.credential!);
- } else {
- throw Exception(); // Get caught just after.
- }
- final account =
- AccountModelFirebase.fromFirebaseUser(_firebaseAuth.currentUser);
- _accountStream.add(account);
- return account;
- } on FirebaseAuthException catch (e) {
- throw ReauthenticateFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw ReauthenticateFailureFirebase();
- }
- }
-
- @override
- Future updateEmail({required String email}) async {
- try {
- await _firebaseAuth.currentUser!.updateEmail(email);
- final account =
- AccountModelFirebase.fromFirebaseUser(_firebaseAuth.currentUser);
- _accountStream.add(account);
- return account;
- } on FirebaseAuthException catch (e) {
- throw UpdateEmailFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw UpdateEmailFailureFirebase();
- }
- }
-
- @override
- Future updatePassword({required String password}) async {
- try {
- await _firebaseAuth.currentUser!.updatePassword(password);
- final account =
- AccountModelFirebase.fromFirebaseUser(_firebaseAuth.currentUser);
- _accountStream.add(account);
- return account;
- } on FirebaseAuthException catch (e) {
- throw UpdatePasswordFailureFirebase.fromCode(e.code);
- } catch (_) {
- throw UpdatePasswordFailureFirebase();
- }
- }
}
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_mock_data_source_impl.dart b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_mock_data_source_impl.dart
deleted file mode 100644
index 1ee3a767..00000000
--- a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_mock_data_source_impl.dart
+++ /dev/null
@@ -1,271 +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 .
-
-import 'dart:async';
-import 'dart:math';
-
-import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
-import 'package:wyatt_type_utils/wyatt_type_utils.dart';
-
-class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
- AuthenticationMockDataSourceImpl({
- this.idToken = 'fake-id-token',
- this.registeredAccounts,
- });
- Pair? _connectedMock;
- Pair? _registeredMock;
- DateTime _lastSignInTime = DateTime.now();
- final StreamController _streamAccount = StreamController()
- ..add(null);
-
- final List>? registeredAccounts;
- final String idToken;
-
- Future _randomDelay() async {
- await Future.delayed(
- Duration(milliseconds: Random().nextInt(400) + 200),
- );
- return;
- }
-
- @override
- Future confirmPasswordReset({
- required String code,
- required String newPassword,
- }) async {
- await _randomDelay();
- }
-
- @override
- Future getIdentityToken() async {
- await _randomDelay();
- return idToken;
- }
-
- @override
- Future refresh() async {
- await _randomDelay();
- if (_connectedMock.isNull) {
- throw RefreshFailureFirebase();
- }
- final refresh = DateTime.now();
- final mock = (_connectedMock?.left as AccountModel?)
- ?.copyWith(lastSignInTime: refresh);
- _connectedMock = _connectedMock?.copyWith(left: mock);
- _streamAccount.add(mock);
- }
-
- @override
- Future sendEmailVerification() async {
- await _randomDelay();
- if (_connectedMock.isNotNull) {
- final refresh = DateTime.now();
- final mock = (_connectedMock?.left as AccountModel?)?.copyWith(
- emailVerified: false,
- lastSignInTime: refresh,
- );
- _streamAccount.add(mock);
- _connectedMock = _connectedMock?.copyWith(left: mock);
- return;
- }
- throw SendEmailVerificationFailureFirebase();
- }
-
- @override
- Future sendPasswordResetEmail({required String email}) async {
- await _randomDelay();
- if (registeredAccounts.isNotNull) {
- final accounts =
- registeredAccounts?.where((pair) => pair.left?.email == email);
- if (accounts.isNotNullOrEmpty) {
- return;
- }
- }
- if (_registeredMock.isNotNull) {
- if (_registeredMock?.left?.email != email) {
- throw SendPasswordResetEmailFailureFirebase();
- }
- return;
- }
- throw SendPasswordResetEmailFailureFirebase();
- }
-
- @override
- Future signInAnonymously() async {
- await _randomDelay();
- final creation = DateTime.now();
- final mock = AccountModel(
- uid: 'mock-id-anom',
- emailVerified: false,
- isAnonymous: true,
- providerId: 'wyatt-studio.fr',
- creationTime: creation,
- lastSignInTime: creation,
- isNewUser: creation == creation,
- );
- _streamAccount.add(mock);
- _connectedMock = _connectedMock?.copyWith(left: mock);
- _lastSignInTime = DateTime.now();
- return Future.value(mock);
- }
-
- @override
- Future signInWithGoogle() async {
- await _randomDelay();
- final creation = DateTime.now();
- final mock = AccountModel(
- uid: 'mock-id-google',
- emailVerified: true,
- isAnonymous: false,
- providerId: 'google.com',
- creationTime: creation,
- lastSignInTime: creation,
- isNewUser: creation == creation,
- );
- _streamAccount.add(mock);
- _connectedMock = _connectedMock?.copyWith(left: mock);
- _lastSignInTime = DateTime.now();
- return Future.value(mock);
- }
-
- @override
- Future signInWithEmailAndPassword({
- required String email,
- required String password,
- }) async {
- await _randomDelay();
- if (registeredAccounts.isNotNull) {
- final accounts =
- registeredAccounts?.where((pair) => pair.left?.email == email);
- if (accounts.isNotNullOrEmpty) {
- final account = accounts?.first;
- if (account?.right != password) {
- throw SignInWithCredentialFailureFirebase.fromCode('wrong-password');
- }
- _streamAccount.add(account!.left);
- _connectedMock = account.copyWith();
- return account.left!;
- }
- }
- if (_registeredMock.isNotNull) {
- if (_registeredMock?.left?.email != email) {
- throw SignInWithCredentialFailureFirebase.fromCode('user-not-found');
- }
- if (_registeredMock?.right != password) {
- throw SignInWithCredentialFailureFirebase.fromCode('wrong-password');
- }
- _streamAccount.add(_registeredMock!.left);
- _connectedMock = _registeredMock!.copyWith();
- _lastSignInTime = DateTime.now();
- return _registeredMock!.left!;
- }
- throw SignInWithCredentialFailureFirebase();
- }
-
- @override
- Future signOut() async {
- _connectedMock = null;
- _streamAccount.add(null);
- }
-
- @override
- Future signUp({
- required String email,
- required String password,
- }) async {
- await _randomDelay();
- if (registeredAccounts.isNotNull) {
- final accounts =
- registeredAccounts?.where((pair) => pair.left?.email == email);
- if (accounts.isNotNullOrEmpty) {
- throw SignUpWithEmailAndPasswordFailureFirebase.fromCode(
- 'email-already-in-use',
- );
- }
- }
- if (_registeredMock?.left?.email == email) {
- throw SignUpWithEmailAndPasswordFailureFirebase.fromCode(
- 'email-already-in-use',
- );
- }
- final creation = DateTime.now();
- final mock = AccountModel(
- uid: 'mock-id-email',
- emailVerified: false,
- isAnonymous: false,
- providerId: 'wyatt',
- email: email,
- creationTime: creation,
- lastSignInTime: creation,
- isNewUser: creation == creation,
- );
- _streamAccount.add(mock);
- _registeredMock = Pair(mock, password);
- _connectedMock = _registeredMock!.copyWith();
- _lastSignInTime = DateTime.now();
- return Future.value(mock);
- }
-
- @override
- Stream streamAccount() => _streamAccount.stream.asBroadcastStream();
-
- @override
- Future verifyPasswordResetCode({required String code}) async {
- await _randomDelay();
- return true;
- }
-
- @override
- Future reauthenticateWithCredential() async {
- await _randomDelay();
- if (_connectedMock.isNull) {
- throw ReauthenticateFailureFirebase();
- }
- await refresh();
- _lastSignInTime = DateTime.now();
- return Future.value(_connectedMock?.left);
- }
-
- @override
- Future 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 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);
- }
-}
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/models/account_model.dart b/packages/wyatt_authentication_bloc/lib/src/data/models/account_model.dart
index 0077378b..c79d54e8 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/models/account_model.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/data/models/account_model.dart
@@ -1,5 +1,4 @@
-// ignore_for_file: public_member_api_docs, sort_constructors_first
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -15,74 +14,77 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+import 'package:firebase_auth/firebase_auth.dart';
+import 'package:wyatt_authentication_bloc/src/core/exceptions/exceptions.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
+/// Account Model to parse Firebase User data
class AccountModel extends Account {
- @override
- final String uid;
+ factory AccountModel.fromFirebaseUserCredential(
+ UserCredential? userCredential,
+ ) {
+ final user = userCredential?.user;
+ if (user != null) {
+ final providerId =
+ (user.providerData.isEmpty) ? '' : user.providerData.first.providerId;
+ return AccountModel._(
+ user: user,
+ id: user.uid,
+ emailVerified: user.emailVerified,
+ isAnonymous: user.isAnonymous,
+ providerId: providerId,
+ creationTime: user.metadata.creationTime,
+ lastSignInTime: user.metadata.lastSignInTime,
+ isNewUser: userCredential?.additionalUserInfo?.isNewUser,
+ email: user.email,
+ phoneNumber: user.phoneNumber,
+ photoURL: user.photoURL,
+ accessToken: userCredential?.credential?.accessToken,
+ );
+ } else {
+ throw ModelParsingFailureFirebase('null-user', 'User cannot be null');
+ }
+ }
- @override
- final String? email;
-
- @override
- final DateTime? creationTime;
-
- @override
- final bool emailVerified;
-
- @override
- final bool isAnonymous;
-
- @override
- final bool? isNewUser;
-
- @override
- final DateTime? lastSignInTime;
-
- @override
- final String? phoneNumber;
-
- @override
- final String? photoURL;
-
- @override
- final String providerId;
-
- AccountModel({
- required this.uid,
- required this.emailVerified,
- required this.isAnonymous,
- required this.providerId,
- this.lastSignInTime,
- this.creationTime,
- this.isNewUser,
- this.email,
- this.phoneNumber,
- this.photoURL,
+ factory AccountModel.fromFirebaseUser(User? user, {String? accessToken}) {
+ if (user != null) {
+ final providerId =
+ (user.providerData.isEmpty) ? '' : user.providerData.first.providerId;
+ return AccountModel._(
+ user: user,
+ id: user.uid,
+ emailVerified: user.emailVerified,
+ isAnonymous: user.isAnonymous,
+ providerId: providerId,
+ creationTime: user.metadata.creationTime,
+ lastSignInTime: user.metadata.lastSignInTime,
+ isNewUser: false,
+ email: user.email,
+ phoneNumber: user.phoneNumber,
+ photoURL: user.photoURL,
+ accessToken: accessToken,
+ );
+ } else {
+ throw ModelParsingFailureFirebase('null-user', 'User cannot be null');
+ }
+ }
+ const AccountModel._({
+ required this.user,
+ required super.id,
+ required super.emailVerified,
+ required super.isAnonymous,
+ required super.providerId,
+ super.lastSignInTime,
+ super.creationTime,
+ super.isNewUser,
+ super.email,
+ super.phoneNumber,
+ super.photoURL,
+ super.accessToken,
});
- AccountModel copyWith({
- String? uid,
- String? email,
- DateTime? creationTime,
- bool? emailVerified,
- bool? isAnonymous,
- bool? isNewUser,
- DateTime? lastSignInTime,
- String? phoneNumber,
- String? photoURL,
- String? providerId,
- }) =>
- AccountModel(
- uid: uid ?? this.uid,
- email: email ?? this.email,
- creationTime: creationTime ?? this.creationTime,
- emailVerified: emailVerified ?? this.emailVerified,
- isAnonymous: isAnonymous ?? this.isAnonymous,
- isNewUser: isNewUser ?? this.isNewUser,
- lastSignInTime: lastSignInTime ?? this.lastSignInTime,
- phoneNumber: phoneNumber ?? this.phoneNumber,
- photoURL: photoURL ?? this.photoURL,
- providerId: providerId ?? this.providerId,
- );
+ final User? user;
+
+ @override
+ String? get refreshToken => user?.refreshToken;
}
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/models/account_model_firebase.dart b/packages/wyatt_authentication_bloc/lib/src/data/models/account_model_firebase.dart
deleted file mode 100644
index 07e5b5a0..00000000
--- a/packages/wyatt_authentication_bloc/lib/src/data/models/account_model_firebase.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-// ignore_for_file: public_member_api_docs, sort_constructors_first
-// 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 .
-
-import 'package:firebase_auth/firebase_auth.dart';
-import 'package:wyatt_authentication_bloc/src/core/exceptions/exceptions.dart';
-import 'package:wyatt_authentication_bloc/src/data/models/account_model.dart';
-
-class AccountModelFirebase extends AccountModel {
- AccountModelFirebase._({
- required super.uid,
- required super.emailVerified,
- required super.isAnonymous,
- required super.providerId,
- super.lastSignInTime,
- super.creationTime,
- super.isNewUser,
- super.email,
- super.phoneNumber,
- super.photoURL,
- });
-
- factory AccountModelFirebase.fromFirebaseUser(User? user) {
- if (user != null) {
- final providerId =
- (user.providerData.isEmpty) ? '' : user.providerData.first.providerId;
- return AccountModelFirebase._(
- uid: user.uid,
- emailVerified: user.emailVerified,
- isAnonymous: user.isAnonymous,
- providerId: providerId,
- creationTime: user.metadata.creationTime,
- lastSignInTime: user.metadata.lastSignInTime,
- isNewUser: false,
- email: user.email,
- phoneNumber: user.phoneNumber,
- photoURL: user.photoURL,
- );
- } else {
- throw ModelParsingFailureFirebase('null-user', 'User cannot be null');
- }
- }
-
- factory AccountModelFirebase.fromFirebaseUserCredential(
- UserCredential? userCredential,
- ) {
- final user = userCredential?.user;
- if (user != null) {
- final providerId =
- (user.providerData.isEmpty) ? '' : user.providerData.first.providerId;
- return AccountModelFirebase._(
- uid: user.uid,
- emailVerified: user.emailVerified,
- isAnonymous: user.isAnonymous,
- providerId: providerId,
- creationTime: user.metadata.creationTime,
- lastSignInTime: user.metadata.lastSignInTime,
- isNewUser: userCredential?.additionalUserInfo?.isNewUser,
- email: user.email,
- phoneNumber: user.phoneNumber,
- photoURL: user.photoURL,
- );
- } else {
- throw ModelParsingFailureFirebase('null-user', 'User cannot be null');
- }
- }
-}
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/models/models.dart b/packages/wyatt_authentication_bloc/lib/src/data/models/models.dart
index 14f991fe..3efbdbc0 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/models/models.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/data/models/models.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -15,4 +15,3 @@
// along with this program. If not, see .
export 'account_model.dart';
-export 'account_wrapper_model.dart';
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart b/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart
index 686be61a..2c25e1bc 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,49 +14,28 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-import 'dart:async';
-
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/core/constants/form_field.dart';
import 'package:wyatt_authentication_bloc/src/core/constants/form_name.dart';
-import 'package:wyatt_authentication_bloc/src/data/models/account_wrapper_model.dart';
-import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_cache_data_source.dart';
import 'package:wyatt_authentication_bloc/src/domain/data_sources/remote/authentication_remote_data_source.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
-import 'package:wyatt_authentication_bloc/src/domain/entities/account_wrapper.dart';
-import 'package:wyatt_authentication_bloc/src/domain/entities/auth_change_event.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/session_wrapper.dart';
import 'package:wyatt_authentication_bloc/src/domain/repositories/authentication_repository.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
-class AuthenticationRepositoryImpl
- extends AuthenticationRepository {
+class AuthenticationRepositoryImpl
+ extends AuthenticationRepository {
AuthenticationRepositoryImpl({
- required this.authenticationCacheDataSource,
required this.authenticationRemoteDataSource,
FormRepository? formRepository,
// ignore: strict_raw_type
List? extraSignUpInputs,
FormInputValidator? customEmailValidator,
FormInputValidator? customPasswordValidator,
- AuthChangeListener? onAuthChange,
- AccountStreamTransformer? accountStreamTransformer,
- }) : _authChangeListener = onAuthChange,
- _accountStreamTransformer = accountStreamTransformer {
+ }) {
_formRepository = formRepository ?? FormRepositoryImpl();
- _accountStreamTransformer ??= (input) => input
- .where((event) => event is! SignUpAuthChangeEvent)
- .map>>((event) async {
- if (listener == null) {
- return Ok(AccountWrapperModel(event.account, null));
- }
- // Handle sign in, sign out and refresh
- final dataResult = await listener!.call(this, event);
- return dataResult.map((data) {
- authenticationCacheDataSource.storeData(data);
- return AccountWrapperModel(event.account, data);
- });
- });
+
if (formRepository != null) {
return;
}
@@ -104,20 +83,47 @@ class AuthenticationRepositoryImpl
),
);
}
- final AuthenticationCacheDataSource authenticationCacheDataSource;
- final AuthenticationRemoteDataSource authenticationRemoteDataSource;
+ final AuthenticationRemoteDataSource authenticationRemoteDataSource;
late FormRepository _formRepository;
- AuthChangeListener? _authChangeListener;
- AccountStreamTransformer? _accountStreamTransformer;
-
+ /// {@macro form_repo}
@override
FormRepository get formRepository => _formRepository;
- @override
- AuthChangeListener? get listener => _authChangeListener;
+ // Stream related methods ===================================================
+ /// {@macro add_session}
+ @override
+ void addSession(SessionWrapper wrapper) =>
+ authenticationRemoteDataSource.addSession(wrapper);
+
+ /// {@macro session_stream}
+ @override
+ Stream> sessionStream() =>
+ authenticationRemoteDataSource.sessionStream();
+
+ // SignUp/SignIn methods ====================================================
+
+ /// {@macro signup_pwd}
+ @override
+ FutureOrResult signUpWithEmailAndPassword({
+ required String email,
+ required String password,
+ }) =>
+ Result.tryCatchAsync(
+ () async {
+ final account =
+ await authenticationRemoteDataSource.signUpWithEmailAndPassword(
+ email: email,
+ password: password,
+ );
+ return account;
+ },
+ (error) => error,
+ );
+
+ /// {@macro signin_pwd}
@override
FutureOrResult signInWithEmailAndPassword({
required String email,
@@ -130,100 +136,127 @@ class AuthenticationRepositoryImpl
email: email,
password: password,
);
- await authenticationCacheDataSource.storeAccount(account);
return account;
},
(error) => error,
);
+ /// {@macro signin_anom}
+ @override
+ FutureOrResult signInAnonymously() =>
+ Result.tryCatchAsync(
+ () async {
+ final account =
+ await authenticationRemoteDataSource.signInAnonymously();
+ return account;
+ },
+ (error) => error,
+ );
+
+ /// {@macro signin_google}
+ @override
+ FutureOrResult signInWithGoogle() =>
+ Result.tryCatchAsync(
+ () async {
+ final account =
+ await authenticationRemoteDataSource.signInWithGoogle();
+ return account;
+ },
+ (error) => error,
+ );
+
+ /// {@macro signout}
@override
FutureOrResult signOut() =>
Result.tryCatchAsync(
() async {
await authenticationRemoteDataSource.signOut();
- await authenticationCacheDataSource.destroy();
},
(error) => error,
);
+ // Account management methods ===============================================
+
+ /// {@macro refresh}
@override
- FutureOrResult signUp({
- required String email,
- required String password,
- }) =>
+ FutureOrResult refresh() =>
Result.tryCatchAsync(
() async {
- final account = await authenticationRemoteDataSource.signUp(
- email: email,
- password: password,
- );
- await authenticationCacheDataSource.storeAccount(account);
+ final account = await authenticationRemoteDataSource.refresh();
return account;
},
(error) => error,
);
+ /// {@macro reauthenticate}
@override
- FutureOrResult destroyCache() =>
- Result.tryCatchAsync(
- authenticationCacheDataSource.destroy,
- (error) => error,
- );
-
- @override
- FutureOrResult> getCache() =>
- Result.tryCatchAsync, AppException, AppException>(
- authenticationCacheDataSource.load,
- (error) => error,
- );
-
- @override
- FutureOrResult getAccount() =>
+ FutureOrResult reauthenticate() =>
Result.tryCatchAsync(
- authenticationCacheDataSource.loadAccount,
- (error) => error,
- );
-
- @override
- FutureOrResult setAccount(
- Account account,
- ) =>
- Result.tryCatchAsync(
() async {
- await authenticationCacheDataSource.storeAccount(account);
+ final account = await authenticationRemoteDataSource.reauthenticate();
+ return account;
},
(error) => error,
);
+ /// {@macro update_email}
@override
- FutureOrResult getData() =>
- Result.tryCatchAsync(
- authenticationCacheDataSource.loadData,
- (error) => error,
- );
-
- @override
- FutureOrResult setData(
- T? data,
- ) =>
- Result.tryCatchAsync(
+ FutureOrResult updateEmail({required String email}) =>
+ Result.tryCatchAsync(
() async {
- await authenticationCacheDataSource.storeData(data);
+ final account =
+ await authenticationRemoteDataSource.updateEmail(email: email);
+ return account;
},
(error) => error,
);
+ /// {@macro update_password}
@override
- FutureOrResult getIdentityToken() =>
- Result.tryCatchAsync(
- authenticationRemoteDataSource.getIdentityToken,
+ FutureOrResult updatePassword({required String password}) =>
+ Result.tryCatchAsync(
+ () async {
+ final account = await authenticationRemoteDataSource.updatePassword(
+ password: password,
+ );
+ return account;
+ },
(error) => error,
);
+ /// {@macro delete}
@override
- Stream>> streamAccount() =>
- _accountStreamTransformer!.call(changes());
+ FutureOrResult delete() =>
+ Result.tryCatchAsync(
+ () async => authenticationRemoteDataSource.delete(),
+ (error) => error,
+ );
+ // Email related stuff ======================================================
+
+ /// {@macro send_email_verification}
+ @override
+ FutureOrResult sendEmailVerification() =>
+ Result.tryCatchAsync(
+ () async {
+ await authenticationRemoteDataSource.sendEmailVerification();
+ },
+ (error) => error,
+ );
+
+ /// {@macro send_password_reset_email}
+ @override
+ FutureOrResult sendPasswordResetEmail({required String email}) =>
+ Result.tryCatchAsync(
+ () async {
+ await authenticationRemoteDataSource.sendPasswordResetEmail(
+ email: email,
+ );
+ },
+ (error) => error,
+ );
+
+ /// {@macro confirm_password_reset}
@override
FutureOrResult confirmPasswordReset({
required String code,
@@ -239,48 +272,7 @@ class AuthenticationRepositoryImpl
(error) => error,
);
- @override
- FutureOrResult sendEmailVerification() =>
- Result.tryCatchAsync(
- () async {
- await authenticationRemoteDataSource.sendEmailVerification();
- },
- (error) => error,
- );
-
- @override
- FutureOrResult sendPasswordResetEmail({required String email}) =>
- Result.tryCatchAsync(
- () async {
- await authenticationRemoteDataSource.sendPasswordResetEmail(
- email: email,
- );
- },
- (error) => error,
- );
-
- @override
- FutureOrResult signInAnonymously() =>
- Result.tryCatchAsync(
- () async {
- final account =
- await authenticationRemoteDataSource.signInAnonymously();
- return account;
- },
- (error) => error,
- );
-
- @override
- FutureOrResult signInWithGoogle() =>
- Result.tryCatchAsync(
- () async {
- final account =
- await authenticationRemoteDataSource.signInWithGoogle();
- return account;
- },
- (error) => error,
- );
-
+ /// {@macro verify_password_reset_code}
@override
FutureOrResult verifyPasswordResetCode({required String code}) =>
Result.tryCatchAsync(
@@ -291,91 +283,4 @@ class AuthenticationRepositoryImpl
},
(error) => error,
);
-
- @override
- FutureOrResult refresh() =>
- Result.tryCatchAsync(
- () async {
- await authenticationRemoteDataSource.refresh();
- },
- (error) => error,
- );
-
- @override
- FutureOrResult reauthenticateWithCredential() =>
- Result.tryCatchAsync(
- () async {
- final account = await authenticationRemoteDataSource
- .reauthenticateWithCredential();
- return account;
- },
- (error) => error,
- );
-
- @override
- FutureOrResult updateEmail({required String email}) =>
- Result.tryCatchAsync(
- () async {
- final account =
- await authenticationRemoteDataSource.updateEmail(email: email);
- return account;
- },
- (error) => error,
- );
-
- @override
- FutureOrResult updatePassword({required String password}) =>
- Result.tryCatchAsync(
- () async {
- final account = await authenticationRemoteDataSource.updatePassword(
- password: password,
- );
- return account;
- },
- (error) => error,
- );
-
- Account? _lastChange;
-
- @override
- Stream changes() => authenticationRemoteDataSource
- .streamAccount()
- .map((account) {
- if (_lastChange != null && account == null) {
- _lastChange = null;
- return SignOutAuthChangeEvent();
- }
- if (_lastChange == null && account != null) {
- _lastChange = account;
- if (account.isNewUser ?? false) {
- if (account.isAnonymous) {
- return AnonymousSignInAuthChangeEvent(account);
- }
- return SignUpAuthChangeEvent(account);
- }
- return SignInAuthChangeEvent(account);
- }
- if (_lastChange != null && account != null) {
- _lastChange = account;
- return RefreshAuthChangeEvent(account);
- }
- if (_lastChange == null && account == null) {
- _lastChange = account;
- return StillUnauthenticatedAuthChangeEvent();
- }
- _lastChange = account;
- return RefreshAuthChangeEvent(account);
- });
-
- @override
- FutureOrResult addAuthChangeListener(AuthChangeListener listener) {
- _authChangeListener = listener;
- return const Ok(null);
- }
-
- @override
- FutureOrResult removeAuthChangeListener() {
- _authChangeListener = null;
- return const Ok(null);
- }
}
diff --git a/packages/wyatt_authentication_bloc/lib/src/data/repositories/repositories.dart b/packages/wyatt_authentication_bloc/lib/src/data/repositories/repositories.dart
index d5979688..0081a38c 100644
--- a/packages/wyatt_authentication_bloc/lib/src/data/repositories/repositories.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/data/repositories/repositories.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/data_sources.dart b/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/data_sources.dart
index 11efe02d..4a8f3011 100644
--- a/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/data_sources.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/data_sources.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,5 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-export 'local/authentication_cache_data_source.dart';
export 'remote/authentication_remote_data_source.dart';
diff --git a/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart b/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart
index 8205bd8d..6bec3426 100644
--- a/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -16,9 +16,20 @@
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
+import 'package:wyatt_authentication_bloc/src/domain/entities/session_wrapper.dart';
-abstract class AuthenticationRemoteDataSource extends BaseRemoteDataSource {
- Future signUp({
+/// Is responsible for abstracting the provenance of the data.
+abstract class AuthenticationRemoteDataSource
+ extends BaseRemoteDataSource {
+ // Stream related methods ===================================================
+
+ void addSession(SessionWrapper wrapper);
+
+ Stream> sessionStream();
+
+ // SignUp/SignIn methods ====================================================
+
+ Future signUpWithEmailAndPassword({
required String email,
required String password,
});
@@ -27,33 +38,27 @@ abstract class AuthenticationRemoteDataSource extends BaseRemoteDataSource {
required String email,
required String password,
});
+ Future signInAnonymously();
+ Future signInWithGoogle();
Future signOut();
- Future refresh();
+ // Account management methods ===============================================
+
+ // Future linkCurrentUserWith(AuthenticationProvider anotherProvider);
+ Future refresh();
+ Future reauthenticate();
+ Future updateEmail({required String email});
+ Future updatePassword({required String password});
+ Future delete();
- Stream streamAccount();
-
- Future getIdentityToken();
+ // Email related stuff ======================================================
Future sendEmailVerification();
-
Future sendPasswordResetEmail({required String email});
-
Future confirmPasswordReset({
required String code,
required String newPassword,
});
-
Future verifyPasswordResetCode({required String code});
-
- Future signInAnonymously();
-
- Future signInWithGoogle();
-
- Future updateEmail({required String email});
-
- Future updatePassword({required String password});
-
- Future reauthenticateWithCredential();
}
diff --git a/packages/wyatt_authentication_bloc/lib/src/domain/domain.dart b/packages/wyatt_authentication_bloc/lib/src/domain/domain.dart
index 6f4ec438..25af7843 100644
--- a/packages/wyatt_authentication_bloc/lib/src/domain/domain.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/domain/domain.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
diff --git a/packages/wyatt_authentication_bloc/lib/src/domain/entities/account.dart b/packages/wyatt_authentication_bloc/lib/src/domain/entities/account.dart
index 5723d3a5..ee6cd353 100644
--- a/packages/wyatt_authentication_bloc/lib/src/domain/entities/account.dart
+++ b/packages/wyatt_authentication_bloc/lib/src/domain/entities/account.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -17,67 +17,88 @@
import 'package:equatable/equatable.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
-abstract class Account extends Equatable implements Entity {
+/// Represents a user [Account] in the
+/// various identity provisioning systems.
+class Account extends Equatable implements Entity {
+ const Account({
+ required this.id,
+ required this.isAnonymous,
+ required this.emailVerified,
+ required this.providerId,
+ this.email,
+ this.phoneNumber,
+ this.photoURL,
+ this.creationTime,
+ this.lastSignInTime,
+ this.isNewUser,
+ this.accessToken,
+ this.refreshToken,
+ });
+
/// The user's unique ID.
- String get uid;
+ final String id;
+
+ /// Returns whether the user is a anonymous.
+ final bool isAnonymous;
/// The users email address.
///
/// Will be `null` if signing in anonymously.
- String? get email;
+ final String? email;
/// Returns whether the users email address has been verified.
///
/// To send a verification email, see `SendEmailVerification`.
- bool get emailVerified;
-
- /// Returns whether the user is a anonymous.
- bool get isAnonymous;
-
- /// Returns the users account creation time.
- ///
- /// When this account was created as dictated by the server clock.
- DateTime? get creationTime;
-
- /// When the user last signed in as dictated by the server clock.
- DateTime? get lastSignInTime;
+ final bool emailVerified;
/// Returns the users phone number.
///
/// This property will be `null` if the user has not signed in or been has
/// their phone number linked.
- String? get phoneNumber;
+ final String? phoneNumber;
/// Returns a photo URL for the user.
///
/// This property will be populated if the user has signed in or been linked
/// with a 3rd party OAuth provider (such as Google).
- String? get photoURL;
+ final String? photoURL;
- /// The provider ID for the user.
- String get providerId;
+ /// Returns the users account creation time.
+ ///
+ /// When this account was created as dictated by the server clock.
+ final DateTime? creationTime;
+
+ /// When the user last signed in as dictated by the server clock.
+ final DateTime? lastSignInTime;
/// Whether the user account has been recently created.
- bool? get isNewUser;
+ final bool? isNewUser;
+
+ /// The provider ID for the user.
+ final String providerId;
+
+ /// The user access token
+ final String? accessToken;
+
+ /// The user refresh token
+ final String? refreshToken;
@override
List