Skip to content

Commit

Permalink
Revise installation of magic link for minimal scenario: now now comp…
Browse files Browse the repository at this point in the history
…iles
  • Loading branch information
jxxcarlson committed Jul 12, 2024
1 parent de60965 commit eb6fe31
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 193 deletions.
5 changes: 4 additions & 1 deletion Notes-min-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ To Implement:
- MagicLink.Backend.checkLogin

- MagicLink.Auth, clause Auth.Common.AuthSignInWithTokenResponse result in
updateFromBackend
updateFromBackend

- MagicLink.Frontend:
- submitEmailForSignin
37 changes: 30 additions & 7 deletions preview/src/ReviewConfig.elm
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,14 @@ configUsers =

configMagicLinkMinimal : List Rule
configMagicLinkMinimal =
[ Import.qualified "Types" [ "Dict", "AssocList", "LocalUUID", "Auth.Common", "MagicLink.Types", "Session", "User" ] |> Import.makeRule
, Import.qualified "Frontend" [ "MagicLink.Types", "Auth.Common", "MagicLink.Frontend", "MagicLink.Auth" ] |> Import.makeRule
, Import.qualified "Backend" [ "Auth.Flow", "MagicLink.Auth", "User" ] |> Import.makeRule
[ Import.qualified "Types" [ "Dict", "AssocList", "EmailAddress", "LocalUUID", "Auth.Common", "MagicLink.Types", "Session", "User" ] |> Import.makeRule
, Import.qualified "Frontend" [ "Dict", "MagicLink.Types", "Auth.Common", "MagicLink.Frontend", "MagicLink.Auth" , "Pages.SignIn"] |> Import.makeRule
, Import.qualified "Backend" [ "Dict", "AssocList", "Time", "Auth.Flow", "MagicLink.Auth", "User", "LocalUUID" ] |> Import.makeRule

, TypeVariant.makeRule "Types" "FrontendMsg" [ "AuthFrontendMsg MagicLink.Types.Msg" ]
, TypeVariant.makeRule "Types" "BackendMsg" [ "AuthBackendMsg Auth.Common.BackendMsg" ]
, TypeVariant.makeRule "Types" "ToBackend" [ "AuthToBackend Auth.Common.ToBackend" ]
, FieldInTypeAlias.makeRule "Types" "LoadedModel" [ "magicLinkModel : MagicLink.Types.Model" ]
, FieldInTypeAlias.makeRule "Types" "LoadedModel" [ "magicLinkModel : MagicLink.Types.Model", "users: Dict.Dict User.EmailString User.User" ]
, TypeVariant.makeRule "Types"
"ToFrontend"
[ "AuthToFrontend Auth.Common.ToFrontend"
Expand All @@ -138,6 +139,7 @@ configMagicLinkMinimal =
, "SignInError String"
--, "CheckSignInResponse (Result BackendDataStatus User.SignInData)"
]

, FieldInTypeAlias.makeRule "Types"
"BackendModel"
[ "localUuidData : Maybe LocalUUID.Data"
Expand All @@ -146,17 +148,38 @@ configMagicLinkMinimal =
, "sessions : Dict.Dict SessionId Auth.Common.UserInfo"
, "secretCounter : Int"
, "sessionDict : AssocList.Dict SessionId String"
, "pendingLogins : MagicLink.Types.PendingLogins"
, "log : MagicLink.Types.Log"
, "sessionInfo : Session.SessionInfo"
, "pendingLogins : AssocList.Dict Lamdera.SessionId {loginAttempts : Int , emailAddress : EmailAddress.EmailAddress , creationTime : Time.Posix , loginCode : Int }"
, "log : List ( Time.Posix, MagicLink.Types.LogItem )"
, "sessionInfo : Dict.Dict SessionId Session.Interaction"
, "users: Dict.Dict User.EmailString User.User"
, "userNameToEmailString : Dict.Dict User.Username User.EmailString"
, "time: Time.Posix"
, "randomAtmosphericNumbers: Maybe (List Int)"


]
, Initializer.makeRule "Frontend" "initLoaded" [ { field = "magicLinkModel", value = "Pages.SignIn.init loadingModel.initUrl" } ]
, Initializer.makeRule "Backend"
"init"
[ { field = "randomAtmosphericNumbers", value = "Just [ 235880, 700828, 253400, 602641 ]" }
, { field = "time", value = "Time.millisToPosix 0" }
, { field = "sessions", value = "Dict.empty" }
, { field = "userNameToEmailString", value = "Dict.empty" }
, { field = "users", value = "Dict.empty" }
, { field = "sessionInfo", value = "Dict.empty" }
, { field = "pendingAuths", value = "Dict.empty" }
, { field = "localUuidData", value = "LocalUUID.initFrom4List [ 235880, 700828, 253400, 602641 ]" }
, { field = "pendingEmailAuths", value = "Dict.empty" }
, { field = "secretCounter", value = "0" }
, { field = "sessionDict", value = "AssocList.empty" }
, { field = "pendingLogins", value = "AssocList.empty" }
, { field = "log", value = "[]" }
]
, ClauseInCase.init "Frontend" "updateLoaded" "AuthFrontendMsg authToFrontendMsg" "MagicLink.Auth.update authToFrontendMsg model.magicLinkModel |> Tuple.mapFirst (\\magicLinkModel -> { model | magicLinkModel = magicLinkModel })" |> ClauseInCase.makeRule
, ClauseInCase.init "Backend" "updateFromFrontend" "AuthToBackend authMsg" "Auth.Flow.updateFromFrontend (MagicLink.Auth.backendConfig model) clientId sessionId authMsg model" |> ClauseInCase.makeRule
, ClauseInCase.init "Backend" "update" "AuthBackendMsg _" "(model, Cmd.none)" |> ClauseInCase.makeRule
, ReplaceFunction.init "Frontend" "tryLoading" tryLoading2
|> ReplaceFunction.makeRule
]


Expand Down
42 changes: 15 additions & 27 deletions vendor/magic-link/MagicLink/Frontend.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module MagicLink.Frontend exposing
, handleRegistrationError
, handleSignInError
, signIn
, signInWithCode
, submitEmailForSignin
, updateMagicLinkModelInModel
)
Expand Down Expand Up @@ -33,37 +34,14 @@ updateMagicLinkModelInModel model =

