[FIX] Change password not working on some cases (#4312)
* create iTotp enum * migrate change user profile to method * Fix minor i18n issues * Use saveUserProfileMethod from Services * Catch cancel event from TwoFactor modal Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
parent
bc09527d78
commit
303d127949
|
@ -0,0 +1,5 @@
|
|||
export enum TwoFactorMethods {
|
||||
TOTP = 'totp',
|
||||
EMAIL = 'email',
|
||||
PASSWORD = 'password'
|
||||
}
|
|
@ -71,6 +71,7 @@
|
|||
"error-remove-last-owner": "This is the last owner. Please set a new owner before removing this one.",
|
||||
"error-role-in-use": "Cannot delete role because it's in use",
|
||||
"error-role-name-required": "Role name is required",
|
||||
"error-password-same-as-current": "Entered password same as current password",
|
||||
"error-the-field-is-required": "The field {{field}} is required.",
|
||||
"error-too-many-requests": "Error, too many requests. Please slow down. You must wait {{seconds}} seconds before trying again.",
|
||||
"error-user-is-not-activated": "User is not activated",
|
||||
|
@ -836,5 +837,6 @@
|
|||
"Mark_as_unread": "Mark as unread",
|
||||
"Mark_as_unread_Info": "Display room as unread when there are unread messages",
|
||||
"Show_badge_for_mentions": "Show badge for mentions",
|
||||
"Show_badge_for_mentions_Info": "Display badge for direct mentions only"
|
||||
"Show_badge_for_mentions_Info": "Display badge for direct mentions only",
|
||||
"totp-invalid": "Code or password invalid"
|
||||
}
|
|
@ -69,6 +69,7 @@
|
|||
"error-remove-last-owner": "Este é o último proprietário. Por favor, defina um novo proprietário antes de remover este.",
|
||||
"error-role-in-use": "Não é possível remover o papel pois ele está em uso",
|
||||
"error-role-name-required": "Nome do papel é obrigatório",
|
||||
"error-password-same-as-current": "Senha digitada coincide com a senha atual",
|
||||
"error-the-field-is-required": "O campo {{field}} é obrigatório.",
|
||||
"error-too-many-requests": "Erro, muitas solicitações. Por favor, diminua a velocidade. Você deve esperar {{seconds}} segundos antes de tentar novamente.",
|
||||
"error-user-is-not-activated": "O usuário não está ativo",
|
||||
|
@ -743,5 +744,6 @@
|
|||
"sending_email_confirmation": "enviando email de confirmação",
|
||||
"Unsupported_format": "Formato não suportado",
|
||||
"Downloaded_file": "Arquivo baixado",
|
||||
"Error_Download_file": "Erro ao baixar o arquivo"
|
||||
"Error_Download_file": "Erro ao baixar o arquivo",
|
||||
"totp-invalid": "Código ou senha inválida"
|
||||
}
|
|
@ -918,6 +918,15 @@ export function getUserInfo(userId: string) {
|
|||
|
||||
export const toggleFavorite = (roomId: string, favorite: boolean) => sdk.post('rooms.favorite', { roomId, favorite });
|
||||
|
||||
export const saveUserProfileMethod = (
|
||||
params: IProfileParams,
|
||||
customFields = {},
|
||||
twoFactorOptions: {
|
||||
twoFactorCode: string;
|
||||
twoFactorMethod: string;
|
||||
} | null
|
||||
) => sdk.current.methodCall('saveUserProfile', params, customFields, twoFactorOptions);
|
||||
|
||||
export const deleteOwnAccount = (password: string, confirmRelinquish = false): any =>
|
||||
// RC 0.67.0
|
||||
sdk.post('users.deleteOwnAccount', { password, confirmRelinquish });
|
||||
|
|
|
@ -41,6 +41,8 @@ import {
|
|||
IProfileParams,
|
||||
IUser
|
||||
} from '../../definitions';
|
||||
import { twoFactor } from '../../lib/services/twoFactor';
|
||||
import { TwoFactorMethods } from '../../definitions/ITotp';
|
||||
import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet';
|
||||
import { DeleteAccountActionSheetContent } from './components/DeleteAccountActionSheetContent';
|
||||
|
||||
|
@ -71,6 +73,10 @@ interface IProfileViewState {
|
|||
customFields: {
|
||||
[key: string | number]: string;
|
||||
};
|
||||
twoFactorCode: null | {
|
||||
twoFactorCode: string;
|
||||
twoFactorMethod: string;
|
||||
};
|
||||
}
|
||||
|
||||
class ProfileView extends React.Component<IProfileViewProps, IProfileViewState> {
|
||||
|
@ -113,7 +119,8 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
url: ''
|
||||
},
|
||||
avatarSuggestions: {},
|
||||
customFields: {}
|
||||
customFields: {},
|
||||
twoFactorCode: null
|
||||
};
|
||||
|
||||
async componentDidMount() {
|
||||
|
@ -194,14 +201,17 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
);
|
||||
};
|
||||
|
||||
handleError = (e: any, func: string, action: string) => {
|
||||
handleError = (e: any, _func: string, action: string) => {
|
||||
if (e.data && e.data.error.includes('[error-too-many-requests]')) {
|
||||
return showErrorAlert(e.data.error);
|
||||
}
|
||||
if (I18n.isTranslated(e.error)) {
|
||||
return showErrorAlert(I18n.t(e.error));
|
||||
}
|
||||
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t(action) }));
|
||||
};
|
||||
|
||||
submit = async () => {
|
||||
submit = async (): Promise<void> => {
|
||||
Keyboard.dismiss();
|
||||
|
||||
if (!this.formIsChanged()) {
|
||||
|
@ -210,7 +220,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
|
||||
this.setState({ saving: true });
|
||||
|
||||
const { name, username, email, newPassword, currentPassword, avatar, customFields } = this.state;
|
||||
const { name, username, email, newPassword, currentPassword, avatar, customFields, twoFactorCode } = this.state;
|
||||
const { user, dispatch } = this.props;
|
||||
const params = {} as IProfileParams;
|
||||
|
||||
|
@ -275,9 +285,16 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
}
|
||||
}
|
||||
|
||||
const result = await Services.saveUserProfile(params, customFields);
|
||||
const twoFactorOptions = params.currentPassword
|
||||
? {
|
||||
twoFactorCode: params.currentPassword,
|
||||
twoFactorMethod: TwoFactorMethods.PASSWORD
|
||||
}
|
||||
: null;
|
||||
|
||||
if (result.success) {
|
||||
const result = await Services.saveUserProfileMethod(params, customFields, twoFactorCode || twoFactorOptions);
|
||||
|
||||
if (result) {
|
||||
logEvent(events.PROFILE_SAVE_CHANGES);
|
||||
if (customFields) {
|
||||
dispatch(setUser({ customFields, ...params }));
|
||||
|
@ -287,10 +304,18 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
EventEmitter.emit(LISTENER, { message: I18n.t('Profile_saved_successfully') });
|
||||
this.init();
|
||||
}
|
||||
this.setState({ saving: false });
|
||||
} catch (e) {
|
||||
this.setState({ saving: false, currentPassword: null, twoFactorCode: null });
|
||||
} catch (e: any) {
|
||||
if (e?.error === 'totp-invalid' && e?.details.method !== TwoFactorMethods.PASSWORD) {
|
||||
try {
|
||||
const code = await twoFactor({ method: e?.details.method, invalid: e?.error === 'totp-invalid' && !!twoFactorCode });
|
||||
return this.setState({ twoFactorCode: code }, () => this.submit());
|
||||
} catch {
|
||||
// cancelled twoFactor modal
|
||||
}
|
||||
}
|
||||
logEvent(events.PROFILE_SAVE_CHANGES_F);
|
||||
this.setState({ saving: false, currentPassword: null });
|
||||
this.setState({ saving: false, currentPassword: null, twoFactorCode: null });
|
||||
this.handleError(e, 'saveUserProfile', 'saving_profile');
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue