Commit 692e71f7 authored by Alexandre Delanoë's avatar Alexandre Delanoë

Merge remote-tracking branch 'origin/397-dev-lost-password' into dev-merge

parents 362ca6e2 4b57ade3
...@@ -12,6 +12,8 @@ import Effect.Aff (launchAff_) ...@@ -12,6 +12,8 @@ import Effect.Aff (launchAff_)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.Components.Bootstrap as B import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Login.Form (form) import Gargantext.Components.Login.Form (form)
import Gargantext.Components.Login.ForgotPassword (forgotPassword)
import Gargantext.Components.Login.Types (FormType(..))
import Gargantext.Components.NgramsTable.Loader as NTL import Gargantext.Components.NgramsTable.Loader as NTL
import Gargantext.Ends (Backend(..)) import Gargantext.Ends (Backend(..))
import Gargantext.Hooks.Loader as GHL import Gargantext.Hooks.Loader as GHL
...@@ -39,12 +41,13 @@ type Props = ...@@ -39,12 +41,13 @@ type Props =
login :: R2.Leaf Props login :: R2.Leaf Props
login = R2.leaf loginCpt login = R2.leaf loginCpt
loginCpt :: R.Component Props loginCpt :: R.Component Props
loginCpt = here.component "login" cpt where loginCpt = here.component "login" cpt where
cpt props@{ sessions, visible } _ = do cpt props@{ sessions, visible } _ = do
-- States -- States
mBackend <- R2.useLive' props.backend mBackend <- R2.useLive' props.backend
formType <- T.useBox Login
formType' <- T.useLive T.unequal formType
-- Render -- Render
pure $ pure $
...@@ -55,12 +58,13 @@ loginCpt = here.component "login" cpt where ...@@ -55,12 +58,13 @@ loginCpt = here.component "login" cpt where
[ [
case mBackend of case mBackend of
Nothing -> chooser props Nothing -> chooser props
Just backend -> form { backend, sessions, visible } Just backend -> case formType' of
Login -> form { backend, formType, sessions, visible }
ForgotPassword -> forgotPassword { backend, sessions }
] ]
chooser :: R2.Leaf Props chooser :: R2.Leaf Props
chooser = R2.leafComponent chooserCpt chooser = R2.leafComponent chooserCpt
chooserCpt :: R.Component Props chooserCpt :: R.Component Props
chooserCpt = here.component "chooser" cpt where chooserCpt = here.component "chooser" cpt where
cpt { backend, backends, sessions } _ = do cpt { backend, backends, sessions } _ = do
......
module Gargantext.Components.Login.ForgotPassword where
import DOM.Simple.Event as DE
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Gargantext.Components.Forms (formGroup)
import Gargantext.Ends (Backend)
import Gargantext.Prelude
import Gargantext.Sessions (Sessions, postForgotPasswordRequest)
import Gargantext.Utils.Reactix as R2
import Formula as F
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.SyntheticEvent as E
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.Login.ForgotPassword"
type Email = String
type Props =
( backend :: Backend
, sessions :: T.Box Sessions )
forgotPassword :: R2.Leaf Props
forgotPassword = R2.leaf forgotPasswordCpt
forgotPasswordCpt :: R.Component Props
forgotPasswordCpt = here.component "forgotPassword" cpt where
cpt { backend, sessions } _ = do
email <- T.useBox ""
pure $ H.div { className: "row" }
[ H.form { className: "col-md-12" }
[ H.h4 {} [ H.text "Forgot password" ]
, formGroup
[ emailInput email ]
, submitButton { backend, email, sessions }
]
]
emailInput :: forall cell. T.ReadWrite cell Email => cell -> R.Element
emailInput value = F.bindInput { value
, type: "email"
, className: "form-control"
, id: "id_email"
, placeholder: "email"
, name: "email"
, maxLength: "254" }
type SubmitButtonProps =
( email :: T.Box Email
| Props )
submitButton :: R2.Leaf SubmitButtonProps
submitButton = R2.leafComponent submitButtonCpt
submitButtonCpt :: R.Component SubmitButtonProps
submitButtonCpt = here.component "submitButton" cpt where
cpt { backend, email, sessions } _ = do
email' <- T.useLive T.unequal email
pure $ formGroup
[ H.button { className: "btn btn-primary"
, on: { click: click email' }}
[ H.text "Submit" ]
]
where
click :: Email -> R.SyntheticEvent DE.MouseEvent -> Effect Unit
click email' e = do
E.preventDefault e
here.log2 "email" email'
here.log2 "backend" backend
here.log2 "sessions" sessions
launchAff_ $ do
res <- postForgotPasswordRequest backend email'
liftEffect $ here.log2 "res" res
module Gargantext.Components.Login.Form where module Gargantext.Components.Login.Form where
import Prelude (Unit, bind, discard, notEq, pure, show, ($), (&&), (*>), (<>)) import Prelude (Unit, bind, discard, not, notEq, pure, show, ($), (&&), (*>), (<>))
import Data.Either (Either(..)) import Data.Either (Either(..))
import DOM.Simple.Event as DE import DOM.Simple.Event as DE
import Effect (Effect) import Effect (Effect)
...@@ -13,8 +13,8 @@ import Reactix.DOM.HTML as H ...@@ -13,8 +13,8 @@ import Reactix.DOM.HTML as H
import Toestand as T import Toestand as T
import Toestand (useFocusedFields) import Toestand (useFocusedFields)
import Gargantext.Components.Login.Types (AuthRequest(..))
import Gargantext.Components.Forms (clearfix, formGroup) import Gargantext.Components.Forms (clearfix, formGroup)
import Gargantext.Components.Login.Types (AuthRequest(..), FormType(..))
import Gargantext.Ends (Backend) import Gargantext.Ends (Backend)
import Gargantext.Sessions as Sessions import Gargantext.Sessions as Sessions
import Gargantext.Sessions (Sessions, postAuthRequest) import Gargantext.Sessions (Sessions, postAuthRequest)
...@@ -45,6 +45,7 @@ formBoxes box = useFocusedFields box {} ...@@ -45,6 +45,7 @@ formBoxes box = useFocusedFields box {}
type Props s v = type Props s v =
( backend :: Backend ( backend :: Backend
, formType :: T.Box FormType
, sessions :: s , sessions :: s
, visible :: v , visible :: v
) )
...@@ -55,7 +56,7 @@ form props = R.createElement formCpt props [] ...@@ -55,7 +56,7 @@ form props = R.createElement formCpt props []
formCpt :: forall s v. T.ReadWrite s Sessions => T.ReadWrite v Boolean formCpt :: forall s v. T.ReadWrite s Sessions => T.ReadWrite v Boolean
=> R.Component (Props s v) => R.Component (Props s v)
formCpt = here.component "form" cpt where formCpt = here.component "form" cpt where
cpt { backend, sessions, visible } _ = do cpt { backend, formType, sessions, visible } _ = do
cell <- T.useBox emptyForm cell <- T.useBox emptyForm
cursors <- useFocusedFields cell {} cursors <- useFocusedFields cell {}
pure $ R2.row pure $ R2.row
...@@ -70,7 +71,8 @@ formCpt = here.component "form" cpt where ...@@ -70,7 +71,8 @@ formCpt = here.component "form" cpt where
[ passwordInput cursors.password [ passwordInput cursors.password
, clearfix ] , clearfix ]
, termsCheckbox cursors.agreed , termsCheckbox cursors.agreed
, submitButton { backend, sessions, visible, cell } , forgotPassword { formType }
, submitButton { backend, formType, sessions, visible, cell }
]] ]]
-- might be wrong, all we care about is preventDefault -- might be wrong, all we care about is preventDefault
...@@ -87,18 +89,15 @@ submitButton ...@@ -87,18 +89,15 @@ submitButton
:: forall s v. T.ReadWrite s Sessions => T.Write v Boolean :: forall s v. T.ReadWrite s Sessions => T.Write v Boolean
=> R2.Leaf (SubmitButtonProps s v) => R2.Leaf (SubmitButtonProps s v)
submitButton = R2.leafComponent submitButtonCpt submitButton = R2.leafComponent submitButtonCpt
submitButtonCpt submitButtonCpt
:: forall s v. T.ReadWrite s Sessions => T.Write v Boolean :: forall s v. T.ReadWrite s Sessions => T.Write v Boolean
=> R.Component (SubmitButtonProps s v) => R.Component (SubmitButtonProps s v)
submitButtonCpt = here.component "submitButton" cpt where submitButtonCpt = here.component "submitButton" cpt where
cpt { backend, sessions, visible, cell } _ = do cpt { backend, formType, sessions, visible, cell } _ = do
{ agreed, username, password } <- T.useLive T.unequal cell { agreed, username, password } <- T.useLive T.unequal cell
pure $ let isValid = agreed && (username `notEq` "") && (password `notEq` "")
if agreed && (username `notEq` "") && (password `notEq` "") pure $ H.div { className: "text-center" }
then H.div { className: "text-center" } [ loginSubmit isValid $ submitForm { backend, formType, sessions, visible } cell ]
[ loginSubmit $ submitForm { backend, sessions, visible } cell ]
else H.div {} []
-- Attempts to submit the form -- Attempts to submit the form
submitForm :: forall s v. T.ReadWrite s Sessions => T.Write v Boolean submitForm :: forall s v. T.ReadWrite s Sessions => T.Write v Boolean
...@@ -157,9 +156,28 @@ passwordInput value = ...@@ -157,9 +156,28 @@ passwordInput value =
, id: "id_password" , id: "id_password"
} }
loginSubmit :: (ChangeEvent -> Effect Unit) -> R.Element loginSubmit :: Boolean -> (ChangeEvent -> Effect Unit) -> R.Element
loginSubmit click = loginSubmit isEnabled click =
H.button { id, className, type: "submit", on: { click } } H.button { id
, className
, disabled: not isEnabled
, type: "submit"
, on: { click } }
[ H.text "Login" ] where [ H.text "Login" ] where
id = "login-button" id = "login-button"
className = "btn btn-primary btn-rounded" className = "btn btn-primary btn-rounded"
type ForgotPasswordProps =
( formType :: T.Box FormType )
forgotPassword :: R2.Leaf ForgotPasswordProps
forgotPassword = R2.leaf forgotPasswordCpt
forgotPasswordCpt :: R.Component ForgotPasswordProps
forgotPasswordCpt = here.component "forgotPassword" cpt where
cpt { formType } _ = do
pure $ H.div { className: "form-group text-center" }
[ H.button { className: "btn btn-danger"
, on: { click } } [ H.text "Forgot password" ]
]
where
click _ = T.write_ ForgotPassword formType
...@@ -54,3 +54,7 @@ instance Eq AuthData where ...@@ -54,3 +54,7 @@ instance Eq AuthData where
_AuthData :: Iso' AuthData { token :: Token, tree_id :: TreeId, user_id :: UserId } _AuthData :: Iso' AuthData { token :: Token, tree_id :: TreeId, user_id :: UserId }
_AuthData = iso (\(AuthData v) -> v) AuthData _AuthData = iso (\(AuthData v) -> v) AuthData
data FormType = Login | ForgotPassword
derive instance Generic FormType _
derive instance Eq FormType
...@@ -4,7 +4,8 @@ module Gargantext.Sessions ...@@ -4,7 +4,8 @@ module Gargantext.Sessions
, WithSession, WithSessionContext , WithSession, WithSessionContext
, load, change , load, change
, Action(..), act, delete, get, post, put, put_ , Action(..), act, delete, get, post, put, put_
, postAuthRequest, deleteWithBody, postWwwUrlencoded , postAuthRequest, postForgotPasswordRequest
, deleteWithBody, postWwwUrlencoded
, getCacheState, setCacheState , getCacheState, setCacheState
) where ) where
...@@ -114,13 +115,20 @@ postAuthRequest :: Backend -> AuthRequest -> Aff (Either String Session) ...@@ -114,13 +115,20 @@ postAuthRequest :: Backend -> AuthRequest -> Aff (Either String Session)
postAuthRequest backend ar@(AuthRequest {username}) = postAuthRequest backend ar@(AuthRequest {username}) =
decode <$> REST.post Nothing (toUrl backend "auth") ar decode <$> REST.post Nothing (toUrl backend "auth") ar
where where
decode (Left _err) = Left "Error when sending REST.post" decode (Left err) = Left $ "Error when sending REST.post: " <> show err
decode (Right (AuthResponse ar2)) decode (Right (AuthResponse ar2))
| {inval: Just (AuthInvalid {message})} <- ar2 = Left message | {inval: Just (AuthInvalid {message})} <- ar2 = Left message
| {valid: Just (AuthData {token, tree_id, user_id})} <- ar2 = | {valid: Just (AuthData {token, tree_id, user_id})} <- ar2 =
Right $ Session { backend, caches: Map.empty, token, treeId: tree_id, username, userId: user_id } Right $ Session { backend, caches: Map.empty, token, treeId: tree_id, username, userId: user_id }
| otherwise = Left "Invalid response from server" | otherwise = Left "Invalid response from server"
postForgotPasswordRequest :: Backend -> String -> Aff (Either String { status :: String })
postForgotPasswordRequest backend email =
decode <$> REST.post Nothing (toUrl backend "async/forgot-password") { email }
where
decode (Left err) = Left $ "Error when sending REST.post: " <> show err
decode (Right s) = Right s
get :: forall a p. JSON.ReadForeign a => ToUrl Session p => get :: forall a p. JSON.ReadForeign a => ToUrl Session p =>
Session -> p -> REST.AffRESTError a Session -> p -> REST.AffRESTError a
get session@(Session {token}) p = REST.get (Just token) (toUrl session p) get session@(Session {token}) p = REST.get (Just token) (toUrl session p)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment