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:
Girish Ramakrishnan
2024-12-10 19:05:31 +01:00
parent fbe334e7d7
commit 41b302b0b9
2 changed files with 61 additions and 43 deletions
+61 -41
View File
@@ -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) {