diff --git a/packages/builder/src/components/settings/Modal.svelte b/packages/builder/src/components/settings/Modal.svelte index 2d832481c3..dc6809f488 100644 --- a/packages/builder/src/components/settings/Modal.svelte +++ b/packages/builder/src/components/settings/Modal.svelte @@ -1,5 +1,5 @@ + +API Keys +
+
+ updateKey(['budibase', e.detail])} + thin + edit + value={keys.budibase} + label="Budibase" /> +
+
+ updateKey(['sendgrid', e.detail])} + thin + edit + value={keys.sendgrid} + label="Sendgrid" /> +
+
+ + diff --git a/packages/builder/src/components/settings/tabs/index.js b/packages/builder/src/components/settings/tabs/index.js index a1d1df38e4..6e34141d09 100644 --- a/packages/builder/src/components/settings/tabs/index.js +++ b/packages/builder/src/components/settings/tabs/index.js @@ -2,4 +2,5 @@ export { default as General } from "./General.svelte" export { default as Integrations } from "./Integrations.svelte" export { default as Permissions } from "./Permissions.svelte" export { default as Users } from "./Users.svelte" +export { default as APIKeys } from "./APIKeys.svelte" export { default as DangerZone } from "./DangerZone.svelte" diff --git a/packages/server/src/api/controllers/apikeys.js b/packages/server/src/api/controllers/apikeys.js new file mode 100644 index 0000000000..35fc29e37e --- /dev/null +++ b/packages/server/src/api/controllers/apikeys.js @@ -0,0 +1,52 @@ +const fs = require("fs") +const readline = require("readline") +const { budibaseAppsDir } = require("../../utilities/budibaseDir") +const ENV_FILE_PATH = "/.env" + +exports.fetch = async function(ctx) { + ctx.status = 200 + ctx.body = { + budibase: process.env.BUDIBASE_API_KEY, + sendgrid: process.env.SENDGRID_API_KEY, + } +} + +exports.update = async function(ctx) { + const key = `${ctx.params.key.toUpperCase()}_API_KEY` + const value = ctx.request.body.value + // Set process.env + process.env[key] = value + + // Write to file + await updateValues([key, value]) + + ctx.status = 200 + ctx.message = `Updated ${ctx.params.key} API key succesfully.` + ctx.body = { [ctx.params.key]: ctx.request.body.value } +} + +async function updateValues([key, value]) { + let newContent = "" + let keyExists = false + const readInterface = readline.createInterface({ + input: fs.createReadStream(`${budibaseAppsDir()}/${ENV_FILE_PATH}`), + output: process.stdout, + console: false, + }) + readInterface.on("line", function(line) { + // Mutate lines and change API Key + if (line.startsWith(key)) { + line = `${key}=${value}` + keyExists = true + } + newContent = `${newContent}\n${line}` + }) + readInterface.on("close", function() { + // Write file here + if (!keyExists) { + // Add API Key if it doesn't exist in the file at all + newContent = `${newContent}\n${key}=${value}` + } + fs.writeFileSync(`${budibaseAppsDir()}/${ENV_FILE_PATH}`, newContent) + }) +} diff --git a/packages/server/src/api/index.js b/packages/server/src/api/index.js index e6143d6725..911b8f7c66 100644 --- a/packages/server/src/api/index.js +++ b/packages/server/src/api/index.js @@ -17,6 +17,7 @@ const { componentRoutes, workflowRoutes, accesslevelRoutes, + apiKeysRoutes, } = require("./routes") const router = new Router() @@ -98,6 +99,9 @@ router.use(clientRoutes.allowedMethods()) router.use(accesslevelRoutes.routes()) router.use(accesslevelRoutes.allowedMethods()) +router.use(apiKeysRoutes.routes()) +router.use(apiKeysRoutes.allowedMethods()) + router.use(staticRoutes.routes()) router.use(staticRoutes.allowedMethods()) diff --git a/packages/server/src/api/routes/apikeys.js b/packages/server/src/api/routes/apikeys.js new file mode 100644 index 0000000000..bec9ab677c --- /dev/null +++ b/packages/server/src/api/routes/apikeys.js @@ -0,0 +1,12 @@ +const Router = require("@koa/router") +const controller = require("../controllers/apikeys") +const authorized = require("../../middleware/authorized") +const { BUILDER } = require("../../utilities/accessLevels") + +const router = Router() + +router + .get("/api/keys", authorized(BUILDER), controller.fetch) + .put("/api/keys/:key", authorized(BUILDER), controller.update) + +module.exports = router diff --git a/packages/server/src/api/routes/index.js b/packages/server/src/api/routes/index.js index b50fee788a..50a652b39e 100644 --- a/packages/server/src/api/routes/index.js +++ b/packages/server/src/api/routes/index.js @@ -11,6 +11,7 @@ const staticRoutes = require("./static") const componentRoutes = require("./component") const workflowRoutes = require("./workflow") const accesslevelRoutes = require("./accesslevel") +const apiKeysRoutes = require("./apikeys") module.exports = { authRoutes, @@ -26,4 +27,5 @@ module.exports = { componentRoutes, workflowRoutes, accesslevelRoutes, + apiKeysRoutes, }