improve structure of OIDC config

This commit is contained in:
Peter Clement 2021-07-13 14:54:20 +01:00
parent 6c8a025760
commit af792cc09e
9 changed files with 82 additions and 30 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -10,7 +10,7 @@
notifications,
} from "@budibase/bbui"
import { goto, params } from "@roxi/routify"
import { auth, organisation } from "stores/portal"
import { auth, organisation, oidc } from "stores/portal"
import GoogleButton from "./_components/GoogleButton.svelte"
import OIDCButton from "./_components/OIDCButton.svelte"
import Logo from "assets/bb-emblem.svg"
@ -50,6 +50,7 @@
onMount(async () => {
await organisation.init()
await oidc.init()
})
</script>
@ -62,10 +63,7 @@
<Heading>Sign in to {company}</Heading>
</Layout>
<GoogleButton />
<OIDCButton
oidcIcon={$organisation.oidcIcon}
oidcName={$organisation.oidcName}
/>
<OIDCButton oidcIcon={$oidc.logo} oidcName={$oidc.name} />
<Divider noGrid />
<Layout gap="XS" noPadding>
<Body size="S" textAlign="center">Sign in with email</Body>

View File

@ -2,7 +2,6 @@
import GoogleLogo from "./_logos/Google.svelte"
import OidcLogo from "./_logos/OIDC.svelte"
import MicrosoftLogo from "assets/microsoft-logo.png"
import OracleLogo from "assets/oracle-logo.png"
import Auth0Logo from "assets/auth0-logo.png"
import OidcLogoPng from "assets/oidc-logo.png"
@ -19,14 +18,8 @@
} from "@budibase/bbui"
import { onMount } from "svelte"
import api from "builderStore/api"
import { writable } from "svelte/store"
import { organisation } from "stores/portal"
const values = writable({
oidcIcon: $organisation.oidcIcon,
oidcName: $organisation.oidcName,
})
const ConfigTypes = {
Google: "google",
OIDC: "oidc",
@ -58,11 +51,10 @@
let iconDropdownOptions = [
{
label: "Azure AD",
value: "AD",
label: "Microsoft",
value: "Microsoft",
icon: MicrosoftLogo,
},
{ label: "Oracle", value: "Oracle", icon: OracleLogo },
{ label: "Auth0", value: "Auth0", icon: Auth0Logo },
{ label: "OIDC", value: "Oidc", icon: OidcLogoPng },
@ -88,9 +80,8 @@
const onFileSelected = e => {
let fileName = e.target.files[0].name
image = e.target.files[0]
$values.oidcIcon = fileName
providers.oidc.config.configs[0].logo = fileName
iconDropdownOptions.unshift({ label: fileName, value: fileName })
image && uploadLogo(image)
}
const providers = { google, oidc }
@ -98,7 +89,6 @@
async function save(docs) {
// only if the user has provided an image, upload it.
image && uploadLogo(image)
await organisation.save($values)
let calls = []
docs.forEach(element => {
calls.push(api.post(`/api/admin/configs`, element))
@ -164,7 +154,7 @@
if (!oidcDoc._id) {
providers.oidc = {
type: ConfigTypes.OIDC,
config: {},
config: { configs: [{}] },
}
} else {
providers.oidc = oidcDoc
@ -194,7 +184,7 @@
To allow users to authenticate using their Google accounts, fill out the
fields below.
</Body>
</Layout>
</Layout>dddd
<Layout gap="XS" noPadding>
{#each GoogleConfigFields.Google as field}
<div class="form-row">
@ -221,7 +211,7 @@
{#each OIDCConfigFields.Oidc as field}
<div class="form-row">
<Label size="L">{OIDCConfigLabels.Oidc[field]}</Label>
<Input bind:value={providers.oidc.config[field]} />
<Input bind:value={providers.oidc.config.configs[0][field]} />
</div>
{/each}
<br />
@ -230,13 +220,13 @@
</Body>
<div class="form-row">
<Label size="L">Name</Label>
<Input bind:value={$values.oidcName} />
<Input bind:value={providers.oidc.config.configs[0].name} />
</div>
<div class="form-row">
<Label size="L">Icon</Label>
<Select
label=""
bind:value={$values.oidcIcon}
bind:value={providers.oidc.config.configs[0].logo}
options={iconDropdownOptions}
on:change={e => e.detail === "Upload" && fileinput.click()}
/>

View File

@ -4,3 +4,4 @@ export { admin } from "./admin"
export { apps } from "./apps"
export { email } from "./email"
export { auth } from "./auth"
export { oidc } from "./oidc"

View File

@ -0,0 +1,32 @@
import { writable } from "svelte/store"
import api from "builderStore/api"
const OIDC_CONFIG = {
logo: undefined,
name: undefined,
}
export function createOidcStore() {
const store = writable(OIDC_CONFIG)
const { set, subscribe } = store
async function init() {
const res = await api.get(`/api/admin/configs/publicOidc`)
const json = await res.json()
if (json.status === 400) {
set(OIDC_CONFIG)
} else {
// Just use the first config for now. We will be support multiple logins buttons later on.
set(...json)
}
}
return {
subscribe,
set,
init,
}
}
export const oidc = createOidcStore()

View File

@ -6,8 +6,6 @@ const DEFAULT_CONFIG = {
logoUrl: undefined,
docsUrl: undefined,
company: "Budibase",
oidcIcon: undefined,
oidcName: undefined,
}
export function createOrganisationStore() {

View File

@ -98,6 +98,30 @@ exports.find = async function (ctx) {
}
}
exports.publicOidc = async function (ctx) {
const db = new CouchDB(GLOBAL_DB)
try {
// Find the config with the most granular scope based on context
const oidcConfig = await getScopedFullConfig(db, {
type: Configs.OIDC,
})
if (!oidcConfig) {
ctx.body = {}
} else {
const partialOidcCofig = oidcConfig.config.configs.map(config => {
return {
logo: config.logo,
name: config.name,
}
})
ctx.body = partialOidcCofig
}
} catch (err) {
ctx.throw(err.status, err)
}
}
exports.publicSettings = async function (ctx) {
const db = new CouchDB(GLOBAL_DB)
try {

View File

@ -49,6 +49,10 @@ const PUBLIC_ENDPOINTS = [
route: "/api/admin/configs/public",
method: "GET",
},
{
route: "/api/admin/configs/publicOidc",
method: "GET",
},
]
const router = new Router()

View File

@ -44,11 +44,15 @@ function googleValidation() {
function oidcValidation() {
// prettier-ignore
return Joi.object({
clientID: Joi.string().required(),
clientSecret: Joi.string().required(),
configUrl: Joi.string().required(),
iconName: Joi.string().optional(),
name: Joi.string().optional(),
configs: Joi.array().items(
Joi.object({
clientID: Joi.string().required(),
clientSecret: Joi.string().required(),
configUrl: Joi.string().required(),
logo: Joi.string().optional(),
name: Joi.string().optional(),
})
).required(true)
}).unknown(true)
}
@ -104,6 +108,7 @@ router
controller.fetch
)
.get("/api/admin/configs/public", controller.publicSettings)
.get("/api/admin/configs/publicOidc", controller.publicOidc)
.get("/api/admin/configs/:type", buildConfigGetValidation(), controller.find)
.post(
"/api/admin/configs/upload/:type/:name",