-- 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
--   <a>https://www.rfc-editor.org/rfc/rfc6749</a>
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
--   <a>https://tools.ietf.org/html/rfc6749#section-5.2</a>
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 <tt>code</tt> for an Access Token with authenticate in
--   request header.
fetchAccessToken :: MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenRequestError m OAuth2Token

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

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

-- | Exchange <tt>code</tt> for an Access Token
--   
--   OAuth2 spec allows credential (<tt>client_id</tt>,
--   <tt>client_secret</tt>) to be sent either in the header (a.k.a
--   <a>ClientSecretBasic</a>). or as form/url params (a.k.a
--   <a>ClientSecretPost</a>).
--   
--   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 <a>fetchAccessToken</a> 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

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

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

-- | Fetch a new AccessToken using the Refresh Token.
--   
--   OAuth2 spec allows credential (<tt>client_id</tt>,
--   <tt>client_secret</tt>) to be sent either in the header (a.k.a
--   <a>ClientSecretBasic</a>). or as form/url params (a.k.a
--   <a>ClientSecretPost</a>).
--   
--   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 <a>refreshAccessToken</a> 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 <tt>Response</tt> if 200 otherwise assume
--   <tt>OAuth2Error</tt>
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 : <tt>hoauth2</tt> + 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 <a>https://www.rfc-editor.org/rfc/rfc6750</a>
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 <a>authGetBS</a> but set access token to query parameter
--   rather than header

-- | <i>Deprecated: use authGetBSWithAuthMethod</i>
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

-- | <i>Deprecated: use authGetJSONWithAuthMethod</i>
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

-- | <i>Deprecated: use authGetBSWithAuthMethod</i>
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.

-- | <i>Deprecated: use <a>authPostBSWithAuthMethod</a></i>
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

-- | <i>Deprecated: use <a>authPostBSWithAuthMethod</a></i>
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

-- | <i>Deprecated: use <a>authPostJSONWithAuthMethod</a></i>
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

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

-- | <a>https://www.rfc-editor.org/rfc/rfc6750#section-2</a>
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 <a>https://www.rfc-editor.org/rfc/rfc6749</a>
module Network.OAuth.OAuth2.AuthorizationRequest

-- | Authorization Code Grant Error Responses
--   <a>https://tools.ietf.org/html/rfc6749#section-4.1.2.1</a> I found
--   hard time to figure a way to test the authorization error flow When
--   anything wrong in <tt>/authorize</tt> request, it will stuck at the
--   Provider page hence no way for this library to parse error response.
--   In other words, <tt>/authorize</tt> 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 <a>authorizationUrlWithParams</a>
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 <a>authorizationUrlWithParams</a>
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

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

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

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

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

-- | <a>https://www.rfc-editor.org/rfc/rfc6749#section-2.3</a> 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, <tt>ClientSecrectBasic</tt> is always assured.
--   <a>ClientSecretPost</a> 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 <a>GrantTypeFlow</a>, 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
--   
--   <ol>
--   <li>Authorization Code. This flow requires authorize call to obtain an
--   authorize code, then exchange the code for tokens.</li>
--   <li>Resource Owner Password. This flow only requires to hit token
--   endpoint with, of course, username and password, to obtain
--   tokens.</li>
--   <li>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.</li>
--   <li>PKCE (rfc7636). This is enhancement on top of authorization code
--   flow.</li>
--   </ol>
--   
--   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.
--   
--   <pre>
--   {-# 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
--       }
--   </pre>
--   
--   Secondly, construct the authorize URL.
--   
--   <pre>
--   authorizeUrl = mkAuthorizeRequest fooApp
--   </pre>
--   
--   Thirdly, after a successful redirect with authorize code, you could
--   exchange for access token
--   
--   <pre>
--   mgr &lt;- liftIO $ newManager tlsManagerSettings
--   tokenResp &lt;- conduitTokenRequest fooApp mgr authorizeCode
--   </pre>
--   
--   Lastly, you probably like to fetch user info
--   
--   <pre>
--   conduitUserInfoRequest fooApp mgr (accessToken tokenResp)
--   </pre>
--   
--   Also you could find example from <tt>hoauth2-providers-tutorials</tt>
--   module.
module Network.OAuth2.Experiment
data GrantTypeFlow

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

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

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

-- | <a>https://www.rfc-editor.org/rfc/rfc7523.html#section-2.1</a>
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 <a>GrantTypeFlow</a>
--   but not completely strict.
--   
--   e.g. Both <a>AuthorizationCode</a> and <a>ResourceOwnerPassword</a>
--   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
--   <a>Network.OAuth.OAuth2</a>. 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?
--   <a>https://datatracker.ietf.org/doc/html/rfc7636#section-4.3</a>
[codeChallengeMethod] :: PkceRequestParam -> CodeChallengeMethod
