Can't delete cookies in Angular JS - javascript

I'm having lot of troubles deleting a cookie using $cookies
On logout, my code does:
var deferred = $q.defer()
$http.post( REST.logout, {} )
.finally( function() {
// finally callback is triggered both on success and error,
// since I don't really care if the server is dead or whatever
console.log('out!')
console.log( $cookies['persistent'] )
delete $cookies['persistent']
$cookies['persistent'] = undefined
console.log( $cookies['persistent'] )
deferred.resolve()
})
return deferred.promise
And the output is:
out!
"441b5deca5da04cad774a3844b6865dac8a98e91-oi=11"
undefined
However, the cookie don't bother itself to go away...
As stated in this SO question Can't delete cookie with AngularJS's $cookies, I've checked the domain, which in my case are the the same, since my web app runs from domokun.zodiac.lan and the cookie has domain of .zodiac.lan
I can add that it cannot be set again on the server side because I've cut off the communication between the client and the server, in order to test this out.
Any chance that you could see something I'm missing out would be wonderful!
tested against angular 1.2.[2-5]

One more possibility is you may be running into what I was running into. In my case I wanted to delete a cookie that had been created outside my app so it wasn't in the same domain. We intercept customers' logins through a common portal to provide their username/password. This then creates an authentication cookie that can be later read by the app, and the request is then forwarded to the app.
Anyway, the problem was that you have to be specific in defining both the path and domain of the cookie to be removed. Angular was able to read this cookie without specifying a path or domain, I was able to read it with simply:
$cookies.get("MySSOCookie");
But to remove (which I did by just overwriting with undefined when I wanted the user to be re-directed back to the authentication landing screen, such as upon logout or timeout), I had to be precise:
$cookies.put('MySSOCookie', undefined, {domain: '.myCompanyName.com', path: '/'});

Use native javascript , here some functions will help you:
//set cookies that you need
function setCookie(name, value, expires){
document.cookie = name + "=" + escape(value) + "; ";
if(expires){
expires = setExpiration(expires);
document.cookie += "expires=" + expires + "; ";
}
}
//expiration of your cookie
function setExpiration(cookieLife){
var today = new Date();
var expr = new Date(today.getTime() + cookieLife * 24 * 60 * 60 * 1000);
return expr.toGMTString();
}
//get cookie with namecookie...
function getCookie(w){
cName = "";
pCOOKIES = new Array();
pCOOKIES = document.cookie.split('; ');
for(bb = 0; bb < pCOOKIES.length; bb++){
NmeVal = new Array();
NmeVal = pCOOKIES[bb].split('=');
if(NmeVal[0] == w){
cName = unescape(NmeVal[1]);
}
}
return cName;
}
For your problem use:
setCookie(nameyourcookie,'')
I have helped you...

Can you use:
$cookieStore.remove('persistent');
http://docs.angularjs.org/api/ngCookies/service/$cookieStore

A potential problem could be if your cookie is marked as httpOnly. HttpOnly cookies cant be read by any javascript. To see if you can read the cookie, try:
$ document.cookie
in your console. If it returns an empty string despite there being cookies present in the browser, then those cookies might be httpOnly. You could also look for the HTTP check mark in the Resources tab in chrome
To get rid of the httpOnly attribute you could see if the server framework has some option for that. In nodejs/express you can pass a flag like this:
app.use(express.cookieSession({cookie: { httpOnly: false }}));
However, I don't know if that's bad practice, seeing as it seems to be some sort of session cookie we are talking about and should be handled by the server.

Related

Salesforce - Enhanced domain third party cookie issue

Anybody facing issue with the new Enhanced domain implementation, I am not able to get the handle to the cookies.
Any help will be much appreciated.
Below is my scenario/steps
salesforce sets the cookie value using an LWC component.
Re-directs the page to OKTA for authentication.
OKTA after authentication re-directs to a visual force page where the JavaScript tried to read the cookie already set in the step 1.
The value reading the while reading the cookie is 'undefined'
It's all working well without Enhanced domain implementation enabled, As Jan 10 2023 is the cutoff date of mandatory implementation of Enhanced Domain on Sandboxes, we are trying to resolve this issue before the cut-off date.
function getCookie(name) {
let cookieString = "; " + document.cookie;
let cookies = cookieString.split("; ");
let currentCookieVal;
cookies.forEach(cookie => {
let currentCookieArr = cookie.split('=__');
if(currentCookieArr.length && currentCookieArr.length === 2) {
if(currentCookieArr[0].includes(name)) {
currentCookieVal = currentCookieArr;
}
}
});
return currentCookieVal;
}
Thanks,
James

