Skip to content

Commit

Permalink
fix(user): password strength on reset (#395)
Browse files Browse the repository at this point in the history
* fix(user): password strength backend validation message

* chore: add isCommonError helper for better error handling

* chore: update i18next
  • Loading branch information
kiremitrov123 authored Nov 13, 2023
1 parent bc1b007 commit e80e7a7
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 14 deletions.
4 changes: 3 additions & 1 deletion public/locales/en/account.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@
"hide_password": "Hide password",
"invalid_link": "Invalid link",
"invalid_password": "Invalid password",
"invalid_token": "The reset password link is invalid or has expired. Please try resetting your password again.",
"invalid_reset_link": "The reset password link is invalid or has expired. Please try resetting your password again.",
"invalid_token": "Invalid token. Check if you've entered the correct token that we emailed you or request a new one by restarting the forgot password process.",
"link_sent": "Password link sent",
"link_sent_text": "Please check your inbox at {{email}}",
"new_password": "New password",
Expand All @@ -187,6 +188,7 @@
"password_helper_text": "Use a minimum of 8 characters (case sensitive) with at least one number",
"password_reset": "Password reset",
"password_reset_text": "",
"password_strength": "Although your password meets the criteria for a strong password, it includes elements that are not advisable, such as prohibited phrases or repeated words. Please modify it to ensure account safety.",
"passwords_do_not_match": "Passwords do not match",
"repeat_new_password": "Repeat new password",
"reset_password": "Edit Password",
Expand Down
4 changes: 3 additions & 1 deletion public/locales/es/account.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@
"hide_password": "Ocultar contraseña",
"invalid_link": "Enlace no válido",
"invalid_password": "Contraseña no válida",
"invalid_token": "El enlace de restablecimiento de contraseña no es válido o ha expirado. Por favor, intenta restablecer tu contraseña nuevamente.",
"invalid_reset_link": "El enlace de restablecimiento de contraseña no es válido o ha expirado. Por favor, intenta restablecer tu contraseña nuevamente.",
"invalid_token": "Token no válido. Verifica si has ingresado el token correcto que te enviamos por correo electrónico o solicita uno nuevo reiniciando el proceso de restablecimiento de contraseña.",
"link_sent": "Enlace de contraseña enviado",
"link_sent_text": "Por favor, revisa tu bandeja de entrada en {{email}}",
"new_password": "Nueva contraseña",
Expand All @@ -197,6 +198,7 @@
"password_helper_text": "Utiliza un mínimo de 8 caracteres (distingue entre mayúsculas y minúsculas) con al menos un número",
"password_reset": "Restablecimiento de contraseña",
"password_reset_text": "",
"password_strength": "Aunque tu contraseña cumple con los criterios de una contraseña segura, incluye elementos que no son recomendables, como frases prohibidas o palabras repetidas. Por favor, modifícala para garantizar la seguridad de tu cuenta.",
"passwords_do_not_match": "Las contraseñas no coinciden",
"repeat_new_password": "Repetir nueva contraseña",
"reset_password": "Editar contraseña",
Expand Down
2 changes: 1 addition & 1 deletion src/components/EditPasswordForm/EditPasswordForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const EditPasswordForm: React.FC<Props> = ({ onSubmit, onChange, onBlur, showOld
) : showResetTokenField ? (
<TextField
className={styles.textField}
value={value.resetPasswordToken}
value={value.resetPasswordToken || ''}
onChange={onChange}
onBlur={onBlur}
label={t('reset.reset_password_token')}
Expand Down
4 changes: 4 additions & 0 deletions src/containers/AccountModal/forms/EditPassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const ResetPassword: React.FC = () => {
if (error.message.includes('invalid param password')) {
setErrors({ password: t('reset.invalid_password') });
} else if (error.message.includes('resetPasswordToken is not valid')) {
setErrors({ form: t('reset.invalid_reset_link') });
} else if (error.message.includes('score does not match standards')) {
setErrors({ form: t('reset.password_strength') });
} else if (error.message.includes('password could not be set')) {
setErrors({ form: t('reset.invalid_token') });
}
}
Expand Down
24 changes: 16 additions & 8 deletions src/services/inplayer.account.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import InPlayer, { AccountData, Env, FavoritesData, UpdateAccountData, WatchHist
import i18next from 'i18next';

import { formatConsentsToRegisterFields } from '#src/utils/collection';
import { getCommonResponseData } from '#src/utils/api';
import { getCommonResponseData, isCommonError } from '#src/utils/api';
import type { Config } from '#types/Config';
import type {
AuthData,
Expand Down Expand Up @@ -30,7 +30,7 @@ import type {
CustomRegisterFieldVariant,
} from '#types/account';
import type { Favorite } from '#types/favorite';
import type { InPlayerAuthData, InPlayerError } from '#types/inplayer';
import type { InPlayerAuthData } from '#types/inplayer';
import type { WatchHistoryItem } from '#types/watchHistory';

enum InPlayerEnv {
Expand Down Expand Up @@ -116,8 +116,10 @@ export const register: Register = async ({ config, email, password, consents })
customerConsents: parseJson(user?.metadata?.consents as string, []),
};
} catch (error: unknown) {
const { response } = error as InPlayerError;
throw new Error(response.data.message);
if (isCommonError(error)) {
throw new Error(error.response.data.message);
}
throw new Error('Failed to create account.');
}
};

Expand Down Expand Up @@ -276,8 +278,11 @@ export const changePasswordWithOldPassword: ChangePasswordWithOldPassword = asyn
errors: [],
responseData: {},
};
} catch {
throw new Error('Failed to change password.');
} catch (error: unknown) {
if (isCommonError(error)) {
throw new Error(error.response.data.message);
}
throw new Error('Failed to change password');
}
};

Expand All @@ -296,8 +301,11 @@ export const changePasswordWithResetToken: ChangePassword = async (payload) => {
errors: [],
responseData: {},
};
} catch {
throw new Error('Failed to change password.');
} catch (error: unknown) {
if (isCommonError(error)) {
throw new Error(error.response.data.message);
}
throw new Error('Failed to change password');
}
};

Expand Down
5 changes: 2 additions & 3 deletions src/services/inplayer.subscription.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import InPlayer, { PurchaseDetails, Card, GetItemAccessV1, SubscriptionDetails a

import type { ChangeSubscription, PaymentDetail, Subscription, Transaction, UpdateCardDetails, UpdateSubscription } from '#types/subscription';
import type { Config } from '#types/Config';
import type { InPlayerError } from '#types/inplayer';
import { isCommonError } from '#src/utils/api';

interface SubscriptionDetails extends InplayerSubscription {
item_id?: number;
Expand Down Expand Up @@ -37,8 +37,7 @@ export async function getActiveSubscription({ config }: { config: Config }) {
}
return null;
} catch (error: unknown) {
const { response } = error as InPlayerError;
if (response.data.code === 402) {
if (isCommonError(error) && error.response.data.code === 402) {
return null;
}
throw new Error('Unable to fetch customer subscriptions.');
Expand Down
12 changes: 12 additions & 0 deletions src/utils/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { CommonResponse } from '@inplayer-org/inplayer.js';

import type { InPlayerError } from '#types/inplayer';

export class ApiError extends Error {
code: number;
message: string;
Expand Down Expand Up @@ -42,3 +44,13 @@ export const getCommonResponseData = (response: { data: CommonResponse }) => {
},
};
};

export const isCommonError = (error: unknown): error is InPlayerError => {
return (
typeof error === 'object' &&
error !== null &&
'response' in error &&
typeof (error as InPlayerError).response?.data?.code === 'number' &&
typeof (error as InPlayerError).response?.data?.message === 'string'
);
};

0 comments on commit e80e7a7

Please sign in to comment.