Îõ³h$EBàð      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnoNone  #$23?É×Ù<|; serversession(Which session IDs should be invalidated.ïNote that this is not the same concept of invalidation as used on J2EE. In this context, invalidation means creating a fresh session ID for this user's session and disabling the old ID. Its purpose is to avoid session fixation attacks. serversessionóInvalidate the current session ID. The current session ID is automatically invalidated on login and logout (cf. >). serversession¡Invalidate all session IDs beloging to the currently logged in user. Only the current session ID will be renewed (the only one for which a cookie can be set).ŒThis is useful, for example, if the user asks to change their password. It's also useful to provide a button to clear all other sessions.>If the user is not logged in, this option behaves exactly as  (i.e., it does not3 invalidate the sessions of all logged out users). Note that, for the purposes of ø, we consider "logged user" the one that is logged in at the *end* of the handler processing. For example, if the user was logged in but the current handler logged him out, the session IDs of the user who was logged in will not be invalidated. serversessionÒDo not force invalidate. Invalidate only if automatically. This is the default. serversession7Opaque token containing the necessary information for L to save the session. serversessionÏThe server-side session backend needs to maintain some state in order to work:&A nonce generator for the session IDs.#A reference to the storage backend.7The name of cookie where the session ID will be saved (=).!Authentication session variable (>).Idle and absolute timeouts (? and @).Timeout resolution (A).)Whether cookies should be persistent (B), HTTP-only (setHTTPOnlyCookies) and/or secure (D). Create a new  using <. serversession4Common exceptions that may be thrown by any storage. serversessionException thrown by 1 whenever a session with same ID already exists. serversessionException thrown by Ê whenever trying to replace a session that is not present on the storage. serversessionA storage backend sto! for server-side sessions. The sess session data type and/or its &Ë version may be constrained depending on the storage backend capabilities. serversession+The session data type used by this storage. serversessionÝMonad where transactions happen for this backend. We do not require transactions to be ACID. serversession"Run a transaction on the IO monad. serversession4Get the session for the given session ID. Returns Nothing if the session is not found. serversessionÝDelete the session with given session ID. Does not do anything if the session is not found. serversessionïDelete all sessions of the given auth ID. Does not do anything if there are no sessions of the given auth ID. serversessionInsert a new session. Throws ý if there already exists a session with the same session ID (we only call this method after generating a fresh session ID). serversession,Replace the contents of a session. Throws þ if there is no session with the given session ID (we only call this method when updating a session that is known to exist).ÐIt is possible to have concurrent requests using the same session ID such that: ¼request 1: loadSession request 2: loadSession request 2: forceInvalidate request 2: saveSession request 1: saveSession The request 2's call to L will have called Î as invalidation was forced. However, request 1 has no idea and will try to replaceSession). The following behaviors are possible: Make replaceSessionŸ insert the session again. However, this will undo the invalidation of request 2. As invalidations are done for security reasons, this is a bad idea.Make replaceSession¿ silently discard the session. The reasoning is that, as the session was going to be invalidated if request 2 came after request 1, we can discard its contents. However, we can't be sure that request 2 would have had the same effect if it had seen the session changes made by request 1 (and vice versa).Make replaceSession¯ throw an error. This error is going to be unrecoverable since usually the session processing is done at the end of the request processing by the web framework, thus leading to a 500 Internal Server Error. However, this signals to the caller that something went wrong, which is correct.úMost of the time this discussion does not matter. Invalidations usually occur at times where only one request is flying.  serversessionA session data type sess( with its special variables taken apart.% serversession6Class for data types to be used as session data (cf. 3, ).The Show constrain is needed for .& serversessionÏThe type of the session data after being decomposed. This may be the same as sess.' serversessionEmpty session data.( serversessionDecompose session data into:'The auth ID of the logged in user (cf. >, ").9If the session is being forced to be invalidated (cf. O, )."The rest of the session data (cf. &).) serversession3Recompose a decomposed session again into a proper sess.* serversessionReturns True8 when both session datas are to be considered the same.-This is used to optimize storage calls (cf. A). Always returning FalseÊ will disable the optimization but won't have any other adverse effects.For data types implementing p), this is usually a good implementation: isSameDecomposed _ = (==) + serversessionReturns True5 if the decomposed session data is to be considered empty.ØThis is used to avoid storing empty session data if at all possible. Always returning FalseÉ will disable the optimization but won't have any other adverse effects., serversessionA newtype for a common session map.9This is a common representation of a session. Although  serversessionµ has generalized session data types, you can use this one if you don't want to worry about it. We strive to support this session data type on all frontends and storage backends./ serversession"Representation of a saved session.#This representation is used by the  serversessionæ family of packages, transferring data between this core package and storage backend packages. The sess0 type variable describes the session data type.1 serversessionSession ID, primary key.2 serversession Value of  % session key, separate from the rest.3 serversessionRest of the session data.4 serversessionWhen this session was created.5 serversession$When this session was last accessed.6 serversession Value of the   session key.7 serversessionÐThe ID of a session. Always 18 bytes base64url-encoded as 24 characters. The sessÖ type variable is a phantom type for the session data type this session ID points to.Implementation notes:Use q for parsing untrusted input.Use ;, for securely generating new session IDs.: serversessionØ(Internal) Check that the given text is a base64url-encoded representation of 18 bytes.; serversession"Securely generate a new SessionId.< serversession Create a new Æ for the server-side session backend using the given storage backend.= serversessionÈSet the name of cookie where the session ID will be saved. Defaults to "JSESSIONID", which is a generic cookie name used by many frameworks thus making it harder to fingerprint this implementation.> serversessionÊSet the name of the session variable that keeps track of the logged user.5This setting is used by session data types that are Map-alike, using a lookup function. However, the %‡ instance of a session data type may choose not to use it. For example, if you implemented a custom data type, you could return the AuthId without needing a lookup.Defaults to "_ID" (used by  yesod-auth).? serversessionãSet the idle timeout for all sessions. This is used both on the client side (by setting the cookie expires fields) and on the server side (the idle timeout is enforced even if the cookie expiration is ignored). Setting to Nothing$ removes the idle timeout entirely.—"[The idle timemout] defines the amount of time a session will remain active in case there is no activity in the session, closing and invalidating the session upon the defined idle period since the last HTTP request received by the web application for a given session ID." ( Ëhttps://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Idle_TimeoutSource)Defaults to 7 days.@ serversessionëSet the absolute timeout for all sessions. This is used both on the client side (by setting the cookie expires fields) and on the server side (the absolute timeout is enforced even if the cookie expiration is ignored). Setting to Nothing( removes the absolute timeout entirely.é"[The absolute timeout] defines the maximum amount of time a session can be active, closing and invalidating the session upon the defined absolute period since the given session was initially created by the web application. After invalidating the session, the user is forced to (re)authenticate again in the web application and establish a new session." ( Ïhttps://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Absolute_TimeoutSource)Defaults to 60 days.A serversessionSet the timeout resolution.¤We need to save both the creation and last access times on sessions in order to implement idle and absolute timeouts. This means that we have to save the updated session on the storage backend even if the request didn't change any session variable, if only to update the last access time.íThis setting provides an optimization where the session is not updated on the storage backend provided that:"No session variables were changed.The difference between the current time and the last saved1 access time is less than the timeout resolution.ÈFor example, with a timeout resolution of 1 minute, every request that does not change the session variables within 1 minute of the last update will not generate any updates on the storage backend.If the timeout resolution is NothingÒ, then this optimization becomes disabled and the session will always be updated.Defaults to 10 minutes.B serversession5Set whether by default cookies should be persistent (True) or non-persistent (Falseý). Persistent cookies are saved across browser sessions. Non-persistent cookies are discarded when the browser is closed.ÅIf you set cookies to be persistent and do not define any timeouts (? or @1), then the cookie is set to expire in 10 years. Defaults to True.C serversession)Set whether cookies should be HTTP-only (True ) or not (FalseÛ). Cookies marked as HTTP-only ("HttpOnly") are not accessible from client-side scripting languages such as JavaScript, thus preventing a large class of XSS attacks. It's highly recommended to set this attribute to True. Defaults to True.D serversession.Set whether cookies should be mared "Secure" (True ) or not (False˜). Cookies marked as "Secure" are not sent via plain HTTP connections, only via HTTPS connections. It's highly recommended to set this attribute to TrueÉ. However, since many sites do not operate over HTTPS, the default is False. Defaults to False.E serversessionCf. =.F serversessionCf. C.G serversessionCf. D.H serversessionøLoad the session map from the storage backend. The value of the session cookie should be given as argument if present.Returns:The session data sess> to be used by the frontend as the current session's value.!Information to be passed back to L; on the end of the request in order to save the session.I serversessionCheck if a session s has expired. Returns the Just s if not expired, or Nothing if expired.J serversessionýCalculate the next point in time where the given session will expire assuming that it sees no activity until then. Returns Nothing5 iff the state does not have any expirations set to Just.K serversessionÉCalculate the date that should be used for the cookie's "Expires" field.L serversession-Save the session on the storage backend. A  given by H6 is expected besides the new contents of the session.Returns NothingÍ if the session was empty and didn't need to be saved. Note that this does not† necessarily means that nothing was done. If you ask for a session to be invalidated and clear every other sesssion variable, then LÎ will invalidate the older session but will avoid creating a new, empty one.M serversession7Invalidates an old session ID if needed. Returns the /9 that should be replaced when saving the session, if any.°Currently we invalidate whenever the auth ID has changed (login, logout, different user) in order to prevent session fixation attacks. We also invalidate when asked to via forceInvalidate.N serversession§Save a session on the database. If an old session is supplied, it is replaced, otherwise a new session is generated. If the session is empty, it is not saved and NothingÇ is returned. If the timeout resolution optimization is applied (cf. A6), the old session is returned and no update is made.O serversessionÊThe session key used to signal that the session ID should be invalidated.S serversessionSanity checks input on q (untrusted input).T serversessionA , decomposes into a ,Ò minus the keys that were removed. The auth key is added back when recomposing.( serversessionThe auth key (cf. >). serversessionSession data to be decomposed. serversessionDecomposed session data.) serversessionThe auth key (cf. >). serversessionThe AuthId , if any. serversession)Decomposed session data to be recomposed. serversessionRecomposed session data.I serversessionNow. N serversessionNow. serversessionThe old session, if any. serversessionThe session data to be saved. serversessionCopy of saved session.Ð  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOÐ789:;6/012345,-.%&'()*+ !"#$ <=>?@ABCDEFGHIJKLMNONone  #$23?É×Ù=K< !"#$%&'()*+,-./01234567<=>?@ABCDEFGHKLO<76/012345%&'()*+ !"#$,-.?@ABCDNone #$23?ÉÔ×ÙBÚo serversession Execute all storage tests using ,.'This function is meant to be used with hspec(. However, we don't want to depend on hspec, so it takes the relevant hspec: functions as arguments. Here's how it should be called: ÕallStorageTests myStorageBackend it runIO parallel shouldBe shouldReturn shouldThrow çSome storage backends are difficult to test with a clean slate. For this reason, this collection of tests works with unclean storage backends. In order to enforce these claims, we always test with an unclean storage backend by getting a single reference to it instead of asking for a function that creates storage backends and calling it on every test.ûIn addition, this test suite can be executed in parallel, there are no dependencies between tests. However, some tests require a large amount of memory so we try to run them sequentially in order to reduce the peak memory usage of the test suite.o serversessionStorage backend. serversessionhspec's it. serversessionhspec 's runIO. serversessionhspec 's parallel serversessionhspec 's shouldBe. serversessionhspec's shouldReturn. serversessionhspec's shouldThrow.ooò       !""#$%&'()*+,--.//0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstõ*serversession-1.0.2-94kRtKfl6owEEpgJIFCUOnWeb.ServerSession.Core.Internal#Web.ServerSession.Core.StorageTestsWeb.ServerSession.CoreForceInvalidateCurrentSessionIdAllSessionIdsOfLoggedUserDoNotForceInvalidateSaveSessionTokenState generatorstorage cookieNameauthKey idleTimeoutabsoluteTimeouttimeoutResolutionpersistentCookieshttpOnlyCookies secureCookiesStorageExceptionSessionAlreadyExistsSessionDoesNotExistseExistingSession seNewSessionStorage SessionData TransactionMrunTransactionM getSession deleteSessiondeleteAllSessionsOfAuthId insertSessionreplaceSessionDecomposedSessiondsAuthIddsForceInvalidate dsDecomposed IsSessionData Decomposed emptySessiondecomposeSessionrecomposeSessionisSameDecomposedisDecomposedEmpty SessionMap unSessionMapSession sessionKey sessionAuthId sessionDatasessionCreatedAtsessionAccessedAtAuthId SessionIdSunScheckSessionIdgenerateSessionId createState setCookieName setAuthKeysetIdleTimeoutsetAbsoluteTimeoutsetTimeoutResolutionsetPersistentCookiessetHttpOnlyCookiessetSecureCookies getCookieNamegetHttpOnlyCookiesgetSecureCookies loadSession checkExpired nextExpires cookieExpires saveSessioninvalidateIfNeededsaveSessionOnDbforceInvalidateKey$fHashableSessionId$fToJSONSessionId$fFromJSONSessionId$fPathPieceSessionId$fIsSessionDataSessionMap$fExceptionStorageException$fEqForceInvalidate$fOrdForceInvalidate$fShowForceInvalidate$fReadForceInvalidate$fBoundedForceInvalidate$fEnumForceInvalidate$fEqSessionMap$fShowSessionMap$fReadSessionMap $fEqSessionId$fOrdSessionId$fShowSessionId$fReadSessionId$fShowSaveSessionToken$fOrdSaveSessionToken$fEqSaveSessionToken$fShowStorageException$fOrdStorageException$fEqStorageException$fShowDecomposedSession$fOrdDecomposedSession$fEqDecomposedSession $fShowSession $fOrdSession $fEqSessionallStorageTestsghc-prim GHC.ClassesEq(path-pieces-0.2.1-3qqfFRSZ4HL4UPuvUVZn5UWeb.PathPieces fromPathPiece