refactor(authentication)!: split data sources (cache, session, external)
This commit is contained in:
parent
5a7930550d
commit
d53e7b80da
@ -14,4 +14,5 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'remote/authentication_firebase_data_source_impl.dart';
|
||||
export 'local/local.dart';
|
||||
export 'remote/remote.dart';
|
||||
|
@ -0,0 +1,56 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_cache_data_source.dart';
|
||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||
|
||||
/// {@template authentication_firebase_cache_data_source_impl}
|
||||
/// A data source that manages the cache strategy.
|
||||
/// This implementation uses Firebase.
|
||||
/// {@endtemplate}
|
||||
class AuthenticationFirebaseCacheDataSourceImpl<Data>
|
||||
extends AuthenticationCacheDataSource<Data> {
|
||||
/// {@macro authentication_firebase_cache_data_source_impl}
|
||||
AuthenticationFirebaseCacheDataSourceImpl({
|
||||
FirebaseAuth? firebaseAuth,
|
||||
}) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance;
|
||||
|
||||
final FirebaseAuth _firebaseAuth;
|
||||
|
||||
// Already done by Firebase
|
||||
@override
|
||||
Future<void> cacheAccount(Account account) => Future.value();
|
||||
|
||||
@override
|
||||
Future<Account?> getCachedAccount() async {
|
||||
final currentUser = _firebaseAuth.currentUser;
|
||||
if (currentUser == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final jwt = await currentUser.getIdToken(true);
|
||||
final currentAccount = AccountModel.fromFirebaseUser(
|
||||
currentUser,
|
||||
accessToken: jwt,
|
||||
);
|
||||
|
||||
return currentAccount;
|
||||
}
|
||||
|
||||
// Already done by Firebase
|
||||
@override
|
||||
Future<void> removeCachedAccount() => Future.value();
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:rxdart/subjects.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_session_data_source.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
|
||||
|
||||
/// {@template authentication_session_data_source_impl}
|
||||
/// A data source that manages the current session.
|
||||
/// {@endtemplate}
|
||||
class AuthenticationSessionDataSourceImpl<Data>
|
||||
extends AuthenticationSessionDataSource<Data> {
|
||||
/// {@macro authentication_session_data_source_impl}
|
||||
AuthenticationSessionDataSourceImpl();
|
||||
|
||||
final StreamController<AuthenticationSession<Data>> _sessionStream =
|
||||
BehaviorSubject();
|
||||
|
||||
@override
|
||||
void addSession(AuthenticationSession<Data> session) {
|
||||
_sessionStream.add(session);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AuthenticationSession<Data>> currentSession() => sessionStream().last;
|
||||
|
||||
@override
|
||||
Stream<AuthenticationSession<Data>> sessionStream() =>
|
||||
_sessionStream.stream.asBroadcastStream();
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'authentication_firebase_cache_data_source_impl.dart';
|
||||
export 'authentication_session_data_source_impl.dart';
|
@ -23,55 +23,27 @@ 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/auth_session.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/authentication_change_event/authentication_change_event.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
/// {@template authentication_firebase_data_source_impl}
|
||||
/// Implementation of [AuthenticationRemoteDataSource] using Firebase.
|
||||
/// {@endtemplate}
|
||||
class AuthenticationFirebaseDataSourceImpl<Data>
|
||||
extends AuthenticationRemoteDataSource<Data> {
|
||||
/// {@macro authentication_firebase_data_source_impl}
|
||||
AuthenticationFirebaseDataSourceImpl({
|
||||
FirebaseAuth? firebaseAuth,
|
||||
GoogleSignIn? googleSignIn,
|
||||
}) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
|
||||
_googleSignIn = googleSignIn ?? GoogleSignIn() {
|
||||
_latestCredentials = BehaviorSubject();
|
||||
_sessionStream = BehaviorSubject();
|
||||
|
||||
// Check for account in memory (persistence)
|
||||
_checkForCachedAccount();
|
||||
}
|
||||
|
||||
late StreamController<AuthenticationSession<Data>> _sessionStream;
|
||||
late StreamController<UserCredential?> _latestCredentials;
|
||||
|
||||
final FirebaseAuth _firebaseAuth;
|
||||
final GoogleSignIn _googleSignIn;
|
||||
|
||||
Future<void> _checkForCachedAccount() async {
|
||||
final currentUser = _firebaseAuth.currentUser;
|
||||
|
||||
if (currentUser == null) {
|
||||
_sessionStream.add(
|
||||
const AuthenticationSession(
|
||||
latestEvent: UnknownAuthenticationEvent(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final jwt = await currentUser.getIdToken(true);
|
||||
final currentAccount = AccountModel.fromFirebaseUser(
|
||||
currentUser,
|
||||
accessToken: jwt,
|
||||
);
|
||||
_sessionStream.add(
|
||||
AuthenticationSession.fromEvent(
|
||||
SignedInFromCacheEvent(account: currentAccount),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Future<Account> _addToCredentialStream(
|
||||
UserCredential userCredential,
|
||||
) async {
|
||||
@ -87,23 +59,6 @@ class AuthenticationFirebaseDataSourceImpl<Data>
|
||||
return account;
|
||||
}
|
||||
|
||||
// Session related methods ===================================================
|
||||
|
||||
/// {@macro add_session}
|
||||
@override
|
||||
void addSession(AuthenticationSession<Data> session) {
|
||||
_sessionStream.add(session);
|
||||
}
|
||||
|
||||
/// {@macro session_stream}
|
||||
@override
|
||||
Stream<AuthenticationSession<Data>> sessionStream() =>
|
||||
_sessionStream.stream.asBroadcastStream();
|
||||
|
||||
/// {@macro current_session}
|
||||
@override
|
||||
Future<AuthenticationSession<Data>> currentSession() => sessionStream().last;
|
||||
|
||||
// SignUp/SignIn methods ====================================================
|
||||
|
||||
/// {@macro signup_pwd}
|
||||
|
@ -0,0 +1,17 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'authentication_firebase_data_source_impl.dart';
|
@ -16,17 +16,22 @@
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/core/utils/forms.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/auth_session.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/repositories/authentication_repository.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/local/authentication_session_data_source.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/domain.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
/// {@template authentication_repository_impl}
|
||||
/// The default implementation of [AuthenticationRepository].
|
||||
/// {@endtemplate}
|
||||
class AuthenticationRepositoryImpl<Data extends Object>
|
||||
extends AuthenticationRepository<Data> {
|
||||
/// {@macro authentication_repository_impl}
|
||||
AuthenticationRepositoryImpl({
|
||||
required this.authenticationRemoteDataSource,
|
||||
required this.authenticationCacheDataSource,
|
||||
required this.authenticationSessionDataSource,
|
||||
FormRepository? formRepository,
|
||||
// ignore: strict_raw_type
|
||||
List<FormInput>? extraSignUpInputs,
|
||||
@ -66,24 +71,57 @@ class AuthenticationRepositoryImpl<Data extends Object>
|
||||
);
|
||||
}
|
||||
|
||||
/// The remote data source used to perform the authentication process.
|
||||
final AuthenticationRemoteDataSource<Data> authenticationRemoteDataSource;
|
||||
|
||||
/// The cache data source used to cache the current account.
|
||||
final AuthenticationCacheDataSource<Data> authenticationCacheDataSource;
|
||||
|
||||
/// The session data source used to manage the current session.
|
||||
final AuthenticationSessionDataSource<Data> authenticationSessionDataSource;
|
||||
|
||||
late FormRepository _formRepository;
|
||||
|
||||
/// {@macro form_repo}
|
||||
@override
|
||||
FormRepository get formRepository => _formRepository;
|
||||
|
||||
// Cache related methods ====================================================
|
||||
|
||||
/// {@macro check_cache_account}
|
||||
@override
|
||||
Future<void> checkForCachedAccount() async {
|
||||
final cachedAccount =
|
||||
await authenticationCacheDataSource.getCachedAccount();
|
||||
|
||||
if (cachedAccount == null) {
|
||||
addSession(
|
||||
const AuthenticationSession(
|
||||
latestEvent: UnknownAuthenticationEvent(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
addSession(
|
||||
AuthenticationSession.fromEvent(
|
||||
SignedInFromCacheEvent(account: cachedAccount),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Session related methods ===================================================
|
||||
|
||||
/// {@macro add_session}
|
||||
@override
|
||||
void addSession(AuthenticationSession<Data> session) =>
|
||||
authenticationRemoteDataSource.addSession(session);
|
||||
authenticationSessionDataSource.addSession(session);
|
||||
|
||||
/// {@macro session_stream}
|
||||
@override
|
||||
Stream<AuthenticationSession<Data>> sessionStream() =>
|
||||
authenticationRemoteDataSource.sessionStream();
|
||||
authenticationSessionDataSource.sessionStream();
|
||||
|
||||
/// {@macro current_session}
|
||||
@override
|
||||
@ -91,7 +129,9 @@ class AuthenticationRepositoryImpl<Data extends Object>
|
||||
Result.tryCatchAsync<AuthenticationSession<Data>, AppException,
|
||||
AppException>(
|
||||
() async {
|
||||
final session = await authenticationRemoteDataSource.currentSession();
|
||||
final session =
|
||||
await authenticationSessionDataSource.currentSession();
|
||||
|
||||
return session;
|
||||
},
|
||||
(error) => error,
|
||||
|
@ -14,4 +14,5 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'remote/authentication_remote_data_source.dart';
|
||||
export 'local/local.dart';
|
||||
export 'remote/remote.dart';
|
||||
|
@ -0,0 +1,40 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
|
||||
|
||||
/// {@template authentication_cache_data_source}
|
||||
/// A data source that manages the cache strategy.
|
||||
/// {@endtemplate}
|
||||
abstract class AuthenticationCacheDataSource<Data> extends BaseLocalDataSource {
|
||||
/// {@macro authentication_cache_data_source}
|
||||
const AuthenticationCacheDataSource();
|
||||
|
||||
/// Returns the cached account if it exists.
|
||||
Future<Account?> getCachedAccount();
|
||||
|
||||
/// Adds the current account to the cache.
|
||||
///
|
||||
/// If an account is already cached, it will be replaced.
|
||||
Future<void> cacheAccount(Account account);
|
||||
|
||||
/// Removes the current account from the cache.
|
||||
///
|
||||
/// The cache will be empty after this operation.
|
||||
/// If no account is cached, nothing will happen.
|
||||
Future<void> removeCachedAccount();
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||
|
||||
/// {@template authentication_session_data_source}
|
||||
/// A data source that manages the current session.
|
||||
/// {@endtemplate}
|
||||
abstract class AuthenticationSessionDataSource<Data>
|
||||
extends BaseLocalDataSource {
|
||||
/// {@macro authentication_session_data_source}
|
||||
const AuthenticationSessionDataSource();
|
||||
|
||||
/// Adds a new session to the data source.
|
||||
void addSession(AuthenticationSession<Data> session);
|
||||
|
||||
/// Returns a stream of sessions.
|
||||
Stream<AuthenticationSession<Data>> sessionStream();
|
||||
|
||||
/// Returns the current session.
|
||||
Future<AuthenticationSession<Data>> currentSession();
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'authentication_cache_data_source.dart';
|
||||
export 'authentication_session_data_source.dart';
|
@ -16,49 +16,71 @@
|
||||
|
||||
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/auth_session.dart';
|
||||
|
||||
/// Is responsible for abstracting the provenance of the data.
|
||||
/// {@template authentication_remote_data_source}
|
||||
/// A remote data source for authentication.
|
||||
/// It is responsible for all the external communication with the authentication
|
||||
/// providers.
|
||||
/// {@endtemplate}
|
||||
abstract class AuthenticationRemoteDataSource<Data>
|
||||
extends BaseRemoteDataSource {
|
||||
// Session related methods ===================================================
|
||||
|
||||
void addSession(AuthenticationSession<Data> session);
|
||||
Stream<AuthenticationSession<Data>> sessionStream();
|
||||
Future<AuthenticationSession<Data>> currentSession();
|
||||
/// {@macro authentication_remote_data_source}
|
||||
const AuthenticationRemoteDataSource();
|
||||
|
||||
// SignUp/SignIn methods ====================================================
|
||||
|
||||
/// Sign up with email and password.
|
||||
Future<Account> signUpWithEmailAndPassword({
|
||||
required String email,
|
||||
required String password,
|
||||
});
|
||||
|
||||
/// Sign in with email and password.
|
||||
Future<Account> signInWithEmailAndPassword({
|
||||
required String email,
|
||||
required String password,
|
||||
});
|
||||
|
||||
/// Sign in anonymously.
|
||||
Future<Account> signInAnonymously();
|
||||
|
||||
/// Sign in with Google.
|
||||
Future<Account> signInWithGoogle();
|
||||
|
||||
/// Sign out.
|
||||
Future<void> signOut();
|
||||
|
||||
// Account management methods ===============================================
|
||||
|
||||
// Future<void> linkCurrentUserWith(AuthenticationProvider anotherProvider);
|
||||
|
||||
/// Refresh the current account.
|
||||
Future<Account> refresh();
|
||||
|
||||
/// Reauthenticate the current account.
|
||||
Future<Account> reauthenticate();
|
||||
|
||||
/// Update the current account's email.
|
||||
Future<Account> updateEmail({required String email});
|
||||
|
||||
/// Update the current account's password.
|
||||
Future<Account> updatePassword({required String password});
|
||||
|
||||
/// Delete the current account.
|
||||
Future<void> delete();
|
||||
|
||||
// Email related stuff ======================================================
|
||||
|
||||
/// Send an email verification.
|
||||
Future<void> sendEmailVerification();
|
||||
|
||||
/// Send a password reset email.
|
||||
Future<void> sendPasswordResetEmail({required String email});
|
||||
|
||||
/// Confirm password reset.
|
||||
Future<void> confirmPasswordReset({
|
||||
required String code,
|
||||
required String newPassword,
|
||||
});
|
||||
|
||||
/// Verify password reset code.
|
||||
Future<bool> verifyPasswordResetCode({required String code});
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'authentication_remote_data_source.dart';
|
@ -19,13 +19,25 @@ import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
|
||||
/// {@template auth_repo}
|
||||
/// Authentication repository interface.
|
||||
/// {@endtemplate}
|
||||
abstract class AuthenticationRepository<Data> extends BaseRepository {
|
||||
/// {@template form_repo}
|
||||
/// Form repository used in different authentication cubits/blocs
|
||||
/// {@endtemplate}
|
||||
FormRepository get formRepository;
|
||||
|
||||
// Stream related methods ===================================================
|
||||
// Cache related methods ====================================================
|
||||
|
||||
/// {@template check_cache_account}
|
||||
/// Checks if there is a cached account.
|
||||
/// And if there is, it will sign in the user automatically by
|
||||
/// emitting an event.
|
||||
/// {@endtemplate}
|
||||
Future<void> checkForCachedAccount();
|
||||
|
||||
// Session related methods ===================================================
|
||||
|
||||
/// {@template add_session}
|
||||
/// Add a new authentication event.
|
||||
|
@ -27,27 +27,45 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
part 'authentication_state.dart';
|
||||
|
||||
/// {@template authentication_cubit}
|
||||
/// Abstract authentication cubit class needs to be implemented in application.
|
||||
///
|
||||
/// This cubit is in charge of managing the global authentication state of
|
||||
/// the application.
|
||||
///
|
||||
/// Its here you can override every callbacks and add your custom logic.
|
||||
/// {@endtemplate}
|
||||
abstract class AuthenticationCubit<Data>
|
||||
extends Cubit<AuthenticationState<Data>> {
|
||||
/// {@macro authentication_cubit}
|
||||
AuthenticationCubit({
|
||||
required this.authenticationRepository,
|
||||
}) : super(const AuthenticationState.unknown()) {
|
||||
_listenForAuthenticationChanges();
|
||||
_init();
|
||||
}
|
||||
|
||||
/// The authentication repository.
|
||||
final AuthenticationRepository<Data> authenticationRepository;
|
||||
|
||||
/// The latest session.
|
||||
AuthenticationSession<Data>? _latestSession;
|
||||
|
||||
/// Method that is called when the cubit is initialized.
|
||||
Future<void> _init() async {
|
||||
/// Setup listeners.
|
||||
_listenForAuthenticationChanges();
|
||||
|
||||
/// Check if there is a cached account.
|
||||
await authenticationRepository.checkForCachedAccount();
|
||||
}
|
||||
|
||||
void _listenForAuthenticationChanges() {
|
||||
authenticationRepository.sessionStream().asyncMap((session) async {
|
||||
final event = session.latestEvent;
|
||||
|
||||
/// If the session is signed in from cache.
|
||||
if (event is SignedInFromCacheEvent) {
|
||||
/// Call the custom routine.
|
||||
final customRoutineResult = await onSignInFromCache(session);
|
||||
|
||||
if (customRoutineResult.isOk) {
|
||||
@ -64,12 +82,18 @@ abstract class AuthenticationCubit<Data>
|
||||
}
|
||||
return session;
|
||||
}).listen((session) async {
|
||||
/// Save the latest session.
|
||||
_latestSession = session;
|
||||
|
||||
/// If there is an account: emit authenticated state.
|
||||
if (session.account != null) {
|
||||
emit(AuthenticationState<Data>.authenticated(session));
|
||||
return;
|
||||
}
|
||||
|
||||
/// If there is no account: emit unauthenticated state.
|
||||
emit(AuthenticationState<Data>.unauthenticated());
|
||||
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user