2021-05-05 04:31:06 +12:00
|
|
|
<script>
|
2021-07-08 03:18:18 +12:00
|
|
|
import GoogleLogo from "./_logos/Google.svelte"
|
2021-07-08 00:41:09 +12:00
|
|
|
import OidcLogo from "./_logos/OIDC.svelte"
|
|
|
|
import MicrosoftLogo from "assets/microsoft-logo.png"
|
|
|
|
import Auth0Logo from "assets/auth0-logo.png"
|
2021-07-16 21:15:38 +12:00
|
|
|
import OktaLogo from "assets/okta-logo.png"
|
|
|
|
import OneLoginLogo from "assets/onelogin-logo.png"
|
2021-07-08 00:41:09 +12:00
|
|
|
import OidcLogoPng from "assets/oidc-logo.png"
|
2021-07-20 21:55:39 +12:00
|
|
|
import { isEqual, cloneDeep } from "lodash/fp"
|
2021-05-05 04:31:06 +12:00
|
|
|
import {
|
|
|
|
Button,
|
|
|
|
Heading,
|
|
|
|
Divider,
|
2021-05-05 05:14:13 +12:00
|
|
|
Label,
|
2021-05-05 04:31:06 +12:00
|
|
|
notifications,
|
2021-05-05 05:14:13 +12:00
|
|
|
Layout,
|
2021-05-05 04:31:06 +12:00
|
|
|
Input,
|
|
|
|
Body,
|
2021-07-08 00:41:09 +12:00
|
|
|
Select,
|
2021-07-20 20:27:12 +12:00
|
|
|
Toggle,
|
2021-05-05 04:31:06 +12:00
|
|
|
} from "@budibase/bbui"
|
|
|
|
import { onMount } from "svelte"
|
|
|
|
import api from "builderStore/api"
|
2021-11-13 02:31:55 +13:00
|
|
|
import { organisation, admin } from "stores/portal"
|
2021-07-14 02:52:21 +12:00
|
|
|
import { uuid } from "builderStore/uuid"
|
2021-09-21 22:47:14 +12:00
|
|
|
import analytics, { Events } from "analytics"
|
2021-07-10 02:05:39 +12:00
|
|
|
|
2021-05-05 04:31:06 +12:00
|
|
|
const ConfigTypes = {
|
|
|
|
Google: "google",
|
2021-07-06 01:24:13 +12:00
|
|
|
OIDC: "oidc",
|
2021-05-05 04:31:06 +12:00
|
|
|
}
|
|
|
|
|
2021-11-13 02:31:55 +13:00
|
|
|
// Some older google configs contain a manually specified value - retain the functionality to edit the field
|
|
|
|
// When there is no value or we are in the cloud - prohibit editing the field, must use platform url to change
|
|
|
|
$: googleCallbackUrl = undefined
|
|
|
|
$: googleCallbackReadonly = $admin.cloud || !googleCallbackUrl
|
|
|
|
|
|
|
|
// Indicate to user that callback is based on platform url
|
|
|
|
// If there is an existing value, indicate that it may be removed to return to default behaviour
|
|
|
|
$: googleCallbackTooltip = googleCallbackReadonly
|
|
|
|
? "Vist the organisation page to update the platform URL"
|
|
|
|
: "Leave blank to use the default callback URL"
|
2021-05-05 04:31:06 +12:00
|
|
|
|
2021-08-05 20:59:08 +12:00
|
|
|
$: GoogleConfigFields = {
|
|
|
|
Google: [
|
|
|
|
{ name: "clientID", label: "Client ID" },
|
|
|
|
{ name: "clientSecret", label: "Client secret" },
|
|
|
|
{
|
|
|
|
name: "callbackURL",
|
|
|
|
label: "Callback URL",
|
2021-11-13 02:31:55 +13:00
|
|
|
readonly: googleCallbackReadonly,
|
|
|
|
tooltip: googleCallbackTooltip,
|
|
|
|
placeholder: $organisation.googleCallbackUrl,
|
2021-08-05 20:59:08 +12:00
|
|
|
},
|
|
|
|
],
|
2021-08-04 21:02:24 +12:00
|
|
|
}
|
2021-08-05 20:59:08 +12:00
|
|
|
|
|
|
|
$: OIDCConfigFields = {
|
|
|
|
Oidc: [
|
|
|
|
{ name: "configUrl", label: "Config URL" },
|
|
|
|
{ name: "clientID", label: "Client ID" },
|
|
|
|
{ name: "clientSecret", label: "Client Secret" },
|
|
|
|
{
|
|
|
|
name: "callbackURL",
|
|
|
|
readonly: true,
|
2021-11-13 02:31:55 +13:00
|
|
|
tooltip: "Vist the organisation page to update the platform URL",
|
|
|
|
label: "Callback URL",
|
|
|
|
placeholder: $organisation.oidcCallbackUrl,
|
2021-08-05 20:59:08 +12:00
|
|
|
},
|
|
|
|
],
|
2021-07-06 01:24:13 +12:00
|
|
|
}
|
2021-07-08 00:41:09 +12:00
|
|
|
|
|
|
|
let iconDropdownOptions = [
|
|
|
|
{
|
2021-07-14 01:54:20 +12:00
|
|
|
label: "Microsoft",
|
|
|
|
value: "Microsoft",
|
2021-07-08 00:41:09 +12:00
|
|
|
icon: MicrosoftLogo,
|
|
|
|
},
|
2021-07-16 21:15:38 +12:00
|
|
|
{
|
|
|
|
label: "Okta",
|
|
|
|
value: "Okta",
|
|
|
|
icon: OktaLogo,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "OneLogin",
|
|
|
|
value: "OneLogin",
|
|
|
|
icon: OneLoginLogo,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "Auth0",
|
|
|
|
value: "Auth0",
|
|
|
|
icon: Auth0Logo,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "OIDC",
|
|
|
|
value: "Oidc",
|
|
|
|
icon: OidcLogoPng,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "Upload your own",
|
|
|
|
value: "Upload",
|
|
|
|
},
|
2021-07-08 00:41:09 +12:00
|
|
|
]
|
|
|
|
|
|
|
|
let fileinput
|
|
|
|
let image
|
2021-07-14 08:46:50 +12:00
|
|
|
|
2021-05-05 04:31:06 +12:00
|
|
|
let google
|
2021-07-06 01:24:13 +12:00
|
|
|
let oidc
|
2021-07-14 08:46:50 +12:00
|
|
|
const providers = { google, oidc }
|
2021-07-20 21:55:39 +12:00
|
|
|
|
|
|
|
// control the state of the save button depending on whether form has changed
|
|
|
|
let originalGoogleDoc
|
|
|
|
let originalOidcDoc
|
2021-07-20 20:27:12 +12:00
|
|
|
let googleSaveButtonDisabled
|
|
|
|
let oidcSaveButtonDisabled
|
2021-07-20 21:55:39 +12:00
|
|
|
$: {
|
2021-07-20 23:30:11 +12:00
|
|
|
isEqual(providers.google?.config, originalGoogleDoc?.config)
|
2021-07-20 21:55:39 +12:00
|
|
|
? (googleSaveButtonDisabled = true)
|
|
|
|
: (googleSaveButtonDisabled = false)
|
2021-07-20 23:30:11 +12:00
|
|
|
isEqual(providers.oidc?.config, originalOidcDoc?.config)
|
2021-07-20 21:55:39 +12:00
|
|
|
? (oidcSaveButtonDisabled = true)
|
|
|
|
: (oidcSaveButtonDisabled = false)
|
|
|
|
}
|
2021-07-14 08:46:50 +12:00
|
|
|
|
|
|
|
// Create a flag so that it will only try to save completed forms
|
2021-07-20 20:27:12 +12:00
|
|
|
$: partialGoogle =
|
2021-08-05 20:59:08 +12:00
|
|
|
providers.google?.config?.clientID || providers.google?.config?.clientSecret
|
2021-07-20 20:27:12 +12:00
|
|
|
$: partialOidc =
|
2021-07-17 01:07:48 +12:00
|
|
|
providers.oidc?.config?.configs[0].configUrl ||
|
|
|
|
providers.oidc?.config?.configs[0].clientID ||
|
|
|
|
providers.oidc?.config?.configs[0].clientSecret
|
2021-07-14 08:46:50 +12:00
|
|
|
$: googleComplete =
|
2021-08-05 20:59:08 +12:00
|
|
|
providers.google?.config?.clientID && providers.google?.config?.clientSecret
|
2021-07-14 08:46:50 +12:00
|
|
|
$: oidcComplete =
|
2021-07-15 03:21:17 +12:00
|
|
|
providers.oidc?.config?.configs[0].configUrl &&
|
|
|
|
providers.oidc?.config?.configs[0].clientID &&
|
|
|
|
providers.oidc?.config?.configs[0].clientSecret
|
|
|
|
|
2021-07-08 00:41:09 +12:00
|
|
|
async function uploadLogo(file) {
|
|
|
|
let data = new FormData()
|
|
|
|
data.append("file", file)
|
|
|
|
const res = await api.post(
|
2021-08-05 20:59:08 +12:00
|
|
|
`/api/global/configs/upload/logos_oidc/${file.name}`,
|
2021-07-08 00:41:09 +12:00
|
|
|
data,
|
|
|
|
{}
|
|
|
|
)
|
|
|
|
return await res.json()
|
|
|
|
}
|
|
|
|
|
|
|
|
const onFileSelected = e => {
|
2021-07-08 03:18:18 +12:00
|
|
|
let fileName = e.target.files[0].name
|
2021-07-08 00:41:09 +12:00
|
|
|
image = e.target.files[0]
|
2021-07-14 01:54:20 +12:00
|
|
|
providers.oidc.config.configs[0].logo = fileName
|
2021-07-08 23:36:09 +12:00
|
|
|
iconDropdownOptions.unshift({ label: fileName, value: fileName })
|
2021-07-08 00:41:09 +12:00
|
|
|
}
|
|
|
|
|
2021-07-06 01:24:13 +12:00
|
|
|
async function save(docs) {
|
2021-07-08 03:18:18 +12:00
|
|
|
// only if the user has provided an image, upload it.
|
|
|
|
image && uploadLogo(image)
|
2021-07-06 01:24:13 +12:00
|
|
|
let calls = []
|
|
|
|
docs.forEach(element => {
|
2021-07-14 08:46:50 +12:00
|
|
|
if (element.type === ConfigTypes.OIDC) {
|
2021-08-05 20:59:08 +12:00
|
|
|
//Add a UUID here so each config is distinguishable when it arrives at the login page
|
|
|
|
for (let config of element.config.configs) {
|
|
|
|
if (!config.uuid) {
|
|
|
|
config.uuid = uuid()
|
|
|
|
}
|
|
|
|
// callback urls shouldn't be included
|
|
|
|
delete config.callbackURL
|
|
|
|
}
|
2021-07-20 20:27:12 +12:00
|
|
|
if (partialOidc) {
|
2021-07-17 01:07:48 +12:00
|
|
|
if (!oidcComplete) {
|
|
|
|
notifications.error(
|
|
|
|
`Please fill in all required ${ConfigTypes.OIDC} fields`
|
|
|
|
)
|
|
|
|
} else {
|
2021-08-05 20:59:08 +12:00
|
|
|
calls.push(api.post(`/api/global/configs`, element))
|
2021-07-20 23:30:11 +12:00
|
|
|
// turn the save button grey when clicked
|
|
|
|
oidcSaveButtonDisabled = true
|
|
|
|
originalOidcDoc = cloneDeep(providers.oidc)
|
2021-07-17 01:07:48 +12:00
|
|
|
}
|
2021-07-16 21:51:58 +12:00
|
|
|
}
|
2021-07-14 08:46:50 +12:00
|
|
|
}
|
|
|
|
if (element.type === ConfigTypes.Google) {
|
2021-07-20 20:27:12 +12:00
|
|
|
if (partialGoogle) {
|
2021-07-17 01:07:48 +12:00
|
|
|
if (!googleComplete) {
|
|
|
|
notifications.error(
|
|
|
|
`Please fill in all required ${ConfigTypes.Google} fields`
|
|
|
|
)
|
|
|
|
} else {
|
2021-08-05 20:59:08 +12:00
|
|
|
calls.push(api.post(`/api/global/configs`, element))
|
2021-07-20 23:30:11 +12:00
|
|
|
googleSaveButtonDisabled = true
|
|
|
|
originalGoogleDoc = cloneDeep(providers.google)
|
2021-07-17 01:07:48 +12:00
|
|
|
}
|
2021-07-16 21:51:58 +12:00
|
|
|
}
|
2021-07-14 02:52:21 +12:00
|
|
|
}
|
2021-07-06 01:24:13 +12:00
|
|
|
})
|
2021-07-16 21:51:58 +12:00
|
|
|
calls.length &&
|
|
|
|
Promise.all(calls)
|
|
|
|
.then(responses => {
|
|
|
|
return Promise.all(
|
|
|
|
responses.map(response => {
|
|
|
|
return response.json()
|
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
|
|
|
.then(data => {
|
|
|
|
data.forEach(res => {
|
|
|
|
providers[res.type]._rev = res._rev
|
|
|
|
providers[res.type]._id = res._id
|
2021-07-08 00:41:09 +12:00
|
|
|
})
|
2021-07-16 21:51:58 +12:00
|
|
|
notifications.success(`Settings saved.`)
|
2021-09-21 22:47:14 +12:00
|
|
|
analytics.captureEvent(Events.SSO.SAVED)
|
2021-07-16 21:51:58 +12:00
|
|
|
})
|
|
|
|
.catch(err => {
|
2021-07-17 01:07:48 +12:00
|
|
|
notifications.error(`Failed to update auth settings. ${err}`)
|
2021-07-16 21:51:58 +12:00
|
|
|
throw new Error(err.message)
|
2021-07-06 01:24:13 +12:00
|
|
|
})
|
2021-05-05 04:31:06 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
onMount(async () => {
|
2021-07-10 02:05:39 +12:00
|
|
|
await organisation.init()
|
2021-05-05 04:31:06 +12:00
|
|
|
// fetch the configs for oauth
|
|
|
|
const googleResponse = await api.get(
|
2021-08-05 20:59:08 +12:00
|
|
|
`/api/global/configs/${ConfigTypes.Google}`
|
2021-05-05 04:31:06 +12:00
|
|
|
)
|
|
|
|
const googleDoc = await googleResponse.json()
|
|
|
|
|
|
|
|
if (!googleDoc._id) {
|
2021-07-06 01:24:13 +12:00
|
|
|
providers.google = {
|
2021-05-05 22:03:45 +12:00
|
|
|
type: ConfigTypes.Google,
|
2021-07-20 20:27:12 +12:00
|
|
|
config: { activated: true },
|
2021-05-05 04:31:06 +12:00
|
|
|
}
|
2021-07-20 23:30:11 +12:00
|
|
|
originalGoogleDoc = cloneDeep(googleDoc)
|
2021-05-05 04:31:06 +12:00
|
|
|
} else {
|
2021-07-24 03:02:38 +12:00
|
|
|
// default activated to true for older configs
|
|
|
|
if (googleDoc.config.activated === undefined) {
|
|
|
|
googleDoc.config.activated = true
|
|
|
|
}
|
2021-07-20 23:30:11 +12:00
|
|
|
originalGoogleDoc = cloneDeep(googleDoc)
|
2021-07-06 01:24:13 +12:00
|
|
|
providers.google = googleDoc
|
|
|
|
}
|
|
|
|
|
2021-11-13 02:31:55 +13:00
|
|
|
googleCallbackUrl = providers?.google?.config?.callbackURL
|
|
|
|
|
2021-07-08 03:18:18 +12:00
|
|
|
//Get the list of user uploaded logos and push it to the dropdown options.
|
2021-07-08 22:15:22 +12:00
|
|
|
//This needs to be done before the config call so they're available when the dropdown renders
|
2021-08-05 20:59:08 +12:00
|
|
|
const res = await api.get(`/api/global/configs/logos_oidc`)
|
2021-07-08 03:18:18 +12:00
|
|
|
const configSettings = await res.json()
|
2021-07-08 22:15:22 +12:00
|
|
|
|
|
|
|
if (configSettings.config) {
|
2021-07-08 23:36:09 +12:00
|
|
|
const logoKeys = Object.keys(configSettings.config)
|
|
|
|
|
|
|
|
logoKeys.map(logoKey => {
|
|
|
|
const logoUrl = configSettings.config[logoKey]
|
|
|
|
iconDropdownOptions.unshift({
|
|
|
|
label: logoKey,
|
|
|
|
value: logoKey,
|
|
|
|
icon: logoUrl,
|
|
|
|
})
|
2021-07-08 03:18:18 +12:00
|
|
|
})
|
2021-07-08 23:36:09 +12:00
|
|
|
}
|
2021-08-05 20:59:08 +12:00
|
|
|
const oidcResponse = await api.get(
|
|
|
|
`/api/global/configs/${ConfigTypes.OIDC}`
|
|
|
|
)
|
2021-07-06 01:24:13 +12:00
|
|
|
const oidcDoc = await oidcResponse.json()
|
|
|
|
if (!oidcDoc._id) {
|
|
|
|
providers.oidc = {
|
|
|
|
type: ConfigTypes.OIDC,
|
2021-07-20 20:27:12 +12:00
|
|
|
config: { configs: [{ activated: true }] },
|
2021-07-06 01:24:13 +12:00
|
|
|
}
|
|
|
|
} else {
|
2021-07-20 21:55:39 +12:00
|
|
|
originalOidcDoc = cloneDeep(oidcDoc)
|
2021-07-06 01:24:13 +12:00
|
|
|
providers.oidc = oidcDoc
|
2021-05-05 04:31:06 +12:00
|
|
|
}
|
2021-07-08 00:41:09 +12:00
|
|
|
})
|
2021-05-05 04:31:06 +12:00
|
|
|
</script>
|
|
|
|
|
2021-09-14 03:05:26 +12:00
|
|
|
<Layout noPadding>
|
2021-05-19 22:07:14 +12:00
|
|
|
<Layout gap="XS" noPadding>
|
2021-07-14 04:32:57 +12:00
|
|
|
<Heading size="M">Authentication</Heading>
|
2021-05-19 22:07:14 +12:00
|
|
|
<Body>
|
|
|
|
Every budibase app comes with basic authentication (email/password)
|
|
|
|
included. You can add additional authentication methods from the options
|
|
|
|
below.
|
|
|
|
</Body>
|
|
|
|
</Layout>
|
2021-07-06 01:24:13 +12:00
|
|
|
{#if providers.google}
|
2021-05-07 22:16:09 +12:00
|
|
|
<Divider />
|
2021-05-19 22:07:14 +12:00
|
|
|
<Layout gap="XS" noPadding>
|
|
|
|
<Heading size="S">
|
2021-09-14 03:05:26 +12:00
|
|
|
<div class="provider-title">
|
2021-05-19 22:07:14 +12:00
|
|
|
<GoogleLogo />
|
2021-09-14 03:05:26 +12:00
|
|
|
<span>Google</span>
|
2021-09-14 03:15:52 +12:00
|
|
|
<Button
|
|
|
|
disabled={googleSaveButtonDisabled}
|
|
|
|
size="s"
|
|
|
|
cta
|
|
|
|
on:click={() => save([providers.google])}
|
|
|
|
>
|
|
|
|
Save
|
|
|
|
</Button>
|
2021-07-20 20:27:12 +12:00
|
|
|
</div>
|
2021-05-19 22:07:14 +12:00
|
|
|
</Heading>
|
|
|
|
<Body size="S">
|
|
|
|
To allow users to authenticate using their Google accounts, fill out the
|
|
|
|
fields below.
|
|
|
|
</Body>
|
2021-07-14 02:52:21 +12:00
|
|
|
</Layout>
|
2021-05-19 22:07:14 +12:00
|
|
|
<Layout gap="XS" noPadding>
|
2021-07-06 01:24:13 +12:00
|
|
|
{#each GoogleConfigFields.Google as field}
|
|
|
|
<div class="form-row">
|
2021-11-13 02:31:55 +13:00
|
|
|
<Label size="L" tooltip={field.tooltip}>{field.label}</Label>
|
2021-08-05 20:59:08 +12:00
|
|
|
<Input
|
|
|
|
bind:value={providers.google.config[field.name]}
|
|
|
|
readonly={field.readonly}
|
|
|
|
placeholder={field.placeholder}
|
|
|
|
/>
|
2021-07-06 01:24:13 +12:00
|
|
|
</div>
|
|
|
|
{/each}
|
2021-07-20 20:27:12 +12:00
|
|
|
<div class="form-row">
|
2021-09-14 03:15:52 +12:00
|
|
|
<Label size="L">Activated</Label>
|
|
|
|
<Toggle text="" bind:value={providers.google.config.activated} />
|
2021-07-20 20:27:12 +12:00
|
|
|
</div>
|
2021-07-06 01:24:13 +12:00
|
|
|
</Layout>
|
|
|
|
{/if}
|
|
|
|
{#if providers.oidc}
|
|
|
|
<Divider />
|
|
|
|
<Layout gap="XS" noPadding>
|
|
|
|
<Heading size="S">
|
2021-09-14 03:05:26 +12:00
|
|
|
<div class="provider-title">
|
2021-07-08 00:41:09 +12:00
|
|
|
<OidcLogo />
|
2021-09-14 03:05:26 +12:00
|
|
|
<span>OpenID Connect</span>
|
2021-09-14 03:15:52 +12:00
|
|
|
<Button
|
|
|
|
disabled={oidcSaveButtonDisabled}
|
|
|
|
size="s"
|
|
|
|
cta
|
|
|
|
on:click={() => save([providers.oidc])}
|
|
|
|
>
|
|
|
|
Save
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
</Heading>
|
2021-07-06 01:24:13 +12:00
|
|
|
<Body size="S">
|
|
|
|
To allow users to authenticate using OIDC, fill out the fields below.
|
|
|
|
</Body>
|
|
|
|
</Layout>
|
|
|
|
<Layout gap="XS" noPadding>
|
|
|
|
{#each OIDCConfigFields.Oidc as field}
|
2021-05-07 22:16:09 +12:00
|
|
|
<div class="form-row">
|
2021-11-13 02:31:55 +13:00
|
|
|
<Label size="L" tooltip={field.tooltip}>{field.label}</Label>
|
2021-08-05 20:59:08 +12:00
|
|
|
<Input
|
|
|
|
bind:value={providers.oidc.config.configs[0][field.name]}
|
|
|
|
readonly={field.readonly}
|
|
|
|
placeholder={field.placeholder}
|
|
|
|
/>
|
2021-05-07 22:16:09 +12:00
|
|
|
</div>
|
|
|
|
{/each}
|
2021-09-14 03:15:52 +12:00
|
|
|
</Layout>
|
|
|
|
<Layout gap="XS" noPadding>
|
2021-07-06 01:24:13 +12:00
|
|
|
<Body size="S">
|
2021-07-08 00:41:09 +12:00
|
|
|
To customize your login button, fill out the fields below.
|
2021-07-06 01:24:13 +12:00
|
|
|
</Body>
|
|
|
|
<div class="form-row">
|
2021-07-08 00:41:09 +12:00
|
|
|
<Label size="L">Name</Label>
|
2021-07-14 01:54:20 +12:00
|
|
|
<Input bind:value={providers.oidc.config.configs[0].name} />
|
2021-07-08 00:41:09 +12:00
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<Label size="L">Icon</Label>
|
2021-07-06 01:24:13 +12:00
|
|
|
<Select
|
2021-07-08 00:41:09 +12:00
|
|
|
label=""
|
2021-07-14 01:54:20 +12:00
|
|
|
bind:value={providers.oidc.config.configs[0].logo}
|
2021-07-08 00:41:09 +12:00
|
|
|
options={iconDropdownOptions}
|
2021-07-08 03:18:18 +12:00
|
|
|
on:change={e => e.detail === "Upload" && fileinput.click()}
|
2021-07-06 01:24:13 +12:00
|
|
|
/>
|
2021-07-08 00:41:09 +12:00
|
|
|
</div>
|
|
|
|
<input
|
|
|
|
type="file"
|
|
|
|
accept=".jpg, .jpeg, .png"
|
|
|
|
on:change={e => onFileSelected(e)}
|
|
|
|
bind:this={fileinput}
|
|
|
|
/>
|
2021-09-14 03:15:52 +12:00
|
|
|
<div class="form-row">
|
2021-07-20 20:27:12 +12:00
|
|
|
<Label size="L">Activated</Label>
|
2021-09-14 03:15:52 +12:00
|
|
|
<Toggle
|
|
|
|
text=""
|
|
|
|
bind:value={providers.oidc.config.configs[0].activated}
|
|
|
|
/>
|
2021-07-20 20:27:12 +12:00
|
|
|
</div>
|
2021-09-14 03:15:52 +12:00
|
|
|
</Layout>
|
2021-05-19 22:07:14 +12:00
|
|
|
{/if}
|
|
|
|
</Layout>
|
2021-05-05 04:31:06 +12:00
|
|
|
|
|
|
|
<style>
|
2021-05-05 05:14:13 +12:00
|
|
|
.form-row {
|
|
|
|
display: grid;
|
2021-09-14 03:15:52 +12:00
|
|
|
grid-template-columns: 100px 1fr;
|
2021-05-05 05:14:13 +12:00
|
|
|
grid-gap: var(--spacing-l);
|
2021-05-07 22:16:09 +12:00
|
|
|
align-items: center;
|
2021-05-05 04:31:06 +12:00
|
|
|
}
|
2021-07-08 00:41:09 +12:00
|
|
|
|
2021-09-14 03:15:52 +12:00
|
|
|
input[type="file"] {
|
2021-07-08 00:41:09 +12:00
|
|
|
display: none;
|
|
|
|
}
|
2021-07-20 20:27:12 +12:00
|
|
|
|
2021-09-14 03:05:26 +12:00
|
|
|
.provider-title {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
gap: var(--spacing-m);
|
|
|
|
}
|
|
|
|
.provider-title span {
|
|
|
|
flex: 1 1 auto;
|
2021-07-20 20:27:12 +12:00
|
|
|
}
|
2021-05-05 04:31:06 +12:00
|
|
|
</style>
|