Skip to content

Commit 6920a61

Browse files
committed
Post certificate move fixes
1 parent 0bb65e4 commit 6920a61

File tree

8 files changed

+130
-58
lines changed

8 files changed

+130
-58
lines changed

src/backend/internal/certificate.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ const internalCertificate = {
2727
.then(() => {
2828
data.owner_user_id = access.token.get('attrs').id;
2929

30+
if (data.provider === 'letsencrypt') {
31+
data.nice_name = data.domain_names.sort().join(', ');
32+
}
33+
3034
return certificateModel
3135
.query()
3236
.omit(omissions())
@@ -246,6 +250,22 @@ const internalCertificate = {
246250
});
247251
},
248252

253+
/**
254+
* @param {Access} access
255+
* @param {Object} data
256+
* @param {Array} data.domain_names
257+
* @param {String} data.meta.letsencrypt_email
258+
* @param {Boolean} data.meta.letsencrypt_agree
259+
* @returns {Promise}
260+
*/
261+
createQuickCertificate: (access, data) => {
262+
return internalCertificate.create(access, {
263+
provider: 'letsencrypt',
264+
domain_names: data.domain_names,
265+
meta: data.meta
266+
});
267+
},
268+
249269
/**
250270
* Validates that the certs provided are good.
251271
* No access required here, nothing is changed or stored.

src/backend/internal/proxy-host.js

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
'use strict';
22

3-
const _ = require('lodash');
4-
const error = require('../lib/error');
5-
const proxyHostModel = require('../models/proxy_host');
6-
const internalHost = require('./host');
7-
const internalNginx = require('./nginx');
8-
const internalAuditLog = require('./audit-log');
3+
const _ = require('lodash');
4+
const error = require('../lib/error');
5+
const proxyHostModel = require('../models/proxy_host');
6+
const internalHost = require('./host');
7+
const internalNginx = require('./nginx');
8+
const internalAuditLog = require('./audit-log');
9+
const internalCertificate = require('./certificate');
910

1011
function omissions () {
1112
return ['is_deleted'];
@@ -19,6 +20,12 @@ const internalProxyHost = {
1920
* @returns {Promise}
2021
*/
2122
create: (access, data) => {
23+
let create_certificate = data.certificate_id === 'new';
24+
25+
if (create_certificate) {
26+
delete data.certificate_id;
27+
}
28+
2229
return access.can('proxy_hosts:create', data)
2330
.then(access_data => {
2431
// Get a list of the ___domain names and check each of them against existing records
@@ -46,14 +53,39 @@ const internalProxyHost = {
4653
.omit(omissions())
4754
.insertAndFetch(data);
4855
})
56+
.then(row => {
57+
if (create_certificate) {
58+
return internalCertificate.createQuickCertificate(access, data)
59+
.then(cert => {
60+
// update host with cert id
61+
return internalProxyHost.update(access, {
62+
id: row.id,
63+
certificate_id: cert.id
64+
});
65+
})
66+
.then(() => {
67+
return row;
68+
});
69+
} else {
70+
return row;
71+
}
72+
})
73+
.then(row => {
74+
// re-fetch with cert
75+
return internalProxyHost.get(access, {
76+
id: row.id,
77+
expand: ['certificate', 'owner']
78+
});
79+
})
4980
.then(row => {
5081
// Configure nginx
5182
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
5283
.then(() => {
53-
return internalProxyHost.get(access, {id: row.id, expand: ['owner']});
84+
return row;
5485
});
5586
})
5687
.then(row => {
88+
// Audit log
5789
data.meta = _.assign({}, data.meta || {}, row.meta);
5890

5991
// Add to audit log
@@ -78,6 +110,12 @@ const internalProxyHost = {
78110
* @return {Promise}
79111
*/
80112
update: (access, data) => {
113+
let create_certificate = data.certificate_id === 'new';
114+
115+
if (create_certificate) {
116+
delete data.certificate_id;
117+
}
118+
81119
return access.can('proxy_hosts:update', data.id)
82120
.then(access_data => {
83121
// Get a list of the ___domain names and check each of them against existing records
@@ -107,13 +145,28 @@ const internalProxyHost = {
107145
throw new error.InternalValidationError('Proxy Host could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id);
108146
}
109147

148+
if (create_certificate) {
149+
return internalCertificate.createQuickCertificate(access, {
150+
domain_names: data.domain_names || row.domain_names,
151+
meta: _.assign({}, row.meta, data.meta)
152+
})
153+
.then(cert => {
154+
// update host with cert id
155+
data.certificate_id = cert.id;
156+
})
157+
.then(() => {
158+
return row;
159+
});
160+
} else {
161+
return row;
162+
}
163+
})
164+
.then(row => {
110165
return proxyHostModel
111166
.query()
112-
.omit(omissions())
113-
.patchAndFetchById(row.id, data)
167+
.where({id: data.id})
168+
.patch(data)
114169
.then(saved_row => {
115-
saved_row.meta = internalHost.cleanMeta(saved_row.meta);
116-
117170
// Add to audit log
118171
return internalAuditLog.add(access, {
119172
action: 'updated',
@@ -125,6 +178,19 @@ const internalProxyHost = {
125178
return _.omit(saved_row, omissions());
126179
});
127180
});
181+
})
182+
.then(() => {
183+
return internalProxyHost.get(access, {
184+
id: data.id,
185+
expand: ['owner', 'certificate']
186+
})
187+
.then(row => {
188+
// Configure nginx
189+
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
190+
.then(() => {
191+
return _.omit(row, omissions());
192+
});
193+
})
128194
});
129195
},
130196

@@ -167,7 +233,6 @@ const internalProxyHost = {
167233
})
168234
.then(row => {
169235
if (row) {
170-
row.meta = internalHost.cleanMeta(row.meta);
171236
return _.omit(row, omissions());
172237
} else {
173238
throw new error.ItemNotFoundError(data.id);
@@ -207,8 +272,6 @@ const internalProxyHost = {
207272
})
208273
.then(() => {
209274
// Add to audit log
210-
row.meta = internalHost.cleanMeta(row.meta);
211-
212275
return internalAuditLog.add(access, {
213276
action: 'deleted',
214277
object_type: 'proxy-host',
@@ -257,13 +320,6 @@ const internalProxyHost = {
257320
}
258321

259322
return query;
260-
})
261-
.then(rows => {
262-
rows.map(row => {
263-
row.meta = internalHost.cleanMeta(row.meta);
264-
});
265-
266-
return rows;
267323
});
268324
},
269325

src/backend/schema/definitions.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,20 @@
116116
"type": "integer",
117117
"minimum": 1
118118
},
119+
"certificate_id": {
120+
"description": "Certificate ID",
121+
"example": 1234,
122+
"anyOf": [
123+
{
124+
"type": "integer",
125+
"minimum": 0
126+
},
127+
{
128+
"type": "string",
129+
"pattern": "^new$"
130+
}
131+
]
132+
},
119133
"access_list_id": {
120134
"description": "Access List ID",
121135
"example": 1234,

src/backend/schema/endpoints/proxy-hosts.json

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,12 @@
2727
"minimum": 1,
2828
"maximum": 65535
2929
},
30-
"ssl_enabled": {
31-
"$ref": "../definitions.json#/definitions/ssl_enabled"
30+
"certificate_id": {
31+
"$ref": "../definitions.json#/definitions/certificate_id"
3232
},
3333
"ssl_forced": {
3434
"$ref": "../definitions.json#/definitions/ssl_forced"
3535
},
36-
"ssl_provider": {
37-
"$ref": "../definitions.json#/definitions/ssl_provider"
38-
},
3936
"block_exploits": {
4037
"$ref": "../definitions.json#/definitions/block_exploits"
4138
},
@@ -46,17 +43,7 @@
4643
"$ref": "../definitions.json#/definitions/access_list_id"
4744
},
4845
"meta": {
49-
"type": "object",
50-
"additionalProperties": false,
51-
"properties": {
52-
"letsencrypt_email": {
53-
"type": "string",
54-
"format": "email"
55-
},
56-
"letsencrypt_agree": {
57-
"type": "boolean"
58-
}
59-
}
46+
"type": "object"
6047
}
6148
},
6249
"properties": {
@@ -78,15 +65,12 @@
7865
"forward_port": {
7966
"$ref": "#/definitions/forward_port"
8067
},
81-
"ssl_enabled": {
82-
"$ref": "#/definitions/ssl_enabled"
68+
"certificate_id": {
69+
"$ref": "#/definitions/certificate_id"
8370
},
8471
"ssl_forced": {
8572
"$ref": "#/definitions/ssl_forced"
8673
},
87-
"ssl_provider": {
88-
"$ref": "#/definitions/ssl_provider"
89-
},
9074
"block_exploits": {
9175
"$ref": "#/definitions/block_exploits"
9276
},
@@ -146,15 +130,12 @@
146130
"forward_port": {
147131
"$ref": "#/definitions/forward_port"
148132
},
149-
"ssl_enabled": {
150-
"$ref": "#/definitions/ssl_enabled"
133+
"certificate_id": {
134+
"$ref": "#/definitions/certificate_id"
151135
},
152136
"ssl_forced": {
153137
"$ref": "#/definitions/ssl_forced"
154138
},
155-
"ssl_provider": {
156-
"$ref": "#/definitions/ssl_provider"
157-
},
158139
"block_exploits": {
159140
"$ref": "#/definitions/block_exploits"
160141
},
@@ -198,15 +179,12 @@
198179
"forward_port": {
199180
"$ref": "#/definitions/forward_port"
200181
},
201-
"ssl_enabled": {
202-
"$ref": "#/definitions/ssl_enabled"
182+
"certificate_id": {
183+
"$ref": "#/definitions/certificate_id"
203184
},
204185
"ssl_forced": {
205186
"$ref": "#/definitions/ssl_forced"
206187
},
207-
"ssl_provider": {
208-
"$ref": "#/definitions/ssl_provider"
209-
},
210188
"block_exploits": {
211189
"$ref": "#/definitions/block_exploits"
212190
},

src/frontend/js/app/nginx/proxy/delete.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<div class="row">
99
<div class="col-sm-12 col-md-12">
1010
<%= i18n('proxy-hosts', 'delete-confirm', {domains: domain_names.join(', ')}) %>
11-
<% if (ssl_enabled) { %>
11+
<% if (certificate_id) { %>
1212
<br><br>
1313
<%- i18n('ssl', 'delete-ssl') %>
1414
<% } %>

src/frontend/js/app/nginx/proxy/form.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@
8787
<div class="col-sm-12 col-md-12 letsencrypt">
8888
<div class="form-group">
8989
<label class="form-label"><%- i18n('ssl', 'letsencrypt-email') %> <span class="form-required">*</span></label>
90-
<input name="meta[letsencrypt_email]" type="email" class="form-control" placeholder="" value="<%- getLetsencryptEmail() %>" required>
90+
<input name="meta[letsencrypt_email]" type="email" class="form-control" placeholder="" value="<%- getLetsencryptEmail() %>" required disabled>
9191
</div>
9292
</div>
9393
<div class="col-sm-12 col-md-12 letsencrypt">
9494
<div class="form-group">
9595
<label class="custom-switch">
96-
<input type="checkbox" class="custom-switch-input" name="meta[letsencrypt_agree]" value="1" required>
96+
<input type="checkbox" class="custom-switch-input" name="meta[letsencrypt_agree]" value="1" required disabled>
9797
<span class="custom-switch-indicator"></span>
9898
<span class="custom-switch-description"><%= i18n('ssl', 'letsencrypt-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
9999
</label>

src/frontend/js/app/nginx/proxy/form.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module.exports = Mn.View.extend({
2424
cancel: 'button.cancel',
2525
save: 'button.save',
2626
certificate_select: 'select[name="certificate_id"]',
27-
ssl_options: '#ssl-options input',
27+
ssl_forced: 'input[name="ssl_forced"]',
2828
letsencrypt: '.letsencrypt'
2929
},
3030

@@ -38,7 +38,7 @@ module.exports = Mn.View.extend({
3838
}
3939

4040
let enabled = id === 'new' || parseInt(id, 10) > 0;
41-
this.ui.ssl_options.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5);
41+
this.ui.ssl_forced.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5);
4242
},
4343

4444
'click @ui.save': function (e) {
@@ -57,6 +57,10 @@ module.exports = Mn.View.extend({
5757
data.block_exploits = !!data.block_exploits;
5858
data.caching_enabled = !!data.caching_enabled;
5959

60+
if (typeof data.ssl_forced !== 'undefined' && data.ssl_forced === '1') {
61+
data.ssl_forced = true;
62+
}
63+
6064
if (typeof data.domain_names === 'string' && data.domain_names) {
6165
data.domain_names = data.domain_names.split(',');
6266
}

src/frontend/js/app/nginx/proxy/list/item.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<div class="text-monospace"><%- forward_ip %>:<%- forward_port %></div>
2121
</td>
2222
<td>
23-
<div><%- certificate ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %></div>
23+
<div><%- certificate && certificate_id ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %></div>
2424
</td>
2525
<td>
2626
<div><%- access_list_id ? access_list.name : i18n('str', 'public') %></div>

0 commit comments

Comments
 (0)