basic setup

This commit is contained in:
ang-st 2015-03-30 22:04:08 +01:00
parent 4102a5ff82
commit e4b5f6158a
12 changed files with 238 additions and 7 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
app.db
node_modules

4
README.md Normal file
View File

@ -0,0 +1,4 @@
#kitteh wiki
simple wiki for thsf site

52
app.js
View File

@ -1,12 +1,51 @@
var Express = require('express'); var Express = require('express');
var Routes = require('./routes'); var Routes = require('./routes');
var passport = require('passport');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var bcrypt = require('bcrypt-nodejs');
var crypto = require('crypto');
var sqlite3 = require('sqlite3');
var Model = require('./model');
var LocalStrategy = require('passport-local').Strategy;
// var TryCatch = require('./trycatch'); // var TryCatch = require('./trycatch');
var App = Express(); var App = Express();
// Configuration // Configuration
passport.use(new LocalStrategy(function(username, password, done) {
new Model.User({username: username}).fetch().then(function(data) {
var user = data;
if(user === null) {
return done(null, false, {message: 'Invalid username or password'});
} else {
user = data.toJSON();
if(!bcrypt.compareSync(password, user.password)) {
return done(null, false, {message: 'Invalid username or password'});
} else {
return done(null, user);
}
}
});
}));
passport.serializeUser(function(user, done) {
done(null, user.username);
});
passport.deserializeUser(function(username, done) {
new Model.User({username: username}).fetch().then(function(user) {
done(null, user);
});
});
App.configure(function(){ App.configure(function(){
App.set('views', __dirname + '/views'); App.set('views', __dirname + '/views');
App.set('view engine', 'jade'); App.set('view engine', 'jade');
@ -14,6 +53,11 @@ App.configure(function(){
// App.use(function (req, res, next) { // App.use(function (req, res, next) {
// TryCatch(next, next); // TryCatch(next, next);
// }); // });
App.use(cookieParser());
App.use(bodyParser());
App.use(session({ secret: 'whenidrinktoomuchigetdrunk' })); // session secret
App.use(passport.initialize());
App.use(passport.session());
App.use(Express.bodyParser()); App.use(Express.bodyParser());
App.use(Express.methodOverride()); App.use(Express.methodOverride());
App.use(App.router); App.use(App.router);
@ -30,9 +74,15 @@ App.configure('production', function(){
// Routes // Routes
App.get('/', Routes.index); App.get('/', Routes.index);
App.get('/signin', Routes.signIn);
App.post('/signin', Routes.signInPost);
App.get('/signup', Routes.signUp);
App.post('/signup', Routes.signUpPost);
App.get('/signout', Routes.signout)
App.get('/:name', Routes.view); App.get('/:name', Routes.view);
App.get('/:name/edit', Routes.edit); App.get('/:name/edit', Routes.edit);
App.post('/:name', Routes.save); App.post('/:name', Routes.save);
server = App.listen(process.env.PORT || 3000); server = App.listen(process.env.PORT || 3000);
console.log("Express server listening on port %d in %s mode", server.address().port, App.settings.env); console.log("Express server listening on port %d in %s mode", server.address().port, App.settings.env);

7
createdb.sh Normal file
View File

@ -0,0 +1,7 @@
CREATE TABLE "users" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"username" TEXT,
"password" TEXT, -- sha256 hash of the plain-text password
"salt" TEXT -- salt that is appended to the password before it is hashed
)

26
db.js
View File

@ -1,6 +1,9 @@
var FS = require('fs'); var FS = require('fs');
var Path = require('path'); var Path = require('path');
var Markdown = require('markdown').markdown; var Markdown = require('markdown').markdown;
var knex = require("knex");
var Bookshelf = require('bookshelf');
// This function is used to map wiki page names to files // This function is used to map wiki page names to files
// on the real filesystem. // on the real filesystem.
@ -55,3 +58,26 @@ exports.savePage = function (name, value, callback) {
var path = pathFromName(name); var path = pathFromName(name);
FS.writeFile(path, value, callback); FS.writeFile(path, value, callback);
}; };
var dbFile = Path.join(__dirname, 'app.db');
var DB = Bookshelf(knex({
client: 'sqlite3',
connection: { filename: dbFile }
}));
FS.exists(dbFile, function(exists) {
if (!exists) {
console.log("create a new DB")
DB.knex.schema.createTable('Users', function(table) {
table.increments("id")
table.string('username')
table.string('password')
}).then( function(){ console.log("DB created") })
}
})
exports.DB = DB;

11
model.js Normal file
View File

@ -0,0 +1,11 @@
var DB = require('./db').DB;
var User = DB.Model.extend({
tableName: 'Users',
idAttribute: 'userId',
});
module.exports = {
User: User
};

View File

@ -3,9 +3,16 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.12.2",
"bookshelf": "^0.7.9",
"cookie-parser": "^1.3.4",
"express": "3.0.2", "express": "3.0.2",
"express-session": "^1.10.4",
"jade": ">= 0.0.1", "jade": ">= 0.0.1",
"knex": "^0.7.6",
"markdown": "~0.3.1", "markdown": "~0.3.1",
"passport-local": "^1.0.0",
"trycatch": "~0.0.9" "trycatch": "~0.0.9"
} }
} }

View File

@ -1,5 +1,4 @@
# Home Page ###Hello THSF
this is a simple wiki :)
This is the homepage of the wiki. ![](http://stuffpoint.com/lol-cats/image/29077-lol-cats-magical-kitteh.png)
Cool stuff here.

View File

@ -1,6 +1,8 @@
// Load our model abstraction so we can load and save pages in the wiki. // Load our model abstraction so we can load and save pages in the wiki.
var passport = require('passport');
var DB = require('../db'); var DB = require('../db');
var Model = require('../model')
var bcrypt = require('bcrypt-nodejs');
// When the wiki is initially loaded, simply redirect to the `home` page. // When the wiki is initially loaded, simply redirect to the `home` page.
exports.index = function(req, res) { exports.index = function(req, res) {
res.redirect("/home"); res.redirect("/home");
@ -16,16 +18,111 @@ exports.view = function (req, res, next) {
// Load a page from the database and render edit form // Load a page from the database and render edit form
exports.edit = function (req, res, next) { exports.edit = function (req, res, next) {
if(!req.isAuthenticated()) {
res.redirect('/signin');
}
else{
DB.loadPage(req.params.name, function (err, page) { DB.loadPage(req.params.name, function (err, page) {
if (err) return next(err); if (err) return next(err);
res.render('edit', page); res.render('edit', page);
}); });
}
}; };
// Save changes to a page and redirect to view page // Save changes to a page and redirect to view page
exports.save = function (req, res, next) { exports.save = function (req, res, next) {
if(!req.isAuthenticated()) {
res.redirect('/signin');
}
else {
DB.savePage(req.params.name, req.body.markdown, function (err) { DB.savePage(req.params.name, req.body.markdown, function (err) {
if (err) return next(err) if (err) return next(err)
res.redirect("/" + req.params.name); res.redirect("/" + req.params.name);
}); });
} }
}
var signIn = function(req, res, next) {
if(req.isAuthenticated()) res.redirect('/');
res.render('signin', {title: 'Sign In'});
};
var signInPost = function(req, res, next) {
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/signin'}, function(err, user, info) {
if(err) {
return res.render('signin', {title: 'Sign In', errorMessage: err.message});
}
if(!user) {
return res.render('signin', {title: 'Sign In', errorMessage: info.message});
}
return req.logIn(user, function(err) {
if(err) {
return res.render('signin', {title: 'Sign In', errorMessage: err.message});
} else {
return res.redirect('/');
}
});
})(req, res, next);
};
var signUp = function(req, res, next) {
if(req.isAuthenticated()) {
res.redirect('/');
} else {
res.render('signup', {title: 'Sign Up'});
}
};
var signUpPost = function(req, res, next) {
var user = req.body;
var usernamePromise = null;
usernamePromise = new Model.User({username: user.username}).fetch();
return usernamePromise.then(function(model) {
if(model) {
res.render('signup', {title: 'signup', errorMessage: 'username already exists'});
} else {
//****************************************************//
// MORE VALIDATION GOES HERE(E.G. PASSWORD VALIDATION)
//****************************************************//
var password = user.password;
var hash = bcrypt.hashSync(password);
var signUpUser = new Model.User({username: user.username, password: hash});
signUpUser.save().then(function(model) {
// sign in the newly registered user
signInPost(req, res, next);
});
}
});
};
var signOut = function(req, res, next) {
if(!req.isAuthenticated()) {
notFound404(req, res, next);
} else {
req.logout();
res.redirect('/signin');
}
};
// 404 not found
var notFound404 = function(req, res, next) {
res.status(404);
res.render('404', {title: '404 Not Found'});
};
exports.signIn=signIn
exports.signInPost=signInPost
exports.signUpPost=signUpPost
exports.signUp = signUp
exports.signOut= signOut
exports.notFound404 = notFound404

4
views/404.jade Normal file
View File

@ -0,0 +1,4 @@
head
404
body
h1 404

13
views/signin.jade Normal file
View File

@ -0,0 +1,13 @@
h2 signin
form(method='post', action="/signin")
if errorMessage
span= errorMessage
p
label(for="username") username
input(id="username", type="text",placeholder='username',required="true" ,name ='username')
p
label(for="password") password
input(id="password", type='text', placeholder='password', required="true", name = 'password')
p
input(type='submit',name="signin", id='signin')
a(href="/signup", title="register") signup

11
views/signup.jade Normal file
View File

@ -0,0 +1,11 @@
h2 signup
form(method='post', action="/signup")
p
label(for="username") username
input(id="username", type="text",placeholder='username',required="true", name="username")
p
label(for="password") password
input(id="password", type='text', placeholder='password', required="true", name="password")
p
input(type='submit',name="signup", id='signup', value='register')
a(href="/signin", title="signin") signin