diff --git a/app/index.js b/app/index.js index 6e4724801..0cf791e76 100644 --- a/app/index.js +++ b/app/index.js @@ -240,7 +240,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..ad7088612 100644 --- a/app/templates/_bower.json +++ b/app/templates/_bower.json @@ -9,7 +9,7 @@ "bootstrap-sass-official": "~3.1.1",<% } %> "bootstrap": "~3.1.1",<% } %> "angular-resource": ">=1.2.*", - "angular-cookies": ">=1.2.*", + "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)/account(coffee).coffee b/app/templates/client/app/account(auth)/account(coffee).coffee index 2b7b8b23b..ac78a810e 100644 --- a/app/templates/client/app/account(auth)/account(coffee).coffee +++ b/app/templates/client/app/account(auth)/account(coffee).coffee @@ -7,6 +7,13 @@ angular.module '<%= scriptAppName %>' templateUrl: 'app/account/login/login.html' controller: 'LoginCtrl' + .when '/login/:sessionToken', + template: ' ' + controller: ($routeParams, Auth, $location) -> + if $routeParams.sessionToken + Auth.setSessionToken $routeParams.sessionToken, -> + $location.path "/" + return .when '/signup', templateUrl: 'app/account/signup/signup.html' controller: 'SignupCtrl' @@ -22,6 +29,14 @@ angular.module '<%= scriptAppName %>' templateUrl: 'app/account/login/login.html' controller: 'LoginCtrl' + .state 'loginWithToken', + url: '/login/:sessionToken' + template: ' ' + controller: ($stateParams, Auth, $location) -> + if $stateParams.sessionToken + Auth.setSessionToken $stateParams.sessionToken, -> + $location.path "/" + return .state 'signup', url: '/signup' templateUrl: 'app/account/signup/signup.html' diff --git a/app/templates/client/app/account(auth)/account(js).js b/app/templates/client/app/account(auth)/account(js).js index 0e30543a5..e672365bc 100644 --- a/app/templates/client/app/account(auth)/account(js).js +++ b/app/templates/client/app/account(auth)/account(js).js @@ -7,6 +7,14 @@ angular.module('<%= scriptAppName %>') templateUrl: 'app/account/login/login.html', controller: 'LoginCtrl' }) + .when('/login/:sessionToken', { + template: ' ', + controller: function($routeParams, Auth, $location){ + if ($routeParams.sessionToken) { + Auth.setSessionToken($routeParams.sessionToken, function(){$location.path('/');}); + } + } + }) .when('/signup', { templateUrl: 'app/account/signup/signup.html', controller: 'SignupCtrl' @@ -23,6 +31,15 @@ angular.module('<%= scriptAppName %>') templateUrl: 'app/account/login/login.html', controller: 'LoginCtrl' }) + .state('loginWithToken', { + url: '/login/:sessionToken', + template: ' ', + controller: function($stateParams, Auth, $location){ + if ($stateParams.sessionToken) { + Auth.setSessionToken($stateParams.sessionToken, function(){$location.path('/');}); + } + } + }) .state('signup', { url: '/signup', templateUrl: 'app/account/signup/signup.html', diff --git a/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee b/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee index 7a16032da..851e3d843 100644 --- a/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee +++ b/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee @@ -9,4 +9,4 @@ angular.module '<%= scriptAppName %>' $scope.delete = (user) -> User.remove id: user._id - _.remove $scope.users, user \ No newline at end of file + _.remove $scope.users, user diff --git a/app/templates/client/app/app(coffee).coffee b/app/templates/client/app/app(coffee).coffee index ea9ae3c95..6b498f325 100644 --- a/app/templates/client/app/app(coffee).coffee +++ b/app/templates/client/app/app(coffee).coffee @@ -15,11 +15,11 @@ 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, $location) -> # Add authorization token to headers request: (config) -> config.headers = config.headers or {} - config.headers.Authorization = 'Bearer ' + $cookieStore.get 'token' if $cookieStore.get 'token' + config.headers.Authorization = 'Bearer ' + $localStorage.token if $localStorage.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..a193de778 100644 --- a/app/templates/client/app/app(js).js +++ b/app/templates/client/app/app(js).js @@ -17,13 +17,13 @@ angular.module('<%= scriptAppName %>', [<%= angularModules %>]) $httpProvider.interceptors.push('authInterceptor');<% } %> })<% } %><% if(filters.auth) { %> - .factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) { + .factory('authInterceptor', function ($rootScope, $q, $localStorage, $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'); + if ($localStorage.token) { + config.headers.Authorization = 'Bearer ' + $localStorage.token; } return config; }, @@ -33,7 +33,7 @@ angular.module('<%= scriptAppName %>', [<%= angularModules %>]) if(response.status === 401) { $location.path('/login'); // remove any stale tokens - $cookieStore.remove('token'); + delete $localStorage.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..8f55939a7 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, $q) -> + currentUser = if $localStorage.token then User.get() else {} ### Authenticate user and save token @@ -18,7 +18,7 @@ angular.module '<%= scriptAppName %>' password: user.password .success (data) -> - $cookieStore.put 'token', data.token + $localStorage.token = data.token currentUser = User.get() deferred.resolve data callback?() @@ -37,7 +37,7 @@ angular.module '<%= scriptAppName %>' @param {Function} ### logout: -> - $cookieStore.remove 'token' + delete $localStorage.token currentUser = {} return @@ -52,7 +52,7 @@ angular.module '<%= scriptAppName %>' createUser: (user, callback) -> User.save user, (data) -> - $cookieStore.put 'token', data.token + $localStorage.token = data.token currentUser = User.get() callback? user @@ -133,4 +133,17 @@ angular.module '<%= scriptAppName %>' Get auth token ### getToken: -> - $cookieStore.get 'token' + $localStorage.token + + + ### + Set session token + @param {String} session token + @return {Promise} + ### + + setSessionToken: (sessionToken, callback) -> + cb = callback || angular.noop; + $localStorage.token = sessionToken + currentUser = User.get(cb) + return 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..b01a2bc18 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, $q) { + + var currentUser = $localStorage.token ? User.get() : {}; return { @@ -22,10 +20,11 @@ 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); + $localStorage.token = data.token; currentUser = User.get(); deferred.resolve(data); return cb(); @@ -45,7 +44,7 @@ angular.module('<%= scriptAppName %>') * @param {Function} */ logout: function() { - $cookieStore.remove('token'); + delete $localStorage.token; currentUser = {}; }, @@ -61,7 +60,7 @@ angular.module('<%= scriptAppName %>') return User.save(user, function(data) { - $cookieStore.put('token', data.token); + $localStorage.token = data.token; currentUser = User.get(); return cb(user); }, @@ -140,7 +139,19 @@ angular.module('<%= scriptAppName %>') * Get auth token */ getToken: function() { - return $cookieStore.get('token'); + return $localStorage.token; + }, + + /** + * Set session token + * + * @param {String} session token + * @return {Promise} + */ + setSessionToken: function(sessionToken, callback) { + var cb = callback || angular.noop; + $localStorage.token = sessionToken; + currentUser = User.get(cb); } }; }); diff --git a/app/templates/karma.conf.js b/app/templates/karma.conf.js index 57b3fa6f2..277ddc697 100644 --- a/app/templates/karma.conf.js +++ b/app/templates/karma.conf.js @@ -15,7 +15,7 @@ module.exports = function(config) { 'client/bower_components/angular/angular.js', '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/api/user(auth)/user.controller.js b/app/templates/server/api/user(auth)/user.controller.js index 17e6e0e04..b84ab94b4 100644 --- a/app/templates/server/api/user(auth)/user.controller.js +++ b/app/templates/server/api/user(auth)/user.controller.js @@ -29,7 +29,7 @@ exports.create = function (req, res, next) { newUser.role = 'user'; newUser.save(function(err, user) { if (err) return validationError(res, err); - var token = jwt.sign({_id: user._id }, config.secrets.session, { expiresInMinutes: 60*5 }); + var token = jwt.sign({_id: user._id }, config.secrets.session, { expiresInMinutes: config.tokenDuration.session }); res.json({ token: token }); }); }; diff --git a/app/templates/server/auth(auth)/auth.service.js b/app/templates/server/auth(auth)/auth.service.js index 38ec34302..9a278468e 100644 --- a/app/templates/server/auth(auth)/auth.service.js +++ b/app/templates/server/auth(auth)/auth.service.js @@ -56,21 +56,20 @@ 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, expiresInMinutes) { + return jwt.sign({ _id: id, role : role }, config.secrets.session, { expiresInMinutes: expiresInMinutes }); } /** * Set token cookie directly for oAuth strategies */ -function setTokenCookie(req, res) { +function setToken(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); - res.cookie('token', JSON.stringify(token)); - res.redirect('/'); + var token = signToken(req.user._id, req.user.role, config.tokenDuration.session); + res.redirect('/login/'+token); } exports.isAuthenticated = isAuthenticated; exports.hasRole = hasRole; exports.signToken = signToken; -exports.setTokenCookie = setTokenCookie; \ No newline at end of file +exports.setToken = setToken; \ No newline at end of file diff --git a/app/templates/server/auth(auth)/facebook(facebookAuth)/index.js b/app/templates/server/auth(auth)/facebook(facebookAuth)/index.js index 4a6f87886..8e0405b19 100644 --- a/app/templates/server/auth(auth)/facebook(facebookAuth)/index.js +++ b/app/templates/server/auth(auth)/facebook(facebookAuth)/index.js @@ -16,6 +16,6 @@ router .get('/callback', passport.authenticate('facebook', { failureRedirect: '/signup', session: false - }), auth.setTokenCookie); + }), auth.setToken); module.exports = router; \ No newline at end of file diff --git a/app/templates/server/auth(auth)/google(googleAuth)/index.js b/app/templates/server/auth(auth)/google(googleAuth)/index.js index 9b1ce39fe..42571c92d 100644 --- a/app/templates/server/auth(auth)/google(googleAuth)/index.js +++ b/app/templates/server/auth(auth)/google(googleAuth)/index.js @@ -19,6 +19,6 @@ router .get('/callback', passport.authenticate('google', { failureRedirect: '/signup', session: false - }), auth.setTokenCookie); + }), auth.setToken); module.exports = router; \ No newline at end of file diff --git a/app/templates/server/auth(auth)/twitter(twitterAuth)/index.js b/app/templates/server/auth(auth)/twitter(twitterAuth)/index.js index 8360247b8..756a72781 100644 --- a/app/templates/server/auth(auth)/twitter(twitterAuth)/index.js +++ b/app/templates/server/auth(auth)/twitter(twitterAuth)/index.js @@ -15,6 +15,6 @@ router .get('/callback', passport.authenticate('twitter', { failureRedirect: '/signup', session: false - }), auth.setTokenCookie); + }), auth.setToken); module.exports = router; \ No newline at end of file diff --git a/app/templates/server/config/_local.env.js b/app/templates/server/config/_local.env.js index c24fffd3a..c93a5e9f3 100644 --- a/app/templates/server/config/_local.env.js +++ b/app/templates/server/config/_local.env.js @@ -20,4 +20,4 @@ module.exports = { <% } %> // Control debug level for modules using visionmedia/debug DEBUG: '' -}; +}; \ No newline at end of file diff --git a/app/templates/server/config/environment/index.js b/app/templates/server/config/environment/index.js index 11d85f4de..c471327ad 100644 --- a/app/templates/server/config/environment/index.js +++ b/app/templates/server/config/environment/index.js @@ -29,6 +29,10 @@ var all = { session: '<%= _.slugify(_.humanize(appname)) + '-secret' %>' }, + tokenDuration : { + session: 60 * 24 * 30 + }, + // List of user roles userRoles: ['guest', 'user', 'admin'], @@ -64,4 +68,4 @@ var all = { // ============================================== module.exports = _.merge( all, - require('./' + process.env.NODE_ENV + '.js') || {}); \ No newline at end of file + require('./' + process.env.NODE_ENV + '.js') || {}); diff --git a/test/fixtures/bower.json b/test/fixtures/bower.json index 7d9aae354..47397b326 100644 --- a/test/fixtures/bower.json +++ b/test/fixtures/bower.json @@ -9,7 +9,7 @@ "bootstrap-sass-official": "~3.1.1", "bootstrap": "~3.1.1", "angular-resource": ">=1.2.*", - "angular-cookies": ">=1.2.*", + "ngstorage": "~0.3.0", "angular-sanitize": ">=1.2.*", "angular-route": ">=1.2.*", "angular-bootstrap": "~0.11.0",