Files
inji-wallet/machines/auth.ts
Tilak Puli ec9fd9f6d9 Inji-344: Refactoring VC Key (#798)
* feat(inji-344): Use VC Key class instead of separate functions for managing vc key

* feat(inji-344): Use properties from VcKey Class instead of reading from vckey string

* feat(inji-344): Rename vcKey to vcMetadata

* feat(inji-344): Use vc's unique id or vckey instead of joined string of vc metadata

* feat(inji-344): Use vc key instead of unique id to avoid confusion. Fix issues reg parsing vc metadata

* feat(inji-344):fix redownloading issue

Co-authored-by: Tilak <tilakpuli15@gmail.com>

* feat(inji-344): Remove vc getting stored on update of pin status

* feat(inji-344): update other vc's pin status to false when any vc is pinned

* feat(inji-344): remove hash ID for UIN

* feat(inji-344): revert google services json

* feat(inji-344): remove mmkv logs added for debugging

* feat(inji-344): fix received vcs not getting displayed on reopen of app

* feat(inji-344): fix id not shown in revoke component

---------

Co-authored-by: Sri Kanth Kola <srikanthsri7447@gmail.com>
2023-09-20 16:51:59 +05:30

240 lines
5.9 KiB
TypeScript

import {init} from 'mosip-inji-face-sdk';
import {assign, ContextFrom, EventFrom, send, StateFrom} from 'xstate';
import {createModel} from 'xstate/lib/model';
import getAllConfigurations, {
downloadModel,
} from '../shared/commonprops/commonProps';
import {AppServices} from '../shared/GlobalContext';
import {StoreEvents, StoreResponseEvent} from './store';
import {generateSecureRandom} from 'react-native-securerandom';
import binaryToBase64 from 'react-native/Libraries/Utilities/binaryToBase64';
const model = createModel(
{
serviceRefs: {} as AppServices,
passcode: '',
passcodeSalt: '',
biometrics: '',
canUseBiometrics: false,
selectLanguage: false,
},
{
events: {
SETUP_PASSCODE: (passcode: string) => ({passcode}),
SETUP_BIOMETRICS: (biometrics: string) => ({biometrics}),
LOGOUT: () => ({}),
LOGIN: () => ({}),
STORE_RESPONSE: (response?: unknown) => ({response}),
SELECT: () => ({}),
NEXT: () => ({}),
},
},
);
export const AuthEvents = model.events;
type SetupBiometricsEvent = EventFrom<typeof model, 'SETUP_BIOMETRICS'>;
export const authMachine = model.createMachine(
{
predictableActionArguments: true,
preserveActionOrder: true,
tsTypes: {} as import('./auth.typegen').Typegen0,
schema: {
context: model.initialContext,
events: {} as EventFrom<typeof model>,
},
id: 'auth',
initial: 'init',
states: {
init: {
entry: ['requestStoredContext'],
on: {
STORE_RESPONSE: [
{
cond: 'hasData',
target: 'checkingAuth',
actions: ['setContext'],
},
{target: 'savingDefaults'},
],
},
},
savingDefaults: {
entry: ['storeContext'],
on: {
STORE_RESPONSE: 'checkingAuth',
},
},
checkingAuth: {
always: [
{cond: 'hasLanguageset', target: 'languagesetup'},
{cond: 'hasPasscodeSet', target: 'unauthorized'},
{cond: 'hasBiometricSet', target: 'unauthorized'},
{target: 'settingUp'},
],
},
languagesetup: {
on: {
SELECT: {
target: 'introSlider',
},
},
},
introSlider: {
invoke: {
src: 'generatePasscodeSalt',
onDone: {
actions: ['setPasscodeSalt', 'storeContext'],
},
},
on: {
NEXT: {
target: 'settingUp',
},
},
},
settingUp: {
on: {
SETUP_PASSCODE: {
target: 'authorized',
actions: ['setPasscode', 'setLanguage', 'storeContext'],
},
SETUP_BIOMETRICS: {
// Note! dont authorized yet we need to setup passcode too as discuss
// target: 'authorized',
actions: ['setBiometrics', 'setLanguage', 'storeContext'],
},
},
},
unauthorized: {
on: {
LOGIN: 'authorized',
},
},
authorized: {
invoke: {
src: 'downloadFaceSdkModel',
onDone: {
actions: ['storeContext'],
},
},
on: {
LOGOUT: 'unauthorized',
SETUP_BIOMETRICS: {
actions: ['setBiometrics', 'storeContext'],
},
},
},
},
},
{
actions: {
requestStoredContext: send(StoreEvents.GET('auth'), {
to: context => context.serviceRefs.store,
}),
storeContext: send(
context => {
const {serviceRefs, ...data} = context;
return StoreEvents.SET('auth', data);
},
{to: context => context.serviceRefs.store},
),
setContext: model.assign((_, event) => {
const {serviceRefs, ...data} = event.response as ContextFrom<
typeof model
>;
return data;
}),
setPasscode: model.assign({
passcode: (_, event) => event.passcode,
}),
setBiometrics: model.assign({
biometrics: (_, event: SetupBiometricsEvent) => event.biometrics,
}),
setLanguage: assign({
selectLanguage: context => true,
}),
setPasscodeSalt: assign({
passcodeSalt: (context, event) => {
return event.data as string;
},
}),
},
services: {
downloadFaceSdkModel: () => () => {
downloadModel();
},
generatePasscodeSalt: () => async context => {
const randomBytes = await generateSecureRandom(16);
return binaryToBase64(randomBytes) as string;
},
},
guards: {
hasData: (_, event: StoreResponseEvent) => event.response != null,
hasPasscodeSet: context => {
return context.passcode !== '';
},
hasBiometricSet: context => {
return context.biometrics !== '' && context.passcode !== '';
},
hasLanguageset: context => {
return !context.selectLanguage;
},
},
},
);
export function createAuthMachine(serviceRefs: AppServices) {
return authMachine.withContext({
...authMachine.context,
serviceRefs,
});
}
type State = StateFrom<typeof authMachine>;
export function selectPasscode(state: State) {
return state.context.passcode;
}
export function selectPasscodeSalt(state: State) {
return state.context.passcodeSalt;
}
export function selectBiometrics(state: State) {
return state.context.biometrics;
}
export function selectCanUseBiometrics(state: State) {
return state.context.canUseBiometrics;
}
export function selectAuthorized(state: State) {
return state.matches('authorized');
}
export function selectUnauthorized(state: State) {
return state.matches('unauthorized');
}
export function selectSettingUp(state: State) {
return state.matches('settingUp');
}
export function selectLanguagesetup(state: State) {
return state.matches('languagesetup');
}
export function selectIntroSlider(state: State) {
return state.matches('introSlider');
}