diff --git a/packages/hoppscotch-sh-admin/locales/en.json b/packages/hoppscotch-sh-admin/locales/en.json index 8920ee48b..e256c15d1 100644 --- a/packages/hoppscotch-sh-admin/locales/en.json +++ b/packages/hoppscotch-sh-admin/locales/en.json @@ -6,6 +6,39 @@ "no_name": "No name", "open_navigation": "Open Navigation" }, + "configs": { + "auth_providers": { + "client_id": "CLIENT ID", + "client_secret": "CLIENT SECRET", + "description": "Configure authentication providers for your server", + "title": "Authentication Providers", + "update_failure": "Failed to update authentication provider configurations!!" + }, + "confirm_changes": "Hoppscotch server must restart to reflect the new changes. Confirm changes made to the server configurations?", + "load_error": "Unable to load server configurations", + "mail_configs": { + "description": " Configure the smtp configurations", + "enable": "Email based authentication", + "smtp_url": "MAILER SMTP URL", + "address_from": "MAILER FROM ADDRESS", + "title": "SMTP Configurations", + "update_failure": "Failed to update smtp configurations!!" + }, + "reset": { + "confirm_reset": "Hoppscotch server must restart to reflect the new changes. Confirm the reset of server configurations?", + "description": "Default configurations will be loaded as specified in the environment file", + "failure": "Failed to reset configurations!!", + "title": "Reset Configurations", + "info": "Reset server configurations" + }, + "restart": { + "description": "{duration} seconds remaining before this page reloads automatically", + "initiate": "Initiating server restart...", + "title": "Server is restarting" + }, + "save_changes": "Save Changes", + "title": "Configurations" + }, "metrics": { "dashboard": "Dashboard", "no_metrics": "No metrics found", @@ -19,6 +52,9 @@ "owner": "OWNER", "viewer": "VIEWER" }, + "settings": { + "settings": "Settings" + }, "shared_requests": { "clear_filter": "Clear Filter", "confirm_request_deletion": "Confirm deletion of the selected shared request?", @@ -65,6 +101,7 @@ "email_success": "Email invitation sent successfully", "enter_team_email": "Please enter email of team owner!!", "error": "Something went wrong", + "error_auth_providers": "Unable to load auth providers", "github_signin_failure": "Failed to login with Github", "google_signin_failure": "Failed to login with Google", "invalid_email": "Please enter a valid email address", diff --git a/packages/hoppscotch-sh-admin/package.json b/packages/hoppscotch-sh-admin/package.json index ac75cc58c..d5d81fa3e 100644 --- a/packages/hoppscotch-sh-admin/package.json +++ b/packages/hoppscotch-sh-admin/package.json @@ -58,6 +58,7 @@ "@graphql-codegen/urql-introspection": "2.2.1", "@import-meta-env/cli": "^0.6.3", "@import-meta-env/unplugin": "^0.4.8", + "@types/lodash-es": "^4.17.12", "@vitejs/plugin-vue": "^3.1.0", "@vue/compiler-sfc": "^3.2.6", "dotenv": "^16.0.3", diff --git a/packages/hoppscotch-sh-admin/src/components.d.ts b/packages/hoppscotch-sh-admin/src/components.d.ts index 9e29af7b4..74372d52e 100644 --- a/packages/hoppscotch-sh-admin/src/components.d.ts +++ b/packages/hoppscotch-sh-admin/src/components.d.ts @@ -19,18 +19,25 @@ 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'] + 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'] IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default'] IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default'] IconLucideInbox: typeof import('~icons/lucide/inbox')['default'] - IconLucideUser: typeof import('~icons/lucide/user')['default'] + SettingsAuthProvider: typeof import('./components/settings/AuthProvider.vue')['default'] + SettingsConfigurations: typeof import('./components/settings/Configurations.vue')['default'] + SettingsReset: typeof import('./components/settings/Reset.vue')['default'] + SettingsServerRestart: typeof import('./components/settings/ServerRestart.vue')['default'] + SettingsSmtpConfiguration: typeof import('./components/settings/SmtpConfiguration.vue')['default'] SmartAnchor: typeof import('./../../hoppscotch-ui/src/components/smart/Anchor.vue')['default'] SmartAutoComplete: typeof import('./../../hoppscotch-ui/src/components/smart/AutoComplete.vue')['default'] SmartCheckbox: typeof import('./../../hoppscotch-ui/src/components/smart/Checkbox.vue')['default'] @@ -47,6 +54,7 @@ declare module '@vue/runtime-core' { SmartProgressRing: typeof import('./../../hoppscotch-ui/src/components/smart/ProgressRing.vue')['default'] SmartRadio: typeof import('./../../hoppscotch-ui/src/components/smart/Radio.vue')['default'] SmartRadioGroup: typeof import('./../../hoppscotch-ui/src/components/smart/RadioGroup.vue')['default'] + SmartSelectWrapper: typeof import('./../../hoppscotch-ui/src/components/smart/SelectWrapper.vue')['default'] SmartSlideOver: typeof import('./../../hoppscotch-ui/src/components/smart/SlideOver.vue')['default'] SmartSpinner: typeof import('./../../hoppscotch-ui/src/components/smart/Spinner.vue')['default'] SmartTab: typeof import('./../../hoppscotch-ui/src/components/smart/Tab.vue')['default'] diff --git a/packages/hoppscotch-sh-admin/src/components/app/Login.vue b/packages/hoppscotch-sh-admin/src/components/app/Login.vue index 84344ac9a..37c15c516 100644 --- a/packages/hoppscotch-sh-admin/src/components/app/Login.vue +++ b/packages/hoppscotch-sh-admin/src/components/app/Login.vue @@ -6,6 +6,15 @@ }} {{ t('state.login_as_admin') }} + +
+ +
+ +
+

