@budibase/server 1.0.48 → 1.0.49-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builder/assets/{index.e083dcaf.js → index.21e57eb4.js} +234 -231
- package/builder/assets/index.83c0944f.css +1 -0
- package/builder/assets/{vendor.f9faf6ab.js → vendor.d526bfe8.js} +12 -12
- package/builder/index.html +3 -3
- package/coverage/clover.xml +2338 -2028
- package/coverage/coverage-final.json +100 -95
- package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +210 -126
- package/coverage/lcov-report/api/controllers/auth.js.html +18 -6
- package/coverage/lcov-report/api/controllers/automation.js.html +21 -21
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +4 -4
- package/coverage/lcov-report/api/controllers/datasource.js.html +72 -36
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +53 -53
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +6 -6
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/migrations.js.html +119 -0
- package/coverage/lcov-report/api/controllers/permission.js.html +15 -15
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.js.html +19 -19
- package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
- package/coverage/lcov-report/api/controllers/role.js.html +9 -9
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +16 -16
- package/coverage/lcov-report/api/controllers/row/index.html +48 -33
- package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
- package/coverage/lcov-report/api/controllers/row/internal.js.html +95 -158
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +41 -17
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +551 -0
- package/coverage/lcov-report/api/controllers/row/utils.js.html +39 -57
- package/coverage/lcov-report/api/controllers/screen.js.html +7 -7
- package/coverage/lcov-report/api/controllers/script.js.html +4 -4
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +629 -0
- package/coverage/lcov-report/api/controllers/table/external.js.html +12 -12
- package/coverage/lcov-report/api/controllers/table/index.html +46 -31
- package/coverage/lcov-report/api/controllers/table/index.js.html +53 -77
- package/coverage/lcov-report/api/controllers/table/internal.js.html +59 -35
- package/coverage/lcov-report/api/controllers/table/utils.js.html +217 -73
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +30 -24
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +14 -14
- package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
- package/coverage/lcov-report/api/controllers/webhook.js.html +15 -15
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +8 -8
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/application.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +18 -18
- package/coverage/lcov-report/api/routes/index.js.html +3 -3
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/{hosting.js.html → migrations.js.html} +17 -14
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/row.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/static.js.html +17 -2
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +24 -24
- package/coverage/lcov-report/automations/automationUtils.js.html +5 -5
- package/coverage/lcov-report/automations/bullboard.js.html +16 -16
- package/coverage/lcov-report/automations/index.html +1 -1
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
- package/coverage/lcov-report/automations/steps/createRow.js.html +13 -19
- package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +11 -20
- package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
- package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
- package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
- package/coverage/lcov-report/automations/steps/index.html +13 -13
- package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
- package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
- package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
- package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
- package/coverage/lcov-report/automations/steps/updateRow.js.html +6 -6
- package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
- package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
- package/coverage/lcov-report/automations/triggers.js.html +18 -18
- package/coverage/lcov-report/automations/utils.js.html +32 -32
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +53 -26
- package/coverage/lcov-report/constants/layouts.js.html +5 -5
- package/coverage/lcov-report/constants/screens.js.html +4 -4
- package/coverage/lcov-report/db/client.js.html +18 -18
- package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
- package/coverage/lcov-report/db/index.html +15 -15
- package/coverage/lcov-report/db/index.js.html +3 -3
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +18 -18
- package/coverage/lcov-report/db/linkedRows/index.html +10 -10
- package/coverage/lcov-report/db/linkedRows/index.js.html +38 -41
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +15 -15
- package/coverage/lcov-report/db/newid.js.html +4 -4
- package/coverage/lcov-report/db/utils.js.html +86 -86
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +5 -5
- package/coverage/lcov-report/events/utils.js.html +3 -3
- package/coverage/lcov-report/index.html +114 -99
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/authorized.js.html +166 -64
- package/coverage/lcov-report/middleware/builder.js.html +8 -8
- package/coverage/lcov-report/middleware/currentapp.js.html +29 -29
- package/coverage/lcov-report/middleware/index.html +30 -30
- package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +270 -42
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/threads/automation.js.html +1 -1
- package/coverage/lcov-report/threads/index.html +15 -15
- package/coverage/lcov-report/threads/index.js.html +10 -10
- package/coverage/lcov-report/threads/query.js.html +23 -8
- package/coverage/lcov-report/threads/utils.js.html +14 -14
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
- package/coverage/lcov-report/utilities/global.js.html +26 -26
- package/coverage/lcov-report/utilities/index.html +19 -19
- package/coverage/lcov-report/utilities/index.js.html +25 -25
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +8 -8
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -27
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +115 -79
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +75 -27
- package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
- package/coverage/lcov-report/utilities/security.js.html +8 -8
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +141 -0
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +356 -0
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +302 -0
- package/coverage/lcov-report/{api/controllers/hosting.js.html → utilities/usageQuota/usageQuoteReset.js.html} +36 -48
- package/coverage/lcov-report/utilities/users.js.html +5 -5
- package/coverage/lcov-report/utilities/workerRequests.js.html +39 -108
- package/coverage/lcov.info +3656 -3057
- package/dist/api/controllers/application.js +61 -34
- package/dist/api/controllers/auth.js +4 -0
- package/dist/api/controllers/datasource.js +11 -0
- package/dist/api/controllers/migrations.js +21 -0
- package/dist/api/controllers/row/internal.js +30 -53
- package/dist/api/controllers/row/internalSearch.js +12 -4
- package/dist/api/controllers/row/staticFormula.js +147 -0
- package/dist/api/controllers/row/utils.js +6 -8
- package/dist/api/controllers/static/index.js +59 -10
- package/dist/api/controllers/table/bulkFormula.js +160 -0
- package/dist/api/controllers/table/index.js +12 -9
- package/dist/api/controllers/table/internal.js +9 -0
- package/dist/api/controllers/table/utils.js +41 -12
- package/dist/api/controllers/user.js +2 -0
- package/dist/api/routes/index.js +2 -2
- package/dist/api/routes/migrations.js +9 -0
- package/dist/api/routes/static.js +2 -1
- package/dist/app.js +35 -5
- package/dist/automations/steps/createRow.js +2 -4
- package/dist/automations/steps/deleteRow.js +1 -4
- package/dist/constants/index.js +7 -0
- package/dist/db/linkedRows/index.js +4 -5
- package/dist/definitions/datasource.js +1 -0
- package/dist/environment.js +2 -0
- package/dist/integrations/base/sql.js +13 -6
- package/dist/integrations/googlesheets.js +340 -0
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/utils.js +57 -9
- package/dist/middleware/authorized.js +55 -30
- package/dist/middleware/usageQuota.js +80 -13
- package/dist/migrations/functions/appUrls.js +46 -0
- package/dist/migrations/functions/quotas1.js +50 -0
- package/dist/migrations/functions/usageQuotas/index.js +20 -0
- package/dist/migrations/functions/usageQuotas/syncApps.js +32 -0
- package/dist/migrations/functions/usageQuotas/syncRows.js +35 -0
- package/dist/migrations/functions/userEmailViewCasing.js +24 -0
- package/dist/migrations/index.js +62 -0
- package/dist/package.json +8 -5
- package/dist/tests/utilities/TestConfiguration.js +13 -6
- package/dist/threads/query.js +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/rowProcessor/index.js +18 -11
- package/dist/utilities/rowProcessor/utils.js +14 -4
- package/dist/utilities/{usageQuota.js → usageQuota/index.js} +44 -31
- package/dist/utilities/usageQuota/rows.js +77 -0
- package/dist/utilities/usageQuota/usageQuoteReset.js +16 -0
- package/dist/utilities/workerRequests.js +0 -20
- package/nodemon.json +1 -1
- package/package.json +9 -6
- package/src/api/controllers/application.js +52 -24
- package/src/api/controllers/auth.js +4 -0
- package/src/api/controllers/datasource.js +12 -0
- package/src/api/controllers/migrations.js +13 -0
- package/src/api/controllers/row/internal.js +29 -50
- package/src/api/controllers/row/internalSearch.js +12 -4
- package/src/api/controllers/row/staticFormula.js +157 -0
- package/src/api/controllers/row/utils.js +6 -12
- package/src/api/controllers/static/index.js +63 -10
- package/src/api/controllers/table/bulkFormula.js +183 -0
- package/src/api/controllers/table/index.js +16 -24
- package/src/api/controllers/table/internal.js +9 -1
- package/src/api/controllers/table/utils.js +57 -9
- package/src/api/controllers/user.js +2 -0
- package/src/api/routes/index.js +2 -2
- package/src/api/routes/migrations.js +14 -0
- package/src/api/routes/static.js +5 -0
- package/src/api/routes/tests/application.spec.js +2 -2
- package/src/api/routes/tests/auth.spec.js +1 -2
- package/src/api/routes/tests/static.spec.js +98 -0
- package/src/app.ts +18 -5
- package/src/automations/steps/createRow.js +2 -4
- package/src/automations/steps/deleteRow.js +1 -4
- package/src/constants/index.js +9 -0
- package/src/db/linkedRows/index.js +4 -5
- package/src/definitions/common.ts +3 -0
- package/src/definitions/datasource.ts +3 -0
- package/src/environment.js +2 -0
- package/src/integrations/base/sql.ts +14 -7
- package/src/integrations/googlesheets.ts +353 -0
- package/src/integrations/index.ts +3 -0
- package/src/integrations/tests/sql.spec.js +16 -0
- package/src/integrations/utils.ts +71 -11
- package/src/middleware/authorized.js +64 -30
- package/src/middleware/tests/authorized.spec.js +6 -4
- package/src/middleware/tests/usageQuota.spec.js +18 -24
- package/src/middleware/usageQuota.js +91 -15
- package/src/migrations/functions/appUrls.ts +34 -0
- package/src/migrations/functions/quotas1.ts +20 -0
- package/src/migrations/functions/tests/appUrls.spec.js +29 -0
- package/src/migrations/functions/tests/quotas1.spec.js +27 -0
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +25 -0
- package/src/migrations/functions/usageQuotas/index.ts +8 -0
- package/src/migrations/functions/usageQuotas/syncApps.ts +18 -0
- package/src/migrations/functions/usageQuotas/syncRows.ts +21 -0
- package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +37 -0
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +43 -0
- package/src/migrations/functions/userEmailViewCasing.ts +13 -0
- package/src/migrations/index.ts +56 -0
- package/src/tests/utilities/TestConfiguration.js +14 -6
- package/src/threads/query.js +5 -0
- package/src/utilities/rowProcessor/index.js +24 -12
- package/src/utilities/rowProcessor/utils.js +23 -7
- package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
- package/src/utilities/usageQuota/index.js +92 -0
- package/src/utilities/usageQuota/rows.js +74 -0
- package/src/utilities/usageQuota/usageQuoteReset.js +18 -0
- package/src/utilities/workerRequests.js +0 -23
- package/builder/assets/index.39e01193.css +0 -1
- package/dist/api/controllers/hosting.js +0 -30
- package/dist/api/routes/hosting.js +0 -11
- package/src/api/controllers/hosting.js +0 -22
- package/src/api/routes/hosting.js +0 -13
- package/src/api/routes/tests/hosting.spec.js +0 -36
- package/src/utilities/usageQuota.js +0 -73
|
@@ -175,6 +175,7 @@ function processAutoColumn(user, table, row, opts = { reprocessing: false, noAut
|
|
|
175
175
|
return { table, row };
|
|
176
176
|
}
|
|
177
177
|
exports.processAutoColumn = processAutoColumn;
|
|
178
|
+
exports.processFormulas = processFormulas;
|
|
178
179
|
/**
|
|
179
180
|
* This will coerce a value to the correct types based on the type transform map
|
|
180
181
|
* @param {object} row The value to coerce
|
|
@@ -218,11 +219,11 @@ exports.inputProcessing = (user = {}, table, row, opts = { noAutoRelationships:
|
|
|
218
219
|
}
|
|
219
220
|
continue;
|
|
220
221
|
}
|
|
221
|
-
//
|
|
222
|
-
// type coercion cannot completely remove the field, so have to do it here
|
|
222
|
+
// remove any formula values, they are to be generated
|
|
223
223
|
if (field.type === FieldTypes.FORMULA) {
|
|
224
224
|
delete clonedRow[key];
|
|
225
225
|
}
|
|
226
|
+
// otherwise coerce what is there to correct types
|
|
226
227
|
else {
|
|
227
228
|
clonedRow[key] = exports.coerce(value, field.type);
|
|
228
229
|
}
|
|
@@ -237,24 +238,23 @@ exports.inputProcessing = (user = {}, table, row, opts = { noAutoRelationships:
|
|
|
237
238
|
/**
|
|
238
239
|
* This function enriches the input rows with anything they are supposed to contain, for example
|
|
239
240
|
* link records or attachment links.
|
|
240
|
-
* @param {
|
|
241
|
+
* @param {string} appId the app in which the request is looking for enriched rows.
|
|
241
242
|
* @param {object} table the table from which these rows came from originally, this is used to determine
|
|
242
243
|
* the schema of the rows and then enrich.
|
|
243
244
|
* @param {object[]|object} rows the rows which are to be enriched.
|
|
244
245
|
* @param {object} opts used to set some options for the output, such as disabling relationship squashing.
|
|
245
246
|
* @returns {object[]|object} the enriched rows will be returned.
|
|
246
247
|
*/
|
|
247
|
-
exports.outputProcessing = (
|
|
248
|
-
const appId = ctx.appId;
|
|
248
|
+
exports.outputProcessing = ({ appId }, table, rows, opts = { squash: true }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
249
249
|
let wasArray = true;
|
|
250
250
|
if (!(rows instanceof Array)) {
|
|
251
251
|
rows = [rows];
|
|
252
252
|
wasArray = false;
|
|
253
253
|
}
|
|
254
254
|
// attach any linked row information
|
|
255
|
-
let enriched = yield linkRows.attachFullLinkedDocs(
|
|
255
|
+
let enriched = yield linkRows.attachFullLinkedDocs(appId, table, rows);
|
|
256
256
|
// process formulas
|
|
257
|
-
enriched = processFormulas(table, enriched);
|
|
257
|
+
enriched = processFormulas(table, enriched, { dynamic: true });
|
|
258
258
|
// update the attachments URL depending on hosting
|
|
259
259
|
for (let [property, column] of Object.entries(table.schema)) {
|
|
260
260
|
if (column.type === FieldTypes.ATTACHMENT) {
|
|
@@ -280,9 +280,11 @@ exports.outputProcessing = (ctx, table, rows, opts = { squash: true }) => __awai
|
|
|
280
280
|
* @param {any} row optional - the row being removed.
|
|
281
281
|
* @param {any} rows optional - if multiple rows being deleted can do this in bulk.
|
|
282
282
|
* @param {any} oldRow optional - if updating a row this will determine the difference.
|
|
283
|
+
* @param {any} oldTable optional - if updating a table, can supply the old table to look for
|
|
284
|
+
* deleted attachment columns.
|
|
283
285
|
* @return {Promise<void>} When all attachments have been removed this will return.
|
|
284
286
|
*/
|
|
285
|
-
exports.cleanupAttachments = (appId, table, { row, rows, oldRow }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
287
|
+
exports.cleanupAttachments = (appId, table, { row, rows, oldRow, oldTable }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
286
288
|
if (!isProdAppID(appId)) {
|
|
287
289
|
const prodAppId = getDeployedAppID(appId);
|
|
288
290
|
// if prod exists, then don't allow deleting
|
|
@@ -297,12 +299,17 @@ exports.cleanupAttachments = (appId, table, { row, rows, oldRow }) => __awaiter(
|
|
|
297
299
|
files = files.concat(row[key].map(attachment => attachment.key));
|
|
298
300
|
}
|
|
299
301
|
}
|
|
300
|
-
|
|
302
|
+
const schemaToUse = oldTable ? oldTable.schema : table.schema;
|
|
303
|
+
for (let [key, schema] of Object.entries(schemaToUse)) {
|
|
301
304
|
if (schema.type !== FieldTypes.ATTACHMENT) {
|
|
302
305
|
continue;
|
|
303
306
|
}
|
|
304
|
-
//
|
|
305
|
-
if (
|
|
307
|
+
// old table had this column, new table doesn't - delete it
|
|
308
|
+
if (oldTable && !table.schema[key]) {
|
|
309
|
+
rows.forEach(row => addFiles(row, key));
|
|
310
|
+
}
|
|
311
|
+
else if (oldRow && row) {
|
|
312
|
+
// if updating, need to manage the differences
|
|
306
313
|
files = files.concat(getRemovedAttachmentKeys(oldRow, row, key));
|
|
307
314
|
}
|
|
308
315
|
else if (row) {
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const { FieldTypes } = require("../../constants");
|
|
2
|
+
const { FieldTypes, FormulaTypes } = require("../../constants");
|
|
3
3
|
const { processStringSync } = require("@budibase/string-templates");
|
|
4
4
|
/**
|
|
5
5
|
* Looks through the rows provided and finds formulas - which it then processes.
|
|
6
6
|
*/
|
|
7
|
-
exports.processFormulas = (table, rows) => {
|
|
7
|
+
exports.processFormulas = (table, rows, { dynamic, contextRows } = { dynamic: true }) => {
|
|
8
8
|
const single = !Array.isArray(rows);
|
|
9
9
|
if (single) {
|
|
10
10
|
rows = [rows];
|
|
11
|
+
contextRows = contextRows ? [contextRows] : contextRows;
|
|
11
12
|
}
|
|
12
13
|
for (let [column, schema] of Object.entries(table.schema)) {
|
|
13
|
-
|
|
14
|
+
const isStatic = schema.formulaType === FormulaTypes.STATIC;
|
|
15
|
+
if (schema.type !== FieldTypes.FORMULA ||
|
|
16
|
+
(dynamic && isStatic) ||
|
|
17
|
+
(!dynamic && !isStatic)) {
|
|
14
18
|
continue;
|
|
15
19
|
}
|
|
16
20
|
// iterate through rows and process formula
|
|
17
|
-
|
|
21
|
+
for (let i = 0; i < rows.length; i++) {
|
|
22
|
+
if (schema.formula) {
|
|
23
|
+
let row = rows[i];
|
|
24
|
+
let context = contextRows ? contextRows[i] : row;
|
|
25
|
+
rows[i] = Object.assign(Object.assign({}, row), { [column]: processStringSync(schema.formula, context) });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
18
28
|
}
|
|
19
29
|
return single ? rows[0] : rows;
|
|
20
30
|
};
|
|
@@ -8,12 +8,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
const env = require("
|
|
12
|
-
const { getGlobalDB } = require("@budibase/backend-core/tenancy");
|
|
11
|
+
const env = require("../../environment");
|
|
12
|
+
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy");
|
|
13
13
|
const { StaticDatabases, generateNewUsageQuotaDoc, } = require("@budibase/backend-core/db");
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
exports.useQuotas = () => {
|
|
15
|
+
// check if quotas are enabled
|
|
16
|
+
if (env.USE_QUOTAS) {
|
|
17
|
+
// check if there are any tenants without limits
|
|
18
|
+
if (env.EXCLUDE_QUOTAS_TENANTS) {
|
|
19
|
+
const excludedTenants = env.EXCLUDE_QUOTAS_TENANTS.replace(/\s/g, "").split(",");
|
|
20
|
+
const tenantId = getTenantId();
|
|
21
|
+
if (excludedTenants.includes(tenantId)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
17
29
|
exports.Properties = {
|
|
18
30
|
ROW: "rows",
|
|
19
31
|
UPLOAD: "storage",
|
|
@@ -21,21 +33,21 @@ exports.Properties = {
|
|
|
21
33
|
USER: "users",
|
|
22
34
|
AUTOMATION: "automationRuns",
|
|
23
35
|
APPS: "apps",
|
|
24
|
-
EMAILS: "emails",
|
|
36
|
+
EMAILS: "emails", // doesn't work yet
|
|
25
37
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
38
|
+
exports.getUsageQuotaDoc = (db) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
let quota;
|
|
40
|
+
try {
|
|
41
|
+
quota = yield db.get(StaticDatabases.GLOBAL.docs.usageQuota);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
// doc doesn't exist. Create it
|
|
45
|
+
quota = generateNewUsageQuotaDoc();
|
|
46
|
+
const response = yield db.put(quota);
|
|
47
|
+
quota._rev = response.rev;
|
|
48
|
+
}
|
|
49
|
+
return quota;
|
|
50
|
+
});
|
|
39
51
|
/**
|
|
40
52
|
* Given a specified tenantId this will add to the usage object for the specified property.
|
|
41
53
|
* @param {string} property The property which is to be added to (within the nested usageQuota object).
|
|
@@ -43,27 +55,28 @@ function getUsageQuotaDoc(db) {
|
|
|
43
55
|
* @returns {Promise<void>} When this completes the API key will now be up to date - the quota period may have
|
|
44
56
|
* also been reset after this call.
|
|
45
57
|
*/
|
|
46
|
-
exports.update = (property, usage) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
-
if (!
|
|
58
|
+
exports.update = (property, usage, opts = { dryRun: false }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
+
if (!exports.useQuotas()) {
|
|
48
60
|
return;
|
|
49
61
|
}
|
|
50
62
|
try {
|
|
51
63
|
const db = getGlobalDB();
|
|
52
|
-
const quota = yield getUsageQuotaDoc(db);
|
|
53
|
-
// Check if the quota needs reset
|
|
54
|
-
if (Date.now() >= quota.quotaReset) {
|
|
55
|
-
quota.quotaReset = getNewQuotaReset();
|
|
56
|
-
for (let prop of Object.keys(quota.usageQuota)) {
|
|
57
|
-
quota.usageQuota[prop] = 0;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
64
|
+
const quota = yield exports.getUsageQuotaDoc(db);
|
|
60
65
|
// increment the quota
|
|
61
66
|
quota.usageQuota[property] += usage;
|
|
62
|
-
if (quota.usageQuota[property] > quota.usageLimits[property]
|
|
67
|
+
if (quota.usageQuota[property] > quota.usageLimits[property] &&
|
|
68
|
+
usage > 0 // allow for decrementing usage when the quota is already exceeded
|
|
69
|
+
) {
|
|
63
70
|
throw new Error(`You have exceeded your usage quota of ${quota.usageLimits[property]} ${property}.`);
|
|
64
71
|
}
|
|
72
|
+
if (quota.usageQuota[property] < 0) {
|
|
73
|
+
// never go negative if the quota has previously been exceeded
|
|
74
|
+
quota.usageQuota[property] = 0;
|
|
75
|
+
}
|
|
65
76
|
// update the usage quotas
|
|
66
|
-
|
|
77
|
+
if (!opts.dryRun) {
|
|
78
|
+
yield db.put(quota);
|
|
79
|
+
}
|
|
67
80
|
}
|
|
68
81
|
catch (err) {
|
|
69
82
|
console.error(`Error updating usage quotas for ${property}`, err);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const { getRowParams, USER_METDATA_PREFIX } = require("../../db/utils");
|
|
12
|
+
const CouchDB = require("../../db");
|
|
13
|
+
const { isDevAppID, getDevelopmentAppID } = require("@budibase/backend-core/db");
|
|
14
|
+
const ROW_EXCLUSIONS = [USER_METDATA_PREFIX];
|
|
15
|
+
const getAppPairs = appIds => {
|
|
16
|
+
// collect the app ids into dev / prod pairs
|
|
17
|
+
// keyed by the dev app id
|
|
18
|
+
const pairs = {};
|
|
19
|
+
for (let appId of appIds) {
|
|
20
|
+
const devId = getDevelopmentAppID(appId);
|
|
21
|
+
if (!pairs[devId]) {
|
|
22
|
+
pairs[devId] = {};
|
|
23
|
+
}
|
|
24
|
+
if (isDevAppID(appId)) {
|
|
25
|
+
pairs[devId].devId = appId;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
pairs[devId].prodId = appId;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return pairs;
|
|
32
|
+
};
|
|
33
|
+
const getAppRows = (appId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
+
const appDb = new CouchDB(appId);
|
|
35
|
+
const response = yield appDb.allDocs(getRowParams(null, null, {
|
|
36
|
+
include_docs: false,
|
|
37
|
+
}));
|
|
38
|
+
return response.rows
|
|
39
|
+
.map(r => r.id)
|
|
40
|
+
.filter(id => {
|
|
41
|
+
for (let exclusion of ROW_EXCLUSIONS) {
|
|
42
|
+
if (id.startsWith(exclusion)) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Return a set of all rows in the given app ids.
|
|
51
|
+
* The returned rows will be unique on a per dev/prod app basis.
|
|
52
|
+
* Rows duplicates may exist across apps due to data import so they are not filtered out.
|
|
53
|
+
*/
|
|
54
|
+
exports.getUniqueRows = (appIds) => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
|
+
let uniqueRows = [];
|
|
56
|
+
const pairs = getAppPairs(appIds);
|
|
57
|
+
for (let pair of Object.values(pairs)) {
|
|
58
|
+
let appRows = [];
|
|
59
|
+
for (let appId of [pair.devId, pair.prodId]) {
|
|
60
|
+
if (!appId) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
appRows.push(yield getAppRows(appId));
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
console.error(e);
|
|
68
|
+
// don't error out if we can't count the app rows, just continue
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// ensure uniqueness on a per app pair basis
|
|
72
|
+
// this can't be done on all rows because app import results in
|
|
73
|
+
// duplicate row ids across apps
|
|
74
|
+
uniqueRows = uniqueRows.concat(...new Set(appRows));
|
|
75
|
+
}
|
|
76
|
+
return uniqueRows;
|
|
77
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// UNUSED CODE
|
|
3
|
+
// Preserved for future use
|
|
4
|
+
/* eslint-disable no-unused-vars */
|
|
5
|
+
function getNewQuotaReset() {
|
|
6
|
+
return Date.now() + 2592000000;
|
|
7
|
+
}
|
|
8
|
+
function resetQuotasIfRequired(quota) {
|
|
9
|
+
// Check if the quota needs reset
|
|
10
|
+
if (Date.now() >= quota.quotaReset) {
|
|
11
|
+
quota.quotaReset = getNewQuotaReset();
|
|
12
|
+
for (let prop of Object.keys(quota.usageQuota)) {
|
|
13
|
+
quota.usageQuota[prop] = 0;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -61,26 +61,6 @@ exports.sendSmtpEmail = (to, from, subject, contents, automation) => __awaiter(v
|
|
|
61
61
|
}
|
|
62
62
|
return response.json();
|
|
63
63
|
});
|
|
64
|
-
exports.getDeployedApps = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
-
try {
|
|
66
|
-
const response = yield fetch(checkSlashesInUrl(env.WORKER_URL + `/api/apps`), request(null, {
|
|
67
|
-
method: "GET",
|
|
68
|
-
}));
|
|
69
|
-
const json = yield response.json();
|
|
70
|
-
const apps = {};
|
|
71
|
-
for (let [key, value] of Object.entries(json)) {
|
|
72
|
-
if (value.url) {
|
|
73
|
-
value.url = value.url.toLowerCase();
|
|
74
|
-
apps[key.toLowerCase()] = value;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return apps;
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
// error, cannot determine deployed apps, don't stop app creation - sort this later
|
|
81
|
-
return {};
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
64
|
exports.getGlobalSelf = (ctx, appId = null) => __awaiter(void 0, void 0, void 0, function* () {
|
|
85
65
|
const endpoint = `/api/global/users/self`;
|
|
86
66
|
const response = yield fetch(checkSlashesInUrl(env.WORKER_URL + endpoint),
|
package/nodemon.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.49-alpha.3",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
"license": "GPL-3.0",
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"@apidevtools/swagger-parser": "^10.0.3",
|
|
73
|
-
"@budibase/backend-core": "^1.0.
|
|
74
|
-
"@budibase/client": "^1.0.
|
|
75
|
-
"@budibase/string-templates": "^1.0.
|
|
73
|
+
"@budibase/backend-core": "^1.0.49-alpha.3",
|
|
74
|
+
"@budibase/client": "^1.0.49-alpha.3",
|
|
75
|
+
"@budibase/string-templates": "^1.0.49-alpha.3",
|
|
76
76
|
"@bull-board/api": "^3.7.0",
|
|
77
77
|
"@bull-board/koa": "^3.7.0",
|
|
78
78
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -92,6 +92,8 @@
|
|
|
92
92
|
"fix-path": "3.0.0",
|
|
93
93
|
"form-data": "^4.0.0",
|
|
94
94
|
"fs-extra": "8.1.0",
|
|
95
|
+
"google-auth-library": "^7.11.0",
|
|
96
|
+
"google-spreadsheet": "^3.2.0",
|
|
95
97
|
"jimp": "0.16.1",
|
|
96
98
|
"joi": "17.2.1",
|
|
97
99
|
"js-yaml": "^4.1.0",
|
|
@@ -110,7 +112,7 @@
|
|
|
110
112
|
"mongodb": "3.6.3",
|
|
111
113
|
"mssql": "6.2.3",
|
|
112
114
|
"mysql2": "^2.3.1",
|
|
113
|
-
"node-fetch": "2.6.
|
|
115
|
+
"node-fetch": "2.6.7",
|
|
114
116
|
"open": "^8.4.0",
|
|
115
117
|
"pg": "8.5.1",
|
|
116
118
|
"pino-pretty": "4.0.0",
|
|
@@ -139,6 +141,7 @@
|
|
|
139
141
|
"@jest/test-sequencer": "^24.8.0",
|
|
140
142
|
"@types/apidoc": "^0.50.0",
|
|
141
143
|
"@types/bull": "^3.15.1",
|
|
144
|
+
"@types/google-spreadsheet": "^3.1.5",
|
|
142
145
|
"@types/jest": "^26.0.23",
|
|
143
146
|
"@types/koa": "^2.13.3",
|
|
144
147
|
"@types/koa-router": "^7.4.2",
|
|
@@ -165,5 +168,5 @@
|
|
|
165
168
|
"optionalDependencies": {
|
|
166
169
|
"oracledb": "^5.3.0"
|
|
167
170
|
},
|
|
168
|
-
"gitHead": "
|
|
171
|
+
"gitHead": "9a271e74c17536fc00aabf0d4672012a28aa52b0"
|
|
169
172
|
}
|
|
@@ -33,10 +33,7 @@ const {
|
|
|
33
33
|
Replication,
|
|
34
34
|
} = require("@budibase/backend-core/db")
|
|
35
35
|
const { USERS_TABLE_SCHEMA } = require("../../constants")
|
|
36
|
-
const {
|
|
37
|
-
getDeployedApps,
|
|
38
|
-
removeAppFromUserRoles,
|
|
39
|
-
} = require("../../utilities/workerRequests")
|
|
36
|
+
const { removeAppFromUserRoles } = require("../../utilities/workerRequests")
|
|
40
37
|
const { clientLibraryPath, stringToReadStream } = require("../../utilities")
|
|
41
38
|
const { getAllLocks } = require("../../utilities/redis")
|
|
42
39
|
const {
|
|
@@ -78,29 +75,42 @@ function getUserRoleId(ctx) {
|
|
|
78
75
|
: ctx.user.role._id
|
|
79
76
|
}
|
|
80
77
|
|
|
81
|
-
|
|
78
|
+
exports.getAppUrl = ctx => {
|
|
79
|
+
// construct the url
|
|
82
80
|
let url
|
|
83
81
|
if (ctx.request.body.url) {
|
|
82
|
+
// if the url is provided, use that
|
|
84
83
|
url = encodeURI(ctx.request.body.url)
|
|
85
84
|
} else if (ctx.request.body.name) {
|
|
85
|
+
// otherwise use the name
|
|
86
86
|
url = encodeURI(`${ctx.request.body.name}`)
|
|
87
87
|
}
|
|
88
88
|
if (url) {
|
|
89
89
|
url = `/${url.replace(URL_REGEX_SLASH, "")}`.toLowerCase()
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
return url
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const checkAppUrl = (ctx, apps, url, currentAppId) => {
|
|
95
|
+
if (currentAppId) {
|
|
96
|
+
apps = apps.filter(app => app.appId !== currentAppId)
|
|
93
97
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
if (apps.some(app => app.url === url)) {
|
|
99
|
+
ctx.throw(400, "App URL is already in use.")
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const checkAppName = (ctx, apps, name, currentAppId) => {
|
|
104
|
+
// TODO: Replace with Joi
|
|
105
|
+
if (!name) {
|
|
106
|
+
ctx.throw(400, "Name is required")
|
|
107
|
+
}
|
|
108
|
+
if (currentAppId) {
|
|
109
|
+
apps = apps.filter(app => app.appId !== currentAppId)
|
|
110
|
+
}
|
|
111
|
+
if (apps.some(app => app.name === name)) {
|
|
112
|
+
ctx.throw(400, "App name is already in use.")
|
|
102
113
|
}
|
|
103
|
-
return url
|
|
104
114
|
}
|
|
105
115
|
|
|
106
116
|
async function createInstance(template) {
|
|
@@ -206,6 +216,12 @@ exports.fetchAppPackage = async ctx => {
|
|
|
206
216
|
}
|
|
207
217
|
|
|
208
218
|
exports.create = async ctx => {
|
|
219
|
+
const apps = await getAllApps(CouchDB, { dev: true })
|
|
220
|
+
const name = ctx.request.body.name
|
|
221
|
+
checkAppName(ctx, apps, name)
|
|
222
|
+
const url = exports.getAppUrl(ctx)
|
|
223
|
+
checkAppUrl(ctx, apps, url)
|
|
224
|
+
|
|
209
225
|
const { useTemplate, templateKey, templateString } = ctx.request.body
|
|
210
226
|
const instanceConfig = {
|
|
211
227
|
useTemplate,
|
|
@@ -218,7 +234,6 @@ exports.create = async ctx => {
|
|
|
218
234
|
const instance = await createInstance(instanceConfig)
|
|
219
235
|
const appId = instance._id
|
|
220
236
|
|
|
221
|
-
const url = await getAppUrlIfNotInUse(ctx)
|
|
222
237
|
const db = new CouchDB(appId)
|
|
223
238
|
let _rev
|
|
224
239
|
try {
|
|
@@ -235,7 +250,7 @@ exports.create = async ctx => {
|
|
|
235
250
|
type: "app",
|
|
236
251
|
version: packageJson.version,
|
|
237
252
|
componentLibraries: ["@budibase/standard-components"],
|
|
238
|
-
name:
|
|
253
|
+
name: name,
|
|
239
254
|
url: url,
|
|
240
255
|
template: ctx.request.body.template,
|
|
241
256
|
instance: instance,
|
|
@@ -262,8 +277,22 @@ exports.create = async ctx => {
|
|
|
262
277
|
ctx.body = newApplication
|
|
263
278
|
}
|
|
264
279
|
|
|
280
|
+
// This endpoint currently operates as a PATCH rather than a PUT
|
|
281
|
+
// Thus name and url fields are handled only if present
|
|
265
282
|
exports.update = async ctx => {
|
|
266
|
-
const
|
|
283
|
+
const apps = await getAllApps(CouchDB, { dev: true })
|
|
284
|
+
// validation
|
|
285
|
+
const name = ctx.request.body.name
|
|
286
|
+
if (name) {
|
|
287
|
+
checkAppName(ctx, apps, name, ctx.params.appId)
|
|
288
|
+
}
|
|
289
|
+
const url = await exports.getAppUrl(ctx)
|
|
290
|
+
if (url) {
|
|
291
|
+
checkAppUrl(ctx, apps, url, ctx.params.appId)
|
|
292
|
+
ctx.request.body.url = url
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const data = await updateAppPackage(ctx.request.body, ctx.params.appId)
|
|
267
296
|
ctx.status = 200
|
|
268
297
|
ctx.body = data
|
|
269
298
|
}
|
|
@@ -285,7 +314,7 @@ exports.updateClient = async ctx => {
|
|
|
285
314
|
version: packageJson.version,
|
|
286
315
|
revertableVersion: currentVersion,
|
|
287
316
|
}
|
|
288
|
-
const data = await updateAppPackage(
|
|
317
|
+
const data = await updateAppPackage(appPackageUpdates, ctx.params.appId)
|
|
289
318
|
ctx.status = 200
|
|
290
319
|
ctx.body = data
|
|
291
320
|
}
|
|
@@ -308,7 +337,7 @@ exports.revertClient = async ctx => {
|
|
|
308
337
|
version: application.revertableVersion,
|
|
309
338
|
revertableVersion: null,
|
|
310
339
|
}
|
|
311
|
-
const data = await updateAppPackage(
|
|
340
|
+
const data = await updateAppPackage(appPackageUpdates, ctx.params.appId)
|
|
312
341
|
ctx.status = 200
|
|
313
342
|
ctx.body = data
|
|
314
343
|
}
|
|
@@ -381,12 +410,11 @@ exports.sync = async (ctx, next) => {
|
|
|
381
410
|
}
|
|
382
411
|
}
|
|
383
412
|
|
|
384
|
-
const updateAppPackage = async (
|
|
385
|
-
const url = await getAppUrlIfNotInUse(ctx)
|
|
413
|
+
const updateAppPackage = async (appPackage, appId) => {
|
|
386
414
|
const db = new CouchDB(appId)
|
|
387
415
|
const application = await db.get(DocumentTypes.APP_METADATA)
|
|
388
416
|
|
|
389
|
-
const newAppPackage = { ...application, ...appPackage
|
|
417
|
+
const newAppPackage = { ...application, ...appPackage }
|
|
390
418
|
if (appPackage._rev !== application._rev) {
|
|
391
419
|
newAppPackage._rev = application._rev
|
|
392
420
|
}
|
|
@@ -16,6 +16,8 @@ exports.fetchSelf = async ctx => {
|
|
|
16
16
|
const user = await getFullUser(ctx, userId)
|
|
17
17
|
// this shouldn't be returned by the app self
|
|
18
18
|
delete user.roles
|
|
19
|
+
// forward the csrf token from the session
|
|
20
|
+
user.csrfToken = ctx.user.csrfToken
|
|
19
21
|
|
|
20
22
|
if (appId) {
|
|
21
23
|
const db = new CouchDB(appId)
|
|
@@ -24,6 +26,8 @@ exports.fetchSelf = async ctx => {
|
|
|
24
26
|
try {
|
|
25
27
|
const userTable = await db.get(InternalTables.USER_METADATA)
|
|
26
28
|
const metadata = await db.get(userId)
|
|
29
|
+
// make sure there is never a stale csrf token
|
|
30
|
+
delete metadata.csrfToken
|
|
27
31
|
// specifically needs to make sure is enriched
|
|
28
32
|
ctx.body = await outputProcessing(ctx, userTable, {
|
|
29
33
|
...user,
|
|
@@ -38,6 +38,13 @@ exports.fetch = async function (ctx) {
|
|
|
38
38
|
)
|
|
39
39
|
).rows.map(row => row.doc)
|
|
40
40
|
|
|
41
|
+
for (let datasource of datasources) {
|
|
42
|
+
if (datasource.config && datasource.config.auth) {
|
|
43
|
+
// strip secrets from response so they don't show in the network request
|
|
44
|
+
delete datasource.config.auth
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
41
48
|
ctx.body = [bbInternalDb, ...datasources]
|
|
42
49
|
}
|
|
43
50
|
|
|
@@ -94,8 +101,13 @@ exports.update = async function (ctx) {
|
|
|
94
101
|
const db = new CouchDB(ctx.appId)
|
|
95
102
|
const datasourceId = ctx.params.datasourceId
|
|
96
103
|
let datasource = await db.get(datasourceId)
|
|
104
|
+
const auth = datasource.config.auth
|
|
97
105
|
await invalidateVariables(datasource, ctx.request.body)
|
|
98
106
|
datasource = { ...datasource, ...ctx.request.body }
|
|
107
|
+
if (auth && !ctx.request.body.auth) {
|
|
108
|
+
// don't strip auth config from DB
|
|
109
|
+
datasource.config.auth = auth
|
|
110
|
+
}
|
|
99
111
|
|
|
100
112
|
const response = await db.put(datasource)
|
|
101
113
|
datasource._rev = response.rev
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const { migrate, MIGRATIONS } = require("../../migrations")
|
|
2
|
+
|
|
3
|
+
exports.migrate = async ctx => {
|
|
4
|
+
const options = ctx.request.body
|
|
5
|
+
// don't await as can take a while, just return
|
|
6
|
+
migrate(options)
|
|
7
|
+
ctx.status = 200
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
exports.fetchDefinitions = async ctx => {
|
|
11
|
+
ctx.body = MIGRATIONS
|
|
12
|
+
ctx.status = 200
|
|
13
|
+
}
|