diff --git a/app/index.js b/app/index.js index c37abac8c..e93dd5726 100644 --- a/app/index.js +++ b/app/index.js @@ -231,6 +231,7 @@ var AngularFullstackGenerator = yeoman.generators.Base.extend({ var angModules = [ "'ngCookies'", + "'ngStorage'", "'ngResource'", "'ngSanitize'" ]; diff --git a/app/templates/_bower.json b/app/templates/_bower.json index 1681050a2..8c673e134 100644 --- a/app/templates/_bower.json +++ b/app/templates/_bower.json @@ -9,7 +9,8 @@ "bootstrap-sass-official": "~3.1.1",<% } %> "bootstrap": "~3.1.1",<% } %> "angular-resource": ">=1.2.*", - "angular-cookies": ">=1.2.*", + "angular-cookies": "~1.2.21", + "ngstorage": "~0.3.0", "angular-sanitize": ">=1.2.*",<% if(filters.ngroute) { %> "angular-route": ">=1.2.*",<% } %><% if(filters.uibootstrap) { %> "angular-bootstrap": "~0.11.0",<% } %> diff --git a/app/templates/client/app/account(auth)/login/login(html).html b/app/templates/client/app/account(auth)/login/login(html).html index 483300478..e818a99ed 100644 --- a/app/templates/client/app/account(auth)/login/login(html).html +++ b/app/templates/client/app/account(auth)/login/login(html).html @@ -22,6 +22,10 @@

Login

+
+ Remember me +
+