{{ t('state.error') }}

+
+
import { onMounted, ref } from 'vue'; +import { useI18n } from '~/composables/i18n'; +import { useToast } from '~/composables/toast'; +import { auth } from '~/helpers/auth'; +import { setLocalConfig } from '~/helpers/localpersistence'; +import IconEmail from '~icons/auth/email'; import IconGithub from '~icons/auth/github'; import IconGoogle from '~icons/auth/google'; -import IconEmail from '~icons/auth/email'; import IconMicrosoft from '~icons/auth/microsoft'; import IconArrowLeft from '~icons/lucide/arrow-left'; import IconFileText from '~icons/lucide/file-text'; -import { setLocalConfig } from '~/helpers/localpersistence'; -import { useStreamSubscriber } from '~/composables/stream'; -import { useToast } from '~/composables/toast'; -import { auth } from '~/helpers/auth'; -import { HoppButtonPrimary, HoppButtonSecondary } from '@hoppscotch/ui'; -import { useI18n } from '~/composables/i18n'; - -const { subscribeToStream } = useStreamSubscriber(); const t = useI18n(); const toast = useToast(); const tosLink = import.meta.env.VITE_APP_TOS_LINK; const privacyPolicyLink = import.meta.env.VITE_APP_PRIVACY_POLICY_LINK; -const allowedAuthProviders = import.meta.env.VITE_ALLOWED_AUTH_PROVIDERS; - -// DATA const form = ref({ email: '', }); +const fetching = ref(false); +const error = ref(false); const signingInWithGoogle = ref(false); const signingInWithGitHub = ref(false); const signingInWithMicrosoft = ref(false); const signingInWithEmail = ref(false); const mode = ref('sign-in'); - const nonAdminUser = ref(false); -onMounted(() => { - const currentUser$ = auth.getCurrentUserStream(); +const allowedAuthProviders = ref([]); - subscribeToStream(currentUser$, (user) => { - if (user && !user.isAdmin) { - nonAdminUser.value = true; - toast.error(t('state.non_admin_login')); - } - }); +onMounted(async () => { + allowedAuthProviders.value = await getAllowedAuthProviders(); }); const signInWithGoogle = () => { @@ -241,6 +239,19 @@ const signInWithEmail = async () => { signingInWithEmail.value = false; }; +const getAllowedAuthProviders = async () => { + fetching.value = true; + try { + const res = await auth.getAllowedAuthProviders(); + return res; + } catch (e) { + error.value = true; + toast.error(t('state.error_auth_providers')); + } finally { + fetching.value = false; + } +}; + const logout = async () => { try { await auth.signOutUser(); diff --git a/packages/hoppscotch-sh-admin/src/components/app/Sidebar.vue b/packages/hoppscotch-sh-admin/src/components/app/Sidebar.vue index 9fd8aaad6..00dec813a 100644 --- a/packages/hoppscotch-sh-admin/src/components/app/Sidebar.vue +++ b/packages/hoppscotch-sh-admin/src/components/app/Sidebar.vue @@ -65,6 +65,7 @@ import { useSidebar } from '~/composables/useSidebar'; import IconDashboard from '~icons/lucide/layout-dashboard'; import IconUser from '~icons/lucide/user'; import IconUsers from '~icons/lucide/users'; +import IconSettings from '~icons/lucide/settings'; import { useI18n } from '~/composables/i18n'; const t = useI18n(); @@ -90,6 +91,12 @@ const primaryNavigations = [ to: '/teams', exact: false, }, + { + label: t('settings.settings'), + icon: IconSettings, + to: '/settings', + exact: true, + }, ]; diff --git a/packages/hoppscotch-sh-admin/src/components/settings/AuthProvider.vue b/packages/hoppscotch-sh-admin/src/components/settings/AuthProvider.vue new file mode 100644 index 000000000..a4053a278 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/components/settings/AuthProvider.vue @@ -0,0 +1,132 @@ + + + diff --git a/packages/hoppscotch-sh-admin/src/components/settings/Configurations.vue b/packages/hoppscotch-sh-admin/src/components/settings/Configurations.vue new file mode 100644 index 000000000..bd20a094a --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/components/settings/Configurations.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/hoppscotch-sh-admin/src/components/settings/Reset.vue b/packages/hoppscotch-sh-admin/src/components/settings/Reset.vue new file mode 100644 index 000000000..ddfa35380 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/components/settings/Reset.vue @@ -0,0 +1,45 @@ + + + diff --git a/packages/hoppscotch-sh-admin/src/components/settings/ServerRestart.vue b/packages/hoppscotch-sh-admin/src/components/settings/ServerRestart.vue new file mode 100644 index 000000000..495e5f56e --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/components/settings/ServerRestart.vue @@ -0,0 +1,87 @@ + + + diff --git a/packages/hoppscotch-sh-admin/src/components/settings/SmtpConfiguration.vue b/packages/hoppscotch-sh-admin/src/components/settings/SmtpConfiguration.vue new file mode 100644 index 000000000..d1c2b9442 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/components/settings/SmtpConfiguration.vue @@ -0,0 +1,110 @@ + + + diff --git a/packages/hoppscotch-sh-admin/src/composables/useClientHandler.ts b/packages/hoppscotch-sh-admin/src/composables/useClientHandler.ts new file mode 100644 index 000000000..2944b9fd8 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/composables/useClientHandler.ts @@ -0,0 +1,49 @@ +import { TypedDocumentNode, useClientHandle } from '@urql/vue'; +import { DocumentNode } from 'graphql'; +import { ref } from 'vue'; + +/** A composable function to handle grapqhl requests + * using urql's useClientHandle + * @param query The query to be executed + * @param getList A function to get the list from the result + * @param variables The variables to be passed to the query + */ +export function useClientHandler< + Result, + Vars extends Record, + ListItem +>( + query: string | TypedDocumentNode | DocumentNode, + getList: (result: Result) => ListItem[], + variables: Vars +) { + const { client } = useClientHandle(); + const fetching = ref(true); + const error = ref(false); + const list = ref([]); + + const fetchList = async () => { + fetching.value = true; + try { + const result = await client + .query(query, { + ...variables, + }) + .toPromise(); + + const resultList = getList(result.data!); + + list.value.push(...resultList); + } catch (e) { + error.value = true; + } + fetching.value = false; + }; + + return { + fetching, + error, + list, + fetchList, + }; +} diff --git a/packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts b/packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts new file mode 100644 index 000000000..73a212e05 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts @@ -0,0 +1,345 @@ +import { computed, onMounted, ref } from 'vue'; +import { cloneDeep } from 'lodash-es'; +import { UseMutationResponse } from '@urql/vue'; +import { useClientHandler } from './useClientHandler'; +import { useToast } from './toast'; +import { useI18n } from '~/composables/i18n'; +import { + InfraConfigEnum, + InfraConfigsDocument, + AllowedAuthProvidersDocument, + EnableAndDisableSsoMutation, + UpdateInfraConfigsMutation, + ResetInfraConfigsMutation, + EnableAndDisableSsoArgs, + InfraConfigArgs, +} from '~/helpers/backend/graphql'; + +// Types +export type SsoAuthProviders = 'google' | 'microsoft' | 'github'; + +export type Config = { + providers: { + google: { + name: SsoAuthProviders; + enabled: boolean; + fields: { + client_id: string; + client_secret: string; + }; + }; + github: { + name: SsoAuthProviders; + enabled: boolean; + fields: { + client_id: string; + client_secret: string; + }; + }; + microsoft: { + name: SsoAuthProviders; + enabled: boolean; + fields: { + client_id: string; + client_secret: string; + }; + }; + }; + + mailConfigs: { + name: string; + enabled: boolean; + fields: { + mailer_smtp_url: string; + mailer_from_address: string; + }; + }; +}; + +type UpdatedConfigs = { + name: string; + value: string; +}; + +/** Composable that handles all operations related to server configurations + * @param updatedConfigs A Config Object contatining the updated configs + */ +export function useConfigHandler(updatedConfigs?: Config) { + const t = useI18n(); + const toast = useToast(); + + // Fetching infra configurations + const { + fetching: fetchingInfraConfigs, + error: infraConfigsError, + list: infraConfigs, + fetchList: fetchInfraConfigs, + } = useClientHandler(InfraConfigsDocument, (x) => x.infraConfigs, { + configNames: [ + 'GOOGLE_CLIENT_ID', + 'GOOGLE_CLIENT_SECRET', + 'MICROSOFT_CLIENT_ID', + 'MICROSOFT_CLIENT_SECRET', + 'GITHUB_CLIENT_ID', + 'GITHUB_CLIENT_SECRET', + 'MAILER_SMTP_URL', + 'MAILER_ADDRESS_FROM', + ] as InfraConfigEnum[], + }); + + // Fetching allowed auth providers + const { + fetching: fetchingAllowedAuthProviders, + error: allowedAuthProvidersError, + list: allowedAuthProviders, + fetchList: fetchAllowedAuthProviders, + } = useClientHandler( + AllowedAuthProvidersDocument, + (x) => x.allowedAuthProviders, + {} + ); + + // Current and working configs + const currentConfigs = ref(); + const workingConfigs = ref(); + + onMounted(async () => { + await fetchInfraConfigs(); + await fetchAllowedAuthProviders(); + + // Transforming the fetched data into a Configs object + currentConfigs.value = { + providers: { + google: { + name: 'google', + enabled: allowedAuthProviders.value.includes('GOOGLE'), + fields: { + client_id: + infraConfigs.value.find((x) => x.name === 'GOOGLE_CLIENT_ID') + ?.value ?? '', + client_secret: + infraConfigs.value.find((x) => x.name === 'GOOGLE_CLIENT_SECRET') + ?.value ?? '', + }, + }, + github: { + name: 'github', + enabled: allowedAuthProviders.value.includes('GITHUB'), + fields: { + client_id: + infraConfigs.value.find((x) => x.name === 'GITHUB_CLIENT_ID') + ?.value ?? '', + client_secret: + infraConfigs.value.find((x) => x.name === 'GITHUB_CLIENT_SECRET') + ?.value ?? '', + }, + }, + microsoft: { + name: 'microsoft', + enabled: allowedAuthProviders.value.includes('MICROSOFT'), + fields: { + client_id: + infraConfigs.value.find((x) => x.name === 'MICROSOFT_CLIENT_ID') + ?.value ?? '', + client_secret: + infraConfigs.value.find( + (x) => x.name === 'MICROSOFT_CLIENT_SECRET' + )?.value ?? '', + }, + }, + }, + mailConfigs: { + name: 'email', + enabled: allowedAuthProviders.value.includes('EMAIL'), + fields: { + mailer_smtp_url: + infraConfigs.value.find((x) => x.name === 'MAILER_SMTP_URL') + ?.value ?? '', + mailer_from_address: + infraConfigs.value.find((x) => x.name === 'MAILER_ADDRESS_FROM') + ?.value ?? '', + }, + }, + }; + + // Cloning the current configs to working configs + // Changes are made only to working configs + workingConfigs.value = cloneDeep(currentConfigs.value); + }); + + // Trasforming the working configs back into the format required by the mutations + const updatedInfraConfigs = computed(() => { + 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 ?? '', + } + ); + } else { + config = config.filter( + (item) => + item.name !== 'GOOGLE_CLIENT_ID' && + item.name !== 'GOOGLE_CLIENT_SECRET' + ); + } + 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 ?? '', + } + ); + } else { + config = config.filter( + (item) => + item.name !== 'MICROSOFT_CLIENT_ID' && + item.name !== 'MICROSOFT_CLIENT_SECRET' + ); + } + + 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 ?? '', + } + ); + } else { + config = config.filter( + (item) => + item.name !== 'GITHUB_CLIENT_ID' && + item.name !== 'GITHUB_CLIENT_SECRET' + ); + } + + 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; + }); + + // Trasforming the working configs back into the format required by the mutations + const updatedAllowedAuthProviders = computed(() => { + return [ + { + provider: 'GOOGLE', + status: updatedConfigs?.providers.google.enabled ? 'ENABLE' : 'DISABLE', + }, + { + provider: 'MICROSOFT', + status: updatedConfigs?.providers.microsoft.enabled + ? 'ENABLE' + : 'DISABLE', + }, + { + provider: 'GITHUB', + status: updatedConfigs?.providers.github.enabled ? 'ENABLE' : 'DISABLE', + }, + { + provider: 'EMAIL', + status: updatedConfigs?.mailConfigs.enabled ? 'ENABLE' : 'DISABLE', + }, + ]; + }); + + // Updating the auth provider configurations + const updateAuthProvider = async ( + updateProviderStatus: UseMutationResponse + ) => { + const variables = { + providerInfo: + updatedAllowedAuthProviders.value as EnableAndDisableSsoArgs[], + }; + + const result = await updateProviderStatus.executeMutation(variables); + + if (result.error) { + toast.error(t('configs.auth_providers.update_failure')); + return false; + } + + return true; + }; + + // Updating the infra configurations + const updateInfraConfigs = async ( + updateInfraConfigsMutation: UseMutationResponse + ) => { + const variables = { + infraConfigs: updatedInfraConfigs.value as InfraConfigArgs[], + }; + + const result = await updateInfraConfigsMutation.executeMutation(variables); + + if (result.error) { + toast.error(t('configs.mail_configs.update_failure')); + return false; + } + + return true; + }; + + // Resetting the infra configurations + const resetInfraConfigs = async ( + resetInfraConfigsMutation: UseMutationResponse + ) => { + const result = await resetInfraConfigsMutation.executeMutation(); + + if (result.error) { + toast.error(t('configs.reset.failure')); + return false; + } + return true; + }; + + return { + currentConfigs, + workingConfigs, + updatedInfraConfigs, + updatedAllowedAuthProviders, + updateAuthProvider, + updateInfraConfigs, + resetInfraConfigs, + fetchingInfraConfigs, + fetchingAllowedAuthProviders, + infraConfigsError, + allowedAuthProvidersError, + }; +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/auth.ts b/packages/hoppscotch-sh-admin/src/helpers/auth.ts index f3641d127..64251a49b 100644 --- a/packages/hoppscotch-sh-admin/src/helpers/auth.ts +++ b/packages/hoppscotch-sh-admin/src/helpers/auth.ts @@ -227,4 +227,9 @@ export const auth = { window.location.href = import.meta.env.VITE_ADMIN_URL; } }, + + getAllowedAuthProviders: async () => { + const res = await authQuery.getProviders(); + return res.data?.providers; + }, }; diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/EnableAndDisableSso.graphql b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/EnableAndDisableSso.graphql new file mode 100644 index 000000000..5a494cad1 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/EnableAndDisableSso.graphql @@ -0,0 +1,3 @@ +mutation EnableAndDisableSSO($providerInfo: [EnableAndDisableSSOArgs!]!) { + enableAndDisableSSO(providerInfo: $providerInfo) +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/ResetInfraConfigs.graphql b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/ResetInfraConfigs.graphql new file mode 100644 index 000000000..6ab752096 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/ResetInfraConfigs.graphql @@ -0,0 +1,3 @@ +mutation ResetInfraConfigs { + resetInfraConfigs +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/UpdateInfraConfigs.graphql b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/UpdateInfraConfigs.graphql new file mode 100644 index 000000000..14217ccb6 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/UpdateInfraConfigs.graphql @@ -0,0 +1,6 @@ +mutation UpdateInfraConfigs($infraConfigs: [InfraConfigArgs!]!) { + updateInfraConfigs(infraConfigs: $infraConfigs) { + name + value + } +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/gql/queries/AllowedAuthProviders.graphql b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/queries/AllowedAuthProviders.graphql new file mode 100644 index 000000000..05a56b32b --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/queries/AllowedAuthProviders.graphql @@ -0,0 +1,3 @@ +query AllowedAuthProviders { + allowedAuthProviders +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/gql/queries/InfraConfigs.graphql b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/queries/InfraConfigs.graphql new file mode 100644 index 000000000..f875fea8a --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/queries/InfraConfigs.graphql @@ -0,0 +1,6 @@ +query InfraConfigs($configNames: [InfraConfigEnum!]!) { + infraConfigs(configNames: $configNames) { + name + value + } +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/rest/authQuery.ts b/packages/hoppscotch-sh-admin/src/helpers/backend/rest/authQuery.ts index 176d9eaf2..d6fc35a94 100644 --- a/packages/hoppscotch-sh-admin/src/helpers/backend/rest/authQuery.ts +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/rest/authQuery.ts @@ -16,6 +16,7 @@ export default { }), refreshToken: () => restApi.get('/auth/refresh'), elevateUser: () => restApi.get('/auth/verify/admin'), + getProviders: () => restApi.get('/auth/providers'), sendMagicLink: (email: string) => restApi.post('/auth/signin?origin=admin', { email, diff --git a/packages/hoppscotch-sh-admin/src/pages/settings.vue b/packages/hoppscotch-sh-admin/src/pages/settings.vue index 0ff02ae4e..957a3b473 100644 --- a/packages/hoppscotch-sh-admin/src/pages/settings.vue +++ b/packages/hoppscotch-sh-admin/src/pages/settings.vue @@ -1,3 +1,81 @@ + + diff --git a/packages/hoppscotch-ui/src/components/smart/ConfirmModal.vue b/packages/hoppscotch-ui/src/components/smart/ConfirmModal.vue index 57d4c23a4..7dadf7426 100644 --- a/packages/hoppscotch-ui/src/components/smart/ConfirmModal.vue +++ b/packages/hoppscotch-ui/src/components/smart/ConfirmModal.vue @@ -1,16 +1,32 @@