From bb4b27f1d98fc376083cabb5033e1ac68e9524c4 Mon Sep 17 00:00:00 2001 From: Henry Laxen Date: Sat, 29 Mar 2025 15:20:35 -0700 Subject: [PATCH 1/2] compiles with 9.10.1 with no warning or errors --- realworld-hs.cabal | 7 +++---- .../Articles/Articles/FeedArticles.hs | 5 ++--- .../Articles/Articles/ListArticles.hs | 3 +-- src/Conduit/Identity/JWT.hs | 4 ++-- src/Conduit/Identity/Password.hs | 20 ++++++++++++++++--- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/realworld-hs.cabal b/realworld-hs.cabal index 5001e88..248e160 100644 --- a/realworld-hs.cabal +++ b/realworld-hs.cabal @@ -85,7 +85,6 @@ library TypeFamilies GADTs ViewPatterns - NoFieldSelectors ghc-options: -Wall -Wno-orphans -Wno-unrecognised-pragmas -O1 build-depends: aeson @@ -113,7 +112,7 @@ library mixins: base hiding (Prelude) , relude (Relude as Prelude) - , relude + , relude default-language: GHC2021 executable app @@ -169,7 +168,7 @@ executable app mixins: base hiding (Prelude) , relude (Relude as Prelude) - , relude + , relude default-language: GHC2021 test-suite spec @@ -232,5 +231,5 @@ test-suite spec mixins: base hiding (Prelude) , relude (Relude as Prelude) - , relude + , relude default-language: GHC2021 diff --git a/src/Conduit/Features/Articles/Articles/FeedArticles.hs b/src/Conduit/Features/Articles/Articles/FeedArticles.hs index 5f52950..b28a661 100644 --- a/src/Conduit/Features/Articles/Articles/FeedArticles.hs +++ b/src/Conduit/Features/Articles/Articles/FeedArticles.hs @@ -17,9 +17,8 @@ import Conduit.Utils ((.-)) import Data.List (lookup) import Database.Esqueleto.Experimental (groupBy, in_, limit, offset, orderBy, select, val, valList, where_, (:&)(..), (==.)) import Database.Esqueleto.Experimental qualified as E -import Relude.Extra (bimapBoth) import UnliftIO (MonadUnliftIO) -import Web.Scotty.Trans (ActionT, ScottyT, captureParams, get, json) +import Web.Scotty.Trans.Strict (ActionT, ScottyT, captureParams, get, json) data FilterOps = FilterOps { filterLimit :: Int64 @@ -39,7 +38,7 @@ getFeedArticles userID ops = runExceptT do parseFilterOps :: ActionT AppM FilterOps parseFilterOps = do - params <- captureParams <&> map (bimapBoth toStrict) + params <- captureParams pure $ FilterOps { filterLimit = (lookup "limit" params >>= toString .- readMaybe) ?: 20 diff --git a/src/Conduit/Features/Articles/Articles/ListArticles.hs b/src/Conduit/Features/Articles/Articles/ListArticles.hs index 407c340..46361e2 100644 --- a/src/Conduit/Features/Articles/Articles/ListArticles.hs +++ b/src/Conduit/Features/Articles/Articles/ListArticles.hs @@ -19,7 +19,6 @@ import Data.Text.Lazy.Builder qualified as TB import Database.Esqueleto.Experimental (exists, from, groupBy, in_, just, leftJoin, limit, offset, on, orderBy, select, subSelectList, table, val, valList, where_, (:&) (..), (==.)) import Database.Esqueleto.Experimental qualified as E import Database.Esqueleto.Internal.Internal (unsafeSqlValue) -import Relude.Extra (bimapBoth) import UnliftIO (MonadUnliftIO) import Web.Scotty.Trans (ActionT, ScottyT, captureParams, get, json) @@ -39,7 +38,7 @@ handleListArticles = get "/api/articles/" $ maybeWithAuth \user -> do parseFilterOps :: ActionT AppM FilterOps parseFilterOps = do - params <- captureParams <&> map (bimapBoth toStrict) + params <- captureParams pure $ FilterOps { filterTag = lookup "tag" params diff --git a/src/Conduit/Identity/JWT.hs b/src/Conduit/Identity/JWT.hs index b5fb026..c23a94f 100644 --- a/src/Conduit/Identity/JWT.hs +++ b/src/Conduit/Identity/JWT.hs @@ -1,6 +1,6 @@ module Conduit.Identity.JWT where -import Conduit.Features.Account.Types (UserID, unID) +import Conduit.Features.Account.Types (UserID(..)) import Data.Aeson (FromJSON) import Data.Time (NominalDiffTime) import Web.JWT (EncodeSigner, JWTClaimsSet(..), VerifySigner, hmacSecret, numericDate, stringOrURI, toVerify) @@ -41,6 +41,6 @@ mkClaims :: NominalDiffTime -> Seconds -> UserID -> JWTClaimsSet mkClaims currTime (Seconds ttl) userID = mempty { iss = stringOrURI "conduit-api" , aud = Left <$> stringOrURI "conduit-client" - , sub = stringOrURI $ show userID.unID + , sub = stringOrURI $ show (unID userID) , exp = numericDate $ currTime + fromIntegral ttl } diff --git a/src/Conduit/Identity/Password.hs b/src/Conduit/Identity/Password.hs index b3d643d..7e5f258 100644 --- a/src/Conduit/Identity/Password.hs +++ b/src/Conduit/Identity/Password.hs @@ -1,4 +1,5 @@ {-# LANGUAGE UndecidableInstances, FieldSelectors #-} +{-# LANGUAGE CPP #-} module Conduit.Identity.Password ( HashedPassword(..) @@ -15,7 +16,10 @@ import Crypto.KDF.Argon2 qualified as Argon import Crypto.Random (MonadRandom (getRandomBytes)) import Data.Aeson (FromJSON) import Data.ByteArray (Bytes, convert) -import Data.ByteString.Base64 (decodeBase64, encodeBase64) +import Data.ByteString.Base64 -- (decodeBase64, encodeBase64) +#if MIN_VERSION_base64(1,0,0) +import Data.Base64.Types +#endif import Data.Text (splitOn) import Relude.Unsafe as Unsafe ((!!)) @@ -45,7 +49,7 @@ argonOptions = defaultOptions { variant = Argon2id , parallelism = 2 , iterations = 2 - , memory = 65536 + , memory = 65536 } hashStrParams :: Text @@ -56,7 +60,11 @@ newSalt :: (MonadIO m) => m ByteString newSalt = liftIO $ getRandomBytes 16 extractSalt :: HashedPassword -> Maybe ByteString +#if MIN_VERSION_base64(1,0,0) +extractSalt (HashedPassword hash') = rightToMaybe . decodeBase64Untyped . encodeUtf8 $ splitOn "$" hash' Unsafe.!! 4 +#else extractSalt (HashedPassword hash') = rightToMaybe . decodeBase64 . encodeUtf8 $ splitOn "$" hash' Unsafe.!! 4 +#endif text2bytes :: Text -> Bytes text2bytes = convert . encodeUtf8 @_ @ByteString @@ -69,7 +77,13 @@ hashPasswordWithSalt (UnsafePassword password) salt = in mkHashedPassword (convert digest) salt mkHashedPassword :: ByteString -> ByteString -> HashedPassword -mkHashedPassword digest salt = HashedPassword $ hashStrParams <> salt' <> "$" <> digest' +#if MIN_VERSION_base64(1,0,0) +mkHashedPassword digest salt = HashedPassword $ + hashStrParams <> extractBase64 salt' <> "$" <> extractBase64 digest' +#else +mkHashedPassword digest salt = HashedPassword $ + hashStrParams <> salt' <> "$" <> digest' +#endif where digest' = encodeBase64 digest; salt' = encodeBase64 salt; -- | Validates a plaintext password against its hashed potential counterpart. From fda7acf17fc1bf5b3843fa5484022d1c4a83dd6e Mon Sep 17 00:00:00 2001 From: Henry Laxen Date: Sat, 29 Mar 2025 15:25:43 -0700 Subject: [PATCH 2/2] removed import list from Base64 in Password.hs --- src/Conduit/Identity/Password.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Conduit/Identity/Password.hs b/src/Conduit/Identity/Password.hs index 7e5f258..2e8eff8 100644 --- a/src/Conduit/Identity/Password.hs +++ b/src/Conduit/Identity/Password.hs @@ -16,7 +16,7 @@ import Crypto.KDF.Argon2 qualified as Argon import Crypto.Random (MonadRandom (getRandomBytes)) import Data.Aeson (FromJSON) import Data.ByteArray (Bytes, convert) -import Data.ByteString.Base64 -- (decodeBase64, encodeBase64) +import Data.ByteString.Base64 #if MIN_VERSION_base64(1,0,0) import Data.Base64.Types #endif