refactor(sh-admin): improved handling of server configurations in admin dashboard (#3971)
Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
committed by
GitHub
parent
eecc3db4e9
commit
94248076e6
@@ -52,7 +52,8 @@
|
|||||||
"title": "Server is restarting"
|
"title": "Server is restarting"
|
||||||
},
|
},
|
||||||
"save_changes": "Save Changes",
|
"save_changes": "Save Changes",
|
||||||
"title": "Configurations"
|
"title": "Configurations",
|
||||||
|
"update_failure": "Failed to update server configurations"
|
||||||
},
|
},
|
||||||
"data_sharing": {
|
"data_sharing": {
|
||||||
"description": "Share anonymous data usage to improve Hoppscotch",
|
"description": "Share anonymous data usage to improve Hoppscotch",
|
||||||
|
|||||||
@@ -69,18 +69,18 @@
|
|||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { Config, SsoAuthProviders } from '~/composables/useConfigHandler';
|
import { ServerConfigs, SsoAuthProviders } from '~/helpers/configs';
|
||||||
import IconEye from '~icons/lucide/eye';
|
import IconEye from '~icons/lucide/eye';
|
||||||
import IconEyeOff from '~icons/lucide/eye-off';
|
import IconEyeOff from '~icons/lucide/eye-off';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
@@ -93,7 +93,7 @@ const capitalize = (text: string) =>
|
|||||||
type ProviderFieldKeys = keyof ProviderFields;
|
type ProviderFieldKeys = keyof ProviderFields;
|
||||||
|
|
||||||
type ProviderFields = {
|
type ProviderFields = {
|
||||||
[Field in keyof Config['providers'][SsoAuthProviders]['fields']]: boolean;
|
[Field in keyof ServerConfigs['providers'][SsoAuthProviders]['fields']]: boolean;
|
||||||
} & Partial<{ tenant: boolean }>;
|
} & Partial<{ tenant: boolean }>;
|
||||||
|
|
||||||
type ProviderFieldMetadata = {
|
type ProviderFieldMetadata = {
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { Config } from '~/composables/useConfigHandler';
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
|
|||||||
@@ -38,17 +38,17 @@
|
|||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { Config } from '~/composables/useConfigHandler';
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
import IconShieldQuestion from '~icons/lucide/shield-question';
|
import IconShieldQuestion from '~icons/lucide/shield-question';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
|
|||||||
@@ -17,20 +17,21 @@ import { useMutation } from '@urql/vue';
|
|||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { useToast } from '~/composables/toast';
|
import { useToast } from '~/composables/toast';
|
||||||
import { Config, useConfigHandler } from '~/composables/useConfigHandler';
|
import { useConfigHandler } from '~/composables/useConfigHandler';
|
||||||
import {
|
import {
|
||||||
EnableAndDisableSsoDocument,
|
EnableAndDisableSsoDocument,
|
||||||
ResetInfraConfigsDocument,
|
ResetInfraConfigsDocument,
|
||||||
UpdateInfraConfigsDocument,
|
|
||||||
ToggleAnalyticsCollectionDocument,
|
ToggleAnalyticsCollectionDocument,
|
||||||
|
UpdateInfraConfigsDocument,
|
||||||
} from '~/helpers/backend/graphql';
|
} from '~/helpers/backend/graphql';
|
||||||
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
workingConfigs?: Config;
|
workingConfigs?: ServerConfigs;
|
||||||
reset?: boolean;
|
reset?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,18 +58,18 @@
|
|||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { Config } from '~/composables/useConfigHandler';
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
import IconEye from '~icons/lucide/eye';
|
import IconEye from '~icons/lucide/eye';
|
||||||
import IconEyeOff from '~icons/lucide/eye-off';
|
import IconEyeOff from '~icons/lucide/eye-off';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
@@ -87,7 +87,7 @@ const smtpConfigs = computed({
|
|||||||
// Mask sensitive fields
|
// Mask sensitive fields
|
||||||
type Field = {
|
type Field = {
|
||||||
name: string;
|
name: string;
|
||||||
key: keyof Config['mailConfigs']['fields'];
|
key: keyof ServerConfigs['mailConfigs']['fields'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const smtpConfigFields = reactive<Field[]>([
|
const smtpConfigFields = reactive<Field[]>([
|
||||||
@@ -100,10 +100,10 @@ const maskState = reactive<Record<string, boolean>>({
|
|||||||
mailer_from_address: true,
|
mailer_from_address: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const toggleMask = (fieldKey: keyof Config['mailConfigs']['fields']) => {
|
const toggleMask = (fieldKey: keyof ServerConfigs['mailConfigs']['fields']) => {
|
||||||
maskState[fieldKey] = !maskState[fieldKey];
|
maskState[fieldKey] = !maskState[fieldKey];
|
||||||
};
|
};
|
||||||
|
|
||||||
const isMasked = (fieldKey: keyof Config['mailConfigs']['fields']) =>
|
const isMasked = (fieldKey: keyof ServerConfigs['mailConfigs']['fields']) =>
|
||||||
maskState[fieldKey];
|
maskState[fieldKey];
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,83 +1,39 @@
|
|||||||
import { AnyVariables, UseMutationResponse } from '@urql/vue';
|
import { AnyVariables, UseMutationResponse } from '@urql/vue';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import {
|
import {
|
||||||
AllowedAuthProvidersDocument,
|
AllowedAuthProvidersDocument,
|
||||||
|
AuthProvider,
|
||||||
EnableAndDisableSsoArgs,
|
EnableAndDisableSsoArgs,
|
||||||
EnableAndDisableSsoMutation,
|
EnableAndDisableSsoMutation,
|
||||||
InfraConfigArgs,
|
InfraConfigArgs,
|
||||||
InfraConfigEnum,
|
InfraConfigEnum,
|
||||||
InfraConfigsDocument,
|
InfraConfigsDocument,
|
||||||
ResetInfraConfigsMutation,
|
ResetInfraConfigsMutation,
|
||||||
|
ServiceStatus,
|
||||||
ToggleAnalyticsCollectionMutation,
|
ToggleAnalyticsCollectionMutation,
|
||||||
UpdateInfraConfigsMutation,
|
UpdateInfraConfigsMutation,
|
||||||
} from '~/helpers/backend/graphql';
|
} from '~/helpers/backend/graphql';
|
||||||
|
import {
|
||||||
|
ALL_CONFIGS,
|
||||||
|
ConfigSection,
|
||||||
|
ConfigTransform,
|
||||||
|
GITHUB_CONFIGS,
|
||||||
|
GOOGLE_CONFIGS,
|
||||||
|
MAIL_CONFIGS,
|
||||||
|
MICROSOFT_CONFIGS,
|
||||||
|
ServerConfigs,
|
||||||
|
UpdatedConfigs,
|
||||||
|
} from '~/helpers/configs';
|
||||||
import { useToast } from './toast';
|
import { useToast } from './toast';
|
||||||
import { useClientHandler } from './useClientHandler';
|
import { useClientHandler } from './useClientHandler';
|
||||||
|
|
||||||
// Types
|
|
||||||
export type SsoAuthProviders = 'google' | 'microsoft' | 'github';
|
|
||||||
|
|
||||||
export type Config = {
|
|
||||||
providers: {
|
|
||||||
google: {
|
|
||||||
name: SsoAuthProviders;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
client_id: string;
|
|
||||||
client_secret: string;
|
|
||||||
callback_url: string;
|
|
||||||
scope: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
github: {
|
|
||||||
name: SsoAuthProviders;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
client_id: string;
|
|
||||||
client_secret: string;
|
|
||||||
callback_url: string;
|
|
||||||
scope: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
microsoft: {
|
|
||||||
name: SsoAuthProviders;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
client_id: string;
|
|
||||||
client_secret: string;
|
|
||||||
callback_url: string;
|
|
||||||
scope: string;
|
|
||||||
tenant: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mailConfigs: {
|
|
||||||
name: string;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
mailer_smtp_url: string;
|
|
||||||
mailer_from_address: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
dataSharingConfigs: {
|
|
||||||
name: string;
|
|
||||||
enabled: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type UpdatedConfigs = {
|
|
||||||
name: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Composable that handles all operations related to server configurations
|
/** Composable that handles all operations related to server configurations
|
||||||
* @param updatedConfigs A Config Object contatining the updated configs
|
* @param updatedConfigs A Config Object contatining the updated configs
|
||||||
*/
|
*/
|
||||||
export function useConfigHandler(updatedConfigs?: Config) {
|
export function useConfigHandler(updatedConfigs?: ServerConfigs) {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
@@ -90,24 +46,9 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
} = useClientHandler(
|
} = useClientHandler(
|
||||||
InfraConfigsDocument,
|
InfraConfigsDocument,
|
||||||
{
|
{
|
||||||
configNames: [
|
configNames: ALL_CONFIGS.flat().map(
|
||||||
'GOOGLE_CLIENT_ID',
|
({ name }) => name
|
||||||
'GOOGLE_CLIENT_SECRET',
|
) as InfraConfigEnum[],
|
||||||
'GOOGLE_CALLBACK_URL',
|
|
||||||
'GOOGLE_SCOPE',
|
|
||||||
'MICROSOFT_CLIENT_ID',
|
|
||||||
'MICROSOFT_CLIENT_SECRET',
|
|
||||||
'MICROSOFT_CALLBACK_URL',
|
|
||||||
'MICROSOFT_SCOPE',
|
|
||||||
'MICROSOFT_TENANT',
|
|
||||||
'GITHUB_CLIENT_ID',
|
|
||||||
'GITHUB_CLIENT_SECRET',
|
|
||||||
'GITHUB_CALLBACK_URL',
|
|
||||||
'GITHUB_SCOPE',
|
|
||||||
'MAILER_SMTP_URL',
|
|
||||||
'MAILER_ADDRESS_FROM',
|
|
||||||
'ALLOW_ANALYTICS_COLLECTION',
|
|
||||||
] as InfraConfigEnum[],
|
|
||||||
},
|
},
|
||||||
(x) => x.infraConfigs
|
(x) => x.infraConfigs
|
||||||
);
|
);
|
||||||
@@ -125,14 +66,14 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Current and working configs
|
// Current and working configs
|
||||||
const currentConfigs = ref<Config>();
|
const currentConfigs = ref<ServerConfigs>();
|
||||||
const workingConfigs = ref<Config>();
|
const workingConfigs = ref<ServerConfigs>();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await fetchInfraConfigs();
|
await fetchInfraConfigs();
|
||||||
await fetchAllowedAuthProviders();
|
await fetchAllowedAuthProviders();
|
||||||
|
|
||||||
const getFieldValue = (name: string) =>
|
const getFieldValue = (name: InfraConfigEnum) =>
|
||||||
infraConfigs.value.find((x) => x.name === name)?.value ?? '';
|
infraConfigs.value.find((x) => x.name === name)?.value ?? '';
|
||||||
|
|
||||||
// Transforming the fetched data into a Configs object
|
// Transforming the fetched data into a Configs object
|
||||||
@@ -140,42 +81,42 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
providers: {
|
providers: {
|
||||||
google: {
|
google: {
|
||||||
name: 'google',
|
name: 'google',
|
||||||
enabled: allowedAuthProviders.value.includes('GOOGLE'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Google),
|
||||||
fields: {
|
fields: {
|
||||||
client_id: getFieldValue('GOOGLE_CLIENT_ID'),
|
client_id: getFieldValue(InfraConfigEnum.GoogleClientId),
|
||||||
client_secret: getFieldValue('GOOGLE_CLIENT_SECRET'),
|
client_secret: getFieldValue(InfraConfigEnum.GoogleClientSecret),
|
||||||
callback_url: getFieldValue('GOOGLE_CALLBACK_URL'),
|
callback_url: getFieldValue(InfraConfigEnum.GoogleCallbackUrl),
|
||||||
scope: getFieldValue('GOOGLE_SCOPE'),
|
scope: getFieldValue(InfraConfigEnum.GoogleScope),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
github: {
|
github: {
|
||||||
name: 'github',
|
name: 'github',
|
||||||
enabled: allowedAuthProviders.value.includes('GITHUB'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Github),
|
||||||
fields: {
|
fields: {
|
||||||
client_id: getFieldValue('GITHUB_CLIENT_ID'),
|
client_id: getFieldValue(InfraConfigEnum.GithubClientId),
|
||||||
client_secret: getFieldValue('GITHUB_CLIENT_SECRET'),
|
client_secret: getFieldValue(InfraConfigEnum.GithubClientSecret),
|
||||||
callback_url: getFieldValue('GITHUB_CALLBACK_URL'),
|
callback_url: getFieldValue(InfraConfigEnum.GoogleCallbackUrl),
|
||||||
scope: getFieldValue('GITHUB_SCOPE'),
|
scope: getFieldValue(InfraConfigEnum.GithubScope),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
microsoft: {
|
microsoft: {
|
||||||
name: 'microsoft',
|
name: 'microsoft',
|
||||||
enabled: allowedAuthProviders.value.includes('MICROSOFT'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Microsoft),
|
||||||
fields: {
|
fields: {
|
||||||
client_id: getFieldValue('MICROSOFT_CLIENT_ID'),
|
client_id: getFieldValue(InfraConfigEnum.MicrosoftClientId),
|
||||||
client_secret: getFieldValue('MICROSOFT_CLIENT_SECRET'),
|
client_secret: getFieldValue(InfraConfigEnum.MicrosoftClientSecret),
|
||||||
callback_url: getFieldValue('MICROSOFT_CALLBACK_URL'),
|
callback_url: getFieldValue(InfraConfigEnum.MicrosoftCallbackUrl),
|
||||||
scope: getFieldValue('MICROSOFT_SCOPE'),
|
scope: getFieldValue(InfraConfigEnum.MicrosoftScope),
|
||||||
tenant: getFieldValue('MICROSOFT_TENANT'),
|
tenant: getFieldValue(InfraConfigEnum.MicrosoftTenant),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mailConfigs: {
|
mailConfigs: {
|
||||||
name: 'email',
|
name: 'email',
|
||||||
enabled: allowedAuthProviders.value.includes('EMAIL'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Email),
|
||||||
fields: {
|
fields: {
|
||||||
mailer_smtp_url: getFieldValue('MAILER_SMTP_URL'),
|
mailer_smtp_url: getFieldValue(InfraConfigEnum.MailerSmtpUrl),
|
||||||
mailer_from_address: getFieldValue('MAILER_ADDRESS_FROM'),
|
mailer_from_address: getFieldValue(InfraConfigEnum.MailerAddressFrom),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dataSharingConfigs: {
|
dataSharingConfigs: {
|
||||||
@@ -191,138 +132,13 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
workingConfigs.value = cloneDeep(currentConfigs.value);
|
workingConfigs.value = cloneDeep(currentConfigs.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Transforming the working configs back into the format required by the mutations
|
/*
|
||||||
const updatedInfraConfigs = computed(() => {
|
Check if any of the config fields are empty
|
||||||
let config: UpdatedConfigs[] = [
|
*/
|
||||||
{
|
|
||||||
name: '',
|
|
||||||
value: '',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (updatedConfigs?.providers.google.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_CLIENT_ID',
|
|
||||||
value: updatedConfigs?.providers.google.fields.client_id ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_CLIENT_SECRET',
|
|
||||||
value: updatedConfigs?.providers.google.fields.client_secret ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_CALLBACK_URL',
|
|
||||||
value: updatedConfigs?.providers.google.fields.callback_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_SCOPE',
|
|
||||||
value: updatedConfigs?.providers.google.fields.scope ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'GOOGLE_CLIENT_ID' &&
|
|
||||||
item.name !== 'GOOGLE_CLIENT_SECRET' &&
|
|
||||||
item.name !== 'GOOGLE_CALLBACK_URL' &&
|
|
||||||
item.name !== 'GOOGLE_SCOPE'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (updatedConfigs?.providers.microsoft.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_CLIENT_ID',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.client_id ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_CLIENT_SECRET',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.client_secret ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_CALLBACK_URL',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.callback_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_SCOPE',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.scope ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_TENANT',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.tenant ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'MICROSOFT_CLIENT_ID' &&
|
|
||||||
item.name !== 'MICROSOFT_CLIENT_SECRET' &&
|
|
||||||
item.name !== 'MICROSOFT_CALLBACK_URL' &&
|
|
||||||
item.name !== 'MICROSOFT_SCOPE' &&
|
|
||||||
item.name !== 'MICROSOFT_TENANT'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updatedConfigs?.providers.github.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'GITHUB_CLIENT_ID',
|
|
||||||
value: updatedConfigs?.providers.github.fields.client_id ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_CLIENT_SECRET',
|
|
||||||
value: updatedConfigs?.providers.github.fields.client_secret ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_CALLBACK_URL',
|
|
||||||
value: updatedConfigs?.providers.github.fields.callback_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_SCOPE',
|
|
||||||
value: updatedConfigs?.providers.github.fields.scope ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'GITHUB_CLIENT_ID' &&
|
|
||||||
item.name !== 'GITHUB_CLIENT_SECRET' &&
|
|
||||||
item.name !== 'GITHUB_CALLBACK_URL' &&
|
|
||||||
item.name !== 'GITHUB_SCOPE'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updatedConfigs?.mailConfigs.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'MAILER_SMTP_URL',
|
|
||||||
value: updatedConfigs?.mailConfigs.fields.mailer_smtp_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MAILER_ADDRESS_FROM',
|
|
||||||
value: updatedConfigs?.mailConfigs.fields.mailer_from_address ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'MAILER_SMTP_URL' && item.name !== 'MAILER_ADDRESS_FROM'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
config = config.filter((item) => item.name !== '');
|
|
||||||
|
|
||||||
return config;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Checking if any of the config fields are empty
|
|
||||||
const isFieldEmpty = (field: string) => field.trim() === '';
|
const isFieldEmpty = (field: string) => field.trim() === '';
|
||||||
|
|
||||||
type ConfigSection = {
|
const AreAnyConfigFieldsEmpty = (config: ServerConfigs): boolean => {
|
||||||
enabled: boolean;
|
|
||||||
fields: Record<string, string>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AreAnyConfigFieldsEmpty = (config: Config): boolean => {
|
|
||||||
const sections: Array<ConfigSection> = [
|
const sections: Array<ConfigSection> = [
|
||||||
config.providers.github,
|
config.providers.github,
|
||||||
config.providers.google,
|
config.providers.google,
|
||||||
@@ -337,28 +153,44 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Transforming the working configs back into the format required by the mutations
|
// Transforming the working configs back into the format required by the mutations
|
||||||
const updatedAllowedAuthProviders = computed(() => {
|
const transformInfraConfigs = () => {
|
||||||
return [
|
const updatedWorkingConfigs: ConfigTransform[] = [
|
||||||
{
|
{
|
||||||
provider: 'GOOGLE',
|
config: GOOGLE_CONFIGS,
|
||||||
status: updatedConfigs?.providers.google.enabled ? 'ENABLE' : 'DISABLE',
|
enabled: updatedConfigs?.providers.google.enabled,
|
||||||
|
fields: updatedConfigs?.providers.google.fields,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: 'MICROSOFT',
|
config: GITHUB_CONFIGS,
|
||||||
status: updatedConfigs?.providers.microsoft.enabled
|
enabled: updatedConfigs?.providers.github.enabled,
|
||||||
? 'ENABLE'
|
fields: updatedConfigs?.providers.github.fields,
|
||||||
: 'DISABLE',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: 'GITHUB',
|
config: MICROSOFT_CONFIGS,
|
||||||
status: updatedConfigs?.providers.github.enabled ? 'ENABLE' : 'DISABLE',
|
enabled: updatedConfigs?.providers.microsoft.enabled,
|
||||||
|
fields: updatedConfigs?.providers.microsoft.fields,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: 'EMAIL',
|
config: MAIL_CONFIGS,
|
||||||
status: updatedConfigs?.mailConfigs.enabled ? 'ENABLE' : 'DISABLE',
|
enabled: updatedConfigs?.mailConfigs.enabled,
|
||||||
|
fields: updatedConfigs?.mailConfigs.fields,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
|
||||||
|
const transformedConfigs: UpdatedConfigs[] = [];
|
||||||
|
|
||||||
|
updatedWorkingConfigs.forEach(({ config, enabled, fields }) => {
|
||||||
|
config.forEach(({ name, key }) => {
|
||||||
|
if (enabled && fields) {
|
||||||
|
const value =
|
||||||
|
typeof fields === 'string' ? fields : String(fields[key]);
|
||||||
|
transformedConfigs.push({ name, value });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return transformedConfigs;
|
||||||
|
};
|
||||||
|
|
||||||
// Generic function to handle mutation execution and error handling
|
// Generic function to handle mutation execution and error handling
|
||||||
const executeMutation = async <T, V>(
|
const executeMutation = async <T, V>(
|
||||||
@@ -379,27 +211,59 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
// Updating the auth provider configurations
|
// Updating the auth provider configurations
|
||||||
const updateAuthProvider = (
|
const updateAuthProvider = (
|
||||||
updateProviderStatus: UseMutationResponse<EnableAndDisableSsoMutation>
|
updateProviderStatus: UseMutationResponse<EnableAndDisableSsoMutation>
|
||||||
) =>
|
) => {
|
||||||
executeMutation(
|
const updatedAllowedAuthProviders: EnableAndDisableSsoArgs[] = [
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Google,
|
||||||
|
status: updatedConfigs?.providers.google.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Microsoft,
|
||||||
|
status: updatedConfigs?.providers.microsoft.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Github,
|
||||||
|
status: updatedConfigs?.providers.github.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Email,
|
||||||
|
status: updatedConfigs?.mailConfigs.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return executeMutation(
|
||||||
updateProviderStatus,
|
updateProviderStatus,
|
||||||
{
|
{
|
||||||
providerInfo:
|
providerInfo: updatedAllowedAuthProviders,
|
||||||
updatedAllowedAuthProviders.value as EnableAndDisableSsoArgs[],
|
|
||||||
},
|
},
|
||||||
'configs.auth_providers.update_failure'
|
'configs.auth_providers.update_failure'
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Updating the infra configurations
|
// Updating the infra configurations
|
||||||
const updateInfraConfigs = (
|
const updateInfraConfigs = (
|
||||||
updateInfraConfigsMutation: UseMutationResponse<UpdateInfraConfigsMutation>
|
updateInfraConfigsMutation: UseMutationResponse<UpdateInfraConfigsMutation>
|
||||||
) =>
|
) => {
|
||||||
executeMutation(
|
const infraConfigs: InfraConfigArgs[] = updatedConfigs
|
||||||
|
? transformInfraConfigs()
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return executeMutation(
|
||||||
updateInfraConfigsMutation,
|
updateInfraConfigsMutation,
|
||||||
{
|
{
|
||||||
infraConfigs: updatedInfraConfigs.value as InfraConfigArgs[],
|
infraConfigs,
|
||||||
},
|
},
|
||||||
'configs.mail_configs.update_failure'
|
'configs.update_failure'
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Resetting the infra configurations
|
// Resetting the infra configurations
|
||||||
const resetInfraConfigs = (
|
const resetInfraConfigs = (
|
||||||
@@ -411,7 +275,6 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
'configs.reset.failure'
|
'configs.reset.failure'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Updating the data sharing configurations
|
|
||||||
const updateDataSharingConfigs = (
|
const updateDataSharingConfigs = (
|
||||||
toggleDataSharingMutation: UseMutationResponse<ToggleAnalyticsCollectionMutation>
|
toggleDataSharingMutation: UseMutationResponse<ToggleAnalyticsCollectionMutation>
|
||||||
) =>
|
) =>
|
||||||
@@ -419,8 +282,8 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
toggleDataSharingMutation,
|
toggleDataSharingMutation,
|
||||||
{
|
{
|
||||||
status: updatedConfigs?.dataSharingConfigs.enabled
|
status: updatedConfigs?.dataSharingConfigs.enabled
|
||||||
? 'ENABLE'
|
? ServiceStatus.Enable
|
||||||
: 'DISABLE',
|
: ServiceStatus.Disable,
|
||||||
},
|
},
|
||||||
'configs.data_sharing.update_failure'
|
'configs.data_sharing.update_failure'
|
||||||
);
|
);
|
||||||
@@ -428,8 +291,6 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
return {
|
return {
|
||||||
currentConfigs,
|
currentConfigs,
|
||||||
workingConfigs,
|
workingConfigs,
|
||||||
updatedInfraConfigs,
|
|
||||||
updatedAllowedAuthProviders,
|
|
||||||
updateAuthProvider,
|
updateAuthProvider,
|
||||||
updateDataSharingConfigs,
|
updateDataSharingConfigs,
|
||||||
updateInfraConfigs,
|
updateInfraConfigs,
|
||||||
|
|||||||
160
packages/hoppscotch-sh-admin/src/helpers/configs.ts
Normal file
160
packages/hoppscotch-sh-admin/src/helpers/configs.ts
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
import { InfraConfigEnum } from './backend/graphql';
|
||||||
|
|
||||||
|
export type SsoAuthProviders = 'google' | 'microsoft' | 'github';
|
||||||
|
|
||||||
|
export type ServerConfigs = {
|
||||||
|
providers: {
|
||||||
|
google: {
|
||||||
|
name: SsoAuthProviders;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
callback_url: string;
|
||||||
|
scope: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
github: {
|
||||||
|
name: SsoAuthProviders;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
callback_url: string;
|
||||||
|
scope: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
microsoft: {
|
||||||
|
name: SsoAuthProviders;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
callback_url: string;
|
||||||
|
scope: string;
|
||||||
|
tenant: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mailConfigs: {
|
||||||
|
name: string;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
mailer_smtp_url: string;
|
||||||
|
mailer_from_address: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
dataSharingConfigs: {
|
||||||
|
name: string;
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdatedConfigs = {
|
||||||
|
name: InfraConfigEnum;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConfigTransform = {
|
||||||
|
config: Config[];
|
||||||
|
enabled?: boolean;
|
||||||
|
fields?: Record<string, string | boolean> | string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConfigSection = {
|
||||||
|
enabled: boolean;
|
||||||
|
fields: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Config = {
|
||||||
|
name: InfraConfigEnum;
|
||||||
|
key: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GOOGLE_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleClientId,
|
||||||
|
key: 'client_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleClientSecret,
|
||||||
|
key: 'client_secret',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleCallbackUrl,
|
||||||
|
key: 'callback_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleScope,
|
||||||
|
key: 'scope',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MICROSOFT_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftClientId,
|
||||||
|
key: 'client_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftClientSecret,
|
||||||
|
key: 'client_secret',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftCallbackUrl,
|
||||||
|
key: 'callback_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftScope,
|
||||||
|
key: 'scope',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftTenant,
|
||||||
|
key: 'tenant',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const GITHUB_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubClientId,
|
||||||
|
key: 'client_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubClientSecret,
|
||||||
|
key: 'client_secret',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubCallbackUrl,
|
||||||
|
key: 'callback_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubScope,
|
||||||
|
key: 'scope',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MAIL_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MailerSmtpUrl,
|
||||||
|
key: 'mailer_smtp_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MailerAddressFrom,
|
||||||
|
key: 'mailer_from_address',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const DATA_SHARING_CONFIGS: Omit<Config, 'key'>[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.AllowAnalyticsCollection,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const ALL_CONFIGS = [
|
||||||
|
GOOGLE_CONFIGS,
|
||||||
|
MICROSOFT_CONFIGS,
|
||||||
|
GITHUB_CONFIGS,
|
||||||
|
MAIL_CONFIGS,
|
||||||
|
DATA_SHARING_CONFIGS,
|
||||||
|
];
|
||||||
@@ -208,13 +208,14 @@ const deleteUserMutation = async (id: string | null) => {
|
|||||||
if (result.error) {
|
if (result.error) {
|
||||||
toast.error(t('state.delete_user_failure'));
|
toast.error(t('state.delete_user_failure'));
|
||||||
} else {
|
} else {
|
||||||
const deletedUsers = result.data?.removeUsersByAdmin || [];
|
const deletedUser = result.data?.removeUsersByAdmin || [];
|
||||||
|
handleUserDeletion(deletedUser);
|
||||||
|
|
||||||
handleUserDeletion(deletedUsers);
|
const { isDeleted } = deletedUser[0];
|
||||||
|
if (isDeleted) router.push('/users');
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDeletion.value = false;
|
confirmDeletion.value = false;
|
||||||
deleteUserUID.value = null;
|
deleteUserUID.value = null;
|
||||||
|
|
||||||
!result.error && router.push('/users');
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user