Performing Operations
-
The generic protocol representing an operation returned by
See moreOperations
.Declaration
Swift
public protocol Operation
-
An operation that requires sending HTTP requests to the backend.
You can provide HTTP request headers that can be sent in the HTTP request. This additional headers can be used for example to correlate the operation executed by the SDK with a more general operation. For instance if you want to correlate all the operations involving the enrollment of a user (which includes registration of an authenticator), you can use this feature.
See
Registration
See
Authentication
See
Deregistration
Declaration
Swift
public protocol HttpOperation : Operation
-
The protocol returned by the
See moreMobileAuthenticationClient
that can be used to execute operations.Declaration
Swift
public protocol Operations
-
The object that can be used to trigger a registration operation from the response of the Cloud HTTP API to the enroll (https://$instance.mauth.nevis.cloud/api/v1/users/enroll) endpoint.
Usage example:
class AuthenticatorSelectorImpl: AuthenticatorSelector { func selectAuthenticator(context: AuthenticatorSelectionContext, handler: AuthenticatorSelectionHandler) { handler.aaid(aaid) } } class BiometricUserVerifierImpl: BiometricUserVerifier { func verifyBiometric(context: BiometricUserVerificationContext, handler: BiometricUserVerificationHandler) { handler.verify() } } class DevicePasscodeUserVerifierImpl: DevicePasscodeUserVerifier { func verifyDevicePasscode(context: DevicePasscodeUserVerificationContext, handler: DevicePasscodeUserVerificationHandler) { handler.verify() } } let deviceInformation = DeviceInformation(name: "<Device name>", fcmRegistrationToken: "<FCM token>") client.operations.authCloudApiRegistration .deviceInformation(deviceInformation) .enrollResponse(enrollResponse) .authenticatorSelector(AuthenticatorSelectorImpl(...)) .biometricUserVerifier(BiometricUserVerifierImpl(...)) .devicePasscodeUserVerifier(DevicePasscodeUserVerifierImpl(...)) .pinEnroller(PinEnrollerImpl(...)) .onError { error in ... } .onSuccess { authorizationProvider in ... } .execute()
The biometric and device Passcode authenticators are enrolled at the OS level. That is why, if one of them must be registered, the user must authenticate through
See moreBiometricUserVerifier
orDevicePasscodeUserVerifier
. In the case of the PIN, the PIN is enrolled during registration, so no verification is needed.Declaration
Swift
public protocol AuthCloudApiRegistration : HttpOperation
-
The object that can be used to trigger a registration operation.
Usage example:
class AuthenticatorSelectorImpl: AuthenticatorSelector { func selectAuthenticator(context: AuthenticatorSelectionContext, handler: AuthenticatorSelectionHandler) { handler.aaid(aaid) } } class BiometricUserVerifierImpl: BiometricUserVerifier { func verifyBiometric(context: BiometricUserVerificationContext, handler: BiometricUserVerificationHandler) { handler.verify() } } class DevicePasscodeUserVerifierImpl: DevicePasscodeUserVerifier { func verifyDevicePasscode(context: DevicePasscodeUserVerificationContext, handler: DevicePasscodeUserVerificationHandler) { handler.verify() } } class PinEnrollerImp: PinEnroller { func enrollPin(context: PinEnrollmentContext, handler: PinEnrollmentHandler) { handler.pin(pin) } } client.operations.registration .username(username) .serverBaseUrl(URL(string: "https://server/path")!) .authenticatorSelector(AuthenticatorSelectorImpl(...)) .biometricUserVerifier(BiometricUserVerifierImpl(...)) .devicePasscodeUserVerifier(DevicePasscodeUserVerifierImpl(...)) .pinEnroller(PinEnrollerImp(...)) .onError { error in ... } .onSuccess { ... } .execute()
The biometric and device Passcode authenticators are enrolled at the OS level. That is why, if one of them must be registered, the user must authenticate through
See moreBiometricUserVerifier
orDevicePasscodeUserVerifier
. In the case of the PIN, the PIN is enrolled during registration, so no verification is needed.Declaration
Swift
public protocol Registration : HttpOperation
-
The object that can be used to trigger an authentication operation.
Usage example:
See moreclass AuthenticatorSelectorImpl: AuthenticatorSelector { func selectAuthenticator(context: AuthenticatorSelectionContext, handler: AuthenticatorSelectionHandler) { handler.aaid(aaid) } } class BiometricUserVerifierImpl: BiometricUserVerifier { func verifyBiometric(context: BiometricUserVerificationContext, handler: BiometricUserVerificationHandler) { handler.verify() } } class DevicePasscodeUserVerifierImpl: DevicePasscodeUserVerifier { func verifyDevicePasscode(context: DevicePasscodeUserVerificationContext, handler: DevicePasscodeUserVerificationHandler) { handler.verify() } } class PinUserVerifierImpl: PinUserVerifier { func verifyPin(context: PinUserVerificationContext, handler: PinUserVerificationHandler) { handler.verify(pin: pin) } } client.operations.authentication .username(username) .authenticatorSelector(AuthenticatorSelectorImpl(...)) .biometricUserVerifier(BiometricUserVerifierImpl(...)) .devicePasscodeUserVerifier(DevicePasscodeUserVerifierImpl(...)) .pinUserVerifier(PinUserVerifierImpl(...)) .onError { error in ... } .onSuccess { authorizationProvider in ... } .execute()
Declaration
Swift
public protocol Authentication : HttpOperation
-
The object that can be used to trigger an deregistration operation.
Usage example:
See moreclient.operations.deregistration .username(username) .aaid(aaid) .authorizationProvider(authorizationProvider) .onError { error in ... } .onSuccess { ... } .execute()
Declaration
Swift
public protocol Deregistration : HttpOperation
-
The object that decodes an
OutOfBandPayload
from aString
in JSON format or a Base64 URL encoded {@code String} representing the JSON. TheOutOfBandPayload
can be used to trigger an out-of-band operationOutOfBandOperation
.Usage example:
client.operations.outOfBandPayloadDecode .json(jsonPayload) .onSuccess { outOfBandPayload in ... } .onError { error in ... } .execute()
The JSON is obtained from a push notification, or as a Base64 URL encoded JSON in QR codes generated by the server. JSON example:
See more{ "nma_data" : { "token" : "b4b07559-f934-4597-a1c5-44d89f691e8f", "redeem_url" : "https://fido.siven.ch/nevisfido/token/redeem/authentication", "attributeName" : "some additional data to be included in the QR code" }, "nma_data_content_type" : "application/json", "nma_data_version" : "1" }
Declaration
Swift
public protocol OutOfBandPayloadDecode : Operation
-
The operation managing an
OutOfBandPayload
. AnOutOfBandPayload
can be provided through different means: a push notification, a QR code or an application link. This operation will process the payload, decrypt it if needed and send it to the server. If the payload is successfully handled by the server, then the SDK will identify whether the operation associated with the payload is a registration or an authentication. Depending on that theonRegistration(_:)
or theonAuthentication(_:)
will be invoked.Usage example:
client.operations.outOfBandOperation .payload(payload) .onRegistration { oobRegistration in ... } .onAuthentication { oobAuthentication in ... } .onError { error in ... } .execute()
See
OutOfBandPayload
Declaration
Swift
public protocol OutOfBandOperation : HttpOperation
-
The operation handling an out-of-band registration. This is the object returned by the SDK, when an
OutOfBandPayload
was processed and theOutOfBandPayload
corresponds to a registration operation.Usage example:
class AuthenticatorSelectorImpl: AuthenticatorSelector { func selectAuthenticator(context: AuthenticatorSelectionContext, handler: AuthenticatorSelectionHandler) { handler.aaid(aaid) } } class BiometricUserVerifierImpl: BiometricUserVerifier { func verifyBiometric(context: BiometricUserVerificationContext, handler: BiometricUserVerificationHandler) { handler.verify() } } class DevicePasscodeUserVerifierImpl: DevicePasscodeUserVerifier { func verifyDevicePasscode(context: DevicePasscodeUserVerificationContext, handler: DevicePasscodeUserVerificationHandler) { handler.verify() } } class PinEnrollerImp: PinEnroller { func enrollPin(context: PinEnrollmentContext, handler: PinEnrollmentHandler) { handler.pin(pin) } } client.operations.outOfBandOperation .payload(payload) .onRegistration { oobRegistration in oobRegistration .deviceInformation(.init(name: "<name>", fcmRegistrationToken: "<target>")) .authenticatorSelector(AuthenticatorSelectorImpl(...)) .biometricUserVerifier(BiometricUserVerifierImpl(...)) .devicePasscodeUserVerifier(DevicePasscodeUserVerifierImpl(...)) .pinEnroller(PinEnrollerImp(...)) .onError { error in ... } .onSuccess { ... } .execute() } .onAuthentication { oobAuthentication in ... } .execute()
The biometric and device Passcode authenticators are enrolled at the OS level. That is why, if one of them must be registered, the user must authenticate through
See moreBiometricUserVerifier
orDevicePasscodeUserVerifier
. In the case of the PIN, the PIN is enrolled during registration, so no verification is needed.Declaration
Swift
public protocol OutOfBandRegistration : HttpOperation
-
The operation handling an out-of-band authentication. This is the object returned by the SDK, when an
OutOfBandPayload
was processed and theOutOfBandPayload
corresponds to an authentication operation.Usage example:
See moreclass AccountSelectorImpl: AccountSelector { func selectAccount(context: AccountSelectionContext, handler: AccountSelectionHandler) { handler.username(username) } } class AuthenticatorSelectorImpl: AuthenticatorSelector { func selectAuthenticator(context: AuthenticatorSelectionContext, handler: AuthenticatorSelectionHandler) { handler.aaid(aaid) } } class BiometricUserVerifierImpl: BiometricUserVerifier { func verifyBiometric(context: BiometricUserVerificationContext, handler: BiometricUserVerificationHandler) { handler.verify() } } class DevicePasscodeUserVerifierImpl: DevicePasscodeUserVerifier { func verifyDevicePasscode(context: DevicePasscodeUserVerificationContext, handler: DevicePasscodeUserVerificationHandler) { handler.verify() } } class PinUserVerifierImpl: PinUserVerifier { func verifyPin(context: PinUserVerificationContext, handler: PinUserVerificationHandler) { handler.verify(pin: pin) } } client.operations.outOfBandOperation .payload(payload) .onRegistration { oobRegistration in ... } .onAuthentication { oobAuthentication in oobAuthentication .accountSelector(AccountSelectorImpl(...)) .authenticatorSelector(AuthenticatorSelectorImpl(...)) .biometricUserVerifier(BiometricUserVerifierImpl(...)) .devicePasscodeUserVerifier(DevicePasscodeUserVerifierImpl(...)) .pinUserVerifier(PinUserVerifierImpl(...)) .onError { error in ... } .onSuccess { ... } .execute() } .onError { error in ... } .execute()
Declaration
Swift
public protocol OutOfBandAuthentication : HttpOperation
-
The object that can be used to change the PIN.
Usage example:
See moreclass PinChangerImpl: PinChanger { func changePin(context: PinChangeContext, handler: PinChangeHandler) { handler.pins(oldPin, newPin) } } client.operations.pinChange .username(username) .pinChanger(PinChangerImpl(...)) .onSuccess { in ... } .onError { error in ... } .execute()
Declaration
Swift
public protocol PinChange : Operation
-
The object containing information of the device where the SDK is running.
For nevisFIDO to be able to generate encrypted out-of-band payloads that can only be decrypted by your application, a
DeviceInformation
must be provided during registration. During registration you must provide thename
and optionally thefcmRegistrationToken
. The other information exposed by theDeviceInformation
(deviceId
andidUsernamePairs
) are generated by the SDK and are not required during registration.For nevisFIDO to be able to dispatch tokens using the Firebase Cloud Messaging infrastructure, the device information
fcmRegistrationToken
must be filled with the token (as defined by Firebase). This registration token is associated with the mobile device receiving the push notifications.There is a single
DeviceInformation
for all accounts. It is created when the first successful registration is completed, and it is deleted when the last authenticator (and thus the last account) is removed (using theDeregistration
ordeleteAuthenticator(username:aaid:)
. When aDeviceInformation
is provided in a registration operation, and aDeviceInformation
is already defined (that is, there is already a registered authenticator), the providedDeviceInformation
will be ignored. The device information contents (name and FCM registration token) can be changed using aDeviceInformationChange
.The
DeviceInformation
data is stored in nevisIDM as generic credentials. For each account registered, a generic credential will be created in nevisIDM containing the device information. These generic credentials are named dispatch targets in the nevisFIDO terminology.The following example creates a
DeviceInformation
using a phone description (that can be provided by the end user, since this is used for the end user to identify the mobile device) and a Firebase registration token:func createDeviceInformation(phoneDescription: String, firebaseRegistrationToken: String) -> DeviceInformation { DeviceInformation(name: phoneDescription, fcmRegistrationToken: firebaseRegistrationToken) }
See
Declaration
Swift
public struct DeviceInformation : Codable
-
The object that updates a device information. The device information change can be used
- to modify the name of the device and/or
to change the Firebase registration token or to disable push notifications.
Warning
If neithername(_:)
orfcmRegistrationToken(_:)
are provided, the providedonSuccess(_:)
object will be called whenDeviceInformationChange.execute()
is invoked.
Usage example:
client.operations.deviceInformationChange .name(newName) .fcmRegistrationToken(fcmToken) .onSuccess { in ... } .onError { error in ... } .execute() client.operations.deviceInformationChange .name(newName) .disablePushNotifications() .onSuccess { in ... } .onError { error in ... } .execute()
Synchronization with retry strategy
The retry strategy can be useful when updating the Firebase Cloud Messaging token. But since it is not known when the token will be updated, synchronization is necessary and should be done by the caller. Below a sample code is provided that solves the synchronization using dispatch queues and groups.
See moreimport Firebase class SampleAppMessagingService { let queue = DispatchQueue(label: "com.sample.fcm.update.serial") } extension SampleAppMessagingService: MessagingDelegate { func messaging(_: Messaging, didReceiveRegistrationToken fcmToken: String?) { guard let fcmToken else { return } processNewToken(fcmToken, client) } private func processNewToken(_ firebaseRegistrationToken: String, _ client: MobileAuthenticationClient) { queue.async { let group = DispatchGroup() group.enter() DispatchQueue.global().async { client.operations.deviceInformationChange .fcmRegistrationToken(firebaseRegistrationToken) .retryPolicy(.constant(maxRetries: 3, delayInSeconds: 30)) .onSuccess { defer { group.leave() } // Firebase registration token successfully updated } .onError { _ in defer { group.leave() } // handle unsuccessful update } .execute() } group.wait() } } }
Declaration
Swift
public protocol DeviceInformationChange : HttpOperation