Skip to content

Commit

Permalink
Updated initAuth() to validate login credentials
Browse files Browse the repository at this point in the history
Signed-off-by: Khalid Warsame <dev@khalidwar.com>
  • Loading branch information
KhalidWar committed Mar 12, 2022
1 parent 178c4ae commit f48b002
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 24 deletions.
4 changes: 2 additions & 2 deletions lib/services/access_token/access_token_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ class AccessTokenService {
key: SecureStorageKeys.instanceURLKey, value: url);
}

Future<String?> getAccessToken(
Future<String> getAccessToken(
{String key = SecureStorageKeys.accessTokenKey}) async {
final accessToken = await secureStorage.read(key: key);
return accessToken;
return accessToken ?? '';
}

Future<String> getInstanceURL() async {
Expand Down
66 changes: 44 additions & 22 deletions lib/state_management/authorization/auth_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,45 +89,67 @@ class AuthNotifier extends StateNotifier<AuthState> {
}
}

/// Initializes
/// Manages authentication flow at app startup.
/// 1. Fetches stored access token and instance url.
/// 2. Attempts to login to check if token and url are valid.
/// 3. If valid, set [state] to [AuthorizationStatus.authorized].
/// 4. If invalid, set [state] to [AuthorizationStatus.unauthorized].
///
/// It also checks if user's device supports biometric authentication.
/// Then sets [state] accordingly.
Future<void> initAuth() async {
try {
final accessToken = await tokenService.getAccessToken();
const bioAuthKey = BiometricNotifier.biometricAuthKey;
final bioKeyValue = await secureStorage.read(key: bioAuthKey);
final isLoginValid = await _validateLoginCredential();
final canCheck = await biometricService.doesPlatformSupportAuth();
final authStatus = await _getBioAuthState();

/// When a logged in is NOT found
if (accessToken == null || accessToken.isEmpty) {
if (isLoginValid) {
final newState = state.copyWith(
authorizationStatus: AuthorizationStatus.unauthorized);
authorizationStatus: AuthorizationStatus.authorized,
authenticationStatus:
canCheck ? authStatus : AuthenticationStatus.unavailable,
);
_updateState(newState);
} else {
/// When a logged in is NOT found
//todo validate accessToken and return unauthorized if it fails
final canCheck = await biometricService.doesPlatformSupportAuth();
final savedAuthStatus = _initBioAuth(bioKeyValue);

final newState = state.copyWith(
authorizationStatus: AuthorizationStatus.authorized,
authorizationStatus: AuthorizationStatus.unauthorized,
authenticationStatus:
canCheck ? savedAuthStatus : AuthenticationStatus.unavailable,
canCheck ? authStatus : AuthenticationStatus.unavailable,
);
_updateState(newState);
}
} catch (error) {
rethrow;
NicheMethod.showToast(error.toString());
}
}

AuthenticationStatus _initBioAuth(String? input) {
if (input == null) {
return AuthenticationStatus.disabled;
/// Fetches and validates stored login credentials
/// and returns bool if valid or not
Future<bool> _validateLoginCredential() async {
try {
final token = await tokenService.getAccessToken();
final url = await tokenService.getInstanceURL();
if (token.isEmpty || url.isEmpty) return false;

final isValid = await tokenService.validateAccessToken(url, token);
return isValid;
} catch (error) {
rethrow;
}
}

if (input == 'true') {
return AuthenticationStatus.enabled;
} else {
return AuthenticationStatus.disabled;
Future<AuthenticationStatus> _getBioAuthState() async {
try {
const bioAuthKey = BiometricNotifier.biometricAuthKey;
final bioAuthValue = await secureStorage.read(key: bioAuthKey);

if (bioAuthValue == null) return AuthenticationStatus.disabled;

return bioAuthValue == 'true'
? AuthenticationStatus.enabled
: AuthenticationStatus.disabled;
} catch (error) {
rethrow;
}
}
}

0 comments on commit f48b002

Please sign in to comment.