Pārlūkot izejas kodu

refac: ldap settings

Timothy J. Baek 6 mēneši atpakaļ
vecāks
revīzija
ad462f0a11

+ 2 - 230
src/lib/components/admin/Settings/Connections.svelte

@@ -20,12 +20,7 @@
 		updateOpenAIKeys,
 		updateOpenAIUrls
 	} from '$lib/apis/openai';
-	import {
-		getLdapConfig,
-		updateLdapConfig,
-		getLdapServer,
-		updateLdapServer
-	} from '$lib/apis/auths';
+
 	import { toast } from 'svelte-sonner';
 	import Switch from '$lib/components/common/Switch.svelte';
 	import Spinner from '$lib/components/common/Spinner.svelte';
@@ -51,22 +46,6 @@
 	let ENABLE_OPENAI_API = null;
 	let ENABLE_OLLAMA_API = null;
 
-	// LDAP
-	let ENABLE_LDAP = false;
-	let LDAP_SERVER = {
-		label: '',
-		host: '',
-		port: '',
-		attribute_for_username: 'uid',
-		app_dn: '',
-		app_dn_password: '',
-		search_base: '',
-		search_filters: '',
-		use_tls: false,
-		certificate_path: '',
-		ciphers: ''
-	};
-
 	const verifyOpenAIHandler = async (idx) => {
 		OPENAI_API_BASE_URLS = OPENAI_API_BASE_URLS.map((url) => url.replace(/\/$/, ''));
 
@@ -158,17 +137,6 @@
 		}
 	};
 
