Merge pull request #14091 from Budibase/merge-env-vars

Move secrets into backend-core.
This commit is contained in:
Sam Rose 2024-07-03 17:16:21 +01:00 committed by GitHub
commit 6420dc7d5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 46 additions and 65 deletions

View File

@ -200,6 +200,9 @@ const environment = {
}, },
ROLLING_LOG_MAX_SIZE: process.env.ROLLING_LOG_MAX_SIZE || "10M", ROLLING_LOG_MAX_SIZE: process.env.ROLLING_LOG_MAX_SIZE || "10M",
DISABLE_SCIM_CALLS: process.env.DISABLE_SCIM_CALLS, DISABLE_SCIM_CALLS: process.env.DISABLE_SCIM_CALLS,
BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL,
BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD,
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
} }
// clean up any environment variable edge cases // clean up any environment variable edge cases

View File

@ -1,23 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
module SendgridMock {
class Email {
constructor() {
// @ts-ignore
this.apiKey = null
}
setApiKey(apiKey: any) {
// @ts-ignore
this.apiKey = apiKey
}
async send(msg: any) {
if (msg.to === "invalid@example.com") {
throw "Invalid"
}
return msg
}
}
module.exports = new Email()
}

View File

@ -7,8 +7,8 @@ import {
AutomationStepType, AutomationStepType,
AutomationIOType, AutomationIOType,
} from "@budibase/types" } from "@budibase/types"
import { env } from "@budibase/backend-core"
import * as automationUtils from "../automationUtils" import * as automationUtils from "../automationUtils"
import environment from "../../environment"
enum Model { enum Model {
GPT_35_TURBO = "gpt-3.5-turbo", GPT_35_TURBO = "gpt-3.5-turbo",
@ -60,7 +60,7 @@ export const definition: AutomationStepSchema = {
} }
export async function run({ inputs }: AutomationStepInput) { export async function run({ inputs }: AutomationStepInput) {
if (!environment.OPENAI_API_KEY) { if (!env.OPENAI_API_KEY) {
return { return {
success: false, success: false,
response: response:
@ -77,7 +77,7 @@ export async function run({ inputs }: AutomationStepInput) {
try { try {
const openai = new OpenAI({ const openai = new OpenAI({
apiKey: environment.OPENAI_API_KEY, apiKey: env.OPENAI_API_KEY,
}) })
const completion = await openai.chat.completions.create({ const completion = await openai.chat.completions.create({

View File

@ -1,6 +1,4 @@
const setup = require("./utilities") import { getConfig, runStep, afterAll as _afterAll } from "./utilities"
import environment from "../../environment"
import { OpenAI } from "openai" import { OpenAI } from "openai"
jest.mock("openai", () => ({ jest.mock("openai", () => ({
@ -26,42 +24,41 @@ const mockedOpenAI = OpenAI as jest.MockedClass<typeof OpenAI>
const OPENAI_PROMPT = "What is the meaning of life?" const OPENAI_PROMPT = "What is the meaning of life?"
describe("test the openai action", () => { describe("test the openai action", () => {
let config = setup.getConfig() let config = getConfig()
let resetEnv: () => void | undefined
beforeAll(async () => { beforeAll(async () => {
await config.init() await config.init()
}) })
beforeEach(() => { beforeEach(() => {
environment.OPENAI_API_KEY = "abc123" resetEnv = config.setCoreEnv({ OPENAI_API_KEY: "abc123" })
}) })
afterAll(setup.afterAll) afterEach(() => {
resetEnv()
})
afterAll(_afterAll)
it("should present the correct error message when the OPENAI_API_KEY variable isn't set", async () => { it("should present the correct error message when the OPENAI_API_KEY variable isn't set", async () => {
delete environment.OPENAI_API_KEY await config.withCoreEnv({ OPENAI_API_KEY: "" }, async () => {
let res = await runStep("OPENAI", { prompt: OPENAI_PROMPT })
let res = await setup.runStep("OPENAI", {
prompt: OPENAI_PROMPT,
})
expect(res.response).toEqual( expect(res.response).toEqual(
"OpenAI API Key not configured - please add the OPENAI_API_KEY environment variable." "OpenAI API Key not configured - please add the OPENAI_API_KEY environment variable."
) )
expect(res.success).toBeFalsy() expect(res.success).toBeFalsy()
}) })
})
it("should be able to receive a response from ChatGPT given a prompt", async () => { it("should be able to receive a response from ChatGPT given a prompt", async () => {
const res = await setup.runStep("OPENAI", { const res = await runStep("OPENAI", { prompt: OPENAI_PROMPT })
prompt: OPENAI_PROMPT,
})
expect(res.response).toEqual("This is a test") expect(res.response).toEqual("This is a test")
expect(res.success).toBeTruthy() expect(res.success).toBeTruthy()
}) })
it("should present the correct error message when a prompt is not provided", async () => { it("should present the correct error message when a prompt is not provided", async () => {
const res = await setup.runStep("OPENAI", { const res = await runStep("OPENAI", { prompt: null })
prompt: null,
})
expect(res.response).toEqual( expect(res.response).toEqual(
"Budibase OpenAI Automation Failed: No prompt supplied" "Budibase OpenAI Automation Failed: No prompt supplied"
) )
@ -84,7 +81,7 @@ describe("test the openai action", () => {
} as any) } as any)
) )
const res = await setup.runStep("OPENAI", { const res = await runStep("OPENAI", {
prompt: OPENAI_PROMPT, prompt: OPENAI_PROMPT,
}) })

View File

@ -75,16 +75,12 @@ const environment = {
AUTOMATION_MAX_ITERATIONS: AUTOMATION_MAX_ITERATIONS:
parseIntSafe(process.env.AUTOMATION_MAX_ITERATIONS) || parseIntSafe(process.env.AUTOMATION_MAX_ITERATIONS) ||
DEFAULTS.AUTOMATION_MAX_ITERATIONS, DEFAULTS.AUTOMATION_MAX_ITERATIONS,
SENDGRID_API_KEY: process.env.SENDGRID_API_KEY,
DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT, DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT,
QUERY_THREAD_TIMEOUT: QUERY_THREAD_TIMEOUT, QUERY_THREAD_TIMEOUT: QUERY_THREAD_TIMEOUT,
AUTOMATION_THREAD_TIMEOUT: AUTOMATION_THREAD_TIMEOUT:
parseIntSafe(process.env.AUTOMATION_THREAD_TIMEOUT) || parseIntSafe(process.env.AUTOMATION_THREAD_TIMEOUT) ||
DEFAULT_AUTOMATION_TIMEOUT, DEFAULT_AUTOMATION_TIMEOUT,
BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL,
BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD,
PLUGINS_DIR: process.env.PLUGINS_DIR || DEFAULTS.PLUGINS_DIR, PLUGINS_DIR: process.env.PLUGINS_DIR || DEFAULTS.PLUGINS_DIR,
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
MAX_IMPORT_SIZE_MB: process.env.MAX_IMPORT_SIZE_MB, MAX_IMPORT_SIZE_MB: process.env.MAX_IMPORT_SIZE_MB,
SESSION_EXPIRY_SECONDS: process.env.SESSION_EXPIRY_SECONDS, SESSION_EXPIRY_SECONDS: process.env.SESSION_EXPIRY_SECONDS,
// SQL // SQL

View File

@ -8,6 +8,7 @@ import {
tenancy, tenancy,
users, users,
cache, cache,
env as coreEnv,
} from "@budibase/backend-core" } from "@budibase/backend-core"
import { watch } from "../watch" import { watch } from "../watch"
import * as automations from "../automations" import * as automations from "../automations"
@ -132,8 +133,8 @@ export async function startup(
// check and create admin user if required // check and create admin user if required
// this must be run after the api has been initialised due to // this must be run after the api has been initialised due to
// the app user sync // the app user sync
const bbAdminEmail = env.BB_ADMIN_USER_EMAIL, const bbAdminEmail = coreEnv.BB_ADMIN_USER_EMAIL,
bbAdminPassword = env.BB_ADMIN_USER_PASSWORD bbAdminPassword = coreEnv.BB_ADMIN_USER_PASSWORD
if ( if (
env.SELF_HOSTED && env.SELF_HOSTED &&
!env.MULTI_TENANCY && !env.MULTI_TENANCY &&

View File

@ -14,11 +14,15 @@ describe("check BB_ADMIN environment variables", () => {
await tenancy.doInTenant(tenancy.DEFAULT_TENANT_ID, async () => { await tenancy.doInTenant(tenancy.DEFAULT_TENANT_ID, async () => {
await config.withEnv( await config.withEnv(
{ {
BB_ADMIN_USER_EMAIL: EMAIL,
BB_ADMIN_USER_PASSWORD: PASSWORD,
MULTI_TENANCY: "0", MULTI_TENANCY: "0",
SELF_HOSTED: "1", SELF_HOSTED: "1",
}, },
() =>
config.withCoreEnv(
{
BB_ADMIN_USER_EMAIL: EMAIL,
BB_ADMIN_USER_PASSWORD: PASSWORD,
},
async () => { async () => {
await startup({ rerun: true }) await startup({ rerun: true })
const user = await users.getGlobalUserByEmail(EMAIL, { const user = await users.getGlobalUserByEmail(EMAIL, {
@ -26,9 +30,12 @@ describe("check BB_ADMIN environment variables", () => {
}) })
expect(user).toBeDefined() expect(user).toBeDefined()
expect(user?.password).toBeDefined() expect(user?.password).toBeDefined()
expect(await utils.compare(PASSWORD, user?.password!)).toEqual(true) expect(await utils.compare(PASSWORD, user?.password!)).toEqual(
true
)
} }
) )
)
}) })
}) })
}) })

View File

@ -290,7 +290,7 @@ export default class TestConfiguration {
* that can be called to reset the environment variables to their original values. * that can be called to reset the environment variables to their original values.
*/ */
setCoreEnv(newEnvVars: Partial<typeof coreEnv>): () => void { setCoreEnv(newEnvVars: Partial<typeof coreEnv>): () => void {
const oldEnv = cloneDeep(env) const oldEnv = cloneDeep(coreEnv)
let key: keyof typeof newEnvVars let key: keyof typeof newEnvVars
for (key in newEnvVars) { for (key in newEnvVars) {