dubdiff/server/api/document/document.controller.js

274 lines
8.2 KiB
JavaScript

/**
* 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')
.populate('revisions', '_id state created description')
.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')
.populate('revisions', '_id state created description')
.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')
.populate('document', '_id title currentRevision revisions')
.populate('document.revisions', '_id')
.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')
.populate('document', '_id title currentRevision revisions')
.populate('document.revisions', '_id')
.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; }
//and the id!
if (req.body._id) { delete req.body._id; }
console.log(req.body);
//get the record for the parent document
Document.findById(req.params.id).exec(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);}
console.log('---');
console.log(document);
//set the owner and document fields for the revision
var revision = _.merge(req.body, {owner: req.user, document: document});
console.log('---');
console.log(revision);
//create the record
Revision.create(revision, function (err, revision) {
if(err) { return handleError(res, err); }
if (!revision) {return handleError(res, "Unknown error creating revision");}
console.log('---');
console.log(revision);
//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) {
Revision
.findById(req.params.revisionida)
.populate('document', 'title')
.exec(function (err, revisiona) {
if(err) { return handleError(res, err); }
if(!revisiona) { return res.send(404); }
Revision
.findById(req.params.revisionidb)
.populate('document', 'title')
.exec(function (err, revisionb) {
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);
}