279 lines
11 KiB
JavaScript
279 lines
11 KiB
JavaScript
|
/**
|
||
|
* This router handles things related to the web browser experience...
|
||
|
*/
|
||
|
// This is the mock data we working with...
|
||
|
|
||
|
module.exports = function (options) {
|
||
|
const config = require('config');
|
||
|
var QRCode = require('qrcode');
|
||
|
var express = options.express;
|
||
|
|
||
|
const db = options.db;
|
||
|
const hdAuthUtil = options.hdAuthUtil;
|
||
|
|
||
|
var router = express.Router();
|
||
|
|
||
|
router.route('/')
|
||
|
.get(function(request, response, next) {
|
||
|
response.render("home", {
|
||
|
user: request.user,
|
||
|
pageTitle: "HDAuth - Account"
|
||
|
})
|
||
|
});
|
||
|
|
||
|
router.route('/authenticate')
|
||
|
.get(function(request, response, next) {
|
||
|
if(request.user) {
|
||
|
response.redirect('/account');
|
||
|
} else {
|
||
|
response.render("login-displayName", {
|
||
|
user: request.user,
|
||
|
pageTitle: "HDAuth - Login"
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
.post(function(request, response, next) {
|
||
|
if(request.user) {
|
||
|
response.redirect('/account');
|
||
|
} else {
|
||
|
db.User.findOne({
|
||
|
where: {
|
||
|
displayName: request.body.displayName
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
association: db.User.ExtendedPublicKeys,
|
||
|
required: true
|
||
|
}
|
||
|
]
|
||
|
}).then(user => {
|
||
|
if(user) {
|
||
|
// TODO: Support multiple login options...
|
||
|
const loginMessage = {
|
||
|
userIdentifier: user.displayName,
|
||
|
domainUrl: "sigidli.com" // TODO: Replace with config value...
|
||
|
}
|
||
|
const challenge = hdAuthUtil.createChallenge(
|
||
|
user.extendedPublicKeys[0].xpub,
|
||
|
JSON.stringify(loginMessage) // TODO: Create a login body...
|
||
|
)
|
||
|
QRCode.toDataURL(JSON.stringify(challenge), function (err, url) {
|
||
|
if(err) {
|
||
|
console.error(err);
|
||
|
}
|
||
|
response.render("xpub-login", {
|
||
|
// challenge user to sign thier xpub
|
||
|
challenge: challenge,
|
||
|
qrCode: url,
|
||
|
user: request.user
|
||
|
})
|
||
|
})
|
||
|
} else {
|
||
|
// User doesn't exist register account
|
||
|
response.render("login-signup", {
|
||
|
user: request.user,
|
||
|
displayName: request.body.displayName,
|
||
|
pageTitle: "HD Auth - Signup",
|
||
|
});
|
||
|
}
|
||
|
|
||
|
}).catch(error => {
|
||
|
console.error("Failed to fulfill account/authenticate post", request.body);
|
||
|
console.error("Reason: ", error);
|
||
|
|
||
|
response.render("error", {
|
||
|
message: "This site didn't have the time for error handling."
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
});
|
||
|
|
||
|
router.route('/authenticate/response')
|
||
|
.post(function(request, response, next) {
|
||
|
if(request.user) {
|
||
|
response.redirect('/account');
|
||
|
} else {
|
||
|
// Verify challenge
|
||
|
if(hdAuthUtil.verifyHDAuthChallengeResponse(request.body)) {
|
||
|
// user passed challenge...
|
||
|
var loginMessage = JSON.parse(request.body.message);
|
||
|
db.User.findOne({
|
||
|
where: {
|
||
|
displayName: loginMessage.userIdentifier,
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
association: db.User.ExtendedPublicKeys
|
||
|
}
|
||
|
]
|
||
|
}).then(user => {
|
||
|
if(user) {
|
||
|
// User created we can authenticate them on the site...
|
||
|
request.logIn(user, function(err) {
|
||
|
if (err) { return next(err); }
|
||
|
return response.redirect('/');
|
||
|
});
|
||
|
} else {
|
||
|
console.error("Authenticated user doesn't exist: ", loginMessage);
|
||
|
}
|
||
|
}).catch(error => {
|
||
|
console.error("Failed to create authenticated user");
|
||
|
console.error("Error: ", error);
|
||
|
next(error);
|
||
|
})
|
||
|
} else {
|
||
|
// user failed challenge
|
||
|
console.error("User failed to authenticate");
|
||
|
// Create new challenge and try again...
|
||
|
return response.redirect('/authenticate');
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
router.route('/register')
|
||
|
.get(function(request, response, next) {
|
||
|
if(request.user) {
|
||
|
response.redirect('/account');
|
||
|
} else {
|
||
|
response.render("account-registration", {
|
||
|
user: request.user,
|
||
|
newUser: {},
|
||
|
pageTitle: "HDAuth - Registration"
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
|
||
|
router.route('/register/xpub')
|
||
|
.post(function(request, response, next) {
|
||
|
if(request.user) {
|
||
|
response.redirect('/account');
|
||
|
} else {
|
||
|
db.User.build({
|
||
|
displayName: request.body.displayName,
|
||
|
extendedPublicKeys: [
|
||
|
{
|
||
|
xpub: request.body.xpub
|
||
|
}
|
||
|
]
|
||
|
}, {
|
||
|
include: [
|
||
|
{
|
||
|
association: db.User.ExtendedPublicKeys
|
||
|
}
|
||
|
]
|
||
|
}).validate()
|
||
|
.then(xpubUser => {
|
||
|
if (xpubUser) {
|
||
|
// Challenge
|
||
|
const registerationMessage = {
|
||
|
userIdentifier: xpubUser.displayName, // identifier the user supplies on the login page
|
||
|
user: xpubUser,
|
||
|
serviceExtendedPublicKey: config.get("bip32.serviceAuthenticatingExtendedPublicKey"),
|
||
|
url: "sigidli.com"
|
||
|
}
|
||
|
const challenge = hdAuthUtil.createChallenge(
|
||
|
request.body.xpub, // update this to identifier...
|
||
|
JSON.stringify(registerationMessage)
|
||
|
)
|
||
|
QRCode.toDataURL(JSON.stringify(challenge), function (err, url) {
|
||
|
if(err) {
|
||
|
console.error(err);
|
||
|
}
|
||
|
response.render("xpub-account-registeration-challenge", {
|
||
|
xpubUser: xpubUser,
|
||
|
// challenge user to sign thier xpub
|
||
|
challenge: challenge,
|
||
|
qrCode: url,
|
||
|
user: request.user
|
||
|
})
|
||
|
})
|
||
|
|
||
|
} else {
|
||
|
console.log("Empty User")
|
||
|
|
||
|
// TODO: error handling..
|
||
|
response.render("error", {
|
||
|
user: request.user,
|
||
|
message: "VOID"
|
||
|
})
|
||
|
}
|
||
|
}).catch(error => {
|
||
|
console.error("Failed to create user");
|
||
|
console.error("Reason: ", error);
|
||
|
|
||
|
// TODO: error handling..
|
||
|
response.render("error", {
|
||
|
user: request.user,
|
||
|
message: "Failed to create user"
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
|
||
|
router.route('/register/xpub/response')
|
||
|
.post(function(request, response, next) {
|
||
|
if(request.user) {
|
||
|
response.redirect('/account');
|
||
|
} else {
|
||
|
// Verify challenge
|
||
|
if(hdAuthUtil.verifyHDAuthChallengeResponse(request.body)) {
|
||
|
// user passed challenge...
|
||
|
// TODO: Load registration request from challenge.message
|
||
|
// TODO: build and validate that user owns xpub...
|
||
|
var xpubUser = JSON.parse(request.body.message).user;
|
||
|
// Possibility that username is taken...
|
||
|
// TODO: Create user without username
|
||
|
db.User.create(xpubUser, {
|
||
|
include: [
|
||
|
{
|
||
|
association: db.User.ExtendedPublicKeys
|
||
|
}
|
||
|
]
|
||
|
}).then(user => {
|
||
|
if(user) {
|
||
|
// User created we can authenticate them on the site...
|
||
|
request.logIn(user, function(err) {
|
||
|
if (err) { return next(err); }
|
||
|
return response.redirect('/');
|
||
|
});
|
||
|
}
|
||
|
}).catch(error => {
|
||
|
console.error("Failed to create authenticated user");
|
||
|
console.error("Error: ", error);
|
||
|
next(error);
|
||
|
})
|
||
|
} else {
|
||
|
// user failed challenge
|
||
|
// TODO: Validate input
|
||
|
// TODO: Createa new challenge
|
||
|
console.error("User failed to authenticate");
|
||
|
// Create new challenge and try again...
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
router.route('/logout')
|
||
|
.post(function(request, response, next) {
|
||
|
if(request.user) {
|
||
|
request.logout();
|
||
|
response.redirect('/');
|
||
|
|
||
|
// db.Session.destroy({
|
||
|
// where: {
|
||
|
// sid: request.sessionID
|
||
|
// }
|
||
|
// }).then(() => {
|
||
|
// console.log("")
|
||
|
// }).catch(error => {
|
||
|
// next(error);
|
||
|
// console.error("Log out error: ", error);
|
||
|
// })
|
||
|
} else {
|
||
|
// No user...
|
||
|
response.redirect('/');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// TODO: add other endpoints
|
||
|
return router;
|
||
|
};
|