mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 13:38:01 -05:00
* [INJIMOB-1192] : use wellknown response instead of mimoto issuer config. -- Remove hardcoding for sunbird issuer in vc activation and verification flow. -- Render idType from wellknown response -- Remove UIN/VID from default add-on fields Signed-off-by: Swati Goel <meet2swati@gmail.com> * [INJIMOB-1192] : fix propType and some refactoring Signed-off-by: Swati Goel <meet2swati@gmail.com> * [INJIMOB-1192] : add credentialType in VcMetadata Signed-off-by: Swati Goel <meet2swati@gmail.com> * [INJIMOB-1192] fix vc download via issuer flow due to credentialType mismatch Co-authored-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] rename supported list of credential type in issuers model Co-authored-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] display id type in history based on wellknown for issuers VC Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] fix id type not shown for VC activation Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] remove unused credentialType field from VCMetaData Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] set default idType for logging activity Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] move vc item machine events into model Events should not be exported to other packages for direct use so that Xstate's createModel() can decorate the function appropriately Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] show verify banner id type from wellknown Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] refactor duplication and unused code Co-authored-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] remove unused displayId in metadata Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] revert the dimensions of camera scanner to old values to support face liveness verification Co-authored-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> * [INJIMOB-1192] remove unused code & debug logs Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> * [INJIMOB-1192] fix failing test cases Co-authored-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> * [INJIMOB-1192] remove unused translations Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> --------- Signed-off-by: Swati Goel <meet2swati@gmail.com> Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Co-authored-by: Swati Goel <meet2swati@gmail.com> Co-authored-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>
223 lines
7.2 KiB
TypeScript
223 lines
7.2 KiB
TypeScript
import {NativeModules} from 'react-native';
|
|
import Cloud from '../../../shared/CloudBackupAndRestoreUtils';
|
|
import {VCMetadata} from '../../../shared/VCMetadata';
|
|
import getAllConfigurations, {
|
|
API_URLS,
|
|
CACHED_API,
|
|
DownloadProps,
|
|
} from '../../../shared/api';
|
|
import {
|
|
generateKeys,
|
|
isHardwareKeystoreExists,
|
|
} from '../../../shared/cryptoutil/cryptoUtil';
|
|
import {
|
|
getBindingCertificateConstant,
|
|
savePrivateKey,
|
|
} from '../../../shared/keystore/SecureKeystore';
|
|
import {CredentialDownloadResponse, request} from '../../../shared/request';
|
|
import {WalletBindingResponse} from '../VCMetaMachine/vc';
|
|
import {verifyCredential} from '../../../shared/vcjs/verifyCredential';
|
|
import {getVerifiableCredential} from './VCItemSelectors';
|
|
import {getSelectedCredentialTypeDetails} from '../../../shared/openId4VCI/Utils';
|
|
import {getCredentialTypes} from '../../../components/VC/common/VCUtils';
|
|
|
|
const {RNSecureKeystoreModule} = NativeModules;
|
|
export const VCItemServices = model => {
|
|
return {
|
|
isUserSignedAlready: () => async () => {
|
|
return await Cloud.isSignedInAlready();
|
|
},
|
|
|
|
updatePrivateKey: async context => {
|
|
const hasSetPrivateKey: boolean = await savePrivateKey(
|
|
context.walletBindingResponse.walletBindingId,
|
|
context.privateKey,
|
|
);
|
|
if (!hasSetPrivateKey) {
|
|
throw new Error('Could not store private key in keystore.');
|
|
}
|
|
return '';
|
|
},
|
|
loadDownloadLimitConfig: async context => {
|
|
var resp = await getAllConfigurations();
|
|
const maxLimit: number = resp.vcDownloadMaxRetry;
|
|
const vcDownloadPoolInterval: number = resp.vcDownloadPoolInterval;
|
|
|
|
const downloadProps: DownloadProps = {
|
|
maxDownloadLimit: maxLimit,
|
|
downloadInterval: vcDownloadPoolInterval,
|
|
};
|
|
return downloadProps;
|
|
},
|
|
|
|
checkDownloadExpiryLimit: async context => {
|
|
if (context.downloadCounter > context.maxDownloadCount) {
|
|
throw new Error(
|
|
'Download limit expired for request id: ' +
|
|
context.vcMetadata.requestId,
|
|
);
|
|
}
|
|
},
|
|
addWalletBindingId: async context => {
|
|
const response = await request(
|
|
API_URLS.walletBinding.method,
|
|
API_URLS.walletBinding.buildURL(),
|
|
{
|
|
requestTime: String(new Date().toISOString()),
|
|
request: {
|
|
authFactorType: 'WLA',
|
|
format: 'jwt',
|
|
individualId: VCMetadata.fromVC(context.vcMetadata).id,
|
|
transactionId: context.bindingTransactionId,
|
|
publicKey: context.publicKey,
|
|
challengeList: [
|
|
{
|
|
authFactorType: 'OTP',
|
|
challenge: context.OTP,
|
|
format: 'alpha-numeric',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
);
|
|
const certificate = response.response.certificate;
|
|
await savePrivateKey(
|
|
getBindingCertificateConstant(VCMetadata.fromVC(context.vcMetadata).id),
|
|
certificate,
|
|
);
|
|
|
|
const walletResponse: WalletBindingResponse = {
|
|
walletBindingId: response.response.encryptedWalletBindingId,
|
|
keyId: response.response.keyId,
|
|
thumbprint: response.response.thumbprint,
|
|
expireDateTime: response.response.expireDateTime,
|
|
};
|
|
return walletResponse;
|
|
},
|
|
|
|
generateKeyPair: async context => {
|
|
if (!isHardwareKeystoreExists) {
|
|
return await generateKeys();
|
|
}
|
|
const isBiometricsEnabled = RNSecureKeystoreModule.hasBiometricsEnabled();
|
|
return RNSecureKeystoreModule.generateKeyPair(
|
|
VCMetadata.fromVC(context.vcMetadata).id,
|
|
isBiometricsEnabled,
|
|
0,
|
|
);
|
|
},
|
|
requestBindingOTP: async context => {
|
|
const vc = getVerifiableCredential(context.verifiableCredential);
|
|
const response = await request(
|
|
API_URLS.bindingOtp.method,
|
|
API_URLS.bindingOtp.buildURL(),
|
|
{
|
|
requestTime: String(new Date().toISOString()),
|
|
request: {
|
|
individualId: VCMetadata.fromVC(context.vcMetadata).id,
|
|
otpChannels: ['EMAIL', 'PHONE'],
|
|
},
|
|
},
|
|
);
|
|
if (response.response == null) {
|
|
throw new Error('Could not process request');
|
|
}
|
|
return response;
|
|
},
|
|
fetchIssuerWellknown: async context => {
|
|
const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
|
|
context.vcMetadata.issuer,
|
|
context.verifiableCredential.wellKnown,
|
|
true,
|
|
);
|
|
const wellknownOfCredential = getSelectedCredentialTypeDetails(
|
|
wellknownResponse,
|
|
getCredentialTypes(context.verifiableCredential),
|
|
);
|
|
return wellknownOfCredential;
|
|
},
|
|
checkStatus: context => (callback, onReceive) => {
|
|
const pollInterval = setInterval(
|
|
() => callback(model.events.POLL()),
|
|
context.downloadInterval,
|
|
);
|
|
|
|
onReceive(async event => {
|
|
if (event.type === 'POLL_STATUS') {
|
|
try {
|
|
const response = await request(
|
|
API_URLS.credentialStatus.method,
|
|
API_URLS.credentialStatus.buildURL(context.vcMetadata.requestId),
|
|
);
|
|
switch (response.response?.statusCode) {
|
|
case 'NEW':
|
|
break;
|
|
case 'ISSUED':
|
|
case 'printing':
|
|
callback(model.events.DOWNLOAD_READY());
|
|
break;
|
|
case 'FAILED':
|
|
default:
|
|
callback(model.events.FAILED());
|
|
clearInterval(pollInterval);
|
|
break;
|
|
}
|
|
} catch (error) {
|
|
callback(model.events.FAILED());
|
|
clearInterval(pollInterval);
|
|
}
|
|
}
|
|
});
|
|
|
|
return () => clearInterval(pollInterval);
|
|
},
|
|
|
|
downloadCredential: context => (callback, onReceive) => {
|
|
const pollInterval = setInterval(
|
|
() => callback(model.events.POLL()),
|
|
context.downloadInterval,
|
|
);
|
|
|
|
onReceive(async event => {
|
|
if (event.type === 'POLL_DOWNLOAD') {
|
|
const response: CredentialDownloadResponse = await request(
|
|
API_URLS.credentialDownload.method,
|
|
API_URLS.credentialDownload.buildURL(),
|
|
{
|
|
individualId: context.vcMetadata.id,
|
|
requestId: context.vcMetadata.requestId,
|
|
},
|
|
);
|
|
|
|
callback(
|
|
model.events.CREDENTIAL_DOWNLOADED({
|
|
credential: response.credential,
|
|
verifiableCredential: response.verifiableCredential,
|
|
generatedOn: new Date(),
|
|
id: context.vcMetadata.id,
|
|
idType: context.vcMetadata.idType,
|
|
requestId: context.vcMetadata.requestId,
|
|
lastVerifiedOn: null,
|
|
walletBindingResponse: null,
|
|
credentialRegistry: '',
|
|
}),
|
|
);
|
|
}
|
|
});
|
|
|
|
return () => clearInterval(pollInterval);
|
|
},
|
|
|
|
verifyCredential: async context => {
|
|
if (context.verifiableCredential) {
|
|
const verificationResult = await verifyCredential(
|
|
getVerifiableCredential(context.verifiableCredential),
|
|
);
|
|
if (!verificationResult.isVerified) {
|
|
throw new Error(verificationResult.errorMessage);
|
|
}
|
|
}
|
|
},
|
|
};
|
|
};
|