-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | wai-session bindings for serversession.
--   
--   API docs and the README are available at
--   <a>http://www.stackage.org/package/serversession-frontend-wai</a>
@package serversession-frontend-wai
@version 1.0


-- | Internal module exposing the guts of the package. Use at your own
--   risk. No API stability guarantees apply.
module Web.ServerSession.Frontend.Wai.Internal

-- | Construct the <tt>wai-session</tt> middleware using the given storage
--   backend and options. This is a convenient function that uses
--   <a>withSession</a>, <a>createState</a>, <a>sessionStore</a>,
--   <a>getCookieName</a> and <a>createCookieTemplate</a>.
withServerSession :: (Functor m, MonadIO m, MonadIO n, Storage sto, SessionData sto ~ SessionMap) => Key (Session m Text ByteString) -> (State sto -> State sto) -> sto -> n Middleware

-- | Construct the <tt>wai-session</tt> session store using the given
--   state. Note that keys and values types are fixed.
--   
--   As <tt>wai-session</tt> always requires a value to be provided, we
--   return an empty <tt>ByteString</tt> when the empty session was not
--   saved.
sessionStore :: (Functor m, MonadIO m, Storage sto, KeyValue (SessionData sto)) => State sto -> SessionStore m (Key (SessionData sto)) (Value (SessionData sto))

-- | Build a <a>Session</a> from an <a>IORef</a> containing the session
--   data.
mkSession :: (Functor m, MonadIO m, KeyValue sess) => IORef sess -> Session m (Key sess) (Value sess)

-- | Class for session data types that can be used as key-value stores.
class IsSessionData sess => KeyValue sess where {
    type family Key sess :: *;
    type family Value sess :: *;
}
kvLookup :: KeyValue sess => Key sess -> sess -> Maybe (Value sess)
kvInsert :: KeyValue sess => Key sess -> Value sess -> sess -> sess

-- | Create a cookie template given a state.
--   
--   Since we don't have access to the <a>Session</a>, we can't fill the
--   <tt>Expires</tt> field. Besides, as the template is constant,
--   eventually the <tt>Expires</tt> field would become outdated. This is a
--   limitation of <tt>wai-session</tt>'s interface, not a
--   <tt>serversession</tt> limitation. Other frontends support the
--   <tt>Expires</tt> field.
--   
--   Instead, we fill only the <tt>Max-age</tt> field. It works fine for
--   modern browsers, but many don't support it and will treat the cookie
--   as non-persistent (notably IE 6, 7 and 8).
createCookieTemplate :: State sto -> SetCookie

-- | Calculate the <tt>Max-age</tt> of a cookie template for the given
--   state.
--   
--   <ul>
--   <li>If the state asks for non-persistent sessions, the result is
--   <tt>Nothing</tt>.</li>
--   <li>If no timeout is defined, the result is 10 years.</li>
--   <li>Otherwise, the max age is set as the maximum timeout.</li>
--   </ul>
calculateMaxAge :: State sto -> Maybe DiffTime

