UNPKG

@nevis-security/nevis-mobile-authentication-sdk-react

Version:

React Native plugin for Nevis Mobile Authentication SDK. Supports only mobile.

188 lines (170 loc) 6.24 kB
/** * Copyright © 2023-2024 Nevis Security AG. All rights reserved. */ import uuid from 'react-native-uuid'; import type { OutOfBandAuthentication } from './OutOfBandAuthentication'; import type { OutOfBandPayload } from './OutOfBandPayload'; import { OutOfBandRegistration } from './OutOfBandRegistration'; import { OutOfBandPlatformOperation } from '../../cache/operation/OutOfBandPlatformOperation'; import { PlatformOperationCache } from '../../cache/PlatformOperationCache'; import { OutOfBandOperationError } from '../../error/outOfBand/operation/OutOfBandOperationError'; import { OutOfBandOperationErrorConverter } from '../../error/outOfBand/operation/OutOfBandOperationErrorConverter'; import NevisMobileAuthenticationSdkReact from '../../MobileAuthenticationSdk'; import { OperationTypeMessage } from '../../model/messages/in/OperationTypeMessage'; import { OutOfBandOperationMessage } from '../../model/messages/out/OutOfBandOperationMessage'; import { HttpOperation, HttpOperationImpl } from '../HttpOperation'; /** * The operation managing an {@link OutOfBandPayload}. * * An {@link OutOfBandPayload} 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 * {@link onRegistration} or the {@link onAuthentication} will be invoked. * * Usage example: * ```ts * [...] * async authenticateUsingOutOfBandPayload( * client: MobileAuthenticationClient, * payload: OutOfBandPayload * ): Promise<void> { * await client.operations.outOfBandOperation * .payload(payload) * .onRegistration((registration) => { * // handle registration * }) * .onAuthentication((authentication) => { * // handle authentication * }) * .onError((_error) => { * // handle out-of-band error * }) * .execute(); * } * [...] * ``` * * @see * - {@link OutOfBandPayload} * - {@link OutOfBandRegistration} * - {@link OutOfBandAuthentication} */ export abstract class OutOfBandOperation extends HttpOperation<OutOfBandOperation> { /** * Specifies the out-of-band payload to be handled. * * **IMPORTANT** \ * Providing the out-of-band payload is required. * * @param payload the payload. * @returns an {@link OutOfBandOperation} object. */ abstract payload(payload: OutOfBandPayload): OutOfBandOperation; /** * Specifies the object that will handle the {@link OutOfBandRegistration} object associated with * the out-of-band payload. * * **IMPORTANT** \ * Providing at least one of the {@link onRegistration} or {@link onAuthentication} callbacks is * required. * * @param onRegistration the callback that will be invoked in case of registration. * @returns an {@link OutOfBandOperation} object. */ abstract onRegistration( onRegistration: (registration: OutOfBandRegistration) => void ): OutOfBandOperation; /** * Specifies the object that will handle the {@link OutOfBandAuthentication} object associated with * the out-of-band payload. * * **IMPORTANT** \ * Providing at least one of the {@link onRegistration} or {@link onAuthentication} callbacks is * required. * * @param onAuthentication the callback that will be invoked in case of authentication. * @returns an {@link OutOfBandOperation} object. */ abstract onAuthentication( onAuthentication: (authentication: OutOfBandAuthentication) => void ): OutOfBandOperation; /** * Specifies the object that will be invoked if the {@link OutOfBandPayload} could not be decoded. * * **IMPORTANT** \ * Providing the {@link onError} is required. * * @param onError the callback which receives an {@link OutOfBandPayloadError}. * @returns an {@link OutOfBandPayloadDecode} object. */ abstract onError(onError: (error: OutOfBandOperationError) => void): OutOfBandOperation; } export class OutOfBandOperationImpl extends HttpOperationImpl<OutOfBandOperation> implements OutOfBandOperation { private _payload?: OutOfBandPayload; private _onRegistration?: (registration: OutOfBandRegistration) => void; private _onAuthentication?: (authentication: OutOfBandAuthentication) => void; private _onError?: (error: OutOfBandOperationError) => void; payload(payload: OutOfBandPayload): OutOfBandOperation { this._payload = payload; return this; } onRegistration( onRegistration: (registration: OutOfBandRegistration) => void ): OutOfBandOperation { this._onRegistration = onRegistration; return this; } onAuthentication( onAuthentication: (authentication: OutOfBandAuthentication) => void ): OutOfBandOperation { this._onAuthentication = onAuthentication; return this; } onError(onError: (error: OutOfBandOperationError) => void): OutOfBandOperation { this._onError = onError; return this; } async execute(): Promise<void> { const operationId = uuid.v4() as string; const subOperationId = uuid.v4() as string; const operation = new OutOfBandPlatformOperation( operationId, subOperationId, this._onRegistration, this._onAuthentication ); PlatformOperationCache.getInstance().put(operation); const message = new OutOfBandOperationMessage( operationId, subOperationId, false, this.onError !== undefined, this.httpRequestHeaders, this._payload, this._onRegistration !== undefined, this._onAuthentication !== undefined ); function finish() { PlatformOperationCache.getInstance().delete(operationId); } return NevisMobileAuthenticationSdkReact.oobOperation(message) .then((json: any) => { const message = OperationTypeMessage.fromJson(json); operation.selectOperation(message.operationType); finish(); }) .catch((error: Error) => { finish(); const operationError = new OutOfBandOperationErrorConverter(error).convert(); this._onError?.(operationError); }); } }