-	const updateLdapServerHandler = async () => {
-		if (!ENABLE_LDAP) return;
-		const res = await updateLdapServer(localStorage.token, LDAP_SERVER).catch((error) => {
-			toast.error(error);
-			return null;
-		});
-		if (res) {
-			toast.success($i18n.t('LDAP server updated'));
-		}
-	};
-
 	onMount(async () => {
 		if ($user.role === 'admin') {
 			await Promise.all([
@@ -180,19 +148,14 @@
 				})(),
 				(async () => {
 					OPENAI_API_KEYS = await getOpenAIKeys(localStorage.token);
-				})(),
-				(async () => {
-					LDAP_SERVER = await getLdapServer(localStorage.token);
 				})()
 			]);
 
 			const ollamaConfig = await getOllamaConfig(localStorage.token);
 			const openaiConfig = await getOpenAIConfig(localStorage.token);
-			const ldapConfig = await getLdapConfig(localStorage.token);
 
 			ENABLE_OPENAI_API = openaiConfig.ENABLE_OPENAI_API;
 			ENABLE_OLLAMA_API = ollamaConfig.ENABLE_OLLAMA_API;
-			ENABLE_LDAP = ldapConfig.ENABLE_LDAP;
 
 			if (ENABLE_OPENAI_API) {
 				OPENAI_API_BASE_URLS.forEach(async (url, idx) => {
@@ -211,13 +174,12 @@
 	on:submit|preventDefault={() => {
 		updateOpenAIHandler();
 		updateOllamaUrlsHandler();
-		updateLdapServerHandler();
 
 		dispatch('save');
 	}}
 >
 	<div class="space-y-3 overflow-y-scroll scrollbar-hidden h-full">
-		{#if ENABLE_OPENAI_API !== null && ENABLE_OLLAMA_API !== null && ENABLE_LDAP !== null}
+		{#if ENABLE_OPENAI_API !== null && ENABLE_OLLAMA_API !== null}
 			<div class=" space-y-3">
 				<div class="mt-2 space-y-2 pr-1.5">
 					<div class="flex justify-between items-center text-sm">
@@ -467,196 +429,6 @@
 					</div>
 				{/if}
 			</div>
-
-			<hr class=" dark:border-gray-850" />
-
-			<div class=" space-y-3">
-				<div class="mt-2 space-y-2 pr-1.5">
-					<div class="flex justify-between items-center text-sm">
-						<div class="  font-medium">{$i18n.t('LDAP')}</div>
-
-						<div class="mt-1">
-							<Switch
-								bind:state={ENABLE_LDAP}
-								on:change={async () => {
-									updateLdapConfig(localStorage.token, ENABLE_LDAP);
-								}}
-							/>
-						</div>
-					</div>
-
-					{#if ENABLE_LDAP}
-						<div class="flex flex-col gap-1">
-							<div class="flex w-full gap-2">
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Label')}
-									</div>
-									<input
-										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-										required
-										placeholder={$i18n.t('Enter server label')}
-										bind:value={LDAP_SERVER.label}
-									/>
-								</div>
-								<div class="w-full"></div>
-							</div>
-							<div class="flex w-full gap-2">
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Host')}
-									</div>
-									<input
-										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-										required
-										placeholder={$i18n.t('Enter server host')}
-										bind:value={LDAP_SERVER.host}
-									/>
-								</div>
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Port')}
-									</div>
-									<Tooltip
-										placement="top-start"
-										content={$i18n.t('Default to 389 or 636 if TLS is enabled')}
-										className="w-full"
-									>
-										<input
-											class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-											type="number"
-											placeholder={$i18n.t('Enter server port')}
-											bind:value={LDAP_SERVER.port}
-										/>
-									</Tooltip>
-								</div>
-							</div>
-							<div class="flex w-full gap-2">
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Application DN')}
-									</div>
-									<Tooltip
-										content={$i18n.t('The Application Account DN you bind with for search')}
-										placement="top-start"
-									>
-										<input
-											class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-											required
-											placeholder={$i18n.t('Enter Application DN')}
-											bind:value={LDAP_SERVER.app_dn}
-										/>
-									</Tooltip>
-								</div>
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Application DN Password')}
-									</div>
-									<SensitiveInput
-										placeholder={$i18n.t('Enter Application DN Password')}
-										bind:value={LDAP_SERVER.app_dn_password}
-									/>
-								</div>
-							</div>
-							<div class="flex w-full gap-2">
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Attribute for Username')}
-									</div>
-									<Tooltip
-										content={$i18n.t(
-											'The LDAP attribute that maps to the username that users use to sign in.'
-										)}
-										placement="top-start"
-									>
-										<input
-											class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-											required
-											placeholder={$i18n.t('Example: sAMAccountName or uid or userPrincipalName')}
-											bind:value={LDAP_SERVER.attribute_for_username}
-										/>
-									</Tooltip>
-								</div>
-							</div>
-							<div class="flex w-full gap-2">
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Search Base')}
-									</div>
-									<Tooltip content={$i18n.t('The base to search for users')} placement="top-start">
-										<input
-											class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-											required
-											placeholder={$i18n.t('Example: ou=users,dc=foo,dc=example')}
-											bind:value={LDAP_SERVER.search_base}
-										/>
-									</Tooltip>
-								</div>
-							</div>
-							<div class="flex w-full gap-2">
-								<div class="w-full">
-									<div class=" self-center text-xs font-medium min-w-fit mb-1">
-										{$i18n.t('Search Filters')}
-									</div>
-									<input
-										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-										placeholder={$i18n.t('Example: (&(objectClass=inetOrgPerson)(uid=%s))')}
-										bind:value={LDAP_SERVER.search_filters}
-									/>
-								</div>
-							</div>
-							<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
-								<a
-									class=" text-gray-300 font-medium underline"
-									href="https://ldap.com/ldap-filters/"
-									target="_blank"
-								>
-									{$i18n.t('Click here for filter guides.')}
-								</a>
-							</div>
-							<div>
-								<div class="flex justify-between items-center text-sm">
-									<div class="  font-medium">{$i18n.t('TLS')}</div>
-
-									<div class="mt-1">
-										<Switch bind:state={LDAP_SERVER.use_tls} />
-									</div>
-								</div>
-								{#if LDAP_SERVER.use_tls}
-									<div class="flex w-full gap-2">
-										<div class="w-full">
-											<div class=" self-center text-xs font-medium min-w-fit mb-1 mt-1">
-												{$i18n.t('Certificate Path')}
-											</div>
-											<input
-												class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-												required
-												placeholder={$i18n.t('Enter certificate path')}
-												bind:value={LDAP_SERVER.certificate_path}
-											/>
-										</div>
-									</div>
-									<div class="flex w-full gap-2">
-										<div class="w-full">
-											<div class=" self-center text-xs font-medium min-w-fit mb-1">
-												{$i18n.t('Ciphers')}
-											</div>
-											<Tooltip content={$i18n.t('Default to ALL')} placement="top-start">
-												<input
-													class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
-													placeholder={$i18n.t('Example: ALL')}
-													bind:value={LDAP_SERVER.ciphers}
-												/>
-											</Tooltip>
-										</div>
-										<div class="w-full"></div>
-									</div>
-								{/if}
-							</div>
-						</div>
-					{/if}
-				</div>
-			</div>
 		{:else}
 			<div class="flex h-full justify-center">
 				<div class="my-auto">

+ 237 - 1
src/lib/components/admin/Settings/Users.svelte

@@ -3,10 +3,19 @@
 	import { getSignUpEnabledStatus, toggleSignUpEnabledStatus } from '$lib/apis/auths';
 	import { getUserPermissions, updateUserPermissions } from '$lib/apis/users';
 
+	import {
+		getLdapConfig,
+		updateLdapConfig,
+		getLdapServer,
+		updateLdapServer
+	} from '$lib/apis/auths';
+
 	import { onMount, getContext } from 'svelte';
 	import { models, config } from '$lib/stores';
 	import Switch from '$lib/components/common/Switch.svelte';
 	import { setDefaultModels } from '$lib/apis/configs';
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
 
 	const i18n = getContext('i18n');
 
@@ -28,6 +37,33 @@
 	let chatEdit = true;
 	let chatTemporary = true;
 
+	// LDAP
+	let ENABLE_LDAP = false;
+	let LDAP_SERVER = {
+		label: '',
+		host: '',
+		port: '',
+		attribute_for_username: 'uid',
+		app_dn: '',
+		app_dn_password: '',
+		search_base: '',
+		search_filters: '',
+		use_tls: false,
+		certificate_path: '',
+		ciphers: ''
+	};
+
+	const updateLdapServerHandler = async () => {
+		if (!ENABLE_LDAP) return;
+		const res = await updateLdapServer(localStorage.token, LDAP_SERVER).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+		if (res) {
+			toast.success($i18n.t('LDAP server updated'));
+		}
+	};
+
 	onMount(async () => {
 		permissions = await getUserPermissions(localStorage.token);
 
@@ -41,6 +77,13 @@
 			whitelistModels = res.models.length > 0 ? res.models : [''];
 		}
 
+		(async () => {
+			LDAP_SERVER = await getLdapServer(localStorage.token);
+		})();
+
+		const ldapConfig = await getLdapConfig(localStorage.token);
+		ENABLE_LDAP = ldapConfig.ENABLE_LDAP;
+
 		defaultModelId = $config.default_models ? $config?.default_models.split(',')[0] : '';
 	});
 </script>
@@ -59,12 +102,15 @@
 			}
 		});
 		await updateModelFilterConfig(localStorage.token, whitelistEnabled, whitelistModels);
+
+		await updateLdapServerHandler();
+
 		saveHandler();
 
 		await config.set(await getBackendConfig());
 	}}
 >
-	<div class=" space-y-3 overflow-y-scroll max-h-full">
+	<div class=" space-y-3 overflow-y-scroll max-h-full pr-1.5">
 		<div>
 			<div class=" mb-2 text-sm font-medium">{$i18n.t('User Permissions')}</div>
 
@@ -87,6 +133,196 @@
 			</div>
 		</div>
 
+		<hr class=" dark:border-gray-850" />
+
+		<div class=" space-y-3">
+			<div class="mt-2 space-y-2 pr-1.5">
+				<div class="flex justify-between items-center text-sm">
+					<div class="  font-medium">{$i18n.t('LDAP')}</div>
+
+					<div class="mt-1">
+						<Switch
+							bind:state={ENABLE_LDAP}
+							on:change={async () => {
+								updateLdapConfig(localStorage.token, ENABLE_LDAP);
+							}}
+						/>
+					</div>
+				</div>
+
+				{#if ENABLE_LDAP}
+					<div class="flex flex-col gap-1">
+						<div class="flex w-full gap-2">
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Label')}
+								</div>
+								<input
+									class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+									required
+									placeholder={$i18n.t('Enter server label')}
+									bind:value={LDAP_SERVER.label}
+								/>
+							</div>
+							<div class="w-full"></div>
+						</div>
+						<div class="flex w-full gap-2">
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Host')}
+								</div>
+								<input
+									class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+									required
+									placeholder={$i18n.t('Enter server host')}
+									bind:value={LDAP_SERVER.host}
+								/>
+							</div>
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Port')}
+								</div>
+								<Tooltip
+									placement="top-start"
+									content={$i18n.t('Default to 389 or 636 if TLS is enabled')}
+									className="w-full"
+								>
+									<input
+										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+										type="number"
+										placeholder={$i18n.t('Enter server port')}
+										bind:value={LDAP_SERVER.port}
+									/>
+								</Tooltip>
+							</div>
+						</div>
+						<div class="flex w-full gap-2">
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Application DN')}
+								</div>
+								<Tooltip
+									content={$i18n.t('The Application Account DN you bind with for search')}
+									placement="top-start"
+								>
+									<input
+										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+										required
+										placeholder={$i18n.t('Enter Application DN')}
+										bind:value={LDAP_SERVER.app_dn}
+									/>
+								</Tooltip>
+							</div>
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Application DN Password')}
+								</div>
+								<SensitiveInput
+									placeholder={$i18n.t('Enter Application DN Password')}
+									bind:value={LDAP_SERVER.app_dn_password}
+								/>
+							</div>
+						</div>
+						<div class="flex w-full gap-2">
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Attribute for Username')}
+								</div>
+								<Tooltip
+									content={$i18n.t(
+										'The LDAP attribute that maps to the username that users use to sign in.'
+									)}
+									placement="top-start"
+								>
+									<input
+										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+										required
+										placeholder={$i18n.t('Example: sAMAccountName or uid or userPrincipalName')}
+										bind:value={LDAP_SERVER.attribute_for_username}
+									/>
+								</Tooltip>
+							</div>
+						</div>
+						<div class="flex w-full gap-2">
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Search Base')}
+								</div>
+								<Tooltip content={$i18n.t('The base to search for users')} placement="top-start">
+									<input
+										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+										required
+										placeholder={$i18n.t('Example: ou=users,dc=foo,dc=example')}
+										bind:value={LDAP_SERVER.search_base}
+									/>
+								</Tooltip>
+							</div>
+						</div>
+						<div class="flex w-full gap-2">
+							<div class="w-full">
+								<div class=" self-center text-xs font-medium min-w-fit mb-1">
+									{$i18n.t('Search Filters')}
+								</div>
+								<input
+									class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+									placeholder={$i18n.t('Example: (&(objectClass=inetOrgPerson)(uid=%s))')}
+									bind:value={LDAP_SERVER.search_filters}
+								/>
+							</div>
+						</div>
+						<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
+							<a
+								class=" text-gray-300 font-medium underline"
+								href="https://ldap.com/ldap-filters/"
+								target="_blank"
+							>
+								{$i18n.t('Click here for filter guides.')}
+							</a>
+						</div>
+						<div>
+							<div class="flex justify-between items-center text-sm">
+								<div class="  font-medium">{$i18n.t('TLS')}</div>
+
+								<div class="mt-1">
+									<Switch bind:state={LDAP_SERVER.use_tls} />
+								</div>
+							</div>
+							{#if LDAP_SERVER.use_tls}
+								<div class="flex w-full gap-2">
+									<div class="w-full">
+										<div class=" self-center text-xs font-medium min-w-fit mb-1 mt-1">
+											{$i18n.t('Certificate Path')}
+										</div>
+										<input
+											class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+											required
+											placeholder={$i18n.t('Enter certificate path')}
+											bind:value={LDAP_SERVER.certificate_path}
+										/>
+									</div>
+								</div>
+								<div class="flex w-full gap-2">
+									<div class="w-full">
+										<div class=" self-center text-xs font-medium min-w-fit mb-1">
+											{$i18n.t('Ciphers')}
+										</div>
+										<Tooltip content={$i18n.t('Default to ALL')} placement="top-start">
+											<input
+												class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+												placeholder={$i18n.t('Example: ALL')}
+												bind:value={LDAP_SERVER.ciphers}
+											/>
+										</Tooltip>
+									</div>
+									<div class="w-full"></div>
+								</div>
+							{/if}
+						</div>
+					</div>
+				{/if}
+			</div>
+		</div>
+
 		<hr class=" dark:border-gray-850 my-2" />
 
 		<div class="mt-2 space-y-3">