Skip to content

Commit

Permalink
add healthz endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
jchartrand committed May 23, 2024
1 parent 03ce9c5 commit 8bc1061
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 23 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@digitalbazaar/ed25519-signature-2020": "^5.2.0",
"@digitalbazaar/ed25519-verification-key-2020": "^4.1.0",
"@digitalbazaar/vc": "^6.0.1",
"axios": "^1.7.2",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"credentials-context": "^2.0.0",
Expand Down
6 changes: 6 additions & 0 deletions src/TransactionException.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default function TransactionException(code, message, stack) {
this.code = code
this.message = message
this.stack = stack
}

65 changes: 50 additions & 15 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import express from 'express';
import express, { request } from 'express';
import logger from 'morgan';
import cors from 'cors';
import axios from 'axios'
import { initializeTransactionManager, setupExchange, retrieveStoredData, getVPR } from './transactionManager.js';
import { getDataForExchangeSetupPost } from './test-fixtures/testData.js';
import { getSignedDIDAuth } from './didAuth.js';
import TransactionException from './TransactionException.js';

export async function build(opts = {}) {

Expand All @@ -18,6 +22,37 @@ export async function build(opts = {}) {
res.send({ message: 'transaction-service server status: ok.' })
});

app.get('/healthz', async function (req, res) {

const baseURL = `${req.protocol}://${req.headers.host}`
const testData = getDataForExchangeSetupPost('test', baseURL)
const exchangeURL = `${baseURL}/exchange`
try {
const response = await axios.post(
exchangeURL,
testData
)
const { data: walletQuerys } = response
const walletQuery = walletQuerys.find(q => q.retrievalId === 'someId')
const parsedDeepLink = new URL(walletQuery.directDeepLink)
const requestURI = parsedDeepLink.searchParams.get('vc_request_url');
const challenge = parsedDeepLink.searchParams.get('challenge');
const didAuth = await getSignedDIDAuth('did:ex:223234', challenge)
const { data } = await axios.post(requestURI, didAuth)
const { tenantName, vc: unSignedVC } = data
if (!tenantName === 'test' || ! unSignedVC.name === "A Simply Wonderful Course") {
throw new TransactionException(503, 'transaction-service healthz failed')
}
} catch (e) {
console.log(`exception in healthz: ${JSON.stringify(e)}`)
return res.status(503).json({
error: `transaction-service healthz check failed with error: ${e}`,
healthy: false
})
}
res.send({ message: 'transaction-service server status: ok.', healthy: true })
})

/*
This is step 1 in an exchange.
Creates a new exchange and stores the provided data
Expand All @@ -31,7 +66,7 @@ export async function build(opts = {}) {
async (req, res) => {
try {
const data = req.body;
if (!data || !Object.keys(data).length) return res.status(400).send({code: 400, message: 'No data was provided in the body.'})
if (!data || !Object.keys(data).length) return res.status(400).send({ code: 400, message: 'No data was provided in the body.' })
const walletQuerys = await setupExchange(data)
return res.json(walletQuerys)
} catch (error) {
Expand All @@ -40,13 +75,13 @@ export async function build(opts = {}) {
}
})

/*
This is step 2 in an exchange, where the wallet
has asked to initiate the exchange, and we reply
here with a Verifiable Presentation Request, asking
for a DIDAuth. Note that in some scenarios the wallet
may skip this step and directly present the DIDAuth.
*/
/*
This is step 2 in an exchange, where the wallet
has asked to initiate the exchange, and we reply
here with a Verifiable Presentation Request, asking
for a DIDAuth. Note that in some scenarios the wallet
may skip this step and directly present the DIDAuth.
*/
app.post("/exchange/:exchangeId",
async (req, res) => {
try {
Expand All @@ -58,12 +93,12 @@ export async function build(opts = {}) {
}
})

/*
This is step 3 in an exchange, where we verify the
supplied DIDAuth, and if verified we return the previously
stored data for the exchange.
*/
app.post("/exchange/:exchangeId/:transactionId",
/*
This is step 3 in an exchange, where we verify the
supplied DIDAuth, and if verified we return the previously
stored data for the exchange.
*/
app.post("/exchange/:exchangeId/:transactionId",
async (req, res) => {
try {
const didAuth = req.body
Expand Down
16 changes: 13 additions & 3 deletions src/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,22 @@ describe('api', () => {
expect(response.body.length).to.eql(testData.data.length)
})




})

describe('GET /healthz', () => {

it.only('returns 200 if running', async () => {

const response = await request(app)
.get("/healthz")

expect(response.header["content-type"]).to.have.string("json");
expect(response.status).to.eql(200);
expect(response.body).to.eql({ message: 'transaction-service server status: ok.', healthy: true })

})

})

})

Expand Down
27 changes: 24 additions & 3 deletions src/didAuth.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
import {verify} from '@digitalbazaar/vc';
import {signPresentation, createPresentation, verify} from '@digitalbazaar/vc';
import {Ed25519VerificationKey2020} from '@digitalbazaar/ed25519-verification-key-2020';
import {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020';
import { securityLoader } from './securityLoader.js';

const documentLoader = securityLoader().build()
const suite = new Ed25519Signature2020();

const signingKeyPairForTesting = await Ed25519VerificationKey2020.generate(
{
seed: new Uint8Array ([
217, 87, 166, 30, 75, 106, 132, 55,
32, 120, 171, 23, 116, 73, 254, 74,
230, 16, 127, 91, 2, 252, 224, 96,
184, 172, 245, 157, 58, 217, 91, 240
]),
controller: "did:key:z6MkvL5yVCgPhYvQwSoSRQou6k6ZGfD5mNM57HKxufEXwfnP"
}
)
const suiteForSigning = new Ed25519Signature2020({key: signingKeyPairForTesting});
const suiteForVerification = new Ed25519Signature2020();

export const getSignedDIDAuth = async (holder = 'did:ex:12345', challenge) => {
const presentation = createPresentation({holder});
return await signPresentation({
presentation, suite: suiteForSigning, challenge, documentLoader
});
}

export const verifyDIDAuth = async ({presentation, challenge}) => {
const result = await verify({presentation, challenge, suite, documentLoader});
const result = await verify({presentation, challenge, suite: suiteForVerification, documentLoader});
return result.verified
}

4 changes: 2 additions & 2 deletions src/test-fixtures/testData.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import testVC from './testVC.js';

const getDataForExchangeSetupPost = (tenantName) => {
const getDataForExchangeSetupPost = (tenantName, exchangeHost = 'http://localhost:4005') => {
const fakeData = {
tenantName,
exchangeHost: 'http://localhost:4005',
exchangeHost,
data: [
{ vc: testVC, retrievalId: 'someId', },
{ vc: testVC, retrievalId: 'blah' }
Expand Down

0 comments on commit 8bc1061

Please sign in to comment.