diff --git a/packages/server/src/api/controllers/deploy/aws.js b/packages/server/src/api/controllers/deploy/aws.js index 2f89d97742..6b73751695 100644 --- a/packages/server/src/api/controllers/deploy/aws.js +++ b/packages/server/src/api/controllers/deploy/aws.js @@ -21,11 +21,21 @@ async function invalidateCDN(cfDistribution, appId) { .promise() } -exports.fetchTemporaryCredentials = async function() { +/** + * Verifies the users API key and + * Verifies that the deployment fits within the quota of the user, + * @param {String} instanceId - instanceId being deployed + * @param {String} appId - appId being deployed + * @param {quota} quota - current quota being changed with this application + */ +exports.verifyDeployment = async function({ instanceId, appId, quota }) { const response = await fetch(process.env.DEPLOYMENT_CREDENTIALS_URL, { method: "POST", body: JSON.stringify({ apiKey: process.env.BUDIBASE_API_KEY, + instanceId, + appId, + quota, }), }) diff --git a/packages/server/src/api/controllers/deploy/index.js b/packages/server/src/api/controllers/deploy/index.js index 34579b64c7..a155fbbf81 100644 --- a/packages/server/src/api/controllers/deploy/index.js +++ b/packages/server/src/api/controllers/deploy/index.js @@ -1,10 +1,17 @@ const CouchDB = require("pouchdb") const PouchDB = require("../../../db") -const { uploadAppAssets, fetchTemporaryCredentials } = require("./aws") +const { + uploadAppAssets, + verifyDeployment, + determineDeploymentAllowed, +} = require("./aws") +const { getRecordParams } = require("../../db/utils") function replicate(local, remote) { return new Promise((resolve, reject) => { - const replication = local.sync(remote) + const replication = local.sync(remote, { + retry: true, + }) replication.on("complete", () => resolve()) replication.on("error", err => reject(err)) @@ -31,13 +38,37 @@ async function replicateCouch({ instanceId, clientId, credentials }) { await Promise.all(replications) } +async function getCurrentInstanceQuota(instanceId) { + const db = new PouchDB(instanceId) + const records = await db.allDocs( + getRecordParams("", null, { + include_docs: true, + }) + ) + const existingRecords = records.rows.length + return { + records: existingRecords, + } +} + exports.deployApp = async function(ctx) { try { const clientAppLookupDB = new PouchDB("client_app_lookup") const { clientId } = await clientAppLookupDB.get(ctx.user.appId) + const instanceQuota = await getCurrentInstanceQuota(ctx.user.instanceId) + const credentials = await verifyDeployment({ + instanceId: ctx.user.instanceId, + appId: ctx.user.appId, + quota: instanceQuota, + }) + ctx.log.info(`Uploading assets for appID ${ctx.user.appId} assets to s3..`) - const credentials = await fetchTemporaryCredentials() + + if (credentials.errors) { + ctx.throw(500, credentials.errors) + return + } await uploadAppAssets({ clientId,