[INJIMOB-3129] handle long client name consent (#1894)

* [INJIMOB-3129] fix display of long client names in OVP consent screen

To avoid, long client names making the consent screen occupy the entire screen, the client names are formatted for display. The logic of formatting involves trimming the value to 15 characters and appending ... with it

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3129] fix enabling of share with selfie button in OVP flow

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3129] optimize import and avoid usage of var

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3129] rename formatText function

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

---------

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
This commit is contained in:
KiruthikaJeyashankar
2025-04-22 11:43:27 +05:30
committed by GitHub
parent 6a6425f22d
commit ca937331ce
5 changed files with 67 additions and 47 deletions

View File

@@ -1,6 +1,6 @@
import {createModel} from 'xstate/lib/model';
import {AppServices} from '../../shared/GlobalContext';
import {SelectedCredentialsForVPSharing, VC} from '../VerifiableCredential/VCMetaMachine/vc';
import {VC} from '../VerifiableCredential/VCMetaMachine/vc';
import {KeyTypes} from '../../shared/cryptoutil/KeyTypes';
import {VPActivityLogType} from '../../components/VPShareActivityLogEvent';
@@ -50,7 +50,7 @@ export const openID4VPModel = createModel(
authenticationResponse: {},
vcsMatchingAuthRequest: {} as Record<string, VC[]>,
checkedAll: false as boolean,
selectedVCs: {} as SelectedCredentialsForVPSharing,
selectedVCs: {} as Record<string, VC[]>,
isShareWithSelfie: false as boolean,
showFaceAuthConsent: true as boolean,
purpose: '' as string,

View File

@@ -222,6 +222,7 @@ export const SendVPScreen: React.FC<ScanLayoutProps> = props => {
onPress={controller.ACCEPT_REQUEST}
/>
)}
{/*If one of the selected vc has image, it needs to sent only after biometric authentication (Share with Selfie)*/}
{controller.checkIfAnyVCHasImage(
controller.vcsMatchingAuthRequest,
) && (

View File

@@ -6,7 +6,10 @@ import {ActorRefFrom} from 'xstate';
import {Theme} from '../../components/ui/styleUtils';
import {selectIsCancelling} from '../../machines/bleShare/commonSelectors';
import {ScanEvents} from '../../machines/bleShare/scan/scanMachine';
import {selectFlowType, selectIsSendingVPError,} from '../../machines/bleShare/scan/scanSelectors';
import {
selectFlowType,
selectIsSendingVPError,
} from '../../machines/bleShare/scan/scanSelectors';
import {
selectAreAllVCsChecked,
selectCredentials,
@@ -35,12 +38,11 @@ import {selectShareableVcs} from '../../machines/VerifiableCredential/VCMetaMach
import {RootRouteProps} from '../../routes';
import {BOTTOM_TAB_ROUTES} from '../../routes/routesConstants';
import {GlobalContext} from '../../shared/GlobalContext';
import {isMosipVC} from '../../shared/Utils';
import {formatTextWithGivenLimit, isMosipVC} from '../../shared/Utils';
import {VCMetadata} from '../../shared/VCMetadata';
import {VPShareOverlayProps} from './VPShareOverlay';
import {ActivityLogEvents} from '../../machines/activityLog';
import {VPShareActivityLog} from '../../components/VPShareActivityLogEvent';
import {SelectedCredentialsForVPSharing} from "../../machines/VerifiableCredential/VCMetaMachine/vc";
type MyVcsTabNavigation = NavigationProp<RootRouteProps>;
@@ -82,37 +84,27 @@ export function useSendVPScreen() {
);
const checkIfAnyVCHasImage = vcs => {
const hasImage = Object.values(vcs)
return Object.values(vcs)
.flatMap(vc => vc)
.some(vc => {
return isMosipVC(vc.vcMetadata?.issuer);
});
return hasImage;
};
const checkIfAllVCsHasImage = vcs => {
const hasImage = Object.values(vcs)
return Object.values(vcs)
.flatMap(vc => vc)
.every(vc => isMosipVC(vc.vcMetadata.issuer));
return hasImage;
};
const getSelectedVCs = () => {
const selectedVcsData: SelectedCredentialsForVPSharing = {};
Object.entries(selectedVCKeys).map(([vcKey, inputDescriptorId]) => {
const getSelectedVCs = (): Record<string, any[]> => {
let selectedVcsData: Record<string, any[]> = {};
Object.entries(selectedVCKeys).forEach(([vcKey, inputDescriptorId]) => {
const vcData = myVcs[vcKey];
const credentialFormat = vcData.format;
if (selectedVcsData.hasOwnProperty(inputDescriptorId)) {
let matchingVcsOfInputDescriptor = selectedVcsData[inputDescriptorId]
if (matchingVcsOfInputDescriptor.hasOwnProperty(credentialFormat)) {
matchingVcsOfInputDescriptor[credentialFormat] = [...matchingVcsOfInputDescriptor[credentialFormat], vcData]
} else {
matchingVcsOfInputDescriptor[credentialFormat] = [vcData]
}
selectedVcsData[inputDescriptorId] = matchingVcsOfInputDescriptor
} else {
selectedVcsData[inputDescriptorId] = {[credentialFormat]: [vcData]}
if (!selectedVcsData[inputDescriptorId]) {
selectedVcsData[inputDescriptorId] = [];
}
selectedVcsData[inputDescriptorId].push(vcData);
});
return selectedVcsData;
};
@@ -225,7 +217,7 @@ export function useSendVPScreen() {
title: t('consentDialog.title'),
titleTestID: 'consentTitle',
message: t('consentDialog.message', {
verifierName: vpVerifierName,
verifierName: formatTextWithGivenLimit(vpVerifierName),
interpolation: {escapeValue: false},
}),
messageTestID: 'consentMsg',
@@ -300,8 +292,8 @@ export function useSendVPScreen() {
SELECT_VC_ITEM:
(vcKey: string, inputDescriptorId: string) =>
(vcRef: ActorRefFrom<typeof VCItemMachine>) => {
var selectedVcs = {...selectedVCKeys};
var isVCSelected = !!!selectedVcs[vcKey];
let selectedVcs = {...selectedVCKeys};
const isVCSelected = !!!selectedVcs[vcKey];
if (isVCSelected) {
selectedVcs[vcKey] = inputDescriptorId;
} else {
@@ -317,7 +309,7 @@ export function useSendVPScreen() {
},
CHECK_ALL: () => {
var updatedVCsList = {};
let updatedVCsList = {};
Object.entries(vcsMatchingAuthRequest).map(([inputDescriptorId, vcs]) => {
vcs.map(vcData => {
const vcKey = VCMetadata.fromVcMetadataString(

View File

@@ -66,3 +66,10 @@ export class UUID {
return uuid();
}
}
export const formatTextWithGivenLimit = (value: string, limit: number = 15) => {
if (value.length > limit) {
return value.substring(0, limit) + '...';
}
return value;
};

View File

@@ -1,6 +1,9 @@
import {NativeModules} from 'react-native';
import {__AppId} from '../GlobalVariables';
import {SelectedCredentialsForVPSharing} from '../../machines/VerifiableCredential/VCMetaMachine/vc';
import {
SelectedCredentialsForVPSharing,
VC,
} from '../../machines/VerifiableCredential/VCMetaMachine/vc';
import {getJWT} from '../cryptoutil/cryptoUtil';
import {getJWK} from '../openId4VCI/Utils';
import getAllConfigurations from '../api';
@@ -24,7 +27,7 @@ export class OpenID4VP {
trustedVerifiersList: any,
) {
const shouldValidateClient = await isClientValidationRequired();
const metadata = await getWalletMetadata() || walletMetadata;
const metadata = (await getWalletMetadata()) || walletMetadata;
const authenticationResponse =
await OpenID4VP.InjiOpenID4VP.authenticateVerifier(
@@ -36,25 +39,10 @@ export class OpenID4VP {
return JSON.parse(authenticationResponse);
}
private static stringifyValues = (
data: Record<string, Record<string, Array<any>>>,
): Record<string, Record<string, string[]>> => {
return Object.fromEntries(
Object.entries(data).map(([key, innerMap]) => [
key,
Object.fromEntries(
Object.entries(innerMap).map(([innerKey, arr]) => [
innerKey,
arr.map(item => JSON.stringify(item)),
]),
),
]),
static async constructUnsignedVPToken(selectedVCs: Record<string, VC[]>) {
let updatedSelectedVCs = this.stringifyValues(
this.processSelectedVCs(selectedVCs),
);
};
static async constructUnsignedVPToken(
selectedVCs: SelectedCredentialsForVPSharing,
) {
let updatedSelectedVCs = this.stringifyValues(selectedVCs);
const vpTokens = await OpenID4VP.InjiOpenID4VP.constructUnsignedVPToken(
updatedSelectedVCs,
@@ -73,6 +61,38 @@ export class OpenID4VP {
static sendErrorToVerifier(error: string) {
OpenID4VP.InjiOpenID4VP.sendErrorToVerifier(error);
}
private static stringifyValues = (
data: Record<string, Record<string, Array<any>>>,
): Record<string, Record<string, string[]>> => {
return Object.fromEntries(
Object.entries(data).map(([key, innerMap]) => [
key,
Object.fromEntries(
Object.entries(innerMap).map(([innerKey, arr]) => [
innerKey,
arr.map(item => JSON.stringify(item)),
]),
),
]),
);
};
private static processSelectedVCs(selectedVCs: Record<string, VC[]>) {
const selectedVcsData: SelectedCredentialsForVPSharing = {};
Object.entries(selectedVCs).forEach(([inputDescriptorId, vcsArray]) => {
vcsArray.forEach(vcData => {
const credentialFormat = vcData.vcMetadata.format;
if (!selectedVcsData[inputDescriptorId]) {
selectedVcsData[inputDescriptorId] = {};
}
if (!selectedVcsData[inputDescriptorId][credentialFormat]) {
selectedVcsData[inputDescriptorId][credentialFormat] = [];
}
selectedVcsData[inputDescriptorId][credentialFormat].push(vcData);
});
});
return selectedVcsData;
}
}
export async function constructProofJWT(