99import PasswordField from 'renderer/components/PasswordField' ;
1010import { useCallback , useRef , useState } from 'react' ;
1111import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
12- import { faCheckCircle } from '@fortawesome/free-solid-svg-icons' ;
12+ import { faCheckCircle , faSpinner } from '@fortawesome/free-solid-svg-icons' ;
1313import LinkButton from 'renderer/components/Button/LinkButton' ;
14+ import ButtonGroup from 'renderer/components/ButtonGroup' ;
1415
1516function SetupAccountNotLogin ( ) {
1617 return (
@@ -93,23 +94,25 @@ function SetupAccountNewMasterKey({ user }: { user: LoginUser }) {
9394
9495 < SetupMasterPasswordInstruction />
9596
96- < PasswordField
97- autoFocus
98- placeholder = "Master password"
99- value = { password }
100- onChange = { setPassword }
101- />
102- < p > </ p >
103- < PasswordField
104- autoFocus
105- placeholder = "Confirm master password"
106- value = { confirmed }
107- onChange = { setConfirmed }
108- />
109- < p > </ p >
110- < Button primary onClick = { onSetupPassword } >
111- Setup Master Password
112- </ Button >
97+ < Stack vertical spacing = "sm" >
98+ < PasswordField
99+ autoFocus
100+ placeholder = "Master password"
101+ value = { password }
102+ onChange = { setPassword }
103+ />
104+
105+ < PasswordField
106+ autoFocus
107+ placeholder = "Confirm master password"
108+ value = { confirmed }
109+ onChange = { setConfirmed }
110+ />
111+
112+ < Button primary onClick = { onSetupPassword } >
113+ Setup Master Password
114+ </ Button >
115+ </ Stack >
113116 </ div >
114117 ) ;
115118}
@@ -153,6 +156,11 @@ function SetupAccountExistingMasterKey({ user }: { user: LoginUser }) {
153156 placeholder = "Master password"
154157 value = { password }
155158 onChange = { setPassword }
159+ onKeyDown = { ( e ) => {
160+ if ( e . key === 'Enter' ) {
161+ onCheckMasterPassword ( ) ;
162+ }
163+ } }
156164 />
157165 < p > </ p >
158166 < Button primary onClick = { onCheckMasterPassword } >
@@ -162,7 +170,108 @@ function SetupAccountExistingMasterKey({ user }: { user: LoginUser }) {
162170 ) ;
163171}
164172
173+ function SetupAccountChangePassword ( { onClose } : { onClose : ( ) => void } ) {
174+ const { api, setMasterPassword : setPersistentPassword } = useAuth ( ) ;
175+ const { refetch } = useCurrentUser ( ) ;
176+ const [ oldMasterPassword , setOldMasterPassword ] = useState ( '' ) ;
177+ const [ confirmMasterPassword , setConfirmMasterPassword ] = useState ( '' ) ;
178+ const [ masterPassword , setMasterPassword ] = useState ( '' ) ;
179+ const [ loading , setLoading ] = useState ( false ) ;
180+ const [ error , setError ] = useState ( '' ) ;
181+
182+ const onChangePassword = useCallback ( ( ) => {
183+ if ( ! masterPassword ) {
184+ setError ( 'Please enter valid master password.' ) ;
185+ return ;
186+ }
187+
188+ if ( confirmMasterPassword !== masterPassword ) {
189+ setError ( 'The password is not matched' ) ;
190+ return ;
191+ }
192+
193+ setLoading ( true ) ;
194+ api
195+ . updateMasterPassword ( masterPassword , oldMasterPassword )
196+ . then ( ( resp ) => {
197+ if ( resp . status ) {
198+ setPersistentPassword ( masterPassword ) ;
199+ refetch ( ) ;
200+ onClose ( ) ;
201+ } else {
202+ setError ( resp . error ?. message ?? '' ) ;
203+ }
204+ setLoading ( false ) ;
205+ } )
206+ . catch ( ( ) => setLoading ( false ) ) ;
207+ } , [
208+ setPersistentPassword ,
209+ oldMasterPassword ,
210+ confirmMasterPassword ,
211+ onClose ,
212+ setLoading ,
213+ refetch ,
214+ ] ) ;
215+
216+ return (
217+ < div >
218+ { error && (
219+ < p style = { { color : 'var(--color-critical)' } } >
220+ < strong > Error</ strong > : { error }
221+ </ p >
222+ ) }
223+
224+ { loading && (
225+ < p >
226+ < FontAwesomeIcon icon = { faSpinner } spin />
227+ < span > Changing password...</ span >
228+ </ p >
229+ ) }
230+
231+ < Stack vertical spacing = "sm" >
232+ < PasswordField
233+ autoFocus
234+ placeholder = "Old master password"
235+ value = { oldMasterPassword }
236+ onChange = { setOldMasterPassword }
237+ />
238+
239+ < PasswordField
240+ placeholder = "New Master password"
241+ value = { masterPassword }
242+ onChange = { setMasterPassword }
243+ />
244+
245+ < PasswordField
246+ placeholder = "Confirm master password"
247+ value = { confirmMasterPassword }
248+ onChange = { setConfirmMasterPassword }
249+ />
250+
251+ < ButtonGroup >
252+ < Button primary onClick = { onChangePassword } disabled = { loading } >
253+ Change Password
254+ </ Button >
255+ < Button onClick = { onClose } > Cancel</ Button >
256+ </ ButtonGroup >
257+ </ Stack >
258+ </ div >
259+ ) ;
260+ }
261+
165262function SetupAccountComplete ( { user } : { user : LoginUser } ) {
263+ const [ showChangePassword , setShowChangePassword ] = useState ( false ) ;
264+
265+ if ( showChangePassword ) {
266+ return (
267+ < SetupAccountChangePassword
268+ onClose = { ( ) => {
269+ setShowChangePassword ( false ) ;
270+ } }
271+ />
272+ ) ;
273+ }
274+
166275 return (
167276 < Stack >
168277 < div >
@@ -175,6 +284,15 @@ function SetupAccountComplete({ user }: { user: LoginUser }) {
175284 < div >
176285 < h2 style = { { marginBottom : '0.5rem' } } > Welcome, { user . name } </ h2 >
177286 < p > Your account is secured with your master password.</ p >
287+
288+ < ul >
289+ < li >
290+ < LinkButton
291+ text = "Change new master password"
292+ onClick = { ( ) => setShowChangePassword ( true ) }
293+ />
294+ </ li >
295+ </ ul >
178296 </ div >
179297 </ Stack >
180298 ) ;
0 commit comments