Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 706a93a

Browse files
chrisakersIgorMinar
authored andcommitted
fix($cookies): update $cookies to prevent duplicate cookie writes and play nice with external code
Update the ngCookies service to prevent repetitive writes via $browser.cookies() Also it is possible for $cookies to get confused about cookies modified outside of $cookies and see those changes as user changes via the $cookies service which would then be set again. This unnecessary setting of cookies can duplicate or overwrite depending on the original cookie's domain. This update prevents that scenario. Closes #11490 Closes #11515
1 parent c4ae7d2 commit 706a93a

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

src/ngCookies/cookies.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ angular.module('ngCookies', ['ng']).
8686
for (name in lastCookies) {
8787
if (isUndefined(cookies[name])) {
8888
$browser.cookies(name, undefined);
89+
delete lastCookies[name];
8990
}
9091
}
9192

@@ -98,24 +99,24 @@ angular.module('ngCookies', ['ng']).
9899
}
99100
if (value !== lastCookies[name]) {
100101
$browser.cookies(name, value);
102+
lastCookies[name] = value;
101103
updated = true;
102104
}
103105
}
104106

105107
//verify what was actually stored
106108
if (updated) {
107-
updated = false;
108109
browserCookies = $browser.cookies();
109110

110111
for (name in cookies) {
111112
if (cookies[name] !== browserCookies[name]) {
112113
//delete or reset all cookies that the browser dropped from $cookies
113114
if (isUndefined(browserCookies[name])) {
114115
delete cookies[name];
116+
delete lastCookies[name];
115117
} else {
116-
cookies[name] = browserCookies[name];
118+
cookies[name] = lastCookies[name] = browserCookies[name];
117119
}
118-
updated = true;
119120
}
120121
}
121122
}

test/ngCookies/cookiesSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,51 @@ describe('$cookies', function() {
4545
}));
4646

4747

48+
it('should only set the browser cookie once per cookie change',
49+
inject(function($cookies, $browser, $rootScope) {
50+
function hasArgs(call) {
51+
return call.args.length > 0;
52+
}
53+
54+
spyOn($browser, 'cookies').andCallThrough();
55+
56+
$cookies.oatmealCookie = 'nom nom';
57+
$rootScope.$digest();
58+
59+
expect($browser.cookies.calls.filter(hasArgs).length).toEqual(1);
60+
}));
61+
62+
63+
it('should only delete the browser cookie once per cookie delete',
64+
inject(function($cookies, $browser, $rootScope) {
65+
function hasArgs(call) {
66+
return call.args.length > 0;
67+
}
68+
69+
spyOn($browser, 'cookies').andCallThrough();
70+
71+
delete $cookies.preexisting;
72+
$rootScope.$digest();
73+
74+
expect($browser.cookies.calls.filter(hasArgs).length).toEqual(1);
75+
}));
76+
77+
78+
it('should allow cookies to be set outside the service without overwriting/duplicating',
79+
inject(function($cookies, $browser, $rootScope) {
80+
var browserCookieSpy = spyOn($browser, 'cookies').andCallThrough();
81+
82+
function hasArgs(call) {
83+
return call.args.length > 0;
84+
}
85+
86+
$browser.cookieHash['preexisting'] = 'vanilla';
87+
$cookies.oatmealCookie = 'nom nom';
88+
$rootScope.$digest();
89+
expect(browserCookieSpy.calls.filter(hasArgs).length).toEqual(1);
90+
}));
91+
92+
4893
it('should convert non-string values to string',
4994
inject(function($cookies, $browser, $rootScope) {
5095
$cookies.nonString = [1, 2, 3];

0 commit comments

Comments
 (0)