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

-- | Haskell OAuth2 authentication client
--   
--   See readme for more details.
@package hoauth2
@version 2.8.0

-- | Bindings Access Token and Refresh Token part of The OAuth 2.0
--   Authorization Framework RFC6749
--   https://www.rfc-editor.org/rfc/rfc6749
module Network.OAuth.OAuth2.TokenRequest
data TokenRequestError
TokenRequestError :: TokenRequestErrorCode -> Maybe Text -> Maybe (URIRef Absolute) -> TokenRequestError
[error] :: TokenRequestError -> TokenRequestErrorCode
[errorDescription] :: TokenRequestError -> Maybe Text
[errorUri] :: TokenRequestError -> Maybe (URIRef Absolute)

-- | Token Error Responses
--   https://tools.ietf.org/html/rfc6749#section-5.2
data TokenRequestErrorCode
InvalidRequest :: TokenRequestErrorCode
InvalidClient :: TokenRequestErrorCode
InvalidGrant :: TokenRequestErrorCode
UnauthorizedClient :: TokenRequestErrorCode
UnsupportedGrantType :: TokenRequestErrorCode
InvalidScope :: TokenRequestErrorCode
UnknownErrorCode :: Text -> TokenRequestErrorCode
parseTokeRequestError :: ByteString -> TokenRequestError

-- | Prepare the URL and the request body query for fetching an access
--   token.
accessTokenUrl :: OAuth2 -> ExchangeToken -> (URI, PostBody)

-- | Obtain a new access token by sending a Refresh Token to the
--   Authorization server.
refreshAccessTokenUrl :: OAuth2 -> RefreshToken -> (URI, PostBody)

-- | Exchange code for an Access Token with authenticate in
--   request header.
fetchAccessToken :: MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenRequestError m OAuth2Token

-- | Deprecated: use fetchAccessTokenWithAuthMethod
fetchAccessToken2 :: MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenRequestError m OAuth2Token

-- | Deprecated: use fetchAccessTokenWithAuthMethod
fetchAccessTokenInternal :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenRequestError m OAuth2Token

-- | Exchange code for an Access Token
--   
--   OAuth2 spec allows credential (client_id,
--   client_secret) to be sent either in the header (a.k.a
--   ClientSecretBasic). or as form/url params (a.k.a
--   ClientSecretPost).
--   
--   The OAuth provider can choose to implement only one, or both. Look for
--   API document from the OAuth provider you're dealing with. If you're
--   uncertain, try fetchAccessToken which sends credential in
--   authorization http header, which is common case.
fetchAccessTokenWithAuthMethod :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenRequestError m OAuth2Token

-- | Fetch a new AccessToken using the Refresh Token with authentication in
--   request header.
refreshAccessToken :: MonadIO m => Manager -> OAuth2 -> RefreshToken -> ExceptT TokenRequestError m OAuth2Token

-- | Deprecated: use refreshAccessTokenWithAuthMethod
refreshAccessToken2 :: MonadIO m => Manager -> OAuth2 -> RefreshToken -> ExceptT TokenRequestError m OAuth2Token

-- | Deprecated: use refreshAccessTokenWithAuthMethod
refreshAccessTokenInternal :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT TokenRequestError m OAuth2Token

-- | Fetch a new AccessToken using the Refresh Token.
--   
--   OAuth2 spec allows credential (client_id,
--   client_secret) to be sent either in the header (a.k.a
--   ClientSecretBasic). or as form/url params (a.k.a
--   ClientSecretPost).
--   
--   The OAuth provider can choose to implement only one, or both. Look for
--   API document from the OAuth provider you're dealing with. If you're
--   uncertain, try refreshAccessToken which sends credential in
--   authorization http header, which is common case.
refreshAccessTokenWithAuthMethod :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT TokenRequestError m OAuth2Token

-- | Conduct post request and return response as JSON.
doJSONPostRequest :: (MonadIO m, FromJSON a) => Manager -> OAuth2 -> URI -> PostBody -> ExceptT TokenRequestError m a

-- | Conduct post request.
doSimplePostRequest :: MonadIO m => Manager -> OAuth2 -> URI -> PostBody -> ExceptT TokenRequestError m ByteString

-- | Gets response body from a Response if 200 otherwise assume
--   OAuth2Error
handleOAuth2TokenResponse :: Response ByteString -> Either TokenRequestError ByteString

-- | Try to parses response as JSON, if failed, try to parse as like query
--   string.
parseResponseFlexible :: FromJSON a => ByteString -> Either TokenRequestError a

-- | Parses the response that contains not JSON but a Query String
parseResponseString :: FromJSON a => ByteString -> Either TokenRequestError a

-- | Set several header values: + userAgennt : hoauth2 + accept :
--   `application/json`
addDefaultRequestHeaders :: Request -> Request

-- | Add Credential (client_id, client_secret) to the request post body.
clientSecretPost :: OAuth2 -> PostBody
instance GHC.Classes.Eq Network.OAuth.OAuth2.TokenRequest.TokenRequestErrorCode
instance GHC.Show.Show Network.OAuth.OAuth2.TokenRequest.TokenRequestErrorCode
instance GHC.Generics.Generic Network.OAuth.OAuth2.TokenRequest.TokenRequestError
instance GHC.Classes.Eq Network.OAuth.OAuth2.TokenRequest.TokenRequestError
instance GHC.Show.Show Network.OAuth.OAuth2.TokenRequest.TokenRequestError
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.TokenRequest.TokenRequestError
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.TokenRequest.TokenRequestErrorCode

-- | Bindings for The OAuth 2.0 Authorization Framework: Bearer Token Usage
--   RFC6750 https://www.rfc-editor.org/rfc/rfc6750
module Network.OAuth.OAuth2.HttpClient

-- | Conduct an authorized GET request and return response as JSON. Inject
--   Access Token to Authorization Header.
authGetJSON :: (FromJSON a, MonadIO m) => Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | Conduct an authorized GET request. Inject Access Token to
--   Authorization Header.
authGetBS :: MonadIO m => Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | Same to authGetBS but set access token to query parameter
--   rather than header

-- | Deprecated: use authGetBSWithAuthMethod
authGetBS2 :: MonadIO m => Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | Conduct an authorized GET request and return response as JSON. Allow
--   to specify how to append AccessToken.
authGetJSONWithAuthMethod :: (MonadIO m, FromJSON a) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | Deprecated: use authGetJSONWithAuthMethod
authGetJSONInternal :: (FromJSON a, MonadIO m) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | Conduct an authorized GET request and return response as ByteString.
--   Allow to specify how to append AccessToken.
authGetBSWithAuthMethod :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | Deprecated: use authGetBSWithAuthMethod
authGetBSInternal :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | Conduct POST request and return response as JSON. Inject Access Token
--   to Authorization Header.
authPostJSON :: (FromJSON a, MonadIO m) => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | Conduct POST request. Inject Access Token to http header
--   (Authorization)
authPostBS :: MonadIO m => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | Conduct POST request with access token only in the request body but
--   header.

-- | Deprecated: use authPostBSWithAuthMethod
authPostBS2 :: MonadIO m => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | Conduct POST request with access token only in the header and not in
--   body

-- | Deprecated: use authPostBSWithAuthMethod
authPostBS3 :: MonadIO m => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | Conduct POST request and return response as JSON. Allow to specify how
--   to append AccessToken.
authPostJSONWithAuthMethod :: (FromJSON a, MonadIO m) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | Deprecated: use authPostJSONWithAuthMethod
authPostJSONInternal :: (FromJSON a, MonadIO m) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | Conduct POST request and return response as ByteString. Allow to
--   specify how to append AccessToken.
authPostBSWithAuthMethod :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | Deprecated: use authPostBSWithAuthMethod
authPostBSInternal :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | https://www.rfc-editor.org/rfc/rfc6750#section-2
data APIAuthenticationMethod

-- | Provides in Authorization header
AuthInRequestHeader :: APIAuthenticationMethod

