diff --git a/src/Conduit/AppM.purs b/src/Conduit/AppM.purs index ce598e7..f0cf50e 100644 --- a/src/Conduit/AppM.purs +++ b/src/Conduit/AppM.purs @@ -17,6 +17,7 @@ import Conduit.Capability.Routing (class MonadRouting) import Conduit.Capability.Routing as Routing import Conduit.Component.Auth (AuthIO) import Conduit.Component.Routing (RoutingIO) +import Conduit.Config as Config import Conduit.Data.Article (Article, ArticleRep, articleCodec, defaultArticlesQuery, mkArticleRepCodec) import Conduit.Data.Auth (toAuth) import Conduit.Data.Comment (Comment, commentCodec) @@ -29,13 +30,14 @@ import Control.Monad.Reader (ReaderT, ask, asks, runReaderT) import Data.Codec.Argonaut (JsonCodec) import Data.Codec.Argonaut as CA import Data.Codec.Argonaut.Record as CAR -import Data.Either (Either) +import Data.Either (Either, isLeft, fromLeft, hush) import Data.Foldable (for_) import Data.HTTP.Method (Method(..)) import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Aff.Class (class MonadAff) import Effect.Class (class MonadEffect, liftEffect) +import Effect.Class.Console as Console import Effect.Exception as Exception import React.Halo as Halo import Record as Record @@ -102,12 +104,18 @@ instance UserRepository AppM where loginUser credentials = do (res :: Either Error { user :: CurrentUser }) <- makeRequest POST (StatusCode 200) Endpoint.Login loginBodyCodec userResponseCodec { user: credentials } for_ res \{ user: currentUser } -> do - Auth.modify $ const $ toAuth currentUser.token (Just $ Record.delete (Proxy :: _ "token") currentUser) + let auth = toAuth currentUser.token (Just $ Record.delete (Proxy :: _ "token") currentUser) + when (isLeft auth && Config.nodeEnv /= "production") do + Console.log $ fromLeft "" auth + Auth.modify $ const $ hush auth pure $ res <#> _.user registerUser user = do (res :: Either Error { user :: CurrentUser }) <- makeRequest POST (StatusCode 200) Endpoint.Users registerBodyCodec userResponseCodec { user } for_ res \{ user: currentUser } -> do - Auth.modify $ const $ toAuth currentUser.token (Just $ Record.delete (Proxy :: _ "token") currentUser) + let auth = toAuth currentUser.token (Just $ Record.delete (Proxy :: _ "token") currentUser) + when (isLeft auth && Config.nodeEnv /= "production") do + Console.log $ fromLeft "" auth + Auth.modify $ const $ hush auth pure $ res <#> _.user updateUser user = do (res :: Either Error { user :: CurrentUser }) <- makeSecureRequest PUT (StatusCode 200) Endpoint.User updateUserBodyCodec userResponseCodec { user } diff --git a/src/Conduit/Component/Auth.purs b/src/Conduit/Component/Auth.purs index e82188a..bffeb74 100644 --- a/src/Conduit/Component/Auth.purs +++ b/src/Conduit/Component/Auth.purs @@ -4,11 +4,12 @@ import Prelude import Affjax.StatusCode (StatusCode(..)) import Conduit.Api.Client (Error, makeSecureRequest') import Conduit.Api.Endpoint as Endpoint +import Conduit.Config as Config import Conduit.Data.Auth (Auth, toAuth) import Conduit.Data.User (CurrentUser, currentUserCodec) import Data.Codec.Argonaut as CA import Data.Codec.Argonaut.Record as CAR -import Data.Either (Either, hush) +import Data.Either (Either, isLeft, fromLeft, hush) import Data.Foldable (for_, traverse_) import Data.HTTP.Method (Method(..)) import Data.Maybe (Maybe(..)) @@ -16,6 +17,7 @@ import Data.Tuple.Nested (type (/\), (/\)) import Effect (Effect) import Effect.Aff (launchAff_) import Effect.Class (liftEffect) +import Effect.Class.Console as Console import Effect.Ref as Ref import Effect.Timer as Timer import Foreign.Day (now) @@ -71,7 +73,9 @@ mkAuthManager = do load = do localStorage <- Window.localStorage =<< window item <- Storage.getItem "token" localStorage - pure $ flip toAuth Nothing =<< item + pure $ flip toAuth' Nothing =<< item + where + toAuth' token user = hush $ toAuth token user save = case _ of Nothing -> do @@ -92,4 +96,8 @@ mkAuthManager = do (res :: Either Error { user :: CurrentUser }) <- makeSecureRequest' token GET (StatusCode 200) Endpoint.User CA.null (CAR.object "UserResponse" { user: currentUserCodec }) unit liftEffect case hush $ _.user <$> res of Nothing -> void $ modify $ const Nothing - Just user -> void $ modify $ const $ toAuth user.token (Just $ Record.delete (Proxy :: Proxy "token") user) + Just user -> do + let auth' = toAuth user.token (Just $ Record.delete (Proxy :: _ "token") user) + when (isLeft auth' && Config.nodeEnv /= "production") do + Console.log $ fromLeft "" auth' + void $ modify $ const $ hush auth' diff --git a/src/Conduit/Data/Auth.purs b/src/Conduit/Data/Auth.purs index 73dd8f3..57ff428 100644 --- a/src/Conduit/Data/Auth.purs +++ b/src/Conduit/Data/Auth.purs @@ -4,7 +4,7 @@ import Prelude import Conduit.Data.Jwt as Jwt import Conduit.Data.User (User) import Conduit.Data.Username (Username) -import Data.Either (hush) +import Data.Either (Either(..)) import Data.Maybe (Maybe) import Data.Time.Duration (Milliseconds(..)) import Foreign.Day (DateTime, fromMilliseconds) @@ -17,7 +17,10 @@ type Auth = } -- | Helpers -toAuth :: String -> Maybe User -> Maybe Auth +toAuth :: String -> Maybe User -> Either String Auth toAuth token user = do - { exp, username } <- hush $ Jwt.decode token - pure { token, username, expirationTime: fromMilliseconds $ Milliseconds $ exp * 1000.0, user } + let jwt = Jwt.decode token + case jwt of + Left e -> Left $ show e + Right { exp, username } -> + pure { token, username, expirationTime: fromMilliseconds $ Milliseconds $ exp * 1000.0, user } diff --git a/src/Conduit/Data/Jwt.purs b/src/Conduit/Data/Jwt.purs index aed1f94..16e958d 100644 --- a/src/Conduit/Data/Jwt.purs +++ b/src/Conduit/Data/Jwt.purs @@ -24,6 +24,12 @@ data Error | JSONParseError String | JSONDecodeError CA.JsonDecodeError +instance showError :: Show Error where + show (MalformedToken) = "MalformedToken" + show (Base64DecodeError e) = "Base64DecodeError: " <> (show e) + show (JSONParseError e) = "JSONParseError: " <> e + show (JSONDecodeError e) = "JSONDecodeError: " <> (show e) + -- | Helpers decode :: String -> Either Error Jwt decode =