-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Secure, modular server-side sessions.
--
@package serversession
@version 1.0
-- | Internal module exposing the guts of the package. Use at your own
-- risk. No API stability guarantees apply.
--
-- UndecidableInstances is required in order to implement
-- Eq, Ord, Show, etc. on data types that have
-- Decomposed fields, and should be fairly safe.
module Web.ServerSession.Core.Internal
-- | 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:
--
--
newtype SessionId sess
S :: Text -> SessionId sess
unS :: SessionId sess -> Text
-- | (Internal) Check that the given text is a base64url-encoded
-- representation of 18 bytes.
checkSessionId :: Text -> Maybe (SessionId sess)
-- | Securely generate a new SessionId.
generateSessionId :: Generator -> IO (SessionId sess)
-- | Value of the authKey session key.
type AuthId = ByteString
-- | 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 sess type variable describes the
-- session data type.
data Session sess
Session :: SessionId sess -> Maybe AuthId -> Decomposed sess -> UTCTime -> UTCTime -> Session sess
-- | Session ID, primary key.
sessionKey :: Session sess -> SessionId sess
-- | Value of authKey session key, separate from the rest.
sessionAuthId :: Session sess -> Maybe AuthId
-- | Rest of the session data.
sessionData :: Session sess -> Decomposed sess
-- | When this session was created.
sessionCreatedAt :: Session sess -> UTCTime
-- | When this session was last accessed.
sessionAccessedAt :: Session sess -> UTCTime
-- | A newtype for a common session map.
--
-- This 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.
newtype SessionMap
SessionMap :: HashMap Text ByteString -> SessionMap
unSessionMap :: SessionMap -> HashMap Text ByteString
-- | Class for data types to be used as session data (cf.
-- sessionData, SessionData).
--
-- The Show constrain is needed for StorageException.
class (Show (Decomposed sess), Typeable (Decomposed sess), Typeable sess) => IsSessionData sess where type family Decomposed sess :: *
emptySession :: IsSessionData sess => sess
decomposeSession :: IsSessionData sess => Text -> sess -> DecomposedSession sess
recomposeSession :: IsSessionData sess => Text -> Maybe AuthId -> Decomposed sess -> sess
isSameDecomposed :: IsSessionData sess => proxy sess -> Decomposed sess -> Decomposed sess -> Bool
isDecomposedEmpty :: IsSessionData sess => proxy sess -> Decomposed sess -> Bool
-- | A session data type sess with its special variables taken
-- apart.
data DecomposedSession sess
DecomposedSession :: !(Maybe ByteString) -> !ForceInvalidate -> !(Decomposed sess) -> DecomposedSession sess
dsAuthId :: DecomposedSession sess -> !(Maybe ByteString)
dsForceInvalidate :: DecomposedSession sess -> !ForceInvalidate
dsDecomposed :: DecomposedSession sess -> !(Decomposed sess)
-- | A storage backend sto for server-side sessions. The
-- sess session data type and/or its Decomposed version
-- may be constrained depending on the storage backend capabilities.
class (Typeable sto, MonadIO (TransactionM sto), IsSessionData (SessionData sto)) => Storage sto where type family SessionData sto :: * type family TransactionM sto :: * -> *
runTransactionM :: Storage sto => sto -> TransactionM sto a -> IO a
getSession :: Storage sto => sto -> SessionId (SessionData sto) -> TransactionM sto (Maybe (Session (SessionData sto)))
deleteSession :: Storage sto => sto -> SessionId (SessionData sto) -> TransactionM sto ()
deleteAllSessionsOfAuthId :: Storage sto => sto -> AuthId -> TransactionM sto ()
insertSession :: Storage sto => sto -> Session (SessionData sto) -> TransactionM sto ()
replaceSession :: Storage sto => sto -> Session (SessionData sto) -> TransactionM sto ()
-- | Common exceptions that may be thrown by any storage.
data StorageException sto
-- | Exception thrown by insertSession whenever a session with same
-- ID already exists.
SessionAlreadyExists :: Session (SessionData sto) -> Session (SessionData sto) -> StorageException sto
seExistingSession :: StorageException sto -> Session (SessionData sto)
seNewSession :: StorageException sto -> Session (SessionData sto)
-- | Exception thrown by replaceSession whenever trying to replace a
-- session that is not present on the storage.
SessionDoesNotExist :: Session (SessionData sto) -> StorageException sto
seNewSession :: StorageException sto -> Session (SessionData sto)
-- | The server-side session backend needs to maintain some state in order
-- to work:
--
--
--
-- Create a new State using createState.
data State sto
State :: !Generator -> !sto -> !Text -> !Text -> !(Maybe NominalDiffTime) -> !(Maybe NominalDiffTime) -> !(Maybe NominalDiffTime) -> !Bool -> !Bool -> !Bool -> State sto
generator :: State sto -> !Generator
storage :: State sto -> !sto
cookieName :: State sto -> !Text
authKey :: State sto -> !Text
idleTimeout :: State sto -> !(Maybe NominalDiffTime)
absoluteTimeout :: State sto -> !(Maybe NominalDiffTime)
timeoutResolution :: State sto -> !(Maybe NominalDiffTime)
persistentCookies :: State sto -> !Bool
httpOnlyCookies :: State sto -> !Bool
secureCookies :: State sto -> !Bool
-- | Create a new State for the server-side session backend using
-- the given storage backend.
createState :: MonadIO m => sto -> m (State sto)
-- | 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.
setCookieName :: Text -> State sto -> State sto
-- | Set the name of the session variable that keeps track of the logged
-- user.
--
-- This setting is used by session data types that are
-- Map-alike, using a lookup function. However, the
-- IsSessionData 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).
setAuthKey :: Text -> State sto -> State sto
-- | 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."
-- (Source)
--
-- Defaults to 7 days.
setIdleTimeout :: Maybe NominalDiffTime -> State sto -> State sto
-- | 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." (Source)
--
-- Defaults to 60 days.
setAbsoluteTimeout :: Maybe NominalDiffTime -> State sto -> State sto
-- | Set 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
-- saved 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.
setTimeoutResolution :: Maybe NominalDiffTime -> State sto -> State sto
-- | Set 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
-- (setIdleTimeout or setAbsoluteTimeout), then the cookie
-- is set to expire in 10 years.
--
-- Defaults to True.
setPersistentCookies :: Bool -> State sto -> State sto
-- | 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.
setHttpOnlyCookies :: Bool -> State sto -> State sto
-- | 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.
setSecureCookies :: Bool -> State sto -> State sto
-- | Cf. setCookieName.
getCookieName :: State sto -> Text
-- | Cf. setHttpOnlyCookies.
getHttpOnlyCookies :: State sto -> Bool
-- | Cf. setSecureCookies.
getSecureCookies :: State sto -> Bool
-- | 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 saveSession on the end of
-- the request in order to save the session.
--
loadSession :: Storage sto => State sto -> Maybe ByteString -> IO (SessionData sto, SaveSessionToken sto)
-- | Check if a session s has expired. Returns the Just s
-- if not expired, or Nothing if expired.
checkExpired :: UTCTime -> State sto -> Session sess -> Maybe (Session sess)
-- | Calculate the next point in time where the given session will expire
-- assuming that it sees no activity until then. Returns Nothing
-- iff the state does not have any expirations set to Just.
nextExpires :: State sto -> Session sess -> Maybe UTCTime
-- | Calculate the date that should be used for the cookie's "Expires"
-- field.
cookieExpires :: State sto -> Session sess -> Maybe UTCTime
-- | Save the session on the storage backend. A SaveSessionToken
-- given by loadSession 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 saveSession will invalidate
-- the older session but will avoid creating a new, empty one.
saveSession :: Storage sto => State sto -> SaveSessionToken sto -> SessionData sto -> IO (Maybe (Session (SessionData sto)))
-- | Opaque token containing the necessary information for
-- saveSession to save the session.
data SaveSessionToken sto
SaveSessionToken :: (Maybe (Session (SessionData sto))) -> UTCTime -> SaveSessionToken sto
-- | Invalidates an old session ID if needed. Returns the Session
-- 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.
invalidateIfNeeded :: Storage sto => State sto -> Maybe (Session (SessionData sto)) -> DecomposedSession (SessionData sto) -> TransactionM sto (Maybe (Session (SessionData sto)))
-- | 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.
-- setTimeoutResolution), the old session is returned and no
-- update is made.
saveSessionOnDb :: Storage sto => State sto -> UTCTime -> Maybe (Session (SessionData sto)) -> DecomposedSession (SessionData sto) -> TransactionM sto (Maybe (Session (SessionData sto)))
-- | The session key used to signal that the session ID should be
-- invalidated.
forceInvalidateKey :: Text
-- | 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.
data ForceInvalidate
-- | Invalidate the current session ID. The current session ID is
-- automatically invalidated on login and logout (cf. setAuthKey).
CurrentSessionId :: ForceInvalidate
-- | 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
-- CurrentSessionId (i.e., it does not invalidate the
-- sessions of all logged out users).
--
-- Note that, for the purposes of AllSessionIdsOfLoggedUser, 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.
AllSessionIdsOfLoggedUser :: ForceInvalidate
-- | Do not force invalidate. Invalidate only if automatically. This is the
-- default.
DoNotForceInvalidate :: ForceInvalidate
instance Typeable SessionId
instance Typeable SessionMap
instance Typeable State
instance Typeable ForceInvalidate
instance Typeable DecomposedSession
instance Typeable Session
instance Typeable SaveSessionToken
instance Typeable StorageException
instance Show (Decomposed (SessionData sto)) => Show (SaveSessionToken sto)
instance Ord (Decomposed (SessionData sto)) => Ord (SaveSessionToken sto)
instance Eq (Decomposed (SessionData sto)) => Eq (SaveSessionToken sto)
instance Show (Decomposed (SessionData sto)) => Show (StorageException sto)
instance Ord (Decomposed (SessionData sto)) => Ord (StorageException sto)
instance Eq (Decomposed (SessionData sto)) => Eq (StorageException sto)
instance Show (Decomposed sess) => Show (DecomposedSession sess)
instance Ord (Decomposed sess) => Ord (DecomposedSession sess)
instance Eq (Decomposed sess) => Eq (DecomposedSession sess)
instance Show (Decomposed sess) => Show (Session sess)
instance Ord (Decomposed sess) => Ord (Session sess)
instance Eq (Decomposed sess) => Eq (Session sess)
instance Eq (SessionId sess)
instance Ord (SessionId sess)
instance Show (SessionId sess)
instance Read (SessionId sess)
instance Eq SessionMap
instance Show SessionMap
instance Read SessionMap
instance Eq ForceInvalidate
instance Ord ForceInvalidate
instance Show ForceInvalidate
instance Read ForceInvalidate
instance Bounded ForceInvalidate
instance Enum ForceInvalidate
instance Storage sto => Exception (StorageException sto)
instance IsSessionData SessionMap
instance Hashable (SessionId sess)
instance ToJSON (SessionId sess)
instance FromJSON (SessionId sess)
instance PathPiece (SessionId sess)
-- | This module contains tests that should pass for every storage backend.
-- These are not intended for end-users of the serversession
-- library. However, they are part of the supported API, so they're not
-- an Internal module.
module Web.ServerSession.Core.StorageTests
-- | Execute all storage tests using SessionMap.
--
-- 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.
allStorageTests :: (Monad m, Storage sto, SessionData sto ~ SessionMap) => sto -> (String -> IO () -> m ()) -> (forall a. IO a -> m a) -> (m () -> m ()) -> (forall a. (Show a, Eq a) => a -> a -> IO ()) -> (forall a. (Show a, Eq a) => IO a -> a -> IO ()) -> (forall a e. Exception e => IO a -> (e -> Bool) -> IO ()) -> m ()
-- | Core server-side session support.
module Web.ServerSession.Core
-- | 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:
--
--
data SessionId sess
-- | Value of the authKey session key.
type AuthId = ByteString
-- | 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 sess type variable describes the
-- session data type.
data Session sess
Session :: SessionId sess -> Maybe AuthId -> Decomposed sess -> UTCTime -> UTCTime -> Session sess
-- | Session ID, primary key.
sessionKey :: Session sess -> SessionId sess
-- | Value of authKey session key, separate from the rest.
sessionAuthId :: Session sess -> Maybe AuthId
-- | Rest of the session data.
sessionData :: Session sess -> Decomposed sess
-- | When this session was created.
sessionCreatedAt :: Session sess -> UTCTime
-- | When this session was last accessed.
sessionAccessedAt :: Session sess -> UTCTime
-- | A storage backend sto for server-side sessions. The
-- sess session data type and/or its Decomposed version
-- may be constrained depending on the storage backend capabilities.
class (Typeable sto, MonadIO (TransactionM sto), IsSessionData (SessionData sto)) => Storage sto where type family SessionData sto :: * type family TransactionM sto :: * -> *
runTransactionM :: Storage sto => sto -> TransactionM sto a -> IO a
getSession :: Storage sto => sto -> SessionId (SessionData sto) -> TransactionM sto (Maybe (Session (SessionData sto)))
deleteSession :: Storage sto => sto -> SessionId (SessionData sto) -> TransactionM sto ()
deleteAllSessionsOfAuthId :: Storage sto => sto -> AuthId -> TransactionM sto ()
insertSession :: Storage sto => sto -> Session (SessionData sto) -> TransactionM sto ()
replaceSession :: Storage sto => sto -> Session (SessionData sto) -> TransactionM sto ()
-- | Common exceptions that may be thrown by any storage.
data StorageException sto
-- | Exception thrown by insertSession whenever a session with same
-- ID already exists.
SessionAlreadyExists :: Session (SessionData sto) -> Session (SessionData sto) -> StorageException sto
seExistingSession :: StorageException sto -> Session (SessionData sto)
seNewSession :: StorageException sto -> Session (SessionData sto)
-- | Exception thrown by replaceSession whenever trying to replace a
-- session that is not present on the storage.
SessionDoesNotExist :: Session (SessionData sto) -> StorageException sto
seNewSession :: StorageException sto -> Session (SessionData sto)
-- | Class for data types to be used as session data (cf.
-- sessionData, SessionData).
--
-- The Show constrain is needed for StorageException.
class (Show (Decomposed sess), Typeable (Decomposed sess), Typeable sess) => IsSessionData sess where type family Decomposed sess :: *
emptySession :: IsSessionData sess => sess
decomposeSession :: IsSessionData sess => Text -> sess -> DecomposedSession sess
recomposeSession :: IsSessionData sess => Text -> Maybe AuthId -> Decomposed sess -> sess
isSameDecomposed :: IsSessionData sess => proxy sess -> Decomposed sess -> Decomposed sess -> Bool
isDecomposedEmpty :: IsSessionData sess => proxy sess -> Decomposed sess -> Bool
-- | A session data type sess with its special variables taken
-- apart.
data DecomposedSession sess
DecomposedSession :: !(Maybe ByteString) -> !ForceInvalidate -> !(Decomposed sess) -> DecomposedSession sess
dsAuthId :: DecomposedSession sess -> !(Maybe ByteString)
dsForceInvalidate :: DecomposedSession sess -> !ForceInvalidate
dsDecomposed :: DecomposedSession sess -> !(Decomposed sess)
-- | A newtype for a common session map.
--
-- This 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.
newtype SessionMap
SessionMap :: HashMap Text ByteString -> SessionMap
unSessionMap :: SessionMap -> HashMap Text ByteString
-- | The server-side session backend needs to maintain some state in order
-- to work:
--
--
--
-- Create a new State using createState.
data State sto
-- | Create a new State for the server-side session backend using
-- the given storage backend.
createState :: MonadIO m => sto -> m (State sto)
-- | Cf. setCookieName.
getCookieName :: State sto -> Text
-- | Cf. setHttpOnlyCookies.
getHttpOnlyCookies :: State sto -> Bool
-- | Cf. setSecureCookies.
getSecureCookies :: State sto -> Bool
-- | 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 saveSession on the end of
-- the request in order to save the session.
--
loadSession :: Storage sto => State sto -> Maybe ByteString -> IO (SessionData sto, SaveSessionToken sto)
-- | Calculate the date that should be used for the cookie's "Expires"
-- field.
cookieExpires :: State sto -> Session sess -> Maybe UTCTime
-- | Save the session on the storage backend. A SaveSessionToken
-- given by loadSession 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 saveSession will invalidate
-- the older session but will avoid creating a new, empty one.
saveSession :: Storage sto => State sto -> SaveSessionToken sto -> SessionData sto -> IO (Maybe (Session (SessionData sto)))
-- | Opaque token containing the necessary information for
-- saveSession to save the session.
data SaveSessionToken sto
-- | The session key used to signal that the session ID should be
-- invalidated.
forceInvalidateKey :: Text
-- | 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.
setCookieName :: Text -> State sto -> State sto
-- | Set the name of the session variable that keeps track of the logged
-- user.
--
-- This setting is used by session data types that are
-- Map-alike, using a lookup function. However, the
-- IsSessionData 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).
setAuthKey :: Text -> State sto -> State sto
-- | 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."
-- (Source)
--
-- Defaults to 7 days.
setIdleTimeout :: Maybe NominalDiffTime -> State sto -> State sto
-- | 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." (Source)
--
-- Defaults to 60 days.
setAbsoluteTimeout :: Maybe NominalDiffTime -> State sto -> State sto
-- | Set 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
-- saved 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.
setTimeoutResolution :: Maybe NominalDiffTime -> State sto -> State sto
-- | Set 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
-- (setIdleTimeout or setAbsoluteTimeout), then the cookie
-- is set to expire in 10 years.
--
-- Defaults to True.
setPersistentCookies :: Bool -> State sto -> State sto
-- | 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.
setHttpOnlyCookies :: Bool -> State sto -> State sto
-- | 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.
setSecureCookies :: Bool -> State sto -> State sto
-- | 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.
data ForceInvalidate
-- | Invalidate the current session ID. The current session ID is
-- automatically invalidated on login and logout (cf. setAuthKey).
CurrentSessionId :: ForceInvalidate
-- | 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
-- CurrentSessionId (i.e., it does not invalidate the
-- sessions of all logged out users).
--
-- Note that, for the purposes of AllSessionIdsOfLoggedUser, 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.
AllSessionIdsOfLoggedUser :: ForceInvalidate
-- | Do not force invalidate. Invalidate only if automatically. This is the
-- default.
DoNotForceInvalidate :: ForceInvalidate