forked from baron/baron-sso
fix: Admin UI 커스텀 필드 로그인 ID 반영 문제 및 비밀번호 초기화 동작 개선 (#440)
- 사용자 정보 수정(UpdateUser) 시 메타데이터(커스텀 필드)를 명시적 loginId 값보다 우선하여 동기화하도록 로직 순서 변경 - Admin UI 사용자 상세의 비밀번호 초기화 기능이 즉시 폼에 덮어씌워지는 문제 해결을 위해, 별도의 확인 절차 후 즉각 독립적인 API 호출을 통해 재설정되도록 개선
This commit is contained in:
@@ -148,7 +148,8 @@ function UserDetailPage() {
|
||||
const queryClient = useQueryClient();
|
||||
const [error, setError] = React.useState<string | null>(null);
|
||||
const [successMsg, setSuccessMsg] = React.useState<string | null>(null);
|
||||
const [showPassword, setShowPassword] = React.useState(false);
|
||||
const [isPasswordResetOpen, setIsPasswordResetOpen] = React.useState(false);
|
||||
const [generatedPassword, setGeneratedPassword] = React.useState<string | null>(null);
|
||||
|
||||
const { data: profile } = useQuery({
|
||||
queryKey: ["me"],
|
||||
@@ -189,7 +190,6 @@ function UserDetailPage() {
|
||||
department: "",
|
||||
position: "",
|
||||
jobTitle: "",
|
||||
password: "",
|
||||
metadata: {},
|
||||
},
|
||||
});
|
||||
@@ -197,22 +197,38 @@ function UserDetailPage() {
|
||||
const isAdmin =
|
||||
profile?.role === "super_admin" || profile?.role === "tenant_admin";
|
||||
|
||||
const resetPasswordMutation = useMutation({
|
||||
mutationFn: (newPass: string) => updateUser(userId, { password: newPass }),
|
||||
onSuccess: (_, newPass) => {
|
||||
setGeneratedPassword(newPass);
|
||||
toast.success(
|
||||
t(
|
||||
"msg.admin.users.detail.password_generated",
|
||||
"사용자 비밀번호가 성공적으로 재설정되었습니다.",
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (err: AxiosError<{ error?: string }>) => {
|
||||
toast.error(
|
||||
err.response?.data?.error ||
|
||||
t("msg.admin.users.detail.update_error", "수정에 실패했습니다."),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const handleGeneratePassword = () => {
|
||||
setIsPasswordResetOpen(true);
|
||||
setGeneratedPassword(null);
|
||||
};
|
||||
|
||||
const confirmGeneratePassword = () => {
|
||||
const newPass = generateSecurePassword();
|
||||
setValue("password", newPass);
|
||||
setShowPassword(true);
|
||||
toast.success(
|
||||
t(
|
||||
"msg.admin.users.detail.password_generated",
|
||||
"안전한 비밀번호가 생성되었습니다.",
|
||||
),
|
||||
);
|
||||
resetPasswordMutation.mutate(newPass);
|
||||
};
|
||||
|
||||
const handleCopyPassword = () => {
|
||||
const pass = watch("password");
|
||||
if (pass) {
|
||||
navigator.clipboard.writeText(pass);
|
||||
if (generatedPassword) {
|
||||
navigator.clipboard.writeText(generatedPassword);
|
||||
toast.success(
|
||||
t("msg.common.copied_to_clipboard", "클립보드에 복사되었습니다."),
|
||||
);
|
||||
@@ -670,14 +686,34 @@ function UserDetailPage() {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{showPassword && (
|
||||
{isPasswordResetOpen && !generatedPassword && (
|
||||
<div className="p-4 border rounded-lg bg-destructive/5 space-y-4">
|
||||
<p className="text-sm">
|
||||
{t(
|
||||
"msg.admin.users.detail.reset_password_confirm",
|
||||
"정말로 이 사용자의 비밀번호를 초기화하시겠습니까? 기존 비밀번호로는 즉시 로그인할 수 없게 됩니다.",
|
||||
)}
|
||||
</p>
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button variant="ghost" size="sm" onClick={() => setIsPasswordResetOpen(false)}>
|
||||
{t("ui.common.cancel", "취소")}
|
||||
</Button>
|
||||
<Button variant="destructive" size="sm" onClick={confirmGeneratePassword} disabled={resetPasswordMutation.isPending}>
|
||||
{resetPasswordMutation.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
{t("ui.admin.users.detail.reset_password", "초기화 및 생성")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{generatedPassword && (
|
||||
<div className="p-4 border border-dashed rounded-lg bg-yellow-500/5 flex flex-wrap items-center justify-between gap-4">
|
||||
<div className="space-y-1">
|
||||
<p className="text-xs font-bold text-yellow-600 uppercase tracking-wider">
|
||||
Generated Password
|
||||
</p>
|
||||
<p className="font-mono text-lg font-bold">
|
||||
{watch("password")}
|
||||
{generatedPassword}
|
||||
</p>
|
||||
</div>
|
||||
<Button size="sm" variant="secondary" onClick={handleCopyPassword}>
|
||||
|
||||
Reference in New Issue
Block a user