165 lines
4.5 KiB
Vue
165 lines
4.5 KiB
Vue
<template>
|
|
<div
|
|
v-if="workingConfigs"
|
|
class="md:grid md:grid-cols-3 md:gap-4 border-divider border-b"
|
|
>
|
|
<div class="pb-8 px-8 md:col-span-1">
|
|
<h3 class="heading">{{ t('configs.auth_providers.title') }}</h3>
|
|
<p class="my-1 text-secondaryLight">
|
|
{{ t('configs.auth_providers.description') }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="space-y-8 p-8 md:col-span-2">
|
|
<section>
|
|
<h4 class="font-semibold text-secondaryDark">
|
|
{{ t('configs.auth_providers.title') }}
|
|
</h4>
|
|
|
|
<div
|
|
v-for="provider in workingConfigs.providers"
|
|
class="space-y-4 py-4"
|
|
>
|
|
<div class="flex items-center">
|
|
<HoppSmartToggle
|
|
:on="provider.enabled"
|
|
@change="provider.enabled = !provider.enabled"
|
|
>
|
|
{{ capitalize(provider.name) }}
|
|
</HoppSmartToggle>
|
|
</div>
|
|
|
|
<div v-if="provider.enabled" class="ml-12">
|
|
<div
|
|
v-for="field in providerConfigFields"
|
|
:key="field.key"
|
|
class="mt-5"
|
|
>
|
|
<template
|
|
v-if="field.applicableProviders.includes(provider.name)"
|
|
>
|
|
<label>{{ field.name }}</label>
|
|
<span class="flex max-w-lg">
|
|
<HoppSmartInput
|
|
v-model="provider.fields[field.key as keyof typeof provider['fields']]"
|
|
:type="
|
|
isMasked(provider.name, field.key) ? 'password' : 'text'
|
|
"
|
|
:autofocus="false"
|
|
class="!my-2 !bg-primaryLight flex-1"
|
|
/>
|
|
<HoppButtonSecondary
|
|
:icon="
|
|
isMasked(provider.name, field.key) ? IconEye : IconEyeOff
|
|
"
|
|
class="bg-primaryLight h-9 mt-2"
|
|
@click="toggleMask(provider.name, field.key)"
|
|
/>
|
|
</span>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useVModel } from '@vueuse/core';
|
|
import { reactive } from 'vue';
|
|
import { useI18n } from '~/composables/i18n';
|
|
import { ServerConfigs, SsoAuthProviders } from '~/helpers/configs';
|
|
import IconEye from '~icons/lucide/eye';
|
|
import IconEyeOff from '~icons/lucide/eye-off';
|
|
|
|
const t = useI18n();
|
|
|
|
const props = defineProps<{
|
|
config: ServerConfigs;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:config', v: ServerConfigs): void;
|
|
}>();
|
|
|
|
const workingConfigs = useVModel(props, 'config', emit);
|
|
|
|
// Capitalize first letter of a string
|
|
const capitalize = (text: string) =>
|
|
text.charAt(0).toUpperCase() + text.slice(1);
|
|
|
|
// Union type for all possible field keys
|
|
type ProviderFieldKeys = keyof ProviderFields;
|
|
|
|
type ProviderFields = {
|
|
[Field in keyof ServerConfigs['providers'][SsoAuthProviders]['fields']]: boolean;
|
|
} & Partial<{ tenant: boolean }>;
|
|
|
|
type ProviderFieldMetadata = {
|
|
name: string;
|
|
key: ProviderFieldKeys;
|
|
applicableProviders: SsoAuthProviders[];
|
|
};
|
|
|
|
const providerConfigFields = <ProviderFieldMetadata[]>[
|
|
{
|
|
name: t('configs.auth_providers.client_id'),
|
|
key: 'client_id',
|
|
applicableProviders: ['google', 'github', 'microsoft'],
|
|
},
|
|
{
|
|
name: t('configs.auth_providers.client_secret'),
|
|
key: 'client_secret',
|
|
applicableProviders: ['google', 'github', 'microsoft'],
|
|
},
|
|
{
|
|
name: t('configs.auth_providers.callback_url'),
|
|
key: 'callback_url',
|
|
applicableProviders: ['google', 'github', 'microsoft'],
|
|
},
|
|
{
|
|
name: t('configs.auth_providers.scope'),
|
|
key: 'scope',
|
|
applicableProviders: ['google', 'github', 'microsoft'],
|
|
},
|
|
{
|
|
name: t('configs.auth_providers.tenant'),
|
|
key: 'tenant',
|
|
applicableProviders: ['microsoft'],
|
|
},
|
|
];
|
|
|
|
const maskState = reactive<Record<SsoAuthProviders, ProviderFields>>({
|
|
google: {
|
|
client_id: true,
|
|
client_secret: true,
|
|
callback_url: true,
|
|
scope: true,
|
|
},
|
|
github: {
|
|
client_id: true,
|
|
client_secret: true,
|
|
callback_url: true,
|
|
scope: true,
|
|
},
|
|
microsoft: {
|
|
client_id: true,
|
|
client_secret: true,
|
|
callback_url: true,
|
|
scope: true,
|
|
tenant: true,
|
|
},
|
|
});
|
|
|
|
const toggleMask = (
|
|
provider: SsoAuthProviders,
|
|
fieldKey: ProviderFieldKeys
|
|
) => {
|
|
maskState[provider][fieldKey] = !maskState[provider][fieldKey];
|
|
};
|
|
|
|
const isMasked = (provider: SsoAuthProviders, fieldKey: ProviderFieldKeys) =>
|
|
maskState[provider][fieldKey];
|
|
</script>
|