Permalink
Browse files

feat($cookiesProvider): provide path, domain, expires and secure options

This change provides properties on `$cookiesProvider` so that you can set the application
level default options for cookies that are set using the `$cookies` service
  • Loading branch information...
1 parent 92c366d commit 53c663699126815eabc2a3bc1e3bafc8b3874268 @shahata shahata committed with petebacondarwin Mar 2, 2015
Showing with 125 additions and 40 deletions.
  1. +69 −40 src/ngCookies/cookies.js
  2. +56 −0 test/ngCookies/cookiesSpec.js
@@ -19,31 +19,66 @@
angular.module('ngCookies', ['ng']).
/**
- * @ngdoc service
- * @name $cookies
- *
+ * @ngdoc provider
+ * @name $cookiesProvider
* @description
- * Provides read/write access to browser's cookies.
- *
- * BREAKING CHANGE: `$cookies` no longer exposes properties that represent the
- * current browser cookie values. Now you must use the get/put/remove/etc. methods
- * as described below.
- *
- * Requires the {@link ngCookies `ngCookies`} module to be installed.
- *
- * @example
- *
- * ```js
- * angular.module('cookiesExample', ['ngCookies'])
- * .controller('ExampleController', ['$cookies', function($cookies) {
- * // Retrieving a cookie
- * var favoriteCookie = $cookies.get('myFavorite');
- * // Setting a cookie
- * $cookies.put('myFavorite', 'oatmeal');
- * }]);
- * ```
- */
- factory('$cookies', ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
+ * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.
+ * */
+ provider('$cookies', [function $CookiesProvider() {
+ /**
+ * @ngdoc property
+ * @name $cookiesProvider#defaults
+ * @description
+ *
+ * Object containing default options to pass when setting cookies.
+ *
+ * The object may have following properties:
+ *
+ * - **path** - `{string}` - The cookie will be available only for this path and its
+ * sub-paths. By default, this would be the URL that appears in your base tag.
+ * - **domain** - `{string}` - The cookie will be available only for this domain and
+ * its sub-domains. For obvious security reasons the user agent will not accept the
+ * cookie if the current domain is not a sub domain or equals to the requested domain.
+ * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
+ * or a Date object indicating the exact date/time this cookie will expire.
+ * - **secure** - `{boolean}` - The cookie will be available only in secured connection.
+ *
+ * Note: by default the address that appears in your <base> tag will be used as path.
+ * This is import so that cookies will be visible for all routes in case html5mode is enabled
+ *
+ **/
+ var defaults = this.defaults = {};
+
+ function calcOptions(options) {
+ return options ? angular.extend({}, defaults, options) : defaults;
+ }
+
+ /**
+ * @ngdoc service
+ * @name $cookies
+ *
+ * @description
+ * Provides read/write access to browser's cookies.
+ *
+ * BREAKING CHANGE: `$cookies` no longer exposes properties that represent the
+ * current browser cookie values. Now you must use the get/put/remove/etc. methods
+ * as described below.
+ *
+ * Requires the {@link ngCookies `ngCookies`} module to be installed.
+ *
+ * @example
+ *
+ * ```js
+ * angular.module('cookiesExample', ['ngCookies'])
+ * .controller('ExampleController', ['$cookies', function($cookies) {
+ * // Retrieving a cookie
+ * var favoriteCookie = $cookies.get('myFavorite');
+ * // Setting a cookie
+ * $cookies.put('myFavorite', 'oatmeal');
+ * }]);
+ * ```
+ */
+ this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
return {
/**
* @ngdoc method
@@ -70,7 +105,7 @@ angular.module('ngCookies', ['ng']).
* @returns {Object} Deserialized cookie value.
*/
getObject: function(key) {
- var value = $$cookieReader()[key];
+ var value = this.get(key);
return value ? angular.fromJson(value) : value;
},
@@ -96,20 +131,11 @@ angular.module('ngCookies', ['ng']).
*
* @param {string} key Id for the `value`.
* @param {string} value Raw value to be stored.
- * @param {Object=} options Object with options that need to be stored for the cookie.
- * The object may have following properties:
- *
- * - **path** - `{string}` - The cookie will be available only for this path and its
- * sub-paths. By default, this would be the URL that appears in your base tag.
- * - **domain** - `{string}` - The cookie will be available only for this domain and
- * its sub-domains. For obvious security reasons the user agent will not accept the
- * cookie if the current domain is not a sub domain or equals to the requested domain.
- * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
- * or a Date object indicating the exact date/time this cookie will expire.
- * - **secure** - `{boolean}` - The cookie will be available only in secured connection.
+ * @param {Object=} options Options object.
+ * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
*/
put: function(key, value, options) {
- $$cookieWriter(key, value, options);
+ $$cookieWriter(key, value, calcOptions(options));
},
/**
@@ -122,9 +148,10 @@ angular.module('ngCookies', ['ng']).
* @param {string} key Id for the `value`.
* @param {Object} value Value to be stored.
* @param {Object=} options Options object.
+ * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
*/
putObject: function(key, value, options) {
- $$cookieWriter(key, angular.toJson(value), options);
+ this.put(key, angular.toJson(value), options);
},
/**
@@ -136,9 +163,11 @@ angular.module('ngCookies', ['ng']).
*
* @param {string} key Id of the key-value pair to delete.
* @param {Object=} options Options object.
+ * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
*/
remove: function(key, options) {
- $$cookieWriter(key, undefined, options);
+ $$cookieWriter(key, undefined, calcOptions(options));
}
};
- }]);
+ }];
+ }]);
@@ -83,4 +83,60 @@ describe('$cookies', function() {
$cookies.remove('name', {path: '/a/b'});
expect($$cookieWriter).toHaveBeenCalledWith('name', undefined, {path: '/a/b'});
}));
+
+
+ it('should pass default options on put', function() {
+ module(function($cookiesProvider) {
+ $cookiesProvider.defaults.secure = true;
+ });
+ inject(function($cookies, $$cookieWriter) {
+ $cookies.put('name', 'value', {path: '/a/b'});
+ expect($$cookieWriter).toHaveBeenCalledWith('name', 'value', {path: '/a/b', secure: true});
+ });
+ });
+
+
+ it('should pass default options on putObject', function() {
+ module(function($cookiesProvider) {
+ $cookiesProvider.defaults.secure = true;
+ });
+ inject(function($cookies, $$cookieWriter) {
+ $cookies.putObject('name', 'value', {path: '/a/b'});
+ expect($$cookieWriter).toHaveBeenCalledWith('name', '"value"', {path: '/a/b', secure: true});
+ });
+ });
+
+
+ it('should pass default options on remove', function() {
+ module(function($cookiesProvider) {
+ $cookiesProvider.defaults.secure = true;
+ });
+ inject(function($cookies, $$cookieWriter) {
+ $cookies.remove('name', {path: '/a/b'});
+ expect($$cookieWriter).toHaveBeenCalledWith('name', undefined, {path: '/a/b', secure: true});
+ });
+ });
+
+
+ it('should let passed options override default options', function() {
+ module(function($cookiesProvider) {
+ $cookiesProvider.defaults.secure = true;
+ });
+ inject(function($cookies, $$cookieWriter) {
+ $cookies.put('name', 'value', {secure: false});
+ expect($$cookieWriter).toHaveBeenCalledWith('name', 'value', {secure: false});
+ });
+ });
+
+
+ it('should pass default options if no options are passed', function() {
+ module(function($cookiesProvider) {
+ $cookiesProvider.defaults.secure = true;
+ });
+ inject(function($cookies, $$cookieWriter) {
+ $cookies.put('name', 'value');
+ expect($$cookieWriter).toHaveBeenCalledWith('name', 'value', {secure: true});
+ });
+ });
+
});

0 comments on commit 53c6636

Please sign in to comment.