Commit 2c0b4fbd authored by Nick Poulden's avatar Nick Poulden
Browse files

Upgraded comments server to Express 3 / Connect 2.

Best to `rm -rf node_modules`, then re-run `npm install`.
parent b6e5ab6f
Loading
Loading
Loading
Loading
+250 −246
Original line number Diff line number Diff line
@@ -19,10 +19,8 @@
 *
 */

config = require('./config');
mongoose = require('mongoose');
var config = require('./config');
require('./database');
require('express-namespace');

var mysql = require('mysql'),
    client = mysql.createClient({
@@ -32,67 +30,78 @@ var mysql = require('mysql'),
        database: config.db.dbName
    }),
    express = require('express'),
    connect = require('connect'),
    MongoStore = require('connect-session-mongo'),
    MongoStore = require('connect-mongo'),
    _ = require('underscore'),
    ForumUser = require('./ForumUser').ForumUser,
    forumUser = new ForumUser(client),
    util = require('./util'),
    crypto = require('crypto');
    crypto = require('crypto'),
    mongoose = require('mongoose');

var app = express();

var app = express.createServer(
app.configure(function() {

    // Headers for Cross Origin Resource Sharing (CORS)
    function (req, res, next) {
    app.use(function (req, res, next) {
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
        res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
        next();
    },
    });

    express.cookieParser(),
    app.use(express.cookieParser(config.sessionSecret));

    // Hack to set session cookie if session ID is set as a URL param.
    // This is because not all browsers support sending cookies via CORS
    function(req, res, next) {
        if (req.query.sid) {
    app.use(function(req, res, next) {
        if (req.query.sid && req.query.sid != 'null') {
            var sid = req.query.sid.replace(/ /g, '+');
            req.cookies = req.cookies || {};
            req.cookies['sencha_docs'] = sid;
            req.sessionID = sid;
            req.signedCookies = req.signedCookies || {};
            req.signedCookies['sencha_docs'] = sid;
        }
        next();
    },
    });

    // Use MongoDB for session storage
    connect.session({ store: new MongoStore, secret: config.sessionSecret, key: 'sencha_docs' }),

    function(req, res, next) {
    app.use(express.session({
        secret: config.sessionSecret,
        key: 'sencha_docs',
        store: new MongoStore({
            url: exports.mongoDb + "/sessions"
        })
    }));

    app.use(function(req, res, next) {
        // IE doesn't get content-type, so default to form encoded.
        if (!req.headers['content-type']) {
            req.headers['content-type'] = 'application/x-www-form-urlencoded';
        }
        next();
    },
    express.bodyParser(),
    express.methodOverride()
);
    });

    app.use(express.bodyParser());
    app.use(express.methodOverride());

    app.enable('jsonp callback');
});

// All URLs start with /auth
app.namespace('/auth', function(){
app.configure('development', function(){
    app.use(express.logger('dev'));
    app.use(express.errorHandler());
});

/**
 * Authentication
 */

    app.get('/session', function(req, res) {
app.get('/auth/session', function(req, res) {
    var result = req.session && req.session.user && forumUser.clientUser(req.session.user);
    res.json(result || false);
});

    app.post('/login', function(req, res){
app.post('/auth/login', function(req, res){

    forumUser.login(req.body.username, req.body.password, function(err, result) {

@@ -114,7 +123,7 @@ app.namespace('/auth', function(){
});

// Remove session
    app.post('/logout', function(req, res){
app.post('/auth/logout', function(req, res){
    req.session.user = null;
    res.json({ success: true });
});
@@ -122,7 +131,7 @@ app.namespace('/auth', function(){
/**
 * Handles comment unsubscription requests.
 */
    app.get('/unsubscribe/:subscriptionId', function(req, res) {
app.get('/auth/unsubscribe/:subscriptionId', function(req, res) {

    Subscription.findOne({ _id: req.params.subscriptionId }, function(err, subscription) {
        if (err) throw(err);
@@ -143,18 +152,15 @@ app.namespace('/auth', function(){
    });
});

});


/**
 * Commenting
 */
app.namespace('/auth/:sdk/:version', function(){

/**
 * Returns a list of comments for a particular target (eg class, guide, video)
 */
    app.get('/comments', util.getCommentReads, function(req, res) {
app.get('/auth/:sdk/:version/comments', util.getCommentReads, function(req, res) {

    if (!req.query.startkey) {
        res.json({error: 'Invalid request'});
@@ -179,7 +185,7 @@ app.namespace('/auth/:sdk/:version', function(){
 * `offset` and `limit` fields. I'd say it's a hack, but at least
 * it works for now.
 */
    app.get('/comments_recent', util.getCommentReads, function(req, res) {
app.get('/auth/:sdk/:version/comments_recent', util.getCommentReads, function(req, res) {
    var offset = parseInt(req.query.offset, 10) || 0;
    var limit = parseInt(req.query.limit, 10) || 100;
    var filter = {
@@ -209,21 +215,21 @@ app.namespace('/auth/:sdk/:version', function(){
 * Returns number of comments for each class/member,
 * and a list of classes/members into which the user has subscribed.
 */
    app.get('/comments_meta', util.getCommentCounts, util.getCommentSubscriptions, function(req, res) {
app.get('/auth/:sdk/:version/comments_meta', util.getCommentCounts, util.getCommentSubscriptions, function(req, res) {
    res.send({ comments: req.commentCounts, subscriptions: req.commentSubscriptions || [] });
});

/**
 * Returns an individual comment (used when editing a comment)
 */
    app.get('/comments/:commentId', util.findComment, function(req, res) {
app.get('/auth/:sdk/:version/comments/:commentId', util.findComment, function(req, res) {
    res.json({ success: true, content: req.comment.content });
});

/**
 * Creates a new comment
 */
    app.post('/comments', util.requireLoggedInUser, function(req, res) {
app.post('/auth/:sdk/:version/comments', util.requireLoggedInUser, function(req, res) {

    var target = JSON.parse(req.body.target);

@@ -260,7 +266,7 @@ app.namespace('/auth/:sdk/:version', function(){
/**
 * Updates an existing comment (for voting or updating contents)
 */
    app.post('/comments/:commentId', util.requireLoggedInUser, util.findComment, function(req, res) {
app.post('/auth/:sdk/:version/comments/:commentId', util.requireLoggedInUser, util.findComment, function(req, res) {

    var voteDirection,
        comment = req.comment;
@@ -288,7 +294,7 @@ app.namespace('/auth/:sdk/:version', function(){
/**
 * Deletes a comment
 */
    app.post('/comments/:commentId/delete', util.requireLoggedInUser, util.findComment, util.requireOwner, function(req, res) {
app.post('/auth/:sdk/:version/comments/:commentId/delete', util.requireLoggedInUser, util.findComment, util.requireOwner, function(req, res) {
    req.comment.deleted = true;
    req.comment.save(function(err, response) {
        res.send({ success: true });
@@ -298,7 +304,7 @@ app.namespace('/auth/:sdk/:version', function(){
/**
 * Restores deleted comment
 */
    app.post('/comments/:commentId/undo_delete', util.requireLoggedInUser, util.findComment, util.requireOwner, util.getCommentReads, function(req, res) {
app.post('/auth/:sdk/:version/comments/:commentId/undo_delete', util.requireLoggedInUser, util.findComment, util.requireOwner, util.getCommentReads, function(req, res) {
    req.comment.deleted = false;
    req.comment.save(function(err, response) {
        res.send({ success: true, comment: util.scoreComments([req.comment], req)[0] });
@@ -308,7 +314,7 @@ app.namespace('/auth/:sdk/:version', function(){
/**
 * Marks a comment 'read'
 */
    app.post('/comments/:commentId/read', util.requireLoggedInUser, util.findCommentMeta, function(req, res) {
app.post('/auth/:sdk/:version/comments/:commentId/read', util.requireLoggedInUser, util.findCommentMeta, function(req, res) {
    req.commentMeta.metaType = 'read';
    req.commentMeta.save(function(err, response) {
        res.send({ success: true });
@@ -318,14 +324,14 @@ app.namespace('/auth/:sdk/:version', function(){
/**
 * Get email subscriptions
 */
    app.get('/subscriptions', util.getCommentSubscriptions, function(req, res) {
app.get('/auth/:sdk/:version/subscriptions', util.getCommentSubscriptions, function(req, res) {
    res.json({ subscriptions: req.commentMeta.subscriptions });
});

/**
 * Subscibe / unsubscribe to a comment thread
 */
    app.post('/subscribe', util.requireLoggedInUser, function(req, res) {
app.post('/auth/:sdk/:version/subscribe', util.requireLoggedInUser, function(req, res) {

    var subscriptionBody = {
        sdk: req.params.sdk,
@@ -354,8 +360,6 @@ app.namespace('/auth/:sdk/:version', function(){
    });
});

});

var port = 3000;
app.listen(port);
console.log("Server started at port "+port+"...");
+8 −1
Original line number Diff line number Diff line

/**
 * Defines comment schema and connects to database
 */

var mongoose = require('mongoose'),
    config = require('./config');

Comment = mongoose.model('Comment', new mongoose.Schema({
    sdk:         String,
    version:     String,
@@ -43,4 +48,6 @@ Meta = mongoose.model('Meta', new mongoose.Schema({
    metaType:    String
}));

mongoose.connect(config.mongoDb);
mongoose.connect(config.mongoDb, function(err, ok) {
    console.log("Connected to DB")
});
+2 −3
Original line number Diff line number Diff line
@@ -4,10 +4,10 @@
  "description": "Commenting backend for JSDuck Documentation",
  "author": "Nick Poudlen <nick@sencha.com>",
  "dependencies": {
    "express": "git://github.com/visionmedia/express.git",
    "express-namespace": "",
    "connect": "",
    "connect-mongo": "",
    "express": "",
    "express-namespace": "",
    "marked": "",
    "mongoose": "",
    "mysql": "",
@@ -17,4 +17,3 @@
    "nodemailer": ""
  }
}
+2 −1
Original line number Diff line number Diff line
@@ -2,7 +2,8 @@
var marked = require('marked'),
    _ = require('underscore'),
    sanitizer = require('sanitizer'),
    nodemailer = require("nodemailer");
    nodemailer = require("nodemailer"),
    mongoose = require('mongoose');

/**
 * Converts Markdown-formatted comment text into HTML.