Permalink
Browse files

Updated Mongoose to 1.0.7

  • Loading branch information...
1 parent 6a269ce commit d1c029b55bedc751e4aca4716f7c557c62c8075c Alex Young committed Feb 7, 2011
Showing with 166 additions and 139 deletions.
  1. +39 −36 app.js
  2. +94 −98 models.js
  3. +1 −1 package.json
  4. +23 −1 public/javascripts/application.js
  5. +7 −1 test/app.test.js
  6. +1 −1 test/helper.js
  7. +1 −1 views/layout.jade
View
75 app.js
@@ -2,10 +2,11 @@ var express = require('express@1.0.0'),
connect = require('connect@0.5.1'),
jade = require('jade@0.6.0'),
app = module.exports = express.createServer(),
- mongoose = require('mongoose@0.0.4').Mongoose,
+ mongoose = require('mongoose@1.0.7'),
mongoStore = require('connect-mongodb@0.1.1'),
markdown = require('markdown').markdown,
sys = require('sys'),
+ models = require('./models'),
db,
Document,
User,
@@ -28,8 +29,6 @@ app.configure('production', function() {
app.set('db-uri', 'mongodb://localhost/nodepad-production');
});
-db = mongoose.connect(app.set('db-uri'));
-
app.configure(function() {
app.set('views', __dirname + '/views');
app.use(express.favicon());
@@ -42,23 +41,25 @@ app.configure(function() {
app.use(express.staticProvider(__dirname + '/public'));
});
-app.Document = Document = require('./models.js').Document(db);
-app.User = User = require('./models.js').User(db);
-app.LoginToken = LoginToken = require('./models.js').LoginToken(db);
+models.defineModels(mongoose, function() {
+ app.Document = Document = mongoose.model('Document');
+ app.User = User = mongoose.model('User');
+ app.LoginToken = LoginToken = mongoose.model('LoginToken');
+ db = mongoose.connect(app.set('db-uri'));
+})
function authenticateFromLoginToken(req, res, next) {
var cookie = JSON.parse(req.cookies.logintoken);
- LoginToken.find({ email: cookie.email,
- series: cookie.series,
- token: cookie.token })
- .first(function(token) {
+ LoginToken.findOne({ email: cookie.email,
+ series: cookie.series,
+ token: cookie.token }, (function(err, token) {
if (!token) {
res.redirect('/sessions/new');
return;
}
- User.find({ email: token.email }).first(function(user) {
+ User.findOne({ email: token.email }, function(err, user) {
if (user) {
req.session.user_id = user.id;
req.currentUser = user;
@@ -72,12 +73,12 @@ function authenticateFromLoginToken(req, res, next) {
res.redirect('/sessions/new');
}
});
- });
+ }));
}
function loadUser(req, res, next) {
if (req.session.user_id) {
- User.findById(req.session.user_id, function(user) {
+ User.findById(req.session.user_id, function(err, user) {
if (user) {
req.currentUser = user;
next();
@@ -136,11 +137,11 @@ app.error(function(err, req, res) {
// Document list
app.get('/documents.:format?', loadUser, function(req, res) {
- Document.find().all(function(documents) {
+ Document.find({}, function(err, documents) {
switch (req.params.format) {
case 'json':
res.send(documents.map(function(d) {
- return d.__doc;
+ return d.toObject();
}));
break;
@@ -153,7 +154,7 @@ app.get('/documents.:format?', loadUser, function(req, res) {
});
app.get('/documents/:id.:format?/edit', loadUser, function(req, res, next) {
- Document.findById(req.params.id, function(d) {
+ Document.findById(req.params.id, function(err, d) {
if (!d) return next(new NotFound('Document not found'));
res.render('documents/edit.jade', {
locals: { d: d, currentUser: req.currentUser }
@@ -173,7 +174,7 @@ app.post('/documents.:format?', loadUser, function(req, res) {
d.save(function() {
switch (req.params.format) {
case 'json':
- res.send(d.__doc);
+ res.send(d.toObject());
break;
default:
@@ -185,12 +186,12 @@ app.post('/documents.:format?', loadUser, function(req, res) {
// Read document
app.get('/documents/:id.:format?', loadUser, function(req, res, next) {
- Document.findById(req.params.id, function(d) {
+ Document.findById(req.params.id, function(err, d) {
if (!d) return next(new NotFound('Document not found'));
switch (req.params.format) {
case 'json':
- res.send(d.__doc);
+ res.send(d.toObject());
break;
case 'html':
@@ -207,15 +208,16 @@ app.get('/documents/:id.:format?', loadUser, function(req, res, next) {
// Update document
app.put('/documents/:id.:format?', loadUser, function(req, res, next) {
- Document.findById(req.body.d.id, function(d) {
+ Document.findById(req.body.d.id, function(err, d) {
if (!d) return next(new NotFound('Document not found'));
d.title = req.body.d.title;
d.data = req.body.d.data;
- d.save(function() {
+
+ d.save(function(err) {
switch (req.params.format) {
case 'json':
- res.send(d.__doc);
+ res.send(d.toObject());
break;
default:
@@ -228,7 +230,7 @@ app.put('/documents/:id.:format?', loadUser, function(req, res, next) {
// Delete document
app.del('/documents/:id.:format?', loadUser, function(req, res, next) {
- Document.findById(req.params.id, function(d) {
+ Document.findById(req.params.id, function(err, d) {
if (!d) return next(new NotFound('Document not found'));
d.remove(function() {
@@ -255,27 +257,28 @@ app.get('/users/new', function(req, res) {
app.post('/users.:format?', function(req, res) {
var user = new User(req.body.user);
- function userSaved() {
+ function userSaveFailed() {
+ req.flash('error', 'Account creation failed');
+ res.render('users/new.jade', {
+ locals: { user: user }
+ });
+ }
+
+ user.save(function(err) {
+ console.log(err);
+ if (err) return userSaveFailed();
+
req.flash('info', 'Your account has been created');
switch (req.params.format) {
case 'json':
- res.send(user.__doc);
+ res.send(user.toObject());
break;
default:
req.session.user_id = user.id;
res.redirect('/documents');
}
- }
-
- function userSaveFailed() {
- req.flash('error', 'Account creation failed');
- res.render('users/new.jade', {
- locals: { user: user }
- });
- }
-
- user.save(userSaved, userSaveFailed);
+ });
});
// Sessions
@@ -286,7 +289,7 @@ app.get('/sessions/new', function(req, res) {
});
app.post('/sessions', function(req, res) {
- User.find({ email: req.body.user.email }).first(function(user) {
+ User.findOne({ email: req.body.user.email }, function(err, user) {
if (user && user.authenticate(req.body.user.password)) {
req.session.user_id = user.id;
View
192 models.js
@@ -1,115 +1,111 @@
-var mongoose = require('mongoose@0.0.4').Mongoose,
- crypto = require('crypto');
-
-mongoose.model('Document', {
- properties: ['title', 'data', 'tags', 'user_id'],
-
- indexes: [
- 'title',
- 'user_id'
- ],
-
- getters: {
- id: function() {
+var crypto = require('crypto'),
+ Document,
+ User,
+ LoginToken;
+
+function defineModels(mongoose, fn) {
+ var Schema = mongoose.Schema,
+ ObjectId = Schema.ObjectId;
+
+ /**
+ * Model: Document
+ */
+ Document = new Schema({
+ 'title': { type: String, index: true },
+ 'data': String,
+ 'tags': [String],
+ 'user_id': ObjectId
+ });
+
+ Document.virtual('id')
+ .get(function() {
return this._id.toHexString();
- }
- }
-});
+ });
-mongoose.model('User', {
- properties: ['email', 'hashed_password', 'salt'],
+ /**
+ * Model: User
+ */
+ function validatePresenceOf(value) {
+ return value && value.length;
+ }
- indexes: [
- [{ email: 1 }, { unique: true }]
- ],
+ User = new Schema({
+ 'email': { type: String, validate: [validatePresenceOf, 'an email is required'], index: { unique: true } },
+ 'hashed_password': String,
+ 'salt': String
+ });
- getters: {
- id: function() {
+ User.virtual('id')
+ .get(function() {
return this._id.toHexString();
- },
-
- password: function() { return this._password; }
- },
+ });
- setters: {
- password: function(password) {
+ User.virtual('password')
+ .set(function(password) {
this._password = password;
this.salt = this.makeSalt();
this.hashed_password = this.encryptPassword(password);
+ })
+ .get(function() { return this._password; });
+
+ User.method('authenticate', function(plainText) {
+ return this.encryptPassword(plainText) === this.hashed_password;
+ });
+
+ User.method('makeSalt', function() {
+ return Math.round((new Date().valueOf() * Math.random())) + '';
+ });
+
+ User.method('encryptPassword', function(password) {
+ return crypto.createHmac('sha1', this.salt).update(password).digest('hex');
+ });
+
+ User.pre('save', function(next) {
+ if (!validatePresenceOf(this.password)) {
+ next(new Error('Invalid password'));
+ } else {
+ next();
}
- },
-
- methods: {
- authenticate: function(plainText) {
- return this.encryptPassword(plainText) === this.hashed_password;
- },
-
- makeSalt: function() {
- return Math.round((new Date().valueOf() * Math.random())) + '';
- },
-
- encryptPassword: function(password) {
- return crypto.createHmac('sha1', this.salt).update(password).digest('hex');
- },
-
- isValid: function() {
- // TODO: Better validation
- return this.email && this.email.length > 0 && this.email.length < 255
- && this.password && this.password.length > 0 && this.password.length < 255;
- },
-
- save: function(okFn, failedFn) {
- if (this.isValid()) {
- this.__super__(okFn);
- } else {
- failedFn();
- }
- }
- }
-});
-
-mongoose.model('LoginToken', {
- properties: ['email', 'series', 'token'],
-
- indexes: [
- 'email',
- 'series',
- 'token'
- ],
-
- methods: {
- randomToken: function() {
- return Math.round((new Date().valueOf() * Math.random())) + '';
- },
-
- save: function(fn) {
- // Automatically create the tokens
- this.token = this.randomToken();
- this.series = this.randomToken();
- this.__super__(fn);
- }
- },
-
- getters: {
- id: function() {
+ });
+
+ /**
+ * Model: LoginToken
+ *
+ * Used for session persistence.
+ */
+ LoginToken = new Schema({
+ email: { type: String, index: true },
+ series: { type: String, index: true },
+ token: { type: String, index: true }
+ });
+
+ LoginToken.method('randomToken', function() {
+ return Math.round((new Date().valueOf() * Math.random())) + '';
+ });
+
+ LoginToken.pre('save', function(next) {
+ // Automatically create the tokens
+ this.token = this.randomToken();
+ this.series = this.randomToken();
+ next();
+ });
+
+ LoginToken.virtual('id')
+ .get(function() {
return this._id.toHexString();
- },
+ });
- cookieValue: function() {
+ LoginToken.virtual('cookieValue')
+ .get(function() {
return JSON.stringify({ email: this.email, token: this.token, series: this.series });
- }
- }
-});
+ });
-exports.User = function(db) {
- return db.model('User');
-};
+ mongoose.model('Document', Document);
+ mongoose.model('User', User);
+ mongoose.model('LoginToken', LoginToken);
-exports.Document = function(db) {
- return db.model('Document');
-};
+ fn();
+}
-exports.LoginToken = function(db) {
- return db.model('LoginToken');
-};
+exports.defineModels = defineModels;
View
2 package.json
@@ -11,7 +11,7 @@
},
"dependencies": {
"express": "1.0.0",
- "mongoose": "0.0.4",
+ "mongoose": "1.0.7",
"connect": "0.5.1",
"connect-mongodb": "0.1.1",
"jade": "0.6.0",
View
24 public/javascripts/application.js
@@ -36,6 +36,28 @@
}
});
+ $('#logout').click(function(e) {
+ e.preventDefault();
+ if (confirm('Are you sure you want to log out?')) {
+ var element = $(this),
+ form = $('<form></form>');
+ form
+ .attr({
+ method: 'POST',
+ action: '/sessions'
+ })
+ .hide()
+ .append('<input type="hidden" />')
+ .find('input')
+ .attr({
+ 'name': '_method',
+ 'value': 'delete'
+ })
+ .end()
+ .submit();
+ }
+ });
+
// Correct widths and heights based on window size
function resize() {
var height = $(window).height() - $('#header').height() - 1,
@@ -87,7 +109,7 @@
$('#save-button').click(function() {
var id = $('#document-list .selected').itemID(),
- params = { d: { data: $('#editor').val(), id: id } };
+ params = { d: { data: $('#editor').val(), id: id, title: $('#document-list .selected').html() } };
$.put('/documents/' + id + '.json', params, function(data) {
// Saved, will return JSON
});
View
8 test/app.test.js
@@ -1,3 +1,7 @@
+/**
+ * Run with expresso test/app.test.js
+ */
+
var app = require('../app'),
assert = require('assert'),
zombie = require('zombie'),
@@ -11,7 +15,9 @@ testHelper.models = [app.User];
testHelper.setup(function() {
// Fixtures
var user = new app.User({'email' : 'alex@example.com', 'password' : 'test' });
- user.save(testHelper.run(exports));
+ user.save(function() {
+ testHelper.run(exports)
+ });
});
testHelper.tests = {
View
2 test/helper.js
@@ -8,7 +8,7 @@ function prepare(models, next) {
var modelCount = models.length;
models.forEach(function(model) {
modelCount--;
- model.find().all(function(records) {
+ model.find({}, function(err, records) {
var count = records.length;
records.forEach(function(result) {
result.remove();
View
2 views/layout.jade
@@ -16,7 +16,7 @@ html
a(href='/') #{nameAndVersion(appName, version)}
- if (typeof currentUser !== 'undefined')
li.right
- a.destroy(href='/sessions') Log Out
+ a#logout(href='/sessions') Log Out
!{flashMessages}
!= body
script(type='text/javascript', src='/javascripts/application.js')

0 comments on commit d1c029b

Please sign in to comment.