mirror of
https://github.com/Infisical/infisical.git
synced 2025-04-17 19:37:38 +00:00
added the ability to change user name
This commit is contained in:
@ -3,10 +3,10 @@ import { Types } from "mongoose";
|
||||
import crypto from "crypto";
|
||||
import bcrypt from "bcrypt";
|
||||
import {
|
||||
MembershipOrg,
|
||||
User,
|
||||
APIKeyData,
|
||||
TokenVersion
|
||||
MembershipOrg,
|
||||
TokenVersion,
|
||||
User
|
||||
} from "../../models";
|
||||
import { getSaltRounds } from "../../config";
|
||||
|
||||
@ -80,6 +80,26 @@ export const updateMyMfaEnabled = async (req: Request, res: Response) => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current user's name [firstName, lastName].
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const updateName = async (req: Request, res: Response) => {
|
||||
const { firstName, lastName }: { firstName: string; lastName: string; } = req.body;
|
||||
req.user.firstName = firstName;
|
||||
req.user.lastName = lastName || "";
|
||||
|
||||
await req.user.save();
|
||||
|
||||
const user = req.user;
|
||||
|
||||
return res.status(200).send({
|
||||
user,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return organizations that the current user is part of.
|
||||
* @param req
|
||||
|
@ -29,6 +29,16 @@ router.patch(
|
||||
usersController.updateMyMfaEnabled
|
||||
);
|
||||
|
||||
router.patch(
|
||||
"/me/name",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
}),
|
||||
body("firstName").exists(),
|
||||
validateRequest,
|
||||
usersController.updateName
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/me/organizations",
|
||||
requireAuth({
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
CreateAPIKeyRes,
|
||||
DeletOrgMembershipDTO,
|
||||
OrgUser,
|
||||
RenameUserDTO,
|
||||
TokenVersion,
|
||||
UpdateOrgUserRoleDTO,
|
||||
User} from "./types";
|
||||
@ -45,6 +46,18 @@ const fetchUserAction = async (action: string) => {
|
||||
return data.userAction;
|
||||
};
|
||||
|
||||
export const useRenameUser = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{}, {}, RenameUserDTO>({
|
||||
mutationFn: ({ newName }) =>
|
||||
apiRequest.patch("/api/v2/users/me/name", { firstName: newName?.split(" ")[0], lastName: newName?.split(" ").slice(1).join(" ") }),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(userKeys.getUser);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetUserAction = (action: string) =>
|
||||
useQuery({
|
||||
queryKey: userKeys.userAction,
|
||||
|
@ -67,6 +67,10 @@ export type CreateAPIKeyRes = {
|
||||
apiKeyData: APIKeyData;
|
||||
}
|
||||
|
||||
export type RenameUserDTO = {
|
||||
newName: string;
|
||||
};
|
||||
|
||||
export type APIKeyData = {
|
||||
_id: string;
|
||||
name: string;
|
||||
|
@ -15,7 +15,7 @@ export const ChangeLanguageSection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4 bg-mineshaft-900 mb-6 max-w-screen-lg rounded-lg border border-mineshaft-600">
|
||||
<div className="p-4 bg-mineshaft-900 mb-6 rounded-lg border border-mineshaft-600">
|
||||
<p className="text-xl font-semibold text-mineshaft-100 mb-8">
|
||||
{t("settings.personal.change-language")}
|
||||
</p>
|
||||
|
@ -3,10 +3,12 @@ import { ChangePasswordSection } from "../ChangePasswordSection";
|
||||
import { EmergencyKitSection } from "../EmergencyKitSection";
|
||||
import { SecuritySection } from "../SecuritySection";
|
||||
import { SessionsSection } from "../SessionsSection";
|
||||
import { UserNameSection } from "../UserNameSection";
|
||||
|
||||
export const PersonalSecurityTab = () => {
|
||||
return (
|
||||
<div>
|
||||
<UserNameSection />
|
||||
<ChangeLanguageSection />
|
||||
<SecuritySection />
|
||||
<SessionsSection />
|
||||
|
@ -12,7 +12,7 @@ const tabs = [
|
||||
export const PersonalTabGroup = () => {
|
||||
return (
|
||||
<Tab.Group>
|
||||
<Tab.List className="mb-6 border-b-2 border-mineshaft-800 w-full">
|
||||
<Tab.List className="mb-4 border-b-2 border-mineshaft-800 w-full">
|
||||
{tabs.map((tab) => (
|
||||
<Tab as={Fragment} key={tab.key}>
|
||||
{({ selected }) => (
|
||||
|
@ -0,0 +1,82 @@
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import * as yup from "yup";
|
||||
|
||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||
import { Button, FormControl, Input } from "@app/components/v2";
|
||||
import { useUser } from "@app/context";
|
||||
import { useRenameUser } from "@app/hooks/api/users/queries";
|
||||
|
||||
const formSchema = yup.object({
|
||||
name: yup.string().required().label("User Name"),
|
||||
});
|
||||
|
||||
type FormData = yup.InferType<typeof formSchema>;
|
||||
|
||||
export const UserNameSection = (): JSX.Element => {
|
||||
const { user } = useUser();
|
||||
const { createNotification } = useNotificationContext();
|
||||
const {
|
||||
handleSubmit,
|
||||
control,
|
||||
reset
|
||||
} = useForm<FormData>({ resolver: yupResolver(formSchema) });
|
||||
const { mutateAsync, isLoading } = useRenameUser();
|
||||
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
reset({ name: `${user?.firstName}${user?.lastName && " "}${user?.lastName}` });
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
const onFormSubmit = async ({ name }: FormData) => {
|
||||
try {
|
||||
if (!user?._id) return;
|
||||
if (name === "") return;
|
||||
|
||||
await mutateAsync({ newName: name});
|
||||
createNotification({
|
||||
text: "Successfully renamed user",
|
||||
type: "success"
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
createNotification({
|
||||
text: "Failed to rename user",
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={handleSubmit(onFormSubmit)}
|
||||
className="p-4 bg-mineshaft-900 mb-6 rounded-lg border border-mineshaft-600"
|
||||
>
|
||||
<p className="text-xl font-semibold text-mineshaft-100 mb-4">
|
||||
User name
|
||||
</p>
|
||||
<div className="mb-2 max-w-md">
|
||||
<Controller
|
||||
defaultValue=""
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Input placeholder={`${user?.firstName} ${user?.lastName}`} {...field} />
|
||||
</FormControl>
|
||||
)}
|
||||
control={control}
|
||||
name="name"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
isLoading={isLoading}
|
||||
colorSchema="primary"
|
||||
variant="outline_bg"
|
||||
type="submit"
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export { UserNameSection } from "./UserNameSection";
|
@ -26,15 +26,13 @@ export const ProjectSettingsPage = () => {
|
||||
<p className="text-3xl font-semibold text-gray-200">{t("settings.project.title")}</p>
|
||||
</div>
|
||||
<Tab.Group>
|
||||
<Tab.List className="mb-6 w-full border-b-2 border-mineshaft-800">
|
||||
<Tab.List className="mb-4 w-full border-b-2 border-mineshaft-800">
|
||||
{tabs.map((tab) => (
|
||||
<Tab as={Fragment} key={tab.key}>
|
||||
{({ selected }) => (
|
||||
<button
|
||||
type="button"
|
||||
className={`w-30 p-4 font-semibold outline-none ${
|
||||
selected ? "border-b-2 border-white text-white" : "text-mineshaft-400"
|
||||
}`}
|
||||
className={`w-30 py-2 mx-2 mr-4 font-medium text-sm outline-none ${selected ? "border-b border-white text-white" : "text-mineshaft-400"}`}
|
||||
>
|
||||
{tab.name}
|
||||
</button>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import * as yup from "yup";
|
||||
|
||||
@ -27,7 +26,6 @@ export const ProjectNameChangeSection = () => {
|
||||
control,
|
||||
reset
|
||||
} = useForm<FormData>({ resolver: yupResolver(formSchema) });
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (currentWorkspace) {
|
||||
@ -67,7 +65,7 @@ export const ProjectNameChangeSection = () => {
|
||||
className="p-4 bg-mineshaft-900 mb-6 rounded-lg border border-mineshaft-600"
|
||||
>
|
||||
<h2 className="text-xl font-semibold flex-1 text-mineshaft-100 mb-8">
|
||||
{t("common.display-name")}
|
||||
Project Name
|
||||
</h2>
|
||||
<div className="max-w-md">
|
||||
<Controller
|
||||
|
Reference in New Issue
Block a user