diff --git a/packages/auth/src/db/Replication.js b/packages/auth/src/db/Replication.js index 9720776413..931bc3d496 100644 --- a/packages/auth/src/db/Replication.js +++ b/packages/auth/src/db/Replication.js @@ -31,7 +31,7 @@ class Replication { * Two way replication operation, intended to be promise based. * @param {Object} opts - PouchDB replication options */ - sync(opts) { + sync(opts = {}) { this.replication = this.promisify(this.source.sync, opts) return this.replication } @@ -40,7 +40,7 @@ class Replication { * One way replication operation, intended to be promise based. * @param {Object} opts - PouchDB replication options */ - replicate(opts) { + replicate(opts = {}) { this.replication = this.promisify(this.source.replicate.to, opts) return this.replication } @@ -61,8 +61,13 @@ class Replication { }) } + /** + * Rollback the target DB back to the state of the source DB + */ async rollback() { await this.target.destroy() + // Recreate the DB again + this.target = getDB(this.target.name) await this.replicate() } diff --git a/packages/auth/src/db/utils.js b/packages/auth/src/db/utils.js index f065f9f89a..b5e5242cb5 100644 --- a/packages/auth/src/db/utils.js +++ b/packages/auth/src/db/utils.js @@ -13,6 +13,9 @@ exports.StaticDatabases = { GLOBAL: { name: "global-db", }, + DEPLOYMENTS: { + name: "deployments", + }, } const DocumentTypes = { @@ -22,6 +25,7 @@ const DocumentTypes = { TEMPLATE: "template", APP: "app", APP_DEV: "app_dev", + APP_METADATA: "app_metadata", ROLE: "role", } @@ -137,6 +141,18 @@ exports.getRoleParams = (roleId = null, otherProps = {}) => { return getDocParams(DocumentTypes.ROLE, roleId, otherProps) } +/** + * Convert a development app ID to a deployed app ID. + */ +exports.getDeployedAppID = appId => { + // if dev, convert it + if (appId.startsWith(exports.APP_DEV_PREFIX)) { + const id = appId.split(exports.APP_DEV_PREFIX)[1] + return `${exports.APP_PREFIX}${id}` + } + return appId +} + /** * Lots of different points in the system need to find the full list of apps, this will * enumerate the entire CouchDB cluster and get the list of databases (every app). @@ -150,7 +166,7 @@ exports.getAllApps = async (devApps = false) => { const appDbNames = allDbs.filter(dbName => dbName.startsWith(exports.APP_PREFIX) ) - const appPromises = appDbNames.map(db => new CouchDB(db).get(db)) + const appPromises = appDbNames.map(db => new CouchDB(db).get(DocumentTypes.APP_METADATA)) if (appPromises.length === 0) { return [] } else { @@ -160,9 +176,9 @@ exports.getAllApps = async (devApps = false) => { .map(({ value }) => value) return apps.filter(app => { if (devApps) { - return app._id.startsWith(exports.APP_DEV_PREFIX) + return app.appId.startsWith(exports.APP_DEV_PREFIX) } - return !app._id.startsWith(exports.APP_DEV_PREFIX) + return !app.appId.startsWith(exports.APP_DEV_PREFIX) }) } } diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index be553066b9..0d80065f2f 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -51,14 +51,14 @@ export const getFrontendStore = () => { store.actions = { initialise: async pkg => { const { layouts, screens, application, clientLibPath } = pkg - const components = await fetchComponentLibDefinitions(application._id) + const components = await fetchComponentLibDefinitions(application.appId) store.update(state => ({ ...state, libraries: application.componentLibraries, components, name: application.name, description: application.description, - appId: application._id, + appId: application.appId, url: application.url, layouts, screens, diff --git a/packages/builder/src/components/deploy/DeployModal.svelte b/packages/builder/src/components/deploy/DeployModal.svelte new file mode 100644 index 0000000000..5fffa4cd55 --- /dev/null +++ b/packages/builder/src/components/deploy/DeployModal.svelte @@ -0,0 +1,110 @@ + + + + +Publish + + + + The changes you have made will be published to the production version of the application. + + diff --git a/packages/builder/src/components/deploy/RevertModal.svelte b/packages/builder/src/components/deploy/RevertModal.svelte new file mode 100644 index 0000000000..c35fbd36c2 --- /dev/null +++ b/packages/builder/src/components/deploy/RevertModal.svelte @@ -0,0 +1,44 @@ + + + + + + + The changes you have made will be deleted and the application reverted back to its production state. + + diff --git a/packages/builder/src/components/start/AppCard.svelte b/packages/builder/src/components/start/AppCard.svelte index a4edb756f4..3e7d87bb0f 100644 --- a/packages/builder/src/components/start/AppCard.svelte +++ b/packages/builder/src/components/start/AppCard.svelte @@ -41,7 +41,7 @@ {/if} {#if app.lockedBy && app.lockedBy?.email === $auth.user?.email} - releaseLock(app._id)} icon="LockOpen"> + releaseLock(app.appId)} icon="LockOpen"> Release Lock {/if} diff --git a/packages/builder/src/components/start/AppRow.svelte b/packages/builder/src/components/start/AppRow.svelte index 693c717ab5..1a4ec1a152 100644 --- a/packages/builder/src/components/start/AppRow.svelte +++ b/packages/builder/src/components/start/AppRow.svelte @@ -50,7 +50,7 @@ deleteApp(app)} icon="Delete">Delete {/if} {#if app.lockedBy && app.lockedBy?.email === $auth.user?.email} - releaseLock(app._id)} icon="LockOpen"> + releaseLock(app.appId)} icon="LockOpen"> Release Lock {/if} diff --git a/packages/builder/src/components/start/CreateAppModal.svelte b/packages/builder/src/components/start/CreateAppModal.svelte index 44859fbb17..8d2ec56655 100644 --- a/packages/builder/src/components/start/CreateAppModal.svelte +++ b/packages/builder/src/components/start/CreateAppModal.svelte @@ -96,7 +96,7 @@ // Select Correct Application/DB in prep for creating user const applicationPkg = await get( - `/api/applications/${appJson._id}/appPackage` + `/api/applications/${appJson.instance._id}/appPackage` ) const pkg = await applicationPkg.json() if (applicationPkg.ok) { @@ -112,7 +112,7 @@ } const userResp = await api.post(`/api/users/metadata/self`, user) await userResp.json() - $goto(`/builder/app/${appJson._id}`) + $goto(`/builder/app/${appJson.instance._id}`) } catch (error) { console.error(error) notifications.error(error) diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte index 98846b3db7..ba4181c6cc 100644 --- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte @@ -1,10 +1,12 @@ - - - - - It's time to shine! - Publish App - - - - feedbackModal.hide()} /> - - - - diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index 01f360b6fd..0136c9cab2 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -18,6 +18,7 @@ import analytics from "analytics" import { onMount } from "svelte" import { apps } from "stores/portal" + import { auth } from "stores/backend" import download from "downloadjs" import { goto } from "@roxi/routify" import ConfirmDialog from "components/common/ConfirmDialog.svelte" @@ -61,17 +62,22 @@ } const openApp = app => { + if (app.lockedBy && app.lockedBy?.email === $auth.user?.email) { + notifications.error(`App locked by ${app.lockedBy.email}. Please allow lock to expire or have them unlock this app.`) + return + } + if (appStatus === AppStatus.DEV) { - $goto(`../../app/${app._id}`) + $goto(`../../app/${app.appId}`) } else { - window.open(`/${app._id}`, "_blank") + window.open(`/${app.appId}`, '_blank'); } } const exportApp = app => { try { download( - `/api/backups/export?appId=${app._id}&appname=${encodeURIComponent( + `/api/backups/export?appId=${app.appId}&appname=${encodeURIComponent( app.name )}` ) @@ -157,7 +163,7 @@ class:appGrid={layout === "grid"} class:appTable={layout === "table"} > - {#each $apps as app, idx (app._id)} + {#each $apps as app, idx (app.appId)} { let apps = [] for (let dbName of appDbNames) { const db = new CouchDB(dbName) - apps.push(db.get(dbName)) + apps.push(db.get(DocumentTypes.APP_METADATA)) } apps = await Promise.all(apps) const app = apps.find( @@ -32,7 +33,7 @@ const run = async () => { return } - const instanceDb = new CouchDB(app._id) + const instanceDb = new CouchDB(app.appId) const remoteDb = new CouchDB(`${remoteUrl}/${appName}`) instanceDb.replicate diff --git a/packages/server/src/api/controllers/application.js b/packages/server/src/api/controllers/application.js index b9485a3ac4..b14660b7d7 100644 --- a/packages/server/src/api/controllers/application.js +++ b/packages/server/src/api/controllers/application.js @@ -85,7 +85,6 @@ async function getAppUrlIfNotInUse(ctx) { } async function createInstance(template) { - // TODO: Do we need the normal app ID? const baseAppId = generateAppID() const appId = generateDevAppID(baseAppId) @@ -125,7 +124,7 @@ exports.fetch = async function (ctx) { if (isDev) { const locks = await getAllLocks() for (let app of apps) { - const lock = locks.find(lock => lock.appId === app._id) + const lock = locks.find(lock => lock.appId === app.appId) if (lock) { app.lockedBy = lock.user } else { @@ -156,7 +155,7 @@ exports.fetchAppDefinition = async function (ctx) { exports.fetchAppPackage = async function (ctx) { const db = new CouchDB(ctx.params.appId) - const application = await db.get(ctx.params.appId) + const application = await db.get(DocumentTypes.APP_METADATA) const [layouts, screens] = await Promise.all([getLayouts(db), getScreens(db)]) ctx.body = { @@ -181,7 +180,8 @@ exports.create = async function (ctx) { const url = await getAppUrlIfNotInUse(ctx) const appId = instance._id const newApplication = { - _id: appId, + _id: DocumentTypes.APP_METADATA, + appId: instance._id, type: "app", version: packageJson.version, componentLibraries: ["@budibase/standard-components"], @@ -244,7 +244,7 @@ exports.delete = async function (ctx) { } const createEmptyAppPackage = async (ctx, app) => { - const db = new CouchDB(app._id) + const db = new CouchDB(app.instance._id) let screensAndLayouts = [] for (let layout of BASE_LAYOUTS) { diff --git a/packages/server/src/api/controllers/component.js b/packages/server/src/api/controllers/component.js index 60e1e99e35..c678d8e587 100644 --- a/packages/server/src/api/controllers/component.js +++ b/packages/server/src/api/controllers/component.js @@ -1,10 +1,11 @@ const CouchDB = require("../../db") +const { DocumentTypes } = require("../../db/utils") const { getComponentLibraryManifest } = require("../../utilities/fileSystem") exports.fetchAppComponentDefinitions = async function (ctx) { const appId = ctx.params.appId || ctx.appId const db = new CouchDB(appId) - const app = await db.get(appId) + const app = await db.get(DocumentTypes.APP_METADATA) let componentManifests = await Promise.all( app.componentLibraries.map(async library => { diff --git a/packages/server/src/api/controllers/deploy/index.js b/packages/server/src/api/controllers/deploy/index.js index 6aab3bc3dd..f5db81e6e8 100644 --- a/packages/server/src/api/controllers/deploy/index.js +++ b/packages/server/src/api/controllers/deploy/index.js @@ -1,6 +1,8 @@ const PouchDB = require("../../../db") const Deployment = require("./Deployment") -const { Replication } = require("@budibase/auth/db") +const { Replication, StaticDatabases } = require("@budibase/auth/db") +const { DocumentTypes } = require("../../../db/utils") + // the max time we can wait for an invalidation to complete before considering it failed const MAX_PENDING_TIME_MS = 30 * 60000 const DeploymentStatus = { @@ -26,16 +28,16 @@ async function checkAllDeployments(deployments) { return { updated, deployments } } -async function storeLocalDeploymentHistory(deployment) { +async function storeDeploymentHistory(deployment) { const appId = deployment.getAppId() const deploymentJSON = deployment.getJSON() - const db = new PouchDB(appId) + const db = new PouchDB(StaticDatabases.DEPLOYMENTS.name) let deploymentDoc try { - deploymentDoc = await db.get("_local/deployments") + deploymentDoc = await db.get(appId) } catch (err) { - deploymentDoc = { _id: "_local/deployments", history: {} } + deploymentDoc = { _id: appId, history: {} } } const deploymentId = deploymentJSON._id @@ -65,12 +67,9 @@ async function deployApp(deployment) { }) await replication.replicate() - - // Strip the _dev prefix and update the appID document in the new DB const db = new PouchDB(productionAppId) - const appDoc = await db.get(deployment.appId) - appDoc._id = productionAppId - delete appDoc._rev + const appDoc = await db.get(DocumentTypes.APP_METADATA) + appDoc.appId = productionAppId appDoc.instance._id = productionAppId await db.put(appDoc) @@ -79,13 +78,17 @@ async function deployApp(deployment) { source: productionAppId, target: deployment.appId, }) - liveReplication.subscribe() + liveReplication.subscribe({ + filter: function (doc) { + return doc._id !== DocumentTypes.APP_METADATA + }, + }) deployment.setStatus(DeploymentStatus.SUCCESS) - await storeLocalDeploymentHistory(deployment) + await storeDeploymentHistory(deployment) } catch (err) { deployment.setStatus(DeploymentStatus.FAILURE, err.message) - await storeLocalDeploymentHistory(deployment) + await storeDeploymentHistory(deployment) throw { ...err, message: `Deployment Failed: ${err.message}`, @@ -95,8 +98,8 @@ async function deployApp(deployment) { exports.fetchDeployments = async function (ctx) { try { - const db = new PouchDB(ctx.appId) - const deploymentDoc = await db.get("_local/deployments") + const db = new PouchDB(StaticDatabases.DEPLOYMENTS.name) + const deploymentDoc = await db.get(ctx.appId) const { updated, deployments } = await checkAllDeployments( deploymentDoc, ctx.user @@ -112,8 +115,8 @@ exports.fetchDeployments = async function (ctx) { exports.deploymentProgress = async function (ctx) { try { - const db = new PouchDB(ctx.appId) - const deploymentDoc = await db.get("_local/deployments") + const db = new PouchDB(StaticDatabases.DEPLOYMENTS.name) + const deploymentDoc = await db.get(ctx.appId) ctx.body = deploymentDoc[ctx.params.deploymentId] } catch (err) { ctx.throw( @@ -126,7 +129,7 @@ exports.deploymentProgress = async function (ctx) { exports.deployApp = async function (ctx) { let deployment = new Deployment(ctx.appId) deployment.setStatus(DeploymentStatus.PENDING) - deployment = await storeLocalDeploymentHistory(deployment) + deployment = await storeDeploymentHistory(deployment) await deployApp(deployment) diff --git a/packages/server/src/api/controllers/dev.js b/packages/server/src/api/controllers/dev.js index 23132ea724..86b9a11c23 100644 --- a/packages/server/src/api/controllers/dev.js +++ b/packages/server/src/api/controllers/dev.js @@ -1,8 +1,11 @@ const fetch = require("node-fetch") +const CouchDB = require("../../db") const env = require("../../environment") const { checkSlashesInUrl } = require("../../utilities") const { request } = require("../../utilities/workerRequests") const { clearLock } = require("../../utilities/redis") +const { Replication } = require("@budibase/auth").db +const { DocumentTypes } = require("../../db/utils") async function redirect(ctx, method) { const { devPath } = ctx.params @@ -45,3 +48,37 @@ exports.clearLock = async ctx => { message: "Lock released successfully.", } } + +exports.revert = async ctx => { + const { appId } = ctx.params + const productionAppId = appId.replace("_dev", "") + + // App must have been deployed first + try { + const db = new CouchDB(productionAppId, { skip_setup: true }) + const info = await db.info() + if (info.error) throw info.error + } catch (err) { + return ctx.throw(400, "App has not yet been deployed") + } + + try { + const replication = new Replication({ + source: productionAppId, + target: appId, + }) + + await replication.rollback() + // update appID in reverted app to be dev version again + const db = new CouchDB(appId) + const appDoc = await db.get(DocumentTypes.APP_METADATA) + appDoc.appId = appId + appDoc.instance._id = appId + await db.put(appDoc) + ctx.body = { + message: "Reverted changes successfully.", + } + } catch (err) { + ctx.throw(400, `Unable to revert. ${err}`) + } +} diff --git a/packages/server/src/api/controllers/static/index.js b/packages/server/src/api/controllers/static/index.js index ba922cb9ad..64cfb122f7 100644 --- a/packages/server/src/api/controllers/static/index.js +++ b/packages/server/src/api/controllers/static/index.js @@ -18,6 +18,7 @@ const env = require("../../../environment") const { objectStoreUrl, clientLibraryPath } = require("../../../utilities") const { upload } = require("../../../utilities/fileSystem") const { attachmentsRelativeURL } = require("../../../utilities") +const { DocumentTypes } = require("../../../db/utils") async function prepareUpload({ s3Key, bucket, metadata, file }) { const response = await upload({ @@ -85,7 +86,7 @@ exports.serveApp = async function (ctx) { } const App = require("./templates/BudibaseApp.svelte").default const db = new CouchDB(appId, { skip_setup: true }) - const appInfo = await db.get(appId) + const appInfo = await db.get(DocumentTypes.APP_METADATA) const { head, html, css } = App.render({ title: appInfo.name, @@ -125,7 +126,7 @@ exports.serveComponentLibrary = async function (ctx) { return send(ctx, "/index.js", { root: componentLibraryPath }) } const db = new CouchDB(appId) - const appInfo = await db.get(appId) + const appInfo = await db.get(DocumentTypes.APP_METADATA) let componentLib = "componentlibrary" if (appInfo && appInfo.version) { diff --git a/packages/server/src/api/index.js b/packages/server/src/api/index.js index 31559d2e2f..332b917a76 100644 --- a/packages/server/src/api/index.js +++ b/packages/server/src/api/index.js @@ -37,7 +37,6 @@ router }) ) .use(currentApp) -// .use(development) // error handling middleware router.use(async (ctx, next) => { diff --git a/packages/server/src/api/routes/dev.js b/packages/server/src/api/routes/dev.js index 8bc7483fc6..bbc8147369 100644 --- a/packages/server/src/api/routes/dev.js +++ b/packages/server/src/api/routes/dev.js @@ -13,6 +13,8 @@ if (env.isDev() || env.isTest()) { .delete("/api/admin/:devPath(.*)", controller.redirectDelete) } -router.delete("/api/dev/:appId/lock", authorized(BUILDER), controller.clearLock) +router + .delete("/api/dev/:appId/lock", authorized(BUILDER), controller.clearLock) + .post("/api/dev/:appId/revert", authorized(BUILDER), controller.revert) module.exports = router diff --git a/packages/server/src/api/routes/tests/utilities/TestFunctions.js b/packages/server/src/api/routes/tests/utilities/TestFunctions.js index cbb7d59ce2..f10989bf56 100644 --- a/packages/server/src/api/routes/tests/utilities/TestFunctions.js +++ b/packages/server/src/api/routes/tests/utilities/TestFunctions.js @@ -21,7 +21,7 @@ exports.clearAllApps = async () => { return } for (let app of apps) { - const appId = app._id + const { appId } = app await appController.delete(new Request(null, { appId })) } } diff --git a/packages/server/src/db/utils.js b/packages/server/src/db/utils.js index c5d10c1444..ed63dff2a4 100644 --- a/packages/server/src/db/utils.js +++ b/packages/server/src/db/utils.js @@ -25,6 +25,7 @@ const AppStatus = { const DocumentTypes = { APP: CoreDocTypes.APP, APP_DEV: CoreDocTypes.APP_DEV, + APP_METADATA: CoreDocTypes.APP_METADATA, ROLE: CoreDocTypes.ROLE, TABLE: "ta", ROW: "ro", diff --git a/packages/server/src/tests/utilities/TestConfiguration.js b/packages/server/src/tests/utilities/TestConfiguration.js index b3f5d5ce04..cd33f14cd1 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.js +++ b/packages/server/src/tests/utilities/TestConfiguration.js @@ -89,7 +89,7 @@ class TestConfiguration { if (this.server) { this.server.close() } - cleanup(this.allApps.map(app => app._id)) + cleanup(this.allApps.map(app => app.appId)) } defaultHeaders() { @@ -141,7 +141,7 @@ class TestConfiguration { async createApp(appName) { this.app = await this._req({ name: appName }, null, controllers.app.create) - this.appId = this.app._id + this.appId = this.app.appId this.allApps.push(this.app) return this.app } diff --git a/packages/server/src/utilities/index.js b/packages/server/src/utilities/index.js index 80852f8c04..1c85d9c7b4 100644 --- a/packages/server/src/utilities/index.js +++ b/packages/server/src/utilities/index.js @@ -1,6 +1,4 @@ const env = require("../environment") -const { APP_PREFIX } = require("../db/utils") -const CouchDB = require("../db") const { OBJ_STORE_DIRECTORY, ObjectStoreBuckets } = require("../constants") const { getAllApps } = require("@budibase/auth/db") diff --git a/packages/server/src/utilities/workerRequests.js b/packages/server/src/utilities/workerRequests.js index aecc79eaa6..14296aa94b 100644 --- a/packages/server/src/utilities/workerRequests.js +++ b/packages/server/src/utilities/workerRequests.js @@ -2,6 +2,7 @@ const fetch = require("node-fetch") const env = require("../environment") const { checkSlashesInUrl } = require("./index") const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles") +const { getDeployedAppID } = require("@budibase/auth/db") function getAppRole(appId, user) { if (!user.roles) { @@ -95,6 +96,8 @@ exports.deleteGlobalUser = async (ctx, globalId) => { } exports.getGlobalUsers = async (ctx, appId = null, globalId = null) => { + // always use the deployed app + appId = getDeployedAppID(appId) const endpoint = globalId ? `/api/admin/users/${globalId}` : `/api/admin/users` @@ -119,9 +122,14 @@ exports.saveGlobalUser = async (ctx, appId, body) => { const globalUser = body._id ? await exports.getGlobalUsers(ctx, appId, body._id) : {} - const roles = globalUser.roles || {} + const preRoles = globalUser.roles || {} if (body.roleId) { - roles[appId] = body.roleId + preRoles[appId] = body.roleId + } + // make sure no dev app IDs in roles + const roles = {} + for (let [appId, roleId] of Object.entries(preRoles)) { + roles[getDeployedAppID(appId)] = roleId } const endpoint = `/api/admin/users` const reqCfg = { diff --git a/packages/worker/src/api/controllers/admin/roles.js b/packages/worker/src/api/controllers/admin/roles.js index 3bb5647ca7..8ef45d3765 100644 --- a/packages/worker/src/api/controllers/admin/roles.js +++ b/packages/worker/src/api/controllers/admin/roles.js @@ -1,24 +1,37 @@ const { getAllRoles } = require("@budibase/auth/roles") -const { getAllApps } = require("@budibase/auth/db") +const { getAllApps, getDeployedAppID, DocumentTypes } = require("@budibase/auth/db") +const CouchDB = require("../../../db") exports.fetch = async ctx => { // always use the dev apps as they'll be most up to date (true) const apps = await getAllApps(true) const promises = [] for (let app of apps) { - promises.push(getAllRoles(app._id)) + // use dev app IDs + promises.push(getAllRoles(app.appId)) } const roles = await Promise.all(promises) const response = {} for (let app of apps) { - response[app._id] = roles.shift() + const deployedAppId = getDeployedAppID(app.appId) + response[deployedAppId] = { + roles: roles.shift(), + name: app.name, + version: app.version, + url: app.url, + } } ctx.body = response } exports.find = async ctx => { const appId = ctx.params.appId + const db = new CouchDB(appId) + const app = await db.get(DocumentTypes.APP_METADATA) ctx.body = { roles: await getAllRoles(appId), + name: app.name, + version: app.version, + url: app.url, } } diff --git a/packages/worker/src/api/controllers/app.js b/packages/worker/src/api/controllers/app.js index bed3b55942..8b556fbb1e 100644 --- a/packages/worker/src/api/controllers/app.js +++ b/packages/worker/src/api/controllers/app.js @@ -1,4 +1,5 @@ const fetch = require("node-fetch") +const { DocumentTypes } = require("@budibase/auth").db const CouchDB = require("../../db") const env = require("../../environment") @@ -14,7 +15,9 @@ exports.getApps = async ctx => { allDbs = await CouchDB.allDbs() } const appDbNames = allDbs.filter(dbName => dbName.startsWith(APP_PREFIX)) - const appPromises = appDbNames.map(db => new CouchDB(db).get(db)) + const appPromises = appDbNames.map(db => + new CouchDB(db).get(DocumentTypes.APP_METADATA) + ) const apps = await Promise.allSettled(appPromises) const body = {} @@ -26,7 +29,7 @@ exports.getApps = async ctx => { let url = app.url || encodeURI(`${app.name}`) url = `/${url.replace(URL_REGEX_SLASH, "")}` body[url] = { - appId: app._id, + appId: app.instance._id, name: app.name, url, }