apps: unarchive can call add() on it's own
all this because the sso flag is not allowed with optionalSso :/
This commit is contained in:
+61
-41
@@ -1418,17 +1418,6 @@ async function install(data, auditSource) {
|
||||
error = validateEnv(env);
|
||||
if (error) throw error;
|
||||
|
||||
let reverseProxyConfig = null;
|
||||
if ('reverseProxyConfig' in data) {
|
||||
reverseProxyConfig = Object.assign({ robotsTxt: null, csp: null, hstsPreload: false }, data.reverseProxyConfig); // ensure fields
|
||||
|
||||
let error = validateCsp(reverseProxyConfig.csp);
|
||||
if (error) throw error;
|
||||
|
||||
error = validateRobotsTxt(reverseProxyConfig.robotsTxt);
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
if (constants.DEMO && constants.DEMO_BLOCKED_APPS.includes(appStoreId)) throw new BoxError(BoxError.BAD_FIELD, 'This app is blocked in the demo');
|
||||
|
||||
// sendmail is enabled by default
|
||||
@@ -1452,18 +1441,6 @@ async function install(data, auditSource) {
|
||||
|
||||
if (constants.DEMO && (await getCount() >= constants.DEMO_APP_LIMIT)) throw new BoxError(BoxError.BAD_STATE, 'Too many installed apps, please uninstall a few and try again');
|
||||
|
||||
let restoreConfig = null;
|
||||
|
||||
if ('archive' in data) { // install from archive. assume these are already validated
|
||||
assert(data.archive.iconBuffer === null || Buffer.isBuffer(data.archive.iconBuffer));
|
||||
assert.strictEqual(typeof data.archive.backupId, 'string');
|
||||
|
||||
icon = data.archive.iconBuffer; // install from archive
|
||||
const backup = await backups.get(data.archive.backupId);
|
||||
if (!backup) throw new BoxError(BoxError.BAD_FIELD, 'Backup not found in archive');
|
||||
restoreConfig = { remotePath: backup.remotePath, backupFormat: backup.format };
|
||||
}
|
||||
|
||||
const appId = uuid.v4();
|
||||
debug(`Installing app ${appId}`);
|
||||
|
||||
@@ -1492,7 +1469,6 @@ async function install(data, auditSource) {
|
||||
enableRedis,
|
||||
notes,
|
||||
crontab,
|
||||
reverseProxyConfig,
|
||||
runState: exports.RSTATE_RUNNING,
|
||||
installationState: exports.ISTATE_PENDING_INSTALL
|
||||
};
|
||||
@@ -1504,7 +1480,7 @@ async function install(data, auditSource) {
|
||||
await purchaseApp({ appId, appstoreId: appStoreId, manifestId: manifest.id || 'customapp' });
|
||||
|
||||
const task = {
|
||||
args: { restoreConfig, skipDnsSetup, overwriteDns },
|
||||
args: { restoreConfig: null, skipDnsSetup, overwriteDns },
|
||||
values: { },
|
||||
requiredState: app.installationState
|
||||
};
|
||||
@@ -2513,31 +2489,75 @@ async function unarchive(archive, data, auditSource) {
|
||||
assert.strictEqual(typeof data, 'object');
|
||||
assert(auditSource && typeof auditSource === 'object');
|
||||
|
||||
const appConfig = archive.appConfig;
|
||||
const backup = await backups.get(archive.backupId);
|
||||
const restoreConfig = { remotePath: backup.remotePath, backupFormat: backup.format };
|
||||
|
||||
const dolly = _.pick(appConfig, 'appStoreId', 'manifest', 'memoryLimit', 'cpuQuota', 'crontab', 'reverseProxyConfig', 'env', 'servicesConfig',
|
||||
const subdomain = data.subdomain.toLowerCase(),
|
||||
domain = data.domain.toLowerCase(),
|
||||
overwriteDns = 'overwriteDns' in data ? data.overwriteDns : false;
|
||||
|
||||
const appConfig = archive.appConfig;
|
||||
const { appStoreId, manifest } = appConfig;
|
||||
|
||||
let error = validateSecondaryDomains(data.secondaryDomains || {}, manifest);
|
||||
if (error) throw error;
|
||||
const secondaryDomains = translateSecondaryDomains(data.secondaryDomains || {});
|
||||
|
||||
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;
|
||||
|
||||
// re-validate because this new box version may not accept old configs
|
||||
error = await checkManifest(manifest);
|
||||
if (error) throw error;
|
||||
|
||||
error = validatePorts(data.ports || null, manifest);
|
||||
if (error) throw error;
|
||||
const portBindings = translateToPortBindings(data.ports || null, manifest);
|
||||
|
||||
const appId = uuid.v4();
|
||||
|
||||
const dolly = _.pick(appConfig, 'memoryLimit', 'cpuQuota', 'crontab', 'reverseProxyConfig', 'env', 'servicesConfig',
|
||||
'tags', 'label', 'enableMailbox', 'mailboxDisplayName', 'mailboxName', 'mailboxDomain', 'enableInbox', 'inboxName', 'inboxDomain', 'devices',
|
||||
'enableTurn', 'enableRedis', 'mounts', 'enableBackup', 'enableAutomaticUpdate', 'accessRestriction', 'operators', 'sso',
|
||||
'notes', 'checklist');
|
||||
|
||||
// intentionally not filled up: redirectDomain, aliasDomains, mailboxDomain
|
||||
const newAppData = Object.assign(dolly, {
|
||||
// from request
|
||||
subdomain: data.subdomain,
|
||||
domain: data.domain,
|
||||
secondaryDomains: data.secondaryDomains || {},
|
||||
ports: data.ports || null,
|
||||
overwriteDns: 'overwriteDns' in data ? data.overwriteDns : false,
|
||||
const obj = Object.assign(dolly, {
|
||||
secondaryDomains,
|
||||
redirectDomains: [],
|
||||
aliasDomains: [],
|
||||
mailboxDomain: data.domain, // archive's mailboxDomain may not exist
|
||||
|
||||
// from the archive
|
||||
archive: {
|
||||
iconBuffer: (await archives.getIcons(archive.id))?.icon,
|
||||
backupId: archive.backupId
|
||||
}
|
||||
runState: exports.RSTATE_RUNNING,
|
||||
installationState: exports.ISTATE_PENDING_INSTALL
|
||||
});
|
||||
obj.icon = (await archives.getIcons(archive.id))?.icon;
|
||||
|
||||
return await install(newAppData, auditSource);
|
||||
const [addError] = await safe(add(appId, appStoreId, manifest, subdomain, domain, portBindings, obj));
|
||||
if (addError && addError.reason === BoxError.ALREADY_EXISTS) throw getDuplicateErrorDetails(addError.message, locations, portBindings);
|
||||
if (addError) throw addError;
|
||||
|
||||
await purchaseApp({ appId, appstoreId: appStoreId, manifestId: manifest.id || 'customapp' });
|
||||
|
||||
const task = {
|
||||
args: { restoreConfig, overwriteDns },
|
||||
values: {},
|
||||
requiredState: obj.installationState
|
||||
};
|
||||
|
||||
const taskId = await addTask(appId, obj.installationState, task, auditSource);
|
||||
|
||||
const newApp = Object.assign({}, _.omit(obj, 'icon'), { appStoreId, manifest, subdomain, domain, portBindings });
|
||||
newApp.fqdn = dns.fqdn(newApp.subdomain, newApp.domain);
|
||||
newApp.secondaryDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
|
||||
newApp.redirectDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
|
||||
newApp.aliasDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, ad.domain); });
|
||||
|
||||
await eventlog.add(eventlog.ACTION_APP_INSTALL, auditSource, { appId, app: newApp, taskId });
|
||||
|
||||
return { id : appId, taskId };
|
||||
}
|
||||
|
||||
async function uninstall(app, auditSource) {
|
||||
|
||||
Reference in New Issue
Block a user