-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Setting cookie attributes in $cookieStore #2459
Conversation
$cookieStore service had no way to set cookie attributes (such as expires). The api for $cookieStore.put and $cookieStore.remove now has a third argument- options,which allows setting cookie attributes, or deleting cookies under a specific path. - to change the path and/or expiration date of a cookie, you can pass an options object as the third argument to cookies(name,value). the options object can override Path and Expires when adding a value. You can pass either path, expires,none or both. - the path option is checked to be a string and be partial to window.location otherwise, the default path is used. (warning is logged) - the expires option is checked to be a Date and in the future, otherwise no expiration is set. (warning is logged) - you can now delete a cookie on a specific path by calling cookie(name,undefined,{path:x}) The $cookie service remains unchanged since supporting cookie attributes would mean serious backward comptability issues. Foundations were put in place to make supporting $cookie easier. GENERIC TEST CHANGE: To support checking cookie path, all unit-tests now run on path "/karma/tests" Documentation was updated for both $cookie and $cookieStore with examples. closes angular#1786, angular#1320 BREAKING CHANGE: As part of the change, deleting a cookie now deletes cookies set in multiple paths (and duplicate cookies if exists). Previously only cookies set in the / path were deleted. Since it is not intutive, if this change breaks someones code, it is probably as an accidental side-effect. It is reasonable to assume that most people actually wanted to delete the cookie even if it wasn't set in the same path (since they can see it). So while this is a breaking change, it fixes bad behaviour. If needed, you can delete the cookie in a specific path using $cookieStore.
I also signed the "Contributor License Agreement" electronically, I think (it redirect to nothing :/) . |
PR Checklist (Minor Feature)
|
Internet Explorer 8 & 9 don't like this: http://ci.angularjs.org/job/angular.js-pete/90/ |
By the way, you appear to have modified all functions to have a space between function and (), which makes it look like you have far more changes than there really are. I suspect that you didn't purposefully do this for some idealistic aim, but that perhaps your editor did it for you? |
Can you explain why you have to expose and mock _setCookie in the service rather than simply injecting document and accessing document[0].cookie in the specs? |
Function spaces- I suspect the editor did that, I've hopefully reverted that in the following commit. the problem with accessing document.cookie is that you can't read the Path or Expiration date of a cookie using javascript. So I couldn't have verified that path and expiration was done properly. That's why I need to capture the calls before they reach document.cookie (or mock document.cookie itself, which is a lot of work for little gain). For example, if I set document.cookie = "cookie=numnum;path=/;expiration=111" when I read document.cookie, I'll get "cookie=numnum". In regards to why injecting a mock document isn't easy, it's mostly because the tests are already using document, and I would need to mock all the APIs that are used (or alternatively use something like harmony-proxies, which don't work on all browsers). I've fixed the IE issues that appeared on the tests, however for some bizzare reason, my IE suite get stuck at test 749, and I'm unable at the moment to complete a full suite on IE. since I haven't touched those tests, I'm mostly sure it works (and the fact they didn't appear on the cross-browser hudson also raises my hopes here). |
Can I ask why "PR is squashed into one commit per logical change" and "PR's commit messages are descriptive" are not checked, did I miss something? |
@Illniyar - To answer your question about the tasks: I would like to look at the mocking issue a bit further because I don't like the idea of creating backdoors just for testing here. I'll give it a go on with IE on my machine. |
What messages do you put for commits that fix regressions in previous commits? how do you "squash" two commits? In regards to mocking cookies, what browser support is needed? I can think of a way of doing it, but I need getter/setter support, and I'm not sure what browsers does angular.js need to support (including version numbers for firefox/chrome etc...). |
Thank you pkozlowski-opensource. I'm not really sure how to squash things now though, should a new branch be created with a new PR? I can't see a way to squash commits on the same branch/repository you are currently working on. |
I've commited a fix that will remove the _setCookie backdoor. Hopefully this should work in: IE8+,FF4+,Chrome and Opera12+. |
@Illniyar - don't worry about squashing. I can rebase if and when we merge. |
@Illniyar - I am having some issues with this: http://plnkr.co/edit/6RuykjI6U1AJec0GMwPE?p=preview It doesn't seem to actually store the cookie in the browser. Moreover, my understanding is that you remove a cookie from the browser by setting its expiration value to now. You are not doing this. Any thoughts? |
I'm not sure what is going on there. If I take the exact same code and put it on directly on a server, it works. Something in Plunker is not working properly, probably there is some kind of permission issue that block the cookie from being set,maybe something to do with the iFrame? In regards to removing cookie, we set the date to "expires=Thu, 01 Jan 1970 00:00:00 GMT" in all places where we try to delete the cookie, I'm not sure what your seeing that is different. |
any news here? |
Would love to see this be pulled in! Thanks for the request @Illniyar 👍 |
@Illniyar Have you considered also adding |
It should be relatively easy to add (along with domain specific cookies ) as the additional options argument provides a lot of lieniency. However there were several reasons why I didn't:
|
I guess we need to hear from @petebacondarwin about how much $cookieStore should do. Would be great to have feature parity with other js cookie libs. |
#950 does mentions a couple things like |
I looked over the commit a4ed23c and I like the direction, but it still needs some major refactoring:
What do you think about these two big changes? Would you be up for addressing them? If you sign up for the $browser refactoring and are capable of making the changes in a timely manner, I'll make sure that this change lands in 1.2 (we'd like to feature freeze 1.1.x within a week). |
The $cookies service (as opposed to the $cookieStore service) was appearently desgined to work as a hashmap, I.E. people might use the cookies hashmap directly (see the example I added to the docs to see how it might be used). I didn't consider returning $cookies as a function, I can't think of a reason why it'll break backward compatability, can you? if not, then it should be done. it shouldn't be a problem moving the cookies part out of $browser. I'd be happy to refactor both (assuming $cookies as a function doesn't break compatability). Considering someone might be using the $browser (and $browser.cookies) directly, shouldn't there be a deprecation period? |
02dc2aa
to
fd2d6c0
Compare
cad9560
to
f294244
Compare
e8dc429
to
e83fab9
Compare
4dd5a20
to
998c61c
Compare
+1 for this! |
I'm having the same issue, would like to see this added |
Same here, this is really needed. |
+1 |
+1 as well. |
+1 too.. |
👍 |
@petebacondarwin hey, I'm not sure how to try this out, but what I don't see there is a global config, so I can set up my default params like path , expiry and domain once |
@petebacondarwin now looking at it again, this was indeed supported! |
The new cookies implementation landed, this can be closed |
👏 |
As a response to issues: #1786,#950,#1918,#1320
This PR enables setting a cookie's path and expires attributes using the $cookieStore service.
$cookies was not changed, since it's API is too strict, I could find no way to implement it without causing breaking changes, or using some terrible hacks.
I would suggest adding a new service to the module to support more advanced features (such as Json $watch expression, which should be more useful then binding the $cookies object directly), but this would probably require a bit of research regarding use cases.
Some things to note regarding the implementation:
delete cookie now deletes cookies set with a path other then / (or baseHref)
that is before the fix, if you had a cookie set on path /karma (if it was added by the server for instance),
you would be able to see it, but deleting it will fail silently (and will not delete)
delete cookie now deletes duplicate cookies with the same name (if they have different paths)
which I override in unit tests. Not the most elegent solution, but the only other way to check Expiration is to mock the document object and change how document.cookie works, and that would have taken me too long for very little benefit.
Design decisions:
the options object can override Path and Expires when adding a value, all other options variables are ignored (but are allowed, I.E. no validation is made).
You can pass either path, expires,none or both.
this is to support backward compatability with $cookies.
Notes:
if the value passed to browser.cookies is not a String, it fails silently.
This is my first time contributing here (and on a Major open source project), I hope this can be incorporated.
I'm more than happy to make changes if something is wrong, so please let me know.