From 648459c488ad5fd3ed95685a0de7767712d8e1cd Mon Sep 17 00:00:00 2001 From: iko Date: Sat, 26 Nov 2022 08:00:29 +0000 Subject: [PATCH] Fixed 2FA login with Bitwarden server (#37) --- .gitignore | 2 ++ backend/BW/Types.purs | 19 ++++++++++++++----- backend/Data/SymmetricCryptoKey.js | 3 +-- backend/Main.purs | 23 +++++++++-------------- dev/build-backend.sh | 2 +- dev/elm-live.sh | 2 +- spago.dhall | 2 +- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 15a1501..e917c57 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ node_modules/ /tests/test-results/ /tests/playwright-report/ /tests/playwright/.cache/ +generated-docs +backend.js.map diff --git a/backend/BW/Types.purs b/backend/BW/Types.purs index 5e146eb..772448b 100644 --- a/backend/BW/Types.purs +++ b/backend/BW/Types.purs @@ -4,19 +4,22 @@ import Prelude import Bridge as Bridge import Data.Argonaut (class DecodeJson, class EncodeJson) +import Data.Either (Either) +import Data.Either as Either +import Data.Int as Int import Data.JNullable (JNullable) import Data.JOpt (JOpt) import Data.Maybe (Maybe(..)) import Data.ShowableJson (ShowableJson) import Data.Timestamp (Timestamp) -import Data.Traversable (traverse) -import Foreign (Foreign) +import Data.Traversable (for) +import Data.Tuple.Nested ((/\)) import Foreign as Foreign -import Foreign.Object (Object) import Literals.Undefined (Undefined) import Type.Prelude (Proxy(..)) -import Untagged.TypeCheck (class HasRuntimeType, hasRuntimeType) +import Untagged.TypeCheck (class HasRuntimeType) import Untagged.Union (type (|+|)) +import Untagged.Union as Union newtype EncryptedString = EncryptedString String @@ -400,11 +403,17 @@ type IdentityTokenResponse , keyConnectorUrl :: JNullable String } -newtype TwoFactorProviderTypes = TwoFactorProviderTypes (Array TwoFactorProviderType) +newtype TwoFactorProviderTypes = TwoFactorProviderTypes (Array (Int |+| String)) instance HasRuntimeType TwoFactorProviderTypes where hasRuntimeType Proxy = Foreign.isArray +fromTwoFactorProviderType :: TwoFactorProviderTypes -> Either String (Array Bridge.TwoFactorProviderType) +fromTwoFactorProviderType (TwoFactorProviderTypes xs) = + for xs $ \rawProvider -> do + providerInt <- Union.reduce (Either.Right /\ (\x -> Either.note x $ Int.fromString x)) rawProvider + Either.note (show providerInt) $ secondFactorTypeToBridge providerInt + type IdentityTwoFactorResponse = { twoFactorProviders :: TwoFactorProviderTypes -- it is a Map type and untaged unions gets confused diff --git a/backend/Data/SymmetricCryptoKey.js b/backend/Data/SymmetricCryptoKey.js index 0adc5bf..30b12a3 100644 --- a/backend/Data/SymmetricCryptoKey.js +++ b/backend/Data/SymmetricCryptoKey.js @@ -1,6 +1,5 @@ -import { SymmetricCryptoKey } from '../../deps/bw/libs/shared/dist/src/models/domain/symmetricCryptoKey.js'; +import { SymmetricCryptoKey } from '../../deps/bw/libs/shared/dist/src/models/domain/symmetricCryptoKey.js' export function fromArrayBuffer(arr) { - console.log("fromArrayBuffer " + arr) return new SymmetricCryptoKey(arr) } diff --git a/backend/Main.purs b/backend/Main.purs index 0126515..d4e106f 100644 --- a/backend/Main.purs +++ b/backend/Main.purs @@ -3,14 +3,14 @@ module Main ) where import Prelude + import BW (ApiService, CryptoFunctions, Services, CryptoService) import BW as WB import BW.Logic (bwPasswordStringHash, decodeCipher, decrypt, encodeCipher, hashPassword, liftPromise) import BW.Logic as Logic -import BW.Types (CipherResponse, Email(..), Password(..), TwoFactorProviderTypes(..), Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote, secondFactorTypeToBridge) +import BW.Types (CipherResponse, Email(..), Password(..), Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote, fromTwoFactorProviderType) import Bridge as Bridge -import Control.Monad.Error.Class (catchError, throwError) -import Control.Monad.Error.Class as Error +import Control.Monad.Error.Class (catchError) import Data.Argonaut (class DecodeJson) import Data.Array as Array import Data.Clipboard as Clipboard @@ -29,7 +29,7 @@ import Effect (Effect) import Effect.Aff (Aff, runAff_, try) import Effect.Class (liftEffect) import Effect.Class.Console (log) -import Effect.Exception (error) +import Effect.Exception (throw) import Effect.Exception as Exc import Effect.Ref as Ref import Elm as Elm @@ -149,20 +149,15 @@ main = do Storage.store storage SyncKey sync Storage.store storage TokenKey token send Bridge.LoginSuccessful - Right (Right (Left { twoFactorProviders: TwoFactorProviderTypes rawProviders, captchaToken })) -> do + Right (Right (Left { twoFactorProviders, captchaToken })) -> do case toEither1 captchaToken of Left captchaTokenString -> liftEffect $ Ref.write (Just captchaTokenString) hCaptchaTokenRef Right _ -> pure unit - providers <- - liftEffect - $ traverse - ( \x -> - secondFactorTypeToBridge x - # Error.liftMaybe (error $ "Unknown second factor provider: " <> show x) - ) - rawProviders + providers <- case fromTwoFactorProviderType twoFactorProviders of + Left x -> liftEffect $ throw $ "Unknown second factor provider: " <> x + Right x -> pure x send $ Bridge.NeedsSecondFactor $ Bridge.Sub_NeedsSecondFactor_List providers Bridge.NeedCiphersList -> runWithDecryptionKey do @@ -291,7 +286,7 @@ processCipher cipher = do | n == cipherTypeCard -> pure Bridge.CardType n | n == cipherTypeIdentity -> pure Bridge.IdentityType - n -> liftEffect $ throwError $ error $ "Unsupported cipher type: " <> show n + n -> liftEffect $ throw $ "Unsupported cipher type: " <> show n date <- liftEffect $ maybe (pure bottom) (Timestamp.toDateTime) $ JNullable.toMaybe cipher.revisionDate pure $ { cipher: diff --git a/dev/build-backend.sh b/dev/build-backend.sh index 699a19d..310fb3a 100755 --- a/dev/build-backend.sh +++ b/dev/build-backend.sh @@ -1,3 +1,3 @@ #!/bin/sh -spago bundle-app --to backend.js +spago bundle-app --source-maps --purs-args "-g sourcemaps" --to backend.js diff --git a/dev/elm-live.sh b/dev/elm-live.sh index e9978fc..5f1f4fa 100755 --- a/dev/elm-live.sh +++ b/dev/elm-live.sh @@ -1,3 +1,3 @@ #!/bin/sh -nix run github:NixOS/nixpkgs?rev=d9a1414346059619d9e13ab93e749bbb82e5252a#elmPackages.elm-live -- $1 --start-page=index.html --proxy-prefix=/api --proxy-host=http://localhost:6009 --pushstate -- --debug --output=elm.js +nix run github:NixOS/nixpkgs?rev=d9a1414346059619d9e13ab93e749bbb82e5252a#elmPackages.elm-live -- $1 --start-page=index.html --proxy-prefix=/api --proxy-host=http://localhost:6009 -- --debug --output=elm.js diff --git a/spago.dhall b/spago.dhall index cdd38dc..8aedb33 100644 --- a/spago.dhall +++ b/spago.dhall @@ -29,8 +29,8 @@ to generate this file without the comments in this block. , "exceptions" , "foldable-traversable" , "foreign" - , "foreign-object" , "functions" + , "integers" , "literals" , "maybe" , "newtype"