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 @@
+
+
+
+
{{ t('configs.auth_providers.title') }}
+
+ {{ t('configs.auth_providers.description') }}
+
+
+
+
+
+
+ {{ t('configs.auth_providers.title') }}
+
+
+
+
+
+ {{ capitalize(provider.name) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
{{ t('configs.reset.title') }}
+
+ {{ t('configs.reset.description') }}
+
+
+
+
+
+ {{ t('configs.reset.info') }}
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+ {{ t('configs.restart.description', { duration }) }}
+
+
+
+
+
+
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 @@
+
+
+
+
{{ t('configs.mail_configs.title') }}
+
+ {{ t('configs.mail_configs.description') }}
+
+
+
+
+
+
+ {{ t('configs.mail_configs.title') }}
+
+
+
+
+
+ {{ t('configs.mail_configs.enable') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
- Settings
+
+
+ {{ t('settings.settings') }}
+
+
+
+
+
+
+
+
+ {{ t('configs.load_error') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
-
+
-
+
{{ title }}
-
-
+
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 71dfebd94..cc0dde3d4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1350,6 +1350,9 @@ importers:
'@import-meta-env/unplugin':
specifier: ^0.4.8
version: 0.4.8(@import-meta-env/cli@0.6.3)(dotenv@16.3.1)
+ '@types/lodash-es':
+ specifier: ^4.17.12
+ version: 4.17.12
'@vitejs/plugin-vue':
specifier: ^3.1.0
version: 3.2.0(vite@3.2.4)(vue@3.3.9)