Please enter your email and password. diff --git a/app/templates/client/app/account(auth)/login/login(jade).jade b/app/templates/client/app/account(auth)/login/login(jade).jade index 4b13c0b13..396c35647 100644 --- a/app/templates/client/app/account(auth)/login/login(jade).jade +++ b/app/templates/client/app/account(auth)/login/login(jade).jade @@ -24,6 +24,9 @@ div(ng-include='"components/navbar/navbar.html"') .form-group label Password input.form-control(type='password', name='password', ng-model='user.password') + .checkbox + input(type='checkbox' value='remember-me' ng-model='user.rememberme') + | Remember me .form-group.has-error p.help-block(ng-show='form.email.$error.required && form.password.$error.required && submitted') diff --git a/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee b/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee index 3f90c25d7..cc87cff3e 100644 --- a/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee +++ b/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee @@ -12,6 +12,7 @@ angular.module '<%= scriptAppName %>' Auth.login email: $scope.user.email password: $scope.user.password + rememberme : $scope.user.rememberme .then -> $location.path '/' diff --git a/app/templates/client/app/account(auth)/login/login.controller(js).js b/app/templates/client/app/account(auth)/login/login.controller(js).js index 7b13da384..82dcddb20 100644 --- a/app/templates/client/app/account(auth)/login/login.controller(js).js +++ b/app/templates/client/app/account(auth)/login/login.controller(js).js @@ -11,7 +11,8 @@ angular.module('<%= scriptAppName %>') if(form.$valid) { Auth.login({ email: $scope.user.email, - password: $scope.user.password + password: $scope.user.password, + rememberme : $scope.user.rememberme }) .then( function() { // Logged in, redirect to home diff --git a/app/templates/client/app/app(coffee).coffee b/app/templates/client/app/app(coffee).coffee index ea9ae3c95..cb2aa16ac 100644 --- a/app/templates/client/app/app(coffee).coffee +++ b/app/templates/client/app/app(coffee).coffee @@ -15,11 +15,12 @@ angular.module '<%= scriptAppName %>', [<%= angularModules %>] $locationProvider.html5Mode true<% if(filters.auth) { %> $httpProvider.interceptors.push 'authInterceptor'<% } %> <% } %><% if(filters.auth) { %> -.factory 'authInterceptor', ($rootScope, $q, $cookieStore, $location) -> +.factory 'authInterceptor', ($rootScope, $q, $localStorage, $cookies, $location) -> # Add authorization token to headers request: (config) -> config.headers = config.headers or {} - config.headers.Authorization = 'Bearer ' + $cookieStore.get 'token' if $cookieStore.get 'token' + token = $localStorage.token||$cookies.token + config.headers.Authorization = 'Bearer ' + token if token config # Intercept 401s and redirect you to login diff --git a/app/templates/client/app/app(js).js b/app/templates/client/app/app(js).js index eef485d7c..043b1ffac 100644 --- a/app/templates/client/app/app(js).js +++ b/app/templates/client/app/app(js).js @@ -17,13 +17,14 @@ angular.module('<%= scriptAppName %>', [<%= angularModules %>]) $httpProvider.interceptors.push('authInterceptor');<% } %> })<% } %><% if(filters.auth) { %> - .factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) { + .factory('authInterceptor', function ($rootScope, $q, $localStorage, $cookies, $location) { return { // Add authorization token to headers request: function (config) { config.headers = config.headers || {}; - if ($cookieStore.get('token')) { - config.headers.Authorization = 'Bearer ' + $cookieStore.get('token'); + var token = $localStorage.token||$cookies.token; + if (token) { + config.headers.Authorization = 'Bearer ' + token; } return config; }, @@ -33,7 +34,8 @@ angular.module('<%= scriptAppName %>', [<%= angularModules %>]) if(response.status === 401) { $location.path('/login'); // remove any stale tokens - $cookieStore.remove('token'); + delete $localStorage.token; + delete $cookies.token; return $q.reject(response); } else { diff --git a/app/templates/client/components/auth(auth)/auth.service(coffee).coffee b/app/templates/client/components/auth(auth)/auth.service(coffee).coffee index ac503ed0b..08d59e433 100644 --- a/app/templates/client/components/auth(auth)/auth.service(coffee).coffee +++ b/app/templates/client/components/auth(auth)/auth.service(coffee).coffee @@ -1,8 +1,8 @@ 'use strict' angular.module '<%= scriptAppName %>' -.factory 'Auth', ($location, $rootScope, $http, User, $cookieStore, $q) -> - currentUser = if $cookieStore.get 'token' then User.get() else {} +.factory 'Auth', ($location, $rootScope, $http, User, $localStorage, $cookies, $q) -> + currentUser = if $localStorage.token||$cookies.token then User.get() else {} ### Authenticate user and save token @@ -16,9 +16,13 @@ angular.module '<%= scriptAppName %>' $http.post '/auth/local', email: user.email password: user.password + rememberme : user.rememberme .success (data) -> - $cookieStore.put 'token', data.token + if user.rememberme + $localStorage.token = data.token + else + $cookies.token = data.token currentUser = User.get() deferred.resolve data callback?() @@ -37,7 +41,8 @@ angular.module '<%= scriptAppName %>' @param {Function} ### logout: -> - $cookieStore.remove 'token' + delete $localStorage.token + delete $cookies.token currentUser = {} return @@ -52,7 +57,7 @@ angular.module '<%= scriptAppName %>' createUser: (user, callback) -> User.save user, (data) -> - $cookieStore.put 'token', data.token + $cookies.token = data.token currentUser = User.get() callback? user @@ -133,4 +138,4 @@ angular.module '<%= scriptAppName %>' Get auth token ### getToken: -> - $cookieStore.get 'token' + $localStorage.token||$cookies.token diff --git a/app/templates/client/components/auth(auth)/auth.service(js).js b/app/templates/client/components/auth(auth)/auth.service(js).js index 9afb12da9..2a309c9b2 100644 --- a/app/templates/client/components/auth(auth)/auth.service(js).js +++ b/app/templates/client/components/auth(auth)/auth.service(js).js @@ -1,11 +1,9 @@ 'use strict'; angular.module('<%= scriptAppName %>') - .factory('Auth', function Auth($location, $rootScope, $http, User, $cookieStore, $q) { - var currentUser = {}; - if($cookieStore.get('token')) { - currentUser = User.get(); - } + .factory('Auth', function Auth($location, $rootScope, $http, User, $localStorage, $cookies, $q) { + + var currentUser = ($localStorage.token||$cookies.token) ? User.get() : {}; return { @@ -22,10 +20,15 @@ angular.module('<%= scriptAppName %>') $http.post('/auth/local', { email: user.email, - password: user.password + password: user.password, + rememberme : user.rememberme }). success(function(data) { - $cookieStore.put('token', data.token); + if (user.rememberme) { + $localStorage.token = data.token; + } else { + $cookies.token = data.token; + } currentUser = User.get(); deferred.resolve(data); return cb(); @@ -45,7 +48,8 @@ angular.module('<%= scriptAppName %>') * @param {Function} */ logout: function() { - $cookieStore.remove('token'); + delete $localStorage.token; + delete $cookies.token; currentUser = {}; }, @@ -61,7 +65,7 @@ angular.module('<%= scriptAppName %>') return User.save(user, function(data) { - $cookieStore.put('token', data.token); + $cookies.token = data.token; currentUser = User.get(); return cb(user); }, @@ -140,7 +144,7 @@ angular.module('<%= scriptAppName %>') * Get auth token */ getToken: function() { - return $cookieStore.get('token'); + return $localStorage.token||$cookies.token; } }; }); diff --git a/app/templates/karma.conf.js b/app/templates/karma.conf.js index 57b3fa6f2..6832b065a 100644 --- a/app/templates/karma.conf.js +++ b/app/templates/karma.conf.js @@ -16,6 +16,7 @@ module.exports = function(config) { 'client/bower_components/angular-mocks/angular-mocks.js', 'client/bower_components/angular-resource/angular-resource.js', 'client/bower_components/angular-cookies/angular-cookies.js', + 'client/bower_components/ngstorage/ngStorage.js', 'client/bower_components/angular-sanitize/angular-sanitize.js', 'client/bower_components/angular-route/angular-route.js',<% if(filters.uibootstrap) { %> 'client/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',<% } %> diff --git a/app/templates/server/auth(auth)/auth.service.js b/app/templates/server/auth(auth)/auth.service.js index 38ec34302..784218bc0 100644 --- a/app/templates/server/auth(auth)/auth.service.js +++ b/app/templates/server/auth(auth)/auth.service.js @@ -56,8 +56,8 @@ function hasRole(roleRequired) { /** * Returns a jwt token signed by the app secret */ -function signToken(id) { - return jwt.sign({ _id: id }, config.secrets.session, { expiresInMinutes: 60*5 }); +function signToken(id, role, expire) { + return jwt.sign({ _id: id, role : role }, config.secrets.session, { expiresInMinutes: expire ? 60*24*7 : 60*5 }); } /** @@ -65,7 +65,7 @@ function signToken(id) { */ function setTokenCookie(req, res) { if (!req.user) return res.json(404, { message: 'Something went wrong, please try again.'}); - var token = signToken(req.user._id, req.user.role); + var token = signToken(req.user._id, req.user.role, req.body.rememberme); res.cookie('token', JSON.stringify(token)); res.redirect('/'); } diff --git a/test/fixtures/bower.json b/test/fixtures/bower.json index dea41015a..1daa1ca21 100644 --- a/test/fixtures/bower.json +++ b/test/fixtures/bower.json @@ -9,7 +9,8 @@ "bootstrap-stylus": "latest", "bootstrap": "~3.1.1", "angular-resource": ">=1.2.*", - "angular-cookies": ">=1.2.*", + "angular-cookies": "~1.2.21", + "ngstorage": "~0.3.0", "angular-sanitize": ">=1.2.*", "angular-route": ">=1.2.*", "angular-bootstrap": "~0.11.0",