mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 03:31:27 +00:00
feat: allowed toggling login options as admin
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Switch } from "@app/components/v2";
|
||||
import { useServerConfig } from "@app/context";
|
||||
import { useUpdateServerConfig } from "@app/hooks/api";
|
||||
import { LoginMethod } from "@app/hooks/api/admin/types";
|
||||
|
||||
const formSchema = z.object({
|
||||
isEmailEnabled: z.boolean(),
|
||||
isGoogleEnabled: z.boolean(),
|
||||
isGithubEnabled: z.boolean(),
|
||||
isGitlabEnabled: z.boolean(),
|
||||
isSamlEnabled: z.boolean(),
|
||||
isLdapEnabled: z.boolean(),
|
||||
isOidcEnabled: z.boolean()
|
||||
});
|
||||
|
||||
type TAuthForm = z.infer<typeof formSchema>;
|
||||
|
||||
export const AuthPanel = () => {
|
||||
const { config } = useServerConfig();
|
||||
const { enabledLoginMethods } = config;
|
||||
const { mutateAsync: updateServerConfig } = useUpdateServerConfig();
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting, isDirty }
|
||||
} = useForm<TAuthForm>({
|
||||
resolver: zodResolver(formSchema),
|
||||
values: enabledLoginMethods
|
||||
? {
|
||||
isEmailEnabled: enabledLoginMethods.includes(LoginMethod.EMAIL),
|
||||
isGoogleEnabled: enabledLoginMethods.includes(LoginMethod.GOOGLE),
|
||||
isGithubEnabled: enabledLoginMethods.includes(LoginMethod.GITHUB),
|
||||
isGitlabEnabled: enabledLoginMethods.includes(LoginMethod.GITLAB),
|
||||
isSamlEnabled: enabledLoginMethods.includes(LoginMethod.SAML),
|
||||
isLdapEnabled: enabledLoginMethods.includes(LoginMethod.LDAP),
|
||||
isOidcEnabled: enabledLoginMethods.includes(LoginMethod.OIDC)
|
||||
}
|
||||
: {
|
||||
isEmailEnabled: true,
|
||||
isGoogleEnabled: true,
|
||||
isGithubEnabled: true,
|
||||
isGitlabEnabled: true,
|
||||
isSamlEnabled: true,
|
||||
isLdapEnabled: true,
|
||||
isOidcEnabled: true
|
||||
}
|
||||
});
|
||||
|
||||
const onAuthFormSubmit = async (formData: TAuthForm) => {
|
||||
try {
|
||||
const enabledMethods: LoginMethod[] = [];
|
||||
if (formData.isEmailEnabled) {
|
||||
enabledMethods.push(LoginMethod.EMAIL);
|
||||
}
|
||||
|
||||
if (formData.isGoogleEnabled) {
|
||||
enabledMethods.push(LoginMethod.GOOGLE);
|
||||
}
|
||||
|
||||
if (formData.isGithubEnabled) {
|
||||
enabledMethods.push(LoginMethod.GITHUB);
|
||||
}
|
||||
|
||||
if (formData.isGitlabEnabled) {
|
||||
enabledMethods.push(LoginMethod.GITLAB);
|
||||
}
|
||||
|
||||
if (formData.isSamlEnabled) {
|
||||
enabledMethods.push(LoginMethod.SAML);
|
||||
}
|
||||
|
||||
if (formData.isLdapEnabled) {
|
||||
enabledMethods.push(LoginMethod.LDAP);
|
||||
}
|
||||
|
||||
if (formData.isOidcEnabled) {
|
||||
enabledMethods.push(LoginMethod.OIDC);
|
||||
}
|
||||
|
||||
if (!enabledMethods.length) {
|
||||
createNotification({
|
||||
type: "error",
|
||||
text: "At least one login method should be enabled."
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await updateServerConfig({
|
||||
enabledLoginMethods: enabledMethods
|
||||
});
|
||||
|
||||
createNotification({
|
||||
text: "Login methods have been successfully updated.",
|
||||
type: "success"
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
createNotification({
|
||||
type: "error",
|
||||
text: "Failed to update login methods."
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4"
|
||||
onSubmit={handleSubmit(onAuthFormSubmit)}
|
||||
>
|
||||
<div className="flex flex-col justify-start">
|
||||
<div className="mb-2 text-xl font-semibold text-mineshaft-100">Login Methods</div>
|
||||
<div className="mb-4 max-w-sm text-sm text-mineshaft-400">
|
||||
Select the login methods available to users
|
||||
</div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isEmailEnabled"
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
id="email-enabled"
|
||||
onCheckedChange={(value) => field.onChange(value)}
|
||||
isChecked={field.value}
|
||||
>
|
||||
<p className="w-24">Email</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isGoogleEnabled"
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
id="google-enabled"
|
||||
onCheckedChange={(value) => field.onChange(value)}
|
||||
isChecked={field.value}
|
||||
>
|
||||
<p className="w-24">Google SSO</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isGithubEnabled"
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
id="enable-github"
|
||||
onCheckedChange={(value) => field.onChange(value)}
|
||||
isChecked={field.value}
|
||||
>
|
||||
<p className="w-24">Github SSO</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isGitlabEnabled"
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
id="enable-gitlab"
|
||||
onCheckedChange={(value) => field.onChange(value)}
|
||||
isChecked={field.value}
|
||||
>
|
||||
<p className="w-24">Gitlab SSO</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isSamlEnabled"
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
id="enable-saml"
|
||||
onCheckedChange={(value) => field.onChange(value)}
|
||||
isChecked={field.value}
|
||||
>
|
||||
<p className="w-24">SAML SSO</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isOidcEnabled"
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
id="enable-oidc"
|
||||
onCheckedChange={(value) => field.onChange(value)}
|
||||
isChecked={field.value}
|
||||
>
|
||||
<p className="w-24">OIDC SSO</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="isLdapEnabled"
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
id="enable-ldap"
|
||||
onCheckedChange={(value) => field.onChange(value)}
|
||||
isChecked={field.value}
|
||||
>
|
||||
<p className="w-24">LDAP</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
className="mt-2"
|
||||
type="submit"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting || !isDirty}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -24,10 +24,12 @@ import {
|
||||
import { useOrganization, useServerConfig, useUser } from "@app/context";
|
||||
import { useGetOrganizations, useUpdateServerConfig } from "@app/hooks/api";
|
||||
|
||||
import { AuthPanel } from "./AuthPanel";
|
||||
import { RateLimitPanel } from "./RateLimitPanel";
|
||||
|
||||
enum TabSections {
|
||||
Settings = "settings",
|
||||
Auth = "auth",
|
||||
RateLimit = "rate-limit"
|
||||
}
|
||||
|
||||
@@ -131,6 +133,7 @@ export const AdminDashboardPage = () => {
|
||||
<TabList>
|
||||
<div className="flex w-full flex-row border-b border-mineshaft-600">
|
||||
<Tab value={TabSections.Settings}>General</Tab>
|
||||
<Tab value={TabSections.Auth}>Auth</Tab>
|
||||
<Tab value={TabSections.RateLimit}>Rate Limit</Tab>
|
||||
</div>
|
||||
</TabList>
|
||||
@@ -203,7 +206,8 @@ export const AdminDashboardPage = () => {
|
||||
Default organization
|
||||
</div>
|
||||
<div className="mb-4 max-w-sm text-sm text-mineshaft-400">
|
||||
Select the default organization you want to set for SAML/LDAP based logins. When selected, user logins will be automatically scoped to the selected organization.
|
||||
Select the default organization you want to set for SAML/LDAP based logins. When
|
||||
selected, user logins will be automatically scoped to the selected organization.
|
||||
</div>
|
||||
<Controller
|
||||
control={control}
|
||||
@@ -310,6 +314,9 @@ export const AdminDashboardPage = () => {
|
||||
</Button>
|
||||
</form>
|
||||
</TabPanel>
|
||||
<TabPanel value={TabSections.Auth}>
|
||||
<AuthPanel />
|
||||
</TabPanel>
|
||||
<TabPanel value={TabSections.RateLimit}>
|
||||
<RateLimitPanel />
|
||||
</TabPanel>
|
||||
|
||||
Reference in New Issue
Block a user