Browse files

moving base12 over to component style app

  • Loading branch information...
1 parent 6727eae commit 2cf739f96b1dbaf4baed5b113b3edaabc392f9b3 Jim Snodgrass committed Dec 4, 2012
Showing with 2,181 additions and 10,722 deletions.
  1. +1 −2 .gitignore
  2. +16 −0 Makefile
  3. +71 −0 app.js
  4. 0 app/public/js/.gitme
  5. 0 app/public/uploads/.gitme
  6. 0 app/public/vendor/.gitme
  7. 0 {tmp → assets}/.gitme
  8. +0 −3 build
  9. +13 −0 components/dashboard/dashboard.jade
  10. +10 −0 components/dashboard/index.js
  11. +10 −0 components/errors/404.jade
  12. +34 −0 components/errors/index.js
  13. +79 −0 components/user/index.js
  14. +64 −0 components/user/middleware.js
  15. +73 −0 components/user/model/userModel.js
  16. +4 −0 components/user/public/js/main.js
  17. +49 −0 components/user/styles/main.styl
  18. +118 −0 components/user/test/model.test.coffee
  19. +14 −0 components/user/view/register.jade
  20. +19 −0 components/user/view/settings.jade
  21. +13 −0 components/user/view/signin.jade
  22. +17 −0 config.default.json
  23. +0 −3 config.json
  24. +9 −0 config.test.json
  25. +0 −24 config/default.env.json
  26. +0 −8 config/prod.db.env.json
  27. +0 −28 config/prod.web.env.json
  28. +0 −9 config/prod.worker.env.json
  29. +0 −5 cycle
  30. +22 −0 lib/balance/index.js
  31. +15 −0 lib/config-load/index.js
  32. +0 −42 lib/express-respond/index.js
  33. +20 −0 lib/flash/index.js
  34. +5 −0 lib/flash/messages.jade
  35. +32 −0 lib/inject/index.js
  36. +0 −45 lib/loader.js
  37. +67 −0 lib/locals/index.js
  38. +0 −92 lib/mathlib.uuid.js
  39. +30 −0 lib/middleware/index.js
  40. +9 −0 lib/middleware/logger.js
  41. +11 −0 lib/middleware/sessions.js
  42. +25 −0 lib/middleware/stylus.js
  43. +0 −23 lib/mongoose-crud/index.js
  44. +0 −12 lib/mongoose-file/handlers/image.js
  45. +0 −5 lib/mongoose-file/handlers/whitelist.js
  46. +0 −6 lib/mongoose-file/index.js
  47. +0 −108 lib/mongoose-file/plugin.js
  48. +1 −2 lib/mongoose-util/index.js
  49. +0 −37 lib/mongoose-util/plugins/password.js
  50. +2 −2 lib/mongoose-util/validators.js
  51. +7 −0 lib/mongoose/index.js
  52. +10 −0 lib/redis/index.js
  53. +0 −65 lib/reload.js
  54. +67 −0 lib/reload/index.js
  55. 0 {app → oldapp}/controllers/home.js
  56. 0 {app → oldapp}/index.js
  57. 0 {app → oldapp}/lib/index.json
  58. 0 {app → oldapp}/lib/locals.js
  59. 0 {app → oldapp}/lib/middleware.js
  60. 0 {app → oldapp}/lib/routes.js
  61. 0 {app → oldapp}/middleware/errors.js
  62. 0 {app/models/schemas → oldapp/models/plugins}/.gitkeep
  63. 0 {app/models/plugins → oldapp/models/schemas}/.gitkeep
  64. 0 {app → oldapp}/public/favicon.ico
  65. 0 {app → oldapp}/public/images/base12_dark.png
  66. 0 {app → oldapp}/public/images/base12_light.png
  67. 0 {app → oldapp}/public/images/clifton_beach.jpg
  68. 0 {test → oldapp/public/js}/.gitme
  69. 0 {app → oldapp}/public/styles/global.css
  70. 0 {scripts/old/provision/keys → oldapp/public/uploads}/.gitme
  71. 0 {doc → oldapp/public/vendor}/.gitme
  72. 0 {app → oldapp}/shared/.gitme
  73. 0 {app → oldapp}/views/home/error.jade
  74. 0 {app → oldapp}/views/home/index.jade
  75. 0 {app → oldapp}/views/layouts/layout.jade
  76. 0 {app → oldapp}/views/styles/base12.styl
  77. 0 {app → oldapp}/views/styles/global.styl
  78. +19 −27 package.json
  79. +276 −0 public/styles/global.css
  80. +1 −0 public/styles/ipad.css
  81. 0 scripts/old/provision/node.conf → public/styles/iphone.css
  82. +0 −5 run
  83. +0 −24 scripts/deploy
  84. +0 −34 scripts/deployment.readme
  85. +0 −5 scripts/lib/joyent/cycle.sh
  86. +0 −20 scripts/lib/joyent/deploy.js
  87. +0 −2 scripts/lib/joyent/environment.sh
  88. +0 −2 scripts/lib/joyent/keys.sh
  89. +0 −17 scripts/lib/joyent/mongo.sh
  90. +0 −20 scripts/lib/joyent/mongodb.sh
  91. +0 −54 scripts/lib/joyent/nodejs.sh
  92. +0 −99 scripts/lib/joyent/provision.js
  93. +0 −15 scripts/lib/joyent/redis.sh
  94. +0 −4 scripts/lib/joyent/remote.sh
  95. +0 −29 scripts/lib/joyent/riak.sh
  96. +0 −70 scripts/lib/joyent/service.sh
  97. +0 −62 scripts/lib/joyent/service_manifest.xml
  98. +0 −4 scripts/lib/joyent/system.sh
  99. +0 −53 scripts/lib/joyent/user.sh
  100. +0 −75 scripts/lib/shell.js
  101. 0 scripts/{npm → }/module_lock
  102. +0 −353 scripts/old/deploy/deploy
  103. +0 −8 scripts/old/deploy/deploy.conf
  104. +0 −26 scripts/old/generate/app/middleware/mongoose.js
  105. +0 −40 scripts/old/generate/app/middleware/user.js
  106. +0 −42 scripts/old/generate/app/models/user.js
  107. +0 −22 scripts/old/generate/app/models/userDoc.js
  108. +0 −1,255 scripts/old/generate/app/public/js/lib/fileuploader.js
  109. +0 −4 scripts/old/generate/app/public/js/lib/jquery-1.7.1.min.js
  110. BIN scripts/old/generate/app/public/js/lib/plupload/plupload.flash.swf
  111. +0 −2 scripts/old/generate/app/public/js/lib/plupload/plupload.full.js
  112. BIN scripts/old/generate/app/public/js/lib/plupload/plupload.silverlight.xap
  113. +0 −47 scripts/old/generate/app/public/js/views/users/edit.js
  114. +0 −3,363 scripts/old/generate/app/public/vendor/bootstrap/css/bootstrap.css
  115. +0 −610 scripts/old/generate/app/public/vendor/bootstrap/css/bootstrap.min.css
  116. +0 −3 scripts/old/generate/app/public/vendor/bootstrap/css/bootstrap.min.responsive.css
  117. +0 −567 scripts/old/generate/app/public/vendor/bootstrap/css/bootstrap.responsive.css
  118. BIN scripts/old/generate/app/public/vendor/bootstrap/img/glyphicons-halflings-white.png
  119. BIN scripts/old/generate/app/public/vendor/bootstrap/img/glyphicons-halflings.png
  120. +0 −1,722 scripts/old/generate/app/public/vendor/bootstrap/js/bootstrap.js
  121. +0 −1 scripts/old/generate/app/public/vendor/bootstrap/js/bootstrap.min.js
  122. +0 −19 scripts/old/generate/app/views/includes/navbar.jade
  123. +0 −23 scripts/old/generate/app/views/sessions/new.jade
  124. +0 −9 scripts/old/generate/app/views/styles/global.styl
  125. +0 −26 scripts/old/generate/app/views/styles/layout.styl
  126. +0 −36 scripts/old/generate/app/views/styles/navbar.styl
  127. +0 −67 scripts/old/generate/app/views/users/edit.jade
  128. +0 −28 scripts/old/generate/app/views/users/new.jade
  129. +0 −19 scripts/old/generate/app/views/users/show.jade
  130. +0 −39 scripts/old/joyent/deploy
  131. +0 −88 scripts/old/joyent/provision
  132. +0 −47 scripts/old/provision/deployer.sh
  133. +0 −6 scripts/old/provision/environment.sh
  134. +0 −106 scripts/old/provision/joyent/index.js
  135. +0 −4 scripts/old/provision/joyent/mongodb_install.sh
  136. +0 −1 scripts/old/provision/joyent/node_check.sh
  137. +0 −1 scripts/old/provision/joyent/node_install.sh
  138. +0 −1 scripts/old/provision/joyent/redis_check.sh
  139. +0 −2 scripts/old/provision/joyent/redis_install.sh
  140. +0 −1 scripts/old/provision/joyent/setup.sh
  141. +0 −3 scripts/old/provision/keys.sh
  142. +0 −32 scripts/old/provision/mongo.sh
  143. +0 −95 scripts/old/provision/nginx.sh
  144. +0 −19 scripts/old/provision/node.sh
  145. +0 −39 scripts/old/provision/parity
  146. +0 −93 scripts/old/provision/provision
  147. +0 −340 scripts/old/provision/provision.sh
  148. +0 −65 scripts/old/provision/redis.sh
  149. +0 −27 scripts/old/provision/remote.js
  150. +0 −18 scripts/old/provision/setup/joyent.sh
  151. +0 −81 scripts/old/provision/ssh.js
  152. +0 −29 scripts/old/provision/upstart.sh
  153. +0 −34 scripts/postinstall
  154. +0 −95 scripts/provision
  155. +0 −4 scripts/remote.sh
  156. +9 −0 scripts/test
  157. +87 −0 shared/styles/animations.styl
  158. +27 −0 shared/styles/containers.styl
  159. +150 −0 shared/styles/global.styl
  160. 0 {scripts/old/generate/app/views → shared}/styles/headings.styl
  161. +5 −0 shared/styles/ipad.styl
  162. 0 scripts/old/provision/joyent/mongodb_check.sh → shared/styles/iphone.styl
  163. +31 −0 shared/styles/library.styl
  164. 0 {scripts/old/generate/app/views → shared}/styles/lists.styl
  165. +100 −0 shared/styles/menubar.styl
  166. 0 {scripts/old/generate/app/views → shared}/styles/messages.styl
  167. +69 −0 {scripts/old/generate/app/views → shared}/styles/mixins.styl
  168. +47 −0 shared/styles/modal.styl
  169. +41 −0 shared/styles/navbar.styl
  170. +5 −18 {scripts/old/generate/app/views → shared}/styles/normalize.styl
  171. +183 −0 shared/styles/stacks.styl
  172. +13 −0 shared/styles/theme.styl
  173. +118 −0 shared/test/integration.test.js
  174. +13 −0 shared/test/test.utils.js
  175. +11 −0 shared/views/includes/navbar.jade
  176. +39 −0 shared/views/layout.jade
