ChangeUnlockPassword.tsx raw
1 import { TriangleAlertIcon } from "lucide-react";
2 import React from "react";
3 import PasswordInput from "src/components/password/PasswordInput";
4
5 import { toast } from "sonner";
6 import SettingsHeader from "src/components/SettingsHeader";
7 import { Alert, AlertDescription, AlertTitle } from "src/components/ui/alert";
8 import { LoadingButton } from "src/components/ui/custom/loading-button";
9 import { Label } from "src/components/ui/label";
10
11 import { useInfo } from "src/hooks/useInfo";
12 import { request } from "src/utils/request";
13
14 export function ChangeUnlockPassword() {
15 const { mutate: refetchInfo } = useInfo();
16
17 const [currentUnlockPassword, setCurrentUnlockPassword] = React.useState("");
18 const [newUnlockPassword, setNewUnlockPassword] = React.useState("");
19 const [confirmNewUnlockPassword, setConfirmNewUnlockPassword] =
20 React.useState("");
21
22 const [loading, setLoading] = React.useState(false);
23
24 const onSubmit = async (e: React.FormEvent) => {
25 e.preventDefault();
26
27 try {
28 if (newUnlockPassword !== confirmNewUnlockPassword) {
29 throw new Error("Password confirmation does not match");
30 }
31 setLoading(true);
32 await request("/api/unlock-password", {
33 method: "PATCH",
34 headers: {
35 "Content-Type": "application/json",
36 },
37 body: JSON.stringify({
38 currentUnlockPassword,
39 newUnlockPassword,
40 }),
41 });
42 await refetchInfo();
43 toast("Successfully changed password", {
44 description: "Please start your node with your new password",
45 });
46 } catch (error) {
47 toast.error("Password change failed", {
48 description: (error as Error).message,
49 });
50 } finally {
51 setLoading(false);
52 }
53 };
54
55 return (
56 <>
57 <SettingsHeader
58 pageTitle="Unlock Password"
59 title="Unlock Password"
60 description="Change unlock password to your Hub. Your node will restart after password change."
61 />
62 <div>
63 <Alert variant="destructive" className="w-full md:max-w-6xl mb-8">
64 <TriangleAlertIcon />
65 <AlertTitle>Important!</AlertTitle>
66 <AlertDescription>
67 Password can't be reset or recovered. Make sure to back it up!
68 </AlertDescription>
69 </Alert>
70 <form
71 onSubmit={onSubmit}
72 className="w-full md:w-96 flex flex-col gap-6"
73 >
74 <div className="grid gap-1.5">
75 <Label htmlFor="current-password">Current Password</Label>
76 <PasswordInput
77 id="current-password"
78 autoFocus
79 onChange={setCurrentUnlockPassword}
80 value={currentUnlockPassword}
81 />
82 </div>
83 <div className="grid gap-1.5">
84 <Label htmlFor="new-password">New Password</Label>
85 <PasswordInput
86 id="new-password"
87 onChange={setNewUnlockPassword}
88 value={newUnlockPassword}
89 />
90 </div>
91 <div className="grid gap-1.5">
92 <Label htmlFor="confirm-new-password">Confirm New Password</Label>
93 <PasswordInput
94 id="confirm-new-password"
95 onChange={setConfirmNewUnlockPassword}
96 value={confirmNewUnlockPassword}
97 />
98 </div>
99 <div className="flex justify-start">
100 <LoadingButton
101 loading={loading}
102 disabled={
103 !(
104 currentUnlockPassword &&
105 newUnlockPassword &&
106 confirmNewUnlockPassword
107 )
108 }
109 >
110 Change Password
111 </LoadingButton>
112 </div>
113 </form>
114 </div>
115 </>
116 );
117 }
118