diff --git a/packages/builder/src/components/start/ExportAppModal.svelte b/packages/builder/src/components/start/ExportAppModal.svelte
index 948416b192..5cc3393a89 100644
--- a/packages/builder/src/components/start/ExportAppModal.svelte
+++ b/packages/builder/src/components/start/ExportAppModal.svelte
@@ -1,5 +1,11 @@
diff --git a/packages/server/src/api/controllers/backup.ts b/packages/server/src/api/controllers/backup.ts
index 53e1bd1792..60312bd36c 100644
--- a/packages/server/src/api/controllers/backup.ts
+++ b/packages/server/src/api/controllers/backup.ts
@@ -1,14 +1,22 @@
import sdk from "../../sdk"
-import { events, context } from "@budibase/backend-core"
+import { events, context, db } from "@budibase/backend-core"
import { DocumentType } from "../../db/utils"
-import { isQsTrue } from "../../utilities"
+import { Ctx } from "@budibase/types"
+
+interface ExportAppDumpRequest {
+ excludeRows: boolean
+}
+
+export async function exportAppDump(ctx: Ctx) {
+ const { appId } = ctx.query as any
+ const { excludeRows } = ctx.request.body
+
+ const [app] = await db.getAppsByIDs([appId])
+ const appName = app.name
-export async function exportAppDump(ctx: any) {
- let { appId, excludeRows } = ctx.query
// remove the 120 second limit for the request
ctx.req.setTimeout(0)
- const appName = decodeURI(ctx.query.appname)
- excludeRows = isQsTrue(excludeRows)
+
const backupIdentifier = `${appName}-export-${new Date().getTime()}.tar.gz`
ctx.attachment(backupIdentifier)
ctx.body = await sdk.backups.streamExportApp(appId, excludeRows)
diff --git a/packages/server/src/api/routes/backup.ts b/packages/server/src/api/routes/backup.ts
index fb455250a7..94e4cf957f 100644
--- a/packages/server/src/api/routes/backup.ts
+++ b/packages/server/src/api/routes/backup.ts
@@ -5,7 +5,7 @@ import { permissions } from "@budibase/backend-core"
const router: Router = new Router()
-router.get(
+router.post(
"/api/backups/export",
authorized(permissions.BUILDER),
controller.exportAppDump
diff --git a/packages/server/src/api/routes/tests/backup.spec.ts b/packages/server/src/api/routes/tests/backup.spec.ts
index ef362ef403..92e0176060 100644
--- a/packages/server/src/api/routes/tests/backup.spec.ts
+++ b/packages/server/src/api/routes/tests/backup.spec.ts
@@ -1,7 +1,9 @@
+import tk from "timekeeper"
import * as setup from "./utilities"
import { events } from "@budibase/backend-core"
import sdk from "../../../sdk"
import { checkBuilderEndpoint } from "./utilities/TestFunctions"
+import { mocks } from "@budibase/backend-core/tests"
describe("/backups", () => {
let request = setup.getRequest()
@@ -16,7 +18,7 @@ describe("/backups", () => {
describe("exportAppDump", () => {
it("should be able to export app", async () => {
const res = await request
- .get(`/api/backups/export?appId=${config.getAppId()}&appname=test`)
+ .post(`/api/backups/export?appId=${config.getAppId()}`)
.set(config.defaultHeaders())
.expect(200)
expect(res.headers["content-type"]).toEqual("application/gzip")
@@ -26,10 +28,24 @@ describe("/backups", () => {
it("should apply authorization to endpoint", async () => {
await checkBuilderEndpoint({
config,
- method: "GET",
+ method: "POST",
url: `/api/backups/export?appId=${config.getAppId()}`,
})
})
+
+ it("should infer the app name from the app", async () => {
+ tk.freeze(mocks.date.MOCK_DATE)
+
+ const res = await request
+ .post(`/api/backups/export?appId=${config.getAppId()}`)
+ .set(config.defaultHeaders())
+
+ expect(res.headers["content-disposition"]).toEqual(
+ `attachment; filename="${
+ config.getApp()!.name
+ }-export-${mocks.date.MOCK_DATE.getTime()}.tar.gz"`
+ )
+ })
})
describe("calculateBackupStats", () => {