Integrated with Idp changes

This commit is contained in:
Monobikash Das
2023-01-13 19:59:10 +05:30
parent 95a28b1bd5
commit 83b303a0dc
10 changed files with 421 additions and 171 deletions

View File

@@ -13,6 +13,8 @@ import { MY_VCS_STORE_KEY } from '../shared/constants';
import { StoreEvents } from './store';
import { linkTransactionResponse, VC } from '../types/vc';
import { request } from '../shared/request';
import { getJwt } from '../shared/cryptoutil/cryptoUtil';
import { getPrivateKey } from '../shared/keystore/SecureKeystore';
const model = createModel(
{
@@ -314,20 +316,32 @@ export const qrLoginMachine =
},
sendConsent: async (context) => {
console.log('Individual id : ' + context.selectedVc.id);
var privateKey = await getPrivateKey(
context.selectedVc.walletBindingResponse?.walletBindingId
);
var walletBindingResponse = context.selectedVc.walletBindingResponse;
var jwt = await getJwt(
privateKey,
context.selectedVc.id,
walletBindingResponse?.keyId,
walletBindingResponse?.thumbprint
);
const resp = await request('POST', '/idp-authenticate', {
requestTime: String(new Date().toISOString()),
request: {
linkedTransactionId: context.linkTransactionId,
individualId: '3295638027105149',
individualId: context.selectedVc.id,
challengeList: [
{
authFactorType: 'OTP',
challenge: '111111',
authFactorType: 'WLA',
challenge: jwt,
format: 'jwt',
},
],
},
});
const trnId = resp.response.linkedTransactionId;
const response = await request('POST', '/idp-consent', {

View File

@@ -1,7 +1,7 @@
import { init } from 'mosip-inji-face-sdk';
import { ContextFrom, EventFrom, send, StateFrom } from 'xstate';
import { createModel } from 'xstate/lib/model';
import getAllProperties from '../shared/commonprops/commonProps';
import getAllConfigurations from '../shared/commonprops/commonProps';
import { AppServices } from '../shared/GlobalContext';
import { StoreEvents, StoreResponseEvent } from './store';
@@ -11,7 +11,6 @@ const model = createModel(
passcode: '',
biometrics: '',
canUseBiometrics: false,
injiAppProperties: null,
},
{
events: {
@@ -88,7 +87,7 @@ export const authMachine = model.createMachine(
invoke: {
src: 'downloadFaceSdkModel',
onDone: {
actions: ['setInjiAppProperties', 'storeContext'],
actions: ['storeContext'],
},
},
on: {
@@ -128,21 +127,13 @@ export const authMachine = model.createMachine(
setBiometrics: model.assign({
biometrics: (_, event: SetupBiometricsEvent) => event.biometrics,
}),
setInjiAppProperties: model.assign({
injiAppProperties: (_, event) => event.data as object,
}),
},
services: {
downloadFaceSdkModel: (context) => async () => {
downloadFaceSdkModel: () => async () => {
var injiProp = null;
try {
if (context.injiAppProperties == null) {
injiProp = await getAllProperties();
} else {
injiProp = context.injiAppProperties;
}
var injiProp = await getAllConfigurations();
const resp: string =
injiProp != null ? injiProp.faceSdkModelUrl : null;
if (resp != null) {
@@ -151,7 +142,6 @@ export const authMachine = model.createMachine(
} catch (error) {
console.log(error);
}
return injiProp;
},
},
@@ -200,7 +190,3 @@ export function selectUnauthorized(state: State) {
export function selectSettingUp(state: State) {
return state.matches('settingUp');
}
export function selectInjiAppProps(state: State) {
return state.context.injiAppProperties;
}

View File

@@ -24,7 +24,6 @@ export interface Typegen0 {
requestStoredContext: 'xstate.init';
setBiometrics: 'SETUP_BIOMETRICS';
setContext: 'STORE_RESPONSE';
setInjiAppProperties: 'done.invoke.auth.authorized:invocation[0]';
setPasscode: 'SETUP_PASSCODE';
storeContext:
| 'SETUP_BIOMETRICS'

View File

@@ -13,9 +13,18 @@ import { StoreEvents } from './store';
import { ActivityLogEvents } from './activityLog';
import { verifyCredential } from '../shared/vcjs/verifyCredential';
import { log } from 'xstate/lib/actions';
import { generateKeys } from '../shared/cryptoutil/cryptoUtil';
import {
generateKeys,
getJwt,
WalletBindingResponse,
} from '../shared/cryptoutil/cryptoUtil';
import { KeyPair } from 'react-native-rsa-native';
import { savePrivateKey } from '../shared/keystore/SecureKeystore';
import {
getBindingCertificateConstant,
getPrivateKey,
savePrivateKey,
} from '../shared/keystore/SecureKeystore';
import getAllConfigurations from '../shared/commonprops/commonProps';
const model = createModel(
{
@@ -37,7 +46,8 @@ const model = createModel(
bindingTransactionId: '',
revoked: false,
downloadCounter: 0,
walletBindingId: '',
maxDownloadCount: 10,
walletBindingResponse: null as WalletBindingResponse,
walletBindingError: '',
publicKey: '',
privateKey: '',
@@ -126,8 +136,20 @@ export const vcItemMachine =
checkingServerData: {
description:
"Download VC data from the server. Uses polling method to check when it's available.",
initial: 'checkingStatus',
initial: 'verifyingDownloadLimitExpiry',
states: {
verifyingDownloadLimitExpiry: {
invoke: {
src: 'checkDownloadExpiryLimit',
onDone: {
target: 'checkingStatus',
actions: 'setMaxDownloadCount',
},
onError: {
actions: log((_, event) => (event.data as Error).message),
},
},
},
checkingStatus: {
invoke: {
src: 'checkStatus',
@@ -135,10 +157,10 @@ export const vcItemMachine =
},
on: {
POLL: {
cond: 'isDownloadAllowed',
actions: send('POLL_STATUS', { to: 'checkStatus' }),
},
DOWNLOAD_READY: {
actions: 'resetDownloadCounter',
target: 'downloadingCredential',
},
},
@@ -388,7 +410,6 @@ export const vcItemMachine =
onDone: [
{
target: 'acceptingBindingOtp',
actions: ['setBindingTransactionId'],
},
],
onError: [
@@ -499,7 +520,8 @@ export const vcItemMachine =
}),
setWalletBindingId: assign({
walletBindingId: (context, event) => event.data as string,
walletBindingResponse: (context, event) =>
event.data as WalletBindingResponse,
}),
updateVc: send(
@@ -543,14 +565,14 @@ export const vcItemMachine =
tag: (_, event) => event.tag,
}),
resetDownloadCounter: model.assign({
downloadCounter: () => 0,
}),
incrementDownloadCounter: model.assign({
downloadCounter: ({ downloadCounter }) => downloadCounter + 1,
}),
setMaxDownloadCount: model.assign({
maxDownloadCount: (_context, event) => event.data as number,
}),
storeTag: send(
(context) => {
const { serviceRefs, ...data } = context;
@@ -621,10 +643,6 @@ export const vcItemMachine =
transactionId: () => String(new Date().valueOf()).substring(3, 13),
}),
setBindingTransactionId: assign({
bindingTransactionId: (_, event) => event.data as string,
}),
clearTransactionId: assign({ transactionId: '' }),
setOtp: model.assign({
@@ -656,27 +674,54 @@ export const vcItemMachine =
},
services: {
checkDownloadExpiryLimit: async (context) => {
var resp = await getAllConfigurations();
const maxLimit: number = resp.vcDownloadMaxRetry;
console.log(maxLimit);
if (maxLimit <= context.downloadCounter) {
throw new Error(
'Download limit expired for request id: ' + context.requestId
);
}
return maxLimit;
},
addWalletBindnigId: async (context) => {
const response = await request('POST', '/wallet-binding', {
requestTime: String(new Date().toISOString()),
request: {
individualId: '8267411571',
authFactorType: 'WLA',
format: 'jwt',
individualId: context.id,
transactionId: context.bindingTransactionId,
publicKey: context.publicKey,
challengeList: [
{
authFactorType: 'OTP',
challenge: context.otp,
format: 'alpha-numeric',
},
],
},
});
return response.response.encryptedWalletBindingId;
const certificate = response.response.certificate;
await savePrivateKey(
getBindingCertificateConstant(context.id),
certificate
);
const walletResponse: WalletBindingResponse = {
walletBindingId: response.response.encryptedWalletBindingId,
keyId: response.response.keyId,
thumbprint: response.response.thumbprint,
expireDateTime: response.response.expireDateTime,
};
return walletResponse;
},
updatePrivateKey: async (context) => {
const hasSetPrivateKey: boolean = await savePrivateKey(
context.walletBindingId,
context.walletBindingResponse.walletBindingId,
context.privateKey
);
if (!hasSetPrivateKey) {
@@ -694,11 +739,13 @@ export const vcItemMachine =
const response = await request('POST', '/binding-otp', {
requestTime: String(new Date().toISOString()),
request: {
individualId: '8267411571',
individualId: context.id,
otpChannels: ['EMAIL'],
},
});
return response.response.transactionId;
if (response.response == null) {
throw new Error('Could not process request');
}
},
checkStatus: (context) => (callback, onReceive) => {
@@ -756,7 +803,7 @@ export const vcItemMachine =
isVerified: false,
lastVerifiedOn: null,
locked: context.locked,
walletBindingId: context.walletBindingId,
walletBindingResponse: null,
})
);
}
@@ -829,7 +876,7 @@ export const vcItemMachine =
},
isDownloadAllowed: (_context, event) => {
return _context.downloadCounter < 10;
return _context.downloadCounter <= _context.maxDownloadCount;
},
isVcValid: (context) => {
@@ -925,11 +972,13 @@ export function selectIsRequestBindingOtp(state: State) {
}
export function selectWalletBindingId(state: State) {
return state.context.walletBindingId;
return state.context.walletBindingResponse;
}
export function selectEmptyWalletBindingId(state: State) {
var val = state.context.walletBindingId;
var val = state.context.walletBindingResponse
? state.context.walletBindingResponse.walletBindingId
: undefined;
return val === undefined || val == null || val.length <= 0 ? true : false;
}

View File

@@ -1,101 +1,246 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"": { type: "" };
"done.invoke.checkStatus": { type: "done.invoke.checkStatus"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.downloadCredential": { type: "done.invoke.downloadCredential"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.addKeyPair:invocation[0]": { type: "done.invoke.vc-item.addKeyPair:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.addingWalletBindingId:invocation[0]": { type: "done.invoke.vc-item.addingWalletBindingId:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.requestingBindingOtp:invocation[0]": { type: "done.invoke.vc-item.requestingBindingOtp:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.requestingLock:invocation[0]": { type: "done.invoke.vc-item.requestingLock:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.requestingOtp:invocation[0]": { type: "done.invoke.vc-item.requestingOtp:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.requestingRevoke:invocation[0]": { type: "done.invoke.vc-item.requestingRevoke:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.updatingPrivateKey:invocation[0]": { type: "done.invoke.vc-item.updatingPrivateKey:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item.verifyingCredential:invocation[0]": { type: "done.invoke.vc-item.verifyingCredential:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform.checkStatus": { type: "error.platform.checkStatus"; data: unknown };
"error.platform.downloadCredential": { type: "error.platform.downloadCredential"; data: unknown };
"error.platform.vc-item.addKeyPair:invocation[0]": { type: "error.platform.vc-item.addKeyPair:invocation[0]"; data: unknown };
"error.platform.vc-item.addingWalletBindingId:invocation[0]": { type: "error.platform.vc-item.addingWalletBindingId:invocation[0]"; data: unknown };
"error.platform.vc-item.requestingBindingOtp:invocation[0]": { type: "error.platform.vc-item.requestingBindingOtp:invocation[0]"; data: unknown };
"error.platform.vc-item.requestingLock:invocation[0]": { type: "error.platform.vc-item.requestingLock:invocation[0]"; data: unknown };
"error.platform.vc-item.requestingRevoke:invocation[0]": { type: "error.platform.vc-item.requestingRevoke:invocation[0]"; data: unknown };
"error.platform.vc-item.updatingPrivateKey:invocation[0]": { type: "error.platform.vc-item.updatingPrivateKey:invocation[0]"; data: unknown };
"error.platform.vc-item.verifyingCredential:invocation[0]": { type: "error.platform.vc-item.verifyingCredential:invocation[0]"; data: unknown };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"addWalletBindnigId": "done.invoke.vc-item.addingWalletBindingId:invocation[0]";
"checkStatus": "done.invoke.checkStatus";
"downloadCredential": "done.invoke.downloadCredential";
"generateKeyPair": "done.invoke.vc-item.addKeyPair:invocation[0]";
"requestBindingOtp": "done.invoke.vc-item.requestingBindingOtp:invocation[0]";
"requestLock": "done.invoke.vc-item.requestingLock:invocation[0]";
"requestOtp": "done.invoke.vc-item.requestingOtp:invocation[0]";
"requestRevoke": "done.invoke.vc-item.requestingRevoke:invocation[0]";
"updatePrivateKey": "done.invoke.vc-item.updatingPrivateKey:invocation[0]";
"verifyCredential": "done.invoke.vc-item.verifyingCredential:invocation[0]";
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
"clearOtp": "" | "BINDING_DONE" | "CANCEL" | "DISMISS" | "REVOKE_VC" | "STORE_RESPONSE" | "done.invoke.vc-item.requestingBindingOtp:invocation[0]" | "done.invoke.vc-item.requestingOtp:invocation[0]" | "done.invoke.vc-item.verifyingCredential:invocation[0]" | "error.platform.vc-item.requestingLock:invocation[0]" | "error.platform.vc-item.requestingRevoke:invocation[0]" | "error.platform.vc-item.verifyingCredential:invocation[0]";
"clearTransactionId": "" | "BINDING_DONE" | "CANCEL" | "DISMISS" | "STORE_RESPONSE" | "done.invoke.vc-item.verifyingCredential:invocation[0]" | "error.platform.vc-item.verifyingCredential:invocation[0]";
"incrementDownloadCounter": "POLL";
"logDownloaded": "CREDENTIAL_DOWNLOADED";
"logRevoked": "STORE_RESPONSE";
"markVcValid": "done.invoke.vc-item.verifyingCredential:invocation[0]";
"requestStoredContext": "GET_VC_RESPONSE" | "REFRESH";
"requestVcContext": "xstate.init";
"resetDownloadCounter": "DOWNLOAD_READY";
"revokeVID": "done.invoke.vc-item.requestingRevoke:invocation[0]";
"setBindingTransactionId": "done.invoke.vc-item.requestingBindingOtp:invocation[0]";
"setCredential": "CREDENTIAL_DOWNLOADED" | "GET_VC_RESPONSE" | "STORE_RESPONSE";
"setLock": "done.invoke.vc-item.requestingLock:invocation[0]";
"setOtp": "INPUT_OTP";
"setOtpError": "error.platform.vc-item.requestingLock:invocation[0]" | "error.platform.vc-item.requestingRevoke:invocation[0]";
"setPrivateKey": "done.invoke.vc-item.addKeyPair:invocation[0]";
"setPublicKey": "done.invoke.vc-item.addKeyPair:invocation[0]";
"setRevoke": "done.invoke.vc-item.requestingRevoke:invocation[0]";
"setTag": "SAVE_TAG";
"setTransactionId": "INPUT_OTP" | "REVOKE_VC" | "done.invoke.vc-item.requestingOtp:invocation[0]" | "error.platform.vc-item.requestingLock:invocation[0]" | "error.platform.vc-item.requestingRevoke:invocation[0]";
"setWalletBindingError": "error.platform.vc-item.addKeyPair:invocation[0]" | "error.platform.vc-item.addingWalletBindingId:invocation[0]" | "error.platform.vc-item.requestingBindingOtp:invocation[0]" | "error.platform.vc-item.updatingPrivateKey:invocation[0]";
"setWalletBindingErrorEmpty": "BINDING_DONE" | "CANCEL";
"setWalletBindingId": "done.invoke.vc-item.addingWalletBindingId:invocation[0]";
"storeContext": "CREDENTIAL_DOWNLOADED" | "done.invoke.vc-item.updatingPrivateKey:invocation[0]" | "done.invoke.vc-item.verifyingCredential:invocation[0]";
"storeLock": "done.invoke.vc-item.requestingLock:invocation[0]";
"storeTag": "SAVE_TAG";
"updatePrivateKey": "done.invoke.vc-item.updatingPrivateKey:invocation[0]";
"updateVc": "CREDENTIAL_DOWNLOADED" | "STORE_RESPONSE" | "done.invoke.vc-item.updatingPrivateKey:invocation[0]" | "done.invoke.vc-item.verifyingCredential:invocation[0]";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"hasCredential": "GET_VC_RESPONSE" | "STORE_RESPONSE";
"isDownloadAllowed": "POLL";
"isVcValid": "";
};
eventsCausingServices: {
"addWalletBindnigId": "done.invoke.vc-item.addKeyPair:invocation[0]";
"checkStatus": "STORE_RESPONSE";
"downloadCredential": "DOWNLOAD_READY";
"generateKeyPair": "INPUT_OTP";
"requestBindingOtp": "CONFIRM";
"requestLock": "INPUT_OTP";
"requestOtp": "LOCK_VC";
"requestRevoke": "INPUT_OTP";
"updatePrivateKey": "done.invoke.vc-item.addingWalletBindingId:invocation[0]";
"verifyCredential": "" | "VERIFY";
};
matchesStates: "acceptingBindingOtp" | "acceptingOtpInput" | "acceptingRevokeInput" | "addKeyPair" | "addingWalletBindingId" | "checkingServerData" | "checkingServerData.checkingStatus" | "checkingServerData.downloadingCredential" | "checkingStore" | "checkingVc" | "checkingVerificationStatus" | "editingTag" | "idle" | "invalid" | "invalid.backend" | "invalid.otp" | "lockingVc" | "loggingRevoke" | "requestingBindingOtp" | "requestingLock" | "requestingOtp" | "requestingRevoke" | "revokingVc" | "showBindingStatus" | "showBindingWarning" | "showingWalletBindingError" | "storingTag" | "updatingPrivateKey" | "verifyingCredential" | { "checkingServerData"?: "checkingStatus" | "downloadingCredential";
"invalid"?: "backend" | "otp"; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
'internalEvents': {
'': { type: '' };
'done.invoke.checkStatus': {
type: 'done.invoke.checkStatus';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.downloadCredential': {
type: 'done.invoke.downloadCredential';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.addKeyPair:invocation[0]': {
type: 'done.invoke.vc-item.addKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.addingWalletBindingId:invocation[0]': {
type: 'done.invoke.vc-item.addingWalletBindingId:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]': {
type: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingBindingOtp:invocation[0]': {
type: 'done.invoke.vc-item.requestingBindingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingLock:invocation[0]': {
type: 'done.invoke.vc-item.requestingLock:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingOtp:invocation[0]': {
type: 'done.invoke.vc-item.requestingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingRevoke:invocation[0]': {
type: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.updatingPrivateKey:invocation[0]': {
type: 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.verifyingCredential:invocation[0]': {
type: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.checkStatus': {
type: 'error.platform.checkStatus';
data: unknown;
};
'error.platform.downloadCredential': {
type: 'error.platform.downloadCredential';
data: unknown;
};
'error.platform.vc-item.addKeyPair:invocation[0]': {
type: 'error.platform.vc-item.addKeyPair:invocation[0]';
data: unknown;
};
'error.platform.vc-item.addingWalletBindingId:invocation[0]': {
type: 'error.platform.vc-item.addingWalletBindingId:invocation[0]';
data: unknown;
};
'error.platform.vc-item.requestingBindingOtp:invocation[0]': {
type: 'error.platform.vc-item.requestingBindingOtp:invocation[0]';
data: unknown;
};
'error.platform.vc-item.requestingLock:invocation[0]': {
type: 'error.platform.vc-item.requestingLock:invocation[0]';
data: unknown;
};
'error.platform.vc-item.requestingRevoke:invocation[0]': {
type: 'error.platform.vc-item.requestingRevoke:invocation[0]';
data: unknown;
};
'error.platform.vc-item.updatingPrivateKey:invocation[0]': {
type: 'error.platform.vc-item.updatingPrivateKey:invocation[0]';
data: unknown;
};
'error.platform.vc-item.verifyingCredential:invocation[0]': {
type: 'error.platform.vc-item.verifyingCredential:invocation[0]';
data: unknown;
};
'xstate.init': { type: 'xstate.init' };
};
'invokeSrcNameMap': {
addWalletBindnigId: 'done.invoke.vc-item.addingWalletBindingId:invocation[0]';
checkDownloadExpiryLimit: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
checkStatus: 'done.invoke.checkStatus';
downloadCredential: 'done.invoke.downloadCredential';
generateKeyPair: 'done.invoke.vc-item.addKeyPair:invocation[0]';
requestBindingOtp: 'done.invoke.vc-item.requestingBindingOtp:invocation[0]';
requestLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
requestOtp: 'done.invoke.vc-item.requestingOtp:invocation[0]';
requestRevoke: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
updatePrivateKey: 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
verifyCredential: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
};
'missingImplementations': {
actions: never;
delays: never;
guards: never;
services: never;
};
'eventsCausingActions': {
clearOtp:
| ''
| 'BINDING_DONE'
| 'CANCEL'
| 'DISMISS'
| 'REVOKE_VC'
| 'STORE_RESPONSE'
| 'done.invoke.vc-item.requestingBindingOtp:invocation[0]'
| 'done.invoke.vc-item.requestingOtp:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
| 'error.platform.vc-item.requestingLock:invocation[0]'
| 'error.platform.vc-item.requestingRevoke:invocation[0]'
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
clearTransactionId:
| ''
| 'BINDING_DONE'
| 'CANCEL'
| 'DISMISS'
| 'STORE_RESPONSE'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
incrementDownloadCounter: 'POLL';
logDownloaded: 'CREDENTIAL_DOWNLOADED';
logRevoked: 'STORE_RESPONSE';
markVcValid: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
requestStoredContext: 'GET_VC_RESPONSE' | 'REFRESH';
requestVcContext: 'xstate.init';
revokeVID: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
setCredential:
| 'CREDENTIAL_DOWNLOADED'
| 'GET_VC_RESPONSE'
| 'STORE_RESPONSE';
setLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
setMaxDownloadCount: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
setOtp: 'INPUT_OTP';
setOtpError:
| 'error.platform.vc-item.requestingLock:invocation[0]'
| 'error.platform.vc-item.requestingRevoke:invocation[0]';
setPrivateKey: 'done.invoke.vc-item.addKeyPair:invocation[0]';
setPublicKey: 'done.invoke.vc-item.addKeyPair:invocation[0]';
setRevoke: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
setTag: 'SAVE_TAG';
setTransactionId:
| 'INPUT_OTP'
| 'REVOKE_VC'
| 'done.invoke.vc-item.requestingOtp:invocation[0]'
| 'error.platform.vc-item.requestingLock:invocation[0]'
| 'error.platform.vc-item.requestingRevoke:invocation[0]';
setWalletBindingError:
| 'error.platform.vc-item.addKeyPair:invocation[0]'
| 'error.platform.vc-item.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item.requestingBindingOtp:invocation[0]'
| 'error.platform.vc-item.updatingPrivateKey:invocation[0]';
setWalletBindingErrorEmpty: 'BINDING_DONE' | 'CANCEL';
setWalletBindingId: 'done.invoke.vc-item.addingWalletBindingId:invocation[0]';
storeContext:
| 'CREDENTIAL_DOWNLOADED'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]';
storeLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
storeTag: 'SAVE_TAG';
updatePrivateKey: 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
updateVc:
| 'CREDENTIAL_DOWNLOADED'
| 'STORE_RESPONSE'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]';
};
'eventsCausingDelays': {};
'eventsCausingGuards': {
hasCredential: 'GET_VC_RESPONSE' | 'STORE_RESPONSE';
isDownloadAllowed: 'POLL';
isVcValid: '';
};
'eventsCausingServices': {
addWalletBindnigId: 'done.invoke.vc-item.addKeyPair:invocation[0]';
checkDownloadExpiryLimit: 'STORE_RESPONSE';
checkStatus: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
downloadCredential: 'DOWNLOAD_READY';
generateKeyPair: 'INPUT_OTP';
requestBindingOtp: 'CONFIRM';
requestLock: 'INPUT_OTP';
requestOtp: 'LOCK_VC';
requestRevoke: 'INPUT_OTP';
updatePrivateKey: 'done.invoke.vc-item.addingWalletBindingId:invocation[0]';
verifyCredential: '' | 'VERIFY';
};
'matchesStates':
| 'acceptingBindingOtp'
| 'acceptingOtpInput'
| 'acceptingRevokeInput'
| 'addKeyPair'
| 'addingWalletBindingId'
| 'checkingServerData'
| 'checkingServerData.checkingStatus'
| 'checkingServerData.downloadingCredential'
| 'checkingServerData.verifyingDownloadLimitExpiry'
| 'checkingStore'
| 'checkingVc'
| 'checkingVerificationStatus'
| 'editingTag'
| 'idle'
| 'invalid'
| 'invalid.backend'
| 'invalid.otp'
| 'lockingVc'
| 'loggingRevoke'
| 'requestingBindingOtp'
| 'requestingLock'
| 'requestingOtp'
| 'requestingRevoke'
| 'revokingVc'
| 'showBindingStatus'
| 'showBindingWarning'
| 'showingWalletBindingError'
| 'storingTag'
| 'updatingPrivateKey'
| 'verifyingCredential'
| {
checkingServerData?:
| 'checkingStatus'
| 'downloadingCredential'
| 'verifyingDownloadLimitExpiry';
invalid?: 'backend' | 'otp';
};
'tags': never;
}

View File

@@ -75,14 +75,12 @@ export const QrConsent: React.FC<QrConsentProps> = (props) => {
if (claim == 'name' || claim == 'picture') {
return null;
} else {
let L = claim.length;
return (
<ListItem key={index} bottomDivider>
<ListItem.Content>
<ListItem.Title>
<Text color={Theme.Colors.profileLabel}>
{t(claim[0]).toUpperCase +
claim.split(claim[1], claim[L - 1]).toLowerCase}
{t(claim).toUpperCase()}
</Text>
</ListItem.Title>
</ListItem.Content>

View File

@@ -1,10 +1,23 @@
import { request } from '../request';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default async function getAllProperties() {
const COMMON_PROPS_KEY: string =
'CommonPropsKey-' + '6964d04a-9268-11ed-a1eb-0242ac120002';
export default async function getAllConfigurations() {
try {
const resp = await request('GET', '/allProperties');
return resp.response;
var response = await AsyncStorage.getItem(COMMON_PROPS_KEY);
if (response) {
return JSON.parse(response);
} else {
const resp = await request('GET', '/allProperties');
const injiProps = resp.response;
const injiPropsString = JSON.stringify(injiProps);
await AsyncStorage.setItem(COMMON_PROPS_KEY, injiPropsString);
return injiProps;
}
} catch (error) {
console.log(error);
throw error;
}
}

View File

@@ -1,30 +1,68 @@
import { KeyPair, RSA } from 'react-native-rsa-native';
import forge from 'node-forge';
import getAllConfigurations from '../commonprops/commonProps';
export function generateKeys(): Promise<KeyPair> {
return Promise.resolve(RSA.generateKeys(4096));
}
export async function getJwt(privateKey: string, payload: JSON) {
const key = forge.pki.privateKeyFromPem(privateKey);
const md = forge.md.sha256.create();
const header = {
alg: 'RS256',
typ: 'JWT',
};
const strHeader = JSON.stringify(header);
const strPayload = JSON.stringify(payload);
const header64 = encodeB64(strHeader);
const payload64 = encodeB64(strPayload);
const preHash = header64 + '.' + payload64;
md.update(preHash, 'utf8');
const signature = key.sign(md);
const signature64 = encodeB64(signature);
var token: string = header64 + '.' + payload64 + '.' + signature64;
return token;
export async function getJwt(
privateKey: string,
individualId: string,
keyId: string,
thumbprint: string
) {
var token: string = null;
try {
var iat = Math.floor(new Date().getTime() / 1000);
var exp = Math.floor(new Date().getTime() / 1000) + 18000;
var config = await getAllConfigurations();
const key = forge.pki.privateKeyFromPem(privateKey);
const md = forge.md.sha256.create();
const header = {
'alg': 'RS256',
'kid': keyId,
'x5t#S256': thumbprint,
};
var myJSON =
'{"iss": "' +
config.issuer +
'", "aud": "' +
config.audience +
'", "sub": "' +
individualId +
'", "iat": ' +
iat +
', "exp": ' +
exp +
'}';
var payload = JSON.parse(myJSON);
const strHeader = JSON.stringify(header);
const strPayload = JSON.stringify(payload);
const header64 = encodeB64(strHeader);
const payload64 = encodeB64(strPayload);
const preHash = header64 + '.' + payload64;
md.update(preHash, 'utf8');
const signature = key.sign(md);
const signature64 = encodeB64(signature);
var token: string = header64 + '.' + payload64 + '.' + signature64;
return token;
} catch (e) {
console.log(e);
throw e;
}
}
function encodeB64(str: string) {
const encodedB64 = forge.util.encode64(str);
return encodedB64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
export interface WalletBindingResponse {
walletBindingId: string;
keyId: string;
thumbprint: string;
expireDateTime: string;
}

View File

@@ -1,5 +1,7 @@
import RNSecureKeyStore, { ACCESSIBLE } from 'react-native-secure-key-store';
const bindingCertificate = '-bindingCertificate';
export async function savePrivateKey(id: string, privateKey: string) {
var result = await RNSecureKeyStore.set(id, privateKey, {
accessible: ACCESSIBLE.ALWAYS_THIS_DEVICE_ONLY,
@@ -11,3 +13,7 @@ export async function getPrivateKey(id: string) {
var result = await RNSecureKeyStore.get(id);
return result;
}
export function getBindingCertificateConstant(id: string) {
return id + bindingCertificate;
}

View File

@@ -1,3 +1,5 @@
import { WalletBindingResponse } from '../shared/cryptoutil/cryptoUtil';
export interface VC {
id: string;
idType: VcIdType;
@@ -12,7 +14,7 @@ export interface VC {
locked: boolean;
reason?: VCSharingReason[];
shouldVerifyPresence?: boolean;
walletBindingId?: string;
walletBindingResponse?: WalletBindingResponse;
}
export interface VCSharingReason {