feat(authentication): add mock + local storage
This commit is contained in:
		
							parent
							
								
									fcc439a311
								
							
						
					
					
						commit
						3f1c93c35f
					
				| @ -0,0 +1,22 @@ | ||||
| // 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/>. | ||||
| 
 | ||||
| abstract class AuthStorage { | ||||
|   static const String refreshToken = 'wyattRefreshToken'; | ||||
|   static const String accessToken = 'wyattAccessToken'; | ||||
|   static const String email = 'wyattEmail'; | ||||
|   static const String id = 'wyattId'; | ||||
| } | ||||
| @ -16,7 +16,9 @@ | ||||
| 
 | ||||
| import 'package:wyatt_architecture/wyatt_architecture.dart'; | ||||
| 
 | ||||
| part 'exceptions_base.dart'; | ||||
| part 'exceptions_firebase.dart'; | ||||
| part 'exceptions_mock.dart'; | ||||
| 
 | ||||
| /// Base exception used in Wyatt Authentication | ||||
| abstract class AuthenticationFailureInterface extends AppException | ||||
|  | ||||
| @ -0,0 +1,382 @@ | ||||
| // 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/>. | ||||
| 
 | ||||
| part of 'exceptions.dart'; | ||||
| 
 | ||||
| /// {@macro apply_action_code_failure} | ||||
| class ApplyActionCodeFailureBase extends ApplyActionCodeFailureInterface { | ||||
|   ApplyActionCodeFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   ApplyActionCodeFailureBase.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'expired-action-code': | ||||
|         msg = 'Action code has expired.'; | ||||
|         break; | ||||
|       case 'invalid-action-code': | ||||
|         msg = 'Action code is invalid.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'Email is not found, please create an account.'; | ||||
|         break; | ||||
| 
 | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_up_with_email_and_password_failure} | ||||
