mgebbe@0: // index.js
mgebbe@0: //
mgebbe@0: // Most of the routes in the application
mgebbe@0: //
mgebbe@0: // Copyright 2013, E14N https://e14n.com/
mgebbe@0: //
mgebbe@0: // Licensed under the Apache License, Version 2.0 (the "License");
mgebbe@0: // you may not use this file except in compliance with the License.
mgebbe@0: // You may obtain a copy of the License at
mgebbe@0: //
mgebbe@0: //     http://www.apache.org/licenses/LICENSE-2.0
mgebbe@0: //
mgebbe@0: // Unless required by applicable law or agreed to in writing, software
mgebbe@0: // distributed under the License is distributed on an "AS IS" BASIS,
mgebbe@0: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mgebbe@0: // See the License for the specific language governing permissions and
mgebbe@0: // limitations under the License.
mgebbe@0: 
mgebbe@0: var wf = require("webfinger"),
mgebbe@0:     async = require("async"),
mgebbe@0:     _ = require("underscore"),
mgebbe@0:     uuid = require("node-uuid"),
mgebbe@0:     User = require("../models/user"),
mgebbe@0:     Host = require("../models/host"),
mgebbe@0:     RequestToken = require("../models/requesttoken"),
mgebbe@0:     RememberMe = require("../models/rememberme"),
mgebbe@0:     site = require("../models/site");
mgebbe@0: 
mgebbe@0: exports.hostmeta = function(req, res) {
mgebbe@0:     res.json({
mgebbe@0:         links: [
mgebbe@0:             {
mgebbe@0:                 rel: "dialback",
mgebbe@0:                 href: site.url("/dialback")
mgebbe@0:             }
mgebbe@0:         ]
mgebbe@0:     });
mgebbe@0: };
mgebbe@0: 
mgebbe@0: exports.index = function(req, res, next) {
mgebbe@0:     var hosts, users, bank = Host.bank();
mgebbe@0: 
mgebbe@0:     if (req.user) {
mgebbe@0:         res.render('index', { pageTitle: "pumpbridge" , user: req.user});
mgebbe@0:     } else {
mgebbe@0:         res.render('login', { pageTitle: "pumpbridge" });
mgebbe@0:     }
mgebbe@0: };
mgebbe@0: 
mgebbe@0: exports.about = function(req, res) {
mgebbe@0:     res.render('about', { pageTitle: "About" });
mgebbe@0: };
mgebbe@0: 
mgebbe@0: exports.login = function(req, res) {
mgebbe@0:     res.render('login', { pageTitle: "Login" });
mgebbe@0: };
mgebbe@0: 
mgebbe@0: exports.handleLogin = function(req, res, next) {
mgebbe@0: 
mgebbe@0:     var id = req.body.webfinger,
mgebbe@0:         rememberme = req.body.rememberme,
mgebbe@0:         hostname = User.getHostname(id),
mgebbe@0:         host;
mgebbe@0: 
mgebbe@0:     req.log.debug(req.body, "Handling login");
mgebbe@0: 
mgebbe@0:     async.waterfall([
mgebbe@0:         function(callback) {
mgebbe@0:             Host.ensureHost(hostname, callback);
mgebbe@0:         },
mgebbe@0:         function(results, callback) {
mgebbe@0:             host = results;
mgebbe@0:             host.getRequestToken(callback);
mgebbe@0:         }
mgebbe@0:     ], function(err, rt) {
mgebbe@0:         if (err) {
mgebbe@0:             if (err instanceof Error) {
mgebbe@0:                 next(err);
mgebbe@0:             } else if (err.data) {
mgebbe@0:                 next(new Error(err.data));
mgebbe@0:             }
mgebbe@0:         } else {
mgebbe@0:             // Remember if the user asked for a rememberme cookie
mgebbe@0:             req.session.remembermeChecked = (rememberme == "on");
mgebbe@0:             res.redirect(host.authorizeURL(rt));
mgebbe@0:         }
mgebbe@0:     });
mgebbe@0: };
mgebbe@0: 
mgebbe@0: exports.authorized = function(req, res, next) {
mgebbe@0: 
mgebbe@0:     var hostname = req.params.hostname,
mgebbe@0:         token = req.query.oauth_token,
mgebbe@0:         verifier = req.query.oauth_verifier,
mgebbe@0:         rt,
mgebbe@0:         host,
mgebbe@0:         access_token,
mgebbe@0:         token_secret,
mgebbe@0:         id,
mgebbe@0:         object,
mgebbe@0:         user,
mgebbe@0:         newUser = false;
mgebbe@0: 
mgebbe@0:     async.waterfall([
mgebbe@0:         function(callback) {
mgebbe@0:             async.parallel([
mgebbe@0:                 function(callback) {
mgebbe@0:                     RequestToken.get(RequestToken.key(hostname, token), callback);
mgebbe@0:                 },
mgebbe@0:                 function(callback) {
mgebbe@0:                     Host.get(hostname, callback);
mgebbe@0:                 }
mgebbe@0:             ], callback);
mgebbe@0:         },
mgebbe@0:         function(results, callback) {
mgebbe@0:             rt = results[0];
mgebbe@0:             host = results[1];
mgebbe@0:             host.getAccessToken(rt, verifier, callback);
mgebbe@0:         },
mgebbe@0:         function(token, secret, extra, callback) {
mgebbe@0:             access_token = token;
mgebbe@0:             token_secret = secret;
mgebbe@0:             async.parallel([
mgebbe@0:                 function(callback) {
mgebbe@0:                     rt.del(callback);
mgebbe@0:                 },
mgebbe@0:                 function(callback) {
mgebbe@0:                     host.whoami(access_token, token_secret, callback);
mgebbe@0:                 }
mgebbe@0:             ], callback);
mgebbe@0:         },
mgebbe@0:         function(results, callback) {
mgebbe@0:             object = results[1];
mgebbe@0:             id = object.id;
mgebbe@0:             if (id.substr(0, 5) == "acct:") {
mgebbe@0:                 id = id.substr(5);
mgebbe@0:             }
mgebbe@0:             User.get(id, function(err, user) {
mgebbe@0:                 if (err && err.name === "NoSuchThingError") {
mgebbe@0:                     newUser = true;
mgebbe@0:                     User.fromPerson(object, access_token, token_secret, callback);
mgebbe@0:                 } else if (err) {
mgebbe@0:                     callback(err, null);
mgebbe@0:                 } else {
mgebbe@0:                     callback(null, user);
mgebbe@0:                 }
mgebbe@0:             });
mgebbe@0:         },
mgebbe@0:         function(results, callback) {
mgebbe@0:             user = results;
mgebbe@0:             if (req.session.remembermeChecked) {
mgebbe@0:                 req.log.debug("Setting rememberme cookie");
mgebbe@0:                 RememberMe.create({user: user.id}, function(err, rm) {
mgebbe@0:                     if (err) {
mgebbe@0:                         callback(err);
mgebbe@0:                     } else {
mgebbe@0:                         req.log.debug({rm: rm}, "Created rememberme record");
mgebbe@0:                         res.cookie("rememberme", rm.uuid, {path: "/", expires: new Date(Date.now() + 180 * 24 * 60 * 60 * 1000), httpOnly: true});
mgebbe@0:                         req.log.debug({rememberme: rm.uuid}, "Set rememberme cookie");
mgebbe@0:                         callback(null);
mgebbe@0:                     }
mgebbe@0:                 });
mgebbe@0:             } else {
mgebbe@0:                 callback(null);
mgebbe@0:             }
mgebbe@0:         }
mgebbe@0:     ], function(err) {
mgebbe@0:         if (err) {
mgebbe@0:             next(err);
mgebbe@0:         } else {
mgebbe@0:             req.session.userID = user.id;
mgebbe@0:             delete req.session.remembermeChecked;
mgebbe@0:             res.redirect("/");
mgebbe@0:         }
mgebbe@0:     });
mgebbe@0: };
mgebbe@0: 
mgebbe@0: exports.handleLogout = function(req, res) {
mgebbe@0: 
mgebbe@0:     delete req.session.userID;
mgebbe@0:     delete req.session.remembermeChecked;
mgebbe@0:     delete req.user;
mgebbe@0: 
mgebbe@0:     res.clearCookie("rememberme");
mgebbe@0: 
mgebbe@0:     res.redirect("/", 303);
mgebbe@0: };