Skip to content

Commit

Permalink
feat(sh-admin): introducing additional SSO related server configurati…
Browse files Browse the repository at this point in the history
…ons to dashboard (#3737)


Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
  • Loading branch information
JoelJacobStephen and jamesgeorge007 committed Mar 8, 2024
1 parent 6d66d12 commit e69d5a6
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 69 deletions.
3 changes: 3 additions & 0 deletions packages/hoppscotch-sh-admin/locales/en.json
Expand Up @@ -10,9 +10,12 @@
},
"configs": {
"auth_providers": {
"callback_url": "CALLBACK URL",
"client_id": "CLIENT ID",
"client_secret": "CLIENT SECRET",
"description": "Configure authentication providers for your server",
"scope": "SCOPE",
"tenant": "TENANT",
"title": "Authentication Providers",
"update_failure": "Failed to update authentication provider configurations!!"
},
Expand Down
6 changes: 6 additions & 0 deletions packages/hoppscotch-sh-admin/src/components.d.ts
Expand Up @@ -17,13 +17,19 @@ declare module '@vue/runtime-core' {
HoppButtonPrimary: typeof import('@hoppscotch/ui')['HoppButtonPrimary']
HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary']
HoppSmartAnchor: typeof import('@hoppscotch/ui')['HoppSmartAnchor']
HoppSmartAutoComplete: typeof import('@hoppscotch/ui')['HoppSmartAutoComplete']
HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal']
HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput']
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink']
HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
HoppSmartPicture: typeof import('@hoppscotch/ui')['HoppSmartPicture']
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab']
HoppSmartTable: typeof import('@hoppscotch/ui')['HoppSmartTable']
HoppSmartTabs: typeof import('@hoppscotch/ui')['HoppSmartTabs']
HoppSmartToggle: typeof import('@hoppscotch/ui')['HoppSmartToggle']
IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default']
IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
SettingsAuthProvider: typeof import('./components/settings/AuthProvider.vue')['default']
SettingsConfigurations: typeof import('./components/settings/Configurations.vue')['default']
Expand Down
109 changes: 71 additions & 38 deletions packages/hoppscotch-sh-admin/src/components/settings/AuthProvider.vue
Expand Up @@ -35,25 +35,29 @@
:key="field.key"
class="mt-5"
>
<label>{{ field.name }}</label>
<span class="flex">
<HoppSmartInput
v-model="provider.fields[field.key]"
:type="
isMasked(provider.name, field.key) ? 'password' : 'text'
"
:disabled="isMasked(provider.name, field.key)"
:autofocus="false"
class="!my-2 !bg-primaryLight"
/>
<HoppButtonSecondary
:icon="
isMasked(provider.name, field.key) ? IconEye : IconEyeOff
"
class="bg-primaryLight h-9 mt-2"
@click="toggleMask(provider.name, field.key)"
/>
</span>
<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'
"
:disabled="isMasked(provider.name, field.key)"
: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>
Expand Down Expand Up @@ -86,47 +90,76 @@ const workingConfigs = useVModel(props, 'config', emit);
const capitalize = (text: string) =>
text.charAt(0).toUpperCase() + text.slice(1);
// Masking sensitive fields
type Field = {
// Union type for all possible field keys
type ProviderFieldKeys = keyof ProviderFields;
type ProviderFields = {
[Field in keyof Config['providers'][SsoAuthProviders]['fields']]: boolean;
} & Partial<{ tenant: boolean }>;
type ProviderFieldMetadata = {
name: string;
key: keyof Config['providers']['google' | 'github' | 'microsoft']['fields'];
key: ProviderFieldKeys;
applicableProviders: SsoAuthProviders[];
};
const providerConfigFields = reactive<Field[]>([
{ name: t('configs.auth_providers.client_id'), key: 'client_id' },
{ name: t('configs.auth_providers.client_secret'), key: 'client_secret' },
]);
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({
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: keyof Config['providers'][
| 'google'
| 'github'
| 'microsoft']['fields']
fieldKey: ProviderFieldKeys
) => {
maskState[provider][fieldKey] = !maskState[provider][fieldKey];
};
const isMasked = (
provider: SsoAuthProviders,
fieldKey: keyof Config['providers'][
| 'google'
| 'github'
| 'microsoft']['fields']
) => maskState[provider][fieldKey];
const isMasked = (provider: SsoAuthProviders, fieldKey: ProviderFieldKeys) =>
maskState[provider][fieldKey];
</script>
Expand Up @@ -33,13 +33,13 @@
class="mt-5"
>
<label>{{ field.name }}</label>
<span class="flex">
<span class="flex max-w-lg">
<HoppSmartInput
v-model="smtpConfigs.fields[field.key]"
:type="isMasked(field.key) ? 'password' : 'text'"
:disabled="isMasked(field.key)"
:autofocus="false"
class="!my-2 !bg-primaryLight"
class="!my-2 !bg-primaryLight flex-1"
/>
<HoppButtonSecondary
:icon="isMasked(field.key) ? IconEye : IconEyeOff"
Expand Down

0 comments on commit e69d5a6

Please sign in to comment.