Merge pull request #413 from Budibase/features/settings-modal-api-keys-tab
Features/settings modal api keys tab
This commit is contained in:
commit
67ad70166e
|
@ -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",
|
||||||
|
|
|
@ -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>
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
})
|
||||||
|
}
|
|
@ -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())
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue