install/unarchive: add support for various fields

This commit is contained in:
Girish Ramakrishnan
2024-12-10 17:30:23 +01:00
parent 9a155491cb
commit fbe334e7d7
4 changed files with 62 additions and 16 deletions

View File

@@ -859,8 +859,8 @@ async function add(id, appStoreId, manifest, subdomain, domain, portBindings, da
assert(data && typeof data === 'object');
const manifestJson = JSON.stringify(manifest),
accessRestriction = data.accessRestriction || null,
accessRestrictionJson = JSON.stringify(accessRestriction),
accessRestrictionJson = data.accessRestriction ? JSON.stringify(data.accessRestriction) : null,
operatorsJson = data.operators ? JSON.stringify(data.operators) : null,
memoryLimit = data.memoryLimit || 0,
cpuQuota = data.cpuQuota || 100,
installationState = data.installationState,
@@ -881,20 +881,26 @@ async function add(id, appStoreId, manifest, subdomain, domain, portBindings, da
upstreamUri = data.upstreamUri || '',
enableTurn = 'enableTurn' in data ? data.enableTurn : true,
enableRedis = 'enableRedis' in data ? data.enableRedis : true,
icon = data.icon || null;
icon = data.icon || null,
notes = data.notes || null,
crontab = data.crontab || null,
enableBackup = 'enableBackup' in data ? data.enableBackup : true,
enableAutomaticUpdate = 'enableAutomaticUpdate' in data ? data.enableAutomaticUpdate : true;
await checkForPortBindingConflict(portBindings, { appId: null });
const queries = [];
queries.push({
query: 'INSERT INTO apps (id, appStoreId, manifestJson, installationState, runState, accessRestrictionJson, memoryLimit, cpuQuota, '
query: 'INSERT INTO apps (id, appStoreId, manifestJson, installationState, runState, accessRestrictionJson, operatorsJson, memoryLimit, cpuQuota, '
+ 'sso, debugModeJson, mailboxName, mailboxDomain, label, tagsJson, reverseProxyConfigJson, checklistJson, servicesConfigJson, icon, '
+ 'enableMailbox, mailboxDisplayName, upstreamUri, enableTurn, enableRedis, devicesJson) '
+ ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
args: [ id, appStoreId, manifestJson, installationState, runState, accessRestrictionJson, memoryLimit, cpuQuota,
+ 'enableMailbox, mailboxDisplayName, upstreamUri, enableTurn, enableRedis, devicesJson, notes, crontab, enableBackup, enableAutomaticUpdate) '
+ ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
args: [ id, appStoreId, manifestJson, installationState, runState, accessRestrictionJson, operatorsJson, memoryLimit, cpuQuota,
sso, debugModeJson, mailboxName, mailboxDomain, label, tagsJson, reverseProxyConfigJson, checklistJson, servicesConfigJson, icon,
enableMailbox, mailboxDisplayName, upstreamUri, enableTurn, enableRedis, devicesJson ]
enableMailbox, mailboxDisplayName, upstreamUri, enableTurn, enableRedis, devicesJson, notes, crontab,
enableBackup, enableAutomaticUpdate
]
});
queries.push({
@@ -1339,7 +1345,9 @@ async function install(data, auditSource) {
const subdomain = data.subdomain.toLowerCase(),
domain = data.domain.toLowerCase(),
accessRestriction = data.accessRestriction || null,
operators = data.operators || null,
memoryLimit = data.memoryLimit || 0,
cpuQuota = data.cpuQuota || 100,
debugMode = data.debugMode || null,
enableBackup = 'enableBackup' in data ? data.enableBackup : true,
enableAutomaticUpdate = 'enableAutomaticUpdate' in data ? data.enableAutomaticUpdate : true,
@@ -1355,7 +1363,9 @@ async function install(data, auditSource) {
enableRedis = 'enableRedis' in data ? data.enableRedis : true,
appStoreId = data.appStoreId,
upstreamUri = data.upstreamUri || '',
manifest = data.manifest;
manifest = data.manifest,
notes = data.notes || null,
crontab = data.crontab || null;
let error = manifestFormat.parse(manifest);
if (error) throw new BoxError(BoxError.BAD_FIELD, `Manifest error: ${error.message}`);
@@ -1370,6 +1380,9 @@ async function install(data, auditSource) {
error = validateAccessRestriction(accessRestriction);
if (error) throw error;
error = validateAccessRestriction(operators); // not a typo. same structure for operators and accessRestriction
if (error) throw error;
error = validateMemoryLimit(manifest, memoryLimit);
if (error) throw error;
@@ -1379,6 +1392,11 @@ async function install(data, auditSource) {
error = validateLabel(label);
if (error) throw error;
error = validateCpuQuota(cpuQuota);
if (error) throw error;
parseCrontab(crontab);
if ('upstreamUri' in data) error = validateUpstreamUri(upstreamUri);
if (error) throw error;
@@ -1400,6 +1418,17 @@ 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
@@ -1424,8 +1453,13 @@ 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 ('backupId' in data) { // install from archive
const backup = await backups.get(data.backupId);
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 };
}
@@ -1435,7 +1469,9 @@ async function install(data, auditSource) {
const app = {
accessRestriction,
operators,
memoryLimit,
cpuQuota,
sso,
debugMode,
mailboxName,
@@ -1454,6 +1490,9 @@ async function install(data, auditSource) {
upstreamUri,
enableTurn,
enableRedis,
notes,
crontab,
reverseProxyConfig,
runState: exports.RSTATE_RUNNING,
installationState: exports.ISTATE_PENDING_INSTALL
};
@@ -2492,8 +2531,10 @@ async function unarchive(archive, data, auditSource) {
mailboxDomain: data.domain, // archive's mailboxDomain may not exist
// from the archive
icon: archive.icon,
backupId: archive.backupId,
archive: {
iconBuffer: (await archives.getIcons(archive.id))?.icon,
backupId: archive.backupId
}
});
return await install(newAppData, auditSource);