{-# LANGUAGE QuasiQuotes #-}

-- | [Facebook Login](http://developers.facebook.com/docs/facebook-login/)
module Network.OAuth2.Provider.Facebook 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 (Manager)
import Network.OAuth.OAuth2
import Network.OAuth2.Experiment
import Network.OAuth2.Provider
import URI.ByteString.QQ

sampleFacebookAuthorizationCodeApp :: AuthorizationCodeApplication
sampleFacebookAuthorizationCodeApp :: AuthorizationCodeApplication
sampleFacebookAuthorizationCodeApp =
  AuthorizationCodeApplication
    { acClientId :: ClientId
acClientId = ClientId
""
    , acClientSecret :: ClientSecret
acClientSecret = ClientSecret
""
    , acScope :: Set Scope
acScope = [Scope] -> Set Scope
forall a. Ord a => [a] -> Set a
Set.fromList [Scope
"user_about_me", Scope
"email"]
    , acAuthorizeRequestExtraParams :: Map Text Text
acAuthorizeRequestExtraParams = Map Text Text
forall k a. Map k a
Map.empty
    , acAuthorizeState :: AuthorizeState
acAuthorizeState = AuthorizeState
"CHANGE_ME"
    , acRedirectUri :: URI
acRedirectUri = [uri|http://localhost|]
    , acName :: Text
acName = Text
"sample-facebook-authorization-code-app"
    , acTokenRequestAuthenticationMethod :: ClientAuthenticationMethod
acTokenRequestAuthenticationMethod = ClientAuthenticationMethod
ClientSecretPost
    }

fetchUserInfo ::
  (MonadIO m, HasUserInfoRequest a, FromJSON b) =>
  IdpApplication i a ->
  Manager ->
  AccessToken ->
  ExceptT BSL.ByteString m b
fetchUserInfo :: forall {k} (m :: * -> *) a b (i :: k).
(MonadIO m, HasUserInfoRequest a, FromJSON b) =>
IdpApplication i a
-> Manager -> AccessToken -> ExceptT ByteString m b
fetchUserInfo = IdpApplication i a
-> Manager -> AccessToken -> ExceptT ByteString m b
forall {k} (m :: * -> *) a b (i :: k).
(MonadIO m, HasUserInfoRequest a, FromJSON b) =>
IdpApplication i a
-> Manager -> AccessToken -> ExceptT ByteString m b
conduitUserInfoRequest

defaultFacebookIdp :: Idp Facebook
defaultFacebookIdp :: Idp 'Facebook
defaultFacebookIdp =
  Idp
    { idpUserInfoEndpoint :: URI
idpUserInfoEndpoint = [uri|https://graph.facebook.com/me?fields=id,name,email|]
    , idpAuthorizeEndpoint :: URI
idpAuthorizeEndpoint = [uri|https://www.facebook.com/dialog/oauth|]
    , idpTokenEndpoint :: URI
idpTokenEndpoint = [uri|https://graph.facebook.com/v2.3/oauth/access_token|]
    , idpDeviceAuthorizationEndpoint :: Maybe URI
idpDeviceAuthorizationEndpoint = Maybe URI
forall a. Maybe a
Nothing
    }

data FacebookUser = FacebookUser
  { FacebookUser -> Text
id :: Text
  , FacebookUser -> Text
name :: Text
  , FacebookUser -> Text
email :: Text
  }
  deriving (Int -> FacebookUser -> ShowS
[FacebookUser] -> ShowS
FacebookUser -> String
(Int -> FacebookUser -> ShowS)
-> (FacebookUser -> String)
-> ([FacebookUser] -> ShowS)
-> Show FacebookUser
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FacebookUser -> ShowS
showsPrec :: Int -> FacebookUser -> ShowS
$cshow :: FacebookUser -> String
show :: FacebookUser -> String
$cshowList :: [FacebookUser] -> ShowS
showList :: [FacebookUser] -> ShowS
Show, (forall x. FacebookUser -> Rep FacebookUser x)
-> (forall x. Rep FacebookUser x -> FacebookUser)
-> Generic FacebookUser
forall x. Rep FacebookUser x -> FacebookUser
forall x. FacebookUser -> Rep FacebookUser x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FacebookUser -> Rep FacebookUser x
from :: forall x. FacebookUser -> Rep FacebookUser x
$cto :: forall x. Rep FacebookUser x -> FacebookUser
to :: forall x. Rep FacebookUser x -> FacebookUser
Generic)

instance FromJSON FacebookUser