merge from upstream
This commit is contained in:
14
README.md
14
README.md
@ -73,11 +73,11 @@ Prerequisites
|
|||||||
- [MongoDB](http://www.mongodb.org/downloads)
|
- [MongoDB](http://www.mongodb.org/downloads)
|
||||||
- [Node.js](http://nodejs.org)
|
- [Node.js](http://nodejs.org)
|
||||||
- Command Line Tools
|
- Command Line Tools
|
||||||
- **Mac OS X**: [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) (or **OS X 10.9 Mavericks**: `xcode-select --install`)
|
- <img src="http://deluge-torrent.org/images/apple-logo.gif" height="17"> **Mac OS X**: [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) (or **OS X 10.9 Mavericks**: `xcode-select --install`)
|
||||||
- **Windows**: [Visual Studio](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-8)
|
- <img src="http://dc942d419843af05523b-ff74ae13537a01be6cfec5927837dcfe.r14.cf1.rackcdn.com/wp-content/uploads/windows-8-50x50.jpg" height="17"> **Windows**: [Visual Studio](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-8)
|
||||||
- **Ubuntu**: `sudo apt-get install build-essential`
|
- <img src="https://lh5.googleusercontent.com/-2YS1ceHWyys/AAAAAAAAAAI/AAAAAAAAAAc/0LCb_tsTvmU/s46-c-k/photo.jpg" height="17"> **Ubuntu**: `sudo apt-get install build-essential`
|
||||||
- **Fedora**: `sudo yum groupinstall "Development Tools"`
|
- <img src="http://i1-news.softpedia-static.com/images/extra/LINUX/small/slw218news1.png" height="17"> **Fedora**: `sudo yum groupinstall "Development Tools"`
|
||||||
- **OpenSUSE**: `sudo zypper install --type pattern devel_basis`
|
- <img src="https://en.opensuse.org/images/b/be/Logo-geeko_head.png" height="17"> **OpenSUSE**: `sudo zypper install --type pattern devel_basis`
|
||||||
|
|
||||||
:exclamation: **Note**: If you are new to Node.js or Express framework,
|
:exclamation: **Note**: If you are new to Node.js or Express framework,
|
||||||
I highly recommend watching [Node.js and Express 101](http://www.youtube.com/watch?v=BN0JlMZCtNU) screencast by Alex Ford that teaches Node and Express from scratch. Alternatively, here is another great tutorial for complete beginners - [Getting Started With Node.js, Express, MongoDB](http://cwbuecheler.com/web/tutorials/2013/node-express-mongo/).
|
I highly recommend watching [Node.js and Express 101](http://www.youtube.com/watch?v=BN0JlMZCtNU) screencast by Alex Ford that teaches Node and Express from scratch. Alternatively, here is another great tutorial for complete beginners - [Getting Started With Node.js, Express, MongoDB](http://cwbuecheler.com/web/tutorials/2013/node-express-mongo/).
|
||||||
@ -503,7 +503,7 @@ to "info" and "success" flash messages, and you could even create a new one your
|
|||||||
|
|
||||||
**Data Usage Controller (Example)**
|
**Data Usage Controller (Example)**
|
||||||
```
|
```
|
||||||
req.flash('warning', 'You have exceeded 90% of your data usage');
|
req.flash('warning', {msg: 'You have exceeded 90% of your data usage'});
|
||||||
```
|
```
|
||||||
|
|
||||||
**User Account Page (Example)**
|
**User Account Page (Example)**
|
||||||
@ -846,7 +846,7 @@ TODO
|
|||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
If something is unclear, confusing, or needs to be refactored, please let me know. Pull requests are always welcome, but due to the opinionated nature of this project, I cannot accept every pull request. Please open an issue before submitting a pull request.
|
If something is unclear, confusing, or needs to be refactored, please let me know. Pull requests are always welcome, but due to the opinionated nature of this project, I cannot accept every pull request. Please open an issue before submitting a pull request. This project uses [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript) with a few exceptions.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
@ -398,6 +398,7 @@ exports.getTwilio = function(req, res, next) {
|
|||||||
/**
|
/**
|
||||||
* POST /api/twilio
|
* POST /api/twilio
|
||||||
* Twilio API example.
|
* Twilio API example.
|
||||||
|
* @param telephone
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.postTwilio = function(req, res, next) {
|
exports.postTwilio = function(req, res, next) {
|
||||||
|
@ -15,9 +15,9 @@ exports.getContact = function(req, res) {
|
|||||||
/**
|
/**
|
||||||
* POST /contact
|
* POST /contact
|
||||||
* Send a contact form via SendGrid.
|
* Send a contact form via SendGrid.
|
||||||
* @param {string} email
|
* @param email
|
||||||
* @param {string} name
|
* @param name
|
||||||
* @param {string} message
|
* @param message
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.postContact = function(req, res) {
|
exports.postContact = function(req, res) {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
var mongoose = require('mongoose');
|
|
||||||
var passport = require('passport');
|
var passport = require('passport');
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
var User = require('../models/User');
|
var User = require('../models/User');
|
||||||
@ -18,8 +17,8 @@ exports.getLogin = function(req, res) {
|
|||||||
/**
|
/**
|
||||||
* POST /login
|
* POST /login
|
||||||
* Sign in using email and password.
|
* Sign in using email and password.
|
||||||
* @param {string} email
|
* @param email
|
||||||
* @param {string} password
|
* @param password
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.postLogin = function(req, res, next) {
|
exports.postLogin = function(req, res, next) {
|
||||||
@ -48,6 +47,16 @@ exports.postLogin = function(req, res, next) {
|
|||||||
})(req, res, next);
|
})(req, res, next);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /logout
|
||||||
|
* Log out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.logout = function(req, res) {
|
||||||
|
req.logout();
|
||||||
|
res.redirect('/');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /signup
|
* GET /signup
|
||||||
* Signup page.
|
* Signup page.
|
||||||
@ -63,8 +72,8 @@ exports.getSignup = function(req, res) {
|
|||||||
/**
|
/**
|
||||||
* POST /signup
|
* POST /signup
|
||||||
* Create a new local account.
|
* Create a new local account.
|
||||||
* @param {string} email
|
* @param email
|
||||||
* @param {string} password
|
* @param password
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.postSignup = function(req, res, next) {
|
exports.postSignup = function(req, res, next) {
|
||||||
@ -134,7 +143,7 @@ exports.postUpdateProfile = function(req, res, next) {
|
|||||||
/**
|
/**
|
||||||
* POST /account/password
|
* POST /account/password
|
||||||
* Update current password.
|
* Update current password.
|
||||||
* @param {string} password
|
* @param password
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.postUpdatePassword = function(req, res, next) {
|
exports.postUpdatePassword = function(req, res, next) {
|
||||||
@ -164,7 +173,7 @@ exports.postUpdatePassword = function(req, res, next) {
|
|||||||
/**
|
/**
|
||||||
* POST /account/delete
|
* POST /account/delete
|
||||||
* Delete user account.
|
* Delete user account.
|
||||||
* @param {string} id
|
* @param id - User ObjectId
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.postDeleteAccount = function(req, res, next) {
|
exports.postDeleteAccount = function(req, res, next) {
|
||||||
@ -178,8 +187,8 @@ exports.postDeleteAccount = function(req, res, next) {
|
|||||||
/**
|
/**
|
||||||
* GET /account/unlink/:provider
|
* GET /account/unlink/:provider
|
||||||
* Unlink OAuth2 provider from the current user.
|
* Unlink OAuth2 provider from the current user.
|
||||||
* @param {string} provider
|
* @param provider
|
||||||
* @param {string} id
|
* @param id - User ObjectId
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.getOauthUnlink = function(req, res, next) {
|
exports.getOauthUnlink = function(req, res, next) {
|
||||||
@ -197,13 +206,3 @@ exports.getOauthUnlink = function(req, res, next) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* GET /logout
|
|
||||||
* Log out.
|
|
||||||
*/
|
|
||||||
|
|
||||||
exports.logout = function(req, res) {
|
|
||||||
req.logout();
|
|
||||||
res.redirect('/');
|
|
||||||
};
|
|
||||||
|
@ -56,8 +56,7 @@ userSchema.methods.comparePassword = function(candidatePassword, cb) {
|
|||||||
userSchema.methods.gravatar = function(size, defaults) {
|
userSchema.methods.gravatar = function(size, defaults) {
|
||||||
if (!size) size = 200;
|
if (!size) size = 200;
|
||||||
if (!defaults) defaults = 'retro';
|
if (!defaults) defaults = 'retro';
|
||||||
var md5 = crypto.createHash('md5');
|
var md5 = crypto.createHash('md5').update(this.email);
|
||||||
md5.update(this.email);
|
|
||||||
return 'https://gravatar.com/avatar/' + md5.digest('hex').toString() + '?s=' + size + '&d=' + defaults;
|
return 'https://gravatar.com/avatar/' + md5.digest('hex').toString() + '?s=' + size + '&d=' + defaults;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
/**
|
||||||
// listed below.
|
* This is a manifest file that will be compiled into application.js, which will
|
||||||
//
|
* include all the files listed below.
|
||||||
// Any JavaScript/Coffee file within this directory can be referenced here using a relative path.
|
*
|
||||||
//
|
* Any JavaScript file within this directory can be referenced here using a
|
||||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
* relative path.
|
||||||
// compiled file.
|
*
|
||||||
//
|
* It's not advisable to add code directly here, but if you do, it will appear
|
||||||
// Read Connect Assets README (https://github.com/adunkman/connect-assets) for details
|
* at the bottom of the compiled file.
|
||||||
// about supported directives.
|
*/
|
||||||
|
|
||||||
//= require lib/jquery-2.1.0.min
|
//= require lib/jquery-2.1.0.min
|
||||||
//= require lib/bootstrap.min
|
//= require lib/bootstrap.min
|
||||||
|
@ -3,6 +3,7 @@ extends ../layout
|
|||||||
block content
|
block content
|
||||||
.col-sm-8.col-sm-offset-2
|
.col-sm-8.col-sm-offset-2
|
||||||
form(method='POST')
|
form(method='POST')
|
||||||
|
input(type='hidden', name='_csrf', value=token)
|
||||||
legend Sign In
|
legend Sign In
|
||||||
.form-group
|
.form-group
|
||||||
.btn-group.btn-group-justified
|
.btn-group.btn-group-justified
|
||||||
@ -22,16 +23,15 @@ block content
|
|||||||
a.btn.btn-google-plus(href='/auth/google')
|
a.btn.btn-google-plus(href='/auth/google')
|
||||||
i.fa.fa-google-plus
|
i.fa.fa-google-plus
|
||||||
| Google
|
| Google
|
||||||
if secrets.localAuth
|
if secrets.localAuth
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(for='email') Email
|
label.control-label(for='email') Email
|
||||||
input.form-control(type='text', name='email', id='email', placeholder='Email', autofocus=true)
|
input.form-control(type='text', name='email', id='email', placeholder='Email', autofocus=true)
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(for='password') Password
|
label.control-label(for='password') Password
|
||||||
input.form-control(type='password', name='password', id='password', placeholder='Password')
|
input.form-control(type='password', name='password', id='password', placeholder='Password')
|
||||||
.form-group
|
.form-group
|
||||||
input.form-control(type='hidden', name='_csrf', value=token)
|
button.btn.btn-primary(type='submit')
|
||||||
.form-group
|
i.fa.fa-unlock-alt
|
||||||
button.btn.btn-primary(type='submit')
|
| Login
|
||||||
i.fa.fa-unlock-alt
|
|
||||||
| Login
|
|
||||||
|
@ -5,6 +5,7 @@ block content
|
|||||||
h3 Profile Information
|
h3 Profile Information
|
||||||
|
|
||||||
form.form-horizontal(action='/account/profile', method='POST')
|
form.form-horizontal(action='/account/profile', method='POST')
|
||||||
|
input(type='hidden', name='_csrf', value=token)
|
||||||
.form-group
|
.form-group
|
||||||
label.col-sm-2.control-label(for='email') Email
|
label.col-sm-2.control-label(for='email') Email
|
||||||
.col-sm-4
|
.col-sm-4
|
||||||
@ -34,8 +35,6 @@ block content
|
|||||||
label.col-sm-2.control-label(for='gravatar') Gravatar
|
label.col-sm-2.control-label(for='gravatar') Gravatar
|
||||||
.col-sm-4
|
.col-sm-4
|
||||||
img(src="#{user.gravatar()}", class='profile', width='100', height='100')
|
img(src="#{user.gravatar()}", class='profile', width='100', height='100')
|
||||||
.form-group
|
|
||||||
input.form-control(type='hidden', name='_csrf', value=token)
|
|
||||||
.form-group
|
.form-group
|
||||||
.col-sm-offset-2.col-sm-4
|
.col-sm-offset-2.col-sm-4
|
||||||
button.btn.btn.btn-primary(type='submit')
|
button.btn.btn.btn-primary(type='submit')
|
||||||
@ -46,29 +45,29 @@ block content
|
|||||||
if secrets.localAuth
|
if secrets.localAuth
|
||||||
.page-header
|
.page-header
|
||||||
h3 Change Password
|
h3 Change Password
|
||||||
|
|
||||||
form.form-horizontal(action='/account/password', method='POST')
|
form.form-horizontal(action='/account/password', method='POST')
|
||||||
.form-group
|
input(type='hidden', name='_csrf', value=token)
|
||||||
label.col-sm-3.control-label(for='password') New Password
|
.form-group
|
||||||
.col-sm-4
|
label.col-sm-3.control-label(for='password') New Password
|
||||||
input.form-control(type='password', name='password', id='password')
|
.col-sm-4
|
||||||
.form-group
|
input.form-control(type='password', name='password', id='password')
|
||||||
label.col-sm-3.control-label(for='confirmPassword') Confirm Password
|
.form-group
|
||||||
.col-sm-4
|
label.col-sm-3.control-label(for='confirmPassword') Confirm Password
|
||||||
input.form-control(type='password', name='confirmPassword', id='confirmPassword')
|
.col-sm-4
|
||||||
.form-group
|
input.form-control(type='password', name='confirmPassword', id='confirmPassword')
|
||||||
input.form-control(type='hidden', name='_csrf', value=token)
|
.form-group
|
||||||
.form-group
|
.col-sm-offset-3.col-sm-4
|
||||||
.col-sm-offset-3.col-sm-4
|
button.btn.btn.btn-primary(type='submit')
|
||||||
button.btn.btn.btn-primary(type='submit')
|
i.fa.fa-keyboard-o
|
||||||
i.fa.fa-keyboard-o
|
| Change Password
|
||||||
| Change Password
|
|
||||||
|
|
||||||
.page-header
|
.page-header
|
||||||
h3 Delete Account
|
h3 Delete Account
|
||||||
|
|
||||||
p You can delete your account, but keep in mind this action is irreversible.
|
p You can delete your account, but keep in mind this action is irreversible.
|
||||||
form(action='/account/delete', method='POST')
|
form(action='/account/delete', method='POST')
|
||||||
|
input(type='hidden', name='_csrf', value=token)
|
||||||
button.btn.btn-danger(type='submit')
|
button.btn.btn-danger(type='submit')
|
||||||
i.fa.fa-trash-o
|
i.fa.fa-trash-o
|
||||||
| Delete my account
|
| Delete my account
|
||||||
|
@ -2,6 +2,7 @@ extends ../layout
|
|||||||
|
|
||||||
block content
|
block content
|
||||||
form.form-horizontal(id='signup-form', method='POST')
|
form.form-horizontal(id='signup-form', method='POST')
|
||||||
|
input(type='hidden', name='_csrf', value=token)
|
||||||
legend Signup
|
legend Signup
|
||||||
.form-group
|
.form-group
|
||||||
label.col-sm-3.control-label(for='email') Email
|
label.col-sm-3.control-label(for='email') Email
|
||||||
@ -15,8 +16,6 @@ block content
|
|||||||
label.col-sm-3.control-label(for='confirmPassword') Confirm Password
|
label.col-sm-3.control-label(for='confirmPassword') Confirm Password
|
||||||
.col-sm-7
|
.col-sm-7
|
||||||
input.form-control(type='password', name='confirmPassword', id='confirmPassword', placeholder='Confirm Password')
|
input.form-control(type='password', name='confirmPassword', id='confirmPassword', placeholder='Confirm Password')
|
||||||
.form-group
|
|
||||||
input.form-control(type='hidden', name='_csrf', value=token)
|
|
||||||
.form-group
|
.form-group
|
||||||
.col-sm-offset-3.col-sm-7
|
.col-sm-offset-3.col-sm-7
|
||||||
button.btn.btn-success(type='submit')
|
button.btn.btn-success(type='submit')
|
||||||
|
@ -5,6 +5,7 @@ block content
|
|||||||
h3 Contact Form
|
h3 Contact Form
|
||||||
|
|
||||||
form.form-horizontal(role='form', method='POST')
|
form.form-horizontal(role='form', method='POST')
|
||||||
|
input(type='hidden', name='_csrf', value=token)
|
||||||
.form-group
|
.form-group
|
||||||
label(class='col-sm-2 control-label', for='name') Name
|
label(class='col-sm-2 control-label', for='name') Name
|
||||||
.col-sm-8
|
.col-sm-8
|
||||||
@ -17,8 +18,6 @@ block content
|
|||||||
label(class='col-sm-2 control-label', for='message') Body
|
label(class='col-sm-2 control-label', for='message') Body
|
||||||
.col-sm-8
|
.col-sm-8
|
||||||
textarea.form-control(type='text', name='message', id='message', rows='7')
|
textarea.form-control(type='text', name='message', id='message', rows='7')
|
||||||
.form-group
|
|
||||||
input.form-control(type='hidden', name='_csrf', value=token)
|
|
||||||
.form-group
|
.form-group
|
||||||
.col-sm-offset-2.col-sm-8
|
.col-sm-offset-2.col-sm-8
|
||||||
button.btn.btn-default(type='submit')
|
button.btn.btn-default(type='submit')
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
if user.profile.picture
|
if user.profile.picture
|
||||||
img.profile-image(src='#{user.profile.picture}')
|
img.profile-image(src='#{user.profile.picture}')
|
||||||
else
|
else
|
||||||
img.profile-image(src='#{user.gravatar()}')
|
img.profile-image(src='#{user.gravatar(60)}')
|
||||||
| #{user.profile.name || user.email || user.id}
|
| #{user.profile.name || user.email || user.id}
|
||||||
i.caret
|
i.caret
|
||||||
ul.dropdown-menu
|
ul.dropdown-menu
|
||||||
|
Reference in New Issue
Block a user