Performing Operations - Objective-C

  • The generic protocol representing an operation returned by NMAOperations.

    See more

    Declaration

    Swift

    @objc
    public protocol NMAOperation
  • 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 more

    Declaration

    Swift

    @objc
    public protocol NMAHttpOperation : NMAOperation
  • The protocol returned by the NMAMobileAuthenticationClient that can be used to execute operations.

    See more

    Declaration

    Swift

    @objc
    public protocol NMAOperations
  • 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:

    @interface NMAAuthenticatorSelectorImpl : NSObject <NMAAuthenticatorSelector>
    
    @end
    
    @implementation NMAAuthenticatorSelectorImpl
    
    - (void)selectAuthenticatorWithContext:(id<NMAAuthenticatorSelectionContext> _Nonnull)context handler:(id<NMAAuthenticatorSelectionHandler> _Nonnull)handler {
        [handler aaid:aaid];
    }
    
    @end
    
    @interface NMABiometricUserVerifierImpl : NSObject <NMABiometricUserVerifier>
    
    @end
    
    @implementation NMABiometricUserVerifierImpl
    
    - (void)verifyBiometricWithContext:(id<NMABiometricUserVerificationContext> _Nonnull)context handler:(id<NMABiometricUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMADevicePasscodeUserVerifierImpl : NSObject <NMADevicePasscodeUserVerifier>
    
    @end
    
    @implementation NMADevicePasscodeUserVerifierImpl
    
    - (void)verifyDevicePasscodeWithContext:(id<NMADevicePasscodeUserVerificationContext> _Nonnull)context handler:(id<NMADevicePasscodeUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    id<NMAAuthCloudApiRegistration> authCloudApiRegistration = [[client operations] authCloudApiRegistration];
    
    [authCloudApiRegistration deviceInformation:[[NMADeviceInformation alloc] initWithName:@"<Device name>" fcmRegistrationToken:@"<FCM token>"]];
    [authCloudApiRegistration enrollResponse:@"<Cloud API - enroll response>"];
    [authCloudApiRegistration authenticatorSelector:[[NMAAuthenticatorSelectorImpl alloc] init]];
    [authCloudApiRegistration biometricUserVerifier:[[NMABiometricUserVerifierImpl alloc] init]];
    [authCloudApiRegistration devicePasscodeUserVerifier:[[NMADevicePasscodeUserVerifierImpl alloc] init]];
    [authCloudApiRegistration onSuccess:^{...}];
    [authCloudApiRegistration onError:^(NMAAuthCloudApiError * _Nonnull error) {...}];
    [authCloudApiRegistration 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 NMABiometricUserVerifier or NMADevicePasscodeUserVerifier. In the case of the PIN, the PIN is enrolled during registration, so no verification is needed.

    See more

    Declaration

    Swift

    @objc
    public protocol NMAAuthCloudApiRegistration : NMAHttpOperation
  • The object that can be used to trigger a registration operation.

    Usage example:

    @interface NMAAuthenticatorSelectorImpl : NSObject <NMAAuthenticatorSelector>
    
    @end
    
    @implementation NMAAuthenticatorSelectorImpl
    
    - (void)selectAuthenticatorWithContext:(id<NMAAuthenticatorSelectionContext> _Nonnull)context handler:(id<NMAAuthenticatorSelectionHandler> _Nonnull)handler {
        [handler aaid:aaid];
    }
    
    @end
    
    @interface NMABiometricUserVerifierImpl : NSObject <NMABiometricUserVerifier>
    
    @end
    
    @implementation NMABiometricUserVerifierImpl
    
    - (void)verifyBiometricWithContext:(id<NMABiometricUserVerificationContext> _Nonnull)context handler:(id<NMABiometricUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMADevicePasscodeUserVerifierImpl : NSObject <NMADevicePasscodeUserVerifier>
    
    @end
    
    @implementation NMADevicePasscodeUserVerifierImpl
    
    - (void)verifyDevicePasscodeWithContext:(id<NMADevicePasscodeUserVerificationContext> _Nonnull)context handler:(id<NMADevicePasscodeUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    NSURL *serverURL = [[NSURL alloc] initWithString:@"https://server/path"];
    id<NMARegistration> registration = [[client operations] registration];
    
    [registration username:username];
    [registration serverUrl:serverURL];
    [registration authorizationProvider:authorizationProvider];
    [registration deviceInformation:[[NMADeviceInformation alloc] initWithName:@"<Device name>" fcmRegistrationToken:@"<FCM token>"]];
    [registration authenticatorSelector:[[NMAAuthenticatorSelectorImpl alloc] init]];
    [registration biometricUserVerifier:[[NMABiometricUserVerifierImpl alloc] init]];
    [registration devicePasscodeUserVerifier:[[NMADevicePasscodeUserVerifierImpl alloc] init]];
    [registration onSuccess:^{...}];
    [registration onError:^(NMAOperationError * _Nonnull error) {...}];
    [registration 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 NMABiometricUserVerifier or NMADevicePasscodeUserVerifier. In the case of the PIN, the PIN is enrolled during registration, so no verification is needed.

    See more

    Declaration

    Swift

    @objc
    public protocol NMARegistration : NMAHttpOperation
  • The object that can be used to trigger an authentication operation.

    Usage example:

    @interface NMAAuthenticatorSelectorImpl : NSObject <NMAAuthenticatorSelector>
    
    @end
    
    @implementation NMAAuthenticatorSelectorImpl
    
    - (void)selectAuthenticatorWithContext:(id<NMAAuthenticatorSelectionContext> _Nonnull)context handler:(id<NMAAuthenticatorSelectionHandler> _Nonnull)handler {
        [handler aaid:aaid];
    }
    
    @end
    
    @interface NMABiometricUserVerifierImpl : NSObject <NMABiometricUserVerifier>
    
    @end
    
    @implementation NMABiometricUserVerifierImpl
    
    - (void)verifyBiometricWithContext:(id<NMABiometricUserVerificationContext> _Nonnull)context handler:(id<NMABiometricUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMADevicePasscodeUserVerifierImpl : NSObject <NMADevicePasscodeUserVerifier>
    
    @end
    
    @implementation NMADevicePasscodeUserVerifierImpl
    
    - (void)verifyDevicePasscodeWithContext:(id<NMADevicePasscodeUserVerificationContext> _Nonnull)context handler:(id<NMADevicePasscodeUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMAPinUserVerifierImpl : NSObject<NMAPinUserVerifier>
    
    @end
    
    @implementation NMAPinUserVerifierImpl
    
    - (void)verifyPinWithContext:(id<NMAPinUserVerificationContext> _Nonnull)context handler:(id<NMAPinUserVerificationHandler> _Nonnull)handler {
        [handler verify:pin];
    }
    
    @end
    
    id<NMAAuthentication> authentication = [[client operations] authentication];
    
    [authentication username:username];
    [authentication authenticatorSelector:[[NMAAuthenticatorSelectorImpl alloc] init]];
    [authentication biometricUserVerifier:[[NMABiometricUserVerifierImpl alloc] init]];
    [authentication devicePasscodeUserVerifier:[[NMADevicePasscodeUserVerifierImpl alloc] init]];
    [authentication pinUserVerifier:[[NMAPinUserVerifierImpl alloc] init]];
    [authentication onSuccess:^(id<NMAAuthorizationProvider> _Nullable authorizationProvider) {...}];
    [authentication onError:^(NMAOperationError * _Nonnull error) {...}];
    [authentication execute];
    
    See more

    Declaration

    Swift

    @objc
    public protocol NMAAuthentication : NMAHttpOperation
  • The object that can be used to trigger an deregistration operation.

    Usage example:

    id<NMADeregistration> deregistration = [[client operations] deregistration];
    
    [deregistration username:username];
    [deregistration aaid:aaid];
    [deregistration onSuccess:^{...}];
    [deregistration onError:^(NMAOperationError * _Nonnull error) {...}];
    [deregistration execute];
    
    See more

    Declaration

    Swift

    @objc
    public protocol NMADeregistration : NMAHttpOperation
  • The object that decodes an NMAOutOfBandPayload from a String in JSON format or a Base64 URL encoded {@code String} representing the JSON. The NMAOutOfBandPayload can be used to trigger an out-of-band operation NMAOutOfBandOperation.

    Usage example:

    id<NMAOutOfBandPayloadDecode> oobPayloadDecode = [[client operations] outOfBandPayloadDecode];
    [oobPayloadDecode json:jsonPushNotification]];
    [oobPayloadDecode onSuccess:^(NMAOutOfBandPayload * _Nonnull oobPayload) {
        // Payload is returned by the SDK.
    }];
    [oobPayloadDecode onError:^(NMAOutOfBandPayloadError * _Nonnull error) {...}];
    [oobPayloadDecode 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:

    {
        "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"
    }
    
    See more

    Declaration

    Swift

    @objc
    public protocol NMAOutOfBandPayloadDecode : NMAOperation
  • The operation managing an NMAOutOfBandPayload. An NMAOutOfBandPayload 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 the onRegistration(_:) or the onAuthentication(_:) will be invoked.

    Usage example:

    id<NMAOutOfBandOperation> oobOperation = [[client operations] outOfBandOperation];
    [oobOperation payload:payload];
    [oobOperation onRegistration:^(id<NMAOutOfBandRegistration> _Nonnull registration) {...}];
    [oobOperation onAuthentication:^(id<NMAOutOfBandAuthentication> _Nonnull authentication) {...}];
    [oobOperation onError:^(NMAOutOfBandOperationError * _Nonnull error) {...}];
    [oobOperation execute];
    
    See more

    Declaration

    Swift

    @objc
    public protocol NMAOutOfBandOperation : NMAHttpOperation
  • The operation handling an out-of-band registration. This is the object returned by the SDK, when an NMAOutOfBandPayload was processed and the NMAOutOfBandPayload corresponds to an registration operation.

    Usage example:

    @interface NMAAuthenticatorSelectorImpl : NSObject <NMAAuthenticatorSelector>
    
    @end
    
    @implementation NMAAuthenticatorSelectorImpl
    
    - (void)selectAuthenticatorWithContext:(id<NMAAuthenticatorSelectionContext> _Nonnull)context handler:(id<NMAAuthenticatorSelectionHandler> _Nonnull)handler {
        [handler aaid:aaid];
    }
    
    @end
    
    @interface NMABiometricUserVerifierImpl : NSObject <NMABiometricUserVerifier>
    
    @end
    
    @implementation NMABiometricUserVerifierImpl
    
    - (void)verifyBiometricWithContext:(id<NMABiometricUserVerificationContext> _Nonnull)context handler:(id<NMABiometricUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMADevicePasscodeUserVerifierImpl : NSObject <NMADevicePasscodeUserVerifier>
    
    @end
    
    @implementation NMADevicePasscodeUserVerifierImpl
    
    - (void)verifyDevicePasscodeWithContext:(id<NMADevicePasscodeUserVerificationContext> _Nonnull)context handler:(id<NMADevicePasscodeUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMAPinEnrollerImpl : NSObject<NMAPinEnroller>
    
    @end
    
    @implementation NMAPinEnrollerImpl
    
    - (void)enrollPinWithContext:(id<NMAPinEnrollmentContext> _Nonnull)context handler:(id<NMAPinEnrollmentHandler> _Nonnull)handler {
        [handler pin:pin];
    }
    
    @end
    
    id<NMAOutOfBandOperation> oobOperation = [[client operations] outOfBandOperation];
    
    [oobOperation payload:payload];
    [oobOperation onRegistration:^(id<NMAOutOfBandRegistration> _Nonnull registration) {
        [registration deviceInformation:[[NMADeviceInformation alloc] initWithName:@"<Device name>" fcmRegistrationToken:@"<FCM token>"]];
        [registration authenticatorSelector:[[NMAAuthenticatorSelectorImpl alloc] init]];
        [registration biometricUserVerifier:[[NMABiometricUserVerifierImpl alloc] init]];
        [registration devicePasscodeUserVerifier:[[NMADevicePasscodeUserVerifierImpl alloc] init]];
        [registration pinEnroller:[[NMAPinEnrollerImpl alloc] init]];
        [registration onSuccess:^{...}];
        [registration onError:^(NMAOperationError * _Nonnull error) {...}];
        [registration execute];
    }];
    [oobOperation onError:^(NMAOutOfBandOperationError * _Nonnull error) {...}];
    
    [oobOperation 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 NMABiometricUserVerifier or NMADevicePasscodeUserVerifier. In the case of the PIN, the PIN is enrolled during registration, so no verification is needed.

    See more

    Declaration

    Swift

    @objc
    public protocol NMAOutOfBandRegistration : NMAHttpOperation
  • The operation handling an out-of-band authentication. This is the object returned by the SDK, when an NMAOutOfBandPayload was processed and the NMAOutOfBandPayload corresponds to an authentication operation.

    Usage example:

    @interface NMAAccountSelectorImpl: NSObject <NMAAccountSelector>
    
    @end
    
    @implementation NMAAccountSelectorImpl
    
    - (void)selectAccountWithContext:(id<NMAAccountSelectionContext> _Nonnull)context handler:(id<NMAAccountSelectionHandler> _Nonnull)handler {
        [handler username:username];
    }
    
    @end
    
    @interface NMAAuthenticatorSelectorImpl : NSObject <NMAAuthenticatorSelector>
    
    @end
    
    @implementation NMAAuthenticatorSelectorImpl
    
    - (void)selectAuthenticatorWithContext:(id<NMAAuthenticatorSelectionContext> _Nonnull)context handler:(id<NMAAuthenticatorSelectionHandler> _Nonnull)handler {
        [handler aaid:aaid];
    }
    
    @end
    
    @interface NMABiometricUserVerifierImpl : NSObject <NMABiometricUserVerifier>
    
    @end
    
    @implementation NMABiometricUserVerifierImpl
    
    - (void)verifyBiometricWithContext:(id<NMABiometricUserVerificationContext> _Nonnull)context handler:(id<NMABiometricUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMADevicePasscodeUserVerifierImpl : NSObject <NMADevicePasscodeUserVerifier>
    
    @end
    
    @implementation NMADevicePasscodeUserVerifierImpl
    
    - (void)verifyDevicePasscodeWithContext:(id<NMADevicePasscodeUserVerificationContext> _Nonnull)context handler:(id<NMADevicePasscodeUserVerificationHandler> _Nonnull)handler {
        [handler verify];
    }
    
    @end
    
    @interface NMAPinUserVerifierImpl : NSObject<NMAPinUserVerifier>
    
    @end
    
    @implementation NMAPinUserVerifierImpl
    
    - (void)verifyPinWithContext:(id<NMAPinUserVerificationContext> _Nonnull)context handler:(id<NMAPinUserVerificationHandler> _Nonnull)handler {
        [handler verify:pin];
    }
    
    @end
    
    id<NMAOutOfBandOperation> oobOperation = [[client operations] outOfBandOperation];
    
    [oobOperation payload:payload];
    [oobOperation onRegistration:^(id<NMAOutOfBandRegistration> _Nonnull registration) {...}];
    
    [oobOperation onAuthentication:^(id<NMAOutOfBandAuthentication> _Nonnull authentication) {
        [authentication accountSelector:[[NMAAccountSelectorImpl alloc] init]];
        [authentication authenticatorSelector:[[NMAAuthenticatorSelectorImpl alloc] init]];
        [authentication pinUserVerifier:[[NMAPinUserVerifierImpl alloc] init]];
        [authentication biometricUserVerifier:[[NMABiometricUserVerifierImpl alloc] init]];
        [authentication devicePasscodeUserVerifier:[[NMADevicePasscodeUserVerifierImpl alloc] init]];
        [authentication onSuccess:^(id<NMAAuthorizationProvider> _Nullable authorizationProvider) {...}];
        [authentication onError:^(NMAOperationError * _Nonnull error) {...}];
        [authentication execute];
    }];
    
    [oobOperation onError:^(NMAOutOfBandOperationError * _Nonnull error) {...}];
    [oobOperation execute];
    
    See more

    Declaration

    Swift

    @objc
    public protocol NMAOutOfBandAuthentication : NMAHttpOperation
  • The object that can be used to change the PIN.

    Usage example:

    @interface NMAPinChangerImpl : NSObject<NMAPinChanger>
    
    @end
    
    @implementation NMAPinChangerImpl
    
    - (void)changePinWithContext:(id<NMAPinChangeContext> _Nonnull)context handler:(id<NMAPinChangeHandler> _Nonnull)handler {
        [handler pins:oldPin :newPin];
    }
    
    @end
    
    id<NMAPinChange> pinChangeOperation = [[client operations] pinChange];
    
    [pinChangeOperation username:username];
    [pinChangeOperation pinChanger:[[NMAPinChangerImpl alloc] init]];
    [pinChangeOperation onSuccess:^{...}];
    [pinChangeOperation onError:^(NMAPinChangeError * _Nonnull error) {...}];
    
    [pinChangeOperation execute];
    
    See more

    Declaration

    Swift

    @objc
    public protocol NMAPinChange : NMAOperation
  • 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, an NMADeviceInformation must be provided during registration. During registration you must provide the name and optionally the fcmRegistrationToken. The other information exposed by the NMADeviceInformation (deviceId and idUsernamePairs) 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 NMADeviceInformation 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 the NMADeregistration or deleteAuthenticator(username:aaid:). When an NMADeviceInformation is provided in a registration operation, and an NMADeviceInformation is already defined (that is, there is already a registered authenticator), the provided NMADeviceInformation will be ignored. The device information contents (name and FCM registration token) can be changed using an NMADeviceInformationChange.

    The NMADeviceInformation 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 an NMADeviceInformation 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:

    - (NMADeviceInformation *)createDeviceInformation:(NSString *)phoneDescription
                            firebaseRegistrationToken:(NSString *)token {
        return [[NMADeviceInformation alloc] initWithName:phoneDescription
                                     fcmRegistrationToken:token];
    }
    
    See more

    Declaration

    Swift

    public class NMADeviceInformation : NSObject, DictionaryConvertible
  • 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 neither name(_:) or fcmRegistrationToken(_:) are provided, the provided onSuccess(_:) object will be called when NMADeviceInformationChange.execute() is invoked.

    Usage example:

    id<NMADeviceInformationChange> deviceInformationChange = [[client operations] deviceInformationChange];
    [deviceInformationChange name:newName];
    [deviceInformationChange fcmRegistrationToken:fcmToken];
    [deviceInformationChange onSuccess:^{...}];
    [deviceInformationChange onError:^(NMADeviceInformationChangeError * _Nonnull error) {...}];
    [deviceInformationChange execute];
    
    [deviceInformationChange name:newName];
    [deviceInformationChange disablePushNotifications];
    [deviceInformationChange onSuccess:^{...}];
    [deviceInformationChange onError:^(NMADeviceInformationChangeError * _Nonnull error) {...}];
    [deviceInformationChange 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.

    @import Firebase;
    @import FirebaseMessaging;
    
    @interface SampleAppMessagingService : NSObject<FIRMessagingDelegate>
    
    @property(strong, nonatomic, nonnull) dispatch_queue_t queue;
    
    @end
    
    @implementation SampleAppMessagingService
    
    - (instancetype)init {
        self = [super init];
        self.queue = dispatch_queue_create("com.sample.fcm.update.serial", DISPATCH_QUEUE_SERIAL);
        return self;
    }
    
    - (void)messaging:(nonnull FIRMessaging *)messaging didReceiveRegistrationToken:(nullable NSString *)fcmToken {
        if (fcmToken != nil) {
            [self process:fcmToken client:self.client];
        }
    }
    
    - (void)process:(nonnull NSString *)token client:(nonnull id<NMAMobileAuthenticationClient>)client {
        dispatch_async(self.queue, ^{
            dispatch_group_t group = dispatch_group_create();
            dispatch_group_enter(group);
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                id<NMADeviceInformationChange> deviceInformationChange = [[client operations] deviceInformationChange];
                [deviceInformationChange fcmRegistrationToken:token];
    
                NMAConstantRetryPolicy* policy = [[NMAConstantRetryPolicy alloc] initWithMaxRetries:3 delayInSeconds:30.0];
                [deviceInformationChange retryPolicy:policy];
                [deviceInformationChange onSuccess:^{
                    // Firebase registration token successfully updated
                    dispatch_group_leave(group);
                }];
                [deviceInformationChange onError:^(NMADeviceInformationChangeError * _Nonnull error) {
                    // handle unsuccessful update
                    dispatch_group_leave(group);
                }];
                [deviceInformationChange execute];
            });
            dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        });
    }
    
    See more

    Declaration

    Swift

    @objc
    public protocol NMADeviceInformationChange : NMAHttpOperation