How can I run code upon session death with Yesod? - haskell

I would like to run code whenever a Yesod session dies. For example whenever a session dies I would like to print "hello" to the console.
I did not use the scaffolding for my application.

Yesod's default sessions are done with clientsession. This works by storing encrypted data in the cookies from the browser—the server doesn't store any state. For this reason, I don't think there's a way to accomplish what you want.
You could switch to some sort of server-stored session, in which case you could kinda do this based off a session expiring, though you'd never be able to detect something like "the user cleared their cookies" which effectively kills a session.

Related

How to get/set session data in Yesod handler tests?

Is it possible to get session data from within a Yesod Handler test?
For example I'd like to get the current userId.
Later on, I'd also like to test two simultaneous browser sessions interacting with the Yesod app in turns.
getRequestCookies does return the session, but in an encrypted state.

creating session without external libraries

I'm thinking about creating session this way:
create a secure token with cryto.randomBytes then store it in cookie.
extract token from cookie when node receive a new connection, store it inside global variable GLOBAL.SESSION[token] = data
I'm stuck on step 2:
What happend if node is crashed? Do I need to store the SESSION in a file like PHP does?
If I do it my way, in order to call SESSION, I need to globalize the token too. However, it's name will be a little long. If I shorten session name via assigning GLOBAL.SESSION[token] = GLOBAL.SESSION, it will be overwritten when node receive another connection.
Should I follow this way? Or Any further ideas about this?
create a secure token with cryto.randomBytes then store it in cookie
Just once? You risk session fixation attacks.
extract token from cookie when node receive a new connection, store it inside global variable GLOBAL.SESSION[token] = data
It's not great practice to keep things global... but that's up to you and your application structure.
What happend if node is crashed?
When your application stops running, everything you put into memory is freed. You are responsible for managing your data, and if you want it persistent, you have to make it persistent by writing to disk, a database, etc.
Should I follow this way?
No. Don't re-invent the wheel. You will inevitably make a security mistake along the way, and you are just creating more work for yourself.
Yes, you will need to store the session data into a persistent database, which could be anything like a flat file, SQL database, or noSQL db like mongo, couchdb, etc.
If you use node.js and express, there is a really good library called connect-session:
https://github.com/expressjs/session
you can readily use instead of reinventing the wheel.

In Nodejs how to get previous session data if cookie deleted

I want to get the previous session data if the user removes all his cookies manually or in other methods. Because i am storing some data in session and in my global too, and I need to remove that data from my global for every session destroyed.
If a user removes all his cookies, then he is a user without cookies, right? So how would you differentiate between this user and any other user? This is a very difficult problem and I doubt there is a reliable solution for it.
For example you might want to identify a user by IP, but IP might change ( dynamic IP ). You might want to identify user by creating WebSocket ( of FlashSocket ) connection and keep it open, but this will work only when user views your page ( and might be closed manually as well ).
So forget about previous sessions. If you need to clean session data, then create a CRON job or background thread ( or background asynchronous job in case of Node.JS ), which will do that periodically. Or you can just use passive cleaning, i.e. implement mechanism for sessions, that will clean itself when getting near the ( predefined ) memory limit ( this should fire when creating a new session ).
I just set the session to expire automatically in redis, so it will clean itself up over time. Unfortunately, I forget how I did this exactly, I think it's a property on the db.
When someone logs out, I destroy the session:
req.session.destroy(function(){
//session has been destroyed
});

How can I do something right before the session expire(destroy)

Hi I am using expressjs for my web application, and I use the session middleware, my question is that how I can do something right before the session expire?
For example, I store something in the session, and I set the req.session.cookie.maxAge to 60000(1 minute), when the session timeout, I want to save the data in the session to disk, how I can do this? I checked the API and the destroy function only support callback...
Thanks!
Assuming you're using connect-session there's nothing like session expiration event.
Sessions expire either :
on the client (when cookie gets outdated). There's no way to know about it until a request is made so there's a danger that the event will never get triggered.
in the session store, usually using some form of time-to-live. Not all session stores support events, so notification can't be done in general.
You can, however try implement your own check using setTimeout() - when it times out check if the session's expiration date is sufficiently close to now and do whatever you need to do.

