Reputation: 39229
I'm trying to integrate Yesod.Auth.Email
into the default scaffolding of Yesod 1.4 (what you get with stack exec -- yesod init --bare && stack init
). So I copied the relevant parts from the authentication and authorization example from the Yesod book to my Foundation.hs
and started adjusting it to the new Yesod version:
instance YesodAuthEmail App where
type AuthEmailId App = UserId
afterPasswordRoute _ = HomeR
addUnverified email verkey = do
userId <- runDB $ insert $ User email Nothing
runDB $ insert $ Email email (Just userId) (Just verkey)
return userId
sendVerifyEmail email _ verurl =
liftIO $ renderSendMail (emptyMail $ Address Nothing "noreply")
{ mailTo = [Address Nothing email]
, mailHeaders =
[ ("Subject", "Verify your email address")
]
, mailParts = [[textPart, htmlPart]]
}
where
textPart = Part
{ partType = "text/plain; charset=utf-8"
, partEncoding = None
, partFilename = Nothing
, partContent = Data.Text.Lazy.Encoding.encodeUtf8
[stext|
Please confirm your email address by clicking on the link below.
#{verurl}
Thank you
|]
, partHeaders = []
}
htmlPart = Part
{ partType = "text/html; charset=utf-8"
, partEncoding = None
, partFilename = Nothing
, partContent = withUrlRenderer
[shamlet|
<p>Please confirm your email address by clicking on the link below.
<p>
<a href=#{verurl}>#{verurl}
<p>Thank you
|]
, partHeaders = []
}
getVerifyKey = runDB . fmap (join . fmap emailVerkey) . getBy
setVerifyKey uid key = runDB $ update uid [EmailVerkey =. Just key]
verifyAccount uid = runDB $ do
mu <- get uid
case mu of
Nothing -> return Nothing
Just u -> do
update uid [EmailVerkey =. Nothing]
return $ Just uid
getPassword = runDB . fmap (join . fmap userPassword) . get
setPassword uid pass = runDB $ update uid [UserPassword =. Just pass]
getEmailCreds email = runDB $ do
mu <- getBy $ UniqueUser email
case mu of
Nothing -> return Nothing
Just (Entity uid u) -> return $ Just EmailCreds
{ emailCredsId = uid
, emailCredsAuthId = Just uid
, emailCredsStatus = isJust $ userPassword u
, emailCredsVerkey = emailVerkey u
, emailCredsEmail = email
}
getEmail = runDB . fmap (fmap emailEmail) . get
The config/models
is unchanged from the yesod init
scaffolding:
User
ident Text
password Text Maybe
UniqueUser ident
deriving Typeable
Email
email Text
user UserId Maybe
verkey Text Maybe
UniqueEmail email
I get a bunch of type errors, mostly because the functions (e.g. getVerifyKey
) are supposed to take/return User
s, not Email
s.
Why did they change to using a separate Email
table instead of keeping the verkey
and email
columns in the User
table anyway? I'm fairly certain my users will never need to register multiple email addresses. Do you recommend keeping it this way so it plays well with the different auth plugins?
Upvotes: 2
Views: 333
Reputation: 41
It looks like you could switch UserId
for EmailId
in type AuthEmailId App = UserId
and it might work without issue.
I think the scaffolded table is there for illustrative purposes (unique columns, joins) and demonstrates a nice conceptual separation between users and emails, but is not strictly necessary.
Upvotes: 2