Trusted device tracking and management for enhanced security and user experience.
Get a list of all devices associated with the current user.
function fetchDevices(): Promise<FetchDevicesOutput>;
interface FetchDevicesOutput {
devices: AWSAuthDevice[];
}
interface AWSAuthDevice {
id: string;
name?: string;
attributes?: Record<string, string>;
createDate?: Date;
lastModifiedDate?: Date;
lastAccessedDate?: Date;
}import { fetchDevices } from "@aws-amplify/auth";
const { devices } = await fetchDevices();
devices.forEach(device => {
console.log(`Device ID: ${device.id}`);
console.log(`Device Name: ${device.name || 'Unknown'}`);
console.log(`Last Accessed: ${device.lastAccessedDate}`);
console.log(`Attributes:`, device.attributes);
console.log('---');
});Mark the current device as trusted/remembered to skip MFA on future sign-ins.
function rememberDevice(): Promise<void>;import { rememberDevice } from "@aws-amplify/auth";
// After successful sign-in with MFA, allow user to remember device
const shouldRememberDevice = confirm("Remember this device for future sign-ins?");
if (shouldRememberDevice) {
await rememberDevice();
console.log("Device marked as trusted");
}Remove a device from the trusted devices list, requiring MFA on next sign-in.
function forgetDevice(input?: ForgetDeviceInput): Promise<void>;
interface ForgetDeviceInput {
device?: {
id: string;
};
}import { forgetDevice, fetchDevices } from "@aws-amplify/auth";
// Forget current device
await forgetDevice();
console.log("Current device forgotten");
// Forget a specific device
const { devices } = await fetchDevices();
const deviceToForget = devices.find(d => d.name === 'Old Phone');
if (deviceToForget) {
await forgetDevice({
device: { id: deviceToForget.id }
});
console.log(`Device ${deviceToForget.name} forgotten`);
}When a user signs in from a new device with MFA enabled:
import { signIn, confirmSignIn, rememberDevice } from "@aws-amplify/auth";
// Sign in process
const { isSignedIn, nextStep } = await signIn({
username: "user@example.com",
password: "MyPassword123!"
});
if (!isSignedIn && nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_SMS_CODE') {
// User enters MFA code
const mfaCode = "123456"; // from user input
const { isSignedIn: mfaComplete } = await confirmSignIn({
challengeResponse: mfaCode
});
if (mfaComplete) {
// Offer to remember device
const shouldRemember = confirm("Remember this device to skip MFA next time?");
if (shouldRemember) {
await rememberDevice();
}
}
}Building a device management interface:
import { fetchDevices, forgetDevice } from "@aws-amplify/auth";
async function buildDeviceManager() {
const { devices } = await fetchDevices();
const deviceList = devices.map(device => ({
id: device.id,
name: device.name || `Device ${device.id.slice(-4)}`,
lastAccessed: device.lastAccessedDate?.toLocaleDateString(),
isCurrentDevice: device.id === getCurrentDeviceId(), // Your implementation
async forget() {
await forgetDevice({ device: { id: device.id } });
console.log(`Device ${this.name} removed from trusted devices`);
}
}));
return deviceList;
}
// Usage in React component or similar
const devices = await buildDeviceManager();
devices.forEach(device => {
console.log(`${device.name} - Last accessed: ${device.lastAccessed}`);
});Device attributes provide additional information about each device:
// Common device attributes
interface DeviceAttributes {
'device_name'?: string; // User-friendly device name
'device_key'?: string; // Unique device identifier
'device_group_key'?: string; // Device group identifier
'device_remembered_status'?: string; // 'remembered' | 'not_remembered'
[key: string]: string | undefined; // Custom attributes
}
// Example of working with device attributes
const { devices } = await fetchDevices();
const currentDevice = devices[0];
if (currentDevice.attributes) {
const deviceName = currentDevice.attributes['device_name'] || 'Unknown Device';
const isRemembered = currentDevice.attributes['device_remembered_status'] === 'remembered';
console.log(`Device: ${deviceName}, Remembered: ${isRemembered}`);
}// Example device trust management
class DeviceTrustManager {
private readonly MAX_TRUSTED_DEVICES = 5;
private readonly TRUST_DURATION_DAYS = 30;
async manageTrustedDevices() {
const { devices } = await fetchDevices();
// Remove old trusted devices
const oldDevices = devices.filter(device => {
const lastAccessed = device.lastAccessedDate;
if (!lastAccessed) return true;
const daysSinceAccess = (Date.now() - lastAccessed.getTime()) / (1000 * 60 * 60 * 24);
return daysSinceAccess > this.TRUST_DURATION_DAYS;
});
// Forget old devices
for (const device of oldDevices) {
await forgetDevice({ device: { id: device.id } });
console.log(`Removed stale device: ${device.name}`);
}
// Check device limit
const remainingDevices = devices.length - oldDevices.length;
if (remainingDevices >= this.MAX_TRUSTED_DEVICES) {
console.warn('Maximum trusted devices reached');
return false;
}
return true;
}
async rememberCurrentDevice() {
const canTrust = await this.manageTrustedDevices();
if (canTrust) {
await rememberDevice();
return true;
}
return false;
}
}import { fetchDevices, forgetDevice, AuthError } from "@aws-amplify/auth";
try {
const { devices } = await fetchDevices();
} catch (error) {
if (error instanceof AuthError) {
switch (error.name) {
case 'NotAuthorizedException':
console.log('User not signed in');
break;
case 'ResourceNotFoundException':
console.log('User pool not found');
break;
case 'InvalidParameterException':
console.log('Invalid request parameters');
break;
default:
console.log('Failed to fetch devices:', error.message);
}
}
}
try {
await forgetDevice({ device: { id: 'invalid-device-id' } });
} catch (error) {
if (error instanceof AuthError) {
switch (error.name) {
case 'ResourceNotFoundException':
console.log('Device not found');
break;
case 'InvalidParameterException':
console.log('Invalid device ID');
break;
default:
console.log('Failed to forget device:', error.message);
}
}
}Device remembering works in conjunction with MFA:
This provides a balance between security and user experience, allowing trusted devices to bypass MFA while maintaining security for unknown devices.