{-# LANGUAGE QuasiQuotes, TypeFamilies #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} module Yesod.Auth.Email ( -- * Plugin authEmail , YesodAuthEmail (..) , EmailCreds (..) , saltPass -- * Routes , loginR , registerR , setpassR , isValidPass ) where import Network.Mail.Mime (randomString) import Yesod.Auth import System.Random import Control.Monad (when) import Control.Applicative ((<$>), (<*>)) import Data.Digest.Pure.MD5 import qualified Data.Text.Lazy as T import qualified Data.Text as TS import Data.Text.Lazy.Encoding (encodeUtf8) import Data.Text (Text) import qualified Crypto.PasswordStore as PS import qualified Data.Text.Encoding as DTE import Control.Monad.Trans.Class import Yesod.Form import Yesod.Core import qualified Yesod.Auth.Message as Msg loginR, registerR, setpassR :: AuthRoute loginR = PluginR "email" ["login"] registerR = PluginR "email" ["register"] setpassR = PluginR "email" ["set-password"] verify :: Text -> Text -> AuthRoute -- FIXME verify eid verkey = PluginR "email" ["verify", eid, verkey] type Email = Text type VerKey = Text type VerUrl = Text type SaltedPass = Text type VerStatus = Bool -- | Data stored in a database for each e-mail address. data EmailCreds m = EmailCreds { emailCredsId :: AuthEmailId m , emailCredsAuthId :: Maybe (AuthId m) , emailCredsStatus :: VerStatus , emailCredsVerkey :: Maybe VerKey } class (YesodAuth site, PathPiece (AuthEmailId site)) => YesodAuthEmail site where type AuthEmailId site addUnverified :: Email -> VerKey -> HandlerT site IO (AuthEmailId site) sendVerifyEmail :: Email -> VerKey -> VerUrl -> HandlerT site IO () getVerifyKey :: AuthEmailId site -> HandlerT site IO (Maybe VerKey) setVerifyKey :: AuthEmailId site -> VerKey -> HandlerT site IO () verifyAccount :: AuthEmailId site -> HandlerT site IO (Maybe (AuthId site)) getPassword :: AuthId site -> HandlerT site IO (Maybe SaltedPass) setPassword :: AuthId site -> SaltedPass -> HandlerT site IO () getEmailCreds :: Email -> HandlerT site IO (Maybe (EmailCreds site)) getEmail :: AuthEmailId site -> HandlerT site IO (Maybe Email) -- | Generate a random alphanumeric string. randomKey :: site -> IO Text randomKey _ = do stdgen <- newStdGen return $ TS.pack $ fst $ randomString 10 stdgen authEmail :: YesodAuthEmail m => AuthPlugin m authEmail = AuthPlugin "email" dispatch $ \tm -> [whamlet| $newline never