Enable encrypting

This commit is contained in:
Adria Navarro 2023-06-09 16:26:48 +01:00
parent 4acfc623b4
commit 978591e2ba
3 changed files with 52 additions and 6 deletions

View File

@ -1,4 +1,6 @@
import crypto from "crypto"
import fs from "fs"
import zlib from "zlib"
import env from "../environment"
const ALGO = "aes-256-ctr"
@ -60,3 +62,24 @@ export function decrypt(
const final = decipher.final()
return Buffer.concat([base, final]).toString()
}
export async function encryptFile(filePath: string, secret: string) {
const outputFilePath = `${filePath}.enc`
const inputFile = fs.createReadStream(filePath)
const outputFile = fs.createWriteStream(outputFilePath)
const salt = crypto.randomBytes(RANDOM_BYTES)
const stretched = stretchString(secret, salt)
const cipher = crypto.createCipheriv(ALGO, stretched, salt)
const encrypted = inputFile.pipe(cipher).pipe(zlib.createGzip())
encrypted.pipe(outputFile)
return new Promise<string>(r => {
outputFile.on("finish", () => {
r(outputFilePath)
})
})
}

View File

@ -4,14 +4,19 @@ import { DocumentType } from "../../db/utils"
import { isQsTrue } from "../../utilities"
export async function exportAppDump(ctx: any) {
let { appId, excludeRows } = ctx.query
let { appId, excludeRows = false, encryptPassword } = 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`
const extension = encryptPassword ? "data" : "tar.gz"
const backupIdentifier = `${appName}-export-${new Date().getTime()}.${extension}`
ctx.attachment(backupIdentifier)
ctx.body = await sdk.backups.streamExportApp(appId, excludeRows)
ctx.body = await sdk.backups.streamExportApp({
appId,
excludeRows,
encryptPassword,
})
await context.doInAppContext(appId, async () => {
const appDb = context.getAppDB()

View File

@ -1,4 +1,4 @@
import { db as dbCore, objectStore } from "@budibase/backend-core"
import { db as dbCore, encryption, objectStore } from "@budibase/backend-core"
import { budibaseTempDir } from "../../../utilities/budibaseDir"
import { streamFile, createTempFolder } from "../../../utilities/fileSystem"
import { ObjectStoreBuckets } from "../../../constants"
@ -31,6 +31,7 @@ interface ExportOpts extends DBDumpOpts {
tar?: boolean
excludeRows?: boolean
excludeLogs?: boolean
encryptPassword?: string
}
function tarFilesToTmp(tmpDir: string, files: string[]) {
@ -150,7 +151,15 @@ export async function exportApp(appId: string, config?: ExportOpts) {
const tarPath = tarFilesToTmp(tmpPath, fs.readdirSync(tmpPath))
// cleanup the tmp export files as tarball returned
fs.rmSync(tmpPath, { recursive: true, force: true })
return tarPath
if (!config.encryptPassword) {
return tarPath
}
const encryptedTarPath = await encryption.encryptFile(
tarPath,
config.encryptPassword
)
return encryptedTarPath
}
// tar not requested, turn the directory where export is
else {
@ -164,11 +173,20 @@ export async function exportApp(appId: string, config?: ExportOpts) {
* @param {boolean} excludeRows Flag to state whether the export should include data.
* @returns {*} a readable stream of the backup which is written in real time
*/
export async function streamExportApp(appId: string, excludeRows: boolean) {
export async function streamExportApp({
appId,
excludeRows,
encryptPassword,
}: {
appId: string
excludeRows: boolean
encryptPassword: string
}) {
const tmpPath = await exportApp(appId, {
excludeRows,
excludeLogs: true,
tar: true,
encryptPassword,
})
return streamFile(tmpPath)
}