| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
IHP.LoginSupport.Middleware
Synopsis
- authMiddleware :: forall user normalizedModel. (normalizedModel ~ NormalizeModel user, normalizedModel ~ CurrentUserRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName user, FilterPrimaryKey (GetTableName normalizedModel), KnownSymbol (GetModelName user)) => Middleware
- adminAuthMiddleware :: forall admin normalizedModel. (normalizedModel ~ NormalizeModel admin, normalizedModel ~ CurrentAdminRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName admin, FilterPrimaryKey (GetTableName normalizedModel), KnownSymbol (GetModelName admin)) => Middleware
- userIdMiddleware :: ByteString -> Middleware
- adminIdMiddleware :: ByteString -> Middleware
- fetchUserMiddleware :: forall user normalizedModel. (normalizedModel ~ NormalizeModel user, normalizedModel ~ CurrentUserRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName user, FilterPrimaryKey (GetTableName normalizedModel)) => Middleware
- fetchAdminMiddleware :: forall admin normalizedModel. (normalizedModel ~ NormalizeModel admin, normalizedModel ~ CurrentAdminRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName admin, FilterPrimaryKey (GetTableName normalizedModel)) => Middleware
- fetchUserMiddlewareFor :: forall user normalizedModel. (normalizedModel ~ NormalizeModel user, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName user, FilterPrimaryKey (GetTableName normalizedModel)) => Key (Maybe UUID) -> Key (Maybe normalizedModel) -> Middleware
- parseSessionUUID :: ByteString -> Maybe UUID
- authMiddlewareWith :: Key (Maybe user) -> (Request -> IO (Maybe user)) -> Middleware
- currentUserVaultKey :: Key (Maybe CurrentUserRecord)
- currentAdminVaultKey :: Key (Maybe CurrentAdminRecord)
- currentUserIdVaultKey :: Key (Maybe UUID)
- currentAdminIdVaultKey :: Key (Maybe UUID)
- lookupAuthVault :: Key (Maybe user) -> Request -> Maybe user
Documentation
authMiddleware :: forall user normalizedModel. (normalizedModel ~ NormalizeModel user, normalizedModel ~ CurrentUserRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName user, FilterPrimaryKey (GetTableName normalizedModel), KnownSymbol (GetModelName user)) => Middleware Source #
Middleware that authenticates the current user and stores it in the request vault
using currentUserVaultKey.
This is the standard middleware for user authentication. Add it to your Config.hs:
import IHP.LoginSupport.Middleware
config :: ConfigBuilder
config = do
option $ AuthMiddleware (authMiddleware @User)For both user and admin authentication:
option $ AuthMiddleware (authMiddleware @User . adminAuthMiddleware @Admin)
This is equivalent to userIdMiddleware (sessionKey @User) . fetchUserMiddleware @User.
adminAuthMiddleware :: forall admin normalizedModel. (normalizedModel ~ NormalizeModel admin, normalizedModel ~ CurrentAdminRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName admin, FilterPrimaryKey (GetTableName normalizedModel), KnownSymbol (GetModelName admin)) => Middleware Source #
Middleware that authenticates the current admin and stores it in the request vault
using currentAdminVaultKey.
option $ AuthMiddleware (authMiddleware @User . adminAuthMiddleware @Admin)
This is equivalent to adminIdMiddleware (sessionKey @Admin) . fetchAdminMiddleware @Admin.
userIdMiddleware :: ByteString -> Middleware Source #
Middleware that reads a userId from the session and stores it in
currentUserIdVaultKey. No database query is performed.
This is useful when you only need the user's UUID (e.g. for row-level security) and want to avoid the cost of a database fetch.
option $ AuthMiddleware (userIdMiddleware (sessionKey @User))
For full user record access, compose with fetchUserMiddleware:
option $ AuthMiddleware (userIdMiddleware (sessionKey @User) . fetchUserMiddleware @User)
adminIdMiddleware :: ByteString -> Middleware Source #
Same as userIdMiddleware but stores the admin ID in currentAdminIdVaultKey.
option $ AuthMiddleware (adminIdMiddleware (sessionKey @Admin))
fetchUserMiddleware :: forall user normalizedModel. (normalizedModel ~ NormalizeModel user, normalizedModel ~ CurrentUserRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName user, FilterPrimaryKey (GetTableName normalizedModel)) => Middleware Source #
Middleware that reads the userId from currentUserIdVaultKey, fetches
the full user record from the database, and stores it in currentUserVaultKey.
Must be composed after userIdMiddleware:
userIdMiddleware (sessionKey @User) . fetchUserMiddleware @User
fetchAdminMiddleware :: forall admin normalizedModel. (normalizedModel ~ NormalizeModel admin, normalizedModel ~ CurrentAdminRecord, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName admin, FilterPrimaryKey (GetTableName normalizedModel)) => Middleware Source #
Middleware that reads the adminId from currentAdminIdVaultKey, fetches
the full admin record from the database, and stores it in currentAdminVaultKey.
Must be composed after adminIdMiddleware:
adminIdMiddleware (sessionKey @Admin) . fetchAdminMiddleware @Admin
fetchUserMiddlewareFor :: forall user normalizedModel. (normalizedModel ~ NormalizeModel user, Typeable normalizedModel, Table normalizedModel, FromRowHasql normalizedModel, PrimaryKey (GetTableName normalizedModel) ~ UUID, GetTableName normalizedModel ~ GetTableName user, FilterPrimaryKey (GetTableName normalizedModel)) => Key (Maybe UUID) -> Key (Maybe normalizedModel) -> Middleware Source #
Building block: reads a UUID from the given ID vault key, fetches the record from the database, and stores it in the given user vault key.
parseSessionUUID :: ByteString -> Maybe UUID Source #
Parse UUID from session bytes. Handles both:
- New format: raw 36-byte UUID ASCII (e.g. "550e8400-e29b-41d4-a716-446655440000")
- Old format: 8-byte cereal length prefix + 36-byte UUID ASCII (44 bytes total)
The old format comes from sessions written with Serialize (Id' table) which
prepends an 8-byte big-endian length prefix via cereal. We support both formats
so existing sessions continue to work without logging users out on upgrade.
TODO: Remove old format support after 2026-05-01. At that point all session cookies using the cereal encoding will have expired.
authMiddlewareWith :: Key (Maybe user) -> (Request -> IO (Maybe user)) -> Middleware Source #
Low-level building block: middleware that runs a fetch function and stores the result in the request vault under the given key.
This decouples the vault insertion from the database lookup, making it useful for testing and custom authentication schemes.
currentUserVaultKey :: Key (Maybe CurrentUserRecord) Source #
Vault key for the current user record.
Used by authMiddleware to store the authenticated user in the WAI request vault.
currentAdminVaultKey :: Key (Maybe CurrentAdminRecord) Source #
Vault key for the current admin record.
Used by adminAuthMiddleware to store the authenticated admin in the WAI request vault.
currentUserIdVaultKey :: Key (Maybe UUID) Source #
Vault key for the current user's UUID.
Used by userIdMiddleware to store just the user ID (no DB fetch).