halogen-websocket-ipc-playzone/src/App/AuthenticationForm.purs

252 lines
9.0 KiB
Plaintext
Raw Normal View History

2023-05-22 02:11:40 +02:00
module App.AuthenticationForm where
2023-07-05 06:50:30 +02:00
import Prelude (Unit, bind, discard, pure, ($), (<<<), (<>))
2023-05-22 02:11:40 +02:00
2023-06-08 21:51:12 +02:00
2023-07-05 06:50:30 +02:00
import Data.ArrayBuffer.Types (ArrayBuffer)
2023-05-22 02:11:40 +02:00
import Data.Either (Either(..))
2023-07-05 06:50:30 +02:00
import Data.Maybe (Maybe(..), maybe)
import Data.Tuple (Tuple(..))
2023-05-22 02:11:40 +02:00
import Effect.Aff.Class (class MonadAff)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.HTML.Properties as HP
import Web.Event.Event as Event
2023-07-05 06:50:30 +02:00
import Web.Event.Event (Event)
2023-05-22 02:11:40 +02:00
2023-07-05 06:50:30 +02:00
import Bulma as Bulma
import App.Email as Email
2023-07-05 04:49:32 +02:00
import App.LogMessage
2023-05-22 02:11:40 +02:00
import App.Messages.AuthenticationDaemon as AuthD
data Output
= AuthToken (Tuple Int String)
| MessageToSend ArrayBuffer
2023-07-05 04:49:32 +02:00
| Log LogMessage
data Query a
= MessageReceived ArrayBuffer a
| ConnectionIsDown a
| ConnectionIsUp a
2023-05-22 02:11:40 +02:00
type Slot = H.Slot Query Output
type Input = Unit
2023-05-22 02:11:40 +02:00
2023-06-04 01:24:05 +02:00
data AuthenticationInput
= AUTH_INP_login String
| AUTH_INP_pass String
data RegisterInput
= REG_INP_login String
| REG_INP_email String
| REG_INP_pass String
2023-05-22 02:11:40 +02:00
data Action
= HandleAuthenticationInput AuthenticationInput
2023-06-04 01:24:05 +02:00
| HandleRegisterInput RegisterInput
--
2023-05-22 02:11:40 +02:00
| AuthenticationAttempt Event
2023-06-03 00:54:18 +02:00
| RegisterAttempt Event
2023-05-22 02:11:40 +02:00
2023-06-04 01:24:05 +02:00
type StateAuthenticationForm = { login :: String, pass :: String }
type StateRegistrationForm = { login :: String, email :: String, pass :: String }
2023-05-22 02:11:40 +02:00
type State =
{ authenticationForm :: StateAuthenticationForm
, registrationForm :: StateRegistrationForm
, wsUp :: Boolean
2023-05-22 02:11:40 +02:00
}
component :: forall m. MonadAff m => H.Component Query Input Output m
component =
2023-05-22 02:11:40 +02:00
H.mkComponent
{ initialState
, render
, eval: H.mkEval $ H.defaultEval
{ handleAction = handleAction
, handleQuery = handleQuery
2023-05-22 02:11:40 +02:00
}
}
initialState :: Input -> State
initialState _ =
{ authenticationForm: { login: "", pass: "" }
2023-06-04 01:24:05 +02:00
, registrationForm: { login: "", email: "", pass: "" }
2023-06-03 00:54:18 +02:00
, wsUp: true
2023-05-22 02:11:40 +02:00
}
render :: forall m. State -> H.ComponentHTML Action () m
2023-07-08 04:00:32 +02:00
render { wsUp, authenticationForm, registrationForm }
= Bulma.section_small
[ case wsUp of
false -> Bulma.p "You are disconnected."
true -> Bulma.columns_ [ Bulma.column_ auth_form, Bulma.column_ register_form ]
]
where
auth_form
= [ Bulma.h3 "Authentication"
, render_auth_form
2023-05-22 02:11:40 +02:00
]
2023-06-03 00:54:18 +02:00
2023-07-08 04:00:32 +02:00
register_form
= [ Bulma.h3 "Register!"
, render_register_form
2023-05-22 02:11:40 +02:00
]
2023-07-08 04:00:32 +02:00
should_be_disabled = (if wsUp then (HP.enabled true) else (HP.disabled true))
render_auth_form = HH.form
[ HE.onSubmit AuthenticationAttempt ]
[ Bulma.box_input "Login" "login" -- title, placeholder
(HandleAuthenticationInput <<< AUTH_INP_login) -- action
authenticationForm.login -- value
true -- validity (TODO)
should_be_disabled -- condition
, Bulma.box_password "Password" "password" -- title, placeholder
(HandleAuthenticationInput <<< AUTH_INP_pass) -- action
authenticationForm.pass -- value
true -- validity (TODO)
should_be_disabled -- condition
, HH.button
[ HP.style "padding: 0.5rem 1.25rem;"
, HP.type_ HP.ButtonSubmit
, (if wsUp then (HP.enabled true) else (HP.disabled true))
]
[ HH.text "Send Message to Server" ]
]
render_register_form = HH.form
[ HE.onSubmit RegisterAttempt ]
[ Bulma.box_input "Login" "login" -- title, placeholder
(HandleRegisterInput <<< REG_INP_login) -- action
registrationForm.login -- value
true -- validity (TODO)
should_be_disabled -- condition
, Bulma.box_input "Email" "email@example.com" -- title, placeholder
(HandleRegisterInput <<< REG_INP_email) -- action
registrationForm.email -- value
true -- validity (TODO)
should_be_disabled -- condition
, Bulma.box_password "Password" "password" -- title, placeholder
(HandleRegisterInput <<< REG_INP_pass) -- action
registrationForm.pass -- value
true -- validity (TODO)
should_be_disabled -- condition
, HH.div_
[ HH.button
[ HP.style "padding: 0.5rem 1.25rem;"
, HP.type_ HP.ButtonSubmit
, (if wsUp then (HP.enabled true) else (HP.disabled true))
]
[ HH.text "Send Message to Server" ]
]
]
2023-05-22 02:11:40 +02:00
handleAction :: forall m. MonadAff m => Action -> H.HalogenM State Action () Output m Unit
handleAction = case _ of
2023-06-04 01:24:05 +02:00
HandleAuthenticationInput authinp -> do
case authinp of
AUTH_INP_login v -> H.modify_ _ { authenticationForm { login = v } }
AUTH_INP_pass v -> H.modify_ _ { authenticationForm { pass = v } }
HandleRegisterInput reginp -> do
case reginp of
REG_INP_login v -> H.modify_ _ { registrationForm { login = v } }
REG_INP_email v -> H.modify_ _ { registrationForm { email = v } }
REG_INP_pass v -> H.modify_ _ { registrationForm { pass = v } }
2023-06-03 00:54:18 +02:00
RegisterAttempt ev -> do
H.liftEffect $ Event.preventDefault ev
{ registrationForm } <- H.get
2023-06-04 01:24:05 +02:00
let login = registrationForm.login
email = registrationForm.email
pass = registrationForm.pass
case login, email, pass of
2023-07-04 03:26:09 +02:00
"", _, _ ->
2023-07-05 04:49:32 +02:00
H.raise $ Log $ UnableToSend "Write your login!"
2023-07-04 03:26:09 +02:00
_, "", _ ->
2023-07-05 04:49:32 +02:00
H.raise $ Log $ UnableToSend "Write your email!"
2023-07-04 03:26:09 +02:00
_, _, "" ->
2023-07-05 04:49:32 +02:00
H.raise $ Log $ UnableToSend "Write your password!"
_, _, _ -> do
message <- H.liftEffect $ AuthD.serialize $
AuthD.MkRegister { login: login
, email: Just (Email.Email email)
, password: pass }
H.raise $ MessageToSend message
2023-07-05 04:49:32 +02:00
H.raise $ Log $ SimpleLog $ "[😇] Trying to register (login: " <> login <> ")"
2023-06-03 00:54:18 +02:00
2023-05-22 02:11:40 +02:00
AuthenticationAttempt ev -> do
H.liftEffect $ Event.preventDefault ev
{ authenticationForm } <- H.get
case authenticationForm.login, authenticationForm.pass of
2023-07-04 03:26:09 +02:00
"" , _ ->
2023-07-05 04:49:32 +02:00
H.raise $ Log $ UnableToSend "Write your login!"
2023-07-04 03:26:09 +02:00
_ , "" ->
2023-07-05 04:49:32 +02:00
H.raise $ Log $ UnableToSend "Write your password!"
login, pass -> do
message <- H.liftEffect $ AuthD.serialize $ AuthD.MkLogin { login: login, password: pass }
H.raise $ MessageToSend message
2023-07-05 04:49:32 +02:00
H.raise $ Log $ SimpleLog $ "[😇] Trying to authenticate (login: " <> login <> ")"
handleQuery :: forall a m. MonadAff m => Query a -> H.HalogenM State Action () Output m (Maybe a)
handleQuery = case _ of
MessageReceived message a -> do
receivedMessage <- H.liftEffect $ AuthD.deserialize message
case receivedMessage of
-- Cases where we didn't understand the message.
Left _ -> pure Nothing
--case err of
-- (AuthD.JSONERROR jerr) -> do
-- print_json_string messageEvent.message
-- handleAction $ WebSocketParseError ("JSON parsing error: " <> jerr <> " JSON is: " <> jerr)
-- (AuthD.UnknownError unerr) -> handleAction $ WebSocketParseError ("Parsing error: AuthD.UnknownError" <> (show unerr))
-- (AuthD.UnknownNumber ) -> handleAction $ WebSocketParseError ("Parsing error: AuthD.UnknownNumber")
-- Cases where we understood the message.
Right response -> do
case response of
-- The authentication failed.
2023-07-04 03:26:09 +02:00
(AuthD.GotError errmsg) -> do
2023-07-05 04:49:32 +02:00
H.raise $ Log $ SimpleLog $ "[😈] Failed: " <> maybe "server didn't tell why" (\v -> v) errmsg.reason
2023-07-04 03:26:09 +02:00
pure (Just a)
-- The authentication was a success!
(AuthD.GotToken msg) -> do
2023-07-05 04:49:32 +02:00
H.raise $ Log $ SimpleLog $ "[🎉] Authenticated to authd!"
H.raise $ AuthToken (Tuple msg.uid msg.token)
pure (Just a)
-- WTH?!
2023-07-04 03:26:09 +02:00
_ -> do
2023-07-05 04:49:32 +02:00
H.raise $ Log $ SimpleLog $ "[😈] Failed! Authentication server didn't send a valid message."
2023-07-04 03:26:09 +02:00
pure Nothing
2023-05-22 02:11:40 +02:00
ConnectionIsDown a -> do
H.modify_ _ { wsUp = false }
pure (Just a)
ConnectionIsUp a -> do
H.modify_ _ { wsUp = true }
pure (Just a)
2023-07-04 03:26:09 +02:00
--print_json_string :: forall m. MonadEffect m => MonadState State m => ArrayBuffer -> m Unit
--print_json_string arraybuffer = do
-- -- fromTypedIPC :: ArrayBuffer -> Effect (Either ParseError (Tuple UInt String))
-- value <- H.liftEffect $ IPC.fromTypedIPC arraybuffer
2023-07-05 04:49:32 +02:00
-- H.raise $ Log $ SimpleLog $ case (value) of
-- Left _ -> "Cannot even fromTypedIPC the message."
-- Right (Tuple messageTypeNumber string) -> "Number is: " <> show messageTypeNumber <> ", received string: " <> string