mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-13 01:02:25 -06:00
feat: make OAuth admin settings read-only when ENABLE_OAUTH_PERSISTENT_CONFIG is off (#28276)
When ENABLE_OAUTH_PERSISTENT_CONFIG is off (the default), oauth.* config is never persisted and is read from environment variables, but the admin panel still let admins edit the OAuth/OIDC fields and silently dropped every save on restart, which kept confusing users who missed the docs warning (open-webui/open-webui#28247). The OAuth/OIDC section is now read-only in that case: the admin oauth config endpoint reports the flag and the UI wraps the section in a disabled fieldset, slightly dimmed with every control inert but all values still visible, plus a note naming the env var. Saving skips the OAuth POST since nothing can change. With the flag enabled the section behaves exactly as before. Known limits: the guard is UI-side only (the POST endpoint keeps accepting writes, unchanged), and disabled fields mean values cannot be selected and the masked client secret cannot be revealed while read-only. Switch.svelte gains a disabled:cursor-not-allowed style that applies to any disabled switch app-wide. Co-authored-by: Tim Baek <tim@openwebui.com>
This commit is contained in:
@@ -1428,11 +1428,13 @@ def _parse_oauth_update_value(field: str, value):
|
||||
|
||||
async def get_oauth_config_values() -> dict:
|
||||
values = await Config.get_many(*OAUTH_CONFIG_KEYS.values())
|
||||
return {
|
||||
form_values = {
|
||||
field: _format_oauth_form_value(field, values[storage_key])
|
||||
for field, storage_key in OAUTH_CONFIG_KEYS.items()
|
||||
if storage_key in values
|
||||
}
|
||||
form_values['ENABLE_OAUTH_PERSISTENT_CONFIG'] = Config.OAUTH_PERSISTENT_ENABLED
|
||||
return form_values
|
||||
|
||||
|
||||
def oauth_config_updates(data: dict) -> dict:
|
||||
@@ -1443,12 +1445,16 @@ def oauth_config_updates(data: dict) -> dict:
|
||||
}
|
||||
|
||||
|
||||
@router.get('/admin/config/oauth', response_model=OAuthConfigForm)
|
||||
class OAuthConfigResponse(OAuthConfigForm):
|
||||
ENABLE_OAUTH_PERSISTENT_CONFIG: bool
|
||||
|
||||
|
||||
@router.get('/admin/config/oauth', response_model=OAuthConfigResponse)
|
||||
async def get_oauth_config(request: Request, user=Depends(get_admin_user)):
|
||||
return await get_oauth_config_values()
|
||||
|
||||
|
||||
@router.post('/admin/config/oauth', response_model=OAuthConfigForm)
|
||||
@router.post('/admin/config/oauth', response_model=OAuthConfigResponse)
|
||||
async def update_oauth_config(request: Request, form_data: OAuthConfigForm, user=Depends(get_admin_user)):
|
||||
await Config.upsert(oauth_config_updates(form_data.model_dump(exclude_none=True)))
|
||||
return await get_oauth_config_values()
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
};
|
||||
|
||||
let oauthConfig: any = null;
|
||||
$: oauthEditable = oauthConfig?.ENABLE_OAUTH_PERSISTENT_CONFIG ?? true;
|
||||
const inputClass =
|
||||
'w-full h-7 rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 text-xs text-gray-700 outline-hidden transition-colors placeholder:text-gray-300 focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:placeholder:text-gray-700 dark:focus:border-blue-500';
|
||||
const textareaClass =
|
||||
@@ -74,7 +75,7 @@
|
||||
};
|
||||
|
||||
const updateOAuthHandler = async () => {
|
||||
if (!oauthConfig) return true;
|
||||
if (!oauthConfig || !oauthEditable) return true;
|
||||
const res = await updateOAuthConfig(localStorage.token, oauthConfig).catch((error) => {
|
||||
toast.error(`${error}`);
|
||||
return null;
|
||||
@@ -526,311 +527,327 @@
|
||||
|
||||
{#if oauthConfig}
|
||||
<AdminSettingSection title={$i18n.t('OAuth / OIDC')}>
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('OAuth / OIDC')}
|
||||
description={$i18n.t('Allow users to authenticate with an OAuth / OIDC provider.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch bind:state={oauthConfig.ENABLE_OAUTH} ariaLabelledbyId={labelId} />
|
||||
</AdminSettingRow>
|
||||
|
||||
{#if oauthConfig.ENABLE_OAUTH}
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Provider Name')}
|
||||
description={$i18n.t('Display name shown for the OAuth provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="SSO"
|
||||
bind:value={oauthConfig.OAUTH_PROVIDER_NAME}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Provider URL')}
|
||||
description={$i18n.t('OpenID discovery URL for this provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="https://accounts.google.com/.well-known/openid-configuration"
|
||||
bind:value={oauthConfig.OPENID_PROVIDER_URL}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Client ID')}
|
||||
description={$i18n.t('OAuth client identifier from the provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder={$i18n.t('Enter Client ID')}
|
||||
bind:value={oauthConfig.OAUTH_CLIENT_ID}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Client Secret')}
|
||||
description={$i18n.t('OAuth client secret from the provider.')}
|
||||
>
|
||||
<SensitiveInput
|
||||
variant="settings"
|
||||
placeholder={$i18n.t('Enter Client Secret')}
|
||||
required={false}
|
||||
bind:value={oauthConfig.OAUTH_CLIENT_SECRET}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Redirect URI')}
|
||||
description={$i18n.t('Callback URI registered with the provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder={$i18n.t('Enter Redirect URI')}
|
||||
bind:value={oauthConfig.OPENID_REDIRECT_URI}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Scopes')}
|
||||
description={$i18n.t('OAuth scopes requested during sign-in.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="openid email profile"
|
||||
bind:value={oauthConfig.OAUTH_SCOPES}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Email Claim')}
|
||||
description={$i18n.t('Claim used as the user email address.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="email"
|
||||
bind:value={oauthConfig.OAUTH_EMAIL_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Username Claim')}
|
||||
description={$i18n.t('Claim used as the display name.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="name"
|
||||
bind:value={oauthConfig.OAUTH_USERNAME_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Picture Claim')}
|
||||
description={$i18n.t('Claim used as the profile picture URL.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="picture"
|
||||
bind:value={oauthConfig.OAUTH_PICTURE_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Sub Claim')}
|
||||
description={$i18n.t('Claim used as the stable user identifier.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="sub"
|
||||
bind:value={oauthConfig.OAUTH_SUB_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('OAuth Signup')}
|
||||
description={$i18n.t('Allow users to create accounts through OAuth.')}
|
||||
let:labelId
|
||||
{#if !oauthEditable}
|
||||
<div
|
||||
class="rounded-lg bg-yellow-500/10 px-2 py-1.5 text-[0.6875rem] text-yellow-700 dark:text-yellow-200"
|
||||
>
|
||||
<Switch bind:state={oauthConfig.ENABLE_OAUTH_SIGNUP} ariaLabelledbyId={labelId} />
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Merge Accounts by Email')}
|
||||
description={$i18n.t('Link OAuth sign-ins to existing accounts with the same email.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.OAUTH_MERGE_ACCOUNTS_BY_EMAIL}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Auto Redirect')}
|
||||
description={$i18n.t(
|
||||
'Send users directly to the OAuth provider from the sign-in page.'
|
||||
{$i18n.t(
|
||||
'These settings are read from environment variables and cannot be edited here while {{ENV_VAR}} is disabled.',
|
||||
{ ENV_VAR: 'ENABLE_OAUTH_PERSISTENT_CONFIG' }
|
||||
)}
|
||||
let:labelId
|
||||
>
|
||||
<Switch bind:state={oauthConfig.OAUTH_AUTO_REDIRECT} ariaLabelledbyId={labelId} />
|
||||
</AdminSettingRow>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Allowed Domains')}
|
||||
description={$i18n.t('Email domains allowed to sign in with OAuth.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="* (all domains)"
|
||||
bind:value={oauthConfig.OAUTH_ALLOWED_DOMAINS}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<!-- LICENSE covers this Open WebUI wordmark.
|
||||
Do not alter, remove, obscure, or replace it except as LICENSE permits:
|
||||
https://docs.openwebui.com/license. -->
|
||||
<fieldset
|
||||
class="flex min-w-0 flex-col gap-2.5 disabled:cursor-not-allowed disabled:opacity-75"
|
||||
disabled={!oauthEditable}
|
||||
>
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Role Mapping')}
|
||||
description={$i18n.t('Map OAuth claims to Open WebUI roles.')}
|
||||
label={$i18n.t('OAuth / OIDC')}
|
||||
description={$i18n.t('Allow users to authenticate with an OAuth / OIDC provider.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.ENABLE_OAUTH_ROLE_MANAGEMENT}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
<Switch bind:state={oauthConfig.ENABLE_OAUTH} ariaLabelledbyId={labelId} />
|
||||
</AdminSettingRow>
|
||||
|
||||
{#if oauthConfig.ENABLE_OAUTH_ROLE_MANAGEMENT}
|
||||
{#if oauthConfig.ENABLE_OAUTH}
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Roles Claim')}
|
||||
description={$i18n.t('Claim containing provider roles.')}
|
||||
label={$i18n.t('Provider Name')}
|
||||
description={$i18n.t('Display name shown for the OAuth provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="roles"
|
||||
bind:value={oauthConfig.OAUTH_ROLES_CLAIM}
|
||||
placeholder="SSO"
|
||||
bind:value={oauthConfig.OAUTH_PROVIDER_NAME}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Admin Roles')}
|
||||
description={$i18n.t('Provider roles that grant admin access.')}
|
||||
label={$i18n.t('Provider URL')}
|
||||
description={$i18n.t('OpenID discovery URL for this provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="admin"
|
||||
bind:value={oauthConfig.OAUTH_ADMIN_ROLES}
|
||||
placeholder="https://accounts.google.com/.well-known/openid-configuration"
|
||||
bind:value={oauthConfig.OPENID_PROVIDER_URL}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Allowed Roles')}
|
||||
description={$i18n.t('Provider roles allowed to sign in.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="*"
|
||||
bind:value={oauthConfig.OAUTH_ALLOWED_ROLES}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
{/if}
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Client ID')}
|
||||
description={$i18n.t('OAuth client identifier from the provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder={$i18n.t('Enter Client ID')}
|
||||
bind:value={oauthConfig.OAUTH_CLIENT_ID}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<!-- LICENSE covers this Open WebUI wordmark.
|
||||
Do not alter, remove, obscure, or replace it except as LICENSE permits:
|
||||
https://docs.openwebui.com/license. -->
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Group Mapping')}
|
||||
description={$i18n.t('Map OAuth claims to Open WebUI groups.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.ENABLE_OAUTH_GROUP_MANAGEMENT}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Client Secret')}
|
||||
description={$i18n.t('OAuth client secret from the provider.')}
|
||||
>
|
||||
<SensitiveInput
|
||||
variant="settings"
|
||||
placeholder={$i18n.t('Enter Client Secret')}
|
||||
required={false}
|
||||
bind:value={oauthConfig.OAUTH_CLIENT_SECRET}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Redirect URI')}
|
||||
description={$i18n.t('Callback URI registered with the provider.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder={$i18n.t('Enter Redirect URI')}
|
||||
bind:value={oauthConfig.OPENID_REDIRECT_URI}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Scopes')}
|
||||
description={$i18n.t('OAuth scopes requested during sign-in.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="openid email profile"
|
||||
bind:value={oauthConfig.OAUTH_SCOPES}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Email Claim')}
|
||||
description={$i18n.t('Claim used as the user email address.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="email"
|
||||
bind:value={oauthConfig.OAUTH_EMAIL_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Username Claim')}
|
||||
description={$i18n.t('Claim used as the display name.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="name"
|
||||
bind:value={oauthConfig.OAUTH_USERNAME_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Picture Claim')}
|
||||
description={$i18n.t('Claim used as the profile picture URL.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="picture"
|
||||
bind:value={oauthConfig.OAUTH_PICTURE_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Sub Claim')}
|
||||
description={$i18n.t('Claim used as the stable user identifier.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="sub"
|
||||
bind:value={oauthConfig.OAUTH_SUB_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
{#if oauthConfig.ENABLE_OAUTH_GROUP_MANAGEMENT}
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Auto-Create Groups')}
|
||||
description={$i18n.t('Create missing groups from OAuth claims.')}
|
||||
label={$i18n.t('OAuth Signup')}
|
||||
description={$i18n.t('Allow users to create accounts through OAuth.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch bind:state={oauthConfig.ENABLE_OAUTH_SIGNUP} ariaLabelledbyId={labelId} />
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Merge Accounts by Email')}
|
||||
description={$i18n.t('Link OAuth sign-ins to existing accounts with the same email.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.ENABLE_OAUTH_GROUP_CREATION}
|
||||
bind:state={oauthConfig.OAUTH_MERGE_ACCOUNTS_BY_EMAIL}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Group Claim')}
|
||||
description={$i18n.t('Claim containing provider groups.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="groups"
|
||||
bind:value={oauthConfig.OAUTH_GROUP_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Auto Redirect')}
|
||||
description={$i18n.t(
|
||||
'Send users directly to the OAuth provider from the sign-in page.'
|
||||
)}
|
||||
let:labelId
|
||||
>
|
||||
<Switch bind:state={oauthConfig.OAUTH_AUTO_REDIRECT} ariaLabelledbyId={labelId} />
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Allowed Domains')}
|
||||
description={$i18n.t('Email domains allowed to sign in with OAuth.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="* (all domains)"
|
||||
bind:value={oauthConfig.OAUTH_ALLOWED_DOMAINS}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<!-- LICENSE covers this Open WebUI wordmark.
|
||||
Do not alter, remove, obscure, or replace it except as LICENSE permits:
|
||||
https://docs.openwebui.com/license. -->
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Role Mapping')}
|
||||
description={$i18n.t('Map OAuth claims to Open WebUI roles.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.ENABLE_OAUTH_ROLE_MANAGEMENT}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
{#if oauthConfig.ENABLE_OAUTH_ROLE_MANAGEMENT}
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Roles Claim')}
|
||||
description={$i18n.t('Claim containing provider roles.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="roles"
|
||||
bind:value={oauthConfig.OAUTH_ROLES_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Admin Roles')}
|
||||
description={$i18n.t('Provider roles that grant admin access.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="admin"
|
||||
bind:value={oauthConfig.OAUTH_ADMIN_ROLES}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Blocked Groups')}
|
||||
description={$i18n.t('Provider groups blocked from signing in.')}
|
||||
label={$i18n.t('Allowed Roles')}
|
||||
description={$i18n.t('Provider roles allowed to sign in.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder={$i18n.t('Comma-separated group names')}
|
||||
bind:value={oauthConfig.OAUTH_BLOCKED_GROUPS}
|
||||
placeholder="*"
|
||||
bind:value={oauthConfig.OAUTH_ALLOWED_ROLES}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- LICENSE covers this Open WebUI wordmark.
|
||||
Do not alter, remove, obscure, or replace it except as LICENSE permits:
|
||||
https://docs.openwebui.com/license. -->
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Group Mapping')}
|
||||
description={$i18n.t('Map OAuth claims to Open WebUI groups.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.ENABLE_OAUTH_GROUP_MANAGEMENT}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
{#if oauthConfig.ENABLE_OAUTH_GROUP_MANAGEMENT}
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Auto-Create Groups')}
|
||||
description={$i18n.t('Create missing groups from OAuth claims.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.ENABLE_OAUTH_GROUP_CREATION}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-3 gap-y-2.5 sm:grid-cols-2">
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Group Claim')}
|
||||
description={$i18n.t('Claim containing provider groups.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder="groups"
|
||||
bind:value={oauthConfig.OAUTH_GROUP_CLAIM}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('Blocked Groups')}
|
||||
description={$i18n.t('Provider groups blocked from signing in.')}
|
||||
>
|
||||
<input
|
||||
class={inputClass}
|
||||
placeholder={$i18n.t('Comma-separated group names')}
|
||||
bind:value={oauthConfig.OAUTH_BLOCKED_GROUPS}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Update Email')}
|
||||
description={$i18n.t('Refresh the account email from OAuth on sign-in.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.OAUTH_UPDATE_EMAIL_ON_LOGIN}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Update Name')}
|
||||
description={$i18n.t('Refresh the account name from OAuth on sign-in.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.OAUTH_UPDATE_NAME_ON_LOGIN}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Update Picture')}
|
||||
description={$i18n.t('Refresh the profile picture from OAuth on sign-in.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.OAUTH_UPDATE_PICTURE_ON_LOGIN}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
{/if}
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Update Email')}
|
||||
description={$i18n.t('Refresh the account email from OAuth on sign-in.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.OAUTH_UPDATE_EMAIL_ON_LOGIN}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Update Name')}
|
||||
description={$i18n.t('Refresh the account name from OAuth on sign-in.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.OAUTH_UPDATE_NAME_ON_LOGIN}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('Update Picture')}
|
||||
description={$i18n.t('Refresh the profile picture from OAuth on sign-in.')}
|
||||
let:labelId
|
||||
>
|
||||
<Switch
|
||||
bind:state={oauthConfig.OAUTH_UPDATE_PICTURE_ON_LOGIN}
|
||||
ariaLabelledbyId={labelId}
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
{/if}
|
||||
</fieldset>
|
||||
</AdminSettingSection>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
{id}
|
||||
aria-labelledby={ariaLabelledbyId || undefined}
|
||||
aria-label={ariaLabel || undefined}
|
||||
class="relative h-4 min-h-4 w-7 shrink-0 cursor-pointer rounded-full mx-[0.0625rem] transition-colors duration-150 {($settings?.highContrastMode ??
|
||||
class="relative h-4 min-h-4 w-7 shrink-0 cursor-pointer rounded-full mx-[0.0625rem] transition-colors duration-150 disabled:cursor-not-allowed {($settings?.highContrastMode ??
|
||||
false)
|
||||
? 'focus:outline focus:outline-2 focus:outline-gray-800 focus:dark:outline-gray-200'
|
||||
: 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400 dark:focus-visible:outline-gray-500'} {state
|
||||
|
||||
Reference in New Issue
Block a user