From ba745ed2c9908f2b3879a41f36d060e37e5b2d79 Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Fri, 15 Nov 2024 16:42:01 +0100 Subject: [PATCH] fix(ui): show password reset error message --- .../Client/ProfileSettings/ChangePassword.tsx | 25 ++++----- frontend/app/mstore/userStore.ts | 51 +++++++++-------- frontend/app/services/UserService.ts | 56 +++++++++++-------- 3 files changed, 72 insertions(+), 60 deletions(-) diff --git a/frontend/app/components/Client/ProfileSettings/ChangePassword.tsx b/frontend/app/components/Client/ProfileSettings/ChangePassword.tsx index 3b997a431..ce3eaeb38 100644 --- a/frontend/app/components/Client/ProfileSettings/ChangePassword.tsx +++ b/frontend/app/components/Client/ProfileSettings/ChangePassword.tsx @@ -1,13 +1,12 @@ import React, { useState, useCallback } from 'react'; import { Button, Message, Form, Input } from 'UI'; import styles from './profileSettings.module.css'; -import { toast } from 'react-toastify'; import { validatePassword } from 'App/validate'; import { PASSWORD_POLICY } from 'App/constants'; import { useStore } from 'App/mstore'; import { observer } from 'mobx-react-lite'; -const ERROR_DOESNT_MATCH = "Passwords don't match"; +const ERROR_DOESNT_MATCH = 'Passwords don\'t match'; const MIN_LENGTH = 8; const ChangePassword = () => { @@ -18,11 +17,11 @@ const ChangePassword = () => { const [oldPassword, setOldPassword] = useState(''); const [newPassword, setNewPassword] = useState<{ value: string; error: boolean }>({ value: '', - error: false, + error: false }); const [newPasswordRepeat, setNewPasswordRepeat] = useState<{ value: string; error: boolean }>({ value: '', - error: false, + error: false }); const [show, setShow] = useState(false); @@ -53,16 +52,14 @@ const ChangePassword = () => { updatePassword({ oldPassword, - newPassword: newPassword.value, - }).then((e: any) => { - const success = !e || !e.errors || e.errors.length === 0; - setShow(!success); - if (success) { - toast.success(`Successfully changed password`); - setOldPassword(''); - setNewPassword({ value: '', error: false }); - setNewPasswordRepeat({ value: '', error: false }); - } + newPassword: newPassword.value + }).then(() => { + setShow(false); + setOldPassword(''); + setNewPassword({ value: '', error: false }); + setNewPasswordRepeat({ value: '', error: false }); + }).catch((e) => { + }); }, [isSubmitDisabled, oldPassword, newPassword, updatePassword] diff --git a/frontend/app/mstore/userStore.ts b/frontend/app/mstore/userStore.ts index e8c40a1ab..0679de2c8 100644 --- a/frontend/app/mstore/userStore.ts +++ b/frontend/app/mstore/userStore.ts @@ -34,22 +34,22 @@ class UserStore { errors: any[] = []; loginRequest = { loading: false, - errors: [] as string[], + errors: [] as string[] }; fetchInfoRequest = { loading: false, - errors: [] as string[], + errors: [] as string[] }; signUpRequest = { loading: false, - errors: [] as string[], + errors: [] as string[] }; updatePasswordRequest = { loading: false, - errors: [] as string[], + errors: [] as string[] }; scopeState: number | null = null; - client = new Client() + client = new Client(); authStore: AuthStore; constructor(authStore: AuthStore) { @@ -74,13 +74,13 @@ class UserStore { }, deserialize: (json) => { return new Account(JSON.parse(json)); - }, - }, + } + } ], - storage: window.localStorage, + storage: window.localStorage }, { - delay: 200, + delay: 200 } ); } @@ -306,7 +306,7 @@ class UserStore { toast.promise(promise, { pending: 'Generating an invite code...', - success: 'Invite code generated successfully', + success: 'Invite code generated successfully' }); return promise; @@ -323,7 +323,7 @@ class UserStore { deleteCookie('jwt', '/', 'openreplay.com'); this.loginRequest = { loading: false, - errors: errors || [], + errors: errors || [] }; }; @@ -344,7 +344,7 @@ class UserStore { deleteCookie('jwt', '/', 'openreplay.com'); this.loginRequest = { loading: false, - errors: error.errors || [], + errors: error.errors || [] }; }); } @@ -367,7 +367,7 @@ class UserStore { runInAction(() => { this.signUpRequest = { loading: false, - errors: error.response?.errors || [], + errors: error.response?.errors || [] }; }); toast.error('Error signing up; please check your data and try again'); @@ -428,15 +428,18 @@ class UserStore { this.scopeState = data.data.scopeState; this.updatePasswordRequest = { loading: false, errors: [] }; }); - return; - } catch (error: any) { + toast.success(`Successfully changed password`); + return data; + } catch (e: any) { + toast.error(e.message || 'Failed to updated password.'); + throw e; + } finally { runInAction(() => { this.updatePasswordRequest = { loading: false, - errors: error.response?.errors || [], + errors: [] }; }); - return error.response; } }; @@ -485,7 +488,7 @@ class UserStore { Object.keys(params).forEach((key) => { this.client[key] = params[key]; this.account[key] = params[key]; - }) + }); }); } catch (error) { // TODO error handling @@ -593,7 +596,7 @@ class UserStore { this.errors = []; this.loginRequest = { loading: false, - errors: [], + errors: [] }; this.scopeState = null; this.client = new Client(); @@ -624,7 +627,7 @@ class AuthStore { sso: null, ssoProvider: null, enforceSSO: null, - edition: 'foss', + edition: 'foss' }; constructor() { @@ -640,13 +643,13 @@ class AuthStore { return Object.keys(ad).length > 0 ? JSON.stringify(ad) : JSON.stringify({}); }, deserialize: (json) => { - return JSON.parse(json) - }, - }, + return JSON.parse(json); + } + } ], expireIn: 60000 * 60, removeOnExpiration: true, - storage: window.localStorage, + storage: window.localStorage }); } diff --git a/frontend/app/services/UserService.ts b/frontend/app/services/UserService.ts index 849dbbfbb..8186dc498 100644 --- a/frontend/app/services/UserService.ts +++ b/frontend/app/services/UserService.ts @@ -153,16 +153,28 @@ export default class UserService { const errorData = await error.response.json(); return { errors: errorData.errors }; } - return { errors: ["An unexpected error occurred."] }; + return { errors: ['An unexpected error occurred.'] }; } } - updatePassword(data: any) { - return this.client - .post('/account/password', data) - .then((response: { json: () => any }) => response.json()) - .then((response: { data: any }) => response || {}); - } + updatePassword = async (data: any) => { + try { + const response = await this.client.post('/account/password', data); + const responseData = await response.json(); + if (responseData.errors) { + throw new Error(responseData.errors[0] || 'An unexpected error occurred.'); + } + + return responseData || {}; + } catch (error: any) { + if (error.response) { + const errorData = await error.response.json(); + const errorMessage = errorData.errors ? errorData.errors[0] : 'An unexpected error occurred.'; + throw new Error(errorMessage); + } + throw new Error('An unexpected error occurred.'); + } + }; fetchTenants() { return this.client @@ -192,21 +204,21 @@ export default class UserService { .then((response: { data: any }) => response.data || {}); } - updateAccount(data: any) { - return this.updateClient(data) - } + updateAccount(data: any) { + return this.updateClient(data); + } - resendEmailVerification(data: any) { - return this.client - .post('/re-validate', data) - .then((response: { json: () => any }) => response.json()) - .then((response: { data: any }) => response.data || {}); - } + resendEmailVerification(data: any) { + return this.client + .post('/re-validate', data) + .then((response: { json: () => any }) => response.json()) + .then((response: { data: any }) => response.data || {}); + } - changeScope(scope: 1 | 2) { - return this.client - .post('/account/scope', { scope }) - .then((response: { json: () => any }) => response.json()) - .then((response: { data: any }) => response.data || {}); - } + changeScope(scope: 1 | 2) { + return this.client + .post('/account/scope', { scope }) + .then((response: { json: () => any }) => response.json()) + .then((response: { data: any }) => response.data || {}); + } }