Merge pull request #1317 from psibi/json-auth
JSON endpoints for Auth.Email, haddock, and i18n fix
This commit is contained in:
commit
d7be78f82e
@ -1,6 +1,13 @@
|
|||||||
|
## 1.4.14.1
|
||||||
|
|
||||||
|
* Add JSON endpoints to Yesod.Auth.Email module
|
||||||
|
* Export croatianMessage from Message module
|
||||||
|
* Minor Haddock rendering fixes at Auth.Email module
|
||||||
|
|
||||||
## 1.4.14
|
## 1.4.14
|
||||||
|
|
||||||
* Remove Google OpenID link [#1309](https://github.com/yesodweb/yesod/pull/1309)
|
* Remove Google OpenID link [#1309](https://github.com/yesodweb/yesod/pull/1309)
|
||||||
|
* Add CSRF Security check in `registerHelperFunction` [#1302](https://github.com/yesodweb/yesod/pull/1302)
|
||||||
|
|
||||||
## 1.4.13.5
|
## 1.4.13.5
|
||||||
|
|
||||||
|
|||||||
@ -4,23 +4,30 @@
|
|||||||
{-# LANGUAGE PatternGuards #-}
|
{-# LANGUAGE PatternGuards #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
{-# LANGUAGE Rank2Types #-}
|
{-# LANGUAGE Rank2Types #-}
|
||||||
|
{-# LANGUAGE ScopedTypeVariables#-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
-- | A Yesod plugin for Authentication via e-mail
|
-- | A Yesod plugin for Authentication via e-mail
|
||||||
--
|
--
|
||||||
-- This plugin works out of the box by only setting a few methods on the type class
|
-- This plugin works out of the box by only setting a few methods on
|
||||||
-- that tell the plugin how to interoprate with your user data storage (your database).
|
-- the type class that tell the plugin how to interoperate with your
|
||||||
-- However, almost everything is customizeable by setting more methods on the type class.
|
-- user data storage (your database). However, almost everything is
|
||||||
-- In addition, you can send all the form submissions via JSON and completely control the user's flow.
|
-- customizeable by setting more methods on the type class. In
|
||||||
|
-- addition, you can send all the form submissions via JSON and
|
||||||
|
-- completely control the user's flow.
|
||||||
|
--
|
||||||
-- This is a standard registration e-mail flow
|
-- This is a standard registration e-mail flow
|
||||||
--
|
--
|
||||||
-- 1) A user registers a new e-mail address, and an e-mail is sent there
|
-- 1. A user registers a new e-mail address, and an e-mail is sent there
|
||||||
-- 2) The user clicks on the registration link in the e-mail
|
-- 2. The user clicks on the registration link in the e-mail. Note that
|
||||||
-- Note that at this point they are actually logged in (without a password)
|
-- at this point they are actually logged in (without a
|
||||||
-- That means that when they log out they will need to reset their password
|
-- password). That means that when they log out they will need to
|
||||||
-- 3) The user sets their password and is redirected to the site.
|
-- reset their password.
|
||||||
-- 4) The user can now
|
-- 3. The user sets their password and is redirected to the site.
|
||||||
-- * logout and sign in
|
-- 4. The user can now
|
||||||
-- * reset their password
|
--
|
||||||
|
-- * logout and sign in
|
||||||
|
-- * reset their password
|
||||||
|
--
|
||||||
module Yesod.Auth.Email
|
module Yesod.Auth.Email
|
||||||
( -- * Plugin
|
( -- * Plugin
|
||||||
authEmail
|
authEmail
|
||||||
@ -70,6 +77,9 @@ import Data.Time (addUTCTime, getCurrentTime)
|
|||||||
import Safe (readMay)
|
import Safe (readMay)
|
||||||
import System.IO.Unsafe (unsafePerformIO)
|
import System.IO.Unsafe (unsafePerformIO)
|
||||||
import qualified Text.Email.Validate
|
import qualified Text.Email.Validate
|
||||||
|
import Network.HTTP.Types.Status (status400)
|
||||||
|
import Data.Aeson.Types (Parser(..), Result(..), parseMaybe, withObject, (.:?))
|
||||||
|
import Data.Maybe (isJust, isNothing, fromJust)
|
||||||
|
|
||||||
loginR, registerR, forgotPasswordR, setpassR :: AuthRoute
|
loginR, registerR, forgotPasswordR, setpassR :: AuthRoute
|
||||||
loginR = PluginR "email" ["login"]
|
loginR = PluginR "email" ["login"]
|
||||||
@ -79,7 +89,7 @@ setpassR = PluginR "email" ["set-password"]
|
|||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
-- Since 1.4.5
|
-- @since 1.4.5
|
||||||
verifyR :: Text -> Text -> AuthRoute -- FIXME
|
verifyR :: Text -> Text -> AuthRoute -- FIXME
|
||||||
verifyR eid verkey = PluginR "email" ["verify", eid, verkey]
|
verifyR eid verkey = PluginR "email" ["verify", eid, verkey]
|
||||||
|
|
||||||
@ -94,7 +104,7 @@ type VerStatus = Bool
|
|||||||
--
|
--
|
||||||
-- Note that any of these other identifiers must not be valid email addresses.
|
-- Note that any of these other identifiers must not be valid email addresses.
|
||||||
--
|
--
|
||||||
-- Since 1.2.0
|
-- @since 1.2.0
|
||||||
type Identifier = Text
|
type Identifier = Text
|
||||||
|
|
||||||
-- | Data stored in a database for each e-mail address.
|
-- | Data stored in a database for each e-mail address.
|
||||||
@ -121,22 +131,22 @@ class ( YesodAuth site
|
|||||||
-- | Add a new email address to the database, but indicate that the address
|
-- | Add a new email address to the database, but indicate that the address
|
||||||
-- has not yet been verified.
|
-- has not yet been verified.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
addUnverified :: Email -> VerKey -> HandlerT site IO (AuthEmailId site)
|
addUnverified :: Email -> VerKey -> HandlerT site IO (AuthEmailId site)
|
||||||
|
|
||||||
-- | Send an email to the given address to verify ownership.
|
-- | Send an email to the given address to verify ownership.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
sendVerifyEmail :: Email -> VerKey -> VerUrl -> HandlerT site IO ()
|
sendVerifyEmail :: Email -> VerKey -> VerUrl -> HandlerT site IO ()
|
||||||
|
|
||||||
-- | Get the verification key for the given email ID.
|
-- | Get the verification key for the given email ID.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
getVerifyKey :: AuthEmailId site -> HandlerT site IO (Maybe VerKey)
|
getVerifyKey :: AuthEmailId site -> HandlerT site IO (Maybe VerKey)
|
||||||
|
|
||||||
-- | Set the verification key for the given email ID.
|
-- | Set the verification key for the given email ID.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
setVerifyKey :: AuthEmailId site -> VerKey -> HandlerT site IO ()
|
setVerifyKey :: AuthEmailId site -> VerKey -> HandlerT site IO ()
|
||||||
|
|
||||||
-- | Verify the email address on the given account.
|
-- | Verify the email address on the given account.
|
||||||
@ -147,39 +157,39 @@ class ( YesodAuth site
|
|||||||
--
|
--
|
||||||
-- See <https://github.com/yesodweb/yesod/issues/1222>.
|
-- See <https://github.com/yesodweb/yesod/issues/1222>.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
verifyAccount :: AuthEmailId site -> HandlerT site IO (Maybe (AuthId site))
|
verifyAccount :: AuthEmailId site -> HandlerT site IO (Maybe (AuthId site))
|
||||||
|
|
||||||
-- | Get the salted password for the given account.
|
-- | Get the salted password for the given account.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
getPassword :: AuthId site -> HandlerT site IO (Maybe SaltedPass)
|
getPassword :: AuthId site -> HandlerT site IO (Maybe SaltedPass)
|
||||||
|
|
||||||
-- | Set the salted password for the given account.
|
-- | Set the salted password for the given account.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
setPassword :: AuthId site -> SaltedPass -> HandlerT site IO ()
|
setPassword :: AuthId site -> SaltedPass -> HandlerT site IO ()
|
||||||
|
|
||||||
-- | Get the credentials for the given @Identifier@, which may be either an
|
-- | Get the credentials for the given @Identifier@, which may be either an
|
||||||
-- email address or some other identification (e.g., username).
|
-- email address or some other identification (e.g., username).
|
||||||
--
|
--
|
||||||
-- Since 1.2.0
|
-- @since 1.2.0
|
||||||
getEmailCreds :: Identifier -> HandlerT site IO (Maybe (EmailCreds site))
|
getEmailCreds :: Identifier -> HandlerT site IO (Maybe (EmailCreds site))
|
||||||
|
|
||||||
-- | Get the email address for the given email ID.
|
-- | Get the email address for the given email ID.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
getEmail :: AuthEmailId site -> HandlerT site IO (Maybe Email)
|
getEmail :: AuthEmailId site -> HandlerT site IO (Maybe Email)
|
||||||
|
|
||||||
-- | Generate a random alphanumeric string.
|
-- | Generate a random alphanumeric string.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- @since 1.1.0
|
||||||
randomKey :: site -> IO Text
|
randomKey :: site -> IO Text
|
||||||
randomKey _ = Nonce.nonce128urlT defaultNonceGen
|
randomKey _ = Nonce.nonce128urlT defaultNonceGen
|
||||||
|
|
||||||
-- | Route to send user to after password has been set correctly.
|
-- | Route to send user to after password has been set correctly.
|
||||||
--
|
--
|
||||||
-- Since 1.2.0
|
-- @since 1.2.0
|
||||||
afterPasswordRoute :: site -> Route site
|
afterPasswordRoute :: site -> Route site
|
||||||
|
|
||||||
-- | Does the user need to provide the current password in order to set a
|
-- | Does the user need to provide the current password in order to set a
|
||||||
@ -187,7 +197,7 @@ class ( YesodAuth site
|
|||||||
--
|
--
|
||||||
-- Default: if the user logged in via an email link do not require a password.
|
-- Default: if the user logged in via an email link do not require a password.
|
||||||
--
|
--
|
||||||
-- Since 1.2.1
|
-- @since 1.2.1
|
||||||
needOldPassword :: AuthId site -> HandlerT site IO Bool
|
needOldPassword :: AuthId site -> HandlerT site IO Bool
|
||||||
needOldPassword aid' = do
|
needOldPassword aid' = do
|
||||||
mkey <- lookupSession loginLinkKey
|
mkey <- lookupSession loginLinkKey
|
||||||
@ -207,7 +217,7 @@ class ( YesodAuth site
|
|||||||
|
|
||||||
-- | Response after sending a confirmation email.
|
-- | Response after sending a confirmation email.
|
||||||
--
|
--
|
||||||
-- Since 1.2.2
|
-- @since 1.2.2
|
||||||
confirmationEmailSentResponse :: Text -> HandlerT site IO TypedContent
|
confirmationEmailSentResponse :: Text -> HandlerT site IO TypedContent
|
||||||
confirmationEmailSentResponse identifier = do
|
confirmationEmailSentResponse identifier = do
|
||||||
mr <- getMessageRender
|
mr <- getMessageRender
|
||||||
@ -223,7 +233,7 @@ class ( YesodAuth site
|
|||||||
--
|
--
|
||||||
-- Default: Lower case the email address.
|
-- Default: Lower case the email address.
|
||||||
--
|
--
|
||||||
-- Since 1.2.3
|
-- @since 1.2.3
|
||||||
normalizeEmailAddress :: site -> Text -> Text
|
normalizeEmailAddress :: site -> Text -> Text
|
||||||
normalizeEmailAddress _ = TS.toLower
|
normalizeEmailAddress _ = TS.toLower
|
||||||
|
|
||||||
@ -233,7 +243,7 @@ class ( YesodAuth site
|
|||||||
--
|
--
|
||||||
-- Default: 'defaultRegisterHandler'.
|
-- Default: 'defaultRegisterHandler'.
|
||||||
--
|
--
|
||||||
-- Since: 1.2.6.
|
-- @since: 1.2.6
|
||||||
registerHandler :: AuthHandler site Html
|
registerHandler :: AuthHandler site Html
|
||||||
registerHandler = defaultRegisterHandler
|
registerHandler = defaultRegisterHandler
|
||||||
|
|
||||||
@ -243,7 +253,7 @@ class ( YesodAuth site
|
|||||||
--
|
--
|
||||||
-- Default: 'defaultForgotPasswordHandler'.
|
-- Default: 'defaultForgotPasswordHandler'.
|
||||||
--
|
--
|
||||||
-- Since: 1.2.6.
|
-- @since: 1.2.6
|
||||||
forgotPasswordHandler :: AuthHandler site Html
|
forgotPasswordHandler :: AuthHandler site Html
|
||||||
forgotPasswordHandler = defaultForgotPasswordHandler
|
forgotPasswordHandler = defaultForgotPasswordHandler
|
||||||
|
|
||||||
@ -253,7 +263,7 @@ class ( YesodAuth site
|
|||||||
--
|
--
|
||||||
-- Default: 'defaultSetPasswordHandler'.
|
-- Default: 'defaultSetPasswordHandler'.
|
||||||
--
|
--
|
||||||
-- Since: 1.2.6.
|
-- @since: 1.2.6
|
||||||
setPasswordHandler ::
|
setPasswordHandler ::
|
||||||
Bool
|
Bool
|
||||||
-- ^ Whether the old password is needed. If @True@, a
|
-- ^ Whether the old password is needed. If @True@, a
|
||||||
@ -340,7 +350,7 @@ emailLoginHandler toParent = do
|
|||||||
return $ renderAuthMessage master langs msg
|
return $ renderAuthMessage master langs msg
|
||||||
-- | Default implementation of 'registerHandler'.
|
-- | Default implementation of 'registerHandler'.
|
||||||
--
|
--
|
||||||
-- Since: 1.2.6
|
-- @since 1.2.6
|
||||||
defaultRegisterHandler :: YesodAuthEmail master => AuthHandler master Html
|
defaultRegisterHandler :: YesodAuthEmail master => AuthHandler master Html
|
||||||
defaultRegisterHandler = do
|
defaultRegisterHandler = do
|
||||||
(widget, enctype) <- lift $ generateFormPost registrationForm
|
(widget, enctype) <- lift $ generateFormPost registrationForm
|
||||||
@ -376,6 +386,11 @@ defaultRegisterHandler = do
|
|||||||
|
|
||||||
return (userRes, widget)
|
return (userRes, widget)
|
||||||
|
|
||||||
|
parseEmail :: Value -> Parser Text
|
||||||
|
parseEmail = withObject "email" (\obj -> do
|
||||||
|
email' <- obj .: "email"
|
||||||
|
return email')
|
||||||
|
|
||||||
registerHelper :: YesodAuthEmail master
|
registerHelper :: YesodAuthEmail master
|
||||||
=> Bool -- ^ allow usernames?
|
=> Bool -- ^ allow usernames?
|
||||||
-> Route Auth
|
-> Route Auth
|
||||||
@ -383,7 +398,15 @@ registerHelper :: YesodAuthEmail master
|
|||||||
registerHelper allowUsername dest = do
|
registerHelper allowUsername dest = do
|
||||||
y <- lift getYesod
|
y <- lift getYesod
|
||||||
checkCsrfHeaderOrParam defaultCsrfHeaderName defaultCsrfParamName
|
checkCsrfHeaderOrParam defaultCsrfHeaderName defaultCsrfParamName
|
||||||
midentifier <- lookupPostParam "email"
|
pidentifier <- lookupPostParam "email"
|
||||||
|
midentifier <- case pidentifier of
|
||||||
|
Nothing -> do
|
||||||
|
(jidentifier :: Result Value) <- lift parseJsonBody
|
||||||
|
case jidentifier of
|
||||||
|
Error _ -> return Nothing
|
||||||
|
Success val -> return $ parseMaybe parseEmail val
|
||||||
|
Just _ -> return pidentifier
|
||||||
|
|
||||||
let eidentifier = case midentifier of
|
let eidentifier = case midentifier of
|
||||||
Nothing -> Left Msg.NoIdentifierProvided
|
Nothing -> Left Msg.NoIdentifierProvided
|
||||||
Just x
|
Just x
|
||||||
@ -425,7 +448,7 @@ getForgotPasswordR = forgotPasswordHandler
|
|||||||
|
|
||||||
-- | Default implementation of 'forgotPasswordHandler'.
|
-- | Default implementation of 'forgotPasswordHandler'.
|
||||||
--
|
--
|
||||||
-- Since: 1.2.6
|
-- @since 1.2.6
|
||||||
defaultForgotPasswordHandler :: YesodAuthEmail master => AuthHandler master Html
|
defaultForgotPasswordHandler :: YesodAuthEmail master => AuthHandler master Html
|
||||||
defaultForgotPasswordHandler = do
|
defaultForgotPasswordHandler = do
|
||||||
(widget, enctype) <- lift $ generateFormPost forgotPasswordForm
|
(widget, enctype) <- lift $ generateFormPost forgotPasswordForm
|
||||||
@ -497,38 +520,56 @@ $newline never
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
|
|
||||||
|
parseCreds :: Value -> Parser (Text, Text)
|
||||||
|
parseCreds = withObject "creds" (\obj -> do
|
||||||
|
email' <- obj .: "email"
|
||||||
|
pass <- obj .: "password"
|
||||||
|
return (email', pass))
|
||||||
|
|
||||||
|
|
||||||
postLoginR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent
|
postLoginR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent
|
||||||
postLoginR = do
|
postLoginR = do
|
||||||
(identifier, pass) <- lift $ runInputPost $ (,)
|
result <- lift $ runInputPostResult $ (,)
|
||||||
<$> ireq textField "email"
|
<$> ireq textField "email"
|
||||||
<*> ireq textField "password"
|
<*> ireq textField "password"
|
||||||
mecreds <- lift $ getEmailCreds identifier
|
|
||||||
maid <-
|
midentifier <- case result of
|
||||||
case ( mecreds >>= emailCredsAuthId
|
FormSuccess (iden, pass) -> return $ Just (iden, pass)
|
||||||
, emailCredsEmail <$> mecreds
|
_ -> do
|
||||||
, emailCredsStatus <$> mecreds
|
(creds :: Result Value) <- lift parseJsonBody
|
||||||
) of
|
case creds of
|
||||||
(Just aid, Just email, Just True) -> do
|
Error _ -> return Nothing
|
||||||
mrealpass <- lift $ getPassword aid
|
Success val -> return $ parseMaybe parseCreds val
|
||||||
case mrealpass of
|
|
||||||
Nothing -> return Nothing
|
case midentifier of
|
||||||
Just realpass -> return $
|
Nothing -> loginErrorMessageI LoginR Msg.NoIdentifierProvided
|
||||||
if isValidPass pass realpass
|
Just (identifier, pass) -> do
|
||||||
then Just email
|
mecreds <- lift $ getEmailCreds identifier
|
||||||
else Nothing
|
maid <-
|
||||||
_ -> return Nothing
|
case ( mecreds >>= emailCredsAuthId
|
||||||
let isEmail = Text.Email.Validate.isValid $ encodeUtf8 identifier
|
, emailCredsEmail <$> mecreds
|
||||||
case maid of
|
, emailCredsStatus <$> mecreds
|
||||||
Just email ->
|
) of
|
||||||
lift $ setCredsRedirect $ Creds
|
(Just aid, Just email, Just True) -> do
|
||||||
(if isEmail then "email" else "username")
|
mrealpass <- lift $ getPassword aid
|
||||||
email
|
case mrealpass of
|
||||||
[("verifiedEmail", email)]
|
Nothing -> return Nothing
|
||||||
Nothing ->
|
Just realpass -> return $ if isValidPass pass realpass
|
||||||
loginErrorMessageI LoginR $
|
then Just email
|
||||||
if isEmail
|
else Nothing
|
||||||
then Msg.InvalidEmailPass
|
_ -> return Nothing
|
||||||
else Msg.InvalidUsernamePass
|
let isEmail = Text.Email.Validate.isValid $ encodeUtf8 identifier
|
||||||
|
case maid of
|
||||||
|
Just email ->
|
||||||
|
lift $ setCredsRedirect $ Creds
|
||||||
|
(if isEmail then "email" else "username")
|
||||||
|
email
|
||||||
|
[("verifiedEmail", email)]
|
||||||
|
Nothing ->
|
||||||
|
loginErrorMessageI LoginR $
|
||||||
|
if isEmail
|
||||||
|
then Msg.InvalidEmailPass
|
||||||
|
else Msg.InvalidUsernamePass
|
||||||
|
|
||||||
getPasswordR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent
|
getPasswordR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent
|
||||||
getPasswordR = do
|
getPasswordR = do
|
||||||
@ -541,7 +582,7 @@ getPasswordR = do
|
|||||||
|
|
||||||
-- | Default implementation of 'setPasswordHandler'.
|
-- | Default implementation of 'setPasswordHandler'.
|
||||||
--
|
--
|
||||||
-- Since: 1.2.6
|
-- @since 1.2.6
|
||||||
defaultSetPasswordHandler :: YesodAuthEmail master => Bool -> AuthHandler master TypedContent
|
defaultSetPasswordHandler :: YesodAuthEmail master => Bool -> AuthHandler master TypedContent
|
||||||
defaultSetPasswordHandler needOld = do
|
defaultSetPasswordHandler needOld = do
|
||||||
messageRender <- lift getMessageRender
|
messageRender <- lift getMessageRender
|
||||||
@ -614,54 +655,81 @@ defaultSetPasswordHandler needOld = do
|
|||||||
fsAttrs = [("autofocus", "")]
|
fsAttrs = [("autofocus", "")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parsePassword :: Value -> Parser (Text, Text, Maybe Text)
|
||||||
|
parsePassword = withObject "password" (\obj -> do
|
||||||
|
email' <- obj .: "new"
|
||||||
|
pass <- obj .: "confirm"
|
||||||
|
curr <- obj .:? "current"
|
||||||
|
return (email', pass, curr))
|
||||||
|
|
||||||
postPasswordR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent
|
postPasswordR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent
|
||||||
postPasswordR = do
|
postPasswordR = do
|
||||||
maid <- lift maybeAuthId
|
maid <- lift maybeAuthId
|
||||||
|
(creds :: Result Value) <- lift parseJsonBody
|
||||||
|
let jcreds = case creds of
|
||||||
|
Error _ -> Nothing
|
||||||
|
Success val -> parseMaybe parsePassword val
|
||||||
|
let doJsonParsing = isJust jcreds
|
||||||
case maid of
|
case maid of
|
||||||
Nothing -> loginErrorMessageI LoginR Msg.BadSetPass
|
Nothing -> loginErrorMessageI LoginR Msg.BadSetPass
|
||||||
Just aid -> do
|
Just aid -> do
|
||||||
tm <- getRouteToParent
|
tm <- getRouteToParent
|
||||||
|
|
||||||
needOld <- lift $ needOldPassword aid
|
needOld <- lift $ needOldPassword aid
|
||||||
if not needOld then confirmPassword aid tm else do
|
if not needOld then confirmPassword aid tm jcreds else do
|
||||||
current <- lift $ runInputPost $ ireq textField "current"
|
res <- lift $ runInputPostResult $ ireq textField "current"
|
||||||
|
let fcurrent = case res of
|
||||||
|
FormSuccess currentPass -> Just currentPass
|
||||||
|
_ -> Nothing
|
||||||
|
let current = if doJsonParsing
|
||||||
|
then getThird jcreds
|
||||||
|
else fcurrent
|
||||||
mrealpass <- lift $ getPassword aid
|
mrealpass <- lift $ getPassword aid
|
||||||
case mrealpass of
|
case mrealpass of
|
||||||
Nothing ->
|
Nothing ->
|
||||||
lift $ loginErrorMessage (tm setpassR) "You do not currently have a password set on your account"
|
lift $ loginErrorMessage (tm setpassR) "You do not currently have a password set on your account"
|
||||||
Just realpass
|
Just realpass
|
||||||
| isValidPass current realpass -> confirmPassword aid tm
|
| isNothing current -> loginErrorMessageI LoginR Msg.BadSetPass
|
||||||
|
| isValidPass (fromJust current) realpass -> confirmPassword aid tm jcreds
|
||||||
| otherwise ->
|
| otherwise ->
|
||||||
lift $ loginErrorMessage (tm setpassR) "Invalid current password, please try again"
|
lift $ loginErrorMessage (tm setpassR) "Invalid current password, please try again"
|
||||||
|
|
||||||
where
|
where
|
||||||
msgOk = Msg.PassUpdated
|
msgOk = Msg.PassUpdated
|
||||||
confirmPassword aid tm = do
|
getThird (Just (_,_,t)) = t
|
||||||
(new, confirm) <- lift $ runInputPost $ (,)
|
getThird Nothing = Nothing
|
||||||
|
getNewConfirm (Just (a,b,_)) = Just (a,b)
|
||||||
|
getNewConfirm _ = Nothing
|
||||||
|
confirmPassword aid tm jcreds = do
|
||||||
|
res <- lift $ runInputPostResult $ (,)
|
||||||
<$> ireq textField "new"
|
<$> ireq textField "new"
|
||||||
<*> ireq textField "confirm"
|
<*> ireq textField "confirm"
|
||||||
|
let creds = if (isJust jcreds)
|
||||||
if new /= confirm
|
then getNewConfirm jcreds
|
||||||
then loginErrorMessageI setpassR Msg.PassMismatch
|
else case res of
|
||||||
else do
|
FormSuccess res' -> Just res'
|
||||||
isSecure <- lift $ checkPasswordSecurity aid new
|
_ -> Nothing
|
||||||
case isSecure of
|
case creds of
|
||||||
|
Nothing -> loginErrorMessageI setpassR Msg.PassMismatch
|
||||||
|
Just (new, confirm) ->
|
||||||
|
if new /= confirm
|
||||||
|
then loginErrorMessageI setpassR Msg.PassMismatch
|
||||||
|
else do
|
||||||
|
isSecure <- lift $ checkPasswordSecurity aid new
|
||||||
|
case isSecure of
|
||||||
Left e -> lift $ loginErrorMessage (tm setpassR) e
|
Left e -> lift $ loginErrorMessage (tm setpassR) e
|
||||||
Right () -> do
|
Right () -> do
|
||||||
salted <- liftIO $ saltPass new
|
salted <- liftIO $ saltPass new
|
||||||
y <- lift $ do
|
y <- lift $ do
|
||||||
setPassword aid salted
|
setPassword aid salted
|
||||||
deleteSession loginLinkKey
|
deleteSession loginLinkKey
|
||||||
addMessageI "success" msgOk
|
addMessageI "success" msgOk
|
||||||
getYesod
|
getYesod
|
||||||
|
|
||||||
mr <- lift getMessageRender
|
mr <- lift getMessageRender
|
||||||
selectRep $ do
|
selectRep $ do
|
||||||
provideRep $
|
provideRep $
|
||||||
fmap asHtml $ lift $ redirect $ afterPasswordRoute y
|
fmap asHtml $ lift $ redirect $ afterPasswordRoute y
|
||||||
provideJsonMessage (mr msgOk)
|
provideJsonMessage (mr msgOk)
|
||||||
|
|
||||||
saltLength :: Int
|
saltLength :: Int
|
||||||
saltLength = 5
|
saltLength = 5
|
||||||
@ -695,13 +763,13 @@ isValidPass' clear' salted' =
|
|||||||
-- | Session variable set when user logged in via a login link. See
|
-- | Session variable set when user logged in via a login link. See
|
||||||
-- 'needOldPassword'.
|
-- 'needOldPassword'.
|
||||||
--
|
--
|
||||||
-- Since 1.2.1
|
-- @since 1.2.1
|
||||||
loginLinkKey :: Text
|
loginLinkKey :: Text
|
||||||
loginLinkKey = "_AUTH_EMAIL_LOGIN_LINK"
|
loginLinkKey = "_AUTH_EMAIL_LOGIN_LINK"
|
||||||
|
|
||||||
-- | Set 'loginLinkKey' to the current time.
|
-- | Set 'loginLinkKey' to the current time.
|
||||||
--
|
--
|
||||||
-- Since 1.2.1
|
-- @since 1.2.1
|
||||||
setLoginLinkKey :: (YesodAuthEmail site, MonadHandler m, HandlerSite m ~ site) => AuthId site -> m ()
|
setLoginLinkKey :: (YesodAuthEmail site, MonadHandler m, HandlerSite m ~ site) => AuthId site -> m ()
|
||||||
setLoginLinkKey aid = do
|
setLoginLinkKey aid = do
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
|
|||||||
@ -13,6 +13,7 @@ module Yesod.Auth.Message
|
|||||||
, japaneseMessage
|
, japaneseMessage
|
||||||
, finnishMessage
|
, finnishMessage
|
||||||
, chineseMessage
|
, chineseMessage
|
||||||
|
, croatianMessage
|
||||||
, spanishMessage
|
, spanishMessage
|
||||||
, czechMessage
|
, czechMessage
|
||||||
, russianMessage
|
, russianMessage
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user