diff --git a/packages/amplify_core/doc/lib/auth.dart b/packages/amplify_core/doc/lib/auth.dart index a69fde0f6c..e47f671733 100644 --- a/packages/amplify_core/doc/lib/auth.dart +++ b/packages/amplify_core/doc/lib/auth.dart @@ -483,6 +483,17 @@ Future forgetSpecificDevice(AuthDevice myDevice) async { } // #enddocregion forget-specific-device +// #docregion fetch-current-device +Future fetchCurrentUserDevice() async { + try { + final device = await Amplify.Auth.fetchCurrentDevice(); + safePrint('Device: $device'); + } on AuthException catch (e) { + safePrint('Get current device failed with error: $e'); + } +} +// #enddocregion fetch-current-device + // #docregion fetch-devices Future fetchAllDevices() async { try { diff --git a/packages/amplify_core/lib/src/category/amplify_auth_category.dart b/packages/amplify_core/lib/src/category/amplify_auth_category.dart index 4a23528d70..9ca67ff88c 100644 --- a/packages/amplify_core/lib/src/category/amplify_auth_category.dart +++ b/packages/amplify_core/lib/src/category/amplify_auth_category.dart @@ -1355,6 +1355,37 @@ class AuthCategory extends AmplifyCategory { () => defaultPlugin.rememberDevice(), ); + /// {@template amplify_core.amplify_auth_category.fetch_current_device} + /// Retrieves the current device. + /// + /// For more information about device tracking, see the + /// [Amplify docs](https://docs.amplify.aws/flutter/build-a-backend/auth/manage-users/manage-devices/#fetch-current-device). + /// + /// ## Examples + /// + /// + /// ```dart + /// import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; + /// import 'package:amplify_flutter/amplify_flutter.dart'; + /// ``` + /// + /// + /// ```dart + /// Future getCurrentUserDevice() async { + /// try { + /// final device = await Amplify.Auth.fetchCurrentDevice(); + /// safePrint('Device: $device'); + /// } on AuthException catch (e) { + /// safePrint('Get current device failed with error: $e'); + /// } + /// } + /// ``` + /// {@endtemplate} + Future fetchCurrentDevice() => identifyCall( + AuthCategoryMethod.fetchCurrentDevice, + () => defaultPlugin.fetchCurrentDevice(), + ); + /// {@template amplify_core.amplify_auth_category.forget_device} /// Forgets the current device. /// diff --git a/packages/amplify_core/lib/src/http/amplify_category_method.dart b/packages/amplify_core/lib/src/http/amplify_category_method.dart index a0c978594b..97ee62251e 100644 --- a/packages/amplify_core/lib/src/http/amplify_category_method.dart +++ b/packages/amplify_core/lib/src/http/amplify_category_method.dart @@ -52,7 +52,8 @@ enum AuthCategoryMethod with AmplifyCategoryMethod { setMfaPreference('49'), getMfaPreference('50'), setUpTotp('51'), - verifyTotpSetup('52'); + verifyTotpSetup('52'), + fetchCurrentDevice('59'); const AuthCategoryMethod(this.method); diff --git a/packages/amplify_core/lib/src/plugin/amplify_auth_plugin_interface.dart b/packages/amplify_core/lib/src/plugin/amplify_auth_plugin_interface.dart index 43e74853f3..80521de18d 100644 --- a/packages/amplify_core/lib/src/plugin/amplify_auth_plugin_interface.dart +++ b/packages/amplify_core/lib/src/plugin/amplify_auth_plugin_interface.dart @@ -189,6 +189,11 @@ abstract class AuthPluginInterface extends AmplifyPluginInterface { throw UnimplementedError('forgetDevice() has not been implemented.'); } + /// {@macro amplify_core.amplify_auth_category.fetch_current_device} + Future fetchCurrentDevice() { + throw UnimplementedError('fetchCurrentDevice() has not been implemented.'); + } + /// {@macro amplify_core.amplify_auth_category.fetch_devices} Future> fetchDevices() { throw UnimplementedError('fetchDevices() has not been implemented.'); diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/device_tracking_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/device_tracking_test.dart index 500582ad0a..8ff7de269e 100644 --- a/packages/auth/amplify_auth_cognito/example/integration_test/device_tracking_test.dart +++ b/packages/auth/amplify_auth_cognito/example/integration_test/device_tracking_test.dart @@ -240,6 +240,45 @@ void main() { await expectLater(Amplify.Auth.rememberDevice(), completes); }); + asyncTest('fetchCurrentDevice returns the current device', (_) async { + await expectLater(Amplify.Auth.fetchCurrentDevice(), completes); + final currentTestDevice = await Amplify.Auth.fetchCurrentDevice(); + final currentDeviceKey = await getDeviceKey(); + expect(currentDeviceKey, currentTestDevice.id); + }); + + asyncTest( + 'The device from fetchCurrentDevice isnt equal to another device.', + (_) async { + final previousDeviceKey = await getDeviceKey(); + await signOutUser(); + await deleteDevice(cognitoUsername, previousDeviceKey!); + await signIn(); + final newCurrentTestDevice = await Amplify.Auth.fetchCurrentDevice(); + expect(newCurrentTestDevice.id, isNot(previousDeviceKey)); + }); + + asyncTest( + 'fetchCurrentDevice throws a DeviceNotTrackedException when device is forgotton.', + (_) async { + expect(await getDeviceState(), DeviceState.remembered); + await Amplify.Auth.forgetDevice(); + await expectLater( + Amplify.Auth.fetchCurrentDevice, + throwsA(isA()), + ); + }); + + asyncTest( + 'fetchCurrentDevice throws a SignedOutException when device signs out.', + (_) async { + await signOutUser(); + await expectLater( + Amplify.Auth.fetchCurrentDevice, + throwsA(isA()), + ); + }); + asyncTest('forgetDevice stops tracking', (_) async { expect(await getDeviceState(), DeviceState.remembered); await Amplify.Auth.forgetDevice(); diff --git a/packages/auth/amplify_auth_cognito_dart/example/lib/common.dart b/packages/auth/amplify_auth_cognito_dart/example/lib/common.dart index 42347c4c90..b266f9ee7d 100644 --- a/packages/auth/amplify_auth_cognito_dart/example/lib/common.dart +++ b/packages/auth/amplify_auth_cognito_dart/example/lib/common.dart @@ -104,6 +104,10 @@ Future> fetchUserAttributes() async { return Amplify.Auth.fetchUserAttributes(); } +Future fetchCurrentDevice() async { + return Amplify.Auth.fetchCurrentDevice(); +} + Future> fetchDevices() async { return Amplify.Auth.fetchDevices(); }