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

An option to hide username in signup view #1954

Merged
merged 4 commits into from
Jan 5, 2021
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ var options = {
- **prefill {Object}**: Allows you to set the initial value for the _email_ and/or _username_ inputs, e.g. `{prefill: {email: "someone@auth0.com", username: "someone"}}`. When omitted no initial value will be provided.
- **signUpLink {String}**: URL for a page that allows the user to sign up. When set to a non-empty string, the user will be linked to the provided URL when clicking the _sign up_ tab in the _login screen_.
- **usernameStyle {String}**: Determines what will be used to identify the user for a Database connection that has the `requires_username` flag set, otherwise it will be ignored. Possible values are `"username"` and `"email"` and by default both `username` and `email` are allowed.
- **signUpHideUsernameField {Boolean}**: When set to `true` hides the _username_ input during sign up for a Database connection that has the `requires_username` flag set. Defaults to `false`.

#### Enterprise options

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SignUpPane onlyEmail is false hide UsernamePane when databaseConnectionRequiresUsername is true and signUpHideUsernameField is true 1`] = `
<div>
<div
data-__type="email_pane"
data-i18n={
Object {
"html": [Function],
"str": [Function],
}
}
data-lock="model"
data-placeholder="emailInputPlaceholder"
data-strictValidation={true}
/>
</div>
`;

exports[`SignUpPane onlyEmail is false shows PasswordPane 1`] = `
<div>
<div
Expand Down Expand Up @@ -30,7 +47,7 @@ exports[`SignUpPane onlyEmail is false shows PasswordPane 1`] = `
</div>
`;

exports[`SignUpPane onlyEmail is false shows UsernamePane when databaseConnectionRequiresUsername is true 1`] = `
exports[`SignUpPane onlyEmail is false shows UsernamePane when databaseConnectionRequiresUsername is true and signUpHideUsernameField is false 1`] = `
<div>
<div
data-__type="email_pane"
Expand Down
10 changes: 9 additions & 1 deletion src/__tests__/engine/classic/sign_up_pane.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,19 @@ describe('SignUpPane', () => {

expectComponent(<Component {...defaultProps} onlyEmail={false} />).toMatchSnapshot();
});
it('shows UsernamePane when databaseConnectionRequiresUsername is true', () => {
it('shows UsernamePane when databaseConnectionRequiresUsername is true and signUpHideUsernameField is false', () => {
require('connection/database/index').databaseConnectionRequiresUsername = () => true;
require('connection/database/index').signUpHideUsernameField = () => false;
const Component = getComponent();

expectComponent(<Component {...defaultProps} onlyEmail={false} />).toMatchSnapshot();
});
it('hide UsernamePane when databaseConnectionRequiresUsername is true and signUpHideUsernameField is true', () => {
require('connection/database/index').databaseConnectionRequiresUsername = () => true;
require('connection/database/index').signUpHideUsernameField = () => true;
const Component = getComponent();

expectComponent(<Component {...defaultProps} />).toMatchSnapshot();
});
});
});
28 changes: 25 additions & 3 deletions src/connection/database/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import { closeLock, logIn as coreLogIn, logInSuccess, validateAndSubmit } from '
import * as l from '../../core/index';
import * as c from '../../field/index';
import {
databaseConnection,
databaseConnectionName,
databaseConnectionRequiresUsername,
databaseLogInWithEmail,
hasScreen,
setScreen,
shouldAutoLogin,
toggleTermsAcceptance as internalToggleTermsAcceptance,
additionalSignUpFields
additionalSignUpFields,
signUpHideUsernameField
} from './index';
import * as i18n from '../../i18n';

Expand Down Expand Up @@ -53,10 +55,24 @@ export function logIn(id, needsMFA = false) {
});
}

function generateRandomUsername(length) {
let result = '';
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}

export function signUp(id) {
const m = read(getEntity, 'lock', id);
const fields = ['email', 'password'];
if (databaseConnectionRequiresUsername(m)) fields.push('username');

// Skip the username validation if signUpHideUsernameField option is enabled.
// We will generate a random username to avoid name collusion before we make the signup API call.
if (databaseConnectionRequiresUsername(m) && !signUpHideUsernameField(m)) fields.push('username');

additionalSignUpFields(m).forEach(x => fields.push(x.get('name')));

validateAndSubmit(id, fields, m => {
Expand All @@ -73,7 +89,13 @@ export function signUp(id) {
}

if (databaseConnectionRequiresUsername(m)) {
params.username = c.getFieldValue(m, 'username');
if (signUpHideUsernameField(m)) {
const usernameValidation = databaseConnection(m).getIn(['validation', 'username']);
const range = usernameValidation ? usernameValidation.toJS() : { max: 15 };
params.username = generateRandomUsername(range.max);
} else {
params.username = c.getFieldValue(m, 'username');
}
}

if (!additionalSignUpFields(m).isEmpty()) {
Expand Down
14 changes: 12 additions & 2 deletions src/connection/database/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ function processDatabaseOptions(opts) {
showTerms,
signUpLink,
usernameStyle,
signUpFieldsStrictValidation
signUpFieldsStrictValidation,
signUpHideUsernameField
} = opts;

let { initialScreen, screens } = processScreenOptions(opts);
Expand Down Expand Up @@ -96,6 +97,10 @@ function processDatabaseOptions(opts) {
signUpFieldsStrictValidation = false;
}

if (!assertMaybeBoolean(opts, 'signUpHideUsernameField')) {
signUpHideUsernameField = false;
}

if (!assertMaybeArray(opts, 'additionalSignUpFields')) {
additionalSignUpFields = undefined;
} else if (additionalSignUpFields) {
Expand Down Expand Up @@ -259,7 +264,8 @@ function processDatabaseOptions(opts) {
screens,
signUpLink,
usernameStyle,
signUpFieldsStrictValidation
signUpFieldsStrictValidation,
signUpHideUsernameField
})
.filter(x => typeof x !== 'undefined')
.toJS();
Expand Down Expand Up @@ -456,6 +462,10 @@ export function signUpFieldsStrictValidation(m) {
return get(m, 'signUpFieldsStrictValidation', false);
}

export function signUpHideUsernameField(m) {
return get(m, 'signUpHideUsernameField', false);
}

export function mustAcceptTerms(m) {
return get(m, 'mustAcceptTerms', false);
}
Expand Down
5 changes: 3 additions & 2 deletions src/engine/classic/sign_up_pane.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
additionalSignUpFields,
databaseConnectionRequiresUsername,
passwordStrengthPolicy,
signUpFieldsStrictValidation
signUpFieldsStrictValidation,
signUpHideUsernameField
} from '../../connection/database/index';
import CaptchaPane from '../../field/captcha/captcha_pane';
import * as l from '../../core/index';
Expand All @@ -30,7 +31,7 @@ export default class SignUpPane extends React.Component {
const header = headerText && <p>{headerText}</p>;

const usernamePane =
!onlyEmail && databaseConnectionRequiresUsername(model) ? (
!onlyEmail && databaseConnectionRequiresUsername(model) && !signUpHideUsernameField(model) ? (
<UsernamePane
i18n={i18n}
lock={model}
Expand Down