submitEmailForSignin : Model -> ( Model, Cmd FrontendMsg )
submitEmailForSignin model =
case model.signInForm of
EnterEmail signInForm_ ->
case EmailAddress.fromString signInForm_.email of
Just email ->
let
model2 =
{ model | signInForm = EnterSigninCode { sentTo = email, loginCode = "", attempts = Dict.empty } }
in
( model2, Helper.trigger <| AuthFrontendMsg <| MagicLink.Types.AuthSigninRequested { methodId = "EmailMagicLink", email = Just signInForm_.email } )

Nothing ->
( { model | signInForm = EnterEmail { signInForm_ | pressedSubmitEmail = True } }, Cmd.none )

EnterSigninCode _ ->
( model, Cmd.none )
-- TODO: implement
( model, Cmd.none )


enterEmail : Model -> String -> ( Model, Cmd msg )
enterEmail model email =
case model.signInForm of
EnterEmail signinForm_ ->
let
signinForm =
{ signinForm_ | email = email }
in
( { model | signInForm = EnterEmail signinForm }, Cmd.none )

EnterSigninCode loginCode_ ->
-- TODO: complete this
-- EnterLoginCode{ sentTo : EmailAddress, loginCode : String, attempts : Dict Int LoginCodeStatus }
( model, Cmd.none )
-- TODO: implement
( model, Cmd.none )


handleRegistrationError : Model -> String -> ( Model, Cmd msg )
Expand All @@ -88,5 +66,15 @@ signIn model userData =
)


signInWithCode : Model -> String -> ( Model, Cmd msg )
signInWithCode model signInCode =
-- TODO: Implement
-- The signInCode is the string the user received via Postmark via email
-- This string must be converted to an integer and then sent to the backend
-- as loginCode to complete the sign in process
-- Lamdera.sendToBackend ((AuthToBackend << Auth.Common.AuthSigInWithToken) loginCode)
( model, Cmd.none )



-- HELPERS
6 changes: 2 additions & 4 deletions vendor/magic-link/MagicLink/Types.elm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ type alias Model =
, signInStatus : SignInStatus
, currentUser : Maybe User.User
, currentUserData : Maybe User.SignInData
, signInForm : SigninFormState

--, signInForm : SigninFormState
, signInState : SignInState
, loginErrorMessage : Maybe String
, realname : String
Expand All @@ -50,12 +51,9 @@ type Msg
= SubmitEmailForSignIn
| AuthSigninRequested { methodId : Auth.Common.MethodId, email : Maybe String }
| ReceivedSigninCode String
| CancelSignIn
| CancelSignUp
| OpenSignUp
| TypedEmailInSignInForm String
| SubmitSignUp
| SignOut
| InputRealname String
| InputUsername String
| InputEmail String
Expand Down
161 changes: 7 additions & 154 deletions vendor/magic-link/Pages/SignIn.elm
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
module Pages.SignIn exposing (headerView, init, view)
module Pages.SignIn exposing (init, view)

import Auth.Common
import Element exposing (Element)
import Element.Background
import Element.Border
import Element.Font
import Element.Input
import MagicLink.LoginForm
import MagicLink.Types
import Route
import Url
import User
import View.Button
import View.Color
import View.Common
import View.Input


type alias Model =
Expand All @@ -27,7 +17,8 @@ init url =
, signInStatus = MagicLink.Types.NotSignedIn
, currentUserData = Nothing
, currentUser = Nothing
, signInForm = MagicLink.LoginForm.init