-- | Invalidate the current session ID (and possibly more, check
--   <a>ForceInvalidate</a>). This is useful to avoid session fixation
--   attacks (cf.
--   <a>http://www.acrossecurity.com/papers/session_fixation.pdf</a>).
forceInvalidate :: Session m Text ByteString -> ForceInvalidate -> m ()
instance Web.ServerSession.Frontend.Wai.Internal.KeyValue Web.ServerSession.Core.Internal.SessionMap


-- | <tt>wai-session</tt> server-side session support.
--   
--   Please note that this frontend has some limitations:
--   
--   <ul>
--   <li>Cookies use the <tt>Max-age</tt> field instead of
--   <tt>Expires</tt>. The <tt>Max-age</tt> field is not supported by all
--   browsers: some browsers will treat them as non-persistent
--   cookies.</li>
--   <li>Also, the <tt>Max-age</tt> is fixed and does not take a given a
--   session into consideration.</li>
--   </ul>
module Web.ServerSession.Frontend.Wai

-- | Construct the <tt>wai-session</tt> middleware using the given storage
--   backend and options. This is a convenient function that uses
--   <a>withSession</a>, <a>createState</a>, <a>sessionStore</a>,
--   <a>getCookieName</a> and <a>createCookieTemplate</a>.
withServerSession :: (Functor m, MonadIO m, MonadIO n, Storage sto, SessionData sto ~ SessionMap) => Key (Session m Text ByteString) -> (State sto -> State sto) -> sto -> n Middleware

-- | Invalidate the current session ID (and possibly more, check
--   <a>ForceInvalidate</a>). This is useful to avoid session fixation
--   attacks (cf.
--   <a>http://www.acrossecurity.com/papers/session_fixation.pdf</a>).
forceInvalidate :: Session m Text ByteString -> ForceInvalidate -> m ()

-- | 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. <a>setAuthKey</a>).
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
--   <a>CurrentSessionId</a> (i.e., it <i>does not</i> invalidate the
--   sessions of all logged out users).
--   
--   Note that, for the purposes of <a>AllSessionIdsOfLoggedUser</a>, 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

-- | Construct the <tt>wai-session</tt> session store using the given
--   state. Note that keys and values types are fixed.
--   
--   As <tt>wai-session</tt> always requires a value to be provided, we
--   return an empty <tt>ByteString</tt> when the empty session was not
--   saved.
sessionStore :: (Functor m, MonadIO m, Storage sto, KeyValue (SessionData sto)) => State sto -> SessionStore m (Key (SessionData sto)) (Value (SessionData sto))

-- | Create a cookie template given a state.
--   
--   Since we don't have access to the <a>Session</a>, we can't fill the
--   <tt>Expires</tt> field. Besides, as the template is constant,
--   eventually the <tt>Expires</tt> field would become outdated. This is a
--   limitation of <tt>wai-session</tt>'s interface, not a
--   <tt>serversession</tt> limitation. Other frontends support the
--   <tt>Expires</tt> field.
--   
--   Instead, we fill only the <tt>Max-age</tt> field. It works fine for
--   modern browsers, but many don't support it and will treat the cookie
--   as non-persistent (notably IE 6, 7 and 8).
createCookieTemplate :: State sto -> SetCookie

-- | Class for session data types that can be used as key-value stores.
class IsSessionData sess => KeyValue sess where {
    type family Key sess :: *;
    type family Value sess :: *;
}
kvLookup :: KeyValue sess => Key sess -> sess -> Maybe (Value sess)
kvInsert :: KeyValue sess => Key sess -> Value sess -> sess -> sess

-- | 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
--   <tt>Map</tt>-alike, using a <tt>lookup</tt> function. However, the
--   <a>IsSessionData</a> 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 <tt>AuthId</tt> without needing a lookup.
--   
--   Defaults to "_ID" (used by <tt>yesod-auth</tt>).
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 <tt>Nothing</tt> 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."
--   (<a>Source</a>)
--   
--   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 <tt>Nothing</tt> 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." (<a>Source</a>)
--   
--   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:
--   
--   <ul>
--   <li>No session variables were changed.</li>
--   <li>The difference between the <i>current</i> time and the last
--   <i>saved</i> access time is less than the timeout resolution.</li>
--   </ul>
--   
--   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 <tt>Nothing</tt>, 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 (<tt>True</tt>) or
--   non-persistent (<tt>False</tt>). 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
--   (<a>setIdleTimeout</a> or <a>setAbsoluteTimeout</a>), then the cookie
--   is set to expire in 10 years.
--   
--   Defaults to <tt>True</tt>.
setPersistentCookies :: () => Bool -> State sto -> State sto

-- | Set whether cookies should be HTTP-only (<tt>True</tt>) or not
--   (<tt>False</tt>). 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 <tt>True</tt>.
--   
--   Defaults to <tt>True</tt>.
setHttpOnlyCookies :: () => Bool -> State sto -> State sto

-- | Set whether cookies should be mared "Secure" (<tt>True</tt>) or not
--   (<tt>False</tt>). Cookies marked as "Secure" are not sent via plain
--   HTTP connections, only via HTTPS connections. It's highly recommended
--   to set this attribute to <tt>True</tt>. However, since many sites do
--   not operate over HTTPS, the default is <tt>False</tt>.
--   
--   Defaults to <tt>False</tt>.
setSecureCookies :: () => Bool -> State sto -> State sto

-- | The server-side session backend needs to maintain some state in order
--   to work:
--   
--   <ul>
--   <li>A nonce generator for the session IDs.</li>
--   <li>A reference to the storage backend.</li>
--   <li>The name of cookie where the session ID will be saved
--   (<a>setCookieName</a>).</li>
--   <li>Authentication session variable (<a>setAuthKey</a>).</li>
--   <li>Idle and absolute timeouts (<a>setIdleTimeout</a> and
--   <a>setAbsoluteTimeout</a>).</li>
--   <li>Timeout resolution (<a>setTimeoutResolution</a>).</li>
--   <li>Whether cookies should be persistent
--   (<a>setPersistentCookies</a>), HTTP-only (<tt>setHTTPOnlyCookies</tt>)
--   and/or secure (<a>setSecureCookies</a>).</li>
--   </ul>
--   
--   Create a new <a>State</a> using <a>createState</a>.
data State sto :: * -> *
