@@ -20,6 +20,7 @@ import Data.Either (Either(..))
2020import Data.HCaptcha (bindHCaptchToken)
2121import Data.JNullable (jnull, nullify)
2222import Data.Maybe (Maybe(..))
23+import Data.Newtype (wrap)
2324import Data.OpenURL (openURL)
2425import Data.Ord.Down (Down(..))
2526import Data.SymmetricCryptoKey (SymmetricCryptoKey)
@@ -38,6 +39,7 @@ import FFI as FFI
3839import Localstorage (class StorageKey)
3940import Localstorage as Storage
4041import Storage (MasterPasswordHashKey(..), PreloginResponseKey(..), SyncKey(..), TokenKey(..), UrlsKey(..))
42+import Untagged.Union (toEither1)
4143import Web.HTML as Html
4244import Web.HTML.Window as Window
4345import Web.Storage.Storage (Storage)
@@ -49,7 +51,10 @@ main = do
4951 storage <- Html.window >>= Window.localStorage
5052 services <- WB.getServices
5153 masterKeyRef <- Ref.new Nothing
52− bindHCaptchToken log
54+ hCaptchaTokenRef <- Ref.new Nothing
55+ bindHCaptchToken \captchaToken -> do
56+ Ref.write (Just captchaToken) hCaptchaTokenRef
57+ Elm.send app Bridge.CaptchaDone
5358 let
5459 run act = do
5560 maybeKey <- Ref.read masterKeyRef
@@ -69,6 +74,8 @@ main = do
6974 Nothing -> requestMasterPassword
7075 Elm.subscribe app \cmd -> case cmd of
7176 Bridge.Login (Bridge.Cmd_Login { email, server, password }) -> do
77+ captchaToken <- Ref.read hCaptchaTokenRef
78+ Ref.write Nothing hCaptchaTokenRef
7279 let
7380 urls = baseUrl server
7481 runElmAff app do
@@ -82,23 +89,28 @@ main = do
8289 }
8390 flip runReaderT env do
8491 prelogin <- liftPromise $ unauthedApi.postPrelogin { email }
85− token <-
92+ loginResponse <-
8693 catchError
87− (Logic.getLogInRequestToken prelogin (Email email) (Password password))
94+ (Logic.getLogInRequestToken prelogin (Email email) (Password password) captchaToken)
8895 (const $ liftEffect $ Exc.throw "Could not log in. Please check your data and try again.")
89− masterKey <- Logic.makePreloginKey prelogin (Email email) (Password password)
90− api <- liftPromise $ services.getApi urls (nullify token)
91− sync <- liftPromise $ api.getSync unit
92− hash <- hashPassword (Password password)
93− log $ show sync
94− liftEffect do
95− Ref.write (Just masterKey) masterKeyRef
96− Storage.store storage UrlsKey server
97− Storage.store storage MasterPasswordHashKey hash
98− Storage.store storage PreloginResponseKey prelogin
99− Storage.store storage SyncKey sync
100− Storage.store storage TokenKey token
101− Elm.send app Bridge.LoginSuccessful
96+ case toEither1 loginResponse of
97+ Left { siteKey } ->
98+ liftEffect do
99+ Elm.send app $ Bridge.NeedsCaptcha siteKey
100+ Right token -> do
101+ masterKey <- Logic.makePreloginKey prelogin (Email email) (Password password)
102+ api <- liftPromise $ services.getApi urls (nullify token)
103+ sync <- liftPromise $ api.getSync unit
104+ hash <- hashPassword (Password password)
105+ log $ show sync
106+ liftEffect do
107+ Ref.write (Just masterKey) masterKeyRef
108+ Storage.store storage UrlsKey server
109+ Storage.store storage MasterPasswordHashKey hash
110+ Storage.store storage PreloginResponseKey prelogin
111+ Storage.store storage SyncKey sync
112+ Storage.store storage TokenKey token
113+ Elm.send app Bridge.LoginSuccessful
102114 Bridge.NeedCiphersList ->
103115 run do
104116 sync <- getOrReset SyncKey