| class SignUpWithEmailAndPasswordFailureBase | ||||
|     extends SignUpWithEmailAndPasswordFailureInterface { | ||||
|   SignUpWithEmailAndPasswordFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignUpWithEmailAndPasswordFailureBase.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'The email address is badly formatted.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'email-already-in-use': | ||||
|         msg = 'An account already exists for that email.'; | ||||
|         break; | ||||
|       case 'operation-not-allowed': | ||||
|         msg = 'Operation is not allowed. Please contact support.'; | ||||
|         break; | ||||
|       case 'weak-password': | ||||
|         msg = 'Please enter a stronger password.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro fetch_sign_in_methods_failure} | ||||
| class FetchSignInMethodsForEmailFailureBase | ||||
|     extends FetchSignInMethodsForEmailFailureInterface { | ||||
|   FetchSignInMethodsForEmailFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   FetchSignInMethodsForEmailFailureBase.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'The email address is badly formatted.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_anonymously_failure} | ||||
| class SignInAnonymouslyFailureBase extends SignInAnonymouslyFailureInterface { | ||||
|   SignInAnonymouslyFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInAnonymouslyFailureBase.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'operation-not-allowed': | ||||
|         msg = 'Operation is not allowed. Please contact support.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_credential_failure} | ||||
| class SignInWithCredentialFailureBase | ||||
|     extends SignInWithCredentialFailureInterface { | ||||
|   SignInWithCredentialFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInWithCredentialFailureBase.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'account-exists-with-different-credential': | ||||
|         msg = 'Account exists with different credentials.'; | ||||
|         break; | ||||
|       case 'invalid-credential': | ||||
|         msg = 'The credential received is malformed or has expired.'; | ||||
|         break; | ||||
|       case 'operation-not-allowed': | ||||
|         msg = 'Operation is not allowed. Please contact support.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'Email is not found, please create an account.'; | ||||
|         break; | ||||
|       case 'wrong-password': | ||||
|         msg = 'Incorrect password, please try again.'; | ||||
|         break; | ||||
|       case 'invalid-verification-code': | ||||
|         msg = 'The credential verification code received is invalid.'; | ||||
|         break; | ||||
|       case 'invalid-verification-id': | ||||
|         msg = 'The credential verification ID received is invalid.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_google_failure} | ||||
| class SignInWithGoogleFailureBase extends SignInWithCredentialFailureBase | ||||
|     implements SignInWithGoogleFailureInterface { | ||||
|   SignInWithGoogleFailureBase([super.code, super.msg]); | ||||
|   SignInWithGoogleFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_facebook_failure} | ||||
| class SignInWithFacebookFailureBase extends SignInWithCredentialFailureBase | ||||
|     implements SignInWithFacebookFailureInterface { | ||||
|   SignInWithFacebookFailureBase([super.code, super.msg]); | ||||
|   SignInWithFacebookFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_apple_failure} | ||||
| class SignInWithAppleFailureBase extends SignInWithCredentialFailureBase | ||||
|     implements SignInWithAppleFailureInterface { | ||||
|   SignInWithAppleFailureBase([super.code, super.msg]); | ||||
|   SignInWithAppleFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_twitter_failure} | ||||
| class SignInWithTwitterFailureBase extends SignInWithCredentialFailureBase | ||||
|     implements SignInWithAppleFailureInterface { | ||||
|   SignInWithTwitterFailureBase([super.code, super.msg]); | ||||
|   SignInWithTwitterFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_email_link_failure} | ||||
| class SignInWithEmailLinkFailureBase | ||||
|     extends SignInWithEmailLinkFailureInterface { | ||||
|   SignInWithEmailLinkFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInWithEmailLinkFailureBase.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'expired-action-code': | ||||
|         msg = 'Action code has expired.'; | ||||
|         break; | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_email_and_password_failure} | ||||
| class SignInWithEmailAndPasswordFailureBase | ||||
|     extends SignInWithEmailAndPasswordFailureInterface { | ||||
|   SignInWithEmailAndPasswordFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInWithEmailAndPasswordFailureBase.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'Email is not found, please create an account.'; | ||||
|         break; | ||||
|       case 'wrong-password': | ||||
|         msg = 'Incorrect password, please try again.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro send_email_verification_failure} | ||||
| class SendEmailVerificationFailureBase | ||||
|     extends SendEmailVerificationFailureInterface { | ||||
|   SendEmailVerificationFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   SendEmailVerificationFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro send_password_reset_email_failure} | ||||
| class SendPasswordResetEmailFailureBase | ||||
|     extends SendPasswordResetEmailFailureInterface { | ||||
|   SendPasswordResetEmailFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SendPasswordResetEmailFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro send_sign_in_link_email_failure} | ||||
| class SendSignInLinkEmailFailureBase | ||||
|     extends SendSignInLinkEmailFailureInterface { | ||||
|   SendSignInLinkEmailFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   SendSignInLinkEmailFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro confirm_password_reset_failure} | ||||
| class ConfirmPasswordResetFailureBase | ||||
|     extends ConfirmPasswordResetFailureInterface { | ||||
|   ConfirmPasswordResetFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   ConfirmPasswordResetFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro verify_password_reset_code_failure} | ||||
| class VerifyPasswordResetCodeFailureBase | ||||
|     extends VerifyPasswordResetCodeFailureInterface { | ||||
|   VerifyPasswordResetCodeFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   VerifyPasswordResetCodeFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro refresh_failure} | ||||
| class RefreshFailureBase extends RefreshFailureInterface { | ||||
|   RefreshFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   RefreshFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_out_failure} | ||||
| class SignOutFailureBase extends SignOutFailureInterface { | ||||
|   SignOutFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   SignOutFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro reauthenticate_failure} | ||||
| class ReauthenticateFailureBase extends ReauthenticateFailureInterface { | ||||
|   ReauthenticateFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   ReauthenticateFailureBase.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'user-mismatch': | ||||
|         msg = 'Given credential does not correspond to the user.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'User is not found, please create an account.'; | ||||
|         break; | ||||
|       case 'invalid-credential': | ||||
|         msg = 'The credential received is malformed or has expired.'; | ||||
|         break; | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'wrong-password': | ||||
|         msg = 'Incorrect password, please try again.'; | ||||
|         break; | ||||
|       case 'invalid-verification-code': | ||||
|         msg = 'The credential verification code received is invalid.'; | ||||
|         break; | ||||
|       case 'invalid-verification-id': | ||||
|         msg = 'The credential verification ID received is invalid.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro update_email_failure} | ||||
| class UpdateEmailFailureBase extends UpdateEmailFailureInterface { | ||||
|   UpdateEmailFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   UpdateEmailFailureBase.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'email-already-in-use': | ||||
|         msg = 'An account already exists for that email.'; | ||||
|         break; | ||||
|       case 'requires-recent-login': | ||||
|         msg = "User's last sign-in time does not meet the security threshold."; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro update_password_failure} | ||||
| class UpdatePasswordFailureBase extends UpdatePasswordFailureInterface { | ||||
|   UpdatePasswordFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   UpdatePasswordFailureBase.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'weak-password': | ||||
|         msg = 'Please enter a stronger password.'; | ||||
|         break; | ||||
|       case 'requires-recent-login': | ||||
|         msg = "User's last sign-in time does not meet the security threshold."; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro model_parsing_failure} | ||||
| class ModelParsingFailureBase extends ModelParsingFailureInterface { | ||||
|   ModelParsingFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   ModelParsingFailureBase.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro delete_account_failure} | ||||
| class DeleteAccountFailureBase extends DeleteAccountFailureInterface { | ||||
|   DeleteAccountFailureBase([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   DeleteAccountFailureBase.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.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,390 @@ | ||||
| // 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/>. | ||||
| 
 | ||||
| part of 'exceptions.dart'; | ||||
| 
 | ||||
| /// {@macro apply_action_code_failure} | ||||
| class ApplyActionCodeFailureMock extends ApplyActionCodeFailureInterface { | ||||
|   ApplyActionCodeFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   ApplyActionCodeFailureMock.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'expired-action-code': | ||||
|         msg = 'Action code has expired.'; | ||||
|         break; | ||||
|       case 'invalid-action-code': | ||||
|         msg = 'Action code is invalid.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'Email is not found, please create an account.'; | ||||
|         break; | ||||
| 
 | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_up_with_email_and_password_failure} | ||||
| class SignUpWithEmailAndPasswordFailureMock | ||||
|     extends SignUpWithEmailAndPasswordFailureInterface { | ||||
|   SignUpWithEmailAndPasswordFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignUpWithEmailAndPasswordFailureMock.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'The email address is badly formatted.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'email-already-in-use': | ||||
|         msg = 'An account already exists for that email.'; | ||||
|         break; | ||||
|       case 'operation-not-allowed': | ||||
|         msg = 'Operation is not allowed. Please contact support.'; | ||||
|         break; | ||||
|       case 'weak-password': | ||||
|         msg = 'Please enter a stronger password.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro fetch_sign_in_methods_failure} | ||||
| class FetchSignInMethodsForEmailFailureMock | ||||
|     extends FetchSignInMethodsForEmailFailureInterface { | ||||
|   FetchSignInMethodsForEmailFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   FetchSignInMethodsForEmailFailureMock.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'The email address is badly formatted.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_anonymously_failure} | ||||
| class SignInAnonymouslyFailureMock | ||||
|     extends SignInAnonymouslyFailureInterface { | ||||
|   SignInAnonymouslyFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInAnonymouslyFailureMock.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'operation-not-allowed': | ||||
|         msg = 'Operation is not allowed. Please contact support.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_credential_failure} | ||||
| class SignInWithCredentialFailureMock | ||||
|     extends SignInWithCredentialFailureInterface { | ||||
|   SignInWithCredentialFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInWithCredentialFailureMock.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'account-exists-with-different-credential': | ||||
|         msg = 'Account exists with different credentials.'; | ||||
|         break; | ||||
|       case 'invalid-credential': | ||||
|         msg = 'The credential received is malformed or has expired.'; | ||||
|         break; | ||||
|       case 'operation-not-allowed': | ||||
|         msg = 'Operation is not allowed. Please contact support.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'Email is not found, please create an account.'; | ||||
|         break; | ||||
|       case 'wrong-password': | ||||
|         msg = 'Incorrect password, please try again.'; | ||||
|         break; | ||||
|       case 'invalid-verification-code': | ||||
|         msg = 'The credential verification code received is invalid.'; | ||||
|         break; | ||||
|       case 'invalid-verification-id': | ||||
|         msg = 'The credential verification ID received is invalid.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_google_failure} | ||||
| class SignInWithGoogleFailureMock | ||||
|     extends SignInWithCredentialFailureMock | ||||
|     implements SignInWithGoogleFailureInterface { | ||||
|   SignInWithGoogleFailureMock([super.code, super.msg]); | ||||
|   SignInWithGoogleFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_facebook_failure} | ||||
| class SignInWithFacebookFailureMock | ||||
|     extends SignInWithCredentialFailureMock | ||||
|     implements SignInWithFacebookFailureInterface { | ||||
|   SignInWithFacebookFailureMock([super.code, super.msg]); | ||||
|   SignInWithFacebookFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_apple_failure} | ||||
| class SignInWithAppleFailureMock extends SignInWithCredentialFailureMock | ||||
|     implements SignInWithAppleFailureInterface { | ||||
|   SignInWithAppleFailureMock([super.code, super.msg]); | ||||
|   SignInWithAppleFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_twitter_failure} | ||||
| class SignInWithTwitterFailureMock | ||||
|     extends SignInWithCredentialFailureMock | ||||
|     implements SignInWithAppleFailureInterface { | ||||
|   SignInWithTwitterFailureMock([super.code, super.msg]); | ||||
|   SignInWithTwitterFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_email_link_failure} | ||||
| class SignInWithEmailLinkFailureMock | ||||
|     extends SignInWithEmailLinkFailureInterface { | ||||
|   SignInWithEmailLinkFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInWithEmailLinkFailureMock.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'expired-action-code': | ||||
|         msg = 'Action code has expired.'; | ||||
|         break; | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_in_with_email_and_password_failure} | ||||
| class SignInWithEmailAndPasswordFailureMock | ||||
|     extends SignInWithEmailAndPasswordFailureInterface { | ||||
|   SignInWithEmailAndPasswordFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SignInWithEmailAndPasswordFailureMock.fromCode(String code) | ||||
|       : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'user-disabled': | ||||
|         msg = 'This user has been disabled. Please contact support for help.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'Email is not found, please create an account.'; | ||||
|         break; | ||||
|       case 'wrong-password': | ||||
|         msg = 'Incorrect password, please try again.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro send_email_verification_failure} | ||||
| class SendEmailVerificationFailureMock | ||||
|     extends SendEmailVerificationFailureInterface { | ||||
|   SendEmailVerificationFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   SendEmailVerificationFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro send_password_reset_email_failure} | ||||
| class SendPasswordResetEmailFailureMock | ||||
|     extends SendPasswordResetEmailFailureInterface { | ||||
|   SendPasswordResetEmailFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   SendPasswordResetEmailFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro send_sign_in_link_email_failure} | ||||
| class SendSignInLinkEmailFailureMock | ||||
|     extends SendSignInLinkEmailFailureInterface { | ||||
|   SendSignInLinkEmailFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   SendSignInLinkEmailFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro confirm_password_reset_failure} | ||||
| class ConfirmPasswordResetFailureMock | ||||
|     extends ConfirmPasswordResetFailureInterface { | ||||
|   ConfirmPasswordResetFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   ConfirmPasswordResetFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro verify_password_reset_code_failure} | ||||
| class VerifyPasswordResetCodeFailureMock | ||||
|     extends VerifyPasswordResetCodeFailureInterface { | ||||
|   VerifyPasswordResetCodeFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   VerifyPasswordResetCodeFailureMock.fromCode(super.code) | ||||
|       : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro refresh_failure} | ||||
| class RefreshFailureMock extends RefreshFailureInterface { | ||||
|   RefreshFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   RefreshFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro sign_out_failure} | ||||
| class SignOutFailureMock extends SignOutFailureInterface { | ||||
|   SignOutFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   SignOutFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro reauthenticate_failure} | ||||
| class ReauthenticateFailureMock extends ReauthenticateFailureInterface { | ||||
|   ReauthenticateFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   ReauthenticateFailureMock.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'user-mismatch': | ||||
|         msg = 'Given credential does not correspond to the user.'; | ||||
|         break; | ||||
|       case 'user-not-found': | ||||
|         msg = 'User is not found, please create an account.'; | ||||
|         break; | ||||
|       case 'invalid-credential': | ||||
|         msg = 'The credential received is malformed or has expired.'; | ||||
|         break; | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'wrong-password': | ||||
|         msg = 'Incorrect password, please try again.'; | ||||
|         break; | ||||
|       case 'invalid-verification-code': | ||||
|         msg = 'The credential verification code received is invalid.'; | ||||
|         break; | ||||
|       case 'invalid-verification-id': | ||||
|         msg = 'The credential verification ID received is invalid.'; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro update_email_failure} | ||||
| class UpdateEmailFailureMock extends UpdateEmailFailureInterface { | ||||
|   UpdateEmailFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   UpdateEmailFailureMock.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'invalid-email': | ||||
|         msg = 'Email is not valid or badly formatted.'; | ||||
|         break; | ||||
|       case 'email-already-in-use': | ||||
|         msg = 'An account already exists for that email.'; | ||||
|         break; | ||||
|       case 'requires-recent-login': | ||||
|         msg = "User's last sign-in time does not meet the security threshold."; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro update_password_failure} | ||||
| class UpdatePasswordFailureMock extends UpdatePasswordFailureInterface { | ||||
|   UpdatePasswordFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
|   UpdatePasswordFailureMock.fromCode(String code) : super.fromCode(code) { | ||||
|     switch (code) { | ||||
|       case 'weak-password': | ||||
|         msg = 'Please enter a stronger password.'; | ||||
|         break; | ||||
|       case 'requires-recent-login': | ||||
|         msg = "User's last sign-in time does not meet the security threshold."; | ||||
|         break; | ||||
|       default: | ||||
|         this.code = 'unknown'; | ||||
|         msg = 'An unknown error occurred.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// {@macro model_parsing_failure} | ||||
| class ModelParsingFailureMock extends ModelParsingFailureInterface { | ||||
|   ModelParsingFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   ModelParsingFailureMock.fromCode(super.code) : super.fromCode(); | ||||
| } | ||||
| 
 | ||||
| /// {@macro delete_account_failure} | ||||
| class DeleteAccountFailureMock extends DeleteAccountFailureInterface { | ||||
|   DeleteAccountFailureMock([String? code, String? msg]) | ||||
|       : super(code ?? 'unknown', msg ?? 'An unknown error occurred.'); | ||||
| 
 | ||||
|   DeleteAccountFailureMock.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.'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,75 @@ | ||||
| // 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:flutter_secure_storage/flutter_secure_storage.dart'; | ||||
| import 'package:wyatt_authentication_bloc/src/core/constants/storage.dart'; | ||||
| import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; | ||||
| 
 | ||||
| /// {@template authentication_secure_storage_cache_data_source_impl} | ||||
| /// A data source that manages the cache strategy. | ||||
| /// This implementation uses Secure Storage. | ||||
| /// {@endtemplate} | ||||
| class AuthenticationSecureStorageCacheDataSourceImpl<Data> | ||||
|     extends AuthenticationCacheDataSource<Data> { | ||||
|   /// {@macro authentication_secure_storage_cache_data_source_impl} | ||||
|   const AuthenticationSecureStorageCacheDataSourceImpl({ | ||||
|     FlutterSecureStorage? secureStorage, | ||||
|   }) : _secureStorage = secureStorage ?? const FlutterSecureStorage(); | ||||
| 
 | ||||
|   final FlutterSecureStorage _secureStorage; | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> cacheAccount(Account account) async { | ||||
|     await _secureStorage.write( | ||||
|       key: AuthStorage.id, | ||||
|       value: account.id, | ||||
|     ); | ||||
|     await _secureStorage.write( | ||||
|       key: AuthStorage.email, | ||||
|       value: account.email, | ||||
|     ); | ||||
|     await _secureStorage.write( | ||||
|       key: AuthStorage.accessToken, | ||||
|       value: account.accessToken, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account?> getCachedAccount() async { | ||||
|     final id = await _secureStorage.read(key: AuthStorage.id); | ||||
|     final email = await _secureStorage.read(key: AuthStorage.email); | ||||
|     final accessToken = await _secureStorage.read(key: AuthStorage.accessToken); | ||||
| 
 | ||||
|     if (id == null || email == null || accessToken == null) { | ||||
|       return null; | ||||
|     } | ||||
| 
 | ||||
|     final currentAccount = AccountModel.fromSecureStorage( | ||||
|       id: id, | ||||
|       email: email, | ||||
|       accessToken: accessToken, | ||||
|     ); | ||||
| 
 | ||||
|     return currentAccount; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> removeCachedAccount() async { | ||||
|     await _secureStorage.delete(key: AuthStorage.id); | ||||
|     await _secureStorage.delete(key: AuthStorage.email); | ||||
|     await _secureStorage.delete(key: AuthStorage.accessToken); | ||||
|   } | ||||
| } | ||||
| @ -15,4 +15,5 @@ | ||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| export 'authentication_firebase_cache_data_source_impl.dart'; | ||||
| export 'authentication_secure_storage_cache_data_source_impl.dart'; | ||||
| export 'authentication_session_data_source_impl.dart'; | ||||
|  | ||||
| @ -0,0 +1,106 @@ | ||||
| // 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/wyatt_authentication_bloc.dart'; | ||||
| 
 | ||||
| /// {@template authentication_base_data_source} | ||||
| /// Base class for custom [AuthenticationRemoteDataSource] implementations. | ||||
| /// It implements all methods as throwing [UnimplementedError]s. | ||||
| /// {@endtemplate} | ||||
| class AuthenticationBaseDataSource<Data> | ||||
|     extends AuthenticationRemoteDataSource<Data> { | ||||
|   /// {@macro authentication_base_data_source} | ||||
|   const AuthenticationBaseDataSource(); | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> confirmPasswordReset({ | ||||
|     required String code, | ||||
|     required String newPassword, | ||||
|   }) { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> delete() { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> reauthenticate() { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> refresh() { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> sendEmailVerification() { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> sendPasswordResetEmail({required String email}) { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> signInAnonymously() { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> signInWithEmailAndPassword({ | ||||
|     required String email, | ||||
|     required String password, | ||||
|   }) { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> signInWithGoogle() { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> signOut() { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> signUpWithEmailAndPassword({ | ||||
|     required String email, | ||||
|     required String password, | ||||
|   }) { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> updateEmail({required String email}) { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<Account> updatePassword({required String password}) { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<bool> verifyPasswordResetCode({required String code}) { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,201 @@ | ||||
| // 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:math'; | ||||
| 
 | ||||
| import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; | ||||
| import 'package:wyatt_type_utils/wyatt_type_utils.dart'; | ||||
| 
 | ||||
| /// {@template authentication_mock_data_source_impl} | ||||
| /// Implementation of [AuthenticationRemoteDataSource] using Mocks. | ||||
| /// {@endtemplate} | ||||
| class AuthenticationMockDataSourceImpl<Data> | ||||
|     extends AuthenticationRemoteDataSource<Data> { | ||||
|   /// {@macro authentication_mock_data_source_impl} | ||||
|   AuthenticationMockDataSourceImpl({ | ||||
|     this.mockData = const { | ||||
|       'test@test.fr': Pair('test12', '1'), | ||||
|       'alice@test.fr': Pair('alice12', '2'), | ||||
|       'bob@test.fr': Pair('bob1234', '3'), | ||||
|     }, | ||||
|     this.accessToken = 'mock_access_token', | ||||
|   }); | ||||
| 
 | ||||
|   /// Mock data. | ||||
|   /// Format: <email, <password, id>> | ||||
|   final Map<String, Pair<String, String>> mockData; | ||||
| 
 | ||||
|   /// Current user. | ||||
|   Account? _currentUser; | ||||
| 
 | ||||
|   /// Access token. | ||||
|   final String accessToken; | ||||
| 
 | ||||
|   /// A random delay to simulate network latency. | ||||
|   Future<void> _randomDelay() async { | ||||
|     await Future<void>.delayed( | ||||
|       Duration(milliseconds: Random().nextInt(400) + 200), | ||||
|     ); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // SignUp/SignIn methods ==================================================== | ||||
| 
 | ||||
|   /// {@macro signup_pwd} | ||||
|   @override | ||||
|   Future<Account> signUpWithEmailAndPassword({ | ||||
|     required String email, | ||||
|     required String password, | ||||
|   }) async { | ||||
|     await _randomDelay(); | ||||
|     mockData[email] = Pair(password, '4'); | ||||
| 
 | ||||
|     return _currentUser = Account( | ||||
|       id: '4', | ||||
|       isAnonymous: false, | ||||
|       emailVerified: false, | ||||
|       providerId: 'mock', | ||||
|       email: email, | ||||
|       accessToken: accessToken, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro signin_pwd} | ||||
|   @override | ||||
|   Future<Account> signInWithEmailAndPassword({ | ||||
|     required String email, | ||||
|     required String password, | ||||
|   }) async { | ||||
|     await _randomDelay(); | ||||
|     final pair = mockData[email]; | ||||
| 
 | ||||
|     if (pair == null || pair.left != password) { | ||||
|       throw SignInWithEmailAndPasswordFailureMock(); | ||||
|     } | ||||
| 
 | ||||
|     return _currentUser = Account( | ||||
|       id: pair.right!, | ||||
|       isAnonymous: false, | ||||
|       emailVerified: true, | ||||
|       providerId: 'mock', | ||||
|       email: email, | ||||
|       accessToken: accessToken, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro signin_anom} | ||||
|   @override | ||||
|   Future<Account> signInAnonymously() async { | ||||
|     await _randomDelay(); | ||||
|     return _currentUser = Account( | ||||
|       id: '5', | ||||
|       isAnonymous: true, | ||||
|       emailVerified: false, | ||||
|       providerId: 'mock', | ||||
|       accessToken: accessToken, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro signin_google} | ||||
|   @override | ||||
|   Future<Account> signInWithGoogle() async { | ||||
|     await _randomDelay(); | ||||
|     return _currentUser = Account( | ||||
|       id: '6', | ||||
|       isAnonymous: false, | ||||
|       emailVerified: true, | ||||
|       providerId: 'google.com', | ||||
|       email: 'mock@gmail.com', | ||||
|       accessToken: accessToken, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro signout} | ||||
|   @override | ||||
|   Future<void> signOut() async { | ||||
|     await _randomDelay(); | ||||
|     _currentUser = null; | ||||
|   } | ||||
| 
 | ||||
|   // Account management methods =============================================== | ||||
| 
 | ||||
|   /// {@macro refresh} | ||||
|   @override | ||||
|   Future<Account> refresh() async { | ||||
|     await _randomDelay(); | ||||
|     if (_currentUser == null) { | ||||
|       throw RefreshFailureMock(); | ||||
|     } | ||||
|     return _currentUser!; | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro reauthenticate} | ||||
|   @override | ||||
|   Future<Account> reauthenticate() async { | ||||
|     await _randomDelay(); | ||||
|     if (_currentUser == null) { | ||||
|       throw ReauthenticateFailureMock(); | ||||
|     } | ||||
|     return _currentUser!; | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro update_email} | ||||
|   @override | ||||
|   Future<Account> updateEmail({required String email}) async { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro update_password} | ||||
|   @override | ||||
|   Future<Account> updatePassword({required String password}) async { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro delete} | ||||
|   @override | ||||
|   Future<void> delete() async { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   // Email related stuff ====================================================== | ||||
| 
 | ||||
|   /// {@macro send_email_verification} | ||||
|   @override | ||||
|   Future<void> sendEmailVerification() async { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro send_password_reset_email} | ||||
|   @override | ||||
|   Future<void> sendPasswordResetEmail({required String email}) async { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro confirm_password_reset} | ||||
|   @override | ||||
|   Future<void> confirmPasswordReset({ | ||||
|     required String code, | ||||
|     required String newPassword, | ||||
|   }) async { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro verify_password_reset_code} | ||||
|   @override | ||||
|   Future<bool> verifyPasswordResetCode({required String code}) async { | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| } | ||||
| @ -14,4 +14,6 @@ | ||||
| // 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_base_data_source.dart'; | ||||
| export 'authentication_firebase_data_source_impl.dart'; | ||||
| export 'authentication_mock_data_source_impl.dart'; | ||||
|  | ||||
| @ -77,6 +77,30 @@ class AccountModel extends Account { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /// {@macro account_model} | ||||
|   factory AccountModel.fromSecureStorage({ | ||||
|     required String? id, | ||||
|     required String? email, | ||||
|     required String? accessToken, | ||||
|   }) { | ||||
|     if (id != null && email != null && accessToken != null) { | ||||
|       return AccountModel._( | ||||
|         user: null, | ||||
|         id: id, | ||||
|         emailVerified: false, | ||||
|         isAnonymous: false, | ||||
|         providerId: '', | ||||
|         email: email, | ||||
|         accessToken: accessToken, | ||||
|       ); | ||||
|     } else { | ||||
|       throw Exception( | ||||
|         'null-id-email-access-token' | ||||
|         'id, email, and accessToken cannot be null', | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   const AccountModel._({ | ||||
|     required this.user, | ||||
|     required super.id, | ||||
|  | ||||
| @ -16,8 +16,6 @@ | ||||
| 
 | ||||
| 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/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'; | ||||
| @ -152,6 +150,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|             email: email, | ||||
|             password: password, | ||||
|           ); | ||||
|           // Cache the account | ||||
|           await authenticationCacheDataSource.cacheAccount(account); | ||||
|           return account; | ||||
|         }, | ||||
|         (error) => error, | ||||
| @ -170,6 +170,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|             email: email, | ||||
|             password: password, | ||||
|           ); | ||||
|           // Cache the account | ||||
|           await authenticationCacheDataSource.cacheAccount(account); | ||||
|           return account; | ||||
|         }, | ||||
|         (error) => error, | ||||
| @ -194,6 +196,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|         () async { | ||||
|           final account = | ||||
|               await authenticationRemoteDataSource.signInWithGoogle(); | ||||
|           // Cache the account | ||||
|           await authenticationCacheDataSource.cacheAccount(account); | ||||
|           return account; | ||||
|         }, | ||||
|         (error) => error, | ||||
| @ -205,6 +209,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|       Result.tryCatchAsync<void, AppException, AppException>( | ||||
|         () async { | ||||
|           await authenticationRemoteDataSource.signOut(); | ||||
|           // Remove the cached account | ||||
|           await authenticationCacheDataSource.removeCachedAccount(); | ||||
|         }, | ||||
|         (error) => error, | ||||
|       ); | ||||
| @ -217,6 +223,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|       Result.tryCatchAsync<Account, AppException, AppException>( | ||||
|         () async { | ||||
|           final account = await authenticationRemoteDataSource.refresh(); | ||||
|           // Cache the account | ||||
|           await authenticationCacheDataSource.cacheAccount(account); | ||||
|           return account; | ||||
|         }, | ||||
|         (error) => error, | ||||
| @ -228,6 +236,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|       Result.tryCatchAsync<Account, AppException, AppException>( | ||||
|         () async { | ||||
|           final account = await authenticationRemoteDataSource.reauthenticate(); | ||||
|           // Cache the account | ||||
|           await authenticationCacheDataSource.cacheAccount(account); | ||||
|           return account; | ||||
|         }, | ||||
|         (error) => error, | ||||
| @ -240,6 +250,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|         () async { | ||||
|           final account = | ||||
|               await authenticationRemoteDataSource.updateEmail(email: email); | ||||
|           // Cache the account | ||||
|           await authenticationCacheDataSource.cacheAccount(account); | ||||
|           return account; | ||||
|         }, | ||||
|         (error) => error, | ||||
| @ -253,6 +265,8 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|           final account = await authenticationRemoteDataSource.updatePassword( | ||||
|             password: password, | ||||
|           ); | ||||
|           // Cache the account | ||||
|           await authenticationCacheDataSource.cacheAccount(account); | ||||
|           return account; | ||||
|         }, | ||||
|         (error) => error, | ||||
| @ -262,7 +276,11 @@ class AuthenticationRepositoryImpl<Data extends Object> | ||||
|   @override | ||||
|   FutureOrResult<void> delete() => | ||||
|       Result.tryCatchAsync<void, AppException, AppException>( | ||||
|         () async => authenticationRemoteDataSource.delete(), | ||||
|         () async { | ||||
|           await authenticationRemoteDataSource.delete(); | ||||
|           // Remove the cached account | ||||
|           await authenticationCacheDataSource.removeCachedAccount(); | ||||
|         }, | ||||
|         (error) => error, | ||||
|       ); | ||||
| 
 | ||||
|  | ||||
| @ -29,6 +29,8 @@ dependencies: | ||||
|   wyatt_type_utils: | ||||
|     hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/ | ||||
|     version: ^0.0.4 | ||||
|   flutter_secure_storage: ^8.0.0 | ||||
|   http: ^0.13.5 | ||||
| 
 | ||||
| dev_dependencies: | ||||
|   flutter_test: { sdk: flutter } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user