Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
kkmanos committed Sep 5, 2023
1 parent 1d12d26 commit 6a5c1c8
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 36 deletions.
3 changes: 2 additions & 1 deletion config/config.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export = {
walletClientUrl: "WALLET_CLIENT_URL",
alg: "ES256",
servicesConfiguration: {
issuanceService: "OpenidForCredentialIssuanceService"
issuanceService: "OpenidForCredentialIssuanceService", // OpenidForCredentialIssuanceService or OpenidForCredentialIssuanceMattrV2Service
didKeyService: "W3C", // W3C or EBSI
}
}
15 changes: 5 additions & 10 deletions samples/wallet-mock/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ app.get('/', async (req, res) => {
{ headers: { "Authorization": `Bearer ${global.user.appToken}` }}
).then(response => {
let { vc_list } = response.data;
console.log("VC list = ");

console.dir(vc_list);
vc_list = vc_list.map((vc) => {
const vcjwt = vc.credential;
const payload = JSON.parse(base64url.decode(vcjwt.split('.')[1]));
Expand All @@ -74,9 +71,7 @@ app.get('/vp', async (req, res) => {
{ headers: { "Authorization": `Bearer ${global.user.appToken}` }}
).then(response => {
let { vp_list } = response.data;
console.log("VP list = ");

console.dir(vp_list);
vp_list = vp_list.map((vp) => {
const vpjwt = vp.presentation;
const payload = JSON.parse(base64url.decode(vpjwt.split('.')[1]));
Expand All @@ -101,7 +96,6 @@ app.get('/vc/:vc_id', async (req, res) => {
{ headers: { "Authorization": `Bearer ${global.user.appToken}` }}
).then(response => {
let vc = response.data;
console.log("VC list = ");

const vcjwt = vc.credential;
const payload = base64url.decode(vcjwt.split('.')[1]);
Expand Down Expand Up @@ -165,11 +159,13 @@ app.get('/init/issuance/:iss', async (req, res) => {


app.get('/init/verification/vid', async (req, res) => {
const url = new URL("http://127.0.0.1:8003/verification/authorize");
url.searchParams.append("scope", "openid vid")
url.searchParams.append("redirect_uri", "http://127.0.0.1:7777");
const url = new URL("http://wallet-enterprise-vid-issuer:8003/verification/authorize");
url.searchParams.append("scope", "openid ver_test:vp_token vid")
url.searchParams.append("redirect_uri", "http://wallet-mock:7777");
url.searchParams.append("client_id", global.user.did)
url.searchParams.append("response_type", "code")
url.searchParams.append("state", "123xxx")

res.redirect(url.toString())
});

Expand All @@ -188,7 +184,6 @@ async function handleCredentialOffer(req, res, next) {
{ credential_offer_url: url },
{ headers: { "Authorization": `Bearer ${global.user.appToken}` }}
).then(success => {
console.log("SUccess = ", success.data)
const { redirect_to } = issuanceInitiation.data;
return res.redirect(redirect_to);
}).catch(e => {
Expand Down
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { issuanceRouter } from './routers/issuance.router';
import { storageRouter } from './routers/storage.router';
import { presentationRouter } from './routers/presentation.router';
import { legalPersonRouter } from './routers/legal_person.router';
import verifiersRouter from './routers/verifiers.router';

const app: Express = express();
// __dirname is "/path/to/dist/src"
Expand Down Expand Up @@ -52,6 +53,7 @@ app.use('/issuance', issuanceRouter);
app.use('/storage', storageRouter);
app.use('/presentation', presentationRouter);
app.use('/legal_person', legalPersonRouter);
app.use('/verifiers', verifiersRouter);

app.listen(config.port, () => {
console.log(`eDiplomas Register app listening at ${config.url}`)
Expand Down
13 changes: 13 additions & 0 deletions src/routers/presentation.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,20 @@ const openidForPresentationService = appContainer.get<OutboundCommunication>(TYP
const presentationRouter: Router = express.Router();
presentationRouter.use(AuthMiddleware);

presentationRouter.post('/initiate', async (req, res) => {
const {
verifier_id,
scope_name
} = req.body;

try {
const { redirect_to } = await openidForPresentationService.initiateVerificationFlow(req.user.username, verifier_id, scope_name);
return res.send({ redirect_to });
}
catch(e) {
return res.status(500).send({ error: "Cannot initiate verification flow" });
}
})

presentationRouter.post('/handle/authorization/request', async (req, res) => {
const {
Expand Down
1 change: 0 additions & 1 deletion src/routers/storage.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ async function getAllVerifiableCredentialsController(req, res) {
}
});

console.log("VC list = ", vc_list)
res.status(200).send({ vc_list: vc_list })

}
Expand Down
15 changes: 15 additions & 0 deletions src/routers/verifiers.router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Router } from "express";
import { appContainer } from "../services/inversify.config";
import { VerifierRegistryService } from "../services/VerifierRegistryService";



const verifiersRouter = Router();
const verifiersRegistryService = appContainer.resolve(VerifierRegistryService)


verifiersRouter.get('/all', async (req, res) => {
res.send({ verifiers: await verifiersRegistryService.getAllVerifiers() });
});

export default verifiersRouter;
28 changes: 10 additions & 18 deletions src/services/DatabaseKeystoreService.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
import { SignJWT, importJWK, jwtVerify } from "jose";
import { AdditionalKeystoreParameters, WalletKeystore } from "./interfaces";
import { AdditionalKeystoreParameters, DidKeyUtilityService, WalletKeystore } from "./interfaces";
import { getUserByUsername, storeKeypair } from "../entities/user.entity";
import { SignVerifiablePresentationJWT, WalletKey } from "@gunet/ssi-sdk";
import { randomUUID } from "crypto";
import { verifiablePresentationSchemaURL } from "../util/util";
import { injectable } from "inversify";
import * as ed25519 from "@transmute/did-key-ed25519";
import * as crypto from "node:crypto";
import { inject, injectable } from "inversify";

import "reflect-metadata";
import { TYPES } from "./types";


@injectable()
export class DatabaseKeystoreService implements WalletKeystore {

public static readonly identifier = "DatabaseKeystoreService"
private readonly algorithm = "EdDSA";

constructor() { }
constructor(
@inject(TYPES.DidKeyUtilityService) private didKeyService: DidKeyUtilityService,
) { }

async generateKeyPair(username: string): Promise<{ did: string }> {
const { didDocument, keys } = await ed25519.generate(
{
secureRandom: () => {
return crypto.randomBytes(32);
},
},
{ accept: 'application/did+json' }
);
console.log("DID document = ", didDocument)
console.log("Keys = ", keys);
storeKeypair(username, didDocument.id, Buffer.from(JSON.stringify(keys[0])));
return { did: didDocument.id }
const { did, key } = await this.didKeyService.generateKeyPair();
storeKeypair(username, did, Buffer.from(JSON.stringify(key)));
return { did: did }
}

async createIdToken(username: string, nonce: string, audience: string, additionalParameters: AdditionalKeystoreParameters): Promise<{ id_token: string; }> {
Expand Down
1 change: 0 additions & 1 deletion src/services/OpenidForCredentialIssuanceMattrV2Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ type IssuanceState = {
@injectable()
export class OpenidForCredentialIssuanceMattrV2Service implements OpenidCredentialReceiving {

public static readonly identifier = "OpenidForCredentialIssuanceService"
// identifierService: IdentifierService = new IdentifierService();
// legalPersonService: LegalPersonService = new LegalPersonService();

Expand Down
4 changes: 2 additions & 2 deletions src/services/OpenidForCredentialIssuanceService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ type IssuanceState = {
@injectable()
export class OpenidForCredentialIssuanceService implements OpenidCredentialReceiving {

public static readonly identifier = "OpenidForCredentialIssuanceService"
// identifierService: IdentifierService = new IdentifierService();
// legalPersonService: LegalPersonService = new LegalPersonService();

Expand Down Expand Up @@ -359,7 +358,8 @@ export class OpenidForCredentialIssuanceService implements OpenidCredentialRecei


for (const cr of credentialResponses) {
this.checkConstantlyForPendingCredential(state, cr.acceptance_token);
if (cr.acceptance_token)
this.checkConstantlyForPendingCredential(state, cr.acceptance_token);
}

// remove the ones that are for deferred endpoint
Expand Down
30 changes: 28 additions & 2 deletions src/services/OpenidForPresentationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import "reflect-metadata";
import { OutboundRequest } from "./types/OutboundRequest";
import { getUserByUsername } from "../entities/user.entity";
import { z } from 'zod';
import config from "../../config";
import { randomUUID } from "crypto";
import { VerifierRegistryService } from "./VerifierRegistryService";

type PresentationDefinition = {
id: string,
Expand Down Expand Up @@ -51,6 +54,7 @@ type Field = {
}

type VerificationState = {
holder_state?: string;
presentation_definition?: PresentationDefinition;
audience?: string;
nonce?: string;
Expand All @@ -61,17 +65,39 @@ type VerificationState = {

@injectable()
export class OpenidForPresentationService implements OutboundCommunication {
public static readonly identifier = "OpenidForPresentationService"

states = new Map<string, VerificationState>();



constructor(
@inject(TYPES.WalletKeystore) private walletKeystore: WalletKeystore,
@inject(TYPES.VerifierRegistryService) private verifierRegistryService: VerifierRegistryService,
@inject(TYPES.OpenidForCredentialIssuanceService) private OpenidCredentialReceivingService: OpenidCredentialReceiving
) { }


async initiateVerificationFlow(username: string, verifierId: number, scopeName: string): Promise<{ redirect_to?: string }> {
const verifier = (await this.verifierRegistryService.getAllVerifiers()).filter(ver => ver.id == verifierId)[0];

const userFetchRes = await getUserByUsername(username);
if (userFetchRes.err) {
return {};
}

const holder_state = randomUUID();
this.states.set(username, { holder_state });

const user = userFetchRes.unwrap();
const url = new URL(verifier.url);
url.searchParams.append("scope", "openid " + scopeName);
url.searchParams.append("redirect_uri", config.walletClientUrl);
url.searchParams.append("client_id", user.did);
url.searchParams.append("response_type", "code");
url.searchParams.append("state", holder_state);
return { redirect_to: url.toString() };
}

async handleRequest(username: string, requestURL: string): Promise<OutboundRequest> {
try {
const { redirect_to } = await this.parseIdTokenRequest(username, requestURL);
Expand Down Expand Up @@ -371,7 +397,7 @@ export class OpenidForPresentationService implements OutboundCommunication {

const directPostPayload = {
vp_token: vp_token,
presentation_submission: JSON.stringify(presentationSubmission),
presentation_submission: presentationSubmission,
state: state
};
const { newLocation } = await axios.post(redirect_uri, qs.stringify(directPostPayload), {
Expand Down
39 changes: 39 additions & 0 deletions src/services/VerifierRegistryService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { injectable } from "inversify";
import 'reflect-metadata';

type Verifier = {
id: number;
name: string;
url: string;
scopes: {
name: string;
description: string;
}[];
}

@injectable()
export class VerifierRegistryService {
private readonly verifierRegistry: Verifier[] = [
{
id: 1,
name: "National Authority",
url: "http://wallet-enterprise-vid-issuer:8003/verification/authorize",
scopes: [
{
name: "vid",
description: "Present your Verifiable ID"
},
{
name: "ver:test",
description: "Test"
}
]
}
];



async getAllVerifiers() {
return this.verifierRegistry;
}
}
32 changes: 32 additions & 0 deletions src/services/W3CDidKeyUtilityService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { injectable } from 'inversify';
import 'reflect-metadata';
import { DidKeyUtilityService } from './interfaces';
import { JWK } from 'jose';
import * as ed25519 from "@transmute/did-key-ed25519";
import * as crypto from "node:crypto";


@injectable()
export class W3CDidKeyUtilityService implements DidKeyUtilityService {


async getPublicKeyJwk(did: string): Promise<JWK> {
const result = await ed25519.resolve(did, { accept: 'application/did+json' });
const verificationMethod = result.didDocument.verificationMethod[0] as any;
return verificationMethod.publicKeyJwk as JWK;
}

async generateKeyPair(): Promise<{ did: string, key: any }> {
const { didDocument, keys } = await ed25519.generate(
{
secureRandom: () => {
return crypto.randomBytes(32);
},
},
{ accept: 'application/did+json' }
);
console.log("DID document = ", didDocument)
console.log("Keys = ", keys);
return { did: didDocument.id, key: keys[0] };
}
}
9 changes: 9 additions & 0 deletions src/services/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { JWK } from "jose";
import { LegalPersonEntity } from "../entities/LegalPerson.entity";
import { OutboundRequest } from "./types/OutboundRequest";

Expand Down Expand Up @@ -30,6 +31,9 @@ export interface WalletKeystore {

export interface OutboundCommunication {


initiateVerificationFlow(username: string, verifierId: number, scopeName: string): Promise<{ redirect_to?: string }>;

handleRequest(username: string, requestURL: string): Promise<OutboundRequest>;

/**
Expand All @@ -44,4 +48,9 @@ export interface OutboundCommunication {

export interface LegalPersonsRegistry {
getByIdentifier(did: string): Promise<LegalPersonEntity>;
}

export interface DidKeyUtilityService {
getPublicKeyJwk(did: string): Promise<JWK>;
generateKeyPair(): Promise<{ did: string, key: any }>
}
Loading

0 comments on commit 6a5c1c8

Please sign in to comment.