-- | Provides in request body
AuthInRequestBody :: APIAuthenticationMethod

-- | Provides in request query parameter
AuthInRequestQuery :: APIAuthenticationMethod
instance GHC.Classes.Ord Network.OAuth.OAuth2.HttpClient.APIAuthenticationMethod
instance GHC.Classes.Eq Network.OAuth.OAuth2.HttpClient.APIAuthenticationMethod

-- | Bindings Authorization part of The OAuth 2.0 Authorization Framework
--   RFC6749 https://www.rfc-editor.org/rfc/rfc6749
module Network.OAuth.OAuth2.AuthorizationRequest

-- | Authorization Code Grant Error Responses
--   https://tools.ietf.org/html/rfc6749#section-4.1.2.1 I found
--   hard time to figure a way to test the authorization error flow When
--   anything wrong in /authorize request, it will stuck at the
--   Provider page hence no way for this library to parse error response.
--   In other words, /authorize ends up with 4xx or 5xx. Revisit
--   this whenever find a case OAuth2 provider redirects back to Relying
--   party with errors.
data Errors
InvalidRequest :: Errors
UnauthorizedClient :: Errors
AccessDenied :: Errors
UnsupportedResponseType :: Errors
InvalidScope :: Errors
ServerError :: Errors
TemporarilyUnavailable :: Errors

-- | See authorizationUrlWithParams
authorizationUrl :: OAuth2 -> URI

-- | Prepare the authorization URL. Redirect to this URL asking for user
--   interactive authentication.
authorizationUrlWithParams :: QueryParams -> OAuth2 -> URI
instance GHC.Generics.Generic Network.OAuth.OAuth2.AuthorizationRequest.Errors
instance GHC.Classes.Eq Network.OAuth.OAuth2.AuthorizationRequest.Errors
instance GHC.Show.Show Network.OAuth.OAuth2.AuthorizationRequest.Errors
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.AuthorizationRequest.Errors

-- | A lightweight oauth2 Haskell binding. See Readme for more details
module Network.OAuth.OAuth2

-- | See authorizationUrlWithParams
authorizationUrl :: OAuth2 -> URI

-- | Prepare the authorization URL. Redirect to this URL asking for user
--   interactive authentication.
authorizationUrlWithParams :: QueryParams -> OAuth2 -> URI

-- | Query Parameter Representation
data OAuth2
OAuth2 :: Text -> Text -> URIRef Absolute -> URIRef Absolute -> URIRef Absolute -> OAuth2
[oauth2ClientId] :: OAuth2 -> Text
[oauth2ClientSecret] :: OAuth2 -> Text
[oauth2AuthorizeEndpoint] :: OAuth2 -> URIRef Absolute
[oauth2TokenEndpoint] :: OAuth2 -> URIRef Absolute
[oauth2RedirectUri] :: OAuth2 -> URIRef Absolute
newtype AccessToken
AccessToken :: Text -> AccessToken
[atoken] :: AccessToken -> Text
newtype RefreshToken
RefreshToken :: Text -> RefreshToken
[rtoken] :: RefreshToken -> Text
newtype IdToken
IdToken :: Text -> IdToken
[idtoken] :: IdToken -> Text

-- | Authorization Code
newtype ExchangeToken
ExchangeToken :: Text -> ExchangeToken
[extoken] :: ExchangeToken -> Text

-- | https://www.rfc-editor.org/rfc/rfc6749#section-4.1.4
data OAuth2Token
OAuth2Token :: AccessToken -> Maybe RefreshToken -> Maybe Int -> Maybe Text -> Maybe IdToken -> OAuth2Token
[accessToken] :: OAuth2Token -> AccessToken

-- | Exists when offline_access scope is in the
--   authorizeUrl and the provider supports Refresh Access Token.
[refreshToken] :: OAuth2Token -> Maybe RefreshToken
[expiresIn] :: OAuth2Token -> Maybe Int

-- | See https://www.rfc-editor.org/rfc/rfc6749#section-5.1. It's
--   required per spec. But OAuth2 provider implementation are vary. Maybe
--   will remove Maybe in future release.
[tokenType] :: OAuth2Token -> Maybe Text