Should Domain Entities always be loaded in their entirety?

I have a custom ASP.NET Membership Provider that I am trying to add password history functionality to. User's passwords expire after X days. Then they have to change their password to one that has not been used in their past X changes.
I already had the User entity, which has a password attribute for their current password. This maps to the User table in the db. Since I needed a list of previous passwords I created a UserPassword table to store this information with a FK reference to the UserId.
Since passwords are value objects, and have no meaning outside of the user, they belong inside the User aggregate, with the User as the root. But here in lies my dilemma. When I retrieve a User from the repository do I always have to get all of their previously used passwords? 99% of the time I don't care about their old passwords, so retrieving them each time I need a User entity seems like a dumb thing to do for db performance. I can't use lazy loading because the User entity is disconnected from the context.
I was thinking of creating a PasswordHistory entity but for the reason stated above, passwords aren't really entities.
How would you DDD experts out there handle this situation?
Thanks.
Edit 1: After considering this some more, I realized this is essentially a question about Lazy Loading. More specifically, how do you handle lazy-loading in a disconnected entity?
Edit 2: I am using LINQ to SQL. The entities are completely detached from the context using this from CodePlex.
It is hard to fully answer this question because you do not specify a platform, so I cannot be exactly sure what you even mean by "disconnected". With Hibernate "disconnected" means you have an object in a valid session but the database connection is not currently open. That is trivial, you simply reconnect and lazy load. The more complicated situation is where you have an object which is "detached" i.e no longer associated with an active session at all and in that case you cannot simply reconnect, you have to either get a new object or attach the one you have to an active session.
Either way, even in the more complicated scenarios, there is still not a whole lot to lazy loading strategies because the requirements are so inflexible: You have to be "connected" to load anything, lazy or otherwise. Period. I will assume "disconnected" means the same thing as detached. Your strategy comes down to two basic scenarios: is this a situation where you probably need to just reconnect/attach on the fly to lazy load, or is it a scenario where you want to make a decision to sometimes conditionally load additional objects before you disconnect in the first place?
Sometimes you may in fact need to code for both possibilities.
In your case you also have to be connected not only to lazy load the old passwords but to update the User object in the first place. Also since this is ASP.NET you might be using session per request, in which case your option is now basically down to only one - conditionally lazy load before your disconnect and that is about it.
The most common scenario would be a person logs in and the system determines they are required to change their password, and asks them to do so before proceeding. In that case you might as well just take care of it immediately after login and keep the User connected. But you are probably using session per request, so what you could do is in the first request process the time limit and if it is expired, you are still connected here so go ahead and return a fully loaded User (assuming you are using the historic passwords in some kind of client side script validation). Then on the submit trip you could reattach or just get a new User instance and update that.
Then there is always the possibility you also have to provide them with the option to change their password at any time. They are already logged in. Does not matter much here, you have a User but the request ended long ago and it does not have passwords loaded. Here, I would probably just write a service method where when they invoke a change password function the service gets a second copy of the User object with the full history for update purposes only, then updates the password, and then discards that object without ever even using it for session or authentication purposes. Or if you are using Session per request you have to do the equivalent - get a fully initialized object for client side validation purposes, then when the data is submitted you can either reattach either one you already have or just get yet a third instance to actually do the update.
If the password is needed after beginning an authenticated session, you could still do the same things and either replace the local User or update the local User's in memory password version as well.
If you have too much stuff going on with multiple levels of authentication most likely you are going to have to require them to logoff and do a full log back in after a password change anyway, so the state of the User does not matter much once they request a password change.
In any case if you are using session per request and your objects become fully detached after every request, in the first scenario you can still lazy load while you are on the server on the original request to return data for client side validation. In the second scenario you have to make another trip (there really is no such thing as lazy loading here). In both case though you have to weigh your two update options because you are always disconnected before an update. You can either just get a second instance from the database on the submit trip to update, or you can reattach the one you already have. It depends on what is optimal/easiest - does saving a db round trip for an uncommon event really matter? Does reattaching using your ORM of choice possibly hit the database again anyway? I would probably not bother to reattach and instead just get a new instance for the actual update as I needed it.

Resources