mirror of
https://github.com/xiaoxinpro/nginx-proxy-manager-zh.git
synced 2025-02-09 13:08:14 -05:00
Add certificate to streams database model
This commit is contained in:
parent
ee4250d770
commit
cd80cc8e4d
@ -1,10 +1,12 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const error = require('../lib/error');
|
const error = require('../lib/error');
|
||||||
const utils = require('../lib/utils');
|
const utils = require('../lib/utils');
|
||||||
const streamModel = require('../models/stream');
|
const streamModel = require('../models/stream');
|
||||||
const internalNginx = require('./nginx');
|
const internalNginx = require('./nginx');
|
||||||
const internalAuditLog = require('./audit-log');
|
const internalAuditLog = require('./audit-log');
|
||||||
const {castJsonIfNeed} = require('../lib/helpers');
|
const internalCertificate = require('./certificate');
|
||||||
|
const internalHost = require('./host');
|
||||||
|
const {castJsonIfNeed} = require('../lib/helpers');
|
||||||
|
|
||||||
function omissions () {
|
function omissions () {
|
||||||
return ['is_deleted'];
|
return ['is_deleted'];
|
||||||
@ -18,6 +20,12 @@ const internalStream = {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
create: (access, data) => {
|
create: (access, data) => {
|
||||||
|
let create_certificate = data.certificate_id === 'new';
|
||||||
|
|
||||||
|
if (create_certificate) {
|
||||||
|
delete data.certificate_id;
|
||||||
|
}
|
||||||
|
|
||||||
return access.can('streams:create', data)
|
return access.can('streams:create', data)
|
||||||
.then((/*access_data*/) => {
|
.then((/*access_data*/) => {
|
||||||
// TODO: At this point the existing ports should have been checked
|
// TODO: At this point the existing ports should have been checked
|
||||||
@ -27,11 +35,40 @@ const internalStream = {
|
|||||||
data.meta = {};
|
data.meta = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let data_no_domains = structuredClone(data);
|
||||||
|
|
||||||
|
// streams aren't routed by domain name so don't store domain names in the DB
|
||||||
|
delete data_no_domains.domain_names;
|
||||||
|
|
||||||
return streamModel
|
return streamModel
|
||||||
.query()
|
.query()
|
||||||
.insertAndFetch(data)
|
.insertAndFetch(data_no_domains)
|
||||||
.then(utils.omitRow(omissions()));
|
.then(utils.omitRow(omissions()));
|
||||||
})
|
})
|
||||||
|
.then((row) => {
|
||||||
|
if (create_certificate) {
|
||||||
|
return internalCertificate.createQuickCertificate(access, data)
|
||||||
|
.then((cert) => {
|
||||||
|
// update host with cert id
|
||||||
|
return internalStream.update(access, {
|
||||||
|
id: row.id,
|
||||||
|
certificate_id: cert.id
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return row;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((row) => {
|
||||||
|
// re-fetch with cert
|
||||||
|
return internalStream.get(access, {
|
||||||
|
id: row.id,
|
||||||
|
expand: ['certificate', 'owner']
|
||||||
|
});
|
||||||
|
})
|
||||||
.then((row) => {
|
.then((row) => {
|
||||||
// Configure nginx
|
// Configure nginx
|
||||||
return internalNginx.configure(streamModel, 'stream', row)
|
return internalNginx.configure(streamModel, 'stream', row)
|
||||||
@ -60,6 +97,12 @@ const internalStream = {
|
|||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
update: (access, data) => {
|
update: (access, data) => {
|
||||||
|
let create_certificate = data.certificate_id === 'new';
|
||||||
|
|
||||||
|
if (create_certificate) {
|
||||||
|
delete data.certificate_id;
|
||||||
|
}
|
||||||
|
|
||||||
return access.can('streams:update', data.id)
|
return access.can('streams:update', data.id)
|
||||||
.then((/*access_data*/) => {
|
.then((/*access_data*/) => {
|
||||||
// TODO: at this point the existing streams should have been checked
|
// TODO: at this point the existing streams should have been checked
|
||||||
@ -71,6 +114,28 @@ const internalStream = {
|
|||||||
throw new error.InternalValidationError('Stream could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id);
|
throw new error.InternalValidationError('Stream could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (create_certificate) {
|
||||||
|
return internalCertificate.createQuickCertificate(access, {
|
||||||
|
domain_names: data.domain_names || row.domain_names,
|
||||||
|
meta: _.assign({}, row.meta, data.meta)
|
||||||
|
})
|
||||||
|
.then((cert) => {
|
||||||
|
// update host with cert id
|
||||||
|
data.certificate_id = cert.id;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return row;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((row) => {
|
||||||
|
// Add domain_names to the data in case it isn't there, so that the audit log renders correctly. The order is important here.
|
||||||
|
data = _.assign({}, {
|
||||||
|
domain_names: row.domain_names
|
||||||
|
}, data);
|
||||||
|
|
||||||
return streamModel
|
return streamModel
|
||||||
.query()
|
.query()
|
||||||
.patchAndFetchById(row.id, data)
|
.patchAndFetchById(row.id, data)
|
||||||
@ -115,7 +180,7 @@ const internalStream = {
|
|||||||
.query()
|
.query()
|
||||||
.where('is_deleted', 0)
|
.where('is_deleted', 0)
|
||||||
.andWhere('id', data.id)
|
.andWhere('id', data.id)
|
||||||
.allowGraph('[owner]')
|
.allowGraph('[owner,certificate]')
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (access_data.permission_visibility !== 'all') {
|
if (access_data.permission_visibility !== 'all') {
|
||||||
@ -132,6 +197,7 @@ const internalStream = {
|
|||||||
if (!row || !row.id) {
|
if (!row || !row.id) {
|
||||||
throw new error.ItemNotFoundError(data.id);
|
throw new error.ItemNotFoundError(data.id);
|
||||||
}
|
}
|
||||||
|
row = internalHost.cleanRowCertificateMeta(row);
|
||||||
// Custom omissions
|
// Custom omissions
|
||||||
if (typeof data.omit !== 'undefined' && data.omit !== null) {
|
if (typeof data.omit !== 'undefined' && data.omit !== null) {
|
||||||
row = _.omit(row, data.omit);
|
row = _.omit(row, data.omit);
|
||||||
@ -197,14 +263,14 @@ const internalStream = {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
return internalStream.get(access, {
|
return internalStream.get(access, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
expand: ['owner']
|
expand: ['certificate', 'owner']
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then((row) => {
|
.then((row) => {
|
||||||
if (!row || !row.id) {
|
if (!row || !row.id) {
|
||||||
throw new error.ItemNotFoundError(data.id);
|
throw new error.ItemNotFoundError(data.id);
|
||||||
} else if (row.enabled) {
|
} else if (row.enabled) {
|
||||||
throw new error.ValidationError('Host is already enabled');
|
throw new error.ValidationError('Stream is already enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
row.enabled = 1;
|
row.enabled = 1;
|
||||||
@ -250,7 +316,7 @@ const internalStream = {
|
|||||||
if (!row || !row.id) {
|
if (!row || !row.id) {
|
||||||
throw new error.ItemNotFoundError(data.id);
|
throw new error.ItemNotFoundError(data.id);
|
||||||
} else if (!row.enabled) {
|
} else if (!row.enabled) {
|
||||||
throw new error.ValidationError('Host is already disabled');
|
throw new error.ValidationError('Stream is already disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
row.enabled = 0;
|
row.enabled = 0;
|
||||||
@ -298,7 +364,7 @@ const internalStream = {
|
|||||||
.query()
|
.query()
|
||||||
.where('is_deleted', 0)
|
.where('is_deleted', 0)
|
||||||
.groupBy('id')
|
.groupBy('id')
|
||||||
.allowGraph('[owner]')
|
.allowGraph('[owner,certificate]')
|
||||||
.orderByRaw('CAST(incoming_port AS INTEGER) ASC');
|
.orderByRaw('CAST(incoming_port AS INTEGER) ASC');
|
||||||
|
|
||||||
if (access_data.permission_visibility !== 'all') {
|
if (access_data.permission_visibility !== 'all') {
|
||||||
@ -317,6 +383,13 @@ const internalStream = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return query.then(utils.omitRows(omissions()));
|
return query.then(utils.omitRows(omissions()));
|
||||||
|
})
|
||||||
|
.then((rows) => {
|
||||||
|
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
|
||||||
|
return internalHost.cleanAllRowsCertificateMeta(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
38
backend/migrations/20240427161436_stream_ssl.js
Normal file
38
backend/migrations/20240427161436_stream_ssl.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const migrate_name = 'stream_ssl';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('stream', (table) => {
|
||||||
|
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
logger.info('[' + migrate_name + '] stream Table altered');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Down...');
|
||||||
|
|
||||||
|
return knex.schema.table('stream', (table) => {
|
||||||
|
table.dropColumn('certificate_id');
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
logger.info('[' + migrate_name + '] stream Table altered');
|
||||||
|
});
|
||||||
|
};
|
@ -1,11 +1,9 @@
|
|||||||
// Objection Docs:
|
const Model = require('objection').Model;
|
||||||
// http://vincit.github.io/objection.js/
|
const db = require('../db');
|
||||||
|
const helpers = require('../lib/helpers');
|
||||||
const db = require('../db');
|
const User = require('./user');
|
||||||
const helpers = require('../lib/helpers');
|
const Certificate = require('./certificate');
|
||||||
const Model = require('objection').Model;
|
const now = require('./now_helper');
|
||||||
const User = require('./user');
|
|
||||||
const now = require('./now_helper');
|
|
||||||
|
|
||||||
Model.knex(db);
|
Model.knex(db);
|
||||||
|
|
||||||
@ -64,6 +62,17 @@ class Stream extends Model {
|
|||||||
modify: function (qb) {
|
modify: function (qb) {
|
||||||
qb.where('user.is_deleted', 0);
|
qb.where('user.is_deleted', 0);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
certificate: {
|
||||||
|
relation: Model.HasOneRelation,
|
||||||
|
modelClass: Certificate,
|
||||||
|
join: {
|
||||||
|
from: 'stream.certificate_id',
|
||||||
|
to: 'certificate.id'
|
||||||
|
},
|
||||||
|
modify: function (qb) {
|
||||||
|
qb.where('certificate.is_deleted', 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ module.exports = Mn.View.extend({
|
|||||||
onRender: function () {
|
onRender: function () {
|
||||||
let view = this;
|
let view = this;
|
||||||
|
|
||||||
view.fetch(['owner'])
|
view.fetch(['owner', 'certificate'])
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (!view.isDestroyed()) {
|
if (!view.isDestroyed()) {
|
||||||
if (response && response.length) {
|
if (response && response.length) {
|
||||||
|
Loading…
Reference in New Issue
Block a user