@nevis-security/nevis-mobile-authentication-sdk-react
Version:
React Native plugin for Nevis Mobile Authentication SDK. Supports only mobile.
167 lines (150 loc) • 5.18 kB
text/typescript
/**
* Copyright © 2024 Nevis Security AG. All rights reserved.
*/
import uuid from 'react-native-uuid';
import type { PasswordChanger } from './PasswordChanger';
import { UserInteractionPlatformOperationImpl } from '../../cache/operation/UserInteractionPlatformOperation';
import { PlatformOperationCache } from '../../cache/PlatformOperationCache';
import type { PasswordChangeError } from '../../error/password/change/PasswordChangeError';
import { PasswordChangeErrorConverter } from '../../error/password/change/PasswordChangeErrorConverter';
import { NativeEventListener } from '../../event/NativeEventListener';
import NevisMobileAuthenticationSdkReact from '../../MobileAuthenticationSdk';
import { PasswordChangeMessage } from '../../model/messages/out/PasswordChangeMessage';
import { Operation } from '../Operation';
/**
* The object that can be used to change the password.
*
* Usage example:
* ```ts
* class PasswordChangerImpl implements PasswordChanger {
* async changePassword(context: PasswordChangeContext, handler: PasswordChangeHandler) {
* handler.passwords(oldPassword, newPassword);
* }
* }
*
* [...]
* async changePassword({
* client: MobileAuthenticationClient,
* username: string,
* }): Promise<void> {
* await client.operations.passwordChange
* .username(username)
* .passwordChanger(PasswordChangerImpl(...))
* .onSuccess(() {
* // handle success
* })
* .onError((error) {
* // handle error
* })
* .execute();
* }
* [...]
* ```
*/
export abstract class PasswordChange extends Operation {
/**
* The username whose password must be changed.
*
* **IMPORTANT** \
* Providing the {@link username} is required.
*
* **WARNING** \
* The username is the technical user identifier stored in the {@link Account.username} property.
* Do not provide the login identifier (for example the users e-mail address) here.
* We recommend always using the username provided via {@link LocalData.accounts}.
*
* @param username the username.
* @returns a {@link PasswordChange} object.
*/
abstract username(username: string): PasswordChange;
/**
* Specifies the object that will be informed of the potential recoverable
* errors and is responsible for obtaining the password from the end-user.
*
* **IMPORTANT** \
* Providing the {@link passwordChanger} is required.
*
* @param passwordChanger the {@link passwordChanger}
* @returns a {@link PasswordChange} object.
*/
abstract passwordChanger(passwordChanger: PasswordChanger): PasswordChange;
/**
* Specifies the object that will be invoked if the password was successfully modified.
*
* **IMPORTANT** \
* Providing the {@link onSuccess} is required.
*
* @param onSuccess the callback which is invoked on successful password modification.
* @returns a {@link PasswordChange} object.
*/
abstract onSuccess(onSuccess: () => void): PasswordChange;
/**
* Specifies the object that will be invoked when the password could not be changed:
* the password was not enrolled, the password is locked or the operation was canceled.
*
* **IMPORTANT** \
* Providing the {@link onError} is required.
*
* @param onError the callback which receives a {@link PasswordChangeError}.
* @returns a {@link PasswordChange} object.
*/
abstract onError(onError: (error: PasswordChangeError) => void): PasswordChange;
}
export class PasswordChangeImpl extends PasswordChange {
private _username?: string;
private _passwordChanger?: PasswordChanger;
private _onSuccess?: () => void;
private _onError?: (error: PasswordChangeError) => void;
username(username: string): PasswordChange {
this._username = username;
return this;
}
passwordChanger(passwordChanger: PasswordChanger): PasswordChange {
this._passwordChanger = passwordChanger;
return this;
}
onSuccess(onSuccess: () => void): PasswordChange {
this._onSuccess = onSuccess;
return this;
}
onError(onError: (error: PasswordChangeError) => void): PasswordChange {
this._onError = onError;
return this;
}
async execute(): Promise<void> {
const operationId = uuid.v4() as string;
const operation = new UserInteractionPlatformOperationImpl(
operationId,
undefined,
undefined,
undefined,
undefined,
undefined,
this._passwordChanger,
undefined
);
PlatformOperationCache.getInstance().put(operation);
NativeEventListener.getInstance().start(operationId);
const message = new PasswordChangeMessage(
operationId,
this._passwordChanger !== undefined,
this._onSuccess !== undefined,
this._onError !== undefined,
this._username
);
function finish() {
NativeEventListener.getInstance().stop(operationId);
PlatformOperationCache.getInstance().delete(operationId);
}
return NevisMobileAuthenticationSdkReact.passwordChange(message)
.then(() => {
finish();
this._onSuccess?.();
})
.catch((error: any) => {
finish();
const passwordChangeError = new PasswordChangeErrorConverter(error).convert();
this._onError?.(passwordChangeError);
});
}
}