Added angular-seed to public folder
@ -37,4 +37,4 @@
|
|||||||
"grunt-concurrent": "latest",
|
"grunt-concurrent": "latest",
|
||||||
"grunt-mocha-test": "latest"
|
"grunt-mocha-test": "latest"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,25 +0,0 @@
|
|||||||
.navbar .nav>li>a.brand {
|
|
||||||
padding-left:20px;
|
|
||||||
margin-left:0
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
margin-top:50px;
|
|
||||||
width:100%
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
position:fixed;
|
|
||||||
left:0px;
|
|
||||||
bottom:0px;
|
|
||||||
height:30px;
|
|
||||||
width:100%;
|
|
||||||
background:#ddd;
|
|
||||||
-webkit-box-shadow:0 8px 6px 6px black;
|
|
||||||
-moz-box-shadow:0 8px 6px 6px black;
|
|
||||||
box-shadow:0 8px 6px 6px black
|
|
||||||
}
|
|
||||||
|
|
||||||
footer p {
|
|
||||||
padding:5px 0 12px 10px
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
h1 {
|
|
||||||
text-align:center
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.articles li:not(:last-child) {
|
|
||||||
border-bottom:1px solid #ccc
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
# humanstxt.org/
|
|
||||||
# The humans responsible & technology colophon
|
|
||||||
|
|
||||||
# TEAM
|
|
||||||
|
|
||||||
<name> -- <role> -- <twitter>
|
|
||||||
|
|
||||||
# THANKS
|
|
||||||
|
|
||||||
<name>
|
|
||||||
|
|
||||||
# TECHNOLOGY COLOPHON
|
|
||||||
|
|
||||||
HTML5, CSS3
|
|
||||||
jQuery, Modernizr
|
|
0
public/img/.gitignore
vendored
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 12 KiB |
58
public/index-async.html
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
[ng-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
// include angular loader, which allows the files to load in any order
|
||||||
|
/*
|
||||||
|
AngularJS v1.0.7
|
||||||
|
(c) 2010-2012 Google, Inc. http://angularjs.org
|
||||||
|
License: MIT
|
||||||
|
*/
|
||||||
|
(function(i){'use strict';function d(c,b,e){return c[b]||(c[b]=e())}return d(d(i,"angular",Object),"module",function(){var c={};return function(b,e,f){e&&c.hasOwnProperty(b)&&(c[b]=null);return d(c,b,function(){function a(a,b,d){return function(){c[d||"push"]([a,b,arguments]);return g}}if(!e)throw Error("No module: "+b);var c=[],d=[],h=a("$injector","invoke"),g={_invokeQueue:c,_runBlocks:d,requires:e,name:b,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),
|
||||||
|
value:a("$provide","value"),constant:a("$provide","constant","unshift"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:h,run:function(a){d.push(a);return this}};f&&h(f);return g})}})})(window);
|
||||||
|
|
||||||
|
|
||||||
|
// include a third-party async loader library
|
||||||
|
/*!
|
||||||
|
* $script.js v1.3
|
||||||
|
* https://github.com/ded/script.js
|
||||||
|
* Copyright: @ded & @fat - Dustin Diaz, Jacob Thornton 2011
|
||||||
|
* Follow our software http://twitter.com/dedfat
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
!function(a,b,c){function t(a,c){var e=b.createElement("script"),f=j;e.onload=e.onerror=e[o]=function(){e[m]&&!/^c|loade/.test(e[m])||f||(e.onload=e[o]=null,f=1,c())},e.async=1,e.src=a,d.insertBefore(e,d.firstChild)}function q(a,b){p(a,function(a){return!b(a)})}var d=b.getElementsByTagName("head")[0],e={},f={},g={},h={},i="string",j=!1,k="push",l="DOMContentLoaded",m="readyState",n="addEventListener",o="onreadystatechange",p=function(a,b){for(var c=0,d=a.length;c<d;++c)if(!b(a[c]))return j;return 1};!b[m]&&b[n]&&(b[n](l,function r(){b.removeEventListener(l,r,j),b[m]="complete"},j),b[m]="loading");var s=function(a,b,d){function o(){if(!--m){e[l]=1,j&&j();for(var a in g)p(a.split("|"),n)&&!q(g[a],n)&&(g[a]=[])}}function n(a){return a.call?a():e[a]}a=a[k]?a:[a];var i=b&&b.call,j=i?b:d,l=i?a.join(""):b,m=a.length;c(function(){q(a,function(a){h[a]?(l&&(f[l]=1),o()):(h[a]=1,l&&(f[l]=1),t(s.path?s.path+a+".js":a,o))})},0);return s};s.get=t,s.ready=function(a,b,c){a=a[k]?a:[a];var d=[];!q(a,function(a){e[a]||d[k](a)})&&p(a,function(a){return e[a]})?b():!function(a){g[a]=g[a]||[],g[a][k](b),c&&c(d)}(a.join("|"));return s};var u=a.$script;s.noConflict=function(){a.$script=u;return this},typeof module!="undefined"&&module.exports?module.exports=s:a.$script=s}(this,document,setTimeout)
|
||||||
|
|
||||||
|
// load all of the dependencies asynchronously.
|
||||||
|
$script([
|
||||||
|
'lib/angular/angular.js',
|
||||||
|
'js/app.js',
|
||||||
|
'js/services.js',
|
||||||
|
'js/controllers.js',
|
||||||
|
'js/filters.js',
|
||||||
|
'js/directives.js'
|
||||||
|
], function() {
|
||||||
|
// when all is done, execute bootstrap angular application
|
||||||
|
angular.bootstrap(document, ['myApp']);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<title>My AngularJS App</title>
|
||||||
|
<link rel="stylesheet" href="css/app.css">
|
||||||
|
</head>
|
||||||
|
<body ng-cloak>
|
||||||
|
<ul class="menu">
|
||||||
|
<li><a href="#/view1">view1</a></li>
|
||||||
|
<li><a href="#/view2">view2</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div ng-view></div>
|
||||||
|
|
||||||
|
<div>Angular seed app: v<span app-version></span></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
29
public/index.html
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" ng-app="myApp">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>My AngularJS App</title>
|
||||||
|
<link rel="stylesheet" href="css/app.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul class="menu">
|
||||||
|
<li><a href="#/view1">view1</a></li>
|
||||||
|
<li><a href="#/view2">view2</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div ng-view></div>
|
||||||
|
|
||||||
|
<div>Angular seed app: v<span app-version></span></div>
|
||||||
|
|
||||||
|
<!-- In production use:
|
||||||
|
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
|
||||||
|
-->
|
||||||
|
<script src="lib/angular/angular.js"></script>
|
||||||
|
<script src="lib/angular/angular-route.js"></script>
|
||||||
|
<script src="js/app.js"></script>
|
||||||
|
<script src="js/services.js"></script>
|
||||||
|
<script src="js/controllers.js"></script>
|
||||||
|
<script src="js/filters.js"></script>
|
||||||
|
<script src="js/directives.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,4 +1,16 @@
|
|||||||
window.app = angular.module('mean', ['ngCookies', 'ngResource', 'ui.bootstrap', 'ui.route', 'mean.system', 'mean.articles']);
|
'use strict';
|
||||||
|
|
||||||
angular.module('mean.system', []);
|
|
||||||
angular.module('mean.articles', []);
|
// Declare app level module which depends on filters, and services
|
||||||
|
angular.module('myApp', [
|
||||||
|
'ngRoute',
|
||||||
|
'myApp.filters',
|
||||||
|
'myApp.services',
|
||||||
|
'myApp.directives',
|
||||||
|
'myApp.controllers'
|
||||||
|
]).
|
||||||
|
config(['$routeProvider', function($routeProvider) {
|
||||||
|
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
|
||||||
|
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
|
||||||
|
$routeProvider.otherwise({redirectTo: '/view1'});
|
||||||
|
}]);
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
//Setting up route
|
|
||||||
window.app.config(['$routeProvider',
|
|
||||||
function($routeProvider) {
|
|
||||||
$routeProvider.
|
|
||||||
when('/articles', {
|
|
||||||
templateUrl: 'views/articles/list.html'
|
|
||||||
}).
|
|
||||||
when('/articles/create', {
|
|
||||||
templateUrl: 'views/articles/create.html'
|
|
||||||
}).
|
|
||||||
when('/articles/:articleId/edit', {
|
|
||||||
templateUrl: 'views/articles/edit.html'
|
|
||||||
}).
|
|
||||||
when('/articles/:articleId', {
|
|
||||||
templateUrl: 'views/articles/view.html'
|
|
||||||
}).
|
|
||||||
when('/', {
|
|
||||||
templateUrl: 'views/index.html'
|
|
||||||
}).
|
|
||||||
otherwise({
|
|
||||||
redirectTo: '/'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
//Setting HTML5 Location Mode
|
|
||||||
window.app.config(['$locationProvider',
|
|
||||||
function($locationProvider) {
|
|
||||||
$locationProvider.hashPrefix("!");
|
|
||||||
}
|
|
||||||
]);
|
|
@ -1,52 +0,0 @@
|
|||||||
angular.module('mean.articles').controller('ArticlesController', ['$scope', '$routeParams', '$location', 'Global', 'Articles', function ($scope, $routeParams, $location, Global, Articles) {
|
|
||||||
$scope.global = Global;
|
|
||||||
|
|
||||||
$scope.create = function() {
|
|
||||||
var article = new Articles({
|
|
||||||
title: this.title,
|
|
||||||
content: this.content
|
|
||||||
});
|
|
||||||
article.$save(function(response) {
|
|
||||||
$location.path("articles/" + response._id);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.title = "";
|
|
||||||
this.content = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.remove = function(article) {
|
|
||||||
article.$remove();
|
|
||||||
|
|
||||||
for (var i in $scope.articles) {
|
|
||||||
if ($scope.articles[i] == article) {
|
|
||||||
$scope.articles.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.update = function() {
|
|
||||||
var article = $scope.article;
|
|
||||||
if (!article.updated) {
|
|
||||||
article.updated = [];
|
|
||||||
}
|
|
||||||
article.updated.push(new Date().getTime());
|
|
||||||
|
|
||||||
article.$update(function() {
|
|
||||||
$location.path('articles/' + article._id);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.find = function() {
|
|
||||||
Articles.query(function(articles) {
|
|
||||||
$scope.articles = articles;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.findOne = function() {
|
|
||||||
Articles.get({
|
|
||||||
articleId: $routeParams.articleId
|
|
||||||
}, function(article) {
|
|
||||||
$scope.article = article;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}]);
|
|
@ -1,13 +0,0 @@
|
|||||||
angular.module('mean.system').controller('HeaderController', ['$scope', 'Global', function ($scope, Global) {
|
|
||||||
$scope.global = Global;
|
|
||||||
|
|
||||||
$scope.menu = [{
|
|
||||||
"title": "Articles",
|
|
||||||
"link": "articles"
|
|
||||||
}, {
|
|
||||||
"title": "Create New Article",
|
|
||||||
"link": "articles/create"
|
|
||||||
}];
|
|
||||||
|
|
||||||
$scope.isCollapsed = false;
|
|
||||||
}]);
|
|
@ -1,3 +0,0 @@
|
|||||||
angular.module('mean.system').controller('IndexController', ['$scope', 'Global', function ($scope, Global) {
|
|
||||||
$scope.global = Global;
|
|
||||||
}]);
|
|
@ -0,0 +1,11 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* Directives */
|
||||||
|
|
||||||
|
|
||||||
|
angular.module('myApp.directives', []).
|
||||||
|
directive('appVersion', ['version', function(version) {
|
||||||
|
return function(scope, elm, attrs) {
|
||||||
|
elm.text(version);
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* Filters */
|
||||||
|
|
||||||
|
angular.module('myApp.filters', []).
|
||||||
|
filter('interpolate', ['version', function(version) {
|
||||||
|
return function(text) {
|
||||||
|
return String(text).replace(/\%VERSION\%/mg, version);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
window.bootstrap = function() {
|
|
||||||
angular.bootstrap(document, ['mean']);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.init = function() {
|
|
||||||
window.bootstrap();
|
|
||||||
};
|
|
||||||
|
|
||||||
angular.element(document).ready(function() {
|
|
||||||
//Fixing facebook bug with redirect
|
|
||||||
if (window.location.hash == "#_=_") window.location.hash = "";
|
|
||||||
|
|
||||||
//Then init the app
|
|
||||||
window.init();
|
|
||||||
});
|
|
@ -1,10 +0,0 @@
|
|||||||
//Articles service used for articles REST endpoint
|
|
||||||
angular.module('mean.articles').factory("Articles", ['$resource', function($resource) {
|
|
||||||
return $resource('articles/:articleId', {
|
|
||||||
articleId: '@_id'
|
|
||||||
}, {
|
|
||||||
update: {
|
|
||||||
method: 'PUT'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}]);
|
|
@ -1,9 +0,0 @@
|
|||||||
angular.module('mean.system').factory("Global", [function() {
|
|
||||||
var _this = this;
|
|
||||||
_this._data = {
|
|
||||||
user: window.user,
|
|
||||||
authenticated: !! window.user
|
|
||||||
};
|
|
||||||
|
|
||||||
return _this._data;
|
|
||||||
}]);
|
|
@ -1,3 +0,0 @@
|
|||||||
# robotstxt.org/
|
|
||||||
|
|
||||||
User-agent: *
|
|
@ -1,21 +0,0 @@
|
|||||||
<section data-ng-controller="ArticlesController">
|
|
||||||
<form class="form-horizontal" data-ng-submit="create()">
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="title">Title</label>
|
|
||||||
<div class="controls">
|
|
||||||
<input type="text" data-ng-model="title" id="title" placeholder="Title" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="content">Content</label>
|
|
||||||
<div class="controls">
|
|
||||||
<textarea data-ng-model="content" id="content" cols="30" rows="10" placeholder="Content"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control-group">
|
|
||||||
<div class="controls">
|
|
||||||
<input type="submit" class="btn">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</section>
|
|
@ -1,25 +0,0 @@
|
|||||||
<section data-ng-controller="ArticlesController" data-ng-init="findOne()">
|
|
||||||
<form class="form-horizontal" data-ng-submit="update()">
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="title">Title</label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<input type="text" data-ng-model="article.title" id="title" placeholder="Title" required>
|
|
||||||
</input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="content">Content</label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<textarea data-ng-model="article.content" id="content" cols="30" rows="10" placeholder="Content">
|
|
||||||
</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control-group">
|
|
||||||
<div class="controls">
|
|
||||||
<input type="submit" class="btn">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</section>
|
|
@ -1,11 +0,0 @@
|
|||||||
<section data-ng-controller="ArticlesController" data-ng-init="find()">
|
|
||||||
<ul class="articles unstyled">
|
|
||||||
<li data-ng-repeat="article in articles">
|
|
||||||
<span>{{article.created | date:'medium'}}</span> /
|
|
||||||
<span>{{article.user.name}}</span>
|
|
||||||
<h2><a data-ng-href="#!/articles/{{article._id}}">{{article.title}}</a></h2>
|
|
||||||
<div>{{article.content}}</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h1 data-ng-hide="!articles || articles.length">No articles yet. <br> Why don't you <a href="/#!/articles/create">Create One</a>?</h1>
|
|
||||||
</section>
|
|
@ -1,6 +0,0 @@
|
|||||||
<section data-ng-controller="ArticlesController" data-ng-init="findOne()">
|
|
||||||
<span>{{article.created | date:'medium'}}</span> /
|
|
||||||
<span>{{article.user.name}}</span>
|
|
||||||
<h2>{{article.title}} <a data-ng-show="global.user._id == article.user._id" href="/#!/articles/{{article._id}}/edit">edit</a></h2>
|
|
||||||
<div>{{article.content}}</div>
|
|
||||||
</section>
|
|
@ -1,28 +0,0 @@
|
|||||||
<div class="navbar-inner" data-ng-controller="HeaderController">
|
|
||||||
<ul class="nav">
|
|
||||||
<li>
|
|
||||||
<a class="brand" href="/">MEAN - A Modern Stack</a>
|
|
||||||
</li>
|
|
||||||
<li data-ng-repeat="item in menu" data-ng-show="global.user" ui-route="/{{item.link}}" ng-class="{active: $uiRoute}">
|
|
||||||
<a href="#!/{{item.link}}">{{item.title}}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav pull-right" data-ng-hide="global.authenticated">
|
|
||||||
<li><a href="signup">Signup</a>
|
|
||||||
</li>
|
|
||||||
<li class="divider-vertical"></li>
|
|
||||||
<li><a href="signin">Signin</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav pull-right" data-ng-show="global.authenticated">
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
|
||||||
{{global.user.name}} <b class="caret"></b>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a href="/signout">Signout</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
@ -1,3 +0,0 @@
|
|||||||
<section data-ng-controller="IndexController">
|
|
||||||
<h1>This is the home view</h1>
|
|
||||||
</section>
|
|
296
server.js
@ -1,21 +1,8 @@
|
|||||||
var express = require('express'),
|
var express = require('express'),
|
||||||
mongoose = require('mongoose'),
|
mongoose = require('mongoose'),
|
||||||
mongoStore = require('connect-mongo')(express),
|
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
flash = require('connect-flash'),
|
|
||||||
helpers = require('view-helpers'),
|
|
||||||
config = require('./conf'),
|
config = require('./conf'),
|
||||||
passport = require('passport'),
|
passport = require('passport');
|
||||||
logger = require('mean-logger');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main application entry file.
|
|
||||||
* Please note that the order of loading is important.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Load configurations
|
|
||||||
//if test env, load example file
|
|
||||||
var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic require login routing middleware
|
* Generic require login routing middleware
|
||||||
@ -219,278 +206,35 @@ ArticleSchema.statics = {
|
|||||||
|
|
||||||
mongoose.model('Article', ArticleSchema);
|
mongoose.model('Article', ArticleSchema);
|
||||||
|
|
||||||
//bootstrap passport config
|
|
||||||
var LocalStrategy = require('passport-local').Strategy,
|
|
||||||
TwitterStrategy = require('passport-twitter').Strategy,
|
|
||||||
FacebookStrategy = require('passport-facebook').Strategy,
|
|
||||||
GitHubStrategy = require('passport-github').Strategy,
|
|
||||||
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
|
|
||||||
|
|
||||||
//Serialize sessions
|
|
||||||
passport.serializeUser(function(user, done) {
|
|
||||||
done(null, user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
passport.deserializeUser(function(id, done) {
|
|
||||||
User.findOne({
|
|
||||||
_id: id
|
|
||||||
}, function(err, user) {
|
|
||||||
done(err, user);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Use local strategy
|
|
||||||
passport.use(new LocalStrategy({
|
|
||||||
usernameField: 'email',
|
|
||||||
passwordField: 'password'
|
|
||||||
},
|
|
||||||
function(email, password, done) {
|
|
||||||
User.findOne({
|
|
||||||
email: email
|
|
||||||
}, function(err, user) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
if (!user) {
|
|
||||||
return done(null, false, {
|
|
||||||
message: 'Unknown user'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!user.authenticate(password)) {
|
|
||||||
return done(null, false, {
|
|
||||||
message: 'Invalid password'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return done(null, user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
//Use twitter strategy
|
|
||||||
passport.use(new TwitterStrategy({
|
|
||||||
consumerKey: config.twitter.clientID,
|
|
||||||
consumerSecret: config.twitter.clientSecret,
|
|
||||||
callbackURL: config.twitter.callbackURL
|
|
||||||
},
|
|
||||||
function(token, tokenSecret, profile, done) {
|
|
||||||
User.findOne({
|
|
||||||
'twitter.id_str': profile.id
|
|
||||||
}, function(err, user) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
if (!user) {
|
|
||||||
user = new User({
|
|
||||||
name: profile.displayName,
|
|
||||||
username: profile.username,
|
|
||||||
provider: 'twitter',
|
|
||||||
twitter: profile._json
|
|
||||||
});
|
|
||||||
user.save(function(err) {
|
|
||||||
if (err) console.log(err);
|
|
||||||
return done(err, user);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return done(err, user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
//Use facebook strategy
|
|
||||||
passport.use(new FacebookStrategy({
|
|
||||||
clientID: config.facebook.clientID,
|
|
||||||
clientSecret: config.facebook.clientSecret,
|
|
||||||
callbackURL: config.facebook.callbackURL
|
|
||||||
},
|
|
||||||
function(accessToken, refreshToken, profile, done) {
|
|
||||||
User.findOne({
|
|
||||||
'facebook.id': profile.id
|
|
||||||
}, function(err, user) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
if (!user) {
|
|
||||||
user = new User({
|
|
||||||
name: profile.displayName,
|
|
||||||
email: profile.emails[0].value,
|
|
||||||
username: profile.username,
|
|
||||||
provider: 'facebook',
|
|
||||||
facebook: profile._json
|
|
||||||
});
|
|
||||||
user.save(function(err) {
|
|
||||||
if (err) console.log(err);
|
|
||||||
return done(err, user);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return done(err, user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
//Use github strategy
|
|
||||||
passport.use(new GitHubStrategy({
|
|
||||||
clientID: config.github.clientID,
|
|
||||||
clientSecret: config.github.clientSecret,
|
|
||||||
callbackURL: config.github.callbackURL
|
|
||||||
},
|
|
||||||
function(accessToken, refreshToken, profile, done) {
|
|
||||||
User.findOne({
|
|
||||||
'github.id': profile.id
|
|
||||||
}, function(err, user) {
|
|
||||||
if (!user) {
|
|
||||||
user = new User({
|
|
||||||
name: profile.displayName,
|
|
||||||
email: profile.emails[0].value,
|
|
||||||
username: profile.username,
|
|
||||||
provider: 'github',
|
|
||||||
github: profile._json
|
|
||||||
});
|
|
||||||
user.save(function(err) {
|
|
||||||
if (err) console.log(err);
|
|
||||||
return done(err, user);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return done(err, user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
//Use google strategy
|
|
||||||
passport.use(new GoogleStrategy({
|
|
||||||
clientID: config.google.clientID,
|
|
||||||
clientSecret: config.google.clientSecret,
|
|
||||||
callbackURL: config.google.callbackURL
|
|
||||||
},
|
|
||||||
function(accessToken, refreshToken, profile, done) {
|
|
||||||
User.findOne({
|
|
||||||
'google.id': profile.id
|
|
||||||
}, function(err, user) {
|
|
||||||
if (!user) {
|
|
||||||
user = new User({
|
|
||||||
name: profile.displayName,
|
|
||||||
email: profile.emails[0].value,
|
|
||||||
username: profile.username,
|
|
||||||
provider: 'google',
|
|
||||||
google: profile._json
|
|
||||||
});
|
|
||||||
user.save(function(err) {
|
|
||||||
if (err) console.log(err);
|
|
||||||
return done(err, user);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return done(err, user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Express Settings
|
* Express Settings
|
||||||
*/
|
*/
|
||||||
app.set('showStackError', true);
|
|
||||||
app.set('port', process.env.PORT || 3000);
|
app.set('port', process.env.PORT || 3000);
|
||||||
app.locals.pretty = true;
|
|
||||||
app.use(express.compress({
|
|
||||||
filter: function(req, res) {
|
|
||||||
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
|
|
||||||
},
|
|
||||||
level: 9
|
|
||||||
}));
|
|
||||||
app.use(express.favicon());
|
app.use(express.favicon());
|
||||||
app.use(express.static(config.root + '/public'));
|
app.use(express.logger('dev'));
|
||||||
app.set('views', config.root + '/app/views');
|
app.use(express.json());
|
||||||
app.set('view engine', 'jade');
|
app.use(express.urlencoded());
|
||||||
app.enable("jsonp callback");
|
|
||||||
app.use(express.cookieParser());
|
|
||||||
app.use(express.bodyParser());
|
|
||||||
app.use(express.methodOverride());
|
app.use(express.methodOverride());
|
||||||
app.use(express.session({
|
|
||||||
secret: '1337',
|
|
||||||
store: new mongoStore({
|
|
||||||
db: db.connection.db,
|
|
||||||
collection: 'sessions'
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
app.use(flash());
|
|
||||||
app.use(helpers(config.app.name));
|
|
||||||
app.use(passport.initialize());
|
|
||||||
app.use(passport.session());
|
|
||||||
app.use(app.router);
|
app.use(app.router);
|
||||||
|
app.use(express.static(config.root + '/public'));
|
||||||
app.use(function(err, req, res, next) {
|
|
||||||
//Treat as 404
|
|
||||||
if (~err.message.indexOf('not found')) return next();
|
|
||||||
|
|
||||||
//Log it
|
|
||||||
console.error(err.stack);
|
|
||||||
|
|
||||||
//Error page
|
|
||||||
res.status(500).render('500', {
|
|
||||||
error: err.stack
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app.use(function(req, res, next) {
|
|
||||||
res.status(404).render('404', {
|
|
||||||
url: req.originalUrl,
|
|
||||||
error: 'Not found'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//User Routes
|
/**
|
||||||
app.post('/users', users.create);
|
* API Routes
|
||||||
app.get('/users/me', users.me);
|
*/
|
||||||
app.get('/users/:userId', users.show);
|
app.post('/api/users', users.create);
|
||||||
|
app.get('/api/users/me', users.me);
|
||||||
//Setting the facebook oauth routes
|
app.get('/api/users/:userId', users.show);
|
||||||
app.get('/auth/facebook', passport.authenticate('facebook', {
|
app.get('/api/articles', articles.all);
|
||||||
scope: ['email', 'user_about_me'],
|
app.post('/api/articles', requiresLogin, articles.create);
|
||||||
failureRedirect: '/signin'
|
app.get('/api/articles/:articleId', articles.show);
|
||||||
}), users.signin);
|
app.put('/api/articles/:articleId', auth.requiresLogin, auth.article.hasAuthorization, articles.update);
|
||||||
|
app.del('/api/articles/:articleId', auth.requiresLogin, auth.article.hasAuthorization, articles.destroy);
|
||||||
app.get('/auth/facebook/callback', passport.authenticate('facebook', {
|
|
||||||
failureRedirect: '/signin'
|
|
||||||
}), users.authCallback);
|
|
||||||
|
|
||||||
//Setting the github oauth routes
|
|
||||||
app.get('/auth/github', passport.authenticate('github', { failureRedirect: '/signin' }), users.signin);
|
|
||||||
app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/signin' }), users.authCallback);
|
|
||||||
|
|
||||||
//Setting the twitter oauth routes
|
|
||||||
app.get('/auth/twitter', passport.authenticate('twitter', { failureRedirect: '/signin' }), users.signin);
|
|
||||||
app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/signin' }), users.authCallback);
|
|
||||||
|
|
||||||
//Setting the google oauth routes
|
|
||||||
app.get('/auth/google', passport.authenticate('google', {
|
|
||||||
failureRedirect: '/signin',
|
|
||||||
scope: [
|
|
||||||
'https://www.googleapis.com/auth/userinfo.profile',
|
|
||||||
'https://www.googleapis.com/auth/userinfo.email'
|
|
||||||
]
|
|
||||||
}), users.signin);
|
|
||||||
app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/signin' }), users.authCallback);
|
|
||||||
|
|
||||||
//Finish with setting up the userId param
|
|
||||||
app.param('userId', users.user);
|
|
||||||
|
|
||||||
//Article Routes
|
|
||||||
var articles = require('../app/controllers/articles');
|
|
||||||
app.get('/articles', articles.all);
|
|
||||||
app.post('/articles', auth.requiresLogin, articles.create);
|
|
||||||
app.get('/articles/:articleId', articles.show);
|
|
||||||
app.put('/articles/:articleId', auth.requiresLogin, auth.article.hasAuthorization, articles.update);
|
|
||||||
app.del('/articles/:articleId', auth.requiresLogin, auth.article.hasAuthorization, articles.destroy);
|
|
||||||
|
|
||||||
|
|
||||||
//Home route
|
app.listen(app.get('port'), function() {
|
||||||
var index = require('../app/controllers/index');
|
console.log('Express server listening on port ' + app.get('port'));
|
||||||
app.get('/', index.render);
|
});
|
||||||
|
|
||||||
console.log('Express app started on port ' + app.get('port'));
|
|
||||||
app.listen(app.get('port'));
|
|