From 148539029a85b56bf8f9bb8e9e9167862a1e8fc5 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Wed, 1 May 2024 11:02:36 -0700 Subject: [PATCH 1/2] feat(auth): add a default deviceName when remembering device --- .../providers/cognito/fetchDevices.test.ts | 8 ++- .../providers/cognito/apis/fetchDevices.ts | 3 ++ .../providers/cognito/utils/signInHelpers.ts | 2 + packages/core/src/libraryUtils.ts | 1 + .../utils/deviceName/getDeviceName.native.ts | 15 ++++++ .../src/utils/deviceName/getDeviceName.ts | 52 +++++++++++++++++++ packages/core/src/utils/deviceName/index.ts | 4 ++ packages/core/src/utils/deviceName/types.ts | 44 ++++++++++++++++ 8 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 packages/core/src/utils/deviceName/getDeviceName.native.ts create mode 100644 packages/core/src/utils/deviceName/getDeviceName.ts create mode 100644 packages/core/src/utils/deviceName/index.ts create mode 100644 packages/core/src/utils/deviceName/types.ts diff --git a/packages/auth/__tests__/providers/cognito/fetchDevices.test.ts b/packages/auth/__tests__/providers/cognito/fetchDevices.test.ts index a3f6fb40384..c7b09e53d8a 100644 --- a/packages/auth/__tests__/providers/cognito/fetchDevices.test.ts +++ b/packages/auth/__tests__/providers/cognito/fetchDevices.test.ts @@ -26,7 +26,10 @@ describe('fetchDevices', () => { const dateEpoch = 1.696296885807e9; const date = new Date(dateEpoch * 1000); const clientResponseDevice = { - DeviceAttributes: [{ Name: 'attributeName', Value: 'attributeValue' }], + DeviceAttributes: [ + { Name: 'attributeName', Value: 'attributeValue' }, + { Name: 'device_name', Value: 'deviceNameValue' }, + ], DeviceCreateDate: dateEpoch, DeviceKey: 'DeviceKey', DeviceLastAuthenticatedDate: dateEpoch, @@ -34,9 +37,10 @@ describe('fetchDevices', () => { }; const apiOutputDevice = { id: 'DeviceKey', - name: undefined, + name: 'deviceNameValue', attributes: { attributeName: 'attributeValue', + device_name: 'deviceNameValue', }, createDate: date, lastModifiedDate: date, diff --git a/packages/auth/src/providers/cognito/apis/fetchDevices.ts b/packages/auth/src/providers/cognito/apis/fetchDevices.ts index 2ac3bddde30..29be20e7a78 100644 --- a/packages/auth/src/providers/cognito/apis/fetchDevices.ts +++ b/packages/auth/src/providers/cognito/apis/fetchDevices.ts @@ -59,9 +59,11 @@ const parseDevicesResponse = async ( DeviceLastModifiedDate, DeviceLastAuthenticatedDate, }) => { + let deviceName: string | undefined; const attributes = DeviceAttributes.reduce( (attrs: any, { Name, Value }) => { if (Name && Value) { + if (Name === 'device_name') deviceName = Value; attrs[Name] = Value; } @@ -72,6 +74,7 @@ const parseDevicesResponse = async ( return { id, + name: deviceName, attributes, createDate: DeviceCreateDate ? new Date(DeviceCreateDate * 1000) diff --git a/packages/auth/src/providers/cognito/utils/signInHelpers.ts b/packages/auth/src/providers/cognito/utils/signInHelpers.ts index ce1336ce611..13edcd84e62 100644 --- a/packages/auth/src/providers/cognito/utils/signInHelpers.ts +++ b/packages/auth/src/providers/cognito/utils/signInHelpers.ts @@ -7,6 +7,7 @@ import { AuthAction, assertTokenProviderConfig, base64Encoder, + getDeviceName, } from '@aws-amplify/core/internals/utils'; import { ClientMetadata, ConfirmSignInOptions } from '../types'; @@ -1072,6 +1073,7 @@ export async function getNewDeviceMetatada( { region: getRegion(userPoolId) }, { AccessToken: accessToken, + DeviceName: await getDeviceName(), DeviceKey: newDeviceMetadata?.DeviceKey, DeviceSecretVerifierConfig: deviceSecretVerifierConfig, }, diff --git a/packages/core/src/libraryUtils.ts b/packages/core/src/libraryUtils.ts index 1eadf9d5c5a..717bfc7805a 100644 --- a/packages/core/src/libraryUtils.ts +++ b/packages/core/src/libraryUtils.ts @@ -29,6 +29,7 @@ export { amplifyUuid } from './utils/amplifyUuid'; export { AmplifyUrl, AmplifyUrlSearchParams } from './utils/amplifyUrl'; export { parseAmplifyConfig } from './utils/parseAmplifyConfig'; export { getClientInfo } from './utils'; +export { getDeviceName } from './utils/deviceName'; // Auth utilities export { diff --git a/packages/core/src/utils/deviceName/getDeviceName.native.ts b/packages/core/src/utils/deviceName/getDeviceName.native.ts new file mode 100644 index 00000000000..e8257aaa807 --- /dev/null +++ b/packages/core/src/utils/deviceName/getDeviceName.native.ts @@ -0,0 +1,15 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { getDeviceName as getDeviceNameNative } from '@aws-amplify/react-native'; + +/** + * Retrieves the device name using name in ios and model in android, + * + * @returns {Promise} A promise that resolves with a string representing the device name. + * + * Example Output: + * ios: 'iPhone' / 'user's iPhone' + * android: 'sdk_gphone64_arm64' + */ +export const getDeviceName = async (): Promise => getDeviceNameNative(); diff --git a/packages/core/src/utils/deviceName/getDeviceName.ts b/packages/core/src/utils/deviceName/getDeviceName.ts new file mode 100644 index 00000000000..3916ba7b36e --- /dev/null +++ b/packages/core/src/utils/deviceName/getDeviceName.ts @@ -0,0 +1,52 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { NavigatorUA } from './types'; +/** + * Retrieves the device name using the User-Agent Client Hints API if available, + * falling back to the traditional userAgent string if not. + * + * @returns {Promise} A promise that resolves with a string representing the device name. + * + * Example Output: + * navigator.userAgentData: + * 'macOS 14.2.1 arm macOS Not A(Brand/99.0.0.0;Google Chrome/121.0.6167.160;Chromium/121.0.6167.160' + * navigator.userAgent: + * 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/115.0' + */ +export const getDeviceName = async (): Promise => { + const { userAgentData } = navigator as NavigatorUA; + + if (!userAgentData) return navigator.userAgent; + + const { + platform = '', + platformVersion = '', + model = '', + architecture = '', + fullVersionList = [], + } = await userAgentData.getHighEntropyValues([ + 'platform', + 'platformVersion', + 'architecture', + 'model', + 'fullVersionList', + ]); + + const versionList = fullVersionList + .map((v: { brand: string; version: string }) => `${v.brand}/${v.version}`) + .join(';'); + + const deviceName = [ + platform, + platformVersion, + architecture, + model, + platform, + versionList, + ] + .filter(value => value) + .join(' '); + + return deviceName; +}; diff --git a/packages/core/src/utils/deviceName/index.ts b/packages/core/src/utils/deviceName/index.ts new file mode 100644 index 00000000000..13b50ee98bd --- /dev/null +++ b/packages/core/src/utils/deviceName/index.ts @@ -0,0 +1,4 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +export { getDeviceName } from './getDeviceName'; diff --git a/packages/core/src/utils/deviceName/types.ts b/packages/core/src/utils/deviceName/types.ts new file mode 100644 index 00000000000..06980d1bf67 --- /dev/null +++ b/packages/core/src/utils/deviceName/types.ts @@ -0,0 +1,44 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// WICG Spec: https://wicg.github.io/ua-client-hints + +// https://wicg.github.io/ua-client-hints/#navigatorua +export interface NavigatorUA { + readonly userAgentData?: NavigatorUAData; +} + +// https://wicg.github.io/ua-client-hints/#dictdef-navigatoruabrandversion +interface NavigatorUABrandVersion { + readonly brand: string; + readonly version: string; +} + +// https://wicg.github.io/ua-client-hints/#dictdef-uadatavalues +interface UADataValues { + readonly brands?: NavigatorUABrandVersion[]; + readonly mobile?: boolean; + readonly platform?: string; + readonly architecture?: string; + readonly bitness?: string; + readonly formFactor?: string[]; + readonly model?: string; + readonly platformVersion?: string; + /** @deprecated in favour of fullVersionList */ + readonly uaFullVersion?: string; + readonly fullVersionList?: NavigatorUABrandVersion[]; + readonly wow64?: boolean; +} + +// https://wicg.github.io/ua-client-hints/#dictdef-ualowentropyjson +interface UALowEntropyJSON { + readonly brands: NavigatorUABrandVersion[]; + readonly mobile: boolean; + readonly platform: string; +} + +// https://wicg.github.io/ua-client-hints/#navigatoruadata +interface NavigatorUAData extends UALowEntropyJSON { + getHighEntropyValues(hints: string[]): Promise; + toJSON(): UALowEntropyJSON; +} From ddfd5e2895e3ae57641bc4ff04a35ed1c3192ba8 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Wed, 1 May 2024 13:59:47 -0700 Subject: [PATCH 2/2] increase bundle size --- packages/aws-amplify/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-amplify/package.json b/packages/aws-amplify/package.json index 7e2f6090c8a..a3254ed2252 100644 --- a/packages/aws-amplify/package.json +++ b/packages/aws-amplify/package.json @@ -383,7 +383,7 @@ "name": "[Auth] confirmSignIn (Cognito)", "path": "./dist/esm/auth/index.mjs", "import": "{ confirmSignIn }", - "limit": "28.10 kB" + "limit": "28.26 kB" }, { "name": "[Auth] updateMFAPreference (Cognito)", @@ -449,7 +449,7 @@ "name": "[Auth] Basic Auth Flow (Cognito)", "path": "./dist/esm/auth/index.mjs", "import": "{ signIn, signOut, fetchAuthSession, confirmSignIn }", - "limit": "29.90 kB" + "limit": "30.06 kB" }, { "name": "[Auth] OAuth Auth Flow (Cognito)",