Merge pull request #648 from andrewhayward/auth

Overhauling user sign-up flow
This commit is contained in:
Chris McAvoy 2013-06-19 12:29:49 -07:00
Родитель 710ae43ec7 a9dc9f3834
Коммит aa983d1db4
4 изменённых файлов: 85 добавлений и 19 удалений

Просмотреть файл

@ -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>&laquo; 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>&laquo; 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>