2015-02-07 13:49:04 -05:00
|
|
|
/**
|
|
|
|
* Using Rails-like standard naming convention for endpoints.
|
|
|
|
* GET /documents -> index
|
|
|
|
* POST /documents -> create
|
|
|
|
* GET /documents/:id -> show
|
|
|
|
* PUT /documents/:id -> update
|
|
|
|
* DELETE /documents/:id -> destroy
|
|
|
|
*/
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var _ = require('lodash');
|
|
|
|
var Document = require('./document.model');
|
|
|
|
var Revision = require('./revision.model');
|
|
|
|
var wdiff = require('../../components/wdiff');
|
|
|
|
var mongoose = require('mongoose');
|
|
|
|
|
|
|
|
|
|
|
|
// Get a list of all documents
|
|
|
|
exports.index = function(req, res) {
|
|
|
|
Document
|
|
|
|
.find()
|
|
|
|
.populate('owner', '_id name')
|
|
|
|
.populate('currentRevision', '_id state created')
|
2015-02-08 20:42:31 -05:00
|
|
|
.populate('revisions', '_id state created description')
|
2015-02-07 13:49:04 -05:00
|
|
|
.exec(function (err, documents) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
return res.json(200, documents);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get a list of all documents
|
|
|
|
exports.indexForUser = function(req, res) {
|
|
|
|
Document
|
|
|
|
.find({owner: req.params.userid})
|
|
|
|
.populate('owner', '_id name')
|
2015-02-08 20:42:31 -05:00
|
|
|
.populate('revisions', '_id state created description')
|
2015-02-07 13:49:04 -05:00
|
|
|
.populate('currentRevision', '_id state created')
|
|
|
|
.exec(function (err, documents) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
return res.json(200, documents);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get a single document
|
|
|
|
exports.show = function(req, res) {
|
|
|
|
Document
|
|
|
|
.findById(req.params.id)
|
|
|
|
.populate('owner', '_id name')
|
|
|
|
.populate('currentRevision', '_id state created description content')
|
|
|
|
.populate('revisions', '_id state created description')
|
|
|
|
.exec(function (err, document) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
if(!document) { return res.send(404); }
|
|
|
|
return res.json(document);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Creates a new document with the current user as owner
|
|
|
|
exports.create = function(req, res) {
|
|
|
|
//we do not allow the api client to change the owner willy-nilly!
|
|
|
|
//can this be set in the schema somehow?
|
|
|
|
if (req.body.owner) { delete req.body.owner; }
|
|
|
|
|
|
|
|
//nor document id
|
|
|
|
if (req.body._id) { delete req.body._id; }
|
|
|
|
|
|
|
|
//the client cant add revisions either
|
|
|
|
if (req.body.revisions) { delete req.body.revisions; }
|
|
|
|
if (req.body.currentRevision) { delete req.body.currentRevision; }
|
|
|
|
|
|
|
|
//add the current user to the document object
|
|
|
|
var document = _.merge(req.body, {owner: req.user._id});
|
|
|
|
|
|
|
|
|
|
|
|
//and add to the db
|
|
|
|
Document.create(document, function(err, document) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
|
|
|
|
//create an initial, empty revision
|
|
|
|
var revision = {document: document, status: 'empty', content:''};
|
|
|
|
Revision.create(revision, function(err, revision) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
|
|
|
|
//then add that revision back to the document
|
|
|
|
document.currentRevision = revision;
|
|
|
|
document.revisions = [revision];
|
|
|
|
|
|
|
|
//save the document and return
|
|
|
|
document.save(function (err, document) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
return res.json(201, document);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
// Updates an existing document in the DB.
|
|
|
|
exports.update = function(req, res) {
|
|
|
|
//we don't allow the id to be updated
|
|
|
|
//!!! do we even need to worry about this? Prolly not!
|
|
|
|
if(req.body._id) { delete req.body._id; }
|
|
|
|
|
|
|
|
//??? should we allow the revisions to be updated here? Prolly not
|
|
|
|
if (req.body.revisions) { delete req.body.revisions; }
|
|
|
|
|
|
|
|
Document.findById(req.params.id, function (err, document) {
|
|
|
|
if (err) { return handleError(res, err); }
|
|
|
|
if(!document) { return res.send(404); }
|
|
|
|
|
|
|
|
// require user authentication
|
|
|
|
if (! mongoose.Types.ObjectId(document.owner).equals(req.user._id))
|
|
|
|
{return res.send(401);}
|
|
|
|
|
|
|
|
//do it
|
|
|
|
var updated = _.merge(document, req.body);
|
|
|
|
updated.save(function (err) {
|
|
|
|
if (err) { return handleError(res, err); }
|
|
|
|
return res.json(200, document);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Deletes a document from the DB.
|
|
|
|
exports.destroy = function(req, res) {
|
|
|
|
Document.findById(req.params.id, function (err, document) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
if(!document) { return res.send(404); }
|
|
|
|
|
|
|
|
// require user authentication
|
|
|
|
if (! mongoose.Types.ObjectId(document.owner).equals(req.user._id))
|
|
|
|
{return res.send(401);}
|
|
|
|
|
|
|
|
//do it
|
|
|
|
document.remove(function(err) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
return res.send(204);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get a list of all revisions for a document
|
|
|
|
exports.indexRevisionsForDocument = function(req, res) {
|
|
|
|
Revision
|
|
|
|
.find({document: req.params.id})
|
|
|
|
.populate('owner', '_id name')
|
2015-02-09 20:47:35 -05:00
|
|
|
.populate('document', '_id title currentRevision revisions')
|
|
|
|
.populate('document.revisions', '_id')
|
2015-02-07 13:49:04 -05:00
|
|
|
.exec(function (err, revisions) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
if(!revisions) { return res.send(404); }
|
|
|
|
|
|
|
|
return res.json(200, revisions);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Show a revision by id
|
|
|
|
exports.showRevision = function(req, res) {
|
|
|
|
Revision
|
|
|
|
.findById(req.params.revisionid)
|
|
|
|
.populate('owner', '_id name')
|
2015-02-09 20:47:35 -05:00
|
|
|
.populate('document', '_id title currentRevision revisions')
|
2015-02-09 20:19:47 -05:00
|
|
|
.populate('document.revisions', '_id')
|
2015-02-07 13:49:04 -05:00
|
|
|
.exec(function (err, revision) {
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
if(!revision) { return res.send(404); }
|
|
|
|
|
|
|
|
//ensure this revision actually belongs to the specified document
|
|
|
|
if (! mongoose.Types.ObjectId(revision.document._id).equals(req.params.id))
|
|
|
|
{return res.status(403).send("Mismatch between revision id and document id.");}
|
|
|
|
|
|
|
|
|
|
|
|
// ??? require user authentication
|
|
|
|
//if (! mongoose.Types.ObjectId(document.owner).equals(req.user._id))
|
|
|
|
// {return res.send(401);}
|
|
|
|
|
|
|
|
return res.json(revision);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// Create a new revision and add it to a document (with the current user as owner)
|
|
|
|
// This can only be performed by the user who owns the document
|
|
|
|
exports.createRevision = function(req, res) {
|
|
|
|
//we do not allow the api client to change the owner willy-nilly!
|
|
|
|
//can this be set in the schema somehow?
|
|
|
|
if (req.body.owner) { delete req.body.owner; }
|
|
|
|
|
|
|
|
//similarly the document
|
|
|
|
if (req.body.document) { delete req.body.document; }
|
|
|
|
|
|
|
|
//and the date
|
|
|
|
if (req.body.created) { delete req.body.created; }
|
|
|
|
|
2015-02-08 20:42:31 -05:00
|
|
|
//and the id!
|
|
|
|
if (req.body._id) { delete req.body._id; }
|
|
|
|
|
|
|
|
console.log(req.body);
|
|
|
|
|
2015-02-07 13:49:04 -05:00
|
|
|
//get the record for the parent document
|
|
|
|
Document.findById(req.params.id).exec(function(err, document){
|
2015-02-08 20:42:31 -05:00
|
|
|
if (err) { return handleError(res, err); }
|
2015-02-07 13:49:04 -05:00
|
|
|
if(!document) { return res.send(404); }
|
|
|
|
|
|
|
|
// require user authentication
|
|
|
|
if (! mongoose.Types.ObjectId(document.owner).equals(req.user._id))
|
|
|
|
{return res.send(401);}
|
|
|
|
|
2015-02-08 20:42:31 -05:00
|
|
|
console.log('---');
|
|
|
|
console.log(document);
|
|
|
|
|
2015-02-07 13:49:04 -05:00
|
|
|
//set the owner and document fields for the revision
|
|
|
|
var revision = _.merge(req.body, {owner: req.user, document: document});
|
|
|
|
|
2015-02-08 20:42:31 -05:00
|
|
|
console.log('---');
|
|
|
|
console.log(revision);
|
|
|
|
|
2015-02-07 13:49:04 -05:00
|
|
|
//create the record
|
|
|
|
Revision.create(revision, function (err, revision) {
|
|
|
|
if(err) { return handleError(res, err); }
|
2015-02-08 20:42:31 -05:00
|
|
|
if (!revision) {return handleError(res, "Unknown error creating revision");}
|
|
|
|
|
|
|
|
console.log('---');
|
|
|
|
console.log(revision);
|
2015-02-07 13:49:04 -05:00
|
|
|
|
|
|
|
//and update the document
|
|
|
|
document.revisions.push(revision);
|
|
|
|
document.currentRevision = revision;
|
|
|
|
document.save(function (err) {
|
|
|
|
if (err) { return handleError(res, err); }
|
|
|
|
return res.json(200, revision);
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
//compares two revisions with wdiff
|
|
|
|
exports.wdiff = function(req, res) {
|
2015-02-08 20:42:31 -05:00
|
|
|
Revision
|
|
|
|
.findById(req.params.revisionida)
|
|
|
|
.populate('document', 'title')
|
|
|
|
.exec(function (err, revisiona) {
|
2015-02-07 13:49:04 -05:00
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
if(!revisiona) { return res.send(404); }
|
|
|
|
|
|
|
|
|
2015-02-08 20:42:31 -05:00
|
|
|
Revision
|
|
|
|
.findById(req.params.revisionidb)
|
|
|
|
.populate('document', 'title')
|
|
|
|
.exec(function (err, revisionb) {
|
2015-02-07 13:49:04 -05:00
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
if(!revisionb) { return res.send(404); }
|
|
|
|
|
|
|
|
//??? do we care if both revisions have the same document?
|
|
|
|
//??? if they both have the same user?
|
|
|
|
//??? if the current user is the owner?
|
|
|
|
|
|
|
|
wdiff(revisiona.content, revisionb.content, true, function(err, result){
|
|
|
|
if(err) { return handleError(res, err); }
|
|
|
|
|
|
|
|
result.a = revisiona;
|
|
|
|
result.b = revisionb;
|
|
|
|
|
|
|
|
res.json(result);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
function handleError(res, err) {
|
|
|
|
return res.send(500, err);
|
|
|
|
}
|