How do I delete all cookies immediately after the browser is closed ( Using HTML and JavaScript )

What my site is and it's bare bones
A basic site made of HTML, CSS and Vanilla JavaScript. I am integrating front-end password protection to the site using JavaScript to check the credentials and assign a cookie which marks them as logged-in. It's just a side-project and security of the content isn't very necessary. The target audience also doesn't have the knowledge of adding cookies from the browser or manipulating the system in any way.
Once the user has signed in, they get redirected to the homepage, where the cookie is checked for. If the log-in cookie is present, they page loads, and if it's not present, the user gets redirected to the log-in page with a note asking to sign in. So far so good.
What's going wrong?
Like most web devs, I started testing the site before giving it a green signal, and turns out Chrome does not clear cookies after I close the browser. This is a spoilsport. Then, I tried using the onunload function on all the pages to delete the cookies, but the cookies are getting deleted even before the user reaches the homepage, and as a result, are directed to the homepage. I don't want to use Session Storage as opening the site in another tab does not take the Session Storage to the other tab.
Is there any way I could achieve deleting cookies when the browser is closed?
Since you're doing all this programming on the client-side, not the server-side, a cookie may not be the best approach - cookies are for transferring persistent information between the client and server. Local Storage may be a more appropriate choice, for controllable semi-persistent data stored on the client. Local Storage persists over different tabs on the same site.
A possible approach would be to have the saved data expire a certain amount of time after any page on your site has last been opened. For example, you could have, on every page, a script that runs every minute or five and sets the expiry time to an hour or 10 minutes in the future, or something like that - depends how much fine control you want over when logout occurs after inactivity. The code would look something like this:
// on pageload:
const advanceExpiry = () => {
localStorage.loginExpiry = Date.now() + 1000 * 60 * 10;
};
const loggedIn = localStorage.loginExpiry && localStorage.loginExpiry > Date.now();
if (loggedIn) {
advanceExpiry();
// every few minutes, push login expiry 10 minutes in the future:
setInterval(advanceExpiry, 1000 * 60 * 5);
} else {
// user has not logged in, or login has expired
localStorage.loginExpiry = 0;
// redirect to login page
}
and, on the login page, do localStorage.loginExpiry = Date.now() + 1000 * 60 * 10; followed by a redirect.
Just to point out, validation on the front-end is not remotely secure - but you already know about that and don't think it matters, which is fine.
There isn't a silver bullet readily available for your problem. However, using a Service Worker in conjunction with the Task Scheduling API and some JavaScript, you will reach close.
More info - Task Scheduling
Delete all cookies after an hour
function deleteAllCookies() {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
}
setTimeout for 1hour
function myFunction() {
myVar = setTimeout(deleteAllCookies, 3600000);
}
Call myFunction when user login's or when he or she starts the application.

Integrate Salesforce registration page with VanillaJS oidc-client-js, getting the error - No matching state found in storage