-- , signInForm = MagicLink.LoginForm.init
, signInState = MagicLink.Types.SisSignedOut
, loginErrorMessage = Nothing
, realname = ""
Expand Down Expand Up @@ -76,157 +67,19 @@ view toSelf model =

signedInView : Model -> Element MagicLink.Types.Msg
signedInView model =
case model.currentUserData of
Nothing ->
Element.none

Just userData ->
signOutButton userData.username
Element.text "signedInView: implement"


signInView : Model -> Element MagicLink.Types.Msg
signInView model =
Element.column []
[ Element.el [ Element.Font.semiBold, Element.Font.size 24 ] (Element.text "Sign in")
, MagicLink.LoginForm.view model.signInForm

--, Element.paragraph [ Element.Font.color (Element.rgb 1 0 0) ] [ Element.text (model.loginErrorMessage |> Maybe.withDefault "") ]
, Element.row
[ Element.spacing 12
, Element.paddingEach { left = 18, right = 0, top = 0, bottom = 0 }
]
[ Element.el [] (Element.text "Need to sign up? "), View.Button.openSignUp ]
]
Element.text "signInView: implement"


signInAfterRegisteringView : Model -> Element MagicLink.Types.Msg
signInAfterRegisteringView model =
Element.column []
[ Element.el [ Element.Font.semiBold, Element.Font.size 24 ] (Element.text "Sign in")
, MagicLink.LoginForm.view model.signInForm
]
Element.text "signInAfterRegisteringView: implement"


signUp : Model -> Element MagicLink.Types.Msg
signUp model =
Element.column [ Element.spacing 18, topPadding ]
[ Element.el [ Element.Font.semiBold, Element.Font.size 24 ] (Element.text "Sign up")
, View.Input.template "Real Name" model.realname MagicLink.Types.InputRealname
, View.Input.template "User Name" model.username MagicLink.Types.InputUsername
, View.Input.template "Email" model.email MagicLink.Types.InputEmail
, Element.row [ Element.spacing 18 ]
[ signUpButton
, cancelSignUpButton
]
, Element.el [ Element.Font.size 14, Element.Font.italic, Element.Font.color View.Color.darkGray ] (Element.text model.message)
]


headerView : Model -> Route.Route -> { window : { width : Int, height : Int }, isCompact : Bool } -> Element MagicLink.Types.Msg
headerView model route config =
Element.el
[ Element.Background.color View.Color.blue
, Element.paddingXY 24 16
, Element.width (Element.px 420) --(Element.px config.window.width)
, Element.alignTop
]
(Element.wrappedRow
[ Element.spacing 24
, Element.Background.color View.Color.blue
, Element.Font.color (Element.rgb 1 1 1)
]
[ if User.isAdmin model.currentUserData then
Element.link
(View.Common.linkStyle route Route.AdminRoute)
{ url = Route.encode Route.AdminRoute, label = Element.text "Admin" }

else
Element.none
, case model.currentUserData of
Just currentUserData_ ->
signOutButton currentUserData_.username

Nothing ->
Element.link
(View.Common.linkStyle route Route.SignInRoute)
{ url = Route.encode Route.SignInRoute
, label =
Element.el []
(case model.currentUserData of
Just currentUserData_ ->
signOutButton currentUserData_.username

Nothing ->
Element.text "Sign in"
)
}
]
)



-- BUTTON


signUpButton : Element.Element MagicLink.Types.Msg
signUpButton =
button MagicLink.Types.SubmitSignUp "Submit"


signOutButton : String -> Element.Element MagicLink.Types.Msg
signOutButton str =
button MagicLink.Types.SignOut ("Sign out " ++ str)


cancelSignUpButton =
button MagicLink.Types.CancelSignUp "Cancel"


button msg label =
Element.Input.button
buttonStyle
{ onPress = Just msg
, label =
Element.el buttonLabelStyle (Element.text label)
}


highlightableButton condition msg label =
Element.Input.button
buttonStyle
{ onPress = Just msg
, label =
Element.el (buttonLabelStyle ++ highlight condition) (Element.text label)
}


buttonStyle =
[ Element.Font.color (Element.rgb 0.2 0.2 0.2)
, Element.height Element.shrink
, Element.paddingXY 8 8
, Element.Border.rounded 8
, Element.Background.color View.Color.blue
, Element.Font.color View.Color.white
, Element.mouseDown
[ Element.Background.color View.Color.buttonHighlight
]
]


buttonLabelStyle =
[ Element.centerX
, Element.centerY
, Element.Font.size 15
]


highlight condition =
if condition then
[ Element.Font.color View.Color.yellow ]

else
[ Element.Font.color View.Color.white ]


topPadding =
Element.paddingEach { left = 0, right = 0, top = 48, bottom = 0 }
Element.text "signUp: implement"

0 comments on commit eb6fe31

Please sign in to comment.