-- | Exists when openid scope is in the authorizeUrl and
--   the provider supports OpenID.
[idToken] :: OAuth2Token -> Maybe IdToken

-- | https://www.rfc-editor.org/rfc/rfc6749#section-2.3 According to
--   spec:
--   
--   The client MUST NOT use more than one authentication method in each
--   request.
--   
--   Which means use Authorization header or Post body.
--   
--   However, in reality, I always have to include authentication in the
--   header.
--   
--   In other words, ClientSecrectBasic is always assured.
--   ClientSecretPost is optional.
--   
--   Maybe consider an alternative implementation that boolean kind of data
--   type is good enough.
data ClientAuthenticationMethod
ClientSecretBasic :: ClientAuthenticationMethod
ClientSecretPost :: ClientAuthenticationMethod
ClientAssertionJwt :: ClientAuthenticationMethod

-- | type synonym of post body content
type PostBody = [(ByteString, ByteString)]
type QueryParams = [(ByteString, ByteString)]
defaultRequestHeaders :: [(HeaderName, ByteString)]
appendQueryParams :: [(ByteString, ByteString)] -> URIRef a -> URIRef a
uriToRequest :: MonadThrow m => URI -> m Request
requestToUri :: Request -> URI
hostLens :: Lens' Request ByteString
portLens :: Lens' Request Int