Integrate Salesforce registration page with VanillaJS, getting the error - No matching state found in storage
We are redirecting the user to Salesforce registration page when Create Account button is created.
Once the User registers in Salesforce, the user is redirected to our site but we are getting this error. ('No matching state found in storage').
We tried the below solution but still getting the same error.
As I stated in my answer, the oidc client maintains state information
in the local storage so that it can verify that it got the response
back from the intended server. You can mimic this by generating a
secure random string and saving it in localStorage. Do this before
sending a request to your auth server to register a new user.
Reference- Integrate third party login in from my registration page with IdentityServer4 and Angular 6 - 'No matching state found in storage'
Is there a function related to creating registration? How to fix this issue?
Thanks.
Appreciate your help.
After spending days on this issue. Finally found the workaround as registration is not a feature of OIDC.
To overcome this issue, need to follow the Sign In process same as for Sign Up process, created the startSignupMainWindow method same as startSigninMainWindow and passing the signUpFlag:true as shown below in code.
/* This function is written to mimic the oidc library sign in process flow */
function startSignupMainWindow() {
var someState = {
message: window.location.href,
signUpFlag: true
};
mgr.signinRedirect({
state: someState,
useReplaceToNavigate: true
}).then(function() {
log("signinRedirect done");
}).catch(function(err) {
log(err);
});
}
Reading the signUpFlag:true in UserManager.js and swapping the Salesforce Sign In page Url with Sign Up page url and calling the Register function in Code.
UserManager.js(oidc - client - dev - js / src / UserManager.js)
//UserManager Customised Code :
return this.createSigninRequest(args).then(signinRequest => {
Log.debug("UserManager._signinStart: got signin request");
navigatorParams.url = signinRequest.url;
navigatorParams.id = signinRequest.state.id;
if (signinRequest.state._data.signUpFlag) {
register(signinRequest.state._id, signinRequest.state._code_challenge);
} else {
return handle.navigate(navigatorParams);
}
})
The below code is Register function written in code.
/* This function is written to send the code_challenge to salesforce server so that
salesforce server holds the code challenge and used to verify the further requests(token-request)
against the code_challenge it received initially.*/
//Customised register function written outside the library (Inside our App):
function register(_id, code_challenge) {
var date = new Date();
var baseUrl = "SALESFORCE_URL/login/SelfRegister?expid=id";
var expId = "id";
var userPage = encodeURIComponent(window.location.href);
var appDetails = "response_type=code&" +
"client_id=CLIENT_ID" +
"client_secret=CLIENT_SECRET&" +
"redirect_uri=CALLBACK_URL&" +
"state=" + _id + "&code_challenge=" + code_challenge + "&code_challenge_method=S256&response_mode=query";
var encodedapp = encodeURIComponent(appDetails);
var startUrl = "/services/oauth2/authorize/expid?" + encodedapp;
var signUpUrl = baseUrl + "&startURL=" + startUrl;
window.open(signUpUrl, "_self");
};

How to avoid duplicate cookies

In my application I set a cookie using jQuery Cookie Plugin v1.4.1 (https://github.com/carhartl/jquery-cookie) like this:
$.removeCookie("Test_Cookie");
$.cookie("Test_Cookie", "xxx");
I want this cookie to only exist once but under some circumstances the cookie exists twice.
How is that possible and what is the best practice to make sure a certain cookie exists only once?
You can use the String.prototype.split() to convert document.cookie to an array of key value strings (key=value), then you can iterate over these, split them, and if the key is the value, break. Please see below for an example:
function checkCookieExists( cookieName ){
var cookies = document.cookie.split(';'); //returns lots of these: key=value
var toCheckCookie = cookieName; //checks if this cookie exists
cookies.forEach(function( cookie ){ //foreach cookie
var key = cookie.split('=')[0]; //the key cookie
if (key.toLowerCase() === toCheckCookie) //if the current key is the toCheckCookie
{
return true;
}
});
return true;
}
One way to get duplicate cookies is to have a page at company.com and another page at dev.company.com. Then requests to dev.company.com will get cookies for domains .company.com and .dev.company.com. The HTTP responses from dev.company.com can never change the cookies the browser is storing for company.com. This means you cannot "clear" all the duplicate cookies with HTTP response from dev.
This can be frustrating because often the library to handle cookies will only return a single cookie for a key. A valid HTTP cookie header is "Cookie: zyx=data1; zyx=data2" Then your library will return only one of these, likely the first one.
A common solution for this is to use a different cookie key for different domains: "Cookie: dev.company.com-xyz=data1; company.com-xyz=data2"
Another solution is to get the HTTP Cookie header, parse it while handling multiple cookies and use the first one that is valid. Like with a valid auth or a valid JWT.

Cookie not being deleted after session closed

I'm using cookies that should be deleted after user closes the page, but they're not. This is how I set cookies with JS
document.cookie="status=false";
I can see the cookie in console and after I close browser and open it again and go to my webpage there's still cookie status=false any idea why?
I solved it with this "trick", I don't know why I can't get cookies to work
window.onbeforeunload = function() {
document.cookie="status=false";
};
document.cookie = ... sets individual cookie values, it does not set "the entire cookie" to the string you passed, so setting "status=false" simply binds or updates the "status" value, irrespective of whatever else is in the cookie:
document.cookie = "cow=bell";
document.cookie = "cat=lol";
// cookie is now "cow=bell&cat=lol", not just "cat=lol"
If you want to delete the entire cookie, set its expiration time to "in the past" and the browser will do the cleanup for you.
(As pointed out in a comment, if you never set an expiration timestamp for your cookie, it'l expire when the page session ends, e.g. you close the tab/browser)
I was actually doing this today. A great reference is the Mozilla cookie documents if you create a js with their var docCookies code then using the functions provided like docCookies.setItem() docCookies.setItem() docCookies.getItem() or docCookies.removeItem() work incredible well.

Categories