Skip to content

fix(auth): SessionExpired Auth Hub event #2609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,16 @@ class AmplifyAuthCognitoDart extends AuthPluginInterface<
if (state is SignInSuccess) {
hubEvent = AuthHubEvent.signedIn(state.user.authUser);
}
if (state is FetchAuthSessionFailure &&
(state.exception is UnauthorizedException ||
state.exception is AuthNotAuthorizedException)) {
hubEvent = AuthHubEvent.sessionExpired();
if (state is FetchAuthSessionSuccess) {
final exception = state.session.userPoolTokensResult.exception;
// TODO(Jordan-Nelson): Update list of exceptions once FetchAuthSession
Copy link
Member Author

@Jordan-Nelson Jordan-Nelson Jan 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, an AuthNotAuthorizedException is thrown for an expired session, but it should be SessionExpiredException. This has always been the case in next and I have a task to update this.

UnauthorizedException was in the list previously, so I left it for now. I'll look into what scenarios what is thrown in to see if this needs to be included when I take care of the task mentioned above.

/// is updated to only throw SessionExpiredException for expired
/// sessions.
if (exception is UnauthorizedException ||
exception is AuthNotAuthorizedException ||
exception is SessionExpiredException) {
hubEvent = AuthHubEvent.sessionExpired();
}
}

if (hubEvent != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import 'package:amplify_auth_cognito_dart/amplify_auth_cognito_dart.dart';
import 'package:amplify_auth_cognito_dart/src/credentials/cognito_keys.dart';
import 'package:amplify_auth_cognito_dart/src/sdk/cognito_identity_provider.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:test/test.dart';

import '../common/jwt.dart';
import '../common/mock_clients.dart';
import '../common/mock_config.dart';
import '../common/mock_secure_storage.dart';

void main() {
AmplifyLogger().logLevel = LogLevel.verbose;

late CognitoAuthStateMachine stateMachine;
late AmplifyAuthCognitoDart plugin;

group('fetchAuthSession', () {
group('when session is expired', () {
setUp(() async {
final expiredIdToken = createJwt(
type: TokenType.id,
expiration: Duration.zero,
);
final secureStorage = MockSecureStorage();
seedStorage(
secureStorage,
identityPoolKeys: identityPoolKeys,
userPoolKeys: userPoolKeys,
);
secureStorage.write(
key: userPoolKeys[CognitoUserPoolKey.idToken],
value: expiredIdToken.raw,
);
stateMachine = CognitoAuthStateMachine();
plugin = AmplifyAuthCognitoDart(credentialStorage: secureStorage)
..stateMachine = stateMachine;
await plugin.configure(
config: mockConfig,
authProviderRepo: AmplifyAuthProviderRepository(),
);

stateMachine.addInstance<CognitoIdentityProviderClient>(
MockCognitoIdentityProviderClient(
initiateAuth: expectAsync0(
() async => throw const AuthNotAuthorizedException(
'Refresh Token has expired.',
),
),
),
);
});

test('should add a sessionExpired event to Auth Hub', () async {
final authStream = Amplify.Hub.availableStreams[HubChannel.Auth];
plugin.fetchAuthSession().ignore();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might fail on DDC - it doesn't like .ignore in tests for some reason (maybe due to #50619 in the Dart repo). Alternative is the same but more verbose:

unawaited(
  plugin.fetchAuthSession().then((_) {}).onError((_, __) {}),
);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They seem to be passing (at least on firefox, looks like they are not running on Chrome) so I will leave for now. If it causes an issue we can change it.

await expectLater(authStream, emits(AuthHubEvent.sessionExpired()));
});
});

tearDown(() async {
await plugin.close();
});
});
}