├── .bowerrc ├── .gitignore ├── public ├── css │ └── app.css ├── scripts │ ├── src │ │ ├── directives.js │ │ ├── filters.js │ │ ├── main.js │ │ ├── app.js │ │ ├── services.js │ │ └── controllers.js │ └── test │ │ ├── appSpec.js │ │ └── test-main.js └── karma.conf.js ├── views ├── partials │ ├── header.html │ ├── login.html │ ├── nav.html │ ├── register.html │ └── auth │ │ ├── thing.html │ │ ├── person.html │ │ └── home.html └── index.html ├── tools └── app.build.js ├── models ├── models.js ├── person.js ├── thing.js └── user.js ├── bower.json ├── package.json ├── config ├── database.js └── passport.js ├── Gruntfile.js ├── server.js ├── app ├── routes.js └── api.js └── README.md /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "public/scripts/lib" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | public/scripts/lib/ 3 | *.idea/ 4 | public/scripts/webapp.min.js 5 | tools/webapp.min.js -------------------------------------------------------------------------------- /public/css/app.css: -------------------------------------------------------------------------------- 1 | /* app css stylesheet */ 2 | 3 | .no-bottom-margin { 4 | margin-bottom: 0px; 5 | border-radius: 0px; 6 | } 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /views/partials/header.html: -------------------------------------------------------------------------------- 1 |
2 |

Welcome to nodejs-expressjs-mongodb-angularjs-bootstrap-toastr-seed

3 |

Star your web-application, from here!

4 |
-------------------------------------------------------------------------------- /public/scripts/src/directives.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* Directives */ 4 | angular.module('myApp.directives', []). 5 | directive('appVersion', ['version', function(version) { 6 | return function(scope, elm, attrs) { 7 | elm.text(version); 8 | }; 9 | }]); -------------------------------------------------------------------------------- /tools/app.build.js: -------------------------------------------------------------------------------- 1 | ({ 2 | baseUrl: '../public/scripts/lib', 3 | mainConfigFile: '../public/scripts/main.js', 4 | preserveLicenseComments: false, //comment in production 5 | out: '../public/scripts/webapp.min.js', 6 | optimize: 'uglify2', 7 | include: ['../main'] 8 | }) 9 | -------------------------------------------------------------------------------- /public/scripts/src/filters.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* Filters */ 4 | angular.module('myApp.filters', []). 5 | filter('interpolate', ['version', function(version) { 6 | return function(text) { 7 | return String(text).replace(/\%VERSION\%/mg, version); 8 | } 9 | }]); 10 | -------------------------------------------------------------------------------- /models/models.js: -------------------------------------------------------------------------------- 1 | module.exports = function(connection) { 2 | 3 | var User = require('./user')(connection); 4 | var Person = require('./person')(connection); 5 | var Thing = require('./thing')(connection); 6 | 7 | return { 8 | user: User, 9 | person: Person, 10 | thing: Thing 11 | } 12 | } -------------------------------------------------------------------------------- /models/person.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | module.exports = function(connection) { 4 | 5 | var Schema = mongoose.Schema; 6 | 7 | var personSchema = new Schema({ 8 | name: String, 9 | age: Number 10 | }); 11 | 12 | var Person = connection.model('Person', personSchema); 13 | 14 | return Person; 15 | } -------------------------------------------------------------------------------- /models/thing.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | module.exports = function(connection) { 4 | 5 | var Schema = mongoose.Schema; 6 | 7 | var thingSchema = new Schema({ 8 | name: String, 9 | size: Number 10 | }); 11 | 12 | var Thing = connection.model('Thing', thingSchema); 13 | 14 | return Thing; 15 | } 16 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.0.2", 4 | "dependencies": { 5 | "angular": "*", 6 | "angular-mocks": "*", 7 | "angular-route": "*", 8 | "angular-local-storage" : "*", 9 | "angular-animate" : "*", 10 | "angular-toastr" : "*", 11 | "jquery": "*", 12 | "bootstrap": "*", 13 | "cryptojslib" : "*", 14 | "requirejs" : "*" 15 | }, 16 | "private": true, 17 | "ignore": [ 18 | "**/.*", 19 | "node_modules", 20 | "bower_components", 21 | "test", 22 | "tests" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "application-name", 3 | "version": "0.0.1", 4 | "private": true, 5 | "main" : "views/index.html", 6 | "dependencies": { 7 | "express": "~3.2.6", 8 | "ejs": "~0.7.1", 9 | "mongoose" : "*", 10 | "mongoose-q":"*", 11 | "passport" : "*", 12 | "passport-local" : "*", 13 | "passport-http-bearer" : "*", 14 | "moment": "*", 15 | "connect-flash" : "*", 16 | "requirejs" : "*", 17 | "node-uuid" : "*", 18 | "grunt": "*", 19 | "grunt-npm-install" : "*", 20 | "grunt-bower-installer" : "*", 21 | "grunt-contrib-requirejs" : "*" 22 | } 23 | } -------------------------------------------------------------------------------- /views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Angular Express MongoDB Bootstrap NotyJS Seed App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var moment = require('moment'); 3 | var expired_time = 60; 4 | 5 | module.exports = function(connection) { 6 | 7 | var Schema = mongoose.Schema; 8 | 9 | var userSchema = new Schema({ 10 | username: String, 11 | password: String, 12 | email: String, 13 | token : { 14 | auth_token: String, 15 | createDate: {type: Date, required: true, default: moment()} 16 | } 17 | 18 | }); 19 | 20 | userSchema.methods.hasExpired = function() { 21 | return (moment().diff(this.token.createDate, 'minutes')) > expired_time; 22 | 23 | }; 24 | 25 | var User = connection.model('User', userSchema); 26 | 27 | 28 | return User; 29 | } 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /public/scripts/test/appSpec.js: -------------------------------------------------------------------------------- 1 | define(['angular','angularMock','app'], function(angular, app) { 2 | 3 | describe('ProvaCtrl', function() { 4 | beforeEach(module('mainApp')); 5 | var $controller; 6 | 7 | beforeEach(inject(function(_$controller_){ 8 | // The injector unwraps the underscores (_) from around the parameter names when matching 9 | $controller = _$controller_; 10 | })); 11 | 12 | describe('firstTest', function() { 13 | var $scope, controller; 14 | 15 | beforeEach(function() { 16 | $scope = {}; 17 | controller = $controller('ProvaCtrl', { $scope: $scope }); 18 | 19 | }); 20 | 21 | it('helloworld', function() { 22 | controller.user = 'Alessandro'; 23 | expect(controller.printHello()).toEqual('Hello World Alessandro'); 24 | }); 25 | 26 | }); 27 | }); 28 | 29 | }); 30 | -------------------------------------------------------------------------------- /config/database.js: -------------------------------------------------------------------------------- 1 | module.exports = function(mongoose) { 2 | 3 | var dbURI = 'mongodb://localhost:27017/myApp'; 4 | var connection = mongoose.createConnection(dbURI,{ server: { poolSize: 5 } }); 5 | 6 | // When successfully connected 7 | connection.on('connected', function () { 8 | console.log('Mongoose connection open to ' + dbURI); 9 | }); 10 | 11 | // If the connection throws an error 12 | connection.on('error',function (err) { 13 | console.log('Mongoose default connection error: ' + err); 14 | }); 15 | 16 | // When the connection is disconnected 17 | connection.on('disconnected', function () { 18 | console.log('Mongoose default connection disconnected'); 19 | }); 20 | 21 | // If the Node process ends, close the Mongoose connection 22 | process.on('SIGINT', function() { 23 | connection.close(function () { 24 | console.log('Mongoose default connection disconnected through app termination'); 25 | process.exit(0); 26 | }); 27 | }); 28 | 29 | return connection; 30 | } 31 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | bower: { 5 | install: { 6 | //just run 'grunt bower:install' and you'll see files from your Bower packages in lib directory 7 | } 8 | }, 9 | requirejs: { 10 | compile: { 11 | options: { 12 | baseUrl: 'public/scripts/lib', 13 | mainConfigFile: 'public/scripts/main.js', 14 | preserveLicenseComments: false, //comment in production 15 | out: 'public/scripts/webapp.min.js', 16 | optimize: 'uglify2', 17 | include: ['../main'] 18 | } 19 | } 20 | }, 21 | nodemon: { 22 | dev: { 23 | script: 'server.js' 24 | } 25 | } 26 | 27 | }); 28 | 29 | grunt.loadNpmTasks('grunt-npm-install'); 30 | grunt.loadNpmTasks('grunt-bower-installer'); 31 | grunt.loadNpmTasks('grunt-contrib-requirejs'); 32 | 33 | grunt.loadNpmTasks('grunt-nodemon'); 34 | 35 | grunt.registerTask('init', ['npm-install', 'bower:install']); 36 | grunt.registerTask('compile', ['requirejs:compile']); 37 | 38 | grunt.registerTask('start', ['nodemon']); 39 | }; 40 | -------------------------------------------------------------------------------- /views/partials/login.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 |
7 |
8 | 9 |
10 |
11 | Login 12 |
13 | 14 |
15 |
16 | 17 |
18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 | 28 |
29 |
30 |
31 | {{vm.failed_login}} 32 |
33 |
34 |
35 | 36 |
-------------------------------------------------------------------------------- /views/partials/nav.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/partials/register.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 | 8 |
9 |
10 | Register User 11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 | 21 | 22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 |
33 | {{vm.failed_register}} 34 |
35 |
36 |
37 | 38 |
-------------------------------------------------------------------------------- /views/partials/auth/thing.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 |
7 |
8 | 9 |
10 | 11 |
Thing
12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 | Create new Thing 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 | 30 |
31 | 32 |
33 | 34 |
35 |
36 | 37 | 38 | 39 |
40 |
41 | 42 |
43 |
-------------------------------------------------------------------------------- /views/partials/auth/person.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 |
7 |
8 | 9 |
10 | 11 |
Person
12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 | Add new Person 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 | 30 |
31 | 32 |
33 | 34 |
35 |
36 | 37 | 38 | 39 |
40 |
41 | 42 |
43 |
-------------------------------------------------------------------------------- /public/scripts/src/main.js: -------------------------------------------------------------------------------- 1 | require.config({ 2 | baseUrl: '../scripts', 3 | paths :{ 4 | 'app' : 'src/app', 5 | 'controllers' : 'src/controllers', 6 | 'services' : 'src/services', 7 | 'angular' :'lib/angular/angular.min', 8 | 'angularRoute' : 'lib/angular-route/angular-route.min', 9 | 'angularLocalStorage' : 'lib/angular-local-storage/dist/angular-local-storage.min', 10 | 'angularAnimate' : 'lib/angular-animate/angular-animate.min', 11 | 'angularToastr': 'lib/angular-toastr/dist/angular-toastr.tpls.min', 12 | 'cryptojslib' : 'lib/cryptojslib/rollups/pbkdf2', 13 | 'jquery' : 'lib/jquery/dist/jquery.min', 14 | 'bootstrap' : 'lib/bootstrap/dist/js/bootstrap.min' 15 | }, 16 | shim: { 17 | 'angular': { 18 | exports: 'angular' 19 | }, 20 | 'angularRoute' :{ 21 | deps: ['angular'], 22 | exports : 'angularRoute' 23 | }, 24 | 'angularAnimate' :{ 25 | deps: ['angular'], 26 | exports : 'angularAnimate' 27 | }, 28 | 'angularLocalStorage' :{ 29 | deps: ['angular'], 30 | exports : 'angularLocalStorage' 31 | }, 32 | 'cryptojslib' : { 33 | exports : 'cryptojslib' 34 | }, 35 | 'angularToastr': { 36 | deps: ['angularAnimate'], 37 | exports: 'angularToastr' 38 | }, 39 | 'bootstrap' : ['jquery'] 40 | } 41 | }); 42 | 43 | 44 | require(['require','angular','bootstrap','app'], function () { 45 | angular.element(document).ready(function() { 46 | angular.bootstrap(document, ['mainApp']); 47 | }); 48 | }); -------------------------------------------------------------------------------- /public/scripts/test/test-main.js: -------------------------------------------------------------------------------- 1 | var tests = []; 2 | for (var file in window.__karma__.files) { 3 | if (window.__karma__.files.hasOwnProperty(file)) { 4 | if (/Spec\.js$/.test(file)) { 5 | tests.push(file); 6 | } 7 | } 8 | } 9 | 10 | requirejs.config({ 11 | // Karma serves files from '/base' 12 | baseUrl: '/base/scripts', 13 | 14 | paths :{ 15 | 'app' : 'src/app', 16 | 'controllers' : 'src/controllers', 17 | 'services' : 'src/services', 18 | 'angular' :'lib/angular/angular.min', 19 | 'angularRoute' : 'lib/angular-route/angular-route.min', 20 | 'angularLocalStorage' : 'lib/angular-local-storage/dist/angular-local-storage.min', 21 | 'angularAnimate' : 'lib/angular-animate/angular-animate.min', 22 | 'angularMock' :'lib/angular-mocks/angular-mocks', 23 | 'angularToastr': 'lib/angular-toastr/dist/angular-toastr.tpls.min', 24 | 'cryptojslib' : 'lib/cryptojslib/rollups/pbkdf2', 25 | 'jquery' : 'lib/jquery/dist/jquery.min', 26 | 'bootstrap' : 'lib/bootstrap/dist/js/bootstrap.min' 27 | }, 28 | shim: { 29 | 'angular': { 30 | exports: 'angular' 31 | }, 32 | 'angularRoute' :{ 33 | deps: ['angular'], 34 | exports : 'angularRoute' 35 | }, 36 | 'angularAnimate' :{ 37 | deps: ['angular'], 38 | exports : 'angularAnimate' 39 | }, 40 | 'angularLocalStorage' :{ 41 | deps: ['angular'], 42 | exports : 'angularLocalStorage' 43 | }, 44 | 'cryptojslib' : { 45 | exports : 'cryptojslib' 46 | }, 47 | 'angularToastr': { 48 | deps: ['angularAnimate'], 49 | exports: 'angularToastr' 50 | }, 51 | 'angularMock' :{ 52 | deps: ['angular'], 53 | exports : 'angularMock' 54 | }, 55 | 'bootstrap' : ['jquery'] 56 | }, 57 | 58 | // ask Require.js to load these files (all our tests) 59 | deps: tests, 60 | 61 | // start test run, once Require.js is done 62 | callback: window.__karma__.start 63 | }); 64 | -------------------------------------------------------------------------------- /public/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Wed Mar 25 2015 20:55:26 GMT+0100 (CET) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine', 'requirejs'], 14 | 15 | 16 | // list of files / patterns to load in the browser 17 | files: [ 18 | 19 | {pattern: 'scripts/lib/**/*.js', included: false}, 20 | {pattern: 'scripts/src/**/*.js', included: false}, 21 | {pattern: 'scripts/test/**/*Spec.js', included: false}, 22 | 23 | 'scripts/test/test-main.js' 24 | ], 25 | 26 | 27 | // list of files to exclude 28 | exclude: [ 29 | 'src/main.js' 30 | ], 31 | 32 | 33 | // preprocess matching files before serving them to the browser 34 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 35 | preprocessors: { 36 | }, 37 | 38 | 39 | // test results reporter to use 40 | // possible values: 'dots', 'progress' 41 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 42 | reporters: ['progress'], 43 | 44 | 45 | // web server port 46 | port: 9876, 47 | 48 | 49 | // enable / disable colors in the output (reporters and logs) 50 | colors: true, 51 | 52 | 53 | // level of logging 54 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 55 | logLevel: config.LOG_INFO, 56 | 57 | 58 | // enable / disable watching file and executing tests whenever any file changes 59 | autoWatch: true, 60 | 61 | 62 | // start these browsers 63 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 64 | browsers: ['Chrome', 'ChromeCanary', 'Firefox', 'Safari', 'PhantomJS', 'Opera', 'IE'], 65 | 66 | 67 | // Continuous Integration mode 68 | // if true, Karma captures browsers, runs the tests and exits 69 | singleRun: false 70 | }); 71 | }; 72 | -------------------------------------------------------------------------------- /config/passport.js: -------------------------------------------------------------------------------- 1 | // load all the things we need 2 | var LocalStrategy = require('passport-local').Strategy; 3 | var BearerStrategy = require('passport-http-bearer').Strategy; 4 | var uuid = require('node-uuid'); 5 | var moment = require('moment'); 6 | 7 | module.exports = function(passport,models) { 8 | 9 | var User = models.user; 10 | 11 | // used to serialize the user for the session 12 | passport.serializeUser(function(user, done) { 13 | done(null, user.id); 14 | }); 15 | 16 | // used to deserialize the user 17 | passport.deserializeUser(function(id, done) { 18 | User.findById(id, function(err, user) { 19 | done(err, user); 20 | }); 21 | }); 22 | 23 | passport.use('local-login',new LocalStrategy( 24 | function(username,password,done) { 25 | 26 | User.findOne({ username: username, 27 | password: password 28 | },function (err, user) { 29 | 30 | if (err){ 31 | return done(err); 32 | } 33 | 34 | if (!user){ 35 | return done(null, false); 36 | } 37 | user.token.auth_token = uuid.v1(); 38 | user.token.createDate = moment(); 39 | 40 | user.save(function(err,user){ 41 | if (err){ 42 | return done(err); 43 | } 44 | return done(null, user); 45 | }); 46 | 47 | }); 48 | } 49 | )); 50 | 51 | passport.use('local-authorization',new BearerStrategy( 52 | function(token, done) { 53 | 54 | console.log(token); 55 | 56 | User.findOne({ 'token.auth_token' : token }, function (err, user) { 57 | if (err) { return done(err); } 58 | if (!user) { 59 | console.log(user); 60 | return done(null, false); 61 | } 62 | if (user.hasExpired()) { 63 | return done(null, false); 64 | } 65 | return done(null, user, { scope: 'all' }); 66 | }); 67 | } 68 | )); 69 | 70 | } 71 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies 3 | */ 4 | var express = require('express'); 5 | var mongoose = require('mongoose'); 6 | var passport = require('passport'); 7 | var flash = require('connect-flash'); 8 | var http = require('http'); 9 | var path = path = require('path'); 10 | var uuid = require('node-uuid'); 11 | 12 | var vhost = 'nodejsapp.local' 13 | var port = process.env.PORT || 3000; 14 | var ip = process.env.IP || "localhost"; 15 | 16 | var app = express(); 17 | 18 | var connection = require('./config/database')(mongoose); 19 | var models = require('./models/models')(connection); 20 | require('./config/passport')(passport,models); // pass passport for configuration 21 | 22 | 23 | app.configure(function() { 24 | // set up our express application 25 | app.set('port', port); 26 | app.use(express.logger('dev')); // log every request to the console 27 | app.use(express.cookieParser()); // read cookies (needed for auth) 28 | app.use(express.bodyParser()); // get information from html forms 29 | app.set('view engine', 'html'); // set up html for templating 30 | app.engine('.html', require('ejs').__express); 31 | app.set('views', __dirname + '/views'); 32 | app.use(express.static(path.join(__dirname, 'public'))); 33 | //app.use(express.session({ secret: 'keyboard cat' }));// persistent login sessions 34 | app.use(express.methodOverride()); 35 | app.use(express.json()); 36 | app.use(express.urlencoded()); 37 | //app.use(flash()); // use connect-flash for flash messages stored in session 38 | 39 | //passport configuration 40 | app.use(passport.initialize()); 41 | //app.use(passport.session());// persistent login sessions 42 | //provagg 43 | app.use(app.router); //init routing 44 | 45 | }); 46 | 47 | require('./app/routes.js')(app, passport,models); // load our routes and pass in our app and fully configured passport 48 | 49 | // development only 50 | if (app.get('env') === 'development') { 51 | app.use(express.errorHandler()); 52 | }; 53 | 54 | // production only 55 | if (app.get('env') === 'production') { 56 | // TODO 57 | }; 58 | 59 | //express.vhost(vhost, app); 60 | 61 | var server = http.createServer(app).listen(app.get('port'), function () { 62 | console.log('Express server listening on port ' + vhost+":"+server.address().port); 63 | }); -------------------------------------------------------------------------------- /app/routes.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app, passport,models) { 2 | 3 | var api = require('./api.js')(models); 4 | 5 | app.get('/', function(req, res){ 6 | res.render('index'); 7 | }); 8 | 9 | app.get('/partials/:name', showClientRequest, function (req, res) { 10 | var name = req.params.name; 11 | res.render('partials/' + name); 12 | }); 13 | 14 | app.get('/partials/auth/:name', showClientRequest, passport.authenticate('local-authorization', { 15 | session: false 16 | }),function (req, res) { 17 | var name = req.params.name; 18 | res.render('partials/auth/' + name); 19 | }); 20 | 21 | app.post('/api/login', showClientRequest, passport.authenticate('local-login', { 22 | session: false 23 | }),api.login); 24 | 25 | app.post('/api/signup', showClientRequest, api.signup); 26 | 27 | 28 | app.get('/api/logout', showClientRequest, passport.authenticate('local-authorization', { 29 | session: false 30 | }),api.logout); 31 | 32 | app.get('/api/people', showClientRequest, passport.authenticate('local-authorization', { 33 | session: false 34 | }),api.getPeople); 35 | 36 | app.post('/api/person', showClientRequest, passport.authenticate('local-authorization', { 37 | session: false 38 | }),api.createPerson); 39 | 40 | app.put('/api/person/:id', showClientRequest, passport.authenticate('local-authorization', { 41 | session: false 42 | }),api.updatePerson); 43 | 44 | app.delete('/api/person/:id', showClientRequest, passport.authenticate('local-authorization', { 45 | session: false 46 | }),api.removePerson); 47 | 48 | app.get('/api/things', showClientRequest, passport.authenticate('local-authorization', { 49 | session: false 50 | }),api.getThings); 51 | 52 | app.post('/api/thing', showClientRequest, passport.authenticate('local-authorization', { 53 | session: false 54 | }),api.createThing); 55 | 56 | app.put('/api/thing/:id', showClientRequest, passport.authenticate('local-authorization', { 57 | session: false 58 | }),api.updateThing); 59 | 60 | app.delete('/api/thing/:id', showClientRequest, passport.authenticate('local-authorization', { 61 | session: false 62 | }),api.removeThing); 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | function showClientRequest(req, res, next) { 75 | var request = { 76 | REQUEST : { 77 | HEADERS: req.headers, 78 | BODY : req.body 79 | } 80 | } 81 | console.log(request) 82 | return next(); 83 | } 84 | } -------------------------------------------------------------------------------- /public/scripts/src/app.js: -------------------------------------------------------------------------------- 1 | 2 | define([ 3 | 'angular', 4 | 'angularRoute', 5 | 'angularAnimate', 6 | 'angularLocalStorage', 7 | 'angularToastr', 8 | 'cryptojslib', 9 | 'controllers', 10 | 'services' 11 | 12 | ], function (angular) { 13 | 'use strict'; 14 | 15 | var mainApp = angular.module('mainApp', [ 16 | 'ngRoute', 17 | 'ngAnimate', 18 | 'LocalStorageModule', 19 | 'toastr', 20 | 'myAppServices', 21 | 'mainAppControllers' 22 | ]); 23 | 24 | 25 | mainApp.config(['$httpProvider',function ($httpProvider) { 26 | $httpProvider.interceptors.push('TokenInterceptor'); 27 | }]); 28 | 29 | mainApp.config(function(toastrConfig) { 30 | angular.extend(toastrConfig, { 31 | allowHtml: false, 32 | closeButton: true, 33 | closeHtml: '', 34 | containerId: 'toast-container', 35 | extendedTimeOut: 2000, 36 | iconClasses: { 37 | error: 'toast-error', 38 | info: 'toast-info', 39 | success: 'toast-success', 40 | warning: 'toast-warning' 41 | }, 42 | maxOpened: 0, 43 | messageClass: 'toast-message', 44 | newestOnTop: true, 45 | onHidden: null, 46 | onShown: null, 47 | positionClass: 'toast-top-full-width', 48 | preventDuplicates: false, 49 | progressBar: false, 50 | tapToDismiss: true, 51 | target: 'body', 52 | templates: { 53 | toast: 'directives/toast/toast.html', 54 | progressbar: 'directives/progressbar/progressbar.html' 55 | }, 56 | timeOut: 5000, 57 | titleClass: 'toast-title', 58 | toastClass: 'toast' 59 | }); 60 | }); 61 | 62 | 63 | mainApp.config(['$routeProvider', 64 | function($routeProvider) { 65 | 66 | $routeProvider. 67 | when('/login', { 68 | templateUrl: 'partials/login', 69 | controller: 'LoginCtrl', 70 | controllerAs: 'vm', 71 | access: { requiredLogin: false } 72 | }). 73 | when('/register', { 74 | templateUrl: 'partials/register', 75 | controller: 'RegistrationCtrl', 76 | controllerAs: 'vm', 77 | access: { requiredLogin: false } 78 | }). 79 | when('/home', { 80 | templateUrl: 'partials/auth/home', 81 | controller: 'HomeCtrl', 82 | controllerAs: 'vm', 83 | resolve: { 84 | data : function(Resolver,ResourceService){ 85 | return Resolver([ResourceService.getPeople(true),ResourceService.getThings(true)]) 86 | } 87 | }, 88 | access: { requiredLogin: true } 89 | }). 90 | when('/person', { 91 | templateUrl: 'partials/auth/person', 92 | controller: 'PersonCtrl', 93 | controllerAs: 'vm', 94 | access: { requiredLogin: true } 95 | }). 96 | when('/thing', { 97 | templateUrl: 'partials/auth/thing', 98 | controller: 'ThingCtrl', 99 | controllerAs: 'vm', 100 | access: { requiredLogin: true } 101 | }). 102 | otherwise({ 103 | redirectTo: '/login' 104 | }); 105 | } 106 | 107 | ]); 108 | 109 | 110 | mainApp.run(['$rootScope','$location','AuthenticationService',function($rootScope, $location, AuthenticationService) { 111 | $rootScope.$on("$routeChangeStart", function(event, nextRoute, currentRoute) { 112 | 113 | if (nextRoute.access===undefined) { 114 | $location.path("/login"); 115 | }else if (nextRoute.access.requiredLogin && !AuthenticationService.isLogged()) { 116 | $location.path("/login"); 117 | }else if (AuthenticationService.isLogged() && !nextRoute.access.requiredLogin) { 118 | $location.path("/home"); 119 | } 120 | }); 121 | }]); 122 | 123 | return mainApp; 124 | 125 | 126 | }); 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #[NEMTAB] NodeJS ExpressJS MongoDB Toastr AngularJS Bootstrap Seed 2 | 3 | I improved this project, adding Toastr (https://github.com/CodeSeven/toastr) for 4 | Popup Notifications, and creating a small set of REST APIs to perform login, 5 | logout, signup (using passport js as middleware) and some CRUD operations 6 | with Express JS and MongoDB. 7 | 8 | I remove Jade Templating, because i don't like it, so i implemented some 9 | little html partilals, using Angular JS template engine. 10 | 11 | Also added bower configuration file to handle JS browser dependencies. 12 | 13 | Added RequireJS. 14 | Added unit test base configuration with Jasmine and Karma. 15 | 16 | Renamed app.js in server.js. 17 | 18 | To start application : 19 | npm install // to install node modules dependencies 20 | bower install // to install bower dependencies 21 | node server.js 22 | 23 | To minify application: 24 | node_modules/requirejs/bin/r.js -o tools/app.build.js 25 | 26 | 27 | 28 | Forked from [btford/angular-express-seed](https://github.com/btford/angular-express-seed) and spiced with [Twitter Bootstrap](https://github.com/twitter/bootstrap). jQuery added for convenience. 29 | 30 | Start an awesome app with AngularJS + Bootstrap on the front, Express + Node on the back. This project is an 31 | application skeleton for a typical [AngularJS](http://angularjs.org/) web app for those who want 32 | to use Node to serve their app. 33 | 34 | The seed contains angular libraries, test libraries and a bunch of scripts all preconfigured for 35 | instant web development gratification. Just clone the repo (or download the zip/tarball) and 36 | you're ready to develop your application. 37 | 38 | The seed app shows how to wire together Angular client-side components with Express on the server. 39 | It also illustrates writing angular partials/views with the Jade templating library. 40 | 41 | _Note: Although Jade supports interpolation, you should be doing that mostly on the client. Mixing 42 | server and browser templating will convolute your app. Instead, use Jade as a syntactic sugar for 43 | HTML, and let AngularJS take care of interpolation on the browser side._ 44 | 45 | ## How to use angular-express-seed 46 | 47 | Clone the angular-express-seed repository, run `npm install` to grab the dependencies and start hacking! 48 | 49 | ### Running the app 50 | 51 | Runs like a typical express app: 52 | 53 | node server.js 54 | 55 | ### Running tests 56 | 57 | Coming soon! 58 | 59 | ### Receiving updates from upstream 60 | 61 | Just fetch the changes and merge them into your project with git. 62 | 63 | 64 | ## Directory Layout 65 | 66 | server.js --> app config 67 | package.json --> for npm 68 | config/ --> contains mongoDB and passport configuration 69 | database.js 70 | passport.js 71 | models/ --> contains mongoDB simple user Schema 72 | users.js 73 | person.js 74 | thing.js 75 | models.js 76 | public/ --> all of the files to be used in on the client side 77 | css/ --> css files 78 | app.css --> default stylesheet 79 | js/ --> javascript files 80 | app.js --> declare top-level app module 81 | controllers.js --> application controllers 82 | directives.js --> custom angular directives 83 | filters.js --> custom angular filters 84 | services.js --> custom angular services 85 | bower_components/ --> angular and 3rd party JavaScript libraries 86 | angular/ 87 | angular-local-storage/ 88 | angular-route/ 89 | bootstrap/ 90 | cryptojslib/ 91 | jquery/ 92 | noty/ 93 | app/ 94 | api.js --> api definitions 95 | routes.js --> route for serving HTML pages, JSON and partials 96 | views/ 97 | index.html --> main page for app 98 | partials/ --> angular view partials (partial jade templates) 99 | header.html 100 | nav.html 101 | register.html 102 | login.html 103 | auth/ 104 | home.html 105 | person.html 106 | thing.html 107 | 108 | 109 | 110 | ## Example App 111 | 112 | A simple [blog](https://github.com/btford/angular-express-blog) based on this seed. 113 | 114 | 115 | ## Contact 116 | 117 | For more information on AngularJS please check out http://angularjs.org/ 118 | For more on Express and Jade, http://expressjs.com/ and http://jade-lang.com/ are 119 | your friends. 120 | -------------------------------------------------------------------------------- /public/scripts/src/services.js: -------------------------------------------------------------------------------- 1 | define(['angular'], function (angular) { 2 | 'use strict'; 3 | 4 | var myAppServices = angular.module('myAppServices', []); 5 | myAppServices.service('Resolver',['$q', Resolver]); 6 | myAppServices.service('ResourceService',['$q', '$http', ResourceService]); 7 | myAppServices.service('TokenInterceptor',['$q','$location','localStorageService', TokenInterceptor]); 8 | myAppServices.service('CryptoJSService',[CryptoJSService]); 9 | myAppServices.service('AuthenticationService',['localStorageService', AuthenticationService]); 10 | 11 | 12 | function Resolver($q) 13 | { 14 | return function(promises){ 15 | return $q.all(promises); 16 | } 17 | } 18 | 19 | function ResourceService($q,$http) 20 | { 21 | 22 | var _promises = {}; 23 | 24 | var _genericCallback = function(key, data){ 25 | _promises[key] = data; 26 | }; 27 | 28 | var _promisesGetter = function(method, URL, data, key, refresh){ 29 | if(!refresh && _promises[key]!== undefined){ 30 | return $q.when(_promises[key]); 31 | }else{ 32 | return _ajaxRequest(method, URL, data, key); 33 | } 34 | }; 35 | 36 | var _ajaxRequest = function(method, URL, data, key){ 37 | var deferred = $q.defer(); 38 | $http({method: method, url: URL, data:data}). 39 | success(function(data) { 40 | deferred.resolve(data); 41 | if(URL==="GET") _genericCallback(key,data); 42 | }). 43 | error(function(data) { 44 | deferred.reject(data); 45 | } 46 | ); 47 | return deferred.promise; 48 | }; 49 | 50 | return { 51 | getPeople : function(refresh){ 52 | return _promisesGetter('GET','/api/people', null, "people", refresh); 53 | }, 54 | getThings : function(refresh){ 55 | return _promisesGetter('GET','/api/things', null, "things", refresh); 56 | }, 57 | createThing : function(thing){ 58 | return _ajaxRequest('POST', '/api/thing', thing, null); 59 | }, 60 | deleteThing : function(thing){ 61 | return _ajaxRequest('DELETE', '/api/thing/'+thing._id, null, null); 62 | }, 63 | createPerson : function(person){ 64 | return _ajaxRequest('POST', '/api/person', person, null); 65 | }, 66 | deletePerson : function(person){ 67 | return _ajaxRequest('DELETE', '/api/person/'+person._id, null, null); 68 | }, 69 | updateThing : function(thing){ 70 | return _ajaxRequest('PUT', '/api/thing/'+thing._id, {thing : thing}, null); 71 | }, 72 | updatePerson: function(person){ 73 | return _ajaxRequest('PUT', '/api/person/'+person._id, {person : person}, null); 74 | }, 75 | signup : function(user){ 76 | return _ajaxRequest('POST', '/api/signup', user, null); 77 | }, 78 | login : function(user){ 79 | return _ajaxRequest('POST', '/api/login', user, null); 80 | } 81 | 82 | 83 | } 84 | } 85 | 86 | function TokenInterceptor($q, $location, localStorageService) 87 | { 88 | return { 89 | request: function (config) { 90 | config.headers = config.headers || {}; 91 | 92 | if(localStorageService.get("auth_token")!==null) 93 | config.headers.Authorization = 'Bearer '+localStorageService.get("auth_token"); 94 | 95 | return config; 96 | }, 97 | 98 | response: function (response) { 99 | return response || $q.when(response); 100 | }, 101 | responseError : function (response) { 102 | 103 | if(response.config.url!=="/api/login" && response.status===401){ 104 | localStorageService.clearAll(); 105 | $location.path("/login"); 106 | } 107 | 108 | return $q.reject(response); 109 | 110 | } 111 | }; 112 | } 113 | 114 | 115 | function CryptoJSService(){ 116 | return CryptoJS; 117 | } 118 | 119 | function AuthenticationService(localStorageService){ 120 | return { 121 | isLogged: function() 122 | { 123 | var authenticated = false; 124 | if(localStorageService.get("auth_token")!==null) 125 | authenticated = true; 126 | 127 | return authenticated; 128 | } 129 | } 130 | } 131 | 132 | return myAppServices; 133 | }); -------------------------------------------------------------------------------- /app/api.js: -------------------------------------------------------------------------------- 1 | module.exports = function(models){ 2 | 3 | var User = models.user; 4 | var Person = models.person; 5 | var Thing = models.thing; 6 | 7 | return { 8 | 9 | signup: function (req,res) 10 | { 11 | 12 | var body = req.body; 13 | 14 | User.findOne({ username: body.username 15 | },function(err, user) { 16 | if (err) 17 | res.send(500, {'message': err}); 18 | // check to see if theres already a user with that email 19 | if (user) { 20 | res.send(403, {'message': 'User already exist!'}); 21 | }else { 22 | var newUser = new User({ username: body.username,email: body.email, password:body.password}) 23 | newUser.save(function (err, user) { 24 | if (err){ 25 | res.send(500, {'message': err}); 26 | } 27 | res.json({ 'message': 'User was successfully registered!'}); 28 | }); 29 | } 30 | }); 31 | }, 32 | 33 | login:function(req,res) 34 | { 35 | res.json({ auth_token: req.user.token.auth_token}); 36 | }, 37 | 38 | logout: function(req,res) 39 | { 40 | req.user.auth_token = null; 41 | req.user.save(function(err,user){ 42 | if (err){ 43 | res.send(500, {'message': err}); 44 | } 45 | res.json({ message: 'See you!'}); 46 | }); 47 | }, 48 | createPerson: function(req,res) 49 | { 50 | var person = req.body.person; 51 | 52 | if (typeof person.name != "string") { 53 | res.send(400, {'message': "Name must be a string!"}); 54 | } 55 | if (typeof person.age != "number") { 56 | res.send(400, {'message': "Age must be a number!"}); 57 | } 58 | 59 | var newPerson = new Person({ name: person.name, age: person.age}) 60 | newPerson.save(function (err, user) { 61 | if (err){ 62 | res.send(500, {'message': err}); 63 | } 64 | res.json({ 'message': 'Person was successfully added!'}); 65 | }); 66 | 67 | }, 68 | updatePerson: function(req,res) 69 | { 70 | var _id = req.params.id; 71 | var person = req.body.person; 72 | 73 | var query = { _id: _id }; 74 | Person.update(query, {name:person.name,age:person.age}, null, function (err, thing) { 75 | if (err){ 76 | res.send(500, {'message': err}); 77 | } 78 | res.json({ 'message': 'Person was successfully updated!'}); 79 | }) 80 | 81 | }, 82 | removePerson: function(req,res) 83 | { 84 | var _id = req.params.id; 85 | 86 | Person.remove({ _id:_id}, function (err, user) { 87 | if (err){ 88 | res.send(500, {'message': err}); 89 | } 90 | res.json({ 'message': 'Person was successfully removed!'}); 91 | }) 92 | 93 | 94 | }, 95 | getPeople: function(req,res) 96 | { 97 | 98 | Person.find(function(err,people){ 99 | res.json({people: people }); 100 | }) 101 | 102 | 103 | }, 104 | createThing: function(req,res) 105 | { 106 | 107 | console.log(req.body); 108 | var thing = req.body.thing; 109 | 110 | if (typeof thing.name != "string") { 111 | res.send(400, {'message': "Name must be a string!"}); 112 | } 113 | if (typeof thing.size != "number") { 114 | res.send(400, {'message': "Size must be a number!"}); 115 | } 116 | 117 | var newThing = new Thing({ name: thing.name, size: thing.size}) 118 | newThing.save(function (err, thing) { 119 | if (err){ 120 | res.send(500, {'message': err}); 121 | } 122 | res.json({ 'message': 'Thing was successfully created!'}); 123 | }); 124 | 125 | }, 126 | updateThing: function(req,res) 127 | { 128 | var _id = req.params.id; 129 | console.log(req.body); 130 | console.log(_id); 131 | 132 | var thing = req.body.thing; 133 | 134 | var query = { _id: _id }; 135 | Thing.update(query, {name:thing.name,size:thing.size}, null, function (err, thing) { 136 | if (err){ 137 | res.send(500, {'message': err}); 138 | } 139 | res.json({ 'message': 'Thing was successfully updated!'}); 140 | }) 141 | 142 | }, 143 | removeThing: function(req,res) 144 | { 145 | var _id = req.params.id; 146 | 147 | Thing.remove({ _id:_id}, function (err, user) { 148 | if (err){ 149 | res.send(500, {'message': err}); 150 | } 151 | res.json({ 'message': 'Thing was successfully removed!'}); 152 | }) 153 | 154 | }, 155 | 156 | getThings: function(req,res) 157 | { 158 | Thing.find(function(err,things){ 159 | res.json({things: things }); 160 | }); 161 | 162 | } 163 | 164 | 165 | } 166 | 167 | } 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /public/scripts/src/controllers.js: -------------------------------------------------------------------------------- 1 | define(['angular'], function (angular) { 2 | 'use strict'; 3 | 4 | var mainAppControllers = angular.module('mainAppControllers', []); 5 | mainAppControllers.controller('NavCtrl', ['$location', 'localStorageService', 'AuthenticationService', NavCtrl]); 6 | mainAppControllers.controller('LoginCtrl', ['$location', 'ResourceService' ,'CryptoJSService', 'localStorageService', 'toastr' ,LoginCtrl]); 7 | mainAppControllers.controller('RegistrationCtrl', ['ResourceService', 'CryptoJSService', 'toastr', RegistrationCtrl]); 8 | mainAppControllers.controller('HomeCtrl', ['ResourceService', 'data', 'toastr', HomeCtrl]); 9 | mainAppControllers.controller('PersonCtrl', ['ResourceService', 'toastr', PersonCtrl]); 10 | mainAppControllers.controller('ThingCtrl', ['ResourceService', 'toastr', ThingCtrl]); 11 | mainAppControllers.controller('ProvaCtrl', [ProvaCtrl]); 12 | 13 | function ProvaCtrl() { 14 | var vm = this; 15 | vm.user = ""; 16 | } 17 | 18 | ProvaCtrl.prototype.printHello = function() 19 | { 20 | var vm = this; 21 | return "Hello World "+vm.user; 22 | }; 23 | 24 | 25 | function NavCtrl($location, localStorageService, AuthenticationService) 26 | { 27 | var vm = this; 28 | vm.$location = $location; 29 | vm.localStorageService = localStorageService; 30 | vm.isAuthenticated = AuthenticationService.isLogged() 31 | } 32 | 33 | NavCtrl.prototype.logout = function () 34 | { 35 | var vm = this; 36 | vm.localStorageService.clearAll(); 37 | vm.$location.path("/login"); 38 | }; 39 | 40 | 41 | 42 | function LoginCtrl ($location, ResourceService, CryptoJS, localStorageService, toastr) 43 | { 44 | var vm = this; 45 | vm.$location = $location; 46 | vm.ResourceService = ResourceService; 47 | vm.CryptoJS = CryptoJS; 48 | vm.localStorageService = localStorageService; 49 | vm.toastr = toastr; 50 | 51 | vm.failed_login = ""; 52 | } 53 | 54 | LoginCtrl.prototype.submit = function() 55 | { 56 | var vm = this; 57 | var salt = vm.username; 58 | var enc_password = CryptoJS.PBKDF2(vm.password, salt, { keySize: 256/32 }); 59 | 60 | var user = {"username": vm.username, "password": enc_password.toString()}; 61 | 62 | if(vm.username!==undefined || vm.password !==undefined){ 63 | 64 | vm.ResourceService.login(user).then(function(data){ 65 | vm.localStorageService.set("auth_token",data.auth_token); 66 | vm.$location.path("/home"); 67 | },function(data, status) { 68 | if(status===401){ 69 | vm.toastr.error('Wrong username and/or password!'); 70 | }else{ 71 | vm.toastr.error(data); 72 | } 73 | }); 74 | 75 | }else{ 76 | noty({text: 'Username and password are mandatory!', timeout: 2000, type: 'error'}); 77 | } 78 | }; 79 | 80 | function RegistrationCtrl (ResourceService, CryptoJS, toastr) 81 | { 82 | var vm = this; 83 | vm.ResourceService = ResourceService; 84 | vm.CryptoJS = CryptoJS; 85 | vm.toastr = toastr; 86 | } 87 | 88 | RegistrationCtrl.prototype.signup = function() 89 | { 90 | var vm = this; 91 | var salt = vm.username; 92 | 93 | var enc_password = CryptoJS.PBKDF2(vm.password, salt, { keySize: 256/32 }); 94 | var enc_check_password = CryptoJS.PBKDF2(vm.check_password, salt, { keySize: 256/32 }); 95 | 96 | var user = {"username": vm.username, "password": enc_password.toString(), "check_password" : enc_check_password.toString() }; 97 | 98 | if(vm.username!==undefined || vm.password !==undefined || vm.check_password !==undefined){ 99 | if(vm.password !== vm.check_password){ 100 | vm.toastr.warning('password and check_password must be the same!'); 101 | }else{ 102 | vm.ResourceService.signup(user).then(function(){ 103 | vm.toastr.success('User successfully registered!'); 104 | vm.username = null; 105 | vm.password = null; 106 | vm.check_password = null; 107 | },function(data) { 108 | vm.toastr.error(data.message); 109 | }); 110 | } 111 | }else{ 112 | noty({text: 'Username and password are mandatory!', timeout: 2000, type: 'warning'}); 113 | } 114 | }; 115 | 116 | 117 | function HomeCtrl(ResourceService, data, toastr) 118 | { 119 | var vm = this; 120 | vm.ResourceService = ResourceService; 121 | vm.data = data; 122 | vm.toastr = toastr; 123 | 124 | vm.people = data[0].people; 125 | vm.things = data[1].things; 126 | } 127 | 128 | HomeCtrl.prototype.updatePerson = function(index, modify) 129 | { 130 | var vm = this; 131 | var person = vm.people[index]; 132 | 133 | if(modify){ 134 | vm.people[index].modify=true; 135 | }else{ 136 | vm.ResourceService.updatePerson(person).then(function(){ 137 | vm.people[index].modify=false; 138 | vm.toastr.success("Person successfully updated!"); 139 | },function(data, status) { 140 | if(status!==401){ 141 | vm.toastr.error(data); 142 | } 143 | }); 144 | } 145 | }; 146 | 147 | HomeCtrl.prototype.updateThing = function(index, modify) 148 | { 149 | var vm = this; 150 | var thing = vm.things[index]; 151 | 152 | if(modify){ 153 | vm.things[index].modify=true; 154 | }else{ 155 | 156 | vm.ResourceService.updateThing(thing).then(function(){ 157 | vm.things[index].modify=false; 158 | vm.toastr.success("Thing successfully updated!"); 159 | },function(data, status) { 160 | if(status!==401){ 161 | vm.toastr.error(data); 162 | } 163 | }); 164 | } 165 | }; 166 | 167 | HomeCtrl.prototype.deleteThing = function(index) 168 | { 169 | var vm = this; 170 | var thing = vm.things[index]; 171 | 172 | vm.ResourceService.deleteThing(thing).then(function(){ 173 | vm.things.splice(index, 1); 174 | vm.toastr.success("Thing successfully deleted!"); 175 | },function(data, status) { 176 | if(status!==401){ 177 | vm.toastr.error(data); 178 | } 179 | }); 180 | }; 181 | 182 | HomeCtrl.prototype.deletePerson = function(index) 183 | { 184 | var vm = this; 185 | var person = vm.people[index]; 186 | 187 | vm.ResourceService.deletePerson(person).then(function(){ 188 | vm.people.splice(index, 1); 189 | vm.toastr.success("Person successfully deleted!"); 190 | },function(data, status) { 191 | if(status!==401){ 192 | vm.toastr.error(data); 193 | } 194 | }); 195 | }; 196 | 197 | function PersonCtrl(ResourceService, toastr) { 198 | var vm = this; 199 | vm.person = null; 200 | vm.ResourceService = ResourceService; 201 | vm.toastr = toastr; 202 | } 203 | 204 | PersonCtrl.prototype.createPerson = function() 205 | { 206 | var vm = this; 207 | var person = {person: vm.person}; 208 | 209 | vm.ResourceService.createPerson(person).then(function(data){ 210 | vm.person = null; 211 | vm.toastr.success(data.message); 212 | },function(data, status) { 213 | if(status!==401){ 214 | vm.toastr.error(data); 215 | } 216 | }); 217 | }; 218 | 219 | 220 | function ThingCtrl(ResourceService, toastr) 221 | { 222 | var vm = this; 223 | vm.thing = null; 224 | vm.ResourceService = ResourceService; 225 | vm.toastr = toastr; 226 | } 227 | 228 | ThingCtrl.prototype.createThing = function() 229 | { 230 | var vm = this; 231 | var thing = {thing: vm.thing}; 232 | 233 | vm.ResourceService.createThing(thing).then(function(data){ 234 | vm.thing = null; 235 | vm.toastr.success(data.message); 236 | },function(data, status) { 237 | if(status!==401){ 238 | vm.toastr.error(data); 239 | } 240 | }); 241 | }; 242 | 243 | return mainAppControllers; 244 | 245 | }); -------------------------------------------------------------------------------- /views/partials/auth/home.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 | 19 |
Things
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 39 | 44 | 45 | 46 | 49 | 52 | 57 | 62 | 63 | 64 | 65 |
NameSize
{{thing.name}}{{thing.size}} 35 | 38 | 40 | 43 | 47 | 48 | 50 | 51 | 53 | 56 | 58 | 61 |
66 | 67 |
68 | 69 |
70 |
71 | 72 | 73 | 74 |
75 |
76 | 77 |
78 | 79 |
People
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 101 | 106 | 107 | 110 | 113 | 118 | 123 | 124 | 125 | 126 | 127 | 128 |
NameAge
{{person.name}}{{person.age}} 97 | 100 | 102 | 105 | 108 | 109 | 111 | 112 | 114 | 117 | 119 | 122 |
129 | 130 |
131 | 132 |
133 |
134 | 135 |
136 | 137 |
138 | 139 |
140 | 141 |
142 | 143 |
144 |
145 |

Add Person

146 |
147 |
148 | Here you can add Person! 149 |

150 | 151 |
152 |
153 | 154 | Add! 155 | 156 |
157 |
158 | 159 |
160 |
161 | 162 |
163 | 164 |
165 | 166 |
167 |
168 |

Create Thing

169 |
170 |
171 | Here you can create thing! 172 |

173 | 174 |
175 | 180 |
181 |
182 |
183 |
184 | 185 |
186 | 187 |
188 |
189 |

Join Set

190 |
191 |
192 | Here you can join existing set! 193 |

194 | 195 |
196 | 201 |
202 |
203 |
204 |
205 | 206 |
207 | 208 | 209 | 210 |
211 | 212 |
213 | 214 |
215 |
216 | 217 |
218 |
Angular seed app: v
219 | 220 |
221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | --------------------------------------------------------------------------------