Added PGP pubkey download button
This commit is contained in:
parent
4d56287583
commit
9c9af58eb5
5 changed files with 123 additions and 30 deletions
|
@ -12,7 +12,6 @@ let templates = new Map();
|
||||||
|
|
||||||
module.exports.transport = false;
|
module.exports.transport = false;
|
||||||
|
|
||||||
|
|
||||||
module.exports.update = () => {
|
module.exports.update = () => {
|
||||||
createMailer(() => false);
|
createMailer(() => false);
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,6 @@ body {
|
||||||
border-bottom: 1px solid #e5e5e5;
|
border-bottom: 1px solid #e5e5e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Make the masthead heading the same height as the navigation */
|
/* Make the masthead heading the same height as the navigation */
|
||||||
|
|
||||||
.header h3 {
|
.header h3 {
|
||||||
|
@ -94,3 +93,7 @@ body {
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gpg-text {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ let lists = require('../lib/models/lists');
|
||||||
let fields = require('../lib/models/fields');
|
let fields = require('../lib/models/fields');
|
||||||
let subscriptions = require('../lib/models/subscriptions');
|
let subscriptions = require('../lib/models/subscriptions');
|
||||||
let settings = require('../lib/models/settings');
|
let settings = require('../lib/models/settings');
|
||||||
|
let openpgp = require('openpgp');
|
||||||
|
|
||||||
router.get('/subscribe/:cid', (req, res, next) => {
|
router.get('/subscribe/:cid', (req, res, next) => {
|
||||||
subscriptions.subscribe(req.params.cid, req.ip, (err, subscription) => {
|
subscriptions.subscribe(req.params.cid, req.ip, (err, subscription) => {
|
||||||
|
@ -34,7 +35,7 @@ router.get('/subscribe/:cid', (req, res, next) => {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.list(['defaultHomepage', 'serviceUrl'], (err, configItems) => {
|
settings.list(['defaultHomepage', 'serviceUrl', 'pgpPrivateKey'], (err, configItems) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +44,8 @@ router.get('/subscribe/:cid', (req, res, next) => {
|
||||||
title: list.name,
|
title: list.name,
|
||||||
layout: 'subscription/layout',
|
layout: 'subscription/layout',
|
||||||
homepage: configItems.defaultHomepage || configItems.serviceUrl,
|
homepage: configItems.defaultHomepage || configItems.serviceUrl,
|
||||||
preferences: '/subscription/' + list.cid + '/manage/' + subscription.cid
|
preferences: '/subscription/' + list.cid + '/manage/' + subscription.cid,
|
||||||
|
hasPubkey: !!configItems.pgpPrivateKey
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -77,10 +79,16 @@ router.get('/:cid', passport.csrfProtection, (req, res, next) => {
|
||||||
data.customFields = fields.getRow(fieldList, data);
|
data.customFields = fields.getRow(fieldList, data);
|
||||||
data.useEditor = true;
|
data.useEditor = true;
|
||||||
|
|
||||||
|
settings.list(['pgpPrivateKey'], (err, configItems) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
data.hasPubkey = !!configItems.pgpPrivateKey;
|
||||||
res.render('subscription/subscribe', data);
|
res.render('subscription/subscribe', data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
router.get('/:cid/confirm-notice', (req, res, next) => {
|
router.get('/:cid/confirm-notice', (req, res, next) => {
|
||||||
lists.getByCid(req.params.cid, (err, list) => {
|
lists.getByCid(req.params.cid, (err, list) => {
|
||||||
|
@ -192,6 +200,18 @@ router.post('/:cid/subscribe', passport.parseForm, passport.csrfProtection, (req
|
||||||
return res.redirect('/subscription/' + encodeURIComponent(req.params.cid) + '?' + tools.queryParams(req.body));
|
return res.redirect('/subscription/' + encodeURIComponent(req.params.cid) + '?' + tools.queryParams(req.body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fields.list(list.id, (err, fieldList) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
let encryptionKeys = [];
|
||||||
|
fields.getRow(fieldList, data).forEach(field => {
|
||||||
|
if (field.type === 'gpg' && field.value) {
|
||||||
|
encryptionKeys.push(field.value.trim());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
settings.list(['defaultHomepage', 'defaultFrom', 'defaultAddress', 'serviceUrl'], (err, configItems) => {
|
settings.list(['defaultHomepage', 'defaultFrom', 'defaultAddress', 'serviceUrl'], (err, configItems) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
|
@ -208,7 +228,8 @@ router.post('/:cid/subscribe', passport.parseForm, passport.csrfProtection, (req
|
||||||
name: [].concat(data.firstName || []).concat(data.lastName || []).join(' '),
|
name: [].concat(data.firstName || []).concat(data.lastName || []).join(' '),
|
||||||
address: email
|
address: email
|
||||||
},
|
},
|
||||||
subject: list.name + ': Please Confirm Subscription'
|
subject: list.name + ': Please Confirm Subscription',
|
||||||
|
encryptionKeys
|
||||||
}, {
|
}, {
|
||||||
html: 'emails/confirm-html.hbs',
|
html: 'emails/confirm-html.hbs',
|
||||||
text: 'emails/confirm-text.hbs',
|
text: 'emails/confirm-text.hbs',
|
||||||
|
@ -226,6 +247,7 @@ router.post('/:cid/subscribe', passport.parseForm, passport.csrfProtection, (req
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
router.get('/:lcid/manage/:ucid', passport.csrfProtection, (req, res, next) => {
|
router.get('/:lcid/manage/:ucid', passport.csrfProtection, (req, res, next) => {
|
||||||
lists.getByCid(req.params.lcid, (err, list) => {
|
lists.getByCid(req.params.lcid, (err, list) => {
|
||||||
|
@ -261,11 +283,18 @@ router.get('/:lcid/manage/:ucid', passport.csrfProtection, (req, res, next) => {
|
||||||
|
|
||||||
subscription.useEditor = true;
|
subscription.useEditor = true;
|
||||||
|
|
||||||
|
settings.list(['pgpPrivateKey'], (err, configItems) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
subscription.hasPubkey = !!configItems.pgpPrivateKey;
|
||||||
|
|
||||||
res.render('subscription/manage', subscription);
|
res.render('subscription/manage', subscription);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
router.post('/:lcid/manage', passport.parseForm, passport.csrfProtection, (req, res, next) => {
|
router.post('/:lcid/manage', passport.parseForm, passport.csrfProtection, (req, res, next) => {
|
||||||
lists.getByCid(req.params.lcid, (err, list) => {
|
lists.getByCid(req.params.lcid, (err, list) => {
|
||||||
|
@ -343,4 +372,42 @@ router.post('/:lcid/unsubscribe', passport.parseForm, passport.csrfProtection, (
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post('/publickey', passport.parseForm, passport.csrfProtection, (req, res, next) => {
|
||||||
|
settings.list(['pgpPassphrase', 'pgpPrivateKey'], (err, configItems) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (!configItems.pgpPrivateKey) {
|
||||||
|
err = new Error('Public key is not set');
|
||||||
|
err.status = 404;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
let privKey;
|
||||||
|
try {
|
||||||
|
privKey = openpgp.key.readArmored(configItems.pgpPrivateKey).keys[0];
|
||||||
|
if (configItems.pgpPassphrase && !privKey.decrypt(configItems.pgpPassphrase)) {
|
||||||
|
privKey = false;
|
||||||
|
}
|
||||||
|
} catch (E) {
|
||||||
|
// just ignore if failed
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!privKey) {
|
||||||
|
err = new Error('Public key is not set');
|
||||||
|
err.status = 404;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pubkey = privKey.toPublic().armor();
|
||||||
|
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Type': 'application/octet-stream',
|
||||||
|
'Content-Disposition': 'attachment; filename=public.asc'
|
||||||
|
});
|
||||||
|
|
||||||
|
res.end(pubkey);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
<h2>Update your preferences</h2>
|
<h2>Update your preferences</h2>
|
||||||
|
|
||||||
|
{{#if hasPubkey}}
|
||||||
|
<form method="post" id="download-pubkey" action="/subscription/publickey">
|
||||||
|
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||||
|
<input type="hidden" name="cid" value="{{cid}}">
|
||||||
|
</form>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<form method="post" action="/subscription/{{lcid}}/manage">
|
<form method="post" action="/subscription/{{lcid}}/manage">
|
||||||
|
|
||||||
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||||
|
@ -42,7 +49,7 @@
|
||||||
|
|
||||||
{{#if typeGpg}}
|
{{#if typeGpg}}
|
||||||
<textarea class="form-control gpg-text" rows="3" name="{{column}}">{{value}}</textarea>
|
<textarea class="form-control gpg-text" rows="3" name="{{column}}">{{value}}</textarea>
|
||||||
<span class="help-block">Insert your GPG public key here to encrypt messages sent to your address</span>
|
<span class="help-block">(optional) Insert your GPG public key here to encrypt messages sent to your address</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if typeDateUs}}
|
{{#if typeDateUs}}
|
||||||
|
@ -104,6 +111,11 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
<div class="pull-right">
|
||||||
|
{{#if hasPubkey}}
|
||||||
|
<button type="submit" class="btn btn-default" form="download-pubkey"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Download our public GPG key</button>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
<button type="submit" class="btn btn-primary"><i class="glyphicon glyphicon-ok"></i> Update Profile</button> or <a href="/subscription/{{lcid}}/unsubscribe/{{cid}}">Unsubscribe</a>
|
<button type="submit" class="btn btn-primary"><i class="glyphicon glyphicon-ok"></i> Update Profile</button> or <a href="/subscription/{{lcid}}/unsubscribe/{{cid}}">Unsubscribe</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
{{#if hasPubkey}}
|
||||||
|
<form method="post" id="download-pubkey" action="/subscription/publickey">
|
||||||
|
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||||
|
<input type="hidden" name="cid" value="{{cid}}">
|
||||||
|
</form>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<form method="post" action="/subscription/{{cid}}/subscribe">
|
<form method="post" action="/subscription/{{cid}}/subscribe">
|
||||||
|
|
||||||
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||||
|
@ -39,7 +46,7 @@
|
||||||
|
|
||||||
{{#if typeGpg}}
|
{{#if typeGpg}}
|
||||||
<textarea class="form-control gpg-text" rows="3" name="{{column}}">{{value}}</textarea>
|
<textarea class="form-control gpg-text" rows="3" name="{{column}}">{{value}}</textarea>
|
||||||
<span class="help-block">Insert your GPG public key here to encrypt messages sent to your address</span>
|
<span class="help-block">(optional) Insert your GPG public key here to encrypt messages sent to your address</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if typeDateUs}}
|
{{#if typeDateUs}}
|
||||||
|
@ -101,6 +108,11 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
<div class="pull-right">
|
||||||
|
{{#if hasPubkey}}
|
||||||
|
<button type="submit" class="btn btn-default" form="download-pubkey"><span class="glyphicon glyphicon-cloud-download" aria-hidden="true"></span> Download our public GPG key</button>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
<button type="submit" class="btn btn-primary">Subscribe to list</button>
|
<button type="submit" class="btn btn-primary">Subscribe to list</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue