module Servant.Auth.Server.Internal.ConfigTypes ( module Servant.Auth.Server.Internal.ConfigTypes , Servant.API.IsSecure(..) ) where import Crypto.JOSE as Jose import Crypto.JWT as Jose import qualified Data.ByteString as BS import Data.Default.Class import Data.Time import GHC.Generics (Generic) import Servant.API (IsSecure(..)) data IsMatch = Matches | DoesNotMatch deriving (Eq, Show, Read, Generic, Ord) data IsPasswordCorrect = PasswordCorrect | PasswordIncorrect deriving (Eq, Show, Read, Generic, Ord) -- The @SameSite@ attribute of cookies determines whether cookies will be sent -- on cross-origin requests. -- -- See -- for more information. data SameSite = AnySite | SameSiteStrict | SameSiteLax deriving (Eq, Show, Read, Generic, Ord) -- | @JWTSettings@ are used to generate cookies, and to verify JWTs. data JWTSettings = JWTSettings { -- | Key used to sign JWT. signingKey :: Jose.JWK -- | Algorithm used to sign JWT. , jwtAlg :: Maybe Jose.Alg -- | Keys used to validate JWT. , validationKeys :: Jose.JWKSet -- | An @aud@ predicate. The @aud@ is a string or URI that identifies the -- intended recipient of the JWT. , audienceMatches :: Jose.StringOrURI -> IsMatch } deriving (Generic) -- | A @JWTSettings@ where the audience always matches. defaultJWTSettings :: Jose.JWK -> JWTSettings defaultJWTSettings k = JWTSettings { signingKey = k , jwtAlg = Nothing , validationKeys = Jose.JWKSet [k] , audienceMatches = const Matches } -- | The policies to use when generating cookies. -- -- If *both* 'cookieMaxAge' and 'cookieExpires' are @Nothing@, browsers will -- treat the cookie as a *session cookie*. These will be deleted when the -- browser is closed. -- -- Note that having the setting @Secure@ may cause testing failures if you are -- not testing over HTTPS. data CookieSettings = CookieSettings { -- | 'Secure' means browsers will only send cookies over HTTPS. Default: -- @Secure@. cookieIsSecure :: !IsSecure -- | How long from now until the cookie expires. Default: @Nothing@. , cookieMaxAge :: !(Maybe DiffTime) -- | At what time the cookie expires. Default: @Nothing@. , cookieExpires :: !(Maybe UTCTime) -- | The URL path and sub-paths for which this cookie is used. Default: @Just "/"@. , cookiePath :: !(Maybe BS.ByteString) -- | Domain name, if set cookie also allows subdomains. Default: @Nothing@. , cookieDomain :: !(Maybe BS.ByteString) -- | 'SameSite' settings. Default: @SameSiteLax@. , cookieSameSite :: !SameSite -- | What name to use for the cookie used for the session. , sessionCookieName :: !BS.ByteString -- | The optional settings to use for XSRF protection. Default: @Just def@. , cookieXsrfSetting :: !(Maybe XsrfCookieSettings) } deriving (Eq, Show, Generic) instance Default CookieSettings where def = defaultCookieSettings defaultCookieSettings :: CookieSettings defaultCookieSettings = CookieSettings { cookieIsSecure = Secure , cookieMaxAge = Nothing , cookieExpires = Nothing , cookiePath = Just "/" , cookieDomain = Nothing , cookieSameSite = SameSiteLax , sessionCookieName = "JWT-Cookie" , cookieXsrfSetting = Just def } -- | The policies to use when generating and verifying XSRF cookies data XsrfCookieSettings = XsrfCookieSettings { -- | What name to use for the cookie used for XSRF protection. xsrfCookieName :: !BS.ByteString -- | What path to use for the cookie used for XSRF protection. Default @Just "/"@. , xsrfCookiePath :: !(Maybe BS.ByteString) -- | What name to use for the header used for XSRF protection. , xsrfHeaderName :: !BS.ByteString -- | Exclude GET request method from XSRF protection. , xsrfExcludeGet :: !Bool } deriving (Eq, Show, Generic) instance Default XsrfCookieSettings where def = defaultXsrfCookieSettings defaultXsrfCookieSettings :: XsrfCookieSettings defaultXsrfCookieSettings = XsrfCookieSettings { xsrfCookieName = "XSRF-TOKEN" , xsrfCookiePath = Just "/" , xsrfHeaderName = "X-XSRF-TOKEN" , xsrfExcludeGet = False } ------------------------------------------------------------------------------ -- Internal {{{ jwtSettingsToJwtValidationSettings :: JWTSettings -> Jose.JWTValidationSettings jwtSettingsToJwtValidationSettings s = defaultJWTValidationSettings (toBool <$> audienceMatches s) where toBool Matches = True toBool DoesNotMatch = False -- }}}