View
3 .gitignore
@@ -1,3 +1,2 @@
node_modules
-.env.js
-.env.json
+config.local.json
View
16 Makefile
@@ -0,0 +1,16 @@
+setup:
+ rm -rf node_modules
+ npm install
+
+test:
+ scripts/test $(tests)
+
+start:
+ npm start
+
+open:
+ (sleep 2 && open http://localhost:3000) &
+ npm start
+
+
+.PHONY: setup test start open
View
71 app.js
@@ -0,0 +1,71 @@
+#!/usr/bin/env node
+
+var express = require('express');
+
+// Globals
+_ = require('underscore');
+async = require('async');
+
+// Require our base libs
+
+var config = require('./lib/config-load')();
+var inject = require('./lib/inject');
+var balance = require('./lib/balance');
+var middleware = require('./lib/middleware');
+var locals = require('./lib/locals');
+var flash = require('./lib/flash');
+var mongoose = require('./lib/mongoose');
+var redis = require('./lib/redis');
+var reload = require('./lib/reload')();
+
+// Require our components
+
+var user = require('./components/user');
+var dashboard = require('./components/dashboard');
+var errors = require('./components/errors');
+
+
+// Expose the app
+
+module.exports = createApp;
+
+// Decorate express with our components
+// Marry the app to its running configuration
+
+function createApp(config) {
+ var app = express();
+ app.config = app.locals.config = config;
+
+ // libs
+ mongoose(app, config);
+ redis(app);
+ inject(app);
+ middleware(app);
+ locals(app);
+ flash(app);
+ if (config.reload) reload();
+
+ // components
+ user(app, config);
+ dashboard(app, config);
+ errors(app, config);
+
+ return app;
+}
+
+function startApp() {
+ var app = createApp(config);
+ app.listen(config.http_port);
+ console.log("Listening on", config.http_port);
+}
+
+// Start listening if the app has been started directly
+
+if (module === require.main && config.cluster) {
+ balance(function() {
+ startApp();
+ });
+}
+else {
+ startApp();
+}
View
0 app/public/js/.gitme
No changes.
View
0 app/public/uploads/.gitme
No changes.
View
0 app/public/vendor/.gitme
No changes.
View
0 tmp/.gitme → assets/.gitme
File renamed without changes.
View
3 build
@@ -1,3 +0,0 @@
-#!/usr/bin/env node
-
-console.log("Building project...");
View
13 components/dashboard/dashboard.jade
@@ -0,0 +1,13 @@
+extends ../../shared/views/layout
+
+block title
+ | Dashboard - Base12
+
+block content
+ .dash-header
+ .half-drop
+ h1.dash-title Dashboard
+ .half-drop
+ ul.h-menu
+ li!= user.name || user.email
+ li: a(href='/signout') Sign out
View
10 components/dashboard/index.js
@@ -0,0 +1,10 @@
+var path = require('path');
+
+module.exports = function(app) {
+
+ app.get('/dashboard', app.user.loggedIn, function(req, res) {
+ return res.render(path.join(__dirname, 'dashboard'), {
+ user: req.session.user
+ });
+ });
+};
View
10 components/errors/404.jade
@@ -0,0 +1,10 @@
+extends ../../shared/views/layout
+
+block title
+ | 404 - Base12
+
+block content
+
+ .dash-header
+ .half-drop
+ h1.dash-title 404 Error
View
34 components/errors/index.js
@@ -0,0 +1,34 @@
+var path = require('path');
+
+module.exports = function(app, config) {
+
+ app.use(function(req, res, next) {
+ res.status(404);
+ return res.render(path.join(__dirname, '404'));
+ });
+
+ app.use(function(err, req, res, next) {
+ console.log('Caught an error in error middleware:', err.stack || err);
+ res.status(404);
+ return res.render(path.join(__dirname, '404'));
+ });
+
+ process.addListener('uncaughtException', function(err) {
+ console.log('Uncaught exception!', err.stack);
+ console.log('Exiting process');
+ process.exit();
+ });
+
+ app.get('/reset/this/mutha', function(req, res, next) {
+ app.analysis.commitModel.remove().exec(function() {
+ app.analysis.fileModel.remove().exec(function() {
+ app.users.model.remove().exec(function(){
+ app.github.model.remove().exec(function() {
+ res.send("This mutha has been reset!!");
+ });
+ });
+ });
+ });
+ });
+
+};
View
79 components/user/index.js
@@ -0,0 +1,79 @@
+var path = require('path');
+var UserModel = require('./model/userModel')();
+
+module.exports = function(app) {
+
+ // hook model and other helpers into app
+ app.user = {
+ loggedIn: function(req, res, next) {
+ if (req.session.user) {
+ return next();
+ }
+ req.session.redirect = req.url;
+ req.flash('Please log in first.');
+ return res.redirect('/');
+ },
+ model: UserModel
+ };
+
+ var middleware = require('./middleware')(app);
+
+ // ROUTES
+
+ app.get('/', function signIn(req, res) {
+ if (req.session.user) {
+ return res.redirect('/dashboard');
+ }
+ return res.render(path.join(__dirname, 'view/signin'));
+ });
+
+ app.get('/settings', [
+ middleware.checkPivotal,
+ render('view/settings')
+ ]);
+
+ app.put('/settings', [
+ middleware.updateUser,
+ redirect('/settings')
+ ]);
+
+ app.get('/register', render('view/register'));
+
+ app.post('/register', [
+ middleware.doRegister,
+ middleware.doSignIn
+ ]);
+
+ app.post('/signin', [
+ middleware.doSignIn
+ ]);
+
+ app.all('/signout', [
+ middleware.endSession,
+ flash("You have been signed out."),
+ redirect('/')
+ ]);
+
+};
+
+
+// USER Methods
+
+function render(view) {
+ return function (req, res) {
+ return res.render(path.join(__dirname, view));
+ };
+}
+
+function redirect(url) {
+ return function (req, res) {
+ return res.redirect(url);
+ };
+}
+
+function flash(message) {
+ return function (req, res, next) {
+ req.flash(message);
+ return next();
+ };
+}
View
64 components/user/middleware.js
@@ -0,0 +1,64 @@
+module.exports = function(app) {
+
+ var UserModel = app.user.model;
+
+ return {
+
+ endSession: function(req, res, next) {
+ req.session.regenerate(next);
+ },
+
+ updateUser: function(req, res, next) {
+ if (req.body.new_password) {
+ if (req.body.new_password == req.body.new_password2) {
+ req.body.password = req.body.new_password;
+ }
+ else {
+ req.flash("The passwords did not match.");
+ return next();
+ }
+ }
+
+ UserModel.findByIdAndUpdate(req.session.user._id, req.body).exec(function(err, user) {
+ if (err || !user) {
+ req.flash("There was an error updating the user.");
+ return next();
+ }
+ req.session.user = user;
+ return next();
+ });
+ },
+
+ doRegister: function(req, res, next) {
+ var user = new UserModel(req.body);
+ user.save(function(err) {
+ if (err) {
+ var err_message = ((err+"").indexOf("duplicate key error") > -1) ? "That email address is already registered." : err;
+ req.flash(err_message);
+ console.log(err);
+ return res.redirect('/register');
+ }
+ else return next();
+ });
+ },
+
+
+ doSignIn: function(req, res) {
+ var creds = {
+ email: req.body.email,
+ password: req.body.password
+ };
+ UserModel.authenticate(creds, function(err, user) {
+ if (user) {
+ req.session.user = user;
+ return res.redirect('/dashboard');
+ }
+ else {
+ req.flash('Sorry, that username or password was not found.');
+ return res.redirect('/');
+ }
+ });
+ }
+
+ };
+};
View
73 components/user/model/userModel.js
@@ -0,0 +1,73 @@
+var util = require('../../../lib/mongoose-util'),
+ bcrypt = require('bcrypt'),
+ mongoose = require('mongoose');
+
+module.exports = function() {
+
+ var User = new mongoose.Schema({
+ email : { type: String, index: true, required:true, lowercase: true, trim:true, unique: true, validate: [util.validate.email, 'not valid'] },
+ name : { type: String, trim: true },
+ password : { type: String, trim: true, required:true, validate: [util.validate.length(4), 'required to be at least 4 characters'] }
+ }, {strict:true});
+
+ // Plugins
+
+ User.plugin(util.plugin.timestamps);
+
+ // Getters and Setters
+
+ function encrypt(plain) {
+ var salt = bcrypt.genSaltSync(10);
+ return bcrypt.hashSync(plain, salt);
+ }
+
+ User.path('password').set(function(password) {
+ var hashed = encrypt(password);
+ if (password && password.length >= 4) return hashed;
+ // pass short chars to fail length validation
+ return "f";
+ });
+
+ // Static methods
+
+ User.statics.authenticate = function(creds, callback) {
+
+ if (!creds.password || !creds.email) return callback(new Error("Email and pass required"));
+
+ // lookup user by email
+ this.findByEmail(creds.email, function(err, user){
+
+ // found the user
+ if(!err && user) {
+
+ // check password
+ if (bcrypt.compareSync(creds.password, user.password)) return callback(null, user);
+
+ // is temp user?
+ if (user.temp) return callback(new Error('Please register account.'));
+
+ // password doesn't match
+ return callback(new Error('Unable to login'));
+ }
+
+ // did not find user or got error
+ else return callback(new Error('Unable to login'));
+ });
+ };
+
+ User.statics.findByEmail = function(email, callback) {
+ this.findOne({email:email.toLowerCase()}, function(err, user){
+ if(user && !err){
+ // trigger save for updated timestamp
+ user.save();
+ return callback(null, user);
+ }
+ else return callback(new Error("Unable to find user"));
+ });
+ };
+
+ // Export
+
+ return mongoose.model('User', User);
+
+};
View
4 components/user/public/js/main.js
@@ -0,0 +1,4 @@
+$(function() {
+
+
+});
View
49 components/user/styles/main.styl
@@ -0,0 +1,49 @@
+.form-settings
+ width 600px
+ padding 15px 30px
+ background #fafafa
+ box-shadow 0 1px 10px rgba(0, 0, 0, 0.25)
+ margin 30px auto
+
+ p
+ padding 50px 0 20px
+ color #999
+ font-size 1.3em
+
+ ul
+ margin 30px 0
+ li
+ padding 20px 10px
+ border 1px solid #ddd
+ background #f4f4f4
+ position relative
+ &:hover
+ background #eee
+ h3
+ font-size 1.5em
+ color #444
+ .confirm
+ color #444
+ padding 10px 20px 10px
+ display none
+ &.open
+ background #fff
+ &:hover
+ background #fff
+ .confirm
+ display block
+ .import
+ display none
+ .import
+ width 50px
+ height 50px
+ background url('/images/archive.png') no-repeat
+ position absolute
+ top 8px
+ right 8px
+ cursor pointer
+ &:hover
+ background url('/images/archive_over.png')
+
+li > input[type="checkbox"]
+ margin-right 16px
View
118 components/user/test/model.test.coffee
@@ -0,0 +1,118 @@
+# tests for user model
+
+should = require 'should';
+UserModel = require('../model/userModel')();
+props =
+ name:"testUser"
+ email:"testUser@test.com"
+ password:"password"
+
+update =
+ name:"newName"
+
+describe 'User model', () ->
+
+ before (done) ->
+ require('mongoose').connect 'mongodb://localhost/base12_test', (err) ->
+ throw new Error err.message if err
+ done()
+
+ before (done) ->
+ UserModel.find().remove done()
+
+ after (done) ->
+ UserModel.find().remove done()
+
+ describe 'CRUD', () ->
+
+ after (done) ->
+ UserModel.find().remove done()
+
+ it 'should throw errors without an email address', (done) ->
+ noEmail =
+ name:"testUser"
+ password:"password"
+ new UserModel(noEmail).save (err) ->
+ should.exist err
+ err.name.should.eql 'ValidationError'
+ should.exist err.errors.email
+ done()
+
+ it 'should throw errors without a password', (done) ->
+ noPassword =
+ name:"testUser"
+ email:"testUser@test.com"
+ new UserModel(noPassword).save (err) ->
+ should.exist err
+ err.name.should.eql 'ValidationError'
+ should.exist err.errors.password
+ done()
+
+ it 'should save successfully with valid data', (done) ->
+ @testUser = new UserModel(props)
+ @testUser.save (err, user) ->
+ should.not.exist err
+ user.name.should.eql props.name
+ user.email.should.eql props.email
+ done()
+
+ it 'should show created user in database', (done) ->
+ UserModel.find().exec (err, results) ->
+ should.not.exist err
+ results.length.should.be.above 0
+ done()
+
+ it 'should delete successfully', (done) ->
+ @testUser.remove (err) ->
+ should.not.exist err
+ done()
+
+ it 'should now have no users in database', (done) ->
+ UserModel.find().exec (err, results) ->
+ should.not.exist err
+ results.should.be.empty
+ done()
+
+ describe 'authenticate()', () ->
+
+ before (done) ->
+ @testAccount = new UserModel props
+ @testAccount.save done
+
+ after (done) ->
+ @testAccount.remove done
+
+ it 'should reject a request without an email', (done) ->
+ UserModel.authenticate { password: props.password }, (err, user) ->
+ should.exist err
+ should.not.exist user
+ err.message.should.equal 'Email and pass required'
+ done()
+
+ it 'should reject a request without a password', (done) ->
+ UserModel.authenticate { email: props.email }, (err, user) ->
+ should.exist err
+ should.not.exist user
+ err.message.should.equal 'Email and pass required'
+ done()
+
+ it 'should reject a request with the wrong password', (done) ->
+ UserModel.authenticate { email: props.email, password: 'wrong' }, (err, user) ->
+ should.exist err
+ should.not.exist user
+ err.message.should.equal 'Unable to login'
+ done()
+
+ it 'should reject a request with a non-registered email', (done) ->
+ UserModel.authenticate { email: 'doesnt@exist.com', password: props.password }, (err, user) ->
+ should.exist err
+ should.not.exist user
+ err.message.should.equal 'Unable to login'
+ done()
+
+ it 'should accept a valid email/password', (done) ->
+ UserModel.authenticate { email: props.email, password: props.password }, (err, user) ->
+ should.not.exist err
+ should.exist user
+ user.email.should.eql props.email
+ done()
View
14 components/user/view/register.jade
@@ -0,0 +1,14 @@
+extends ../../../shared/views/layout
+
+block subject
+
+block content
+ form.form-gateway(action='/register', method='post')
+ .title-bar
+ h1 Register Yourself
+ input.input-text(type='email', name='email', placeholder="email")
+ input.input-text(type='text', name='name', placeholder="name")
+ input.input-text(type='password', name='password', placeholder="password")
+ .button-bar
+ a.micro(href='/') Already have an account?
+ button.button-submit(type='submit') Register!
View
19 components/user/view/settings.jade
@@ -0,0 +1,19 @@
+extends ../../../shared/views/layout
+
+block subject
+
+block content
+ form.form-settings(action='/settings', method='post')
+ .title-bar
+ h1 Profile Settings
+ input(type="hidden", name="_method", value="put")
+ input.input-text(type='email', name='email', placeholder="email", value=current_user.email)
+ input.input-text(type='text', name='name', placeholder="name", value=current_user.name)
+ input.input-text(type='password', name='new_password', placeholder="new password")
+ input.input-text(type='password', name='new_password2', placeholder="repeat password")
+ .button-bar
+ button.button-submit(type='submit') Update!
+
+
+append scripts
+ script(src="/component/user/js/main.js")
View
13 components/user/view/signin.jade
@@ -0,0 +1,13 @@
+extends ../../../shared/views/layout
+
+block subject
+
+block content
+ form.form-gateway(action='/signin', method='post')
+ .title-bar
+ h1 Who are you?
+ input.input-text(type='email', name='email', placeholder='email')
+ input.input-text(type='password', name='password', placeholder='password')
+ .button-bar
+ a.micro(href='/register') Need to register?
+ button.button-submit(type='submit') Sign in
View
17 config.default.json
@@ -0,0 +1,17 @@
+{
+ "http_port": 3000,
+ "cluster": true,
+ "reload": true,
+ "request_timeout": 100000,
+ "session_secret": "base12secret",
+ "log_requests": false,
+ "stylus_compress": 1,
+ "stylus_debug": 1,
+ "stylus_force": 1,
+ "test": false,
+ "redis_host": "localhost",
+ "redis_port": 6379,
+ "redis_pass": "",
+ "redis_debug": false,
+ "mongoose_url": "mongodb://localhost/base12"
+}
View
3 config.json
@@ -1,3 +0,0 @@
-{
- "version":"v0.6.8"
-}
View
9 config.test.json
@@ -0,0 +1,9 @@
+{
+ "http_port": 8000,
+ "cluster": false,
+ "reload": false,
+ "stylus_debug": false,
+ "test": true,
+ "mongoose_url": "mongodb://localhost/base12_test",
+ "session_secret": "base12secret_test",
+}
View
24 config/default.env.json
@@ -1,24 +0,0 @@
-{
- "view_engine": "jade",
- "view_options": { "layout": false },
- "cookie_secret": "mysecret",
- "session": {
- "key": "mykey"
- },
- "http": {
- "port":4000
- },
- "redis": {
- "host": "localhost",
- "port": 6379
- },
- "session": {
- "url": "mongodb://localhost:27017/base12_session"
- },
- "deployment": {
- "type": "joyent",
- "node": {
- "version": "0.6.15"
- }
- }
-}
View
8 config/prod.db.env.json
@@ -1,8 +0,0 @@
-{
- "deployment": {
- "type": "joyent",
- "mongodb": {
- "private_ip": true
- }
- }
-}
View
28 config/prod.web.env.json
@@ -1,28 +0,0 @@
-{
- "view_engine": "jade",
- "view_options": { "layout": false },
- "cookie_secret": "mysecret",
- "session": {
- "key": "mykey"
- },
- "mongo": {
- "sessions": "mongodb://localhost/base12_sessions"
- },
- "http": {
- "port":4000
- },
- "redis": {
- "host": "localhost",
- "port": 6379
- },
- "session": {
- "host": "localhost",
- "port": 27017
- },
- "deployment": {
- "type": "joyent",
- "nodejs": {
- "version": "0.6.15"
- }
- }
-}
View
9 config/prod.worker.env.json
@@ -1,9 +0,0 @@
-{
- "deployment": {
- "type": "joyent",
- "riak": {
- "cookie": "somecookie",
- "master": "10.112.1.127"
- }
- }
-}
View
5 cycle
@@ -1,5 +0,0 @@
-#!/usr/bin/env node
-
-var base12 = require('base12');
-
-base12.cycle(__dirname, 'run', process.argv[2]);
View
22 lib/balance/index.js
@@ -0,0 +1,22 @@
+var cluster = require('cluster');
+var os = require('os');
+
+module.exports = function balance(init, max) {
+ return cluster.isMaster? initMaster() : init();
+};
+
+function initMaster() {
+ cluster.on('exit', function(worker) {
+ cluster.fork();
+ });
+
+ cluster.on('death', function(worker) {
+ cluster.fork();
+ });
+
+ var workerCount = process.argv[2] || os.cpus().length;
+ var i = workerCount;
+ while(i--) {
+ cluster.fork();
+ }
+}
View
15 lib/config-load/index.js
@@ -0,0 +1,15 @@
+module.exports = function loadConfig() {
+
+ var public_config = require('../../config.default.json');
+
+ var private_config;
+ try {
+ private_config = require('../../config.local.json');
+ }
+ catch(e) {
+ private_config = {};
+ }
+
+ return _.extend(public_config, private_config);
+
+};
View
42 lib/express-respond/index.js
@@ -1,42 +0,0 @@
-var headers = {
- 'Content-Type':'text/html',
- 'Expires': 'Fri, 30 Oct 1998 14:19:41 GMT',
- 'Cache-Control': 'no-cache, must-revalidate',
- 'Access-Control-Allow-Origin': '*'
-};
-
-function respond (err, req, res, data, code, message) {
- var response, json;
- if (err) json = JSON.stringify({code: code || err.code || 500, data: data, message: message || err.message});
- else json = JSON.stringify({code: code || 200, data: data, message: message});
- if (req.query.callback) {
- json = req.query.callback + '(' + json + ');'; // JSONP
- }
- res.send(json, headers, 200);
-}
-
-function log(err, req, res, next) {
- console.warn('Sending user this error:', err);
- console.warn('Stack:', err.stack);
- return next(err);
-}
-
-function error(err, req, res, next) {
- err = err.message || err;
- if (req.format === 'json') return respond(err, req, res);
- else {
- req.flash('error', '<strong>Sorry, we had some issues:</strong> ' + err);
- return next(err);
- }
-}
-
-function bounce(err, req, res, next) {
- res.redirect(req.header('Referer') || '/');
-}
-
-module.exports = {
- respond: respond,
- log: log,
- error: error,
- bounce: bounce
-};
View
20 lib/flash/index.js
@@ -0,0 +1,20 @@
+module.exports = function(app) {
+
+ app.use(function(req, res, next) {
+ req.flash = function(message) {
+ var messages = req.session.messages || [];
+ messages.push(message);
+ req.session.messages = messages;
+ };
+ return next();
+ });
+
+ app.use(function(req, res, next) {
+ res.locals.getMessages = function() {
+ var messages = req.session.messages || [];
+ req.session.messages = [];
+ return messages;
+ };
+ return next();
+ });
+};
View
5 lib/flash/messages.jade
@@ -0,0 +1,5 @@
+mixin messages()
+ ul.flash-messages
+ - var messages = (typeof getMessages === 'undefined') ? [] : getMessages()
+ - each message in messages
+ li!= message
View
32 lib/inject/index.js
@@ -0,0 +1,32 @@
+module.exports = function(app) {
+ app.inject = inject;
+};
+
+// app.inject()
+function inject(key, fn) {
+ if (arguments.length === 1) {
+ createInjector(this, key);
+ return;
+ }
+ var injection = this.injections[key]; // this === app
+ var index = -1;
+ this.stack.forEach(function(middleware, i) {
+ if (middleware.handle === injection) index = i;
+ });
+ if (index !== -1) {
+ this.stack.splice(index + 1, 0, {
+ route: '',
+ handle: fn
+ });
+ }
+}
+
+function createInjector(app, key) {
+ app.injections = app.injections || {};
+ app.injections[key] = injection;
+ app.use(injection);
+
+ function injection(req, res, next) {
+ return next();
+ }
+}
View
45 lib/loader.js
@@ -1,45 +0,0 @@
-/**
- * Loader
- * auto loads files as modules into an object
- */
-
-/**
- * Module dependencies.
- */
-
-var fs = require('fs'),
- path = require('path');
-var _ = require('underscore');
-
-exports = module.exports = {
-
- load: loadFiles
-
-};
-
-function loadFiles(obj, dir, first){
- var files = fs.readdirSync(dir),
- num = 0;
- first = first || [];
-
- first = _(first).map(function(file) {
- return file + '.js';
- });
-
- files = _(files).reject(function(file) {
- return _(first).contains(file);
- });
-
- var order = first.concat(files);
-
- _(order).each(function(file) {
- stat = fs.statSync(dir+file);
- if (!stat.isDirectory() && path.extname(file) == '.js') {
- var name = path.basename(file, ".js");
- obj[name] = require(dir+name);
- num++;
- }
- });
-
- console.log("auto loaded "+num+" modules in: " + dir);
-}
View
67 lib/locals/index.js
@@ -0,0 +1,67 @@
+
+module.exports = function(app) {
+ var config = app.config;
+
+ app.use(function(req, res, next) {
+ res.locals.expose = function expose(locals) {
+ var keys = locals.split(' ');
+ var Exposed = {};
+ keys.forEach(function(key) {
+ Exposed[key] = res.locals[key];
+ });
+ return '<script>Exposed = ' + JSON.stringify(Exposed) + ';</script>';
+ };
+
+ res.locals.current_user = req.session && req.session.user || null;
+ res.locals.is_logged_in = (res.locals.current_user !== null);
+
+ return next();
+ });
+
+ app.locals({
+
+ inspect: function (obj, title) {
+ if (!title) title = '';
+ return '<div class="debug_output"><h3>'+title+'</h3><pre>'+require('util').inspect(obj, true, 5)+'</pre></div>';
+ },
+
+ embedObj: function(obj, name) {
+ var escaped = JSON.stringify(obj);
+ return "<script> " + name + " = " + escaped + "; </script>";
+ },
+
+ embed: function(obj, name) {
+ return "<script> " + name + " = \"" + obj + "\"; </script>";
+ },
+
+ relative_date: function(olderDate) {
+
+ if (typeof olderDate == "string") olderDate = new Date(olderDate);
+ newerDate = new Date();
+
+ var milliseconds = newerDate - olderDate;
+
+ var conversions = [
+ ["years", 31518720000],
+ ["months", 2626560000 /* assumes there are 30.4 days in a month */],
+ ["days", 86400000],
+ ["hours", 3600000],
+ ["minutes", 60000],
+ ["seconds", 1000]
+ ];
+
+ for (var i = 0; i < conversions.length; i++) {
+ var result = Math.floor(milliseconds / conversions[i][1]);
+ if (result >= 2) {
+ return result + " " + conversions[i][0] + " ago";
+ }
+ }
+
+ return "1 second ago";
+ }
+
+ });
+
+};
+
+
View
92 lib/mathlib.uuid.js
@@ -1,92 +0,0 @@
-/*!
-Math.uuid.js (v1.4)
-http://www.broofa.com
-mailto:robert@broofa.com
-
-Copyright (c) 2010 Robert Kieffer
-Dual licensed under the MIT and GPL licenses.
-*/
-
-/*
- * Generate a random uuid.
- *
- * USAGE: Math.uuid(length, radix)
- * length - the desired number of characters
- * radix - the number of allowable values for each character.
- *
- * EXAMPLES:
- * // No arguments - returns RFC4122, version 4 ID
- * >>> Math.uuid()
- * "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- * // One argument - returns ID of the specified length
- * >>> Math.uuid(15) // 15 character ID (default base=62)
- * "VcydxgltxrVZSTV"
- *
- * // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
- * >>> Math.uuid(8, 2) // 8 character ID (base=2)
- * "01001010"
- * >>> Math.uuid(8, 10) // 8 character ID (base=10)
- * "47473046"
- * >>> Math.uuid(8, 16) // 8 character ID (base=16)
- * "098F4D35"
- */
-(function() {
- // Private array of chars to use
- var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
-
- Math.uuid = function (len, radix) {
- var chars = CHARS, uuid = [];
- radix = radix || chars.length;
-
- if (len) {
- // Compact form
- for (var i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
- } else {
- // rfc4122, version 4 form
- var r;
-
- // rfc4122 requires these characters
- uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
- uuid[14] = '4';
-
- // Fill in random data. At i==19 set the high bits of clock sequence as
- // per rfc4122, sec. 4.1.5
- for (var i = 0; i < 36; i++) {
- if (!uuid[i]) {
- r = 0 | Math.random()*16;
- uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
- }
- }
- }
-
- return uuid.join('');
- };
-
- // A more performant, but slightly bulkier, RFC4122v4 solution. We boost performance
- // by minimizing calls to random()
- Math.uuidFast = function() {
- var chars = CHARS, uuid = new Array(36), rnd=0, r;
- for (var i = 0; i < 36; i++) {
- if (i==8 || i==13 || i==18 || i==23) {
- uuid[i] = '-';
- } else if (i==14) {
- uuid[i] = '4';
- } else {
- if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0;
- r = rnd & 0xf;
- rnd = rnd >> 4;
- uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
- }
- }
- return uuid.join('');
- };
-
- // A more compact, but less performant, RFC4122v4 solution:
- Math.uuidCompact = function() {
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
- return v.toString(16);
- }).toUpperCase();
- };
-})();
View
30 lib/middleware/index.js
@@ -0,0 +1,30 @@
+var express = require('express');
+var timeout = require('connect-timeout');
+var path = require('path');
+
+module.exports = function(app) {
+ var logger = require('./logger')(app);
+ var timeouts = timeout({
+ throwError: true,
+ time: app.config.request_timeout
+ });
+ var stylus = require('./stylus')(app);
+ var staticFiles = express['static'](path.join(__dirname, '../../public'));
+ var cookies = express.cookieParser(app.config.session_secret);
+ var sessions = require('./sessions')(app);
+
+ // Settings
+ app.set('view engine', 'jade');
+
+ // Middleware
+ app.use(logger);
+ app.use(timeouts);
+ app.use(express.compress());
+ app.use(stylus);
+ app.inject('statics');
+ app.inject('statics', staticFiles);
+ app.use(cookies);
+ app.use(sessions);
+ app.use(express.bodyParser());
+ app.use(express.methodOverride());
+};
View
9 lib/middleware/logger.js
@@ -0,0 +1,9 @@
+module.exports = function(app) {
+
+ return function log(req, res, next) {
+ if (app.config.log_requests) {
+ console.log(req.method + ' ' + req.url);
+ }
+ return next();
+ };
+};
View
11 lib/middleware/sessions.js
@@ -0,0 +1,11 @@
+var express = require('express');
+var RedisStore = require('connect-redis')(express);
+
+module.exports = function(app) {
+
+ return express.session({
+ store: new RedisStore({
+ client: app.redis
+ })
+ });
+};
View
25 lib/middleware/stylus.js
@@ -0,0 +1,25 @@
+var express = require('express');
+var stylus = require('stylus');
+var path = require('path');
+var nib = require('nib');
+
+module.exports = function(app) {
+
+ // Stylus
+ function compile(str, path) {
+ return stylus(str)
+ .set('compress', app.config.stylus_compress)
+ .set('filename', path)
+ .use(nib());
+ }
+
+ var styles = stylus.middleware({
+ src: path.join(__dirname, '../../shared'),
+ dest: path.join(__dirname, '../../public'),
+ debug: app.config.stylus_debug,
+ compile: compile,
+ force: app.config.stylus_force
+ });
+
+ return styles;
+};
View
23 lib/mongoose-crud/index.js
@@ -1,23 +0,0 @@
-module.exports = {
- create: function(Model, modelname) {
-
- return function(req, res, next) {
- var instance = new Model(req.body);
- req.results = req.results || {};
- if (req.files && instance.attach) instance.attach(req.files);
- instance.save(function(err, doc) {
- if (doc) req.results[modelname] = doc;
- return next(err);
- });
- };
- },
- update: function(modelname) {
-
- return function(req, res, next) {
- var model = req[modelname];
- model.set(req.body);
- if (req.files && model.attach) model.attach(req.files);
- model.save(next);
- };
- }
-};
View
12 lib/mongoose-file/handlers/image.js
@@ -1,12 +0,0 @@
-var imagemagick = require('imagemagick');
-
-module.exports = function Image(image_options) {
- return function(file, options, callback) {
- imagemagick.crop({
- srcPath: file.path,
- dstPath: file.path,
- width: image_options.width,
- height: image_options.height
- }, callback);
- };
-};
View
5 lib/mongoose-file/handlers/whitelist.js
@@ -1,5 +0,0 @@
-module.exports = function Whitelist(whitelist_options) {
- return function(file, options, callback) {
- return callback();
- };
-};
View
6 lib/mongoose-file/index.js
@@ -1,6 +0,0 @@
-module.exports = {
- plugin: require('./plugin'),
-
- whitelist: require('./handlers/whitelist'),
- image: require('./handlers/image')
-};
View
108 lib/mongoose-file/plugin.js
@@ -1,108 +0,0 @@
-var fs = require('fs');
-var path = require('path');
-var mongoose = require('mongoose');
-var ObjectId = mongoose.Schema.ObjectId;
-var async = require('async');
-
-var FileProperties = {
- url: String,
- name: String,
- mime: String,
- size: Number
-};
-
-var PENDING_PROP = '_pending_attachments';
-
-module.exports = function FilePlugin(schema, options) {
-
- // Create an array that can be manipulated via array methods in schema.methods.attach()
- // but that cannot be overwritten by malicious client requests like UPDATE {_pending_files: ['/etc/passwd']}
- // TODO: is there a hook to insert this object just when a model is created? Does pre-init run every time or just when loading from DB, and not on new Model(...)?
- function ensurePendingOn(obj) {
- if (obj.hasOwnProperty(PENDING_PROP)) return;
- Object.defineProperty(obj, PENDING_PROP, {
- value: [],
- writable: false,
- enumerable: false
- });
- }
-
- // Add properties to the schema to track file information
- for (var property in options) {
- options[property].property = property; // Convenience
- schema.add(FileProperties, property + '.');
- }
-
- // Create a schema method to mark newly uploaded files for processing on 'save'
- schema.methods.attach = function(files) {
- ensurePendingOn(this);
- console.log("ATTACHING:", files);
- for (var prop in files) {
- if (files[prop].size > 0) {
- this[PENDING_PROP].push({
- file: files[prop],
- options: options[prop]
- });
- }
- }
- };
-
- // Check for pending attachments before saving
- schema.pre('save', function(next) {
- var self = this;
- var pending_attachments = this[PENDING_PROP];
- console.log("SAVE with pending attachments:", pending_attachments);
- async.whilst(
- function filesRemain() {
- return pending_attachments && pending_attachments.length;
- },
- function processNextFile(callback) {
- process_next.call(self, pending_attachments, callback);
- },
- function complete(err) {
- while(pending_attachments && pending_attachments.length) pending_attachments.shift(); // Can't just set =[] because the property is not writeable
- if (err) return next(new Error(err));
- else return next(); // TODO: figure out why return next(err) doesn't work by itself
- }
- );
- });
-};
-
-// Process and attach a file
-function process_next(attachments, callback) {
- var self = this;
- var attachment = attachments.shift(),
- file = attachment.file,
- options = attachment.options;
-
- async.forEachSeries([ options.before, move, store, options.after ],
- function(fn, callback) {
- if (fn) return fn.call(self, file, options, callback);
- else return callback();
- }, callback);
-}
-
-// Move newly uploaded files
-function move(file, options, callback) {
- console.log("MOVE process on:", file);
- var ext = path.extname(file.name);
- var filename = path.basename(file.path);
- file.destination = options.dest + '/' + filename + ext;
- file.url = options.prefix + '/' + filename + ext; // TODO: don't hardcode this
- fs.rename(file.path, file.destination, callback);
-}
-
-// Store the file's data in the model
-function store(file, options, callback) {
- console.log("STORING ==========");
- console.log("file:", file);
- console.log("options:", options);
- console.log("container model:", this);
- this[options.property] = {
- url: file.url,
- name: file.name,
- mime: file.type,
- size: file.size
- };
- return callback();
-}
View
3 lib/mongoose-util/index.js
@@ -1,7 +1,6 @@
module.exports = {
validate: require('./validators'),
plugin: {
- timestamps: require('./plugins/timestamps'),
- password: require('./plugins/password')
+ timestamps: require('./plugins/timestamps')
}
};
View
37 lib/mongoose-util/plugins/password.js
@@ -1,37 +0,0 @@
-var hash = require('password-hash');
-
-function oneway(clear) {
- return hash.generate(clear, { algorithm: 'sha256', saltLength: 12 });
-}
-
-module.exports = function(schema, options) {
-
- options = options || {};
- options.length = options.length || 5;
-
- schema.add({ password: { type: String, trim: true, required: options.required }});
-
- schema.path('password').set(function(password) {
- if (password.length < options.length) {
- return undefined;
- }
- return oneway(password);
- });
-
- schema.methods.verify_password = function(password) {
- return hash.verify(password, this.password);
- };
-
- schema.statics.find_with_password = function(props, password, callback) {
- return this.findOne(props, function(err, doc) {
- if(doc && !err && doc.verify_password(password)) {
- return callback(undefined, doc);
- }
- else {
- return callback();
- }
- });
- };
-
-
-};
View
4 lib/mongoose-util/validators.js
@@ -2,13 +2,13 @@ module.exports = {
length: function (i) {
return function(str) {
- return str && str.length > i;
+ return str && str.length >= i;
};
},
email: function (email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
- return email.match(re) !== null;
+ return email && email.match(re) !== null;
}
};
View
7 lib/mongoose/index.js
@@ -0,0 +1,7 @@
+var mongoose = require('mongoose');
+
+module.exports = function(app, config) {
+ // only connect once
+ if (mongoose.connection.readyState !== 0) return;
+ mongoose.connect(config.mongoose_url);
+};
View
10 lib/redis/index.js
@@ -0,0 +1,10 @@
+var redis = require('redis');
+
+module.exports = function(app) {
+ redis.debug_mode = app.config.redis_debug;
+
+ var client = redis.createClient(app.config.redis_port, app.config.redis_host);
+ client.auth(app.config.redis_pass);
+ client.select(app.config.redis_db);
+ app.redis = client;
+};
View
65 lib/reload.js
@@ -1,65 +0,0 @@
-/*!
- * Cluster - reload
- * Branched from 2011 LearnBoost <dev@learnboost.com>
- * @author Jim Snodgrass <jim@skookum.com>
- * MIT Licensed
- */
-
-/**
- * Module dependencies.
- */
-
-var fs = require('fs'),
- basename = require('path').basename,
- extname = require('path').extname;
-
-exports = module.exports = function(options){
- options = options || {};
-
- // defaults
- var interval = options.interval || 100,
- extensions = options.extensions || ['.js'],
- signal = options.signal || 'SIGQUIT';
-
- files = fs.readdirSync(server.set('root'));
- files.forEach(traverse);
-
- // traverse file if it is a directory
- // otherwise setup the watcher
- function traverse(file) {
- fs.stat(file, function(err, stat){
- if (!err) {
- if (stat.isDirectory()) {
- if (~exports.ignoreDirectories.indexOf(basename(file))) return;
- fs.readdir(file, function(err, files){
- files.map(function(f){
- return file + '/' + f;
- }).forEach(traverse);
- });
- } else {
- watch(file);
- }
- }
- else {
- console.log("ERR Looking at file in reloader:", err);
- }
- });
- }
-
- // watch file for changes
- function watch(file) {
- if (!~extensions.indexOf(extname(file))) return;
- fs.watchFile(file, { interval: interval }, function(curr, prev){
- if (curr.mtime > prev.mtime) {
- console.log(' \033[36mchanged\033[0m \033[90m- %s\033[0m', file);
- process.kill(process.pid, signal);
- }
- });
- }
-};
-
-/**
- * Directories to ignore.
- */
-
-exports.ignoreDirectories = ['node_modules', 'support', 'test', 'bin', 'public', '.git'];
View
67 lib/reload/index.js
@@ -0,0 +1,67 @@
+/*!
+ * Cluster - reload
+ * Branched from 2011 LearnBoost <dev@learnboost.com>
+ * @author Jim Snodgrass <jim@skookum.com>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('fs'),
+ basename = require('path').basename,
+ extname = require('path').extname;
+
+exports = module.exports = function(options){
+ options = options || {};
+
+ // defaults
+ var interval = options.interval || 100,
+ extensions = options.extensions || ['.js'],
+ signal = options.signal || 'SIGQUIT';
+
+ return function(){
+ files = fs.readdirSync('.');
+ files.forEach(traverse);
+
+ // traverse file if it is a directory
+ // otherwise setup the watcher
+ function traverse(file) {
+ fs.stat(file, function(err, stat){
+ if (!err) {
+ if (stat.isDirectory()) {
+ if (~exports.ignoreDirectories.indexOf(basename(file))) return;
+ fs.readdir(file, function(err, files){
+ files.map(function(f){
+ return file + '/' + f;
+ }).forEach(traverse);
+ });
+ } else {
+ watch(file);
+ }
+ }
+ else {
+ console.log("ERR Looking at file in reloader:", err);
+ }
+ });
+ }
+
+ // watch file for changes
+ function watch(file) {
+ if (!~extensions.indexOf(extname(file))) return;
+ fs.watchFile(file, { interval: interval }, function(curr, prev){
+ if (curr.mtime > prev.mtime) {
+ console.log(' \033[36mchanged\033[0m \033[90m- %s\033[0m', file);
+ process.kill(process.pid, signal);
+ }
+ });
+ }
+ };
+};
+
+/**
+ * Directories to ignore.
+ */
+
+exports.ignoreDirectories = ['node_modules', 'test', 'bin', 'public', 'scripts', '.git'];
View
0 app/controllers/home.js → oldapp/controllers/home.js
File renamed without changes.
View
0 app/index.js → oldapp/index.js
File renamed without changes.
View
0 app/lib/index.json → oldapp/lib/index.json
File renamed without changes.
View
0 app/lib/locals.js → oldapp/lib/locals.js
File renamed without changes.
View
0 app/lib/middleware.js → oldapp/lib/middleware.js
File renamed without changes.
View
0 app/lib/routes.js → oldapp/lib/routes.js
File renamed without changes.
View
0 app/middleware/errors.js → oldapp/middleware/errors.js
File renamed without changes.
View
0 app/models/schemas/.gitkeep → oldapp/models/plugins/.gitkeep
File renamed without changes.
View
0 app/models/plugins/.gitkeep → oldapp/models/schemas/.gitkeep
File renamed without changes.
View
0 app/public/favicon.ico → oldapp/public/favicon.ico
File renamed without changes.
View
0 app/public/images/base12_dark.png → oldapp/public/images/base12_dark.png
File renamed without changes
View
0 app/public/images/base12_light.png → oldapp/public/images/base12_light.png
File renamed without changes
View
0 app/public/images/clifton_beach.jpg → oldapp/public/images/clifton_beach.jpg
File renamed without changes
View
0 test/.gitme → oldapp/public/js/.gitme
File renamed without changes.
View
0 app/public/styles/global.css → oldapp/public/styles/global.css
File renamed without changes.
View
0 scripts/old/provision/keys/.gitme → oldapp/public/uploads/.gitme
File renamed without changes.
View
0 doc/.gitme → oldapp/public/vendor/.gitme
File renamed without changes.
View
0 app/shared/.gitme → oldapp/shared/.gitme
File renamed without changes.
View
0 app/views/home/error.jade → oldapp/views/home/error.jade
File renamed without changes.
View
0 app/views/home/index.jade → oldapp/views/home/index.jade
File renamed without changes.
View
0 app/views/layouts/layout.jade → oldapp/views/layouts/layout.jade
File renamed without changes.
View
0 app/views/styles/base12.styl → oldapp/views/styles/base12.styl
File renamed without changes.
View
0 app/views/styles/global.styl → oldapp/views/styles/global.styl
File renamed without changes.
View
46 package.json
@@ -3,39 +3,31 @@
"version": "0.0.1",
"directories": {},
"engines": {
- "node": ">=0.6.6",
+ "node": ">=0.8.0",
"npm": ">=1.1"
},
"dependencies": {
- "base12": "0.3.1",
- "jade": "latest",
- "express": "git://github.com/Skookum/express.git",
- "connect": "2.0.3",
- "connect-timeout": "latest",
- "stylus": "latest",
- "mongodb": "latest",
- "connect-mongodb": "latest",
- "express-resource": "latest",
- "express-messages": "git://github.com/hunterloftis/express-messages.git#master",
- "redis": "latest",
- "strobe": "latest",
- "restfuljs": "latest"
+ "express": "3.0.1",
+ "connect": "2.6.2",
+ "connect-timeout": "0.0.1",
+ "connect-redis": "1.4.4",
+ "connect-parallel": "0.0.3",
+ "jade": "0.27.6",
+ "stylus": "0.30.1",
+ "mongoose": "3.3.1",
+ "bcrypt": "0.7.3",
+ "redis": "0.7.1",
+ "bcrypt": "0.7.2",
+ "nib": "~0.8.2",
+ "async": "0.1.22",
+ "underscore": "1.4.2"
},
"devDependencies": {
- "vows": "latest",
- "commander": "latest",
- "async": "latest",
- "handlebars": "latest"
+ "mocha": "1.6.0",
+ "should": "1.2.0"
},
"scripts": {
- "start": "./run",
- "lock": "scripts/module_lock.js",
- "postinstall": "scripts/postinstall",
- "test": "vows test/*.vows.js"
- },
- "constants": {
- "title": "base12 app",
- "session_length": 1209600000,
- "request_timeout": 10000
+ "start": "node app",
+ "lock": "scripts/module_lock.js"
}
}
View
276 public/styles/global.css
@@ -0,0 +1,276 @@
+*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0;margin:0}
+.wrap{max-width:page_width;position:relative;margin:0 auto}
+.pop{-webkit-animation:pop 250ms ease-out;-moz-animation:pop 250ms ease-out;-ms-animation:pop 250ms ease-out;-o-animation:pop 250ms ease-out;animation:pop 250ms ease-out;-webkit-transform-style:preserve-3d}
+.popSmall{-webkit-animation:popSmall 250ms ease-out;-moz-animation:popSmall 250ms ease-out;-ms-animation:popSmall 250ms ease-out;-o-animation:popSmall 250ms ease-out;animation:popSmall 250ms ease-out;-webkit-transform-style:preserve-3d}
+.slide-up{-webkit-animation:slide-up 250ms ease-out;-moz-animation:slide-up 250ms ease-out;-ms-animation:slide-up 250ms ease-out;-o-animation:slide-up 250ms ease-out;animation:slide-up 250ms ease-out;-webkit-transform-style:preserve-3d}
+.slide-left{-webkit-animation:slide-left 250ms ease-in;-moz-animation:slide-left 250ms ease-in;-ms-animation:slide-left 250ms ease-in;-o-animation:slide-left 250ms ease-in;animation:slide-left 250ms ease-in;-webkit-transform-style:preserve-3d}
+.card-drop{-webkit-animation:card-drop 250ms ease-out;-moz-animation:card-drop 250ms ease-out;-ms-animation:card-drop 250ms ease-out;-o-animation:card-drop 250ms ease-out;animation:card-drop 250ms ease-out;-webkit-transform-style:preserve-3d}
+.all_transitions{-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;-webkit-transform-style:preserve-3d}
+@-moz-keyframes pop{0%{-webkit-transform:scale3d(.7,.7,1);-moz-transform:scale3d(.7,.7,1);-ms-transform:scale3d(.7,.7,1);-o-transform:scale3d(.7,.7,1);transform:scale3d(.7,.7,1)}
+45%{-webkit-transform:scale3d(1.1,1.1,1);-moz-transform:scale3d(1.1,1.1,1);-ms-transform:scale3d(1.1,1.1,1);-o-transform:scale3d(1.1,1.1,1);transform:scale3d(1.1,1.1,1)}
+70%{-webkit-transform:scale3d(1.05,1.05,1);-moz-transform:scale3d(1.05,1.05,1);-ms-transform:scale3d(1.05,1.05,1);-o-transform:scale3d(1.05,1.05,1);transform:scale3d(1.05,1.05,1)}
+100%{-webkit-transform:scale3d(1,1,1);-moz-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);-o-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}
+}@-webkit-keyframes pop{0%{-webkit-transform:scale3d(.7,.7,1);-moz-transform:scale3d(.7,.7,1);-ms-transform:scale3d(.7,.7,1);-o-transform:scale3d(.7,.7,1);transform:scale3d(.7,.7,1)}
+45%{-webkit-transform:scale3d(1.1,1.1,1);-moz-transform:scale3d(1.1,1.1,1);-ms-transform:scale3d(1.1,1.1,1);-o-transform:scale3d(1.1,1.1,1);transform:scale3d(1.1,1.1,1)}
+70%{-webkit-transform:scale3d(1.05,1.05,1);-moz-transform:scale3d(1.05,1.05,1);-ms-transform:scale3d(1.05,1.05,1);-o-transform:scale3d(1.05,1.05,1);transform:scale3d(1.05,1.05,1)}
+100%{-webkit-transform:scale3d(1,1,1);-moz-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);-o-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}
+}@-o-keyframes pop{0%{-webkit-transform:scale3d(.7,.7,1);-moz-transform:scale3d(.7,.7,1);-ms-transform:scale3d(.7,.7,1);-o-transform:scale3d(.7,.7,1);transform:scale3d(.7,.7,1)}
+45%{-webkit-transform:scale3d(1.1,1.1,1);-moz-transform:scale3d(1.1,1.1,1);-ms-transform:scale3d(1.1,1.1,1);-o-transform:scale3d(1.1,1.1,1);transform:scale3d(1.1,1.1,1)}
+70%{-webkit-transform:scale3d(1.05,1.05,1);-moz-transform:scale3d(1.05,1.05,1);-ms-transform:scale3d(1.05,1.05,1);-o-transform:scale3d(1.05,1.05,1);transform:scale3d(1.05,1.05,1)}
+100%{-webkit-transform:scale3d(1,1,1);-moz-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);-o-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}
+}@-ms-keyframes pop{0%{-webkit-transform:scale3d(.7,.7,1);-moz-transform:scale3d(.7,.7,1);-ms-transform:scale3d(.7,.7,1);-o-transform:scale3d(.7,.7,1);transform:scale3d(.7,.7,1)}
+45%{-webkit-transform:scale3d(1.1,1.1,1);-moz-transform:scale3d(1.1,1.1,1);-ms-transform:scale3d(1.1,1.1,1);-o-transform:scale3d(1.1,1.1,1);transform:scale3d(1.1,1.1,1)}
+70%{-webkit-transform:scale3d(1.05,1.05,1);-moz-transform:scale3d(1.05,1.05,1);-ms-transform:scale3d(1.05,1.05,1);-o-transform:scale3d(1.05,1.05,1);transform:scale3d(1.05,1.05,1)}
+100%{-webkit-transform:scale3d(1,1,1);-moz-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);-o-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}
+}@keyframes pop{0%{-webkit-transform:scale3d(.7,.7,1);-moz-transform:scale3d(.7,.7,1);-ms-transform:scale3d(.7,.7,1);-o-transform:scale3d(.7,.7,1);transform:scale3d(.7,.7,1)}
+45%{-webkit-transform:scale3d(1.1,1.1,1);-moz-transform:scale3d(1.1,1.1,1);-ms-transform:scale3d(1.1,1.1,1);-o-transform:scale3d(1.1,1.1,1);transform:scale3d(1.1,1.1,1)}
+70%{-webkit-transform:scale3d(1.05,1.05,1);-moz-transform:scale3d(1.05,1.05,1);-ms-transform:scale3d(1.05,1.05,1);-o-transform:scale3d(1.05,1.05,