DeviceClient
public class DeviceClient : @unchecked Sendable
Client for managing user devices
DeviceClient provides a type-safe interface for managing various types of authentication
devices registered to a user.
Supported Device Types
Mutable (Full CRUD)
- Oath: TOTP/HOTP authentication devices
- Push: Push notification authentication devices
- Bound: Device binding for 2FA
- Profile: Device profiling information
- WebAuthn: WebAuthn/FIDO2 credentials
Usage
// Initialize with configuration
let config = DeviceClientConfig(
serverUrl: "https://openam.example.com",
realm: "alpha",
cookieName: "iPlanetDirectoryPro",
ssoToken: token
)
let client = DeviceClient(config: config)
// Fetch devices
let result = await client.oath.get()
switch result {
case .success(let devices):
print("Found \(devices.count) devices")
case .failure(let error):
print("Error: \(error)")
}
// Update a device
if case .success(let devices) = await client.bound.get(),
var device = devices.first {
device.deviceName = "My Updated Device"
let updateResult = await client.bound.update(device)
if case .success = updateResult {
print("Device updated successfully")
}
}
// Delete a device
let deleteResult = await client.oath.delete(deviceToDelete)
if case .failure(let error) = deleteResult {
print("Failed to delete: \(error)")
}
Error Handling
All operations return Result types:
let result = await client.oath.get()
switch result {
case .success(let devices):
print("Fetched \(devices.count) devices")
case .failure(let error):
switch error {
case .requestFailed(let statusCode, let message):
print("Request failed: \(statusCode) - \(message)")
case .networkError(let error):
print("Network error: \(error)")
default:
print("Error: \(error.localizedDescription)")
}
}
Thread Safety
DeviceClient is safe to use from any thread. All async methods are marked with appropriate
concurrency annotations and will execute on appropriate queues.
Important
Ensure the SSO token in the configuration is valid before making requestsNote
The client does not automatically refresh tokens; token management is the caller’s responsibility-
Initializes a new DeviceClient
Creates a client instance configured for device management operations.
Example:
let config = DeviceClientConfig( serverUrl: "https://openam.example.com", realm: "alpha", cookieName: "iPlanetDirectoryPro", ssoToken: token ) let client = DeviceClient(config: config)Declaration
Swift
public init(config: DeviceClientConfig)Parameters
configThe configuration containing server details, credentials, and HTTP client
-
Provides access to Oath devices
Oath devices support TOTP (Time-based One-Time Password) and HOTP (HMAC-based One-Time Password) These devices are mutable - they support full CRUD operations.
Supported operations:
get(): Retrieve all Oath devices for the userupdate(_:): Update device properties (e.g., device name)delete(_:): Delete a specific Oath device
Example:
let result = await client.oath.get() switch result { case .success(let devices): if var device = devices.first { device.deviceName = "My Work Phone" let updateResult = await client.oath.update(device) if case .success = updateResult { print("Device updated") } let deleteResult = await client.oath.delete(device) if case .success = deleteResult { print("Device deleted") } } case .failure(let error): print("Error: \(error)") }Declaration
Swift
public lazy var oath: any DeviceRepository<OathDevice> { get set } -
Provides access to Push devices
Push devices support push notification-based authentication. These devices are mutable - they support full CRUD operations.
Supported operations:
get(): Retrieve all Push devices for the userupdate(_:): Update device properties (e.g., device name)delete(_:): Delete a specific Push device
Example:
let result = await client.push.get() switch result { case .success(let devices): if var device = devices.first { device.deviceName = "My Work Phone" let updateResult = await client.push.update(device) if case .success = updateResult { print("Device updated") } let deleteResult = await client.push.delete(device) if case .success = deleteResult { print("Device deleted") } } case .failure(let error): print("Error: \(error)") }Declaration
Swift
public lazy var push: any DeviceRepository<PushDevice> { get set } -
Provides access to Bound devices
Bound devices represent device bindings for two-factor authentication. These devices are mutable - they support full CRUD operations.
Supported operations:
get(): Retrieve all Bound devices for the userupdate(_:): Update device properties (e.g., device name)delete(_:): Delete a specific Bound device
Example:
let result = await client.bound.get() switch result { case .success(let devices): if var device = devices.first { device.deviceName = "My Work Phone" let updateResult = await client.bound.update(device) if case .success = updateResult { print("Device updated") } let deleteResult = await client.bound.delete(device) if case .success = deleteResult { print("Device deleted") } } case .failure(let error): print("Error: \(error)") }Declaration
Swift
public lazy var bound: any DeviceRepository<BoundDevice> { get set } -
Provides access to Profile devices
Profile devices store device profiling information including location and metadata. These devices are mutable - they support full CRUD operations.
Supported operations:
get(): Retrieve all Profile devices for the userupdate(_:): Update device properties (e.g., device name)delete(_:): Delete a specific Profile device
Example:
let result = await client.profile.get() switch result { case .success(let devices): if var device = devices.first { device.deviceName = "My iPhone" let updateResult = await client.profile.update(device) if case .success = updateResult { print("Device updated") } let deleteResult = await client.profile.delete(device) if case .success = deleteResult { print("Device deleted") } } case .failure(let error): print("Error: \(error)") }Declaration
Swift
public lazy var profile: any DeviceRepository<ProfileDevice> { get set } -
Provides access to WebAuthn devices
WebAuthn devices represent FIDO2/WebAuthn credentials for passwordless authentication. These devices are mutable - they support full CRUD operations.
Supported operations:
get(): Retrieve all WebAuthn devices for the userupdate(_:): Update device properties (e.g., device name)delete(_:): Delete a specific WebAuthn device
Example:
let result = await client.webAuthn.get() switch result { case .success(let devices): if var device = devices.first { device.deviceName = "My YubiKey" let updateResult = await client.webAuthn.update(device) if case .success = updateResult { print("Device updated") } let deleteResult = await client.webAuthn.delete(device) if case .success = deleteResult { print("Device deleted") } } case .failure(let error): print("Error: \(error)") }Declaration
Swift
public lazy var webAuthn: any DeviceRepository<WebAuthnDevice> { get set }
View on GitHub