mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 21:48:04 -05:00
Inji-400: Cache api calls and return initial values if network not available (#883)
* feat(inji-400): Use Initial Config for all properties incase cache and network not available. * feat(inji-400): Create cache apis to fetch and cache issuer api's * feat(inji-400): Update Initial Config comments and remove qa-inji urls * feat(inji-400): Rename catchAPIMethod to generateCacheAPIFunction * feat(inji-400): Rename qa inji url from warningDomainName * feat(inji-400): Update logs for api calls --------- Signed-off-by: Swati Goel <meet2swati@gmail.com> Co-authored-by: Swati Goel <meet2swati@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import {
|
|||||||
CredentialWrapper,
|
CredentialWrapper,
|
||||||
VerifiableCredential,
|
VerifiableCredential,
|
||||||
} from '../types/VC/EsignetMosipVC/vc';
|
} from '../types/VC/EsignetMosipVC/vc';
|
||||||
|
import {CACHED_API} from '../shared/api';
|
||||||
|
|
||||||
const model = createModel(
|
const model = createModel(
|
||||||
{
|
{
|
||||||
@@ -360,21 +361,13 @@ export const IssuersMachine = model.createMachine(
|
|||||||
},
|
},
|
||||||
services: {
|
services: {
|
||||||
downloadIssuersList: async () => {
|
downloadIssuersList: async () => {
|
||||||
const defaultIssuer = {
|
return await CACHED_API.fetchIssuers();
|
||||||
id: 'UIN, VID, AID',
|
},
|
||||||
displayName: 'UIN, VID, AID',
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await request('GET', '/residentmobileapp/issuers');
|
|
||||||
return [defaultIssuer, ...response.response.issuers];
|
|
||||||
},
|
|
||||||
downloadIssuerConfig: async (_, event) => {
|
downloadIssuerConfig: async (_, event) => {
|
||||||
const response = await request(
|
return await CACHED_API.fetchIssuerConfig(event.id);
|
||||||
'GET',
|
|
||||||
`/residentmobileapp/issuers/${event.id}`,
|
|
||||||
);
|
|
||||||
return response.response;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
downloadCredential: async context => {
|
downloadCredential: async context => {
|
||||||
const body = await getBody(context);
|
const body = await getBody(context);
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
|
|||||||
21
shared/InitialConfig.ts
Normal file
21
shared/InitialConfig.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Initial configs used by app if network is not available when app is opened for first time. once network is available response is cached and used from then
|
||||||
|
// Note: Need to keep this config in sync with actual mimoto response.
|
||||||
|
|
||||||
|
export const INITIAL_CONFIG = {
|
||||||
|
// These properties are stored in mosip-config github repo / inji-default.properties
|
||||||
|
allProperties: {
|
||||||
|
modelDownloadMaxRetry: '10',
|
||||||
|
audience: 'ida-binding',
|
||||||
|
allowedInternalAuthType: 'otp,bio-Finger,bio-Iris,bio-Face',
|
||||||
|
vcDownloadMaxRetry: '10',
|
||||||
|
minStorageRequiredForAuditEntry: '2',
|
||||||
|
minStorageRequired: '2',
|
||||||
|
vcDownloadPoolInterval: '6000',
|
||||||
|
issuer: 'residentapp',
|
||||||
|
allowedAuthType: 'demo,otp,bio-Finger,bio-Iris,bio-Face',
|
||||||
|
allowedEkycAuthType: 'demo,otp,bio-Finger,bio-Iris,bio-Face',
|
||||||
|
warningDomainName: '',
|
||||||
|
aboutInjiUrl: 'https://docs.mosip.io/inji',
|
||||||
|
faceSdkModelUrl: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
168
shared/api.ts
Normal file
168
shared/api.ts
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
import {request} from './request';
|
||||||
|
import Storage, {API_CACHED_STORAGE_KEYS} from './storage';
|
||||||
|
import {COMMON_PROPS_KEY} from './commonprops/commonProps';
|
||||||
|
import {INITIAL_CONFIG} from './InitialConfig';
|
||||||
|
|
||||||
|
export const API_URLS = {
|
||||||
|
issuersList: {
|
||||||
|
method: 'GET',
|
||||||
|
buildURL: (): `/${string}` => '/residentmobileapp/issuers',
|
||||||
|
},
|
||||||
|
issuerConfig: {
|
||||||
|
method: 'GET',
|
||||||
|
buildURL: (issuerId: string): `/${string}` =>
|
||||||
|
`/residentmobileapp/issuers/${issuerId}`,
|
||||||
|
},
|
||||||
|
allProperties: {
|
||||||
|
method: 'GET',
|
||||||
|
buildURL: (): `/${string}` => '/residentmobileapp/allProperties',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const API = {
|
||||||
|
fetchIssuers: async () => {
|
||||||
|
const defaultIssuer = {
|
||||||
|
id: 'UIN, VID, AID',
|
||||||
|
displayName: 'UIN, VID, AID',
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await request(
|
||||||
|
API_URLS.issuersList.method,
|
||||||
|
API_URLS.issuersList.buildURL(),
|
||||||
|
);
|
||||||
|
return [defaultIssuer, ...(response.response.issuers || [])];
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchIssuerConfig: async (issuerId: string) => {
|
||||||
|
const response = await request(
|
||||||
|
API_URLS.issuerConfig.method,
|
||||||
|
API_URLS.issuerConfig.buildURL(issuerId),
|
||||||
|
);
|
||||||
|
return response.response;
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchAllProperties: async () => {
|
||||||
|
const response = await request(
|
||||||
|
API_URLS.allProperties.method,
|
||||||
|
API_URLS.allProperties.buildURL(),
|
||||||
|
);
|
||||||
|
return response.response;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CACHED_API = {
|
||||||
|
fetchIssuers: () =>
|
||||||
|
generateCacheAPIFunction({
|
||||||
|
cacheKey: API_CACHED_STORAGE_KEYS.fetchIssuers,
|
||||||
|
fetchCall: API.fetchIssuers,
|
||||||
|
}),
|
||||||
|
|
||||||
|
fetchIssuerConfig: (issuerId: string) =>
|
||||||
|
generateCacheAPIFunction({
|
||||||
|
cacheKey: API_CACHED_STORAGE_KEYS.fetchIssuerConfig(issuerId),
|
||||||
|
fetchCall: API.fetchIssuerConfig.bind(null, issuerId),
|
||||||
|
}),
|
||||||
|
|
||||||
|
getAllProperties: () =>
|
||||||
|
generateCacheAPIFunction({
|
||||||
|
isCachePreferred: true,
|
||||||
|
cacheKey: COMMON_PROPS_KEY,
|
||||||
|
fetchCall: API.fetchAllProperties,
|
||||||
|
onErrorHardCodedValue: INITIAL_CONFIG.allProperties,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
interface GenerateCacheAPIFunctionProps {
|
||||||
|
isCachePreferred?: boolean;
|
||||||
|
cacheKey: string;
|
||||||
|
fetchCall: (...props: any) => Promise<any>;
|
||||||
|
onErrorHardCodedValue?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateCacheAPIFunction({
|
||||||
|
isCachePreferred = false,
|
||||||
|
cacheKey = '',
|
||||||
|
fetchCall = () => Promise.resolve(),
|
||||||
|
onErrorHardCodedValue = undefined,
|
||||||
|
}: GenerateCacheAPIFunctionProps) {
|
||||||
|
if (isCachePreferred) {
|
||||||
|
return await generateCacheAPIFunctionWithCachePreference(
|
||||||
|
cacheKey,
|
||||||
|
fetchCall,
|
||||||
|
onErrorHardCodedValue,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return await generateCacheAPIFunctionWithAPIPreference(
|
||||||
|
cacheKey,
|
||||||
|
fetchCall,
|
||||||
|
onErrorHardCodedValue,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateCacheAPIFunctionWithCachePreference(
|
||||||
|
cacheKey: string,
|
||||||
|
fetchCall: (...props: any[]) => any,
|
||||||
|
onErrorHardCodedValue?: any,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const response = (await Storage.getItem(cacheKey)) as string;
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
return JSON.parse(response);
|
||||||
|
} else {
|
||||||
|
const response = await fetchCall();
|
||||||
|
|
||||||
|
Storage.setItem(cacheKey, JSON.stringify(response)).then(() =>
|
||||||
|
console.log('Cached response for ' + cacheKey),
|
||||||
|
);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`Failed to load due to network issue in cache preferred api call.
|
||||||
|
cache key:${cacheKey} and has onErrorHardCodedValue:${
|
||||||
|
onErrorHardCodedValue != undefined
|
||||||
|
}`);
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
if (onErrorHardCodedValue != undefined) {
|
||||||
|
return onErrorHardCodedValue;
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateCacheAPIFunctionWithAPIPreference(
|
||||||
|
cacheKey: string,
|
||||||
|
fetchCall: (...props: any[]) => any,
|
||||||
|
onErrorHardCodedValue?: any,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const response = await fetchCall();
|
||||||
|
Storage.setItem(cacheKey, JSON.stringify(response)).then(() =>
|
||||||
|
console.log('Cached response for ' + cacheKey),
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`Failed to load due to network issue in API preferred api call.
|
||||||
|
cache key:${cacheKey} and has onErrorHardCodedValue:${
|
||||||
|
onErrorHardCodedValue != undefined
|
||||||
|
}`);
|
||||||
|
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
const response = (await Storage.getItem(cacheKey)) as string;
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
return JSON.parse(response);
|
||||||
|
} else {
|
||||||
|
if (onErrorHardCodedValue != undefined) {
|
||||||
|
return onErrorHardCodedValue;
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,13 @@
|
|||||||
import { request } from '../request';
|
import {init} from 'mosip-inji-face-sdk';
|
||||||
import Storage from '../storage';
|
import {changeCrendetialRegistry} from '../constants';
|
||||||
import { init } from 'mosip-inji-face-sdk';
|
import {CACHED_API} from '../api';
|
||||||
import { changeCrendetialRegistry } from '../constants';
|
|
||||||
|
|
||||||
export const COMMON_PROPS_KEY: string =
|
export const COMMON_PROPS_KEY: string =
|
||||||
'CommonPropsKey-' + '6964d04a-9268-11ed-a1eb-0242ac120002';
|
'CommonPropsKey-' + '6964d04a-9268-11ed-a1eb-0242ac120002';
|
||||||
|
|
||||||
export default async function getAllConfigurations(host = undefined) {
|
export default async function getAllConfigurations(host = undefined) {
|
||||||
try {
|
host && changeCrendetialRegistry(host);
|
||||||
host && changeCrendetialRegistry(host);
|
return await CACHED_API.getAllProperties();
|
||||||
const response = await Storage.getItem(COMMON_PROPS_KEY);
|
|
||||||
if (response) {
|
|
||||||
return JSON.parse(response);
|
|
||||||
} else {
|
|
||||||
const resp = await request('GET', '/residentmobileapp/allProperties');
|
|
||||||
const injiProps = resp.response;
|
|
||||||
const injiPropsString = JSON.stringify(injiProps);
|
|
||||||
await Storage.setItem(COMMON_PROPS_KEY, injiPropsString);
|
|
||||||
return injiProps;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function downloadModel() {
|
export async function downloadModel() {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
import {__AppId} from './GlobalVariables';
|
import {__AppId} from './GlobalVariables';
|
||||||
import {HOST, MIMOTO_BASE_URL} from './constants';
|
import {HOST, MIMOTO_BASE_URL} from './constants';
|
||||||
|
|
||||||
|
export type HTTP_METHOD = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
|
||||||
|
|
||||||
export class BackendResponseError extends Error {
|
export class BackendResponseError extends Error {
|
||||||
constructor(name: string, message: string) {
|
constructor(name: string, message: string) {
|
||||||
super(message);
|
super(message);
|
||||||
@@ -13,7 +15,7 @@ export class BackendResponseError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function request(
|
export async function request(
|
||||||
method: 'GET' | 'POST' | 'PATCH',
|
method: HTTP_METHOD,
|
||||||
path: `/${string}`,
|
path: `/${string}`,
|
||||||
body?: Record<string, unknown>,
|
body?: Record<string, unknown>,
|
||||||
host = MIMOTO_BASE_URL,
|
host = MIMOTO_BASE_URL,
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ import {VCMetadata} from './VCMetadata';
|
|||||||
const MMKV = new MMKVLoader().initialize();
|
const MMKV = new MMKVLoader().initialize();
|
||||||
const vcDirectoryPath = `${DocumentDirectoryPath}/inji/VC`;
|
const vcDirectoryPath = `${DocumentDirectoryPath}/inji/VC`;
|
||||||
|
|
||||||
|
export const API_CACHED_STORAGE_KEYS = {
|
||||||
|
fetchIssuers: 'CACHE_FETCH_ISSUERS',
|
||||||
|
fetchIssuerConfig: (issuerId: string) =>
|
||||||
|
`CACHE_FETCH_ISSUER_CONFIG_${issuerId}`,
|
||||||
|
};
|
||||||
|
|
||||||
async function generateHmac(
|
async function generateHmac(
|
||||||
encryptionKey: string,
|
encryptionKey: string,
|
||||||
data: string,
|
data: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user