Support echo server to test POST /verify

TL;DR:
- Add common dependencies like Servant, Aeson, Warp, Cors
- Define a POST /verify endpoint for our client to hit
- POST to /verify client-side onSignIn
This commit is contained in:
William Carroll 2020-08-06 22:21:30 +01:00
parent 1fc1087014
commit a7ddb56b9b
5 changed files with 79 additions and 8 deletions

View file

@ -5,8 +5,12 @@ in pkgs.mkShell {
elmPackages.elm elmPackages.elm
elmPackages.elm-format elmPackages.elm-format
elmPackages.elm-live elmPackages.elm-live
(haskellPackages.ghcWithPackages (hpkgs: with hpkgs; [ (haskellPackages.ghcWithPackages (hpkgs: [
hspec hpkgs.hspec
hpkgs.servant-server
hpkgs.aeson
hpkgs.wai-cors
hpkgs.warp
])) ]))
]; ];
} }

View file

@ -0,0 +1,15 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
--------------------------------------------------------------------------------
module API where
--------------------------------------------------------------------------------
import Data.Text
import Servant.API
import Web.Cookie
import qualified Types as T
--------------------------------------------------------------------------------
type API = "verify"
:> ReqBody '[JSON] T.VerifyGoogleSignInRequest
:> Post '[JSON] NoContent

View file

@ -1,6 +1,35 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE RecordWildCards #-}
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
module Main where module Main where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Servant
import API
import Control.Monad.IO.Class (liftIO)
import qualified Network.Wai.Handler.Warp as Warp
import qualified Network.Wai.Middleware.Cors as Cors
import qualified Types as T
--------------------------------------------------------------------------------
server :: Server API
server = verifyGoogleSignIn
where
verifyGoogleSignIn :: T.VerifyGoogleSignInRequest -> Handler NoContent
verifyGoogleSignIn T.VerifyGoogleSignInRequest{..} = do
liftIO $ putStrLn $ "Received: " ++ idToken
pure NoContent
main :: IO () main :: IO ()
main = putStrLn "Working!" main = do
Warp.run 3000 (enforceCors $ serve (Proxy @ API) $ server)
where
enforceCors = Cors.cors (const $ Just corsPolicy)
corsPolicy :: Cors.CorsResourcePolicy
corsPolicy =
Cors.simpleCorsResourcePolicy
{ Cors.corsOrigins = Just (["http://localhost:8000"], True)
, Cors.corsMethods = Cors.simpleMethods ++ ["PUT", "PATCH", "DELETE", "OPTIONS"]
, Cors.corsRequestHeaders = Cors.simpleHeaders ++ ["Content-Type", "Authorization"]
}

View file

@ -0,0 +1,16 @@
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
--------------------------------------------------------------------------------
module Types where
--------------------------------------------------------------------------------
import Data.Aeson
--------------------------------------------------------------------------------
data VerifyGoogleSignInRequest = VerifyGoogleSignInRequest
{ idToken :: String
} deriving (Eq, Show)
instance FromJSON VerifyGoogleSignInRequest where
parseJSON = withObject "" $ \x -> do
idToken <- x .: "idToken"
pure VerifyGoogleSignInRequest{..}

View file

@ -11,11 +11,18 @@
<a href="#" onclick="signOut();">Sign out</a> <a href="#" onclick="signOut();">Sign out</a>
<script> <script>
function onSignIn(googleUser) { function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile(); var idToken = googleUser.getAuthResponse().id_token;
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead. fetch('http://localhost:3000/verify', {
console.log('Name: ' + profile.getName()); method: 'POST',
console.log('Image URL: ' + profile.getImageUrl()); headers: {
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present. 'Content-Type': 'application/json',
},
body: JSON.stringify({
idToken: idToken,
})
})
.then(x => console.log(x))
.catch(err => console.error(err));
} }
function signOut() { function signOut() {
var auth2 = gapi.auth2.getAuthInstance(); var auth2 = gapi.auth2.getAuthInstance();