{-# LANGUAGE QuasiQuotes #-} -- | [Auth0](https://auth0.com) -- -- * [Auth0 Authorize Application](https://auth0.com/docs/api/authentication#authorize-application) -- -- * [OAuth 2.0 Authorization Framework](https://auth0.com/docs/authenticate/protocols/oauth) module Network.OAuth2.Provider.Auth0 where import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Trans.Except (ExceptT (..)) import Data.Aeson (FromJSON) import Data.ByteString.Lazy.Char8 qualified as BSL import Data.Map.Strict qualified as Map import Data.Set qualified as Set import Data.Text.Lazy (Text) import GHC.Generics import Network.HTTP.Conduit import Network.OAuth.OAuth2 import Network.OAuth2.Experiment import Network.OAuth2.Provider import Network.OIDC.WellKnown import URI.ByteString.QQ sampleAuth0AuthorizationCodeApp :: AuthorizationCodeApplication sampleAuth0AuthorizationCodeApp = AuthorizationCodeApplication { acClientId = "" , acClientSecret = "" , acScope = Set.fromList ["openid", "profile", "email", "offline_access"] , acAuthorizeState = "CHANGE_ME" , acRedirectUri = [uri|http://localhost|] , acName = "sample-auth0-authorization-code-app" , acAuthorizeRequestExtraParams = Map.empty , acTokenRequestAuthenticationMethod = ClientSecretBasic } fetchUserInfo :: (MonadIO m, HasUserInfoRequest a, FromJSON b) => IdpApplication i a -> Manager -> AccessToken -> ExceptT BSL.ByteString m b fetchUserInfo = conduitUserInfoRequest mkAuth0Idp :: MonadIO m => -- | Full domain with no http protocol. e.g. @foo.auth0.com@ Text -> ExceptT Text m (Idp Auth0) mkAuth0Idp domain = do OpenIDConfiguration {..} <- fetchWellKnown domain pure ( Idp { -- https://auth0.com/docs/api/authentication#user-profile idpUserInfoEndpoint = userinfoEndpoint , -- https://auth0.com/docs/api/authentication#authorization-code-flow idpAuthorizeEndpoint = authorizationEndpoint , -- https://auth0.com/docs/api/authentication#authorization-code-flow44 idpTokenEndpoint = tokenEndpoint , idpDeviceAuthorizationEndpoint = Just deviceAuthorizationEndpoint } ) -- | https://auth0.com/docs/api/authentication#user-profile data Auth0User = Auth0User { name :: Text , email :: Text , sub :: Text } deriving (Show, Generic) instance FromJSON Auth0User