Skip to content

Commit

Permalink
enable presentation request
Browse files Browse the repository at this point in the history
  • Loading branch information
eike-hass committed May 13, 2024
1 parent 1872480 commit 8052c8d
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 67 deletions.
7 changes: 5 additions & 2 deletions backend/src/oid4vc/oid4vp.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/* eslint-disable */
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
import { wrappers } from "protobufjs";
import { Observable } from "rxjs";
import { Any } from "../google/protobuf/any";
import { Struct } from "../google/protobuf/struct";

export const protobufPackage = "oid4vc";

export interface OID4VPRequestConfig {
presentationDefinition: Any | undefined;
presentationDefinition: { [key: string]: any } | undefined;
nonce?: string | undefined;
state?: string | undefined;
}
Expand All @@ -18,6 +19,8 @@ export interface OID4VPRequest {

export const OID4VC_PACKAGE_NAME = "oid4vc";

wrappers[".google.protobuf.Struct"] = { fromObject: Struct.wrap, toObject: Struct.unwrap } as any;

export interface OID4VPClient {
createRequest(request: OID4VPRequestConfig): Observable<OID4VPRequest>;
}
Expand Down
90 changes: 43 additions & 47 deletions backend/src/webapp/webapp.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,6 @@ export class WebAppGateway {
});

this.logger.debug(`send SIOPV2 invite for session_id:${session_id}`);

// //TODO remove once OID4VCI component can call back
// setTimeout(() => {
// this.connectDid(session_id, 'did:web:example.com', payload.scope);
// }, 10000);
}

@SubscribeMessage('requestPresentation')
Expand All @@ -104,7 +99,8 @@ export class WebAppGateway {
)[0];

this.logger.debug(
`receiving presentation request for session_id:${session_id}, provider:${payload.provider} and scope:${payload.scope}`,
`receiving presentation request for session_id:${session_id}, provider:${payload.provider}, scope:${payload.scope} and presentationDefinition`,
payload.presentationDefinition,
);

const url = await this.webAppService.requestPresentation(
Expand All @@ -119,47 +115,47 @@ export class WebAppGateway {

this.logger.debug(`send presentation offer for session_id:${session_id}`);

//TODO remove once OID4VCI component can call back
setTimeout(() => {
this.presentation(
session_id,
{
vc: {
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://www.w3.org/2018/credentials/examples/v1',
],
id: 'http://example.edu/credentials/3732',
type: ['VerifiableCredential', 'UniversityDegreeCredential'],
issuer: 'https://example.edu/issuers/14',
issuanceDate: '2010-01-01T19:23:24Z',
credentialSubject: {
id: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
degree: {
type: 'BachelorDegree',
name: 'Bachelor of Science and Arts',
},
firstName: 'Ben',
lastName: 'Utzer',
date: Date.now(),
nationality: 'german',
birthplace: 'Musterstadt',
country: 'Germany',
phone: '00-0000',
},
credentialSchema: {
id: 'https://example.org/examples/degree.json',
type: 'JsonSchemaValidator2018',
},
},
iss: 'https://example.edu/issuers/14',
nbf: 1262373804,
jti: 'http://example.edu/credentials/3732',
sub: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
},
payload.scope,
);
}, 10000);
// //TODO remove once OID4VCI component can call back
// setTimeout(() => {
// this.presentation(
// session_id,
// {
// vc: {
// '@context': [
// 'https://www.w3.org/2018/credentials/v1',
// 'https://www.w3.org/2018/credentials/examples/v1',
// ],
// id: 'http://example.edu/credentials/3732',
// type: ['VerifiableCredential', 'UniversityDegreeCredential'],
// issuer: 'https://example.edu/issuers/14',
// issuanceDate: '2010-01-01T19:23:24Z',
// credentialSubject: {
// id: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
// degree: {
// type: 'BachelorDegree',
// name: 'Bachelor of Science and Arts',
// },
// firstName: 'Ben',
// lastName: 'Utzer',
// date: Date.now(),
// nationality: 'german',
// birthplace: 'Musterstadt',
// country: 'Germany',
// phone: '00-0000',
// },
// credentialSchema: {
// id: 'https://example.org/examples/degree.json',
// type: 'JsonSchemaValidator2018',
// },
// },
// iss: 'https://example.edu/issuers/14',
// nbf: 1262373804,
// jti: 'http://example.edu/credentials/3732',
// sub: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
// },
// payload.scope,
// );
// }, 10000);
}

@SubscribeMessage('requestIssuance')
Expand Down
14 changes: 9 additions & 5 deletions backend/src/webapp/webapp.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { PresentationDefinitionV2 } from '../../../types/PresentationExchange';
import { IdentityService } from 'src/identity/identity.service';
import type { Issuers } from '../../../types/Issuers';
import { Scopes } from '../../../types/Scopes';
import { SIOPV2Service } from 'src/oid4vc/oid4vc.service';
import { OID4VPService, SIOPV2Service } from 'src/oid4vc/oid4vc.service';
import { User } from 'src/user/user';

@Injectable()
export class WebAppService {
constructor(
@Inject(CACHE_MANAGER) private readonly cache: RedisCache,
private readonly siopV2Service: SIOPV2Service,
private readonly oid4vpService: OID4VPService,
@Inject(forwardRef(() => WebAppGateway))
private webAppGateway: WebAppGateway,
@Inject(IdentityService)
Expand Down Expand Up @@ -47,11 +48,14 @@ export class WebAppService {
presentationDefinition,
);

//const token = await this.requestTokenForSessionId(session_id);
//TODO replace with call against OID4VCI component using either a token or session_id
const url = 'example.com';
const token = await this.requestTokenForSessionId(session_id);

return url;
const siopResponse = await this.oid4vpService.createOID4VPRequest({
state: token,
presentationDefinition: presentationDefinition,
});

return siopResponse.uri;
}

async requestIssuance(
Expand Down
13 changes: 12 additions & 1 deletion oid4vc/TangleLabs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion oid4vc/TangleLabs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"express": "^4.18.2",
"express-async-handler": "^1.2.0",
"key-did-resolver": "^4.0.0",
"memory-cache-node": "^1.4.0"
"memory-cache-node": "^1.4.0",
"pb-util": "^1.0.3"
},
"devDependencies": {
"ts-node": "^10.9.2"
Expand Down
7 changes: 5 additions & 2 deletions oid4vc/TangleLabs/src/grpcService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { loadSync } from "@grpc/proto-loader";
import { RelyingParty, SiopRequestResult, VcIssuer } from "@tanglelabs/oid4vc";
import { PresentationDefinitionV2 } from "@sphereon/pex-models";
import { Cache } from "./cache";
import {struct, Struct} from 'pb-util';

const crypto = await import('node:crypto');

Expand Down Expand Up @@ -51,14 +52,16 @@ export const createService = async (

async function createOID4VPRequest(
call: grpc.ServerUnaryCall<
{ presentationDefinition: any; state: any; nonce: string },
{ presentationDefinition: Struct; state: string; nonce: string },
any
>,
callback: grpc.sendUnaryData<SiopRequestResult>
): Promise<void> {
const requestId = crypto.randomUUID();

console.debug(struct.decode(call.request.presentationDefinition));
const request = await rp.createRequest({
presentationDefinition: call.request.presentationDefinition,
presentationDefinition: struct.decode(call.request.presentationDefinition) as unknown as PresentationDefinitionV2,
requestBy: "reference",
requestUri: encodeURIComponent(`${process.env.PUBLIC_URL}/api/offer/${requestId}`),
responseType: "vp_token",
Expand Down
4 changes: 2 additions & 2 deletions proto/oid4vc/oid4vp.proto
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
syntax = "proto3";
package oid4vc;

import "google/protobuf/any.proto";
import "google/protobuf/struct.proto";

service OID4VP {
rpc CreateRequest (OID4VPRequestConfig) returns (OID4VPRequest) {}
}

message OID4VPRequestConfig {
google.protobuf.Any presentationDefinition = 1;
google.protobuf.Struct presentationDefinition = 1;
optional string nonce = 2;
optional string state = 3;
}
Expand Down
9 changes: 5 additions & 4 deletions web/src/context/globalState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ interface RequestInviteAction extends ReducerBaseAction {
interface RequestPresentationAction extends ReducerBaseAction {
type: Actions.REQUEST_PRESENTATION,
provider: Providers,
presentationDefinition: any,
}

interface RequestIssuanceAction extends ReducerBaseAction {
Expand Down Expand Up @@ -88,9 +89,9 @@ const requestSIOPInvite: RequestSIOPInvite = (provider, scope) => {
}

// OIDC4VP
type RequestPresentation = (provider: Providers, scope: Scopes) => void
const requestPresentation: RequestPresentation = (provider, scope) => {
socket.emit('requestPresentation', {provider, scope});
type RequestPresentation = (provider: Providers, scope: Scopes, presentationDefinition: any) => void
const requestPresentation: RequestPresentation = (provider, scope, presentationDefinition) => {
socket.emit('requestPresentation', {provider, scope, presentationDefinition});
}

// OIDC4VCI
Expand Down Expand Up @@ -215,7 +216,7 @@ export function GlobalStateProvider({ children }: any) {
}

case Actions.REQUEST_PRESENTATION: {
requestPresentation(action.provider, action.scope);
requestPresentation(action.provider, action.scope, action.presentationDefinition);
return state;
}

Expand Down
29 changes: 26 additions & 3 deletions web/src/pages/Company/ProvideData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,42 @@ const ProvideData: React.FC = () => {
navigate(nextStep);
}, [nextStep, navigate]);

useEffect(() => {
useEffect(() => {

dispatch?.({
type: Actions.REQUEST_PRESENTATION,
provider: Providers.WaltId,
presentationDefinition: {
id: '32f54163-7166-48f1-93d8-ff217bdb0653',
input_descriptors: [
{
id: 'wa_driver_license',
name: 'Washington State Business License',
purpose:
'We can only allow licensed Washington State business representatives into the WA Business Conference',
constraints: {
fields: [
{
path: [
'$.credentialSubject.dateOfBirth',
'$.credentialSubject.dob',
'$.vc.credentialSubject.dateOfBirth',
'$.vc.credentialSubject.dob',
],
},
],
},
},
],
},
scope: Scopes.CompanyHouse,

})

}, [dispatch]);

useEffect(() => {
if(state[Scopes.CompanyHouse]?.credentials?.length) {
if (state[Scopes.CompanyHouse]?.credentials?.length) {
goToNextStep();
}
}, [state, goToNextStep])
Expand Down

0 comments on commit 8052c8d

Please sign in to comment.