Make certs upload to DB, reflect in UI, and use production letsencrypt when not dev environment variable

develop
Thomas Lynch 1 year ago
parent bf3c71b7df
commit 9841784340
  1. 5
      acme.js
  2. 25
      controllers/domains.js
  3. 13
      pages/domains.js
  4. 7
      router.js

@ -2,6 +2,7 @@
const fs = require('fs').promises;
const acme = require('acme-client');
const dev = process.env.NODE_ENV !== 'production';
/**
* Function used to satisfy an ACME challenge
@ -74,7 +75,7 @@ module.exports = {
init: async function() {
/* Init client */
module.exports.client = new acme.Client({
directoryUrl: acme.directory.letsencrypt.staging,
directoryUrl: dev ? acme.directory.letsencrypt.staging : acme.directory.letsencrypt.production,
accountKey: await acme.crypto.createPrivateKey()
});
},
@ -94,7 +95,7 @@ module.exports = {
});
/* Done */
const haproxyCert = `${cert.toString()}\n${key.toString()}`;
return { key, csr, cet, haproxyCert, date: new Date() };
return { key, csr, cert, haproxyCert, date: new Date() };
},
};

@ -40,8 +40,29 @@ exports.addDomain = async (req, res) => {
return dynamicResponse(req, res, 400, { error: 'Invalid input' });
}
//const { csr, key, cert, haproxyCert, date } = await acme.generate(req.body.domain);
//TODO: save (replace) in db with domain as key and username.
const { csr, key, cert, haproxyCert, date } = await acme.generate(req.body.domain);
const fd = new FormData();
fd.append('file_upload', new Blob([haproxyCert], { type: 'text/plain' }), `${req.body.domain}.pem`);
await fetch(`${res.locals.dataPlane.defaults.baseURL}/services/haproxy/storage/ssl_certificates`, {
method: 'POST',
headers: { 'authorization': res.locals.dataPlane.defaults.headers.authorization },
body: fd,
})
.then(res => res.text())
.then(res => console.log(res))
const account = await db.db.collection('certs')
.replaceOne({
_id: req.body.domain,
}, {
_id: req.body.domain,
username: res.locals.user.username,
csr, key, cert, haproxyCert,
date,
}, {
upsert: true,
});
//TODO: mongodb encryption
//TODO: make upload to all user clusters/servers
//TODO: add scheduled task to aggregate domains and upload certs to clusters of that username through dataplane
//TODO: make scheduled task also run this again for certs close to expiry and repeat ^

@ -54,6 +54,9 @@ export default function Domains(props) {
<td>
{d}
</td>
<td title={user.certsMap[d] || null}>
{user.certsMap[d] ? '🔐' : '-'}
</td>
</tr>
);
})
@ -76,6 +79,16 @@ export default function Domains(props) {
<table className="table table-bordered text-nowrap">
<tbody>
<tr className="align-middle">
<th className="col-1" />
<th>
Domain
</th>
<th>
HTTPS?
</th>
</tr>
{domainList}
{/* Add new domain form */}

@ -29,13 +29,16 @@ const testRouter = (server, app) => {
const fetchSession = async (req, res, next) => {
if (req.session.user) {
const account = await db.db.collection('accounts').findOne({_id:req.session.user});
const account = await db.db.collection('accounts').findOne({ _id: req.session.user });
if (account) {
const certs = await db.db.collection('certs').find({ username: account._id }, { projection: { _id: 1, username: 1, date: 1 }}).toArray();
const certsMap = (certs || []).reduce((acc, cert) => { acc[cert._id] = cert.date; return acc; }, {});
res.locals.user = {
username: account._id,
domains: account.domains,
clusters: account.clusters,
activeCluster: account.activeCluster,
certsMap,
};
return next();
}
@ -128,7 +131,7 @@ const testRouter = (server, app) => {
clusterRouter.post('/cluster', useSession, fetchSession, checkSession, hasCluster, csrfMiddleware, clustersController.setCluster);
clusterRouter.post('/cluster/add', useSession, fetchSession, checkSession, hasCluster, csrfMiddleware, clustersController.addCluster);
clusterRouter.post('/cluster/delete', useSession, fetchSession, checkSession, hasCluster, csrfMiddleware, clustersController.deleteClusters);
clusterRouter.post('/domain/add', useSession, fetchSession, checkSession, hasCluster, csrfMiddleware, domainsController.addDomain);
clusterRouter.post('/domain/add', useSession, fetchSession, checkSession, useHaproxy, hasCluster, csrfMiddleware, domainsController.addDomain);
clusterRouter.post('/domain/delete', useSession, fetchSession, checkSession, hasCluster, csrfMiddleware, domainsController.deleteDomain);
server.use('/forms', clusterRouter);

Loading…
Cancel
Save