зеркало из https://github.com/mozilla/CSOL-site.git
Merge pull request #648 from andrewhayward/auth
Overhauling user sign-up flow
This commit is contained in:
Коммит
aa983d1db4
|
@ -184,6 +184,16 @@ function processInitialLearnerSignup (req, res, next) {
|
||||||
res.render('auth/signup.html', signup);
|
res.render('auth/signup.html', signup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function finish (user) {
|
||||||
|
signup.state = user.underage ? 'child' : 'more';
|
||||||
|
signup.profileId = user.id;
|
||||||
|
signup.passwordGenerated = false;
|
||||||
|
signup.password = signup.generatedPassword = generatePassword();
|
||||||
|
|
||||||
|
req.session.signup = signup;
|
||||||
|
res.redirect(303, '/signup');
|
||||||
|
}
|
||||||
|
|
||||||
var errors = [];
|
var errors = [];
|
||||||
|
|
||||||
var isValidUsername = validateUsername(signup.username);
|
var isValidUsername = validateUsername(signup.username);
|
||||||
|
@ -207,25 +217,37 @@ function processInitialLearnerSignup (req, res, next) {
|
||||||
// race conditions on usernames - even if the username does not exist now, it may
|
// race conditions on usernames - even if the username does not exist now, it may
|
||||||
// well have been created by the time sign-up is complete.
|
// well have been created by the time sign-up is complete.
|
||||||
// This will fail if the username is already being used
|
// This will fail if the username is already being used
|
||||||
learners.create({
|
learners.find({where: {username: normalizedUsername}})
|
||||||
username: normalizedUsername,
|
.error(fail)
|
||||||
password: '',
|
.success(function(user) {
|
||||||
underage: underage,
|
if (!user) {
|
||||||
birthday: birthday
|
if (signup.profileId) {
|
||||||
})
|
// Releasing previous user profile, which they might have created if
|
||||||
.error(function(err) {
|
// they've gone backwards in the sign-up process and started with
|
||||||
// Did try a `findOrCreate`, but couldn't get `isNewRecord` to work
|
// another username
|
||||||
if (err.code === 'ER_DUP_ENTRY')
|
learners.find(signup.profileId).success(function(profile) {
|
||||||
|
if (profile && !profile.complete)
|
||||||
|
profile.destroy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return learners.create({
|
||||||
|
username: normalizedUsername,
|
||||||
|
password: '',
|
||||||
|
underage: underage,
|
||||||
|
birthday: birthday
|
||||||
|
}).error(fail).success(finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.id !== signup.profileId)
|
||||||
return fail(new FieldError('username', 'This username is already in use'));
|
return fail(new FieldError('username', 'This username is already in use'));
|
||||||
|
|
||||||
return fail(err);
|
user.updateAttributes({
|
||||||
})
|
underage: underage,
|
||||||
.success(function(user) {
|
birthday: birthday
|
||||||
signup.state = underage ? 'child' : 'more';
|
}).error(fail).success(function() {
|
||||||
signup.passwordGenerated = false;
|
finish(user);
|
||||||
signup.password = signup.generatedPassword = generatePassword();
|
});
|
||||||
req.session.signup = signup;
|
|
||||||
res.redirect(303, '/signup');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,6 +756,9 @@ module.exports = function (app) {
|
||||||
if (signup.state === 'more')
|
if (signup.state === 'more')
|
||||||
return res.render('auth/signup-next.html', signup);
|
return res.render('auth/signup-next.html', signup);
|
||||||
|
|
||||||
|
if (signup.state === 'initial')
|
||||||
|
return res.render('auth/signup.html', signup);
|
||||||
|
|
||||||
req.session.signup = signup = {
|
req.session.signup = signup = {
|
||||||
example: usernames.generate()
|
example: usernames.generate()
|
||||||
};
|
};
|
||||||
|
@ -744,6 +769,37 @@ module.exports = function (app) {
|
||||||
app.post('/signup', function (req, res, next) {
|
app.post('/signup', function (req, res, next) {
|
||||||
var signup = req.session.signup || {};
|
var signup = req.session.signup || {};
|
||||||
|
|
||||||
|
if (req.body['action'] === 'go-back') {
|
||||||
|
var form = req.body;
|
||||||
|
|
||||||
|
'first_name' in form && (signup.first_name = (form.first_name||'').trim());
|
||||||
|
'last_name' in form && (signup.last_name = (form.last_name||'').trim());
|
||||||
|
'email' in form && (signup.email = (form.email||'').trim());
|
||||||
|
'parent_email' in form && (signup.parent_email = (form.parent_email||'').trim());
|
||||||
|
|
||||||
|
'school' in form && (signup.school = (form.school||'').trim());
|
||||||
|
'studentId' in form && (signup.studentId = (form.studentId||'').trim());
|
||||||
|
'gender' in form && (signup.gender = form.gender || null);
|
||||||
|
'raceEthnicity' in form && (signup.raceEthnicity = form.raceEthnicity);
|
||||||
|
'zipCode' in form && (signup.zipCode = (form.zipCode||'').trim());
|
||||||
|
|
||||||
|
signup.state = 'initial';
|
||||||
|
|
||||||
|
req.session.signup = signup;
|
||||||
|
return res.redirect('/signup');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.body['action'] === 'restart') {
|
||||||
|
return learners.find(signup.profileId)
|
||||||
|
.complete(function(err, profile) {
|
||||||
|
if (profile && !profile.complete)
|
||||||
|
profile.destroy();
|
||||||
|
|
||||||
|
delete req.session.signup;
|
||||||
|
return res.redirect('/signup');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (signup.state === 'child')
|
if (signup.state === 'child')
|
||||||
return processChildLearnerSignup(req, res, next);
|
return processChildLearnerSignup(req, res, next);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form class="form-horizontal row-fluid" method="post">
|
<form class="form-horizontal row-fluid" method="post">
|
||||||
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
|
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
|
||||||
|
<button class="btn btn-link pull-left" name="action" value="go-back" formnovalidate>« Go Back</button>
|
||||||
|
<button class="btn pull-right" name="action" value="restart" formnovalidate>Restart</button>
|
||||||
|
<br><br>
|
||||||
<fieldset class="span12 well">
|
<fieldset class="span12 well">
|
||||||
<div class="control-group {{ _fields.first_name.state }} {{ _fields.last_name.state }}">
|
<div class="control-group {{ _fields.first_name.state }} {{ _fields.last_name.state }}">
|
||||||
<label class="control-label" for="input-email">Your Name</label>
|
<label class="control-label" for="input-email">Your Name</label>
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form class="form-horizontal row-fluid" method="post">
|
<form class="form-horizontal row-fluid" method="post">
|
||||||
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
|
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
|
||||||
|
<button class="btn btn-link pull-left" name="action" value="go-back" formnovalidate>« Go Back</button>
|
||||||
|
<button class="btn pull-right" name="action" value="restart" formnovalidate>Restart</button>
|
||||||
|
<br><br>
|
||||||
<fieldset class="span12 well">
|
<fieldset class="span12 well">
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<div class="controls"><small><em>Fields marked * are optional</em></small></div>
|
<div class="controls"><small><em>Fields marked * are optional</em></small></div>
|
||||||
|
@ -88,6 +91,10 @@
|
||||||
{{ ethnicity }}
|
{{ ethnicity }}
|
||||||
</label>
|
</label>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" id="input-ethnicity" name="raceEthnicity" value=""{% if not raceEthnicity %} checked{% endif %}>
|
||||||
|
<i>Don't want to say</i>
|
||||||
|
</label>
|
||||||
|
|
||||||
{% if _fields.raceEthnicity.message -%}
|
{% if _fields.raceEthnicity.message -%}
|
||||||
<span class="help-block message"><strong><em>{{ _fields.raceEthnicity.message }}</em></strong></span>
|
<span class="help-block message"><strong><em>{{ _fields.raceEthnicity.message }}</em></strong></span>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<div class="control-group {{ _fields.birthday.state }}">
|
<div class="control-group {{ _fields.birthday.state }}">
|
||||||
<label class="control-label" for="input-birthday-month">Birthday</label>
|
<label class="control-label" for="input-birthday-month">Birthday</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<select id="input-birthday-month" name="birthday_month" class="input-small" required="required">
|
<select id="input-birthday-month" name="birthday_month" class="input-medium" required="required">
|
||||||
<option></option>
|
<option></option>
|
||||||
{% for month in months %}
|
{% for month in months %}
|
||||||
<option value="{{ loop.index }}"{% if birthday_month == loop.index %} selected="selected"{% endif %}>{{ month }}</option>
|
<option value="{{ loop.index }}"{% if birthday_month == loop.index %} selected="selected"{% endif %}>{{ month }}</option>
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
<option{% if birthday_day == day %} selected="selected"{% endif %}>{{ day }}</option>
|
<option{% if birthday_day == day %} selected="selected"{% endif %}>{{ day }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<select id="input-birthday-year" name="birthday_year" class="input-mini" required="required">
|
<select id="input-birthday-year" name="birthday_year" class="input-small" required="required">
|
||||||
<option></option>
|
<option></option>
|
||||||
{% for year in range(2012, 1979, (-1)) %}
|
{% for year in range(2012, 1979, (-1)) %}
|
||||||
<option {% if birthday_year == year %} selected="selected"{% endif %}>{{ year }}</option>
|
<option {% if birthday_year == year %} selected="selected"{% endif %}>{{ year }}</option>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче