Skip to content

Commit

Permalink
Picking this back up
Browse files Browse the repository at this point in the history
  • Loading branch information
potatono committed Jan 1, 2013
1 parent d7ca2b2 commit 2c2533e
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 42 deletions.
13 changes: 8 additions & 5 deletions app.js
Expand Up @@ -3,14 +3,14 @@
* Module dependencies.
*/

var express = require('express')
var config = require('./config')
, express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, login = require('./routes/login')
, http = require('http')
, path = require('path')
, auth = require('connect-auth')
, config = require('./config');
, auth = require('connect-auth');

var app = express();

Expand Down Expand Up @@ -44,10 +44,13 @@ app.configure('development', function(){
app.get('/', routes.index);
app.get('/users', user.list);
app.get('/login', login.index);
app.get('/login/local', login.local);
app.post('/login/signup', login.signup);
app.post('/login/signin', login.signin);
app.get('/login/facebook', login.facebook);
app.get('/login/twitter', login.twitter);
app.get('/login/check-username/:username', login.checkUsername);
app.get('/login/check-email/:email', login.checkEmail);

http.createServer(app).listen(app.get('port'), function(){
http.createServer(app).listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
11 changes: 0 additions & 11 deletions lib/linkfilter/model/credential.js

This file was deleted.

12 changes: 0 additions & 12 deletions lib/linkfilter/model/user.js

This file was deleted.

51 changes: 51 additions & 0 deletions models/credentials.js
@@ -0,0 +1,51 @@
var schema = require("linkfilter/model/schema"),
users = require("linkfilter/model/users"),
bcrypt = require("bcrypt"),
async = require("async");

var credentials = schema.define('credentials', {
method: { type: String, length: 25, index: true },
secret: { type: String, length: 100 }
});

users.hasMany(credentials, { as: 'credentials', foreignKey: 'users_id' });
credentials.belongsTo(users, { as: 'user', foreignKey: 'users_id' });

credentials.findByMethodSecret = function(method, secret, cb) {
async.waterfall([
function(cb) {
bcrypt.hash(secret, 10, cb);
},

function(hash, cb) {
credentials.all({ 'where': { 'method': method, 'secret': hash } }, cb);
}
],

cb);
};

credentials.ensureUser = function(username, email, method, secret, cb) {
console.log("in ensure user");
async.waterfall([
function(cb) {
credentials.findByMethodSecret(method, secret, cb);
},

function(credentials, cb) {
if (credentials.length == 0) {
users.create({ 'username':username, 'email':email }, cb);
}
else if (credentials.length == 1) {
credentials[0].user(cb);
}
else {
throw new Error("More than one credential match");
}
}
],

cb);
};

module.exports = credentials;
13 changes: 13 additions & 0 deletions models/external-accounts.js
@@ -0,0 +1,13 @@
var schema = require("./schema"),
users = require("./users"),
async = require("async");

var accounts = schema.define('external_accounts', {
site: { type: String, length: 25, index: true },
external_id: { type: String, length: 100, index: true },
details: { type: schema.Text }
});

users.hasMany(accounts, { as: 'accounts', foreignKey: 'users_id' });
accounts.belongsTo(users, { as: 'user', foreignKey: 'users_id' });

File renamed without changes.
71 changes: 71 additions & 0 deletions models/users.js
@@ -0,0 +1,71 @@
var schema = require("./schema"),
async = require("async"),
bcrypt = require("bcrypt");

var users = schema.define('users', {
username: { type: String, length: 25, index: true },
email: { type: String, length: 50, index: true },
password: { type: String, length: 50 }
});

users.validatesPresenceOf("username", { message: "username is required" });
users.validatesPresenceOf("password", { message: "password is required" });
users.validatesPresenceOf("email", { message: "email is required" });
users.validatesUniquenessOf("username", { message: "username is not unique" });
users.validatesUniquenessOf("email", { message: "email is not unique" });

users.signin = function(username, password, cb) {
async.waterfall([
function(cb) {
users.all({ 'where': { 'username': username } }, cb);
},

function(results, cb) {
if (!results || results.length == 0) {
throw new Error("No users found matching the username " + username);
}
else if (results.length > 1) {
throw new Error("Found more than one user matching the username " + username);
}
else {
cb(results[0]);
}
},

function(user, cb) {
bcrypt.compare(password, user.password, function(err,result) { cb(err,user,result); });
},

function(user, result, cb) {
if (result)
cb(user);
else
throw new Error("Password does not match");
}
],

cb);
};

users.signup = function(data, cb) {
async.waterfall([
function(cb) {
bcrypt.genSalt(10, cb);
},

function(salt, cb) {
bcrypt.hash(data.password, salt, cb);
},

function(hash, cb) {
data.password = hash;

users.create(data,cb);
}
],

cb);
};

module.exports = users;

1 change: 1 addition & 0 deletions routes/index.js
Expand Up @@ -6,5 +6,6 @@
exports.index = function(req, res){
console.log(req.isAuthenticated());
console.log(req.getAuthDetails());
console.log(req.session);
res.render('index', { title: 'Home' });
};
83 changes: 77 additions & 6 deletions routes/login.js
@@ -1,39 +1,110 @@
function loginWith(method, req, res, next) {
var async = require("async"),
bcrypt = require("bcrypt"),
users = require("../models/users"),
accounts = require("../models/external-accounts");

function loginWith(method, req, res, cb) {
req.authenticate([method], function(error, authenticated) {
if (error) {
console.log(error);
res.end();
}
else {
if (authenticated === undefined) {
// Browser interaction required, do nothing.
}
else {
next();
cb(req,res);
}
}
});
}

function facebookAuthenticated(req, res) {
var details = req.getAuthDetails();
var user = details.user;

console.log(user);

console.log("Ensuring user");

}

function twitterAuthenticated(req, res) {
var details = req.getAuthDetails();
var user = details.user;

console.log(user);

}

function getUniquenessChecker(key) {
return function(req, res, next) {
if (!req.param(key))
return res.json(400, { 'error': key + ' is required' });

var where = {};
where[key] = req.param(key);

users.all(
{ 'where': where },

function(err, results) {
if (err) {
res.json(500, { 'errors': err });
}
else {
res.json(200, { 'unique': results.length == 0, 'matches': results.length });
}
}
);
}
};

exports.facebook = function(req, res, next) {
console.log("exports.facebook");

if (req.isAuthenticated()) {
res.redirect("/");
console.log("isAuthenticated");
//res.redirect(global.config.app.url);
facebookAuthenticated(req, res);
}
else {
console.log("loginWith");
loginWith("facebook", req, res, next);
}
};


exports.twitter = function(req, res, next) {
if (req.isAuthenticated()) {
res.redirect("/");
res.redirect(global.config.app.url);
}
else {
loginWith("twitter", req, res, next);
loginWith("twitter", req, res, twitterAuthenticated);
}
};

exports.signup = function(req, res, next) {
users.signup({
'username': req.param('username'),
'password': req.param('password'),
'email': req.param('email')
},

function(err, user) {
if (err) {
res.json(400, { 'errors': user.errors });
}
else {
req.session.user = user;
res.json(200, user);
}
});
};

exports.checkUsername = getUniquenessChecker('username');
exports.checkEmail = getUniquenessChecker('email');

exports.index = function(req, res){
res.render('login', { title: 'Login' });
};
Expand Down
8 changes: 4 additions & 4 deletions support/tests/user.js
@@ -1,6 +1,6 @@
var config = require("../../config");
var async = require("async");
var User = require("linkfilter/model/user");
var user = require("./models/users");

exports.tearDown = function(callback) {
try { global.schema.client.end(); } catch (e) {}
Expand All @@ -12,20 +12,20 @@ exports.testCrud = function(test) {

async.waterfall([
function(cb) {
User.create({ 'username':username },cb);
users.create({ 'username':username, 'email':username+'@example.com' },cb);
},
function(user,cb) {
test.ok(user.id > 0, "User has id after save");

User.find(user.id,cb);
users.find(user.id,cb);
},
function(user,cb) {
test.equals(username, user.username, "Loaded user and username match");

user.destroy(cb);
},
function(cb) {
User.all({ where: { 'username':username } },cb);
users.all({ where: { 'username':username } },cb);
},
function(matches,cb) {
test.equals(0,matches.length, "Cannot find user after delete");
Expand Down

0 comments on commit 2c2533e

Please sign in to comment.