LOCATION_TYPE can move into location.js
This commit is contained in:
+37
-49
@@ -132,17 +132,6 @@ exports = module.exports = {
|
||||
HEALTH_ERROR: 'error',
|
||||
HEALTH_DEAD: 'dead',
|
||||
|
||||
// subdomain table types
|
||||
LOCATION_TYPE_PRIMARY: 'primary',
|
||||
LOCATION_TYPE_SECONDARY: 'secondary',
|
||||
LOCATION_TYPE_REDIRECT: 'redirect',
|
||||
LOCATION_TYPE_ALIAS: 'alias',
|
||||
|
||||
// should probably be in table as well
|
||||
LOCATION_TYPE_DASHBOARD: 'dashboard',
|
||||
LOCATION_TYPE_MAIL: 'mail',
|
||||
LOCATION_TYPE_DIRECTORY_SERVER: 'directoryserver',
|
||||
|
||||
// exported for testing
|
||||
_validatePortBindings: validatePortBindings,
|
||||
_validateAccessRestriction: validateAccessRestriction,
|
||||
@@ -168,6 +157,7 @@ const appstore = require('./appstore.js'),
|
||||
domains = require('./domains.js'),
|
||||
eventlog = require('./eventlog.js'),
|
||||
fs = require('fs'),
|
||||
Location = require('./location.js'),
|
||||
logs = require('./logs.js'),
|
||||
mail = require('./mail.js'),
|
||||
manifestFormat = require('cloudron-manifestformat'),
|
||||
@@ -715,15 +705,15 @@ function postProcess(result) {
|
||||
for (let i = 0; i < subdomainTypes.length; i++) {
|
||||
const subdomain = subdomains[i], domain = domains[i], certificate = safe.JSON.parse(subdomainCertificateJsons[i]);
|
||||
|
||||
if (subdomainTypes[i] === exports.LOCATION_TYPE_PRIMARY) {
|
||||
if (subdomainTypes[i] === Location.TYPE_PRIMARY) {
|
||||
result.subdomain = subdomain;
|
||||
result.domain = domain;
|
||||
result.certificate = certificate;
|
||||
} else if (subdomainTypes[i] === exports.LOCATION_TYPE_SECONDARY) {
|
||||
} else if (subdomainTypes[i] === Location.TYPE_SECONDARY) {
|
||||
result.secondaryDomains.push({ domain, subdomain, certificate, environmentVariable: subdomainEnvironmentVariables[i] });
|
||||
} else if (subdomainTypes[i] === exports.LOCATION_TYPE_REDIRECT) {
|
||||
} else if (subdomainTypes[i] === Location.TYPE_REDIRECT) {
|
||||
result.redirectDomains.push({ domain, subdomain, certificate });
|
||||
} else if (subdomainTypes[i] === exports.LOCATION_TYPE_ALIAS) {
|
||||
} else if (subdomainTypes[i] === Location.TYPE_ALIAS) {
|
||||
result.aliasDomains.push({ domain, subdomain, certificate });
|
||||
}
|
||||
}
|
||||
@@ -852,7 +842,7 @@ async function add(id, appStoreId, manifest, subdomain, domain, portBindings, da
|
||||
|
||||
queries.push({
|
||||
query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)',
|
||||
args: [ id, domain, subdomain, exports.LOCATION_TYPE_PRIMARY ]
|
||||
args: [ id, domain, subdomain, Location.TYPE_PRIMARY ]
|
||||
});
|
||||
|
||||
Object.keys(portBindings).forEach(function (env) {
|
||||
@@ -873,7 +863,7 @@ async function add(id, appStoreId, manifest, subdomain, domain, portBindings, da
|
||||
data.secondaryDomains.forEach(function (d) {
|
||||
queries.push({
|
||||
query: 'INSERT INTO locations (appId, domain, subdomain, type, environmentVariable) VALUES (?, ?, ?, ?, ?)',
|
||||
args: [ id, d.domain, d.subdomain, exports.LOCATION_TYPE_SECONDARY, d.environmentVariable ]
|
||||
args: [ id, d.domain, d.subdomain, Location.TYPE_SECONDARY, d.environmentVariable ]
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -882,7 +872,7 @@ async function add(id, appStoreId, manifest, subdomain, domain, portBindings, da
|
||||
data.redirectDomains.forEach(function (d) {
|
||||
queries.push({
|
||||
query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)',
|
||||
args: [ id, d.domain, d.subdomain, exports.LOCATION_TYPE_REDIRECT ]
|
||||
args: [ id, d.domain, d.subdomain, Location.TYPE_REDIRECT ]
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -891,7 +881,7 @@ async function add(id, appStoreId, manifest, subdomain, domain, portBindings, da
|
||||
data.aliasDomains.forEach(function (d) {
|
||||
queries.push({
|
||||
query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)',
|
||||
args: [ id, d.domain, d.subdomain, exports.LOCATION_TYPE_ALIAS ]
|
||||
args: [ id, d.domain, d.subdomain, Location.TYPE_ALIAS ]
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -947,23 +937,23 @@ async function updateWithConstraints(id, app, constraints) {
|
||||
|
||||
if ('subdomain' in app && 'domain' in app) { // must be updated together as they are unique together
|
||||
queries.push({ query: 'DELETE FROM locations WHERE appId = ?', args: [ id ]}); // all locations of an app must be updated together
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)', args: [ id, app.domain, app.subdomain, exports.LOCATION_TYPE_PRIMARY ]});
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)', args: [ id, app.domain, app.subdomain, Location.TYPE_PRIMARY ]});
|
||||
|
||||
if ('secondaryDomains' in app) {
|
||||
app.secondaryDomains.forEach(function (d) {
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type, environmentVariable) VALUES (?, ?, ?, ?, ?)', args: [ id, d.domain, d.subdomain, exports.LOCATION_TYPE_SECONDARY, d.environmentVariable ]});
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type, environmentVariable) VALUES (?, ?, ?, ?, ?)', args: [ id, d.domain, d.subdomain, Location.TYPE_SECONDARY, d.environmentVariable ]});
|
||||
});
|
||||
}
|
||||
|
||||
if ('redirectDomains' in app) {
|
||||
app.redirectDomains.forEach(function (d) {
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)', args: [ id, d.domain, d.subdomain, exports.LOCATION_TYPE_REDIRECT ]});
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)', args: [ id, d.domain, d.subdomain, Location.TYPE_REDIRECT ]});
|
||||
});
|
||||
}
|
||||
|
||||
if ('aliasDomains' in app) {
|
||||
app.aliasDomains.forEach(function (d) {
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)', args: [ id, d.domain, d.subdomain, exports.LOCATION_TYPE_ALIAS ]});
|
||||
queries.push({ query: 'INSERT INTO locations (appId, domain, subdomain, type) VALUES (?, ?, ?, ?)', args: [ id, d.domain, d.subdomain, Location.TYPE_ALIAS ]});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1261,19 +1251,19 @@ async function validateLocations(locations) {
|
||||
constants.IMAP_SUBDOMAIN
|
||||
];
|
||||
|
||||
const { fqdn:dashboardFqdn } = await dashboard.getLocation();
|
||||
const dashboardLocation = await dashboard.getLocation();
|
||||
for (const location of locations) {
|
||||
if (!(location.domain in domainObjectMap)) return new BoxError(BoxError.BAD_FIELD, `No such domain in ${location.type} location`);
|
||||
|
||||
let subdomain = location.subdomain;
|
||||
if (location.type === exports.LOCATION_TYPE_ALIAS && subdomain.startsWith('*')) {
|
||||
if (location.type === Location.TYPE_ALIAS && subdomain.startsWith('*')) {
|
||||
if (subdomain === '*') continue;
|
||||
subdomain = subdomain.replace(/^\*\./, ''); // remove *.
|
||||
}
|
||||
|
||||
if (RESERVED_SUBDOMAINS.indexOf(subdomain) !== -1) return new BoxError(BoxError.BAD_FIELD, `subdomain '${subdomain}' is reserved`);
|
||||
|
||||
if (dns.fqdn(subdomain, location.domain) === dashboardFqdn) return new BoxError(BoxError.BAD_FIELD, `subdomain '${subdomain}' is reserved for dashboard`);
|
||||
if (location.fqdn === dashboardLocation.fqdn) return new BoxError(BoxError.BAD_FIELD, `subdomain '${subdomain}' is reserved for dashboard`);
|
||||
|
||||
const error = dns.validateHostname(subdomain, location.domain);
|
||||
if (error) return new BoxError(BoxError.BAD_FIELD, `Bad ${location.type} location: ${error.message}`);
|
||||
@@ -1366,10 +1356,10 @@ async function install(data, auditSource) {
|
||||
icon = Buffer.from(icon, 'base64');
|
||||
}
|
||||
|
||||
const locations = [{ subdomain, domain, type: exports.LOCATION_TYPE_PRIMARY }]
|
||||
.concat(secondaryDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_SECONDARY })))
|
||||
.concat(redirectDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_REDIRECT })))
|
||||
.concat(aliasDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_ALIAS })));
|
||||
const locations = [new Location(subdomain, domain, Location.TYPE_PRIMARY)]
|
||||
.concat(secondaryDomains.map(sd => new Location(sd.subdomain, sd.domain, Location.TYPE_SECONDARY)))
|
||||
.concat(redirectDomains.map(rd => new Location(rd.subdomain, rd.domain, Location.TYPE_REDIRECT)))
|
||||
.concat(aliasDomains.map(ad => new Location(ad.subdomain, ad.domain, Location.TYPE_ALIAS)));
|
||||
|
||||
error = await validateLocations(locations);
|
||||
if (error) throw error;
|
||||
@@ -1808,6 +1798,16 @@ async function setReverseProxyConfig(app, reverseProxyConfig, auditSource) {
|
||||
await eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId, app, reverseProxyConfig });
|
||||
}
|
||||
|
||||
async function getLocation(subdomain, domain) {
|
||||
assert.strictEqual(typeof subdomain, 'string');
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
|
||||
const result = await database.query(`SELECT ${LOCATION_FIELDS} FROM locations WHERE subdomain=? AND domain=?`, [ subdomain, domain ]);
|
||||
if (result.length === 0) return null;
|
||||
|
||||
return new Location(subdomain, domain, result[0].type, safe.JSON.parse(result[0].certificateJson));
|
||||
}
|
||||
|
||||
async function setCertificate(app, data, auditSource) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert(data && typeof data === 'object');
|
||||
@@ -1827,23 +1827,11 @@ async function setCertificate(app, data, auditSource) {
|
||||
const result = await database.query('UPDATE locations SET certificateJson=? WHERE location=? AND domain=?', [ certificate ? JSON.stringify(certificate) : null, subdomain, domain ]);
|
||||
if (result.affectedRows === 0) throw new BoxError(BoxError.NOT_FOUND, 'Location not found');
|
||||
|
||||
const location = await getLocation(subdomain, domain); // fresh location object
|
||||
const location = await getLocation(subdomain, domain); // fresh location object with type
|
||||
await reverseProxy.setUserCertificate(app, location);
|
||||
await eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: app.id, app, subdomain, domain, cert });
|
||||
}
|
||||
|
||||
async function getLocation(subdomain, domain) {
|
||||
assert.strictEqual(typeof subdomain, 'string');
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
|
||||
const result = await database.query(`SELECT ${LOCATION_FIELDS} FROM locations WHERE subdomain=? AND domain=?`, [ subdomain, domain ]);
|
||||
if (result.length === 0) return null;
|
||||
|
||||
result[0].certificate = safe.JSON.parse(result[0].certificateJson);
|
||||
result[0].fqdn = dns.fqdn(subdomain, domain);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
async function setLocation(app, data, auditSource) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof data, 'object');
|
||||
@@ -1888,10 +1876,10 @@ async function setLocation(app, data, auditSource) {
|
||||
values.aliasDomains = data.aliasDomains;
|
||||
}
|
||||
|
||||
const locations = [{ subdomain: values.subdomain, domain: values.domain, type: exports.LOCATION_TYPE_PRIMARY }]
|
||||
.concat(values.secondaryDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_SECONDARY })))
|
||||
.concat(values.redirectDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_REDIRECT })))
|
||||
.concat(values.aliasDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_ALIAS })));
|
||||
const locations = [new Location(values.subdomain, values.domain, Location.TYPE_PRIMARY)]
|
||||
.concat(values.secondaryDomains.map(sd => new Location(sd.subdomain, sd.domain, Location.TYPE_SECONDARY)))
|
||||
.concat(values.redirectDomains.map(rd => new Location(rd.subdomain, rd.domain, Location.TYPE_REDIRECT)))
|
||||
.concat(values.aliasDomains.map(ad => new Location(ad.subdomain, ad.domain, Location.TYPE_ALIAS)));
|
||||
|
||||
error = await validateLocations(locations);
|
||||
if (error) throw error;
|
||||
@@ -2293,8 +2281,8 @@ async function clone(app, data, user, auditSource) {
|
||||
if (error) throw error;
|
||||
const secondaryDomains = translateSecondaryDomains(data.secondaryDomains || {});
|
||||
|
||||
const locations = [{ subdomain, domain, type: exports.LOCATION_TYPE_PRIMARY }]
|
||||
.concat(secondaryDomains.map(ad => Object.assign(ad, { type: exports.LOCATION_TYPE_SECONDARY })));
|
||||
const locations = [new Location(subdomain, domain, Location.TYPE_PRIMARY)]
|
||||
.concat(secondaryDomains.map(sd => new Location(sd.subdomain, sd.domain, Location.TYPE_SECONDARY)));
|
||||
|
||||
error = await validateLocations(locations);
|
||||
if (error) throw error;
|
||||
|
||||
Reference in New Issue
Block a user