Show Registered Devices

📱 Registered Devices Overview

The Registered Devices feature allows the application to retrieve and manage all devices associated with a specific user. This information helps users view their active sessions and device history, and enables secure device management actions such as renaming or removing devices.


🧩 Key Concepts

ConceptDescription
getRegisteredDeviceDetails APIUsed to fetch all devices registered to a user
onGetRegistredDeviceDetails eventCallback triggered with the list of devices and their metadata
deviceManagementCoolingPeriodEndTimestampA timestamp during which edit/delete actions are restricted

🛠 When to Use

  • Displaying a list of user's previously registered devices
  • Enabling device rename or delete actions in the UI
  • Enforcing cooldown periods after sensitive changes or security events

📦 Typical Use Case

  1. User opens the Device Management screen
  2. App calls getRegisteredDeviceDetails(userId)
  3. SDK triggers onGetRegistredDeviceDetails with a list of devices
  4. App filters out expired or deactivated devices
  5. UI disables actions for devices under cooling period

📥 getRegisteredDeviceDetails API

Overview

The getRegisteredDeviceDetails API is used to retrieve a list of all devices registered under a given user ID. This allows apps to show users their active sessions and manage device-specific actions like renaming, deletion, and security enforcement.


🧠 Functionality

  • Fetches all devices associated with a user
  • Triggers the onGetRegistredDeviceDetails callback with detailed metadata
  • Used in device management screens or settings sections

Request parameters

ParameterTypeRequiredDescription
userIDStringUnique user identifier.


📩 Event: onGetRegistredDeviceDetails

Overview

The onGetRegistredDeviceDetails event is emitted by the REL-ID SDK in response to the getRegisteredDeviceDetails API call. This functionality allows an app to retrieve and present a list of devices associated with a user's account.


Sample Payload

{
  "errCode": 0,
  "error": {
    "longErrorCode": 0,
    "shortErrorCode": 0,
    "errorString": "Success"
  },
  "eMethId": 12,
  "pArgs": {
    "jwt": "",
    "service_details": {},
    "response": {
      "ResponseData": {
        "device": [
          {
            "devUUID": "1J02T42WFFDFYS7IF3SM4QU96N8UQ2J5ZI4R6UNAJMES3601T5",
            "devName": "Android_Lenovo A7020a48_070820071831",
            "status": "ACTIVE",
            "lastAccessedTs": "2020-07-08T07:18:46UTC",
            "createdTs": "2020-07-08T07:18:13UTC",
            "appUuid": "0676491d-37db-4c0d-b649-1d37db6c0ddf",
            "devBind": 0
          }
        ],
        "deviceManagementCoolingPeriodEndTimestamp": 1747306419000
      },
      "ResponseDataLen": 293,
      "StatusMsg": "Success.",
      "StatusCode": 100,
      "CredOpMode": -1
    },
    "pxyDetails": {
      "isStarted": 0,
      "isLocalhostOnly": 0,
      "isAutoStarted": 0,
      "isPrivacyEnabled": 0,
      "portType": 0,
      "port": 0
    }
  }
}

🔑 Device Fields

FieldDescription
devUUIDUnique identifier for the device
devNameDevice's display name
statusStatus: ACTIVE, DELETE, BLOCKED, etc.
lastAccessedTsISO timestamp when the device was last used
createdTsISO timestamp when the device was registered
currentDevicetrue if it is the device currently in use
devBind0 for permanent, 1 for temporary binding
deviceManagementCoolingPeriodEndTimestampTemporarily restricts device management operations (likedevice deletion or name changes) for a specified period.

🔄 Field: status Values

StatusDescriptionScreen Behavior
ACTIVEDevice is active and usableShow as "active"
BLOCKEDDevice is blockedDisable interactions, show warning
DELETEDevice has been marked for deletionDo not allow changes

🖥️ UI Screen Requirements

The app must display a "Registered Devices" screen to the user, showing the following:

  • Device name (editable or read-only)
  • Status (ACTIVE, BLOCKED, etc.)
  • Last accessed time
  • Delete button (if allowed)
  • Highlight for the current device (currentDevice: true)

The user should be able to:


🔒 Note on deviceManagementCoolingPeriodEndTimestamp

The deviceManagementCoolingPeriodEndTimestamp is part of the onGetRegisteredDeviceDetails callback response. It represents a cooling-off period during which certain device management actions are temporarily restricted for enhanced security. This timestamp prevents sensitive device management actions (like renaming or deleting a device) from being performed immediately after high-risk events. It ensures that malicious or accidental device manipulations are avoided during critical security windows.

🧠 Developer Responsibilities

1. Manage UI State

  • Disable or hide Edit/Delete buttons for devices until the cooling period has expired.
  • Compare current time with deviceManagementCoolingPeriodEndTimestamp.
const isCoolingActive = Date.now() < deviceManagementCoolingPeriodEndTimestamp;

2. User Communication

  • Display meaningful messages or tooltips to inform the user why device actions are disabled.
  • Example: “You can update this device after the security hold period ends at 12:35 PM.”

