diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index 49c2c147a6..451da5fa8f 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -1,3 +1,4 @@ +import fs from "fs" import { Integration, DatasourceFieldType, @@ -22,6 +23,7 @@ import { escapeDangerousCharacters } from "../utilities" import { Client, ClientConfig, types } from "pg" import { exec } from "child_process" +import { storeTempFile } from "../utilities/fileSystem" // Return "date" and "timestamp" types as plain strings. // This lets us reference the original stored timezone. @@ -385,11 +387,36 @@ class PostgresIntegration extends Sql implements DatasourcePlus { async getSchema() { const dumpCommandParts = [ - `PGPASSWORD="${this.config.password}"`, - `pg_dump -U ${this.config.user} -h ${this.config.host} -p ${this.config.port} -d ${this.config.database} --schema-only`, + `user=${this.config.user}`, + `host=${this.config.host}`, + `port=${this.config.port}`, + `dbname=${this.config.database}`, ] - const dumpCommand = dumpCommandParts.join(" ") + if (this.config.ssl) { + dumpCommandParts.push("sslmode=verify-ca") + if (this.config.ca) { + const caFilePath = storeTempFile(this.config.ca) + fs.chmodSync(caFilePath, "0600") + dumpCommandParts.push(`sslrootcert=${caFilePath}`) + } + + if (this.config.clientCert) { + const clientCertFilePath = storeTempFile(this.config.clientCert) + fs.chmodSync(clientCertFilePath, "0600") + dumpCommandParts.push(`sslcert=${clientCertFilePath}`) + } + + if (this.config.clientKey) { + const clientKeyFilePath = storeTempFile(this.config.clientKey) + fs.chmodSync(clientKeyFilePath, "0600") + dumpCommandParts.push(`sslkey=${clientKeyFilePath}`) + } + } + + const dumpCommand = `PGPASSWORD="${ + this.config.password + }" pg_dump --schema-only "${dumpCommandParts.join(" ")}"` return new Promise((res, rej) => { exec(dumpCommand, (error, stdout, stderr) => { diff --git a/packages/server/src/utilities/fileSystem/filesystem.ts b/packages/server/src/utilities/fileSystem/filesystem.ts index 9434f071d4..a44fa03c28 100644 --- a/packages/server/src/utilities/fileSystem/filesystem.ts +++ b/packages/server/src/utilities/fileSystem/filesystem.ts @@ -81,7 +81,9 @@ export const streamFile = (path: string) => { * @param {string} fileContents contents which will be written to a temp file. * @return {string} the path to the temp file. */ -export const storeTempFile = (fileContents: any) => { +export const storeTempFile = ( + fileContents: string | NodeJS.ArrayBufferView +) => { const path = join(budibaseTempDir(), uuid()) fs.writeFileSync(path, fileContents) return path