From d9ea5977cd9cd596e81c4b9282512d04d8f22f1f Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 5 Jan 2017 18:24:05 -0300 Subject: [PATCH 1/7] Unique displayName for the User. --- models/user.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/models/user.js b/models/user.js index 7df713337..f4ddbd895 100644 --- a/models/user.js +++ b/models/user.js @@ -46,7 +46,11 @@ const UserSchema = new mongoose.Schema({ // This is sourced from the social provider or set manually during user setup // and simply provides a name to display for the given user. - displayName: String, + displayName: { + type: String, + unique: true, + required: true + }, // This is true when the user account is disabled, no action should be // acknowledged when they are disabled. Logins are also prevented. From 712e436f584f4a7ba861fae0e8b00dfe16caee80 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 6 Jan 2017 16:38:44 -0300 Subject: [PATCH 2/7] Cleans error on email address or name. We need to go through all the errors and manage them better with translations. --- client/coral-framework/actions/auth.js | 4 +++- client/coral-framework/translations.json | 6 ++++-- client/coral-sign-in/translations.js | 2 ++ models/user.js | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index 106224c25..f06ea7526 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -82,7 +82,9 @@ export const fetchSignUp = formData => (dispatch) => { dispatch(changeView('SIGNIN')); }, 3000); }) - .catch(() => dispatch(signUpFailure(lang.t('error.emailInUse')))); // We need to inprove error handling. TODO (bc) + .catch(() => { + dispatch(signUpFailure(lang.t('error.emailORusernameInUse'))); + }); // We need to improve error handling. TODO (bc) }; // Forgot Password Actions diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index 06a39944a..99d3341b1 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -10,7 +10,8 @@ "displayName": "Display name is too short", "confirmPassword": "Passwords don`t match. Please, check again", "emailPasswordError": "Email and/or password combination incorrect.", - "emailInUse": "Email address already in use" + "emailInUse": "Email address already in use", + "emailORusernameInUse": "Email address or Username already in use" } }, "es": { @@ -24,7 +25,8 @@ "displayName": "El nombre es muy corto", "confirmPassword": "Las contraseñas no coinciden", "emailPasswordError": "Email y/o contraseña incorrecta.", - "emailInUse": "Email address already in use" + "emailInUse": "Correo electronico en uso.", + "emailORusernameInUse": "Correo o Nombre en uso." } } } diff --git a/client/coral-sign-in/translations.js b/client/coral-sign-in/translations.js index 200cb91f1..a50ad6f54 100644 --- a/client/coral-sign-in/translations.js +++ b/client/coral-sign-in/translations.js @@ -19,6 +19,7 @@ export default { alreadyHaveAnAccount: 'Already have an account?', recoverPassword: 'Recover password', emailInUse: 'Email address already in use', + emailORusernameInUse: 'Email address or Username already in use', requiredField: 'This field is required', passwordsDontMatch: 'Passwords don\'t match.', checkTheForm: 'Invalid Form. Please, check the fields' @@ -44,6 +45,7 @@ export default { alreadyHaveAnAccount: 'Ya tienes una cuenta?', recoverPassword: 'Recuperar contraseña', emailInUse: 'Este email se encuentra en uso', + emailORusernameInUse: 'Este email ó nombre se encuentran en uso', requiredField: 'Este campo es requerido', passwordsDontMatch: 'Las contraseñas no coinciden', checkTheForm: 'Formulario Inválido. Por favor, completa los campos' diff --git a/models/user.js b/models/user.js index d8a116ae5..bcc22d895 100644 --- a/models/user.js +++ b/models/user.js @@ -356,7 +356,7 @@ UserService.createLocalUser = (email, password, displayName) => { user.save((err) => { if (err) { if (err.code === 11000) { - return reject('Email address already in use'); + return reject(new Error('Email address or Name already in use')); } return reject(err); } From 4dbc73f9abf77af12e2f5080520405a98e548694 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 6 Jan 2017 16:57:25 -0300 Subject: [PATCH 3/7] Add a test on already used display name. --- tests/models/user.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/models/user.js b/tests/models/user.js index 7484880bf..46584a9dc 100644 --- a/tests/models/user.js +++ b/tests/models/user.js @@ -80,6 +80,22 @@ describe('models.User', () => { }); + describe('#createLocalUser', () => { + it('should not create a user with duplicate display name', () => { + return User.createLocalUsers([{ + email: 'otrostampi@gmail.com', + displayName: 'Stampi', + password: '1Coralito!' + }]) + .then((user) => { + expect(user).to.be.null; + }) + .catch((error) => { + expect(error).to.not.be.null; + }); + }); + }); + describe('#createEmailConfirmToken', () => { it('should create a token for a valid user', () => { From 15e7ef6368f89fda4d9a7e2254a1ebe259f65110 Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 12 Jan 2017 10:46:18 -0800 Subject: [PATCH 4/7] Adds an error const. --- errors.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/errors.js b/errors.js index 0651b4fff..68509520d 100644 --- a/errors.js +++ b/errors.js @@ -15,6 +15,10 @@ const ErrEmailTaken = new Error('Email address already in use'); ErrEmailTaken.translation_key = 'EMAIL_IN_USE'; ErrEmailTaken.status = 400; +const ErrEmailDisplaynameTaken = new Error('Email or Display name already in use'); +ErrEmailDisplaynameTaken.translation_key = 'EMAIL_DISPLAYNAME_IN_USE'; +ErrEmailDisplaynameTaken.status = 400; + const ErrSpecialChars = new Error('No special characters are allowed in a display name'); ErrSpecialChars.translation_key = 'NO_SPECIAL_CHARACTERS'; ErrSpecialChars.status = 400; From acf3ad5e28ccf2d24fa2e9451e52480c275bae3b Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 12 Jan 2017 11:10:07 -0800 Subject: [PATCH 5/7] Some conflicts were added. --- client/coral-framework/translations.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index 08afa8d9a..8015d71e5 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -31,10 +31,8 @@ "displayName": "Los nombres pueden contener letras, números y _", "confirmPassword": "Las contraseñas no coinciden", "emailPasswordError": "Email y/o contraseña incorrecta.", -<<<<<<< HEAD "emailInUse": "Correo electronico en uso.", - "emailORusernameInUse": "Correo o Nombre en uso." -======= + "emailORusernameInUse": "Correo o Nombre en uso.", "EMAIL_REQUIRED": "Se requiere una dirección de correo electrónico", "PASSWORD_REQUIRED": "Debe ingresar una contraseña", "PASSWORD_LENGTH": "La contraseña es muy corta", @@ -42,7 +40,6 @@ "DISPLAY_NAME_REQUIRED": "Debe ingresar un nombre", "NO_SPECIAL_CHARACTERS": "Los nombres pueden contener letras, números y _", "PROFANITY_ERROR": "Los nombres no pueden contener blasfemias. Por favor contacte al administrador si cree que esto es un error" ->>>>>>> master } } } From 1027b19a499ad47e812b54eced7f40c0ba1b769e Mon Sep 17 00:00:00 2001 From: gaba Date: Thu, 12 Jan 2017 14:43:36 -0800 Subject: [PATCH 6/7] Added regex to look for the field that is duplicated. Not sure if there is a better way to do it. --- client/coral-framework/translations.json | 7 ++++--- errors.js | 9 +++++---- models/user.js | 6 +++++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json index 8015d71e5..5bf9b40a9 100644 --- a/client/coral-framework/translations.json +++ b/client/coral-framework/translations.json @@ -14,7 +14,8 @@ "PASSWORD_REQUIRED": "Must input a password", "PASSWORD_LENGTH": "Password is too short", "EMAIL_IN_USE": "Email address already in use", - "EMAIL_DISPLAYNAME_IN_USE": "Email address or display name already in use", + "EMAIL_DISPLAY_NAME_IN_USE": "Email address or display name already in use", + "DISPLAYNAME_IN_USE": "Display name already in use", "DISPLAY_NAME_REQUIRED": "Must input a display name", "NO_SPECIAL_CHARACTERS": "Display names can contain letters, numbers and _ only", "PROFANITY_ERROR": "Display names must not contain profanity. Please contact the administrator if you believe this to be in error." @@ -31,12 +32,12 @@ "displayName": "Los nombres pueden contener letras, números y _", "confirmPassword": "Las contraseñas no coinciden", "emailPasswordError": "Email y/o contraseña incorrecta.", - "emailInUse": "Correo electronico en uso.", - "emailORusernameInUse": "Correo o Nombre en uso.", "EMAIL_REQUIRED": "Se requiere una dirección de correo electrónico", "PASSWORD_REQUIRED": "Debe ingresar una contraseña", "PASSWORD_LENGTH": "La contraseña es muy corta", "EMAIL_IN_USE": "La dirección de correo electrónico se encuentra en uso", + "EMAIL_DISPLAY_NAME_IN_USE": "Correo o Nombre en uso.", + "DISPLAYNAME_IN_USE": "Nombre en uso.", "DISPLAY_NAME_REQUIRED": "Debe ingresar un nombre", "NO_SPECIAL_CHARACTERS": "Los nombres pueden contener letras, números y _", "PROFANITY_ERROR": "Los nombres no pueden contener blasfemias. Por favor contacte al administrador si cree que esto es un error" diff --git a/errors.js b/errors.js index 68509520d..0bd8711c6 100644 --- a/errors.js +++ b/errors.js @@ -15,9 +15,9 @@ const ErrEmailTaken = new Error('Email address already in use'); ErrEmailTaken.translation_key = 'EMAIL_IN_USE'; ErrEmailTaken.status = 400; -const ErrEmailDisplaynameTaken = new Error('Email or Display name already in use'); -ErrEmailDisplaynameTaken.translation_key = 'EMAIL_DISPLAYNAME_IN_USE'; -ErrEmailDisplaynameTaken.status = 400; +const ErrDisplayTaken = new Error('Display name already in use'); +ErrDisplayTaken.translation_key = 'DISPLAYNAME_IN_USE'; +ErrDisplayTaken.status = 400; const ErrSpecialChars = new Error('No special characters are allowed in a display name'); ErrSpecialChars.translation_key = 'NO_SPECIAL_CHARACTERS'; @@ -45,5 +45,6 @@ module.exports = { ErrEmailTaken, ErrSpecialChars, ErrMissingDisplay, - ErrContainsProfanity + ErrContainsProfanity, + ErrDisplayTaken }; diff --git a/models/user.js b/models/user.js index 0b6241dfe..b0ead1c5a 100644 --- a/models/user.js +++ b/models/user.js @@ -383,7 +383,11 @@ UserService.createLocalUser = (email, password, displayName) => { user.save((err) => { if (err) { if (err.code === 11000) { - return reject(errors.ErrEmailDisplaynameTaken); + const regex = new RegExp('displayName', 'g'); + if (regex.exec(err.message)[0] === 'displayName') { + return reject(errors.ErrDisplayTaken); + } + return reject(errors.ErrEmailTaken); } return reject(err); } From 06ab33343f3b29799c7051ca0043cb3d97083d05 Mon Sep 17 00:00:00 2001 From: gaba Date: Fri, 13 Jan 2017 14:15:31 -0800 Subject: [PATCH 7/7] Errors needs to use APIError. --- errors.js | 2 +- models/user.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/errors.js b/errors.js index 6cdc7425a..1b26e7170 100644 --- a/errors.js +++ b/errors.js @@ -54,7 +54,7 @@ const ErrEmailTaken = new APIError('Email address already in use', { status: 400 }); -const ErrDisplayTaken = new Error('Display name already in use', { +const ErrDisplayTaken = new APIError('Display name already in use', { translation_key: 'DISPLAYNAME_IN_USE', status: 400 }); diff --git a/models/user.js b/models/user.js index b0ead1c5a..a0ca34d7a 100644 --- a/models/user.js +++ b/models/user.js @@ -383,8 +383,7 @@ UserService.createLocalUser = (email, password, displayName) => { user.save((err) => { if (err) { if (err.code === 11000) { - const regex = new RegExp('displayName', 'g'); - if (regex.exec(err.message)[0] === 'displayName') { + if (err.message.match('displayName')) { return reject(errors.ErrDisplayTaken); } return reject(errors.ErrEmailTaken);