Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use DID instead of username to identify users internally #14

Merged
merged 6 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions src/entities/user.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,26 +143,6 @@ async function getUserByCredentials(username: string, password: string): Promise
}
}

async function getUserByUsername(username: string): Promise<Result<UserEntity, GetUserErr>> {
try {

const res = await AppDataSource.getRepository(UserEntity)
.createQueryBuilder("user")
.where("user.username = :username", { username: username })
.getOne();
if (!res) {
return Err(GetUserErr.NOT_EXISTS);
}

return Ok(res);
}
catch(e) {
console.log(e);
return Err(GetUserErr.DB_ERR)
}
}


async function getAllUsers(): Promise<Result<UserEntity[], GetUserErr>> {
try {

Expand Down Expand Up @@ -207,6 +187,5 @@ export {
getUserByDID,
getUserByCredentials,
UpdateFcmError,
getUserByUsername,
getAllUsers
}
20 changes: 13 additions & 7 deletions src/routers/issuance.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import express, { Router } from 'express';
import { AuthMiddleware } from '../middlewares/auth.middleware';
import _ from 'lodash';
import { appContainer } from '../services/inversify.config';
import { OpenidCredentialReceiving } from '../services/interfaces';
import { IssuanceErr, OpenidCredentialReceiving } from '../services/interfaces';
import { TYPES } from '../services/types';


Expand All @@ -23,7 +23,7 @@ issuanceRouter.post('/generate/authorization/request', async (req, res) => {
const {
legal_person_did,
} = req.body;
const result = await openidForCredentialIssuanceService.generateAuthorizationRequestURL(req.user.username, null, legal_person_did);
const result = await openidForCredentialIssuanceService.generateAuthorizationRequestURL(req.user.did, null, legal_person_did);
res.send(result);
}
catch(err) {
Expand All @@ -38,7 +38,7 @@ issuanceRouter.post('/generate/authorization/request/with/offer', async (req, re
credential_offer_url,
} = req.body;

const result = await openidForCredentialIssuanceService.generateAuthorizationRequestURL(req.user.username, credential_offer_url, null);
const result = await openidForCredentialIssuanceService.generateAuthorizationRequestURL(req.user.did, credential_offer_url, null);
res.send(result);
}
catch(err) {
Expand All @@ -57,8 +57,14 @@ issuanceRouter.post('/handle/authorization/response', async (req, res) => {
if (!(new URL(authorization_response_url).searchParams.get("code"))) {
return res.status(500).send({});
}
await openidForCredentialIssuanceService.handleAuthorizationResponse(req.user.username, authorization_response_url);
res.send({});
const result = await openidForCredentialIssuanceService.handleAuthorizationResponse(req.user.did, authorization_response_url);
if (result.ok) {
res.send({});
} else if (result.val === IssuanceErr.STATE_NOT_FOUND) {
res.status(404).send({});
} else {
res.status(500).send({});
}
}
catch(err) {
res.status(500).send({ error: "Failed to handle authorization response" });
Expand All @@ -72,7 +78,7 @@ issuanceRouter.post('/request/credentials/with/pre_authorized', async (req, res)
user_pin
} = req.body;

await openidForCredentialIssuanceService.requestCredentialsWithPreAuthorizedGrant(req.user.username, user_pin);
await openidForCredentialIssuanceService.requestCredentialsWithPreAuthorizedGrant(req.user.did, user_pin);
res.send({});
}
catch(err) {
Expand All @@ -83,4 +89,4 @@ issuanceRouter.post('/request/credentials/with/pre_authorized', async (req, res)

export {
issuanceRouter
}
}
16 changes: 13 additions & 3 deletions src/routers/presentation.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ presentationRouter.post('/handle/authorization/request', async (req, res) => {
} = req.body;

try{
const outboundRequest = await openidForPresentationService.handleRequest(req.user.username, authorization_request)
const outboundRequestResult = await openidForPresentationService.handleRequest(req.user.did, authorization_request);
if (!outboundRequestResult.ok) {
return res.status(500).send({});
}

const outboundRequest = outboundRequestResult.val;
if (outboundRequest.conformantCredentialsMap && outboundRequest.verifierDomainName) {
const { conformantCredentialsMap, verifierDomainName } = outboundRequest;
// convert from map to JSON
Expand Down Expand Up @@ -54,7 +59,12 @@ presentationRouter.post('/generate/authorization/response', async (req, res) =>

const selection = new Map(Object.entries(verifiable_credentials_map)) as Map<string, string>;
try {
const { redirect_to, error } = await openidForPresentationService.sendResponse(req.user.username, selection);
const result = await openidForPresentationService.sendResponse(req.user.did, selection);
if (!result.ok) {
return res.status(500).send({});
}

const { redirect_to, error } = result.val;
if (error) {
const errText = `Error generating authorization response: ${error}`;
console.error(errText);
Expand All @@ -74,4 +84,4 @@ presentationRouter.post('/generate/authorization/response', async (req, res) =>

export {
presentationRouter
}
}
2 changes: 1 addition & 1 deletion src/routers/user.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,4 @@ userController.post('/login', async (req: Request, res: Response) => {
// res.send({ publicKeyJwk });
// });

export default userController;
export default userController;
58 changes: 31 additions & 27 deletions src/services/DatabaseKeystoreService.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { SignJWT, importJWK } from "jose";
import { AdditionalKeystoreParameters, WalletKeystore } from "./interfaces";
import { getUserByUsername } 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 "reflect-metadata";
import { Err, Ok, Result } from "ts-results";

import { SignVerifiablePresentationJWT, WalletKey } from "@gunet/ssi-sdk";
import { AdditionalKeystoreParameters, WalletKeystore, WalletKeystoreErr } from "./interfaces";
import { verifiablePresentationSchemaURL } from "../util/util";
import { getUserByDID } from "../entities/user.entity";


@injectable()
Expand All @@ -16,13 +18,15 @@ export class DatabaseKeystoreService implements WalletKeystore {

constructor() { }

async createIdToken(username: string, nonce: string, audience: string, additionalParameters: AdditionalKeystoreParameters): Promise<{ id_token: string; }> {
async createIdToken(userDid: string, nonce: string, audience: string, additionalParameters: AdditionalKeystoreParameters): Promise<Result<{ id_token: string; }, WalletKeystoreErr>> {
const user = (await getUserByDID(userDid)).unwrap();
const keys = JSON.parse(user.keys.toString()) as WalletKey;

const user = (await getUserByUsername(username)).unwrap();
if (!keys.privateKey) {
return Err(WalletKeystoreErr.KEYS_UNAVAILABLE);
}

const keys = JSON.parse(user.keys.toString()) as WalletKey;
const privateKey = await importJWK(keys.privateKey, keys.alg);

const jws = await new SignJWT({ nonce: nonce })
.setProtectedHeader({
alg: keys.alg,
Expand All @@ -36,14 +40,18 @@ export class DatabaseKeystoreService implements WalletKeystore {
.setIssuedAt()
.sign(privateKey);

return { id_token: jws };
return Ok({ id_token: jws });
}

async signJwtPresentation(username: string, nonce: string, audience: string, verifiableCredentials: any[], additionalParameters: AdditionalKeystoreParameters): Promise<{ vpjwt: string }> {
const user = (await getUserByUsername(username)).unwrap();
async signJwtPresentation(userDid: string, nonce: string, audience: string, verifiableCredentials: any[], additionalParameters: AdditionalKeystoreParameters): Promise<Result<{ vpjwt: string }, WalletKeystoreErr>> {
const user = (await getUserByDID(userDid)).unwrap();
const keys = JSON.parse(user.keys.toString()) as WalletKey;
const privateKey = await importJWK(keys.privateKey, keys.alg);

if (!keys.privateKey) {
return Err(WalletKeystoreErr.KEYS_UNAVAILABLE);
}

const privateKey = await importJWK(keys.privateKey, keys.alg);
const jws = await new SignVerifiablePresentationJWT()
.setProtectedHeader({
alg: keys.alg,
Expand All @@ -55,7 +63,7 @@ export class DatabaseKeystoreService implements WalletKeystore {
.setType(["VerifiablePresentation"])
.setAudience(audience)
.setCredentialSchema(
verifiablePresentationSchemaURL,
verifiablePresentationSchemaURL,
"FullJsonSchemaValidator2021")
.setIssuer(user.did)
.setSubject(user.did)
Expand All @@ -65,36 +73,32 @@ export class DatabaseKeystoreService implements WalletKeystore {
.setIssuedAt()
.setExpirationTime('1m')
.sign(privateKey);
return { vpjwt: jws };
return Ok({ vpjwt: jws });
}

async generateOpenid4vciProof(username: string, audience: string, nonce: string, additionalParameters: AdditionalKeystoreParameters): Promise<{ proof_jwt: string }> {
async generateOpenid4vciProof(userDid: string, audience: string, nonce: string, additionalParameters: AdditionalKeystoreParameters): Promise<Result<{ proof_jwt: string }, WalletKeystoreErr>> {
const user = (await getUserByDID(userDid)).unwrap();
const keys = JSON.parse(user.keys.toString()) as WalletKey;

const user = (await getUserByUsername(username)).unwrap();
if (!keys.privateKey) {
return Err(WalletKeystoreErr.KEYS_UNAVAILABLE);
}

const keys = JSON.parse(user.keys.toString()) as WalletKey;
const privateKey = await importJWK(keys.privateKey, keys.alg);
const header = {
alg: keys.alg,
typ: "openid4vci-proof+jwt",
kid: keys.did + "#" + keys.did.split(":")[2]
};

const jws = await new SignJWT({ nonce: nonce })
.setProtectedHeader(header)
.setIssuedAt()
.setIssuer(user.did)
.setAudience(audience)
.setExpirationTime('1m')
.sign(privateKey);
return { proof_jwt: jws };

}
async getIdentifier(username: string): Promise<string> {
const user = (await getUserByUsername(username)).unwrap();
return user.did;
return Ok({ proof_jwt: jws });
}



}
}
Loading