Confirm login and allow reset

This commit is contained in:
Jay McCarthy 2013-10-14 15:05:25 -06:00
parent 6380adeed3
commit c53fa19f1f
4 changed files with 115 additions and 76 deletions

View File

@ -116,45 +116,69 @@
['email email]
['passwd passwd]
['code email-code])
(define passwd-path (build-path users.new-path email))
(define (generate-a-code email)
(define correct-email-code
(number->string (random (expt 10 8))))
(hash-set! email-codes email correct-email-code)
correct-email-code)
(define (check-code-or true false)
(cond
[(and (not (string=? "" email-code))
(hash-ref email-codes email #f))
=> (λ (correct-email-code)
(cond
[(equal? correct-email-code email-code)
(display-to-file (bcrypt-encode (string->bytes/utf-8 passwd))
passwd-path
#:exists 'replace)
(hash-remove! email-codes email)
(true)]
[else
"wrong-code"]))]
[else
(false)
#f]))
(match (ensure-authenticate email passwd (λ () #t))
["failed" #f]
["new-user"
(define passwd-path (build-path users.new-path email))
(cond
[(and (not (string=? "" email-code))
(hash-ref email-codes email #f))
=> (λ (correct-email-code)
(cond
[(equal? correct-email-code email-code)
(when (not (file-exists? passwd-path))
(display-to-file (bcrypt-encode (string->bytes/utf-8 passwd))
passwd-path))
(hash-remove! email-codes email)
#t]
[else
"wrong-code"]))]
[else
(define correct-email-code
(number->string (random (expt 10 8))))
(hash-set! email-codes email correct-email-code)
["failed"
(check-code-or
(λ () (hasheq 'curation (curation-administrator? email)))
(λ ()
(send-mail-message
"pkg@racket-lang.org"
"Account confirmation for Racket PNR"
"Account password reset for Racket Package Catalog"
(list email)
empty empty
(list "Someone tried to register your email address for an account on the Racket Package Catalog."
"If you want to proceed, use this code:"
""
correct-email-code
""
"This code will expire, so if it is not available, you'll have to try to register again."))
"emailed"])]
(list
"Someone tried to login with your email address for an account on the Racket Package Catalog, but failed."
"If you this was you, please use this code to reset your password:"
""
(generate-a-code email)
""
"This code will expire, so if it is not available, you'll have to try to again."))))]
["new-user"
(check-code-or
(λ () #t)
(λ ()
(send-mail-message
"pkg@racket-lang.org"
"Account confirmation for Racket Package Catalog"
(list email)
empty empty
(list
"Someone tried to register your email address for an account on the Racket Package Catalog."
"If you want to proceed, use this code:"
""
(generate-a-code email)
""
"This code will expire, so if it is not available, you'll have to try to register again."))))]
[#t
(hasheq 'curation (curation-administrator? email))]))

View File

@ -19,15 +19,26 @@
<div id="login" class="package">
<table>
<tr><td>Email Address:</td><td><input id="login_email_text" type="text"></td></tr>
<tr><td id="login_passwd_label">Password:</td><td><input id="login_passwd_text" type="password"></td></tr>
<tr><td>Password:</td><td><input id="login_passwd_text" type="password"></td></tr>
<tr id="login_confirm_row"><td>Confirm Password:</td><td><input id="login_confirm_text" type="password"></td></tr>
<tr id="login_code_row"><td>Email Code:</td><td><input id="login_code_text" type="password"></td></tr>
<tr><td colspan="2" id="login_error"></td></tr>
</table>
<button id="login_button">Log In</button>
<p>If you enter an unclaimed email address, then an account will
be created with the password you type in, after you confirm
the email address.</p>
<p>Passwords are stored in the delicious bcrypt format, but
transferred as plain-text over an HTTPS connection.</p>
<p>If you enter an unclaimed email address, then we will email
you a code. If you type in that code and confirm the password
you typed in, then we will create an account for you with the
given password.</p>
<p>If you enter an claimed email address, but an incorrect
password, then we will email you a code. If you type in that
code and confirm the password you typed in, then we will change
your password to the one you typed in.</p>
<p>Passwords are transferred over an HTTPS connection, but not
the same connection you got this page from. The passwords are
transferred in plain-text, but stored on the server in the
delicious bcrypt format. This means that someone could hack
our server and watch you transmit your password live but not
be able to use our password database.</p>
</div>
<div id="package_info" class="package">

View File

@ -399,53 +399,57 @@ $( document ).ready(function() {
position: { my: "center", at: "center", of: "#search_menu" },
modal: true });
var saved_password = false;
function login_submit () {
$( "#login_error" ).html( "" );
var et = $( "#login_email_text" );
var pt = $( "#login_passwd_text" );
var e = $( "#login_email_text" ).val();
var p = $( "#login_passwd_text" ).val();
var cp = $( "#login_confirm_text" ).val();
var c = $( "#login_code_text" ).val();
var e = et.val();
var p;
var c;
if ( saved_password ) {
p = saved_password;
c = pt.val(); }
if ( c && p != cp ) {
$( "#login_error" ).html( "You did not type in the same password." ); }
else {
p = pt.val();
c = ""; }
$.getJSON( dynamic_url("/jsonp/authenticate"),
{ email: e, passwd: p, code: c },
function( resp ) {
if ( resp == "emailed" ) {
$( "#login_confirm_row" ).show();
$( "#login_code_row" ).show();
$.getJSON( dynamic_url("/jsonp/authenticate"),
{ email: e, passwd: p, code: c },
function( resp ) {
if ( resp == "emailed" ) {
saved_password = p;
$( "#login_passwd_label" ).html( "Code:" );
pt.val("");
$( "#login_error" ).html( "Check your email for an email code." ); }
else if ( resp == "wrong-code" ) {
pt.val("");
$( "#login_error" ).html( "That is not the correct code." ); }
else if ( resp ) {
$( "#login_passwd_label" ).html( "Password:" );
$( "#login_error" ).html( "Check your email for an email code." ); }
else if ( resp == "wrong-code" ) {
$( "#login_code_text" ).val("");
$( "#login_error" ).html( "That is not the correct code." ); }
else if ( resp ) {
$( "#login_email_text" ).val("");
$( "#login_passwd_text" ).val("");
$( "#login_confirm_text" ).val("");
$( "#login_code_text" ).val("");
et.val("");
pt.val("");
$( "#login_confirm_row" ).hide();
$( "#login_code_row" ).hide();
localStorage['email'] = e;
localStorage['passwd'] = p;
localStorage['email'] = e;
localStorage['passwd'] = p;
$( "#login" ).dialog( "close" );
$( "#login" ).dialog( "close" );
initial_login(); }
else {
pt.val("");
$( "#login_error" ).html( "Incorrect password, please retry" ); }; } ); }
initial_login(); }
else {
$( "#login_confirm_row" ).show();
$( "#login_code_row" ).show();
$( "#login_error" ).html( "Incorrect password, please retry or check your email for a change password code." ); }; } ); } }
$( "#login_passwd_text" ).keypress( function (e) {
if (e.which == 13) { login_submit (); } } );
$( "#login_code_text" ).keypress( function (e) {
if (e.which == 13) { login_submit (); } } );
$( "#login_button" ).click( function (e) { login_submit (); } );
$( "#login_confirm_row" ).hide();
$( "#login_code_row" ).hide();
function menu_logout () {
$("#logout").html( jslink( "login", function () { $( "#login" ).dialog( "open" ); } ) ); }
function menu_loggedin ( curate_p ) {

View File

@ -146,7 +146,7 @@ a.inactive {
a.possible {
}
#login table tr:nth-child(3) td {
#login table tr:nth-child(5) td {
text-align: center;
color: red;
}