Merge pull request #413 from Budibase/features/settings-modal-api-keys-tab

Features/settings modal api keys tab
This commit is contained in:
Kevin Åberg Kultalahti 2020-07-06 14:51:30 +02:00 committed by GitHub
commit 67ad70166e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 132 additions and 1 deletions

View File

@ -1,5 +1,5 @@
<script> <script>
import { General, Users, DangerZone } from "./tabs" import { General, Users, DangerZone, APIKeys } from "./tabs"
import { Input, TextArea, Button, Switcher } from "@budibase/bbui" import { Input, TextArea, Button, Switcher } from "@budibase/bbui"
import { SettingsIcon, CloseIcon } from "components/common/Icons/" import { SettingsIcon, CloseIcon } from "components/common/Icons/"
@ -20,6 +20,11 @@
key: "USERS", key: "USERS",
component: Users, component: Users,
}, },
{
title: "API Keys",
key: "API_KEYS",
component: APIKeys,
},
{ {
title: "Danger Zone", title: "Danger Zone",
key: "DANGERZONE", key: "DANGERZONE",

View File

@ -0,0 +1,55 @@
<script>
import { Input, Button } from "@budibase/bbui"
import { store } from "builderStore"
import api from "builderStore/api"
import Title from "../TabTitle.svelte"
let keys = { budibase: "", sendGrid: "" }
async function updateKey([key, value]) {
const response = await api.put(`/api/keys/${key}`, { value })
const res = await response.json()
keys = { ...keys, ...res }
}
// Get Keys
async function fetchKeys() {
const response = await api.get(`/api/keys/`)
const res = await response.json()
keys = res
}
fetchKeys()
</script>
<Title>API Keys</Title>
<div class="container">
<div class="background">
<Input
on:save={e => updateKey(['budibase', e.detail])}
thin
edit
value={keys.budibase}
label="Budibase" />
</div>
<div class="background">
<Input
on:save={e => updateKey(['sendgrid', e.detail])}
thin
edit
value={keys.sendgrid}
label="Sendgrid" />
</div>
</div>
<style>
.container {
display: grid;
grid-gap: var(--space);
}
.background {
border-radius: 5px;
background-color: var(--light-grey);
padding: 12px 12px 18px 12px;
}
</style>

View File

@ -2,4 +2,5 @@ export { default as General } from "./General.svelte"
export { default as Integrations } from "./Integrations.svelte" export { default as Integrations } from "./Integrations.svelte"
export { default as Permissions } from "./Permissions.svelte" export { default as Permissions } from "./Permissions.svelte"
export { default as Users } from "./Users.svelte" export { default as Users } from "./Users.svelte"
export { default as APIKeys } from "./APIKeys.svelte"
export { default as DangerZone } from "./DangerZone.svelte" export { default as DangerZone } from "./DangerZone.svelte"

View File

@ -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)
})
}

View File

@ -17,6 +17,7 @@ const {
componentRoutes, componentRoutes,
workflowRoutes, workflowRoutes,
accesslevelRoutes, accesslevelRoutes,
apiKeysRoutes,
} = require("./routes") } = require("./routes")
const router = new Router() const router = new Router()
@ -98,6 +99,9 @@ router.use(clientRoutes.allowedMethods())
router.use(accesslevelRoutes.routes()) router.use(accesslevelRoutes.routes())
router.use(accesslevelRoutes.allowedMethods()) router.use(accesslevelRoutes.allowedMethods())
router.use(apiKeysRoutes.routes())
router.use(apiKeysRoutes.allowedMethods())
router.use(staticRoutes.routes()) router.use(staticRoutes.routes())
router.use(staticRoutes.allowedMethods()) router.use(staticRoutes.allowedMethods())

View File

@ -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

View File

@ -11,6 +11,7 @@ const staticRoutes = require("./static")
const componentRoutes = require("./component") const componentRoutes = require("./component")
const workflowRoutes = require("./workflow") const workflowRoutes = require("./workflow")
const accesslevelRoutes = require("./accesslevel") const accesslevelRoutes = require("./accesslevel")
const apiKeysRoutes = require("./apikeys")
module.exports = { module.exports = {
authRoutes, authRoutes,
@ -26,4 +27,5 @@ module.exports = {
componentRoutes, componentRoutes,
workflowRoutes, workflowRoutes,
accesslevelRoutes, accesslevelRoutes,
apiKeysRoutes,
} }