Added authentication/verification flow to account creation

Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
James Ketr 2018-10-03 22:04:41 -07:00
parent 389185a59c
commit 0b12ac9d20
4 changed files with 120 additions and 44 deletions

View File

@ -28,7 +28,7 @@
return callback(this.responseText, this);
}
if (this.status == 200) {
if (this.status >= 200 && this.status < 300) {
return callback(undefined, this);
}
};

View File

@ -61,6 +61,11 @@
box-sizing: border-box;
}
#requestAccess paper-button,
#login paper-button {
margin-top: 1em;
}
#header {
padding: 0.5em;
background: #ddd;
@ -258,18 +263,42 @@
font-weight: bold;
}
#loginStatus {
padding: 1em;
border: 2px solid #444;
margin: 1.5em -0.5em;
color: #222;
box-sizing: border-box;
}
#loginStatus iron-icon {
margin-right: 1em;
min-width: 1.5em;
display: inline-block;
}
#loginStatus .title {
font-weight: bold;
line-height: 1.5em;
}
#loginStatus .status {
margin-top: 0.5em;
}
#requestAccess {
max-width: 60ex;
border: 1px solid #444;
box-sizing: border-box;
}
#requestAccess div > div {
#requestAccess .title {
padding: 0.5em;
background-color: #ddd;
}
#requestAccess .title {
background-color: #ddd;
#requestAccess #createButton {
margin-top: 1.5em;
}
</style>
@ -365,6 +394,13 @@
provide your email address, and tell me who in the extended Ketrenos
universe you know. If you're not a bot, I'll very likely give you access :)</p>
</div>
<div id="loginStatus" hidden$="[[!loginStatus]]" class="layout vertical justified start">
<div class="layout horizontal center">
<iron-icon icon="info-outline"></iron-icon>
<div class="title self-start">[[loginStatusTitle]]</div>
</div>
<div class="status self-start">[[loginStatus]]</div>
</div>
<paper-input tabindex=0 autofocus id="username" label="User ID" value="{{username}}" on-keypress="enterCheck"></paper-input>
<paper-input tabindex=0 id="password" label="Password" type="password" value="{{password}}" on-keypress="enterCheck"></paper-input>
<paper-button tabindex=0 id="loginButton" disabled$="[[disableLogin(username,password)]]" on-tap="login" raised><div hidden$="[[loggingIn]]">login</div><div hidden$="[[!loggingIn]]"><paper-spinner active$="[[loggingIn]]"></paper-spinner></div></paper-button>
@ -383,15 +419,18 @@
<div class="layout vertical">
<div class="title">Create an account</div>
<div>
<p>To have your account activated, tell me who you know in the 'who do you know?' field.</p>
<p>Thanks,</p>
<p>James</p>
<p>To have your account activated, tell me who you know in the 'who do you know?' field. You will receive
an email with an authentication token; click the link in the email, and you're account will be verified. Once
verified, I can grant you access to the system.
</p>
<p>Thanks,<br>
James</p>
</div>
<paper-input tabindex=0 autofocus id="mail" label="E-mail" value="{{mail}}" on-keypress="enterCheck"></paper-input>
<paper-input tabindex=0 autofocus id="mail" label="E-mail" value="{{username}}" on-keypress="enterCheck"></paper-input>
<paper-input tabindex=0 id="password" label="Password" type="password" value="{{password}}" on-keypress="enterCheck"></paper-input>
<paper-input tabindex=0 id="name" label="Display name" value="{{name}}" on-keypress="enterCheck"></paper-input>
<paper-input tabindex=0 id="who" label="Who do you know?" value="{{who}}" on-keypress="enterCheck"></paper-input>
<paper-button tabindex=0 id="createButton" disabled$="[[disableCreate(mail,password,name,who)]]" on-tap="create" raised><div hidden$="[[loggingIn]]">create</div><div hidden$="[[!loggingIn]]"><paper-spinner active$="[[loggingIn]]"></paper-spinner></div></paper-button>
<paper-button tabindex=0 id="createButton" disabled$="[[disableCreate(username,password,name,who)]]" on-tap="create" raised><div hidden$="[[loggingIn]]">create</div><div hidden$="[[!loggingIn]]"><paper-spinner active$="[[loggingIn]]"></paper-spinner></div></paper-button>
</div>
</paper-dialog>
<paper-toast id="toast"></paper-toast>
@ -409,6 +448,10 @@
type: String,
value: ""
},
loginStatus: {
type: String,
value: ""
},
username: {
type: String,
value: ""
@ -417,10 +460,6 @@
type: String,
value: ""
},
mail: {
type: String,
value: ""
},
years: {
type: Array,
value: []
@ -484,8 +523,8 @@
return !username || username == "" || !password || password == "";
},
disableCreate: function(mail, password, name, who) {
return !mail || mail == "" ||
disableCreate: function(username, password, name, who) {
return !username || username == "" ||
!password || password == "" ||
!name || name == "" ||
!who || who == "";
@ -493,8 +532,16 @@
enterCheck: function(event) {
if (event.key == 'Enter') {
var next = event.currentTarget.nextElementSibling;
event.preventDefault();
var next = event.currentTarget.nextElementSibling;
while (next && !next.hasAttribute("tabindex")) {
next = event.currentTarget.nextElementSibling;
}
if (!next) {
return;
}
if (next.tagName.toLowerCase() == "paper-button") {
if (!next.disabled) {
next.click();
@ -542,7 +589,7 @@
window.fetch("api/v1/users/login", function(error, xhr) {
this.loggingIn = false;
this.loading = false;
this.password = "";
// this.password = "";
var user;
if (error) {
@ -566,9 +613,7 @@
return;
}
if (user && user.username) {
this.user = user;
}
this.user = user;
}.bind(this), null, "POST", { u: this.username, p: this.password });
},
@ -582,7 +627,7 @@
window.fetch("api/v1/users/create", function(error, xhr) {
this.loggingIn = false;
this.loading = false;
this.password = "";
// this.password = "";
var user;
this.$.requestAccess.close();
@ -615,7 +660,7 @@
w: this.who,
p: this.password,
n: this.name,
m: this.mail
m: this.username
});
},
@ -1255,10 +1300,29 @@
this.resetPhotos();
this.path = "";
if (user) {
this.mode = "memories";
} else {
if (!user) {
this.mode = "login";
this.loginStatus = null;
return;
}
if (user.authenticated && user.mailVerified) {
this.loginStatus = null;
this.mode = "memories";
return;
}
this.mode = "login";
if (!user.mailVerified) {
this.loginStatusTitle = "Account not verified";
this.loginStatus = "An email has been sent to " + user.mail + ". " +
"Click the link in that email to verify your email address.";
} else if (!user.authenticated) {
this.loginStatusTitle = "Account not authorized";
this.loginStatus = "Your email address has been verified. Next, James needs to authorize your account. " +
"He has received an email and will process the request as quickly as he can.";
}
},

View File

@ -149,6 +149,7 @@ app.use(basePath, function(req, res, next) {
if (results.length == 0) {
throw "DB mis-match between authentications and users table";
}
let user = results[0],
envelope = {
to: config.get("admin.mail"),
@ -160,6 +161,14 @@ app.use(basePath, function(req, res, next) {
html: hb.compile(templates.html)(user)
};
req.session.user = {
name: user.displayName,
mail: user.mail,
username: user.uid,
authenticated: user.authenticated,
mailVerified: user.mailVerified
};
return new Promise(function (resolve, reject) {
let attempts = 10;

View File

@ -29,6 +29,8 @@ require("../db/users").then(function(db) {
});
router.get("/", function(req, res/*, next*/) {
console.log("/users");
if (req.session.user) {
return res.status(200).send(req.session.user);
}
@ -174,16 +176,14 @@ router.post("/create", function(req, res) {
send(envelope);
});
}).then(function() {
/*
req.session.user = {
name: name,
mail: mail,
username: username,
};
return res.status(200).send(req.session.user);
*/
req.session.user = {};
return res.status(401).send("Account has not been authenticated.");
req.session.user = {
name: name,
mail: mail,
username: mail,
authenticated: false,
mailVerified: false
};
return res.status(200).send(req.session.user);
});
});
});
@ -203,6 +203,7 @@ router.post("/login", function(req, res) {
return ldapPromise(username, password).then(function(user) {
user.authenticated = 1;
user.mailVerified = 1;
return user;
}).catch(function() {
console.log("User not found in LDAP. Looking up in DB.");
@ -226,20 +227,22 @@ router.post("/login", function(req, res) {
return res.status(401).send("Invalid login credentials");
}
if (!user.authenticated) {
console.log(username + " not authenticated.");
req.session.user = {};
return res.status(401).send("Account has not been authenticated.");
}
console.log("Logging in as " + user.displayName);
req.session.user = {
name: user.displayName,
mail: user.mail,
username: user.uid
username: user.uid,
authenticated: user.authenticated,
mailVerified: user.mailVerified
};
if (!user.mailVerified) {
console.log("Logged in as " + user.displayName + ", who is not verified email.");
} else if (!user.authenticated) {
console.log("Logged in as " + user.displayName + ", who is not authenticated.");
} else {
console.log("Logging in as " + user.displayName);
}
return res.status(200).send(req.session.user);
});
});