-- | This module contains a new way of doing OAuth2 authorization and
--   authentication in order to obtain Access Token and maybe Refresh Token
--   base on rfc6749.
--   
--   This module will become default in future release. (TBD but likely
--   3.0).
--   
--   The key concept/change is to introduce the GrantTypeFlow, which
--   determines the entire work flow per spec. Each work flow will have
--   slight different request parameters, which often time you'll see
--   different configuration when creating OAuth2 application in the IdP
--   developer application page.
--   
--   Here are supported flows
--   
--   
--   
- Authorization Code. This flow requires authorize call to obtain an
--   authorize code, then exchange the code for tokens.
--   
- Resource Owner Password. This flow only requires to hit token
--   endpoint with, of course, username and password, to obtain
--   tokens.
--   
- Client Credentials. This flow also only requires to hit token
--   endpoint but with different parameters. Client credentials flow does
--   not involve an end user hence you won't be able to hit userinfo
--   endpoint with access token obtained.
--   
- PKCE (rfc7636). This is enhancement on top of authorization code
--   flow.
--   
--   
--   Implicit flow is not supported because it is more for SPA (single page
--   app) and more or less obsolete by Authorization Code flow with PKCE.
--   
--   Here is quick sample for how to use vocabularies from this new module.
--   
--   Firstly, initialize your IdP (use google as example) and the
--   application.
--   
--   
--   {-# LANGUAGE DataKinds #-}
--   
--   data Google = Google deriving (Eq, Show)
--   googleIdp :: Idp Google
--   googleIdp =
--     Idp
--       { idpFetchUserInfo = authGetJSON @(IdpUserInfo Google),
--         idpAuthorizeEndpoint = [uri|https://accounts.google.com/o/oauth2/v2/auth|],
--         idpTokenEndpoint = [uri|https://oauth2.googleapis.com/token|],
--         idpUserInfoEndpoint = [uri|https://www.googleapis.com/oauth2/v2/userinfo|]
--       }
--   
--   fooApp :: IdpApplication 'AuthorizationCode Google
--   fooApp =
--     AuthorizationCodeIdpApplication
--       { idpAppClientId = "xxxxx",
--         idpAppClientSecret = "xxxxx",
--         idpAppScope =
--           Set.fromList
--             [ "https://www.googleapis.com/auth/userinfo.email",
--               "https://www.googleapis.com/auth/userinfo.profile"
--             ],
--         idpAppAuthorizeState = "CHANGE_ME",
--         idpAppAuthorizeExtraParams = Map.empty,
--         idpAppRedirectUri = [uri|http://localhost/oauth2/callback|],
--         idpAppName = "default-google-App",
--         idpAppTokenRequestAuthenticationMethod = ClientSecretBasic,
--         idp = googleIdp
--       }
--   
--   
--   Secondly, construct the authorize URL.
--   
--   
--   authorizeUrl = mkAuthorizeRequest fooApp
--   
--   
--   Thirdly, after a successful redirect with authorize code, you could
--   exchange for access token
--   
--   
--   mgr <- liftIO $ newManager tlsManagerSettings
--   tokenResp <- conduitTokenRequest fooApp mgr authorizeCode
--   
--   
--   Lastly, you probably like to fetch user info
--   
--   
--   conduitUserInfoRequest fooApp mgr (accessToken tokenResp)
--   
--   
--   Also you could find example from hoauth2-providers-tutorials
--   module.
module Network.OAuth2.Experiment
data GrantTypeFlow

-- | https://www.rfc-editor.org/rfc/rfc6749#section-4.1
AuthorizationCode :: GrantTypeFlow

-- | https://www.rfc-editor.org/rfc/rfc6749#section-4.3
ResourceOwnerPassword :: GrantTypeFlow

-- | https://www.rfc-editor.org/rfc/rfc6749#section-4.4
ClientCredentials :: GrantTypeFlow

-- | https://www.rfc-editor.org/rfc/rfc7523.html#section-2.1
JwtBearer :: GrantTypeFlow
class ToResponseTypeValue (a :: GrantTypeFlow)
toResponseTypeValue :: (ToResponseTypeValue a, IsString b) => b
toResponseTypeParam :: forall a b req. (ToResponseTypeValue a, IsString b) => req a -> Map b b
newtype UrnOAuthParam a
UrnOAuthParam :: a -> UrnOAuthParam a

-- | Grant type query parameter has association with GrantTypeFlow
--   but not completely strict.
--   
--   e.g. Both AuthorizationCode and ResourceOwnerPassword
--   flow could support refresh token flow.
data GrantTypeValue
GTAuthorizationCode :: GrantTypeValue
GTPassword :: GrantTypeValue
GTClientCredentials :: GrantTypeValue
GTRefreshToken :: GrantTypeValue
GTJwtBearer :: GrantTypeValue
newtype Scope
Scope :: Text -> Scope
[$sel:unScope:Scope] :: Scope -> Text
newtype ClientId
ClientId :: Text -> ClientId
[$sel:unClientId:ClientId] :: ClientId -> Text

-- | Can be either "Client Secret" or JWT base on client authentication
--   method
newtype ClientSecret
ClientSecret :: Text -> ClientSecret
[$sel:unClientSecret:ClientSecret] :: ClientSecret -> Text

-- | In order to reuse some methods from legacy
--   Network.OAuth.OAuth2. Will be removed when Experiment module
--   becomes default.
toOAuth2Key :: ClientId -> ClientSecret -> OAuth2
newtype RedirectUri
RedirectUri :: URI -> RedirectUri
[$sel:unRedirectUri:RedirectUri] :: RedirectUri -> URI
newtype AuthorizeState
AuthorizeState :: Text -> AuthorizeState
[$sel:unAuthorizeState:AuthorizeState] :: AuthorizeState -> Text
newtype Username
Username :: Text -> Username
[$sel:unUsername:Username] :: Username -> Text
newtype Password
Password :: Text -> Password
[$sel:unPassword:Password] :: Password -> Text
class ToQueryParam a
toQueryParam :: ToQueryParam a => a -> Map Text Text
class HasAuthorizeRequest (a :: GrantTypeFlow) where {
    data AuthorizationRequest a;
    type MkAuthorizationRequestResponse a;
}
mkAuthorizeRequestParameter :: HasAuthorizeRequest a => IdpApplication a i -> AuthorizationRequest a
mkAuthorizeRequest :: HasAuthorizeRequest a => IdpApplication a i -> MkAuthorizationRequestResponse a
class HasTokenRequest (a :: GrantTypeFlow) where {
    
    -- | Each GrantTypeFlow has slightly different request parameter to /token
    --   endpoint.
    data TokenRequest a;
    
    -- | Only 'AuthorizationCode flow (but not resource owner password nor
    --   client credentials) will use <a>ExchangeToken</a> in the token request
    --   create type family to be explicit on it. with 'type instance
    --   WithExchangeToken a b = b' implies no exchange token v.s. 'type
    --   instance WithExchangeToken a b = ExchangeToken -&gt; b' implies
    --   needing an exchange token
    type WithExchangeToken a b;
}
mkTokenRequest :: HasTokenRequest a => IdpApplication a i -> WithExchangeToken a (TokenRequest a)
conduitTokenRequest :: (HasTokenRequest a, MonadIO m) => IdpApplication a i -> Manager -> WithExchangeToken a (ExceptT TokenRequestError m OAuth2Token)
class HasPkceAuthorizeRequest (a :: GrantTypeFlow)
mkPkceAuthorizeRequest :: (HasPkceAuthorizeRequest a, MonadIO m) => IdpApplication a i -> m (Text, CodeVerifier)
class HasPkceTokenRequest (b :: GrantTypeFlow)
conduitPkceTokenRequest :: (HasPkceTokenRequest b, MonadIO m) => IdpApplication b i -> Manager -> (ExchangeToken, CodeVerifier) -> ExceptT TokenRequestError m OAuth2Token
class HasRefreshTokenRequest (a :: GrantTypeFlow) where {
    
    -- | <a>https://www.rfc-editor.org/rfc/rfc6749#page-47</a>
    data RefreshTokenRequest a;
}
mkRefreshTokenRequest :: HasRefreshTokenRequest a => IdpApplication a i -> RefreshToken -> RefreshTokenRequest a
conduitRefreshTokenRequest :: (HasRefreshTokenRequest a, MonadIO m) => IdpApplication a i -> Manager -> RefreshToken -> ExceptT TokenRequestError m OAuth2Token
type family IdpUserInfo a
class HasUserInfoRequest (a :: GrantTypeFlow)
conduitUserInfoRequest :: (HasUserInfoRequest a, FromJSON (IdpUserInfo i)) => IdpApplication a i -> Manager -> AccessToken -> ExceptT ByteString IO (IdpUserInfo i)

-- | Shall IdpApplication has a field of 'Idp a'??
data Idp a
Idp :: URI -> URI -> URI -> (forall m. (FromJSON (IdpUserInfo a), MonadIO m) => Manager -> AccessToken -> URI -> ExceptT ByteString m (IdpUserInfo a)) -> Idp a
[$sel:idpUserInfoEndpoint:Idp] :: Idp a -> URI
[$sel:idpAuthorizeEndpoint:Idp] :: Idp a -> URI
[$sel:idpTokenEndpoint:Idp] :: Idp a -> URI
[$sel:idpFetchUserInfo:Idp] :: Idp a -> forall m. (FromJSON (IdpUserInfo a), MonadIO m) => Manager -> AccessToken -> URI -> ExceptT ByteString m (IdpUserInfo a)
data family IdpApplication (a :: GrantTypeFlow) (i :: Type)
mkPkceParam :: MonadIO m => m PkceRequestParam
newtype CodeChallenge
CodeChallenge :: Text -> CodeChallenge
[unCodeChallenge] :: CodeChallenge -> Text
newtype CodeVerifier
CodeVerifier :: Text -> CodeVerifier
[unCodeVerifier] :: CodeVerifier -> Text
data CodeChallengeMethod
S256 :: CodeChallengeMethod
data PkceRequestParam
PkceRequestParam :: CodeVerifier -> CodeChallenge -> CodeChallengeMethod -> PkceRequestParam
[codeVerifier] :: PkceRequestParam -> CodeVerifier
[codeChallenge] :: PkceRequestParam -> CodeChallenge

-- | spec says optional but really it shall be s256 or can be omitted?
--   https://datatracker.ietf.org/doc/html/rfc7636#section-4.3
[codeChallengeMethod] :: PkceRequestParam -> CodeChallengeMethod
