diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/Dockerfile b/AliceFaberAcmeDemo/controllers/acme-controller/Dockerfile index 9811e86..e22fc3e 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/Dockerfile +++ b/AliceFaberAcmeDemo/controllers/acme-controller/Dockerfile @@ -1,4 +1,18 @@ -FROM node:22 as build -COPY . . +FROM node:22 + +WORKDIR /app + +# Copy package.json and package-lock.json +COPY package*.json ./ + +# Install dependencies RUN npm install -ENTRYPOINT [ "npm", "start" ] + +# Copy the rest of the application files +COPY . . + +# Expose the port the app runs on +EXPOSE 80 + +# Start the application +CMD ["node", "app.js"] diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/app.js b/AliceFaberAcmeDemo/controllers/acme-controller/app.js index 2b33249..ba1a231 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/app.js +++ b/AliceFaberAcmeDemo/controllers/acme-controller/app.js @@ -1,57 +1,66 @@ -var createError = require('http-errors'); -const express = require('express'); -const path = require('path'); -const cookieParser = require('cookie-parser'); -const logger = require('morgan'); -const { engine } = require('express-handlebars'); -const helpers = require('handlebars-helpers'); - -const indexRouter = require('./routes/index'); -const connectionRouter = require('./routes/connection'); -const proofRouter = require('./routes/proof'); +var createError = require("http-errors"); +const express = require("express"); +const path = require("path"); +const cookieParser = require("cookie-parser"); +const logger = require("morgan"); +const { engine } = require("express-handlebars"); +const helpers = require("handlebars-helpers"); + +const indexRouter = require("./routes/index"); +const connectionRouter = require("./routes/connection"); +const proofRouter = require("./routes/proof"); const app = express(); // view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'hbs'); -app.engine('hbs', engine({ - extname: 'hbs', - defaultView: 'default', - layoutsDir: path.join(__dirname, '/views/layouts/'), - partialsDir: [ - path.join(__dirname, '/views/partials'), - path.join(__dirname, '/views/partials/connection'), - path.join(__dirname, '/views/partials/home'), - path.join(__dirname, '/views/partials/proof'), - ], - helpers: helpers(['array', 'comparison']) -})); - -app.use(logger('dev')); +app.set("views", path.join(__dirname, "views")); +app.set("view engine", "hbs"); +app.engine( + "hbs", + engine({ + extname: "hbs", + defaultView: "default", + layoutsDir: path.join(__dirname, "/views/layouts/"), + partialsDir: [ + path.join(__dirname, "/views/partials"), + path.join(__dirname, "/views/partials/connection"), + path.join(__dirname, "/views/partials/home"), + path.join(__dirname, "/views/partials/proof"), + ], + helpers: helpers(["array", "comparison"]), + }) +); + +app.use(logger("dev")); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); +app.use(express.static(path.join(__dirname, "public"))); -app.use('/', indexRouter); -app.use('/connections', connectionRouter); -app.use('/proofs', proofRouter); +app.use("/", indexRouter); +app.use("/connections", connectionRouter); +app.use("/proofs", proofRouter); // catch 404 and forward to error handler -app.use(function(req, res, next) { +app.use(function (req, res, next) { next(createError(404)); }); // error handler -app.use(function(err, req, res, next) { +app.use(function (err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; - res.locals.error = req.app.get('env') === 'development' ? err : {}; + res.locals.error = req.app.get("env") === "development" ? err : {}; // render the error page res.status(err.status || 500); - res.render('error'); + res.render("error"); +}); + +// Start the server +const PORT = process.env.PORT || 80; +app.listen(PORT, () => { + console.log(`Server is running on port ${PORT}`); }); module.exports = app; diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/docker-compose.yml b/AliceFaberAcmeDemo/controllers/acme-controller/docker-compose.yml new file mode 100644 index 0000000..2710c38 --- /dev/null +++ b/AliceFaberAcmeDemo/controllers/acme-controller/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3" +services: + acme-controller: + build: . + ports: + - "8140:80" # Expose a different port for the controller + environment: + - AGENT_HOST=host.docker.internal + - AGENT_PORT=8040 + networks: + - aca +networks: + aca: diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/package.json b/AliceFaberAcmeDemo/controllers/acme-controller/package.json index a6463ba..1483437 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/package.json +++ b/AliceFaberAcmeDemo/controllers/acme-controller/package.json @@ -10,6 +10,7 @@ "ext": "js,json,hbs,css" }, "dependencies": { + "axios": "^1.8.3", "cookie-parser": "^1.4.7", "debug": "^2.6.9", "express": "^4.21.1", diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/routes/connection.js b/AliceFaberAcmeDemo/controllers/acme-controller/routes/connection.js index 259dd59..369ac48 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/routes/connection.js +++ b/AliceFaberAcmeDemo/controllers/acme-controller/routes/connection.js @@ -1,133 +1,156 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const { check, validationResult } = require('express-validator'); +const { check, validationResult } = require("express-validator"); -const NavLinkService = require('../services/NavLinkService'); +const NavLinkService = require("../services/NavLinkService"); const navLinkService = new NavLinkService(); navLinkService.registerCustomLinks([ - { "label": "Active", "url": "/connections/active" }, - { "label": "Pending", "url": "/connections/pending" }, - { "label": "New", "url": "/connections/new" }, - { "label": "Accept", "url": "/connections/accept" } + { label: "Active", url: "/connections/active" }, + { label: "Pending", url: "/connections/pending" }, + { label: "New", url: "/connections/new" }, + { label: "Accept", url: "/connections/accept" }, ]); router.use(function (req, res, next) { - navLinkService.clearLinkClasses(); - navLinkService.setNavLinkActive('/connections'); - next(); + navLinkService.clearLinkClasses(); + navLinkService.setNavLinkActive("/connections"); + next(); }); -router.get('/', async function (req, res, next) { - res.redirect('/connections/active'); +router.get("/", async function (req, res, next) { + res.redirect("/connections/active"); }); -router.get('/active', async function (req, res, next) { - const agentService = require('../services/AgentService'); - const allConnections = await agentService.getConnections(); - const connections = allConnections.filter(connection => connection.state === 'active' || connection.state === 'request'); - - navLinkService.setCustomNavLinkActive('/connections/active'); - res.render('connection', { - navLinks: navLinkService.getNavLinks(), - customNavLinks: navLinkService.getCustomNavLinks(), - connections - }); +router.get("/active", async function (req, res, next) { + const agentService = require("../services/AgentService"); + const allConnections = await agentService.getConnections(); + const connections = allConnections.filter( + (connection) => + connection.state === "active" || connection.state === "request" + ); + + navLinkService.setCustomNavLinkActive("/connections/active"); + res.render("connection", { + navLinks: navLinkService.getNavLinks(), + customNavLinks: navLinkService.getCustomNavLinks(), + connections, + }); }); -router.get('/pending', async function (req, res, next) { - const agentService = require('../services/AgentService'); - const allConnections = await agentService.getConnections(); - const connections = allConnections.filter(connection => connection.state === 'invitation'); - - navLinkService.setCustomNavLinkActive('/connections/pending'); - res.render('connection', { - navLinks: navLinkService.getNavLinks(), - customNavLinks: navLinkService.getCustomNavLinks(), - connections - }); +router.get("/pending", async function (req, res, next) { + const agentService = require("../services/AgentService"); + const allConnections = await agentService.getConnections(); + const connections = allConnections.filter( + (connection) => connection.state === "invitation" + ); + + navLinkService.setCustomNavLinkActive("/connections/pending"); + res.render("connection", { + navLinks: navLinkService.getNavLinks(), + customNavLinks: navLinkService.getCustomNavLinks(), + connections, + }); }); -router.get('/new', handleNewConnectionGet); +router.get("/new", handleNewConnectionGet); -router.post('/new', handleNewConnectionPost, handleNewConnectionGet); +router.post("/new", handleNewConnectionPost, handleNewConnectionGet); async function handleNewConnectionGet(req, res, next) { - navLinkService.setCustomNavLinkActive('/connections/new'); - res.render('new_connection', { - navLinks: navLinkService.getNavLinks(), - customNavLinks: navLinkService.getCustomNavLinks(), - invitation: req.invitation - }); + navLinkService.setCustomNavLinkActive("/connections/new"); + res.render("new_connection", { + navLinks: navLinkService.getNavLinks(), + customNavLinks: navLinkService.getCustomNavLinks(), + invitation: req.invitation, + }); } async function handleNewConnectionPost(req, res, next) { - const agentService = require('../services/AgentService'); - - const invitation = await agentService.createInvitation(); - if (invitation) { - invitation.invitation = JSON.stringify(invitation.invitation, null, 4); - } - req.invitation = invitation - next(); + const agentService = require("../services/AgentService"); + + const invitation = await agentService.createInvitation(); + console.log("Invitation Object:", invitation); // Debugging log + if (invitation) { + invitation.invitation = JSON.stringify(invitation.invitation, null, 4); + } + req.invitation = invitation; + next(); } -router.get('/accept', handleAcceptConnectionGet); - -router.post('/accept', [ - check('invitation_object') - .notEmpty() - .withMessage('Invitation object is required'), - check('invitation_object') - .custom((value) => { - try { - JSON.parse(value); - return true; - } catch (error) { - throw new Error(`Invalid object: ${error.message}`); - } - }) -], handleAcceptConnectionPost, handleAcceptConnectionGet); +router.get("/accept", handleAcceptConnectionGet); + +router.post( + "/accept", + [ + check("invitation_object") + .notEmpty() + .withMessage("Invitation object is required"), + check("invitation_object").custom((value) => { + try { + JSON.parse(value); + return true; + } catch (error) { + throw new Error(`Invalid object: ${error.message}`); + } + }), + ], + handleAcceptConnectionPost, + handleAcceptConnectionGet +); async function handleAcceptConnectionGet(req, res, next) { - navLinkService.setCustomNavLinkActive('/connections/accept'); - - if (req.errors) { - res.status(422); - } - - res.render('accept_connection', { - navLinks: navLinkService.getNavLinks(), - customNavLinks: navLinkService.getCustomNavLinks(), - errors: req.errors || null, - invitation: req.errors && req.invitaion || null - }); + navLinkService.setCustomNavLinkActive("/connections/accept"); + + if (req.errors) { + res.status(422); + } + + res.render("accept_connection", { + navLinks: navLinkService.getNavLinks(), + customNavLinks: navLinkService.getCustomNavLinks(), + errors: req.errors || null, + invitation: (req.errors && req.invitaion) || null, + }); } async function handleAcceptConnectionPost(req, res, next) { - const agentService = require('../services/AgentService'); - - const errors = validationResult(req); - if (!errors.isEmpty()) { - req.errors = errors.array({ onlyFirstError: true }); - req.invitaion = req.body; - return next(); - } - - await agentService.receiveInvitation(req.body.invitation_object); - res.status(201).redirect('/connections/active'); + const agentService = require("../services/AgentService"); + + const errors = validationResult(req); + if (!errors.isEmpty()) { + req.errors = errors.array({ onlyFirstError: true }); + req.invitation = req.body; + console.error("Validation errors:", req.errors); // Debugging log + return next(); + } + + console.log("Received invitation object:", req.body.invitation_object); // Debugging log + + try { + const response = await agentService.receiveInvitation( + req.body.invitation_object + ); + console.log("API response from receiveInvitation:", response); // Debugging log + res.status(201).redirect("/connections/active"); + } catch (error) { + console.error("Error in handleAcceptConnectionPost:", error); // Debugging log + res.status(500).send("Failed to process invitation"); + } } -router.get('/:id/remove', async function (req, res, next) { - const connectionId = req.params.id; - const state = req.query.state || ''; +router.get("/:id/remove", async function (req, res, next) { + const connectionId = req.params.id; + const state = req.query.state || ""; - if (connectionId) { - const agentService = require('../services/AgentService'); - await agentService.removeConnection(connectionId); - } + if (connectionId) { + const agentService = require("../services/AgentService"); + await agentService.removeConnection(connectionId); + } - const redirectUrl = `/connections/${state === 'invitation' ? 'pending' : 'active'}`; - res.redirect(redirectUrl); + const redirectUrl = `/connections/${ + state === "invitation" ? "pending" : "active" + }`; + res.redirect(redirectUrl); }); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/routes/proof.js b/AliceFaberAcmeDemo/controllers/acme-controller/routes/proof.js index d1d4813..f4797ce 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/routes/proof.js +++ b/AliceFaberAcmeDemo/controllers/acme-controller/routes/proof.js @@ -1,131 +1,142 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const { check, validationResult } = require('express-validator'); +const { check, validationResult } = require("express-validator"); -const NavLinkService = require('../services/NavLinkService'); +const NavLinkService = require("../services/NavLinkService"); const navLinkService = new NavLinkService(); navLinkService.registerCustomLinks([ - { "label": "Proofs", "url": "/proofs" }, - { "label": "Request Proof", "url": "/proofs/request" } + { label: "Proofs", url: "/proofs" }, + { label: "Request Proof", url: "/proofs/request" }, ]); const proofJSON = { - "connection_id": "", - "proof_request": { - "name": "Proof of Education", - "version": "1.0", - "requested_attributes": { + comment: "This is a comment about the reason for the proof", + connection_id: "", + presentation_request: { + indy: { + name: "Proof of Education", + version: "1.0", + requested_attributes: { "0_name_uuid": { - "name": "name", - "restrictions": [ + name: "name", + restrictions: [ { - "cred_def_id": "" - } - ] + cred_def_id: "", + }, + ], }, "0_date_uuid": { - "name": "date", - "restrictions": [ + name: "date", + restrictions: [ { - "cred_def_id": "" - } - ] + cred_def_id: "", + }, + ], }, "0_degree_uuid": { - "name": "degree", - "restrictions": [ + name: "degree", + restrictions: [ { - "cred_def_id": "" - } - ] + cred_def_id: "", + }, + ], }, "0_self_attested_thing_uuid": { - "name": "self_attested_thing" - } + name: "self_attested_thing", + }, }, - "requested_predicates": { + requested_predicates: { "0_age_GE_uuid": { - "name": "birthdate_dateint", - "p_type": ">=", - "p_value": 18, - "restrictions": [ + name: "birthdate_dateint", + p_type: ">=", + p_value: 18, + restrictions: [ { - "cred_def_id": "" - } - ] - } - } - } - } + cred_def_id: "", + }, + ], + }, + }, + }, + }, +}; router.use(function (req, res, next) { - navLinkService.clearLinkClasses(); - navLinkService.setNavLinkActive('/proofs'); - next(); + navLinkService.clearLinkClasses(); + navLinkService.setNavLinkActive("/proofs"); + next(); }); -router.get('/', async function(req, res, next) { - const agentService = require('../services/AgentService'); +router.get("/", async function (req, res, next) { + const agentService = require("../services/AgentService"); - const proofs = await agentService.getProofRequests(); + const proofs = await agentService.getProofRequests(); - navLinkService.setCustomNavLinkActive('/proofs'); - res.render('proof', { - navLinks: navLinkService.getNavLinks(), - customNavLinks: navLinkService.getCustomNavLinks(), - proofs: proofs - }); + navLinkService.setCustomNavLinkActive("/proofs"); + res.render("proof", { + navLinks: navLinkService.getNavLinks(), + customNavLinks: navLinkService.getCustomNavLinks(), + proofs: proofs, + }); }); -router.get('/request', handleRequestProofGet); +router.get("/request", handleRequestProofGet); -router.post('/request', [ - check('connection_id') - .notEmpty() - .withMessage('Connection ID is required'), - check('credential_definition_id') - .notEmpty() - .withMessage('Credential Definition ID is required'), -], handleRequestProofPost, handleRequestProofGet); +router.post( + "/request", + [ + check("connection_id").notEmpty().withMessage("Connection ID is required"), + check("credential_definition_id") + .notEmpty() + .withMessage("Credential Definition ID is required"), + ], + handleRequestProofPost, + handleRequestProofGet +); async function handleRequestProofGet(req, res, next) { - const agentService = require('../services/AgentService'); - const allConnections = await agentService.getConnections(); - const connections = allConnections.filter(connection => connection.state === 'active' || connection.state === 'request'); - - if (req.errors) { - res.status(422); - } - - navLinkService.setCustomNavLinkActive('/proofs/request'); - - res.render('request_proof', { - navLinks: navLinkService.getNavLinks(), - customNavLinks: navLinkService.getCustomNavLinks(), - connections, - errors: req.errors || null, - error_keys: (req.errors || []).map(error => error.param), - proof: { - proof: (req.errors && req.proof.proof_object) || JSON.stringify(proofJSON, null, 4), - connectionId: req.errors && req.proof.connection_id, - credentialDefinitionId: req.errors && req.proof.credential_definition_id, - } - }); + const agentService = require("../services/AgentService"); + const allConnections = await agentService.getConnections(); + const connections = allConnections.filter( + (connection) => + connection.state === "active" || connection.state === "request" + ); + + if (req.errors) { + res.status(422); + } + + navLinkService.setCustomNavLinkActive("/proofs/request"); + + res.render("request_proof", { + navLinks: navLinkService.getNavLinks(), + customNavLinks: navLinkService.getCustomNavLinks(), + connections, + errors: req.errors || null, + error_keys: (req.errors || []).map((error) => error.param), + proof: { + proof: + (req.errors && req.proof.proof_object) || + JSON.stringify(proofJSON, null, 4), + connectionId: req.errors && req.proof.connection_id, + credentialDefinitionId: req.errors && req.proof.credential_definition_id, + }, + }); } async function handleRequestProofPost(req, res, next) { - const agentService = require('../services/AgentService'); + const agentService = require("../services/AgentService"); - const errors = validationResult(req); + const errors = validationResult(req); - if (!errors.isEmpty()) { - req.errors = errors.array(); - req.proof = req.body; - return next(); - } + if (!errors.isEmpty()) { + req.errors = errors.array(); + req.proof = req.body; + return next(); + } - await agentService.sendProofRequest(req.body.proof_object); - res.status(201).redirect('/proofs'); + await agentService.sendProofRequest(req.body.proof_object); + res.status(201).redirect("/proofs"); } -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/services/AgentService.js b/AliceFaberAcmeDemo/controllers/acme-controller/services/AgentService.js index ccf1a61..4a61e2a 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/services/AgentService.js +++ b/AliceFaberAcmeDemo/controllers/acme-controller/services/AgentService.js @@ -1,159 +1,143 @@ -const http = require('http'); +const http = require("http"); +const axios = require("axios"); -const hostname = process.env.ACME_AGENT_HOST || 'localhost'; +const hostname = process.env.ACME_AGENT_HOST || "host.docker.internal"; const port = 8041; -console.log('Agent is running on: ' + `http://${hostname}:${port}`); - -function httpAsync(options, body) { - return new Promise(function (resolve, reject) { - const req = http.request(options, (res) => { - const { statusCode } = res; - const contentType = res.headers['content-type']; - - let e; - if (statusCode !== 200) { - e = new Error('Request Failed.\n' + `Status Code: ${statusCode}`); - } else if (!/^application\/json/.test(contentType)) { - e = new Error('Invalid content-type.\n' + `Expected application/json but received ${contentType}`); - } - if (e) { - // Consume response data to free up memory - res.resume(); - return reject(e); - } - - res.setEncoding('utf8'); - let rawData = ''; - res.on('data', (chunk) => { rawData += chunk; }); - res.on('end', () => { - try { - const parsedData = JSON.parse(rawData); - return resolve(parsedData); - } catch (e) { - return reject(e); - } - }); - }).on('error', (e) => { - return reject(e); - }); - - if (body) { - req.write(body || ''); - } - - req.end(); - }); -} +console.log("Agent is running on: " + `http://${hostname}:${port}`); class AgentService { - async getStatus() { - try { - const response = await httpAsync({ - hostname: hostname, - port: port, - path: '/status', - method: 'GET' - }); - return response; - } catch (error) { - console.error(error); - return null; - } + async getStatus() { + try { + const response = await axios.get(`http://${hostname}:${port}/status`); + return response.data; + } catch (error) { + console.error(error); + return null; } + } - async getConnections() { - try { - const response = await httpAsync({ - hostname: hostname, - port: port, - path: '/connections', - method: 'GET' - }); - return response.results; - } catch (error) { - console.error(error); - return []; - } + async getConnections() { + try { + const response = await axios.get( + `http://${hostname}:${port}/connections` + ); + return response.data.results; + } catch (error) { + console.error(error); + return []; } + } - async createInvitation() { - try { - const response = await httpAsync({ - hostname: hostname, - port: port, - path: '/connections/create-invitation', - method: 'POST' - }); - return response; - } catch (error) { - console.error(error); - return {}; + async createInvitation() { + try { + // Define the request payload + const invitationRequest = { + handshake_protocols: ["https://didcomm.org/didexchange/1.1"], + }; + + // Make the POST request using axios + const response = await axios.post( + `http://${hostname}:${port}/out-of-band/create-invitation`, + invitationRequest, + { + headers: { + "Content-Type": "application/json", + }, } + ); + + // Log the invitation data + console.log("Invitation created successfully:", response.data); + + return response.data; + } catch (error) { + // Log any errors + console.error("Error creating invitation:", error.message); + return {}; } + } - async receiveInvitation(invitation) { - try { - const response = await httpAsync({ - hostname: hostname, - port: port, - path: '/connections/receive-invitation', - method: 'POST' - }, invitation); - return response; - } catch (error) { - console.error(error); - return; - } + async receiveInvitation(invitation) { + try { + // Step 1: Receive the invitation + const receiveInvitationUrl = `http://${hostname}:${port}/out-of-band/receive-invitation`; + console.log( + "Sending request to /out-of-band/receive-invitation with URL:", + receiveInvitationUrl + ); + console.log("Request body:", JSON.stringify(invitation)); + + const response = await axios.post(receiveInvitationUrl, invitation, { + headers: { + "Content-Type": "application/json", + }, + }); + + console.log( + "API response from /out-of-band/receive-invitation:", + response.data + ); + + return response.data; // Return only the response from receive-invitation + } catch (error) { + console.error("Error in receiveInvitation:", error.message); + if (error.response) { + console.error("Response data:", error.response.data); + console.error("Response status:", error.response.status); + } + throw error; // Propagate the error to the caller } + } - async removeConnection(connectionId) { - try { - await httpAsync({ - hostname: hostname, - port: port, - path: `/connections/${connectionId}/remove`, - method: 'POST' - }); - } catch (error) { - console.error(error); - } finally { - return; - } + async removeConnection(connectionId) { + if (!connectionId) { + console.error("Must provide a connection ID"); + return; } - async getProofRequests() { - try { - const response = await httpAsync({ - hostname: hostname, - port: port, - path: '/present-proof/records', - method: 'GET' - }); - return response.results; - } catch (error) { - console.error(error); - return []; - } + console.log(`Removing connection with ID: ${connectionId}`); + + try { + await axios.delete( + `http://${hostname}:${port}/connections/${connectionId}` + ); + console.log(`Connection with ID ${connectionId} removed successfully`); + } catch (error) { + console.error( + `Failed to remove connection with ID ${connectionId}:`, + error + ); + } + } + + async getProofRequests() { + try { + const response = await axios.get( + `http://${hostname}:${port}/present-proof-2.0/records` + ); + return response.data.results; + } catch (error) { + console.error(error); + return []; } + } - async sendProofRequest(proofRequest) { - try { - await httpAsync({ - hostname: hostname, - port: port, - path: '/present-proof/send-request', - method: 'POST', - headers: { - 'Content-Type': 'application/json' - } - }, proofRequest); - } catch (error) { - console.error(error); - } finally { - return; + async sendProofRequest(proofRequest) { + try { + await axios.post( + `http://${hostname}:${port}/present-proof-2.0/send-request`, + proofRequest, + { + headers: { + "Content-Type": "application/json", + }, } + ); + } catch (error) { + console.error(error); } + } } -module.exports = new AgentService(); \ No newline at end of file +module.exports = new AgentService(); diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/views/accept_connection.hbs b/AliceFaberAcmeDemo/controllers/acme-controller/views/accept_connection.hbs index 4637d35..5431b33 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/views/accept_connection.hbs +++ b/AliceFaberAcmeDemo/controllers/acme-controller/views/accept_connection.hbs @@ -83,19 +83,28 @@ } } } - + function decode(e) { - try { - const value = e.target.value; - if (!value) { - return; - } - const url = new URL(value); - const invitationParam = url.searchParams.get('c_i'); - if (!invitationParam) { - throw new Error(); - } + try { + const value = e.target.value; + if (!value) { + return; + } + const url = new URL(value); + + // Try to get the 'c_i' parameter first + let invitationParam = url.searchParams.get('c_i'); + + // If 'c_i' is not found, try to get the 'oob' parameter + if (!invitationParam) { + invitationParam = url.searchParams.get('oob'); + } + + if (!invitationParam) { + throw new Error('No valid invitation parameter found in the URL.'); + } + // Decode the Base64-encoded invitation parameter objectInput.value = JSON.stringify(JSON.parse(atob(invitationParam)), null, 4); removeInvalidObjectErr(); } catch (error) { diff --git a/AliceFaberAcmeDemo/controllers/acme-controller/views/partials/proof/proof_card.hbs b/AliceFaberAcmeDemo/controllers/acme-controller/views/partials/proof/proof_card.hbs index ed40a7c..cb80c10 100644 --- a/AliceFaberAcmeDemo/controllers/acme-controller/views/partials/proof/proof_card.hbs +++ b/AliceFaberAcmeDemo/controllers/acme-controller/views/partials/proof/proof_card.hbs @@ -2,9 +2,9 @@
- {{ proof.presentation_request.name }} - {{#if proof.presentation_request.version}} -  ({{ proof.presentation_request.version }}) + {{ proof.by_format.pres_request.indy.name }} + {{#if proof.by_format.pres_request.indy.version}} +  ({{ proof.by_format.pres_request.indy.version }}) {{/if}}
@@ -17,11 +17,46 @@ {{ proof.created_at }}
+
Presentation Exchange ID:  -

{{ proof.presentation_exchange_id }}

+

{{ proof.pres_ex_id }}

+ + {{#if proof.by_format.pres_request.indy.requested_attributes}} +
+ Requested Attributes: +
    + {{#each proof.by_format.pres_request.indy.requested_attributes}} +
  • {{this.name}}
  • + {{/each}} +
+
+ {{/if}} + + {{#if proof.by_format.pres.indy.requested_proof.revealed_attrs}} +
+ Revealed Attributes: +
    + {{#each proof.by_format.pres.indy.requested_proof.revealed_attrs}} +
  • {{@key}}: {{this.raw}}
  • + {{/each}} +
+
+ {{/if}} + + {{#if proof.by_format.pres.indy.requested_proof.self_attested_attrs}} +
+ Self-Attested Attributes: +
    + {{#each proof.by_format.pres.indy.requested_proof.self_attested_attrs}} +
  • {{@key}}: {{this}}
  • + {{/each}} +
+
+ {{/if}} + {{#eq proof.verified 'true'}}
@@ -30,9 +65,28 @@   Verified
+ {{else}} + {{#if (or (eq proof.state 'done') (eq proof.state 'abandoned'))}} +
+ + + +   + Rejected +
+ {{else}} +
+ + + +   + Processing +
+ {{/if}} {{/eq}}
+