3. Automated Restoration

  • Use timers or scheduled checks to automatically re-enable device actions once the timestamp is reached.
  • This can improve UX by removing the need for manual refreshes.
setTimeout(() => {
  // Re-enable buttons or refresh UI
}, deviceManagementCoolingPeriodEndTimestamp - Date.now());

📌 Notes

  • The timestamp is in milliseconds since epoch (UTC).
  • This feature is enforced by the SDK backend but must be handled in UI by the app developer.

💻 Sample Code (Platform-Specific)

React Native
import RdnaClient from 'react-native-rdna-client';
import { useEffect } from 'react';

const fetchRegisteredDevices = (userID) => {
  RdnaClient.on(RdnaClient.onGetRegistredDeviceDetails, (response) => {
    const devices = response?.devices || [];

    devices.forEach((device) => {
      const isCoolingActive =
        Date.now() < device.deviceManagementCoolingPeriodEndTimestamp;

      console.log(`📱 ${device.deviceName}`);
      console.log(`🔒 Cooling Active: ${isCoolingActive}`);
      if (isCoolingActive) {
        console.log(
          `⏳ Available after: ${new Date(
            device.deviceManagementCoolingPeriodEndTimestamp
          ).toLocaleString()}`
        );
      }
    });
  });

  RdnaClient.getRegisteredDeviceDetails(userID, (syncResponse) => {
    console.log("➡️ Sync Response: ", syncResponse);
  });
};

useEffect(() => {
  fetchRegisteredDevices("[email protected]");
}, []);
Flutter
import 'package:rdna_client/rdna_client.dart';
import 'package:rdna_client/rdna_struct.dart';

final RdnaClient rdnaClient = RdnaClient();

void setupDeviceListener(String userId) {
  rdnaClient.on(RdnaClient.onGetRegistredDeviceDetails, (event) {
    List<dynamic> devices = event?.payload['devices'] ?? [];

    for (var device in devices) {
      final coolingTimestamp = device['deviceManagementCoolingPeriodEndTimestamp'];
      final isCoolingActive = DateTime.now().millisecondsSinceEpoch < coolingTimestamp;

      print("📱 ${device['deviceName']}");
      print("🔒 Cooling Active: $isCoolingActive");
      if (isCoolingActive) {
        print("⏳ Available after: ${DateTime.fromMillisecondsSinceEpoch(coolingTimestamp)}");
      }
    }
  });

  rdnaClient.getRegisteredDeviceDetails(userId);
}
Cordova
document.addEventListener("deviceready", () => {
  const userId = "[email protected]";

  document.addEventListener(
    "onGetRegistredDeviceDetails",
    function (event) {
      const devices = event?.data?.devices || [];

      devices.forEach((device) => {
        const coolingEnd = device.deviceManagementCoolingPeriodEndTimestamp;
        const isCoolingActive = Date.now() < coolingEnd;

        console.log("📱", device.deviceName);
        console.log("🔒 Cooling Active:", isCoolingActive);
        if (isCoolingActive) {
          console.log("⏳ Available after:", new Date(coolingEnd).toLocaleString());
        }
      });
    },
    false
  );

  com.uniken.rdnaplugin.RdnaClient.getRegisteredDeviceDetails(
    function (success) {
      console.log("Sync call success:", success);
    },
    function (error) {
      console.error("Error in API call:", error);
    },
    [userId]
  );
});
Native iOS (Objective-C)
- (void)onGetRegistredDeviceDetails:(NSArray<RDNADeviceDetails *> *)deviceList {
    for (RDNADeviceDetails *device in deviceList) {
        BOOL isCoolingActive = [[NSDate date] timeIntervalSince1970] * 1000 < device.deviceManagementCoolingPeriodEndTimestamp;
        NSLog(@"📱 Device: %@", device.deviceName);
        NSLog(@"🔒 Cooling Active: %@", isCoolingActive ? @"YES" : @"NO");
        if (isCoolingActive) {
            NSDate *coolingEnd = [NSDate dateWithTimeIntervalSince1970:(device.deviceManagementCoolingPeriodEndTimestamp / 1000)];
            NSLog(@"⏳ Available after: %@", coolingEnd);
        }
    }
}

RDNAError *error = [rdnaInstance getRegisteredDeviceDetails:@"[email protected]"];
Native Android (Java)
@Override
public void onGetRegistredDeviceDetails(List<RDNADeviceDetails> deviceList) {
    for (RDNADeviceDetails device : deviceList) {
        boolean isCoolingActive = System.currentTimeMillis() < device.getDeviceManagementCoolingPeriodEndTimestamp();
        Log.d("Device", "📱 " + device.getDeviceName());
        Log.d("Cooling", "🔒 Cooling Active: " + isCoolingActive);
        if (isCoolingActive) {
            Date date = new Date(device.getDeviceManagementCoolingPeriodEndTimestamp());
            Log.d("CoolingEnd", "⏳ Available after: " + date.toString());
        }
    }
}

RDNAError err = rdna.getRegisteredDeviceDetails("[email protected]");

On Success

  • Populate UI with device list
  • Enable delete/edit options based on payload

On Failure

  • Show error message
  • Offer retry or contact support