summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/index.js13
-rw-r--r--server/lib/api.js54
-rw-r--r--server/lib/auth.js9
-rw-r--r--server/lib/middleware.js6
-rw-r--r--server/lib/schemas/Documentation.js33
-rw-r--r--server/lib/schemas/Project.js8
-rw-r--r--server/lib/schemas/User.js13
-rw-r--r--server/lib/util.js51
-rw-r--r--server/lib/views.js51
9 files changed, 208 insertions, 30 deletions
diff --git a/server/index.js b/server/index.js
index a1efaf2..f418c42 100644
--- a/server/index.js
+++ b/server/index.js
@@ -63,6 +63,9 @@ app.all('*', middleware.ensureLocals);
// Initialize views
app.get('/', views.home);
+app.get('/about', views.docs);
+app.get('/about/:name/edit', views.docs);
+app.get('/about/:name', views.docs);
app.get('/login', views.modal);
app.get('/signup', views.modal);
app.post('/auth/signin', auth.loggedInLocal);
@@ -74,10 +77,18 @@ app.get('/auth/facebook', auth.login('facebook'));
app.get('/auth/facebook/callback', auth.loggedIn('facebook'));
app.get('/profile', views.profile)
app.get('/profile/edit', views.profile)
+
app.get('/api/profile', middleware.ensureAuthenticated, api.profile.show)
app.put('/api/profile', middleware.ensureAuthenticated, api.profile.update)
-app.get('/project/new', views.modal);
+app.get('/project/new', middleware.ensureAuthenticated, views.modal);
+
+app.get('/staff', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.staff.index);
+app.get('/staff/bless', middleware.ensureAuthenticated, views.staff.bless);
+
+app.get('/api/docs', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.docs.show)
+app.post('/api/docs/new', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.docs.create)
+app.post('/api/docs/edit', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.docs.update)
app.get(/^\/([-_a-zA-Z0-9]+)\/?$/, views.profile)
diff --git a/server/lib/api.js b/server/lib/api.js
index cf2a911..9a8a1fc 100644
--- a/server/lib/api.js
+++ b/server/lib/api.js
@@ -8,8 +8,8 @@ var passport = require('passport'),
util = require('./util'),
upload = require('./upload'),
config = require('../../config.json'),
- User = require('./schemas/User');
-
+ User = require('./schemas/User'),
+ Documentation = require('./schemas/Documentation');
var api = {
@@ -35,11 +35,10 @@ var api = {
}
delete data.old_password
delete data.new_password
- delete data.isAdmin
+ delete data.isStaff
+ data.updated_at = new Date ()
if (req.files.avatar) {
- // handle the upload here
- console.log("GOT SOME FILES")
upload.put("avatars", req.files.avatar, {
acceptable: function(){
console.log("acceptable")
@@ -66,6 +65,51 @@ var api = {
})
}
}
+ },
+
+
+ docs: {
+ show: function(req, res){
+ Documentation.findOne({ name: req.query.name }, function(err, doc){
+ if (doc) {
+ res.json(doc)
+ }
+ else {
+ var name = util.sanitize(req.query.name)
+ if (name == "new") {
+ name = ""
+ }
+ res.json({ name: name, isNew: true })
+ }
+ })
+ },
+
+ create: function(req, res){
+ var data = util.cleanQuery(req.body)
+ data.name = data.new_name
+ delete data.new_name
+ new Documentation(data).save(function(err, doc){
+ if (err || ! doc) { return res.json({ error: err }) }
+ res.json(doc)
+ })
+ },
+
+ update: function(req, res){
+ var data = util.cleanQuery(req.body)
+ if (data.name == "new") {
+ return api.docs.create(req, res)
+ }
+ Documentation.findOne({ name: data.name }, function(err, doc){
+ if (err || ! doc) { return res.json({ error: err }) }
+ data.name = data.new_name
+ delete data.new_name
+ _.extend(doc, data)
+ doc.save(function(err, doc){
+ if (err || ! doc) { return res.json({ error: err }) }
+ res.json(doc)
+ })
+ })
+ },
}
}
diff --git a/server/lib/auth.js b/server/lib/auth.js
index 5a952f5..47c1c7c 100644
--- a/server/lib/auth.js
+++ b/server/lib/auth.js
@@ -98,7 +98,7 @@ var auth = {
},
deserializeUser: function (id, done) {
- User.findOne({ _id: id }, "_id displayName username photo", function (err, user) {
+ User.findOne({ _id: id }, "_id displayName username photo isStaff", function (err, user) {
done(err, user);
});
},
@@ -112,7 +112,7 @@ var auth = {
shasum.update(password)
password = shasum.digest('hex');
- User.findOne({ username: username }, function (err, user) {
+ User.findOne({ username: username }, "_id username", function (err, user) {
if (user) {
res.json({ error: { errors: { username: { message: "Username has been taken" } } } })
return
@@ -121,7 +121,10 @@ var auth = {
username: username,
displayName: username,
password: password,
- email: email
+ email: email,
+ created_ip: util.ipToNum(req.connection.remoteAddress),
+ last_ip: util.ipToNum(req.connection.remoteAddress),
+ created_at: new Date ()
}
new User(data).save(function(err, user){
if (err || ! data) { return res.json({ error: err }) }
diff --git a/server/lib/middleware.js b/server/lib/middleware.js
index fb19e68..dbe0b26 100644
--- a/server/lib/middleware.js
+++ b/server/lib/middleware.js
@@ -25,10 +25,10 @@ var middleware = {
next();
},
- ensureIsAdmin: function (req, res, next) {
+ ensureIsStaff: function (req, res, next) {
User.findOne({ _id: req.user._id }, function (err, user) {
- if (! user.isAdmin) {
- return res.redirect('http://' + config.host + '/' + req.user.username);
+ if (! user.isStaff) {
+ return res.redirect('http://' + config.host + '/');
}
req.user = user
next();
diff --git a/server/lib/schemas/Documentation.js b/server/lib/schemas/Documentation.js
new file mode 100644
index 0000000..35cf34f
--- /dev/null
+++ b/server/lib/schemas/Documentation.js
@@ -0,0 +1,33 @@
+/* jshint node: true */
+
+
+var mongoose = require('mongoose'),
+ _ = require('lodash'),
+ util = require('../util');
+
+var DocumentationSchema = new mongoose.Schema({
+ name: {
+ type: String,
+ required: true,
+ unique: true,
+ validate: [function (val){
+ val = util.slugify(val || this.displayName || "")
+ if (! val.length) return false
+ if (val == "new") return false
+ return true
+ },"{PATH} name is required"]
+ },
+ displayName: {
+ type: String,
+ },
+ body: {
+ type: String,
+ default: ""
+ },
+ created_at: { type: Date },
+ updated_at: { type: Date },
+});
+
+
+module.exports = exports = mongoose.model('documentation', DocumentationSchema);
+exports.schema = DocumentationSchema;
diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js
index a0382b3..5176e06 100644
--- a/server/lib/schemas/Project.js
+++ b/server/lib/schemas/Project.js
@@ -1,10 +1,9 @@
/* jshint node: true */
-var NONALPHANUMERICS_REGEX = new RegExp('[^-_a-zA-Z0-9]', 'g')
-
var mongoose = require('mongoose'),
_ = require('lodash'),
- config = require('../../../config.json');
+ config = require('../../../config.json'),
+ util = require('../util');
var ProjectSchema = new mongoose.Schema({
name: { type: String, required: true },
@@ -12,7 +11,7 @@ var ProjectSchema = new mongoose.Schema({
type: String,
required: true,
validate: [function (val){
- val = (val || this.displayName || "").replace(/\s/g,"-").replace(NONALPHANUMERICS_REGEX, '-').replace(/-+/g,"-")
+ val = util.sanitize(val || this.displayName || "")
if (! val.length) return false
return true
},"{PATH} name is required"]
@@ -33,6 +32,5 @@ var ProjectSchema = new mongoose.Schema({
updated_at: { type: Date },
});
-
module.exports = exports = mongoose.model('project', ProjectSchema);
exports.schema = ProjectSchema;
diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js
index 24b0adf..5a93df2 100644
--- a/server/lib/schemas/User.js
+++ b/server/lib/schemas/User.js
@@ -1,7 +1,5 @@
/* jshint node: true */
-var NONALPHANUMERICS_REGEX = new RegExp('[^-_a-zA-Z0-9]', 'g')
-
var mongoose = require('mongoose'),
_ = require('lodash'),
crypto = require('crypto'),
@@ -16,7 +14,7 @@ var UserSchema = new mongoose.Schema({
type: String,
required: true,
validate: [function (val) {
- val = val.replace(NONALPHANUMERICS_REGEX, "")
+ val = util.slugify(val)
this.username = val.toLowerCase()
switch (val) {
case 'login':
@@ -27,6 +25,7 @@ var UserSchema = new mongoose.Schema({
case 'about':
case 'settings':
case 'assets':
+ case 'staff':
case 'admin':
case 'terms':
case 'api':
@@ -39,7 +38,7 @@ var UserSchema = new mongoose.Schema({
return true
}, "{PATH} is not an acceptable name"]
},
- email: { type: String, efault: "" },
+ email: { type: String, default: "" },
emailVerified: {
type: Boolean,
default: false,
@@ -57,7 +56,11 @@ var UserSchema = new mongoose.Schema({
website: { type: String, default: "" },
twitterName: { type: String, default: "" },
facebookUrl: { type: String, default: "" },
- isAdmin: { type: Boolean, default: false }
+ isStaff: { type: Boolean, default: false },
+ created_at: { type: Date },
+ updated_at: { type: Date },
+ created_ip: { type: Number },
+ last_ip: { type: Number },
});
UserSchema.methods.validPassword = function (pw) {
diff --git a/server/lib/util.js b/server/lib/util.js
index 88d16cb..228563a 100644
--- a/server/lib/util.js
+++ b/server/lib/util.js
@@ -1,21 +1,56 @@
var _ = require('lodash');
+var whitespace = new RegExp('\s', 'g')
var whitespaceHead = /^\s+/
var whitespaceTail = /\s+$/
+var nonAlphanumerics = new RegExp('[^-_a-zA-Z0-9]', 'g')
+var consecutiveDashes = new RegExp("-+", 'g')
+var entities = new RegExp("[<>&]", 'g')
var util = {}
-util.trim = function (s){ return s.replace(whitespaceHead,"").replace(whitespaceTail,"") }
+
+util.trim = function (s){ return (s || "").replace(whitespaceHead,"").replace(whitespaceTail,"") }
+
+util.slugify = function (s){
+ return (s || "").replace(whitespace,"-").replace(nonAlphanumerics, '-').replace(consecutiveDashes,"-")
+}
+
+util.sanitize = function (s){
+ return (s || "").replace(entities, "")
+}
+
+util.capitalize = function (s) {
+ return (s || "").split(" ").map(util.capitalizeWord).join(" ");
+}
+
+util.capitalizeWord = function (s) {
+ return s.charAt(0).toUpperCase() + s.slice(1);
+}
+
util.cleanQuery = function (query) {
- var update = _.extend({}, query);
- delete update._id;
- delete update.created_at;
- delete update.modified_at;
- delete update.modified_by;
- delete update.created_by;
- return update;
+ var update = _.extend({}, query);
+ delete update._id;
+ delete update.created_at;
+ delete update.modified_at;
+ delete update.modified_by;
+ delete update.created_by;
+ return update;
}
+util.ip2num = function(dot) {
+ var d = dot.split('.');
+ return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
+}
+
+util.num2ip = function(num) {
+ var d = num % 256;
+ for (var i = 3; i > 0; i--) {
+ num = Math.floor(num/256);
+ d = num % 256 + '.' + d;
+ }
+ return d;
+}
module.exports = util
diff --git a/server/lib/views.js b/server/lib/views.js
index 224dd3f..94774cb 100644
--- a/server/lib/views.js
+++ b/server/lib/views.js
@@ -2,9 +2,20 @@
var User = require('./schemas/User'),
Project = require('./schemas/Project'),
+ Documentation = require('./schemas/Documentation'),
config = require('../../config'),
+ marked = require('marked'),
+ util = require('./util'),
_ = require('lodash');
+marked.setOptions({
+ renderer: new marked.Renderer(),
+ gfm: true,
+ sanitize: true,
+ smartLists: true,
+ smartypants: true,
+});
+
var views = {}
views.modal = function (req, res) {
@@ -17,6 +28,34 @@ views.home = function (req, res) {
})
}
+views.docs = function (req, res){
+ var name = req.params.name || "index"
+
+ if (name === "new") {
+ res.render('docs', {
+ doc: { name: "new" },
+ content: null,
+ isNew: true
+ })
+ return
+ }
+
+ Documentation.findOne({ name: name }, function(err, doc) {
+ if (err || ! doc) {
+ return res.render('docs', {
+ doc: { name: util.sanitize(name) },
+ content: null,
+ isNew: true
+ })
+ }
+ res.render('docs', {
+ doc: doc,
+ content: marked(doc.body),
+ isNew: false
+ })
+ })
+}
+
views.profile = function (req, res) {
var username = req.params[0] || req.user.username
if (username) {
@@ -43,4 +82,16 @@ views.profile = function (req, res) {
}
}
+views.staff = {
+ index: function(req, res){
+ res.render('staff')
+ },
+ bless: function(req, res){
+ req.user.isStaff = true
+ req.user.save(function(){
+ res.redirect("/staff")
+ })
+ },
+}
+
module.exports = views