From 6a4877159dd4a13d81525d85c31571af676ec06a Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Oct 2023 17:43:14 +0100 Subject: [PATCH 1/2] Quick fix to make sure that the important components of the app metadata are correctly updated - as well as adjusting the import modal to check if the export is encrypted. --- .../components/start/ImportAppModal.svelte | 1 + .../server/src/sdk/app/applications/import.ts | 41 +++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/components/start/ImportAppModal.svelte b/packages/builder/src/components/start/ImportAppModal.svelte index 7d30ded896..1bc32dc7a4 100644 --- a/packages/builder/src/components/start/ImportAppModal.svelte +++ b/packages/builder/src/components/start/ImportAppModal.svelte @@ -54,6 +54,7 @@ label="App export" on:change={e => { file = e.detail?.[0] + encrypted = file?.name?.endsWith(".enc.tar.gz") }} /> diff --git a/packages/server/src/sdk/app/applications/import.ts b/packages/server/src/sdk/app/applications/import.ts index a7788924d8..158e4772b2 100644 --- a/packages/server/src/sdk/app/applications/import.ts +++ b/packages/server/src/sdk/app/applications/import.ts @@ -4,6 +4,8 @@ import { Document, Database, RowValue, + DocumentType, + App, } from "@budibase/types" import backups from "../backups" @@ -12,9 +14,39 @@ export type FileAttributes = { path: string } +async function getNewAppMetadata( + tempDb: Database, + appDb: Database +): Promise { + // static doc denoting app information + const docId = DocumentType.APP_METADATA + try { + const [tempMetadata, appMetadata] = await Promise.all([ + tempDb.get(docId), + appDb.get(docId), + ]) + return { + ...appMetadata, + automationErrors: undefined, + theme: tempMetadata.theme, + customTheme: tempMetadata.customTheme, + features: tempMetadata.features, + icon: tempMetadata.icon, + navigation: tempMetadata.navigation, + type: tempMetadata.type, + version: tempMetadata.version, + } + } catch (err: any) { + throw new Error( + `Unable to retrieve app metadata for import - ${err.message}` + ) + } +} + function mergeUpdateAndDeleteDocuments( updateDocs: Document[], - deleteDocs: Document[] + deleteDocs: Document[], + metadata: App ) { // compress the documents to create and to delete (if same ID, then just update the rev) const finalToDelete = [] @@ -26,7 +58,7 @@ function mergeUpdateAndDeleteDocuments( finalToDelete.push(deleteDoc) } } - return [...updateDocs, ...finalToDelete] + return [...updateDocs, ...finalToDelete, metadata] } async function removeImportableDocuments(db: Database) { @@ -90,12 +122,15 @@ export async function updateWithExport( await backups.importApp(devId, tempDb, template, { importObjStoreContents: false, }) + const newMetadata = await getNewAppMetadata(tempDb, appDb) // get the documents to copy const toUpdate = await getImportableDocuments(tempDb) // clear out the old documents const toDelete = await removeImportableDocuments(appDb) // now bulk update documents - add new ones, delete old ones and update common ones - await appDb.bulkDocs(mergeUpdateAndDeleteDocuments(toUpdate, toDelete)) + await appDb.bulkDocs( + mergeUpdateAndDeleteDocuments(toUpdate, toDelete, newMetadata) + ) } finally { await tempDb.destroy() } From cef71ff70830c5798cd2ee546381b50443a6c57e Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 13 Oct 2023 18:03:10 +0100 Subject: [PATCH 2/2] Adding test cases for navbar update. --- .../[application]/settings/exportImport.svelte | 2 +- .../src/api/routes/tests/appImport.spec.ts | 5 ++++- .../src/tests/utilities/api/application.ts | 18 ++++++++++++++++++ .../server/src/tests/utilities/api/index.ts | 3 +++ 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 packages/server/src/tests/utilities/api/application.ts diff --git a/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte b/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte index bfa0274781..64ca0e0a2c 100644 --- a/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte +++ b/packages/builder/src/pages/builder/app/[application]/settings/exportImport.svelte @@ -13,7 +13,7 @@ import ExportAppModal from "components/start/ExportAppModal.svelte" import ImportAppModal from "components/start/ImportAppModal.svelte" - $: filteredApps = $apps.filter(app => app.devId == $store.appId) + $: filteredApps = $apps.filter(app => app.devId === $store.appId) $: app = filteredApps.length ? filteredApps[0] : {} $: appDeployed = app?.status === AppStatus.DEPLOYED diff --git a/packages/server/src/api/routes/tests/appImport.spec.ts b/packages/server/src/api/routes/tests/appImport.spec.ts index ef3c739e72..51331323de 100644 --- a/packages/server/src/api/routes/tests/appImport.spec.ts +++ b/packages/server/src/api/routes/tests/appImport.spec.ts @@ -23,7 +23,10 @@ describe("/applications/:appId/import", () => { .set(config.defaultHeaders()) .expect("Content-Type", /json/) .expect(200) - expect(res.body.message).toBe("app updated") + const appPackage = await config.api.application.get(appId!) + expect(appPackage.navigation?.links?.length).toBe(2) + expect(expect(appPackage.navigation?.links?.[0].url).toBe("/blank")) + expect(expect(appPackage.navigation?.links?.[1].url).toBe("/derp")) const screens = await config.api.screen.list() expect(screens.length).toBe(2) expect(screens[0].routing.route).toBe("/derp") diff --git a/packages/server/src/tests/utilities/api/application.ts b/packages/server/src/tests/utilities/api/application.ts new file mode 100644 index 0000000000..85bc4e4173 --- /dev/null +++ b/packages/server/src/tests/utilities/api/application.ts @@ -0,0 +1,18 @@ +import { App } from "@budibase/types" +import TestConfiguration from "../TestConfiguration" +import { TestAPI } from "./base" + +export class ApplicationAPI extends TestAPI { + constructor(config: TestConfiguration) { + super(config) + } + + get = async (appId: string): Promise => { + const result = await this.request + .get(`/api/applications/${appId}/appPackage`) + .set(this.config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + return result.body.application as App + } +} diff --git a/packages/server/src/tests/utilities/api/index.ts b/packages/server/src/tests/utilities/api/index.ts index 889133b847..fce8237760 100644 --- a/packages/server/src/tests/utilities/api/index.ts +++ b/packages/server/src/tests/utilities/api/index.ts @@ -6,6 +6,7 @@ import { ViewV2API } from "./viewV2" import { DatasourceAPI } from "./datasource" import { LegacyViewAPI } from "./legacyView" import { ScreenAPI } from "./screen" +import { ApplicationAPI } from "./application" export default class API { table: TableAPI @@ -15,6 +16,7 @@ export default class API { permission: PermissionAPI datasource: DatasourceAPI screen: ScreenAPI + application: ApplicationAPI constructor(config: TestConfiguration) { this.table = new TableAPI(config) @@ -24,5 +26,6 @@ export default class API { this.permission = new PermissionAPI(config) this.datasource = new DatasourceAPI(config) this.screen = new ScreenAPI(config) + this.application = new ApplicationAPI(config) } }