basic setup
This commit is contained in:
parent
4102a5ff82
commit
e4b5f6158a
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
app.db
|
||||||
|
node_modules
|
52
app.js
52
app.js
@ -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
7
createdb.sh
Normal 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
26
db.js
@ -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
11
model.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
var DB = require('./db').DB;
|
||||||
|
var User = DB.Model.extend({
|
||||||
|
tableName: 'Users',
|
||||||
|
idAttribute: 'userId',
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
User: User
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
|
101
routes/index.js
101
routes/index.js
@ -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
4
views/404.jade
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
head
|
||||||
|
404
|
||||||
|
body
|
||||||
|
h1 404
|
13
views/signin.jade
Normal file
13
views/signin.jade
Normal 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
11
views/signup.jade
Normal 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
|
Loading…
Reference in New Issue
Block a user