Skip to content

Commit

Permalink
Merge pull request #190 from Sphereon-Opensource/feature/SPRIND-4
Browse files Browse the repository at this point in the history
feature/SPRIND-4
  • Loading branch information
nklomp authored Aug 5, 2024
2 parents 736e487 + 2aede93 commit fafd1a1
Show file tree
Hide file tree
Showing 23 changed files with 1,688 additions and 883 deletions.
65 changes: 35 additions & 30 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,34 @@
"@reduxjs/toolkit": "^1.9.7",
"@scure/base": "^1.1.7",
"@sphereon/did-auth-siop": "0.6.4",
"@sphereon/did-provider-oyd": "0.24.0",
"@sphereon/did-provider-oyd": "0.24.1-next.3",
"@sphereon/isomorphic-webcrypto": "2.5.0-unstable.0",
"@sphereon/oid4vci-client": "0.15.1-next.9",
"@sphereon/oid4vci-common": "0.15.1-next.9",
"@sphereon/pex": "4.0.1",
"@sphereon/pex-models": "^2.2.4",
"@sphereon/ssi-sdk-ext.did-provider-jwk": "0.24.0",
"@sphereon/ssi-sdk-ext.did-provider-key": "0.24.0",
"@sphereon/ssi-sdk-ext.did-resolver-ebsi": "0.24.0",
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.24.0",
"@sphereon/ssi-sdk-ext.did-resolver-key": "0.24.0",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.0",
"@sphereon/ssi-sdk-ext.key-manager": "0.24.0",
"@sphereon/ssi-sdk-ext.key-utils": "0.24.0",
"@sphereon/ssi-sdk-ext.kms-local": "0.24.0",
"@sphereon/ssi-sdk.agent-config": "0.29.0",
"@sphereon/ssi-sdk.contact-manager": "0.29.0",
"@sphereon/ssi-sdk.core": "0.29.0",
"@sphereon/ssi-sdk.credential-store": "0.29.0",
"@sphereon/ssi-sdk.data-store": "0.29.0",
"@sphereon/ssi-sdk.event-logger": "0.29.0",
"@sphereon/ssi-sdk.issuance-branding": "0.29.0",
"@sphereon/ssi-sdk.oid4vci-holder": "0.29.0",
"@sphereon/ssi-sdk.sd-jwt": "0.29.0",
"@sphereon/ssi-sdk.siopv2-oid4vp-op-auth": "0.29.0",
"@sphereon/ssi-sdk.vc-handler-ld-local": "0.29.0",
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.29.0",
"@sphereon/ssi-types": "0.29.0",
"@sphereon/ssi-sdk-ext.did-provider-jwk": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.did-provider-key": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.did-resolver-ebsi": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.did-resolver-key": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.key-manager": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.key-utils": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.kms-local": "0.24.1-next.3",
"@sphereon/ssi-sdk.agent-config": "0.29.1-next.46",
"@sphereon/ssi-sdk.contact-manager": "0.29.1-next.46",
"@sphereon/ssi-sdk.core": "0.29.1-next.46",
"@sphereon/ssi-sdk.credential-store": "0.29.1-next.46",
"@sphereon/ssi-sdk.data-store": "0.29.1-next.46",
"@sphereon/ssi-sdk.event-logger": "0.29.1-next.46",
"@sphereon/ssi-sdk.issuance-branding": "0.29.1-next.46",
"@sphereon/ssi-sdk.oid4vci-holder": "0.29.1-next.46",
"@sphereon/ssi-sdk.sd-jwt": "0.29.1-next.46",
"@sphereon/ssi-sdk.siopv2-oid4vp-op-auth": "0.29.1-next.46",
"@sphereon/ssi-sdk.vc-handler-ld-local": "0.29.1-next.46",
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.29.1-next.46",
"@sphereon/ssi-types": "0.29.1-next.46",
"@sphereon/ui-components.core": "^0.3.0",
"@sphereon/ui-components.credential-branding": "^0.3.0",
"@sphereon/ui-components.ssi-react-native": "^0.3.0",
Expand Down Expand Up @@ -157,7 +157,8 @@
"uint8arrays": "^3.1.1",
"vm-browserify": "^1.1.2",
"web-did-resolver": "^2.0.23",
"xstate": "^4.38.3"
"xstate": "^4.38.3",
"@sd-jwt/sd-jwt-vc": "^0.6.1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down Expand Up @@ -208,7 +209,8 @@
"ts-node": "^10.9.1",
"typescript": "~5.3.3",
"webpack": "^5.76.1",
"xmlhttprequest": "^1.8.0"
"xmlhttprequest": "^1.8.0",
"@sd-jwt/types": "^0.6.1"
},
"react-native": {
"_stream_transform": "readable-stream/transform",
Expand Down Expand Up @@ -245,17 +247,20 @@
"@expo/prebuild-config": "~7.0.0",
"ajv": "^8.12.0",
"@sphereon/did-auth-siop": "0.6.4",
"@sphereon/ssi-sdk-ext.key-utils": "0.24.0",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.0",
"@sphereon/ssi-types": "0.29.0",
"@sphereon/ssi-sdk.core": "0.29.0",
"@sphereon/ssi-sdk.data-store": "0.29.0",
"@sphereon/ssi-sdk-ext.key-utils": "0.24.1-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-next.3",
"@sphereon/ssi-types": "0.29.1-next.46",
"@sphereon/ssi-sdk.core": "0.29.1-next.46",
"@sphereon/ssi-sdk.data-store": "0.29.1-next.46",
"@sphereon/oid4vci-client": "0.15.1-next.9",
"@sphereon/oid4vci-common": "0.15.1-next.9",
"@sphereon/ui-components.core": "^0.3.0",
"@sphereon/ui-components.ssi-react-native": "^0.3.0",
"@sphereon/ui-components.credential-branding": "^0.3.0",
"@sphereon/pex": "4.0.1",
"@sphereon/ssi-sdk-ext.kms-local": "0.23.1-next.5",
"@sphereon/ssi-sdk-ext.key-manager": "0.23.1-next.5",
"@sphereon/ssi-sdk.contact-manager": "0.28.1-unstable.43",
"@sphereon/pex-models": "2.2.4",
"@mattrglobal/bbs-signatures": "npm:empty-npm-package",
"@veramo/core": "4.2.0",
Expand Down
1 change: 0 additions & 1 deletion src/agent/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {getDidOydResolver, OydDIDProvider} from '@sphereon/did-provider-oyd';
import {getUniResolver} from '@sphereon/did-uni-client';
import {JwkDIDProvider} from '@sphereon/ssi-sdk-ext.did-provider-jwk';
import {getDidKeyResolver, SphereonKeyDidProvider} from '@sphereon/ssi-sdk-ext.did-provider-key';
import {getResolver as getDidEbsiResolver} from '@sphereon/ssi-sdk-ext.did-resolver-ebsi';
Expand Down
1 change: 1 addition & 0 deletions src/agent/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const oid4vciHolder = new OID4VCIHolder({
const {identifier} = args;
await dispatchIdentifier({identifier});
},
hasher: generateDigest,
});

export const createAgentPlugins = ({
Expand Down
24 changes: 19 additions & 5 deletions src/components/views/SSIConnectionDetailsView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Identity, MetadataItem} from '@sphereon/ssi-sdk.data-store';
import {Identity, MetadataItem, MetadataTypes} from '@sphereon/ssi-sdk.data-store';
import React, {FC} from 'react';
import {ListRenderItemInfo} from 'react-native';

import {toLocalDateString} from '../../../utils';
import {DETAILS_INITIAL_NUMBER_TO_RENDER} from '../../../@config/constants';
import {translate} from '../../../localization/Localization';
import {
Expand All @@ -20,10 +20,24 @@ export interface IProps {
}

const SSIConnectionDetailsView: FC<IProps> = (props: IProps): JSX.Element => {
// TODO rename to identity?
const {identity} = props;

const renderItem = (itemInfo: ListRenderItemInfo<MetadataItem<any>>) => {
const parseValue = (value: MetadataTypes): string => {
// FIXME we need to check the MetadataTypes, it holds undefined but the value field of MetadataItem cannot be undefined.
// And we need to check if the database can have the value null
// Besides that we might want rename the type to MetadataType
if (!value) {
return '';
}

if (value instanceof Date) {
return toLocalDateString(value.getTime());
}

return value.toString();
};

const renderItem = (itemInfo: ListRenderItemInfo<MetadataItem<MetadataTypes>>) => {
return (
<LabelRow>
<Column>
Expand Down Expand Up @@ -51,7 +65,7 @@ const SSIConnectionDetailsView: FC<IProps> = (props: IProps): JSX.Element => {
// TODO has a ItemSeparatorComponent which is a bit nicer to use then the logic now with margins
data={identity.metadata}
renderItem={renderItem}
keyExtractor={(item: MetadataItem<any>) => item.id}
keyExtractor={(item: MetadataItem<MetadataTypes>) => item.id}
initialNumToRender={DETAILS_INITIAL_NUMBER_TO_RENDER}
removeClippedSubviews
/>
Expand Down
2 changes: 1 addition & 1 deletion src/navigation/machines/oid4vciStateNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ const navigateReviewCredentials = async (args: OID4VCIMachineNavigationArgs): Pr
headerTitle: translate(signingMode ? 'credential_sign_title' : 'credential_offer_title'),
rawCredential: credentialsToAccept[0].rawVerifiableCredential,
credential: await toNonPersistedCredentialSummary({
verifiableCredential: credentialsToAccept[0].uniformVerifiableCredential!,
verifiableCredential: credentialsToAccept[0].uniformVerifiableCredential,
credentialRole: CredentialRole.HOLDER,
branding: localeBranding,
issuer: contact,
Expand Down
2 changes: 1 addition & 1 deletion src/navigation/machines/siopV2StateNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ const navigateSelectCredentials = async (args: SiopV2MachineNavigationArgs): Pro
if (authorizationRequestData.presentationDefinitions.length > 1) {
return Promise.reject(Error('Multiple presentation definitions present'));
}
const presentationDefinitionWithLocation: PresentationDefinitionWithLocation = authorizationRequestData.presentationDefinitions![0];
const presentationDefinitionWithLocation: PresentationDefinitionWithLocation = authorizationRequestData.presentationDefinitions[0];
const format: Format | undefined = authorizationRequestData.registrationMetadataPayload?.registration?.vp_formats;
const subjectSyntaxTypesSupported: Array<string> | undefined =
authorizationRequestData.registrationMetadataPayload?.registration?.subject_syntax_types_supported;
Expand Down
20 changes: 10 additions & 10 deletions src/navigation/navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ import OpenBrowserScreen from '../screens/OpenBrowserScreen';
import SSIContactAddScreen from '../screens/SSIContactAddScreen';
import SSIContactDetailsScreen from '../screens/SSIContactDetailsScreen';
import SSIContactsOverviewScreen from '../screens/SSIContactsOverviewScreen';
import SSICredentialDetailsScreen from '../screens/SSICredentialDetailsScreen';
import CredentialDetailsScreen from '../screens/CredentialDetailsScreen';
import SSICredentialRawJsonScreen from '../screens/SSICredentialRawJsonScreen';
import SSICredentialsSelectScreen from '../screens/SSICredentialSelectScreen';
import SSICredentialSelectTypeScreen from '../screens/SSICredentialSelectTypeScreen';
import SSICredentialsOverviewScreen from '../screens/SSICredentialsOverviewScreen';
import SSICredentialsRequiredScreen from '../screens/SSICredentialsRequiredScreen';
import CredentialsOverviewScreen from '../screens/CredentialsOverviewScreen';
import CredentialsRequiredScreen from '../screens/CredentialsRequiredScreen';
import SSIErrorScreen from '../screens/SSIErrorScreen';
import SSILoadingScreen from '../screens/SSILoadingScreen';
import SSILockScreen from '../screens/SSILockScreen';
Expand Down Expand Up @@ -176,15 +176,15 @@ const CredentialsStack = (): JSX.Element => {
}}>
<Stack.Screen
name={ScreenRoutesEnum.CREDENTIALS_OVERVIEW}
component={SSICredentialsOverviewScreen}
component={CredentialsOverviewScreen}
options={{
headerTitle: translate('credentials_overview_title'),
header: (props: NativeStackHeaderProps) => <SSIHeaderBar {...props} showBorder showBackButton={false} />,
}}
/>
<Stack.Screen
name={ScreenRoutesEnum.CREDENTIAL_DETAILS}
component={SSICredentialDetailsScreen}
component={CredentialDetailsScreen}
options={({route}) => ({
headerTitle: translate('credential_details_title'),
header: (props: NativeStackHeaderProps) => (
Expand Down Expand Up @@ -304,7 +304,7 @@ const QRStack = (): JSX.Element => {
/>
<Stack.Screen
name={ScreenRoutesEnum.CREDENTIAL_DETAILS}
component={SSICredentialDetailsScreen}
component={CredentialDetailsScreen}
options={({route}) => ({
headerTitle: route.params.headerTitle ? route.params.headerTitle : translate('credential_details_title'),
header: (props: NativeStackHeaderProps) => (
Expand Down Expand Up @@ -359,7 +359,7 @@ const QRStack = (): JSX.Element => {
/>
<Stack.Screen
name={ScreenRoutesEnum.CREDENTIALS_REQUIRED}
component={SSICredentialsRequiredScreen}
component={CredentialsRequiredScreen}
options={({route}) => ({
headerTitle: translate('credentials_required_title'),
header: (props: NativeStackHeaderProps) => (
Expand Down Expand Up @@ -705,7 +705,7 @@ export const OID4VCIStack = (): JSX.Element => {
/>
<Stack.Screen
name={ScreenRoutesEnum.CREDENTIAL_DETAILS}
component={SSICredentialDetailsScreen}
component={CredentialDetailsScreen}
options={({route}) => ({
headerTitle: route.params.headerTitle ? route.params.headerTitle : translate('credential_details_title'),
header: (props: NativeStackHeaderProps) => (
Expand Down Expand Up @@ -789,7 +789,7 @@ export const SiopV2Stack = (): JSX.Element => {
/>
<Stack.Screen
name={ScreenRoutesEnum.CREDENTIALS_REQUIRED}
component={SSICredentialsRequiredScreen}
component={CredentialsRequiredScreen}
options={({route}) => ({
headerTitle: translate('credentials_required_title'),
header: (props: NativeStackHeaderProps) => (
Expand Down Expand Up @@ -836,7 +836,7 @@ export const SiopV2Stack = (): JSX.Element => {
/>
<Stack.Screen
name={ScreenRoutesEnum.CREDENTIAL_DETAILS}
component={SSICredentialDetailsScreen}
component={CredentialDetailsScreen}
options={({route}) => ({
headerTitle: route.params.headerTitle ? route.params.headerTitle : translate('credential_details_title'),
header: (props: NativeStackHeaderProps) => (
Expand Down
16 changes: 13 additions & 3 deletions src/providers/authentication/SIOPv2Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {APP_ID} from '../../@config/constants';
import agent, {agentContext, didMethodsSupported, didResolver} from '../../agent';
import {getOrCreatePrimaryIdentifier} from '../../services/identityService';
import {SupportedDidMethodEnum} from '../../types';
import {generateDigest} from '../../utils';
import {encodeJoseBlob} from '@veramo/utils';

const debug: Debugger = Debug(`${APP_ID}:authentication`);

Expand Down Expand Up @@ -91,7 +93,7 @@ export const siopSendAuthorizationResponse = async (
let identifier: IIdentifier = identifiers[0];
let presentationSubmission: PresentationSubmission | undefined;
if (await session.hasPresentationDefinitions()) {
const oid4vp: OID4VP = await session.getOID4VP();
const oid4vp: OID4VP = await session.getOID4VP({hasher: generateDigest});

const credentialsAndDefinitions = args.verifiableCredentialsWithDefinition
? args.verifiableCredentialsWithDefinition
Expand All @@ -104,8 +106,16 @@ export const siopSendAuthorizationResponse = async (
: 'https://self-issued.me/v2');
debug(`NONCE: ${session.nonce}, domain: ${domain}`);

const firstVC = CredentialMapper.toUniformCredential(credentialsAndDefinitions[0].credentials[0]);
const holder = Array.isArray(firstVC.credentialSubject) ? firstVC.credentialSubject[0].id : firstVC.credentialSubject.id;
const firstVC = CredentialMapper.toUniformCredential(credentialsAndDefinitions[0].credentials[0], {hasher: generateDigest});
const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
? firstVC.decodedPayload.cnf?.jwk
? //TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
//doesn't apply to did:jwk only, as you can represent any DID key as a JWK. So whenever you encounter a JWK it doesn't mean it had to come from a did:jwk in the system. It just can always be represented as a did:jwk
`did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
: firstVC.decodedPayload.sub
: Array.isArray(firstVC.credentialSubject)
? firstVC.credentialSubject[0].id
: firstVC.credentialSubject.id;
if (holder) {
try {
identifier = await session.context.agent.didManagerGet({did: holder});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import SSITabView from '../../components/views/SSITabView';
import {CredentialSummary, getCredentialStatus, getIssuerLogo} from '@sphereon/ui-components.credential-branding';
import {translate} from '../../localization/Localization';
import {
SSICredentialDetailsScreenButtonContainer as ButtonContainer,
SSICredentialDetailsScreenButtonContentContainer as ButtonContainerContent,
SSICredentialDetailsScreenCredentialCardContainer as CardContainer,
CredentialDetailsScreenButtonContainer as ButtonContainer,
CredentialDetailsScreenButtonContentContainer as ButtonContainerContent,
CredentialDetailsScreenCredentialCardContainer as CardContainer,
SSIBasicHorizontalCenterContainerStyled as Container,
SSICredentialDetailsScreenContentContainer as ContentContainer,
CredentialDetailsScreenContentContainer as ContentContainer,
SSIStatusBarDarkModeStyled as StatusBar,
} from '../../styles/components';
import {ITabViewRoute, ScreenRoutesEnum, StackParamList} from '../../types';
Expand All @@ -36,7 +36,7 @@ const getCredentialCardLogo = (credential: CredentialSummary): ImageAttributes |
}
};

const SSICredentialDetailsScreen: FC<Props> = (props: Props): JSX.Element => {
const CredentialDetailsScreen: FC<Props> = (props: Props): JSX.Element => {
const {navigation} = props;
const {credential, primaryAction, secondaryAction, showActivity = false, onBack} = props.route.params;
const issuer: string = credential.issuer.alias;
Expand Down Expand Up @@ -133,4 +133,4 @@ const SSICredentialDetailsScreen: FC<Props> = (props: Props): JSX.Element => {
);
};

export default SSICredentialDetailsScreen;
export default CredentialDetailsScreen;
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ interface IState {
refreshing: boolean;
}

class SSICredentialsOverviewScreen extends PureComponent<IProps, IState> {
class CredentialsOverviewScreen extends PureComponent<IProps, IState> {
state: IState = {
refreshing: false,
};
Expand Down Expand Up @@ -158,4 +158,4 @@ const mapStateToProps = (state: RootState) => {
};
};

export default connect(mapStateToProps, mapDispatchToProps)(SSICredentialsOverviewScreen);
export default connect(mapStateToProps, mapDispatchToProps)(CredentialsOverviewScreen);
Loading

0 comments on commit fafd1a1

Please sign in to comment.