Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CAUTH-423] Add captcha in the sign-up flow #1902

Merged
merged 2 commits into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions scripts/complete-translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const processLanguage = async lang => {
console.log(`translating: ${lang}`);
const langDictionary = require('../lib/i18n/' + lang).default;
await processNode(enDictionary, langDictionary, lang);
cleanNode(enDictionary, langDictionary);
const communityAlert = `
// This file was automatically translated.
// Feel free to submit a PR if you find a more accurate translation.
Expand Down Expand Up @@ -63,6 +64,22 @@ const processNode = async (enNode, langNode, lang) => {
}
};

/**
* delete deprecate translations that are not longer present in the english language
*/
const cleanNode = (enNode, langNode) => {
for (let key of Object.keys(langNode)) {
if (typeof langNode[key] === 'object') {
cleanNode(enNode[key], langNode[key]);
} else {
if (typeof enNode[key] === 'undefined') {
console.log('removing', key);
delete langNode[key];
}
}
}
};

const translateKey = async (toTranslate, lang) => {
if (lang == 'ua') {
//Note: "ua" is not a valid language code, the actual lang code is uk-ua
Expand Down
97 changes: 56 additions & 41 deletions src/connection/database/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,9 @@ export function logIn(id, needsMFA = false) {

const fields = [usernameField, 'password'];

const captchaConfig = l.captcha(m);
const isCaptchaRequired = captchaConfig && l.captcha(m).get('required');
if (isCaptchaRequired) {
const captcha = c.getFieldValue(m, 'captcha');
if (!captcha) {
return showMissingCaptcha(captchaConfig, m, id);
}
params['captcha'] = captcha;
fields.push('captcha');
const isCaptchaValid = setCaptchaParams(m, params, fields);
if (!isCaptchaValid) {
return showMissingCaptcha(m, id);
}

const mfaCode = c.getFieldValue(m, 'mfa_code');
Expand All @@ -59,17 +53,6 @@ export function logIn(id, needsMFA = false) {
});
}

function showMissingCaptcha(captchaConfig, m, id) {
const captchaError =
captchaConfig.get('provider') === 'recaptcha_v2' ? 'invalid_recaptcha' : 'invalid_captcha';
const errorMessage = i18n.html(m, ['error', 'login', captchaError]);
swap(updateEntity, 'lock', id, m => {
m = l.setSubmitting(m, false, errorMessage);
return c.showInvalidField(m, 'captcha');
});
return m;
}

export function signUp(id) {
const m = read(getEntity, 'lock', id);
const fields = ['email', 'password'];
Expand All @@ -84,6 +67,11 @@ export function signUp(id) {
autoLogin: shouldAutoLogin(m)
};

const isCaptchaValid = setCaptchaParams(m, params, fields);
if (!isCaptchaValid) {
return showMissingCaptcha(m, id);
}

if (databaseConnectionRequiresUsername(m)) {
params.username = c.getFieldValue(m, 'username');
}
Expand Down Expand Up @@ -113,7 +101,10 @@ export function signUp(id) {
if (!!popupHandler) {
popupHandler._current_popup.kill();
}
setTimeout(() => signUpError(id, error), 250);
const wasInvalidCaptcha = error && error.code === 'invalid_captcha';
swapCaptcha(id, wasInvalidCaptcha, () => {
setTimeout(() => signUpError(id, error), 250);
});
} else {
signUpSuccess(id, result, popupHandler, ...args);
}
Expand All @@ -127,12 +118,6 @@ function signUpSuccess(id, result, popupHandler) {
l.emitEvent(lock, 'signup success', result);

if (shouldAutoLogin(lock)) {
const isCaptchaRequired = l.captcha(lock) && l.captcha(lock).get('required');

if (isCaptchaRequired) {
return successCaptchaRequired(id);
}

swap(updateEntity, 'lock', id, m => m.set('signedUp', true));

// TODO: check options, redirect is missing
Expand Down Expand Up @@ -203,20 +188,6 @@ function autoLogInError(id, error) {
});
}

function successCaptchaRequired(id) {
swap(updateEntity, 'lock', id, m => {
if (!hasScreen(m, 'login')) {
return l.setSubmitting(m, false);
}
// _ prevents cleaning the fields
m = l.setSubmitting(setScreen(m, 'login', ['_']), false);

const message = i18n.str(m, ['error', 'signUp', 'captcha_required']);

return l.setGlobalSuccess(m, message);
});
}

export function resetPassword(id) {
validateAndSubmit(id, ['email'], m => {
const params = {
Expand Down Expand Up @@ -313,3 +284,47 @@ export function swapCaptcha(id, wasInvalid, next) {
}
});
}

/**
* Display the error message of missing captcha in the header of lock.
*
* @param {Object} m model
* @param {Number} id
*/
function showMissingCaptcha(m, id) {
const captchaConfig = l.captcha(m);
const captchaError =
captchaConfig.get('provider') === 'recaptcha_v2' ? 'invalid_recaptcha' : 'invalid_captcha';
const errorMessage = i18n.html(m, ['error', 'login', captchaError]);
swap(updateEntity, 'lock', id, m => {
m = l.setSubmitting(m, false, errorMessage);
return c.showInvalidField(m, 'captcha');
});
return m;
}

/**
* Set the captcha value in the fields object before sending the request.
*
* @param {Object} m model
* @param {Object} params
* @param {Object} fields
*
* @returns {Boolean} returns true if is required and missing the response from the user
*/
function setCaptchaParams(m, params, fields) {
const captchaConfig = l.captcha(m);
const isCaptchaRequired = captchaConfig && l.captcha(m).get('required');
if (!isCaptchaRequired) {
return true;
}
const captcha = c.getFieldValue(m, 'captcha');
//captcha required and missing
if (!captcha) {
return false;
}

params['captcha'] = captcha;
fields.push('captcha');
return true;
}
3 changes: 3 additions & 0 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,9 @@ export function setCaptcha(m, value, wasInvalid) {
}

export function captcha(m) {
//some tests send an string as model.
// https://github.com/auth0/lock/blob/82f56187698528699478bd429858cf91e387763c/src/__tests__/engine/classic/sign_up_pane.test.jsx#L28
if (typeof m !== 'object') { return; }
return get(m, 'captcha');
}

Expand Down
9 changes: 9 additions & 0 deletions src/engine/classic/sign_up_pane.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
databaseConnectionRequiresUsername,
passwordStrengthPolicy
} from '../../connection/database/index';
import CaptchaPane from '../../field/captcha/captcha_pane';
import * as l from '../../core/index';
import { swapCaptcha } from '../../connection/database/actions';

export default class SignUpPane extends React.Component {
render() {
Expand Down Expand Up @@ -53,6 +56,11 @@ export default class SignUpPane extends React.Component {
/>
));

const captchaPane =
l.captcha(model) && l.captcha(model).get('required') ? (
<CaptchaPane i18n={i18n} lock={model} onReload={() => swapCaptcha(l.id(model), false)} />
) : null;

const passwordPane = !onlyEmail && (
<PasswordPane
i18n={i18n}
Expand All @@ -69,6 +77,7 @@ export default class SignUpPane extends React.Component {
<EmailPane i18n={i18n} lock={model} placeholder={emailInputPlaceholder} />
{usernamePane}
{passwordPane}
{captchaPane}
{fields}
</div>
);
Expand Down
1 change: 0 additions & 1 deletion src/i18n/af.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export default {
password_strength_error: 'Wagwoord is swak.',
user_exists: 'Gebruiker bestaan reeds.',
username_exists: 'Gebruikersnaam bestaan reeds.',
captcha_required: 'Voer die kode hieronder in om aan te sluit.',
social_signup_needs_terms_acception:
'Gee toestemming tot die onderstaande diensbepalings om voort te gaan.'
}
Expand Down
1 change: 0 additions & 1 deletion src/i18n/ar.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export default {
password_strength_error: 'كلمة المرور ضعيفة جداً.',
user_exists: 'المستخدم موجود بالفعل.',
username_exists: 'اسم المستخدم موجود بالفعل.',
captcha_required: 'أدخل الرمز الموضح أدناه لإنهاء الاشتراك.',
social_signup_needs_terms_acception: 'يرجى الموافقة على شروط الخدمة أدناه للمتابعة.'
}
},
Expand Down
1 change: 0 additions & 1 deletion src/i18n/az.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export default {
password_strength_error: 'Şifrə çox sadədir.',
user_exists: 'Bu istifadəçi artıq mövcuddur.',
username_exists: 'Bu istifadəçi adı istifadə olunur.',
captcha_required: 'Qeydiyyatı başa çatdırmaq üçün aşağıda göstərilən kodu daxil edin.',
social_signup_needs_terms_acception:
'Xahiş edirik davam etmək üçün aşağıda göstərilən Xidmət şərtlərinə razılıq verin.'
}
Expand Down
1 change: 0 additions & 1 deletion src/i18n/bg.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export default {
password_strength_error: 'Паролата е много несигурна.',
user_exists: 'Този профил вече съществува.',
username_exists: 'Това потребителско име вече съществува.',
captcha_required: 'Въведете кода, показан по-долу, за да завършите регистрацията.',
social_signup_needs_terms_acception:
'Моля, приемете Общите условия по-долу, за да продължите.'
}
Expand Down
2 changes: 0 additions & 2 deletions src/i18n/ca.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ export default {
password_strength_error: 'La contrasenya és massa feble.',
user_exists: 'Ja existeix aquest usuari.',
username_exists: "Ja existeix aquest nom d'usuari.",
captcha_required:
'Introduïu el codi que es mostra a continuació per finalitzar la inscripció.',
social_signup_needs_terms_acception: 'Per continuar, accepteu les Condicions del servei.'
}
},
Expand Down
1 change: 0 additions & 1 deletion src/i18n/cs.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export default {
password_strength_error: 'Heslo je příliš slabé.',
user_exists: 'Uživatel už existuje.',
username_exists: 'Uživatelské jméno už existuje.',
captcha_required: 'Chcete-li dokončit registraci, zadejte níže uvedený kód.',
social_signup_needs_terms_acception:
'Pokračujte prosím souhlasem s níže uvedenými smluvními podmínkami.'
}
Expand Down
3 changes: 1 addition & 2 deletions src/i18n/da.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ export default {
user_exists: 'Denne bruger eksisterer allerede.',
username_exists: 'Dette brugernavn eksisterer allerede.',
social_signup_needs_terms_acception:
'Du accepterer servicevilkårene nedenfor for at fortsætte.',
captcha_required: 'Indtast nedenstående kode for at afslutte tilmeldingen.'
'Du accepterer servicevilkårene nedenfor for at fortsætte.'
}
},
success: {
Expand Down
3 changes: 1 addition & 2 deletions src/i18n/de.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ export default {
user_exists: 'Der Nutzer existiert bereits.',
username_exists: 'Der Nutzername wird bereits verwendet.',
social_signup_needs_terms_acception:
'Bitte stimmen Sie den untenstehenden Nutzungsbedingungen zu, um fortzufahren.',
captcha_required: 'Geben Sie den unten gezeigten Code ein, um die Anmeldung abzuschließen.'
'Bitte stimmen Sie den untenstehenden Nutzungsbedingungen zu, um fortzufahren.'
}
},
success: {
Expand Down
2 changes: 0 additions & 2 deletions src/i18n/el.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ export default {
password_strength_error: 'Ο κωδικός πρόσβασης είναι πολύ προβλέψιμος.',
user_exists: 'Ο λογαριασμός υπάρχει ήδη.',
username_exists: 'Το όνομα χρήστη υπάρχει ήδη.',
captcha_required:
'Εισαγάγετε τον κωδικό που εμφανίζεται παρακάτω για να ολοκληρώσετε την εγγραφή.',
social_signup_needs_terms_acception:
'Αποδεχτείτε τους Όρους Παροχής Υπηρεσιών παρακάτω για να συνεχίσετε.'
}
Expand Down
1 change: 0 additions & 1 deletion src/i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export default {
},
signUp: {
invalid_password: 'Password is invalid.',
captcha_required: 'Enter the code shown below to finish signing up.',
'lock.fallback': "We're sorry, something went wrong when attempting to sign up.",
password_dictionary_error: 'Password is too common.',
password_no_user_info_error: 'Password is based on user information.',
Expand Down
2 changes: 0 additions & 2 deletions src/i18n/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ export default {
},
signUp: {
invalid_password: 'La contraseña es inválida.',
captcha_required:
'Ingrese el código que se muestra a continuación para finalizar el registro.',
'lock.fallback': 'Ocurrió un error durante el registro.',
password_dictionary_error: 'La constraseña es muy común.',
password_no_user_info_error: 'La constraseña es similar a los datos del usuario.',
Expand Down
1 change: 0 additions & 1 deletion src/i18n/et.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export default {
password_strength_error: 'Parool on liiga nõrk.',
user_exists: 'Selline kasutaja on juba olemas.',
username_exists: 'Selline kasutajanimi on juba olemas.',
captcha_required: 'Registreerumise lõpetamiseks sisestage allpool näidatud kood.',
social_signup_needs_terms_acception: 'Jätkamiseks nõustuge allolevate teenusetingimustega.'
}
},
Expand Down
1 change: 0 additions & 1 deletion src/i18n/fa.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export default {
password_strength_error: 'رمز عبور بسیار ضعیف است.',
user_exists: 'کاربر قبلا ثبت شده است.',
username_exists: 'نام کاربری قبلا ثبت شده است.',
captcha_required: 'برای پایان کار ، کد نشان داده شده در زیر را وارد کنید.',
social_signup_needs_terms_acception: 'لطفاً برای ادامه با شرایط خدمات زیر موافقت کنید.'
}
},
Expand Down
4 changes: 1 addition & 3 deletions src/i18n/fi.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ export default {
password_strength_error: 'Salasana on liian heikko.',
user_exists: 'Käyttäjä on jo olemassa.',
username_exists: 'Käyttäjätunnus on jo olemassa.',
social_signup_needs_terms_acception:
'Ole hyvä ja hyväksy alla olevat käyttöehdot jatkaaksesi',
captcha_required: 'Kirjoita alla oleva koodi päättääksesi rekisteröinnin.'
social_signup_needs_terms_acception: 'Ole hyvä ja hyväksy alla olevat käyttöehdot jatkaaksesi'
}
},
success: {
Expand Down
1 change: 0 additions & 1 deletion src/i18n/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export default {
password_strength_error: 'La force du mot de passe est trop faible.',
user_exists: 'Cet utilisateur existe déjà.',
username_exists: 'Ce nom d’utilisateur existe déjà.',
captcha_required: 'Saisissez le code ci-dessous pour terminer votre inscription.',
social_signup_needs_terms_acception:
"Veuillez accepter les conditions d'utilisation ci-dessous pour continuer."
}
Expand Down
1 change: 0 additions & 1 deletion src/i18n/he.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export default {
password_strength_error: 'סיסמא חלשה מדי.',
user_exists: 'משתמש קיים במערכת.',
username_exists: 'שם המשתמש קיים במערכת.',
captcha_required: 'הזן את הקוד המופיע למטה כדי לסיים את ההרשמה.',
social_signup_needs_terms_acception: 'אנא הסכים לתנאי השירות שלהלן כדי להמשיך.'
}
},
Expand Down
1 change: 0 additions & 1 deletion src/i18n/hr.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ export default {
password_strength_error: 'Lozinka je preslaba.',
user_exists: 'Korisnik već postoji.',
username_exists: 'Korisničko ime već postoji.',
captcha_required: 'Unesite kôd prikazan dolje da biste se dovršili s prijavom.',
social_signup_needs_terms_acception: 'Prihvatite niže navedene Uvjete pružanja usluge.'
}
},
Expand Down
3 changes: 1 addition & 2 deletions src/i18n/hu.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ export default {
user_exists: 'A felhasználó már létezik.',
username_exists: 'A felhasználónév már foglalt.',
social_signup_needs_terms_acception:
'Kérjük, fogadd el a felhasználási feltételeket és az adatkezelési tájékoztatót a folytatáshoz.',
captcha_required: 'A regisztráció befejezéséhez írja be az alább látható kódot.'
'Kérjük, fogadd el a felhasználási feltételeket és az adatkezelési tájékoztatót a folytatáshoz.'
}
},
success: {
Expand Down
2 changes: 0 additions & 2 deletions src/i18n/id.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export default {
password_strength_error: 'Kata sandi terlalu lemah.',
user_exists: 'Pengguna sudah ada.',
username_exists: 'Nama pengguna sudah ada.',
captcha_required:
'Masukkan kode yang ditunjukkan di bawah ini untuk menyelesaikan pendaftaran.',
social_signup_needs_terms_acception:
'Harap setujui Persyaratan Layanan di bawah ini untuk melanjutkan.'
}
Expand Down
3 changes: 1 addition & 2 deletions src/i18n/it.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ export default {
user_exists: "L'utente esiste già.",
username_exists: 'Il nome utente esiste già.',
social_signup_needs_terms_acception:
'Si prega di accettare i Termini di servizio di seguito per continuare.',
captcha_required: 'Inserisci il codice mostrato di seguito per completare la registrazione.'
'Si prega di accettare i Termini di servizio di seguito per continuare.'
}
},
success: {
Expand Down
3 changes: 1 addition & 2 deletions src/i18n/ja.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ export default {
user_exists: 'すでに登録されているユーザーです。',
username_exists: 'すでに使用されているユーザー名です。',
social_signup_needs_terms_acception:
'サインアップするには以下の利用規約・プライバシーボリシーに同意してください。',
captcha_required: '以下のコードを入力して、サインアップを完了してください。'
'サインアップするには以下の利用規約・プライバシーボリシーに同意してください。'
}
},
success: {
Expand Down
Loading