packages feed

yesod-auth 1.4.8 → 1.4.11

raw patch · 5 files changed

+275/−17 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Yesod.Auth: defaultLoginHandler :: AuthHandler master Html
+ Yesod.Auth.Hardcoded: authHardcoded :: YesodAuthHardcoded m => AuthPlugin m
+ Yesod.Auth.Hardcoded: class (YesodAuth site) => YesodAuthHardcoded site
+ Yesod.Auth.Hardcoded: doesUserNameExist :: YesodAuthHardcoded site => Text -> HandlerT site IO Bool
+ Yesod.Auth.Hardcoded: loginR :: AuthRoute
+ Yesod.Auth.Hardcoded: validatePassword :: YesodAuthHardcoded site => Text -> Text -> HandlerT site IO Bool
+ Yesod.Auth.Message: LogoutTitle :: AuthMessage
+ Yesod.Auth.Message: UserName :: AuthMessage
- Yesod.Auth: class (Yesod master, PathPiece (AuthId master), RenderMessage master FormMessage) => YesodAuth master where type family AuthId master authLayout = defaultLayout authenticate creds = do { muid <- getAuthId creds; return $ maybe (UserError InvalidLogin) Authenticated muid } getAuthId creds = do { auth <- authenticate creds; return $ case auth of { Authenticated auid -> Just auid _ -> Nothing } } loginHandler = do { tp <- getRouteToParent; lift $ authLayout $ do { setTitleI LoginTitle; master <- getYesod; mapM_ (flip apLogin tp) (authPlugins master) } } renderAuthMessage _ _ = defaultMessage redirectToReferer _ = False onLogin = setMessageI NowLoggedIn onLogout = return () maybeAuthId = defaultMaybeAuthId onErrorHtml dest msg = do { setMessage $ toHtml msg; fmap asHtml $ redirect dest } runHttpRequest req inner = do { man <- authHttpManager <$> getYesod; HandlerT $ \ t -> withResponse req man $ \ res -> unHandlerT (inner res) t }
+ Yesod.Auth: class (Yesod master, PathPiece (AuthId master), RenderMessage master FormMessage) => YesodAuth master where type family AuthId master authLayout = defaultLayout authenticate creds = do { muid <- getAuthId creds; return $ maybe (UserError InvalidLogin) Authenticated muid } getAuthId creds = do { auth <- authenticate creds; return $ case auth of { Authenticated auid -> Just auid _ -> Nothing } } loginHandler = defaultLoginHandler renderAuthMessage _ _ = defaultMessage redirectToReferer _ = False onLogin = setMessageI NowLoggedIn onLogout = return () maybeAuthId = defaultMaybeAuthId onErrorHtml dest msg = do { setMessage $ toHtml msg; fmap asHtml $ redirect dest } runHttpRequest req inner = do { man <- authHttpManager <$> getYesod; HandlerT $ \ t -> withResponse req man $ \ res -> unHandlerT (inner res) t }
- Yesod.Auth.Email: class (YesodAuth site, PathPiece (AuthEmailId site), RenderMessage site AuthMessage) => YesodAuthEmail site where type family AuthEmailId site randomKey _ = nonce128urlT defaultNonceGen needOldPassword aid' = do { mkey <- lookupSession loginLinkKey; case mkey >>= readMay . unpack of { Just (aidT, time) | Just aid <- fromPathPiece aidT, toPathPiece (aid `asTypeOf` aid') == toPathPiece aid' -> do { now <- liftIO getCurrentTime; return $ addUTCTime (60 * 30) time <= now } _ -> return True } } checkPasswordSecurity _ x | length x >= 3 = return $ Right () | otherwise = return $ Left "Password must be at least three characters" confirmationEmailSentResponse identifier = do { mr <- getMessageRender; selectRep $ do { provideJsonMessage (mr msg); provideRep $ authLayout $ do { setTitleI ConfirmationEmailSentTitle; (do { (asWidgetT . toWidget) ((preEscapedText . pack) "<p>"); ((liftM (toHtml .) getMessageRender) >>= (\ urender_ayV3 -> (asWidgetT . toWidget) (urender_ayV3 msg))); (asWidgetT . toWidget) ((preEscapedText . pack) "</p>\n") }) } } } where msg = ConfirmationEmailSent identifier normalizeEmailAddress _ = toLower registerHandler = defaultRegisterHandler forgotPasswordHandler = defaultForgotPasswordHandler setPasswordHandler = defaultSetPasswordHandler
+ Yesod.Auth.Email: class (YesodAuth site, PathPiece (AuthEmailId site), RenderMessage site AuthMessage) => YesodAuthEmail site where type family AuthEmailId site randomKey _ = nonce128urlT defaultNonceGen needOldPassword aid' = do { mkey <- lookupSession loginLinkKey; case mkey >>= readMay . unpack of { Just (aidT, time) | Just aid <- fromPathPiece aidT, toPathPiece (aid `asTypeOf` aid') == toPathPiece aid' -> do { now <- liftIO getCurrentTime; return $ addUTCTime (60 * 30) time <= now } _ -> return True } } checkPasswordSecurity _ x | length x >= 3 = return $ Right () | otherwise = return $ Left "Password must be at least three characters" confirmationEmailSentResponse identifier = do { mr <- getMessageRender; selectRep $ do { provideJsonMessage (mr msg); provideRep $ authLayout $ do { setTitleI ConfirmationEmailSentTitle; (do { (asWidgetT . toWidget) ((preEscapedText . pack) "<p>"); ((liftM (toHtml .) getMessageRender) >>= (\ urender_azc7 -> (asWidgetT . toWidget) (urender_azc7 msg))); (asWidgetT . toWidget) ((preEscapedText . pack) "</p>\n") }) } } } where msg = ConfirmationEmailSent identifier normalizeEmailAddress _ = toLower registerHandler = defaultRegisterHandler forgotPasswordHandler = defaultForgotPasswordHandler setPasswordHandler = defaultSetPasswordHandler

Files

ChangeLog.md view
@@ -1,3 +1,11 @@+## 1.4.11++Add Yesod.Auth.Hardcoded++## 1.4.9++* Expose defaultLoginHandler+ ## 1.4.8  * GoogleEmail2: proper error message when permission denied
Yesod/Auth.hs view
@@ -30,6 +30,7 @@       -- * User functions     , AuthenticationResult (..)     , defaultMaybeAuthId+    , defaultLoginHandler     , maybeAuthPair     , maybeAuth     , requireAuthId@@ -149,16 +150,25 @@      -- | What to show on the login page.     ---    -- Default handler concatenates plugin widgets and wraps the result-    -- in 'authLayout'. Override if you need fancy widget containers-    -- or entirely custom page.+    -- By default this calls 'defaultLoginHandler', which concatenates+    -- plugin widgets and wraps the result in 'authLayout'. Override if+    -- you need fancy widget containers, additional functionality, or an+    -- entirely custom page.  For example, in some applications you may+    -- want to prevent the login page being displayed for a user who is+    -- already logged in, even if the URL is visited explicitly; this can+    -- be done by overriding 'loginHandler' in your instance declaration+    -- with something like:+    --+    -- > instance YesodAuth App where+    -- >     ...+    -- >     loginHandler = do+    -- >         ma <- lift maybeAuthId+    -- >         when (isJust ma) $+    -- >             lift $ redirect HomeR   -- or any other Handler code you want+    -- >         defaultLoginHandler+    --      loginHandler :: AuthHandler master Html-    loginHandler = do-        tp <- getRouteToParent-        lift $ authLayout $ do-            setTitleI Msg.LoginTitle-            master <- getYesod-            mapM_ (flip apLogin tp) (authPlugins master)+    loginHandler = defaultLoginHandler      -- | Used for i18n of messages provided by this package.     renderAuthMessage :: master@@ -253,6 +263,21 @@     . cached     . fmap CachedMaybeAuth     . getAuthEntity+++-- | Default handler to show the login page.+--+-- This is the default 'loginHandler'.  It concatenates plugin widgets and+-- wraps the result in 'authLayout'.  See 'loginHandler' for more details.+--+-- Since 1.4.9+defaultLoginHandler :: AuthHandler master Html+defaultLoginHandler = do+    tp <- getRouteToParent+    lift $ authLayout $ do+        setTitleI Msg.LoginTitle+        master <- getYesod+        mapM_ (flip apLogin tp) (authPlugins master)   loginErrorMessageI :: (MonadResourceBase m, YesodAuth master)
+ Yesod/Auth/Hardcoded.hs view
@@ -0,0 +1,195 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE QuasiQuotes           #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE TemplateHaskell       #-}+{-# LANGUAGE TypeFamilies          #-}+{-|+Module      : Yesod.Auth.Hardcoded+Description : Very simple auth plugin for hardcoded auth pairs.+Copyright   : (c) Arthur Fayzrakhmanov, 2015+License     : MIT+Maintainer  : heraldhoi@gmail.com+Stability   : experimental++Sometimes you may want to have some hardcoded set of users (e.g. site managers)+that allowed to log in and visit some specific sections of your website without+ability to register new managers.  This simple plugin is designed exactly for+this purpose.++Here is a quick usage example.++== Define hardcoded users representation++Let's assume, that we want to have some hardcoded managers with normal site+users.  Let's define hardcoded user representation:++@+data SiteManager = SiteManager+  { manUserName :: Text+  , manPassWord :: Text }+  deriving Show++siteManagers :: [SiteManager]+siteManagers = [SiteManager "content editor" "top secret"]+@+++== Describe 'YesodAuth' instance++Now we need to have some convenient 'AuthId' type representing both+cases:++@+instance YesodAuth App where+  type AuthId App = Either UserId Text+@++Here, right @Text@ value will present hardcoded user name (which obviously must+be unique).++'AuthId' must have an instance of 'PathPiece' class, this is needed to store+user identifier in session (this happens in 'setCreds' and 'setCredsRedirect'+actions) and to read that identifier from session (this happens in+`dafaultMaybeAuthId` action).  So we have to define it:++@+import Text.Read (readMaybe)++instance PathPiece (Either UserId Text) where+  fromPathPiece = readMaybe . unpack+  toPathPiece = pack . show+@++Quiet simple so far.  Now let's add plugin to 'authPlugins' list, and define+'authenticate' method, it should return user identifier for given credentials,+for normal users it is usually persistent key, for hardcoded users we will+return user name again.++@+instance YesodAuth App where+  -- ..+  authPlugins _ = [authHardcoded]++  authenticate Creds{..} =+    return+      (case credsPlugin of+         "hardcoded" ->+           case lookupUser credsIdent of+             Nothing -> UserError InvalidLogin+             Just m  -> Authenticated (Right (manUserName m)))+@++Here @lookupUser@ is just a helper function to lookup hardcoded users by name:++@+lookupUser :: Text -> Maybe SiteManager+lookupUser username = find (\m -> manUserName m == username) siteManagers+@+++== Describe an 'YesodAuthPersist' instance++Now we need to manually define 'YesodAuthPersist' instance.++> instance YesodAuthPersist App where+>   type AuthEntity App = Either User SiteManager+>+>   getAuthEntity (Left uid) =+>     do x <- runDB (get uid)+>        return (Left <$> x)+>   getAuthEntity (Right username) = return (Right <$> lookupUser username)+++== Define 'YesodAuthHardcoded' instance++Finally, let's define an plugin instance++@+instance YesodAuthHardcoded App where+  validatePassword u = return . validPassword u+  doesUserNameExist  = return . isJust . lookupUser++validPassword :: Text -> Text -> Bool+validPassword u p =+  case find (\m -> manUserName m == u && manPassWord m == p) siteManagers of+    Just _ -> True+    _      -> False+@+++== Conclusion++Now we can use 'maybeAuthId', 'maybeAuthPair', 'requireAuthId', and+'requireAuthPair', moreover, the returned value makes possible to distinguish+normal users and site managers.+-}+module Yesod.Auth.Hardcoded+  ( YesodAuthHardcoded(..)+  , authHardcoded+  , loginR )+  where++import           Yesod.Auth          (Auth, AuthPlugin (..), AuthRoute,+                                      Creds (..), Route (..), YesodAuth,+                                      loginErrorMessageI, setCredsRedirect)+import qualified Yesod.Auth.Message  as Msg+import           Yesod.Core+import           Yesod.Form          (ireq, runInputPost, textField)++import           Control.Applicative ((<$>), (<*>))+import           Data.Text           (Text)+++loginR :: AuthRoute+loginR = PluginR "hardcoded" ["login"]++class (YesodAuth site) => YesodAuthHardcoded site where++  -- | Check whether given user name exists among hardcoded names.+  doesUserNameExist :: Text -> HandlerT site IO Bool++  -- | Validate given user name with given password.+  validatePassword :: Text -> Text -> HandlerT site IO Bool+++authHardcoded :: YesodAuthHardcoded m => AuthPlugin m+authHardcoded =+  AuthPlugin "hardcoded" dispatch loginWidget+  where+    dispatch "POST" ["login"] = postLoginR >>= sendResponse+    dispatch _ _ = notFound+    loginWidget toMaster =+      [whamlet|+        $newline never+        <form method="post" action="@{toMaster loginR}">+          <table>+            <tr>+              <th>_{Msg.UserName}+              <td>+                 <input type="text" name="username" required>+            <tr>+              <th>_{Msg.Password}+              <td>+                 <input type="password" name="password" required>+            <tr>+              <td colspan="2">+                 <button type="submit" .btn .btn-success>_{Msg.LoginTitle}+        |]+++postLoginR :: (YesodAuthHardcoded master)+           => HandlerT Auth (HandlerT master IO) TypedContent+postLoginR =+  do (username, password) <- lift (runInputPost+       ((,) <$> ireq textField "username"+            <*> ireq textField "password"))+     isValid <- lift (validatePassword username password)+     if isValid+        then lift (setCredsRedirect (Creds "hardcoded" username []))+        else do isExists <- lift (doesUserNameExist username)+                loginErrorMessageI LoginR+                                   (if isExists+                                       then Msg.InvalidUsernamePass+                                       else Msg.IdentifierNotFound username)
Yesod/Auth/Message.hs view
@@ -19,8 +19,8 @@     , dutchMessage     ) where -import Data.Monoid (mappend)-import Data.Text (Text)+import           Data.Monoid (mappend)+import           Data.Text   (Text)  data AuthMessage =       NoOpenID@@ -28,6 +28,7 @@     | LoginGoogle     | LoginYahoo     | Email+    | UserName     | IdentifierNotFound Text     | Password     | Register@@ -61,7 +62,9 @@     | PasswordResetPrompt     | InvalidUsernamePass     | Logout+    | LogoutTitle     | AuthError+{-# DEPRECATED Logout "Please, use LogoutTitle instead." #-}  -- | Defaults to 'englishMessage'. defaultMessage :: AuthMessage -> Text@@ -73,6 +76,7 @@ englishMessage LoginGoogle = "Login via Google" englishMessage LoginYahoo = "Login via Yahoo" englishMessage Email = "Email"+englishMessage UserName = "User name" englishMessage Password = "Password" englishMessage Register = "Register" englishMessage RegisterLong = "Register a new account"@@ -97,7 +101,7 @@ englishMessage LoginViaEmail = "Login via email" englishMessage InvalidLogin = "Invalid login" englishMessage NowLoggedIn = "You are now logged in"-englishMessage LoginTitle = "Login"+englishMessage LoginTitle = "Log In" englishMessage PleaseProvideUsername = "Please fill in your username" englishMessage PleaseProvidePassword = "Please fill in your password" englishMessage NoIdentifierProvided = "No email/username provided"@@ -108,7 +112,8 @@ englishMessage PasswordResetPrompt = "Enter your e-mail address or username below, and a password reset e-mail will be sent to you." englishMessage InvalidUsernamePass = "Invalid username/password combination" englishMessage (IdentifierNotFound ident) = "Login not found: " `mappend` ident-englishMessage Logout = "Logout"+englishMessage Logout = "Log Out"+englishMessage LogoutTitle = "Log Out" englishMessage AuthError = "Authentication Error" -- FIXME by Google Translate  portugueseMessage :: AuthMessage -> Text@@ -117,6 +122,7 @@ portugueseMessage LoginGoogle = "Entrar via Google" portugueseMessage LoginYahoo = "Entrar via Yahoo" portugueseMessage Email = "E-mail"+portugueseMessage UserName = "Nome de usuário" -- FIXME by Google Translate "user name" portugueseMessage Password = "Senha" portugueseMessage Register = "Registrar" portugueseMessage RegisterLong = "Registrar uma nova conta"@@ -154,6 +160,7 @@ -- TODO portugueseMessage i@(IdentifierNotFound _) = englishMessage i portugueseMessage Logout = "Sair" -- FIXME by Google Translate+portugueseMessage LogoutTitle = "Sair" -- FIXME by Google Translate portugueseMessage AuthError = "Erro de autenticação" -- FIXME by Google Translate  spanishMessage :: AuthMessage -> Text@@ -162,6 +169,7 @@ spanishMessage LoginGoogle = "Entrar utilizando Google" spanishMessage LoginYahoo = "Entrar utilizando Yahoo" spanishMessage Email = "Correo electrónico"+spanishMessage UserName = "Nombre de Usuario" -- FIXME by Google Translate "user name" spanishMessage Password = "Contraseña" spanishMessage Register = "Registrarse" spanishMessage RegisterLong = "Registrar una nueva cuenta"@@ -186,7 +194,7 @@ spanishMessage LoginViaEmail = "Entrar mediante una cuenta de correo" spanishMessage InvalidLogin = "Login inválido" spanishMessage NowLoggedIn = "Usted ha ingresado al sitio"-spanishMessage LoginTitle = "Login"+spanishMessage LoginTitle = "Log In" spanishMessage PleaseProvideUsername = "Por favor escriba su nombre de usuario" spanishMessage PleaseProvidePassword = "Por favor escriba su contraseña" spanishMessage NoIdentifierProvided = "No ha indicado una cuenta de correo/nombre de usuario"@@ -199,6 +207,7 @@ -- TODO spanishMessage i@(IdentifierNotFound _) = englishMessage i spanishMessage Logout = "Finalizar la sesión" -- FIXME by Google Translate+spanishMessage LogoutTitle = "Finalizar la sesión" -- FIXME by Google Translate spanishMessage AuthError = "Error de autenticación" -- FIXME by Google Translate  swedishMessage :: AuthMessage -> Text@@ -207,6 +216,7 @@ swedishMessage LoginGoogle = "Logga in via Google" swedishMessage LoginYahoo = "Logga in via Yahoo" swedishMessage Email = "Epost"+swedishMessage UserName = "Användarnamn"  -- FIXME by Google Translate "user name" swedishMessage Password = "Lösenord" swedishMessage Register = "Registrera" swedishMessage RegisterLong = "Registrera ett nytt konto"@@ -245,6 +255,7 @@ -- TODO swedishMessage i@(IdentifierNotFound _) = englishMessage i swedishMessage Logout = "Loggar ut" -- FIXME by Google Translate+swedishMessage LogoutTitle = "Loggar ut" -- FIXME by Google Translate swedishMessage AuthError = "Autentisering Fel" -- FIXME by Google Translate  germanMessage :: AuthMessage -> Text@@ -253,6 +264,7 @@ germanMessage LoginGoogle = "Login via Google" germanMessage LoginYahoo = "Login via Yahoo" germanMessage Email = "Email"+germanMessage UserName = "Benutzername" -- FIXME by Google Translate "user name" germanMessage Password = "Passwort" germanMessage Register = "Registrieren" germanMessage RegisterLong = "Neuen Account registrieren"@@ -277,7 +289,7 @@ germanMessage LoginViaEmail = "Login via e-Mail" germanMessage InvalidLogin = "Ungültiger Login" germanMessage NowLoggedIn = "Login erfolgreich"-germanMessage LoginTitle = "Login"+germanMessage LoginTitle = "Log In" germanMessage PleaseProvideUsername = "Bitte Nutzername angeben" germanMessage PleaseProvidePassword = "Bitte Passwort angeben" germanMessage NoIdentifierProvided = "Keine Email-Adresse oder kein Nutzername angegeben"@@ -290,6 +302,7 @@ -- TODO germanMessage i@(IdentifierNotFound _) = englishMessage i germanMessage Logout = "Ausloggen" -- FIXME by Google Translate+germanMessage LogoutTitle = "Ausloggen" -- FIXME by Google Translate germanMessage AuthError = "Authorisierungsfehler" -- FIXME by Google Translate  frenchMessage :: AuthMessage -> Text@@ -298,6 +311,7 @@ frenchMessage LoginGoogle = "Se connecter avec Google" frenchMessage LoginYahoo = "Se connecter avec Yahoo" frenchMessage Email = "Adresse électronique"+frenchMessage UserName = "Nom d'utilisateur" -- FIXME by Google Translate "user name" frenchMessage Password = "Mot de passe" frenchMessage Register = "S'inscrire" frenchMessage RegisterLong = "Créer un compte"@@ -334,6 +348,7 @@ frenchMessage InvalidUsernamePass = "La combinaison de ce mot de passe et de ce nom d'utilisateur n'existe pas." frenchMessage (IdentifierNotFound ident) = "Nom d'utilisateur introuvable: " `mappend` ident frenchMessage Logout = "Déconnexion"+frenchMessage LogoutTitle = "Déconnexion" frenchMessage AuthError = "Erreur d'authentification" -- FIXME by Google Translate  norwegianBokmålMessage :: AuthMessage -> Text@@ -342,6 +357,7 @@ norwegianBokmålMessage LoginGoogle = "Logg inn med Google" norwegianBokmålMessage LoginYahoo = "Logg inn med Yahoo" norwegianBokmålMessage Email = "E-post"+norwegianBokmålMessage UserName = "Brukernavn" -- FIXME by Google Translate "user name" norwegianBokmålMessage Password = "Passord" norwegianBokmålMessage Register = "Registrer" norwegianBokmålMessage RegisterLong = "Registrer en ny konto"@@ -379,6 +395,7 @@ -- TODO norwegianBokmålMessage i@(IdentifierNotFound _) = englishMessage i norwegianBokmålMessage Logout = "Logge ut" -- FIXME by Google Translate+norwegianBokmålMessage LogoutTitle = "Logge ut" -- FIXME by Google Translate norwegianBokmålMessage AuthError = "Godkjenningsfeil" -- FIXME by Google Translate  japaneseMessage :: AuthMessage -> Text@@ -387,6 +404,7 @@ japaneseMessage LoginGoogle = "Googleでログイン" japaneseMessage LoginYahoo = "Yahooでログイン" japaneseMessage Email = "Eメール"+japaneseMessage UserName = "ユーザー名" -- FIXME by Google Translate "user name" japaneseMessage Password = "パスワード" japaneseMessage Register = "登録" japaneseMessage RegisterLong = "新規アカウント登録"@@ -424,6 +442,7 @@ japaneseMessage (IdentifierNotFound ident) =   ident `mappend` "は登録されていません" japaneseMessage Logout = "ログアウト" -- FIXME by Google Translate+japaneseMessage LogoutTitle = "ログアウト" -- FIXME by Google Translate japaneseMessage AuthError = "認証エラー" -- FIXME by Google Translate  finnishMessage :: AuthMessage -> Text@@ -432,6 +451,7 @@ finnishMessage LoginGoogle = "Kirjaudu Google-tilillä" finnishMessage LoginYahoo = "Kirjaudu Yahoo-tilillä" finnishMessage Email = "Sähköposti"+finnishMessage UserName = "Käyttäjätunnus" -- FIXME by Google Translate "user name" finnishMessage Password = "Salasana" finnishMessage Register = "Luo uusi" finnishMessage RegisterLong = "Luo uusi tili"@@ -470,6 +490,7 @@ -- TODO finnishMessage i@(IdentifierNotFound _) = englishMessage i finnishMessage Logout = "Kirjaudu ulos" -- FIXME by Google Translate+finnishMessage LogoutTitle = "Kirjaudu ulos" -- FIXME by Google Translate finnishMessage AuthError = "Authentication Error" -- FIXME by Google Translate  chineseMessage :: AuthMessage -> Text@@ -478,6 +499,7 @@ chineseMessage LoginGoogle = "用Google帐户登录" chineseMessage LoginYahoo = "用Yahoo帐户登录" chineseMessage Email = "邮箱"+chineseMessage UserName = "用户名" -- FIXME by Google Translate "user name" chineseMessage Password = "密码" chineseMessage Register = "注册" chineseMessage RegisterLong = "注册新帐户"@@ -515,6 +537,7 @@ -- TODO chineseMessage i@(IdentifierNotFound _) = englishMessage i chineseMessage Logout = "註銷" -- FIXME by Google Translate+chineseMessage LogoutTitle = "註銷" -- FIXME by Google Translate chineseMessage AuthError = "验证错误" -- FIXME by Google Translate  czechMessage :: AuthMessage -> Text@@ -523,6 +546,7 @@ czechMessage LoginGoogle = "Přihlásit přes Google" czechMessage LoginYahoo = "Přihlásit přes Yahoo" czechMessage Email = "E-mail"+czechMessage UserName = "Uživatelské jméno" czechMessage Password = "Heslo" czechMessage Register = "Registrovat" czechMessage RegisterLong = "Zaregistrovat nový účet"@@ -558,6 +582,7 @@ -- TODO czechMessage i@(IdentifierNotFound _) = englishMessage i czechMessage Logout = "Odhlásit" -- FIXME by Google Translate+czechMessage LogoutTitle = "Odhlásit" -- FIXME by Google Translate czechMessage AuthError = "Chyba ověřování" -- FIXME by Google Translate  -- Так как e-mail – это фактическое сокращение словосочетания electronic mail,@@ -568,6 +593,7 @@ russianMessage LoginGoogle = "Вход с помощью Google" russianMessage LoginYahoo = "Вход с помощью Yahoo" russianMessage Email = "Эл.почта"+russianMessage UserName = "Имя пользователя" russianMessage Password = "Пароль" russianMessage Register = "Регистрация" russianMessage RegisterLong = "Создать учётную запись"@@ -604,6 +630,7 @@ russianMessage InvalidUsernamePass = "Неверное сочетание имени пользователя и пароля" russianMessage (IdentifierNotFound ident) = "Логин не найден: " `mappend` ident russianMessage Logout = "Выйти"+russianMessage LogoutTitle = "Выйти" russianMessage AuthError = "Ошибка аутентификации"  dutchMessage :: AuthMessage -> Text@@ -612,6 +639,7 @@ dutchMessage LoginGoogle = "Inloggen via Google" dutchMessage LoginYahoo = "Inloggen via Yahoo" dutchMessage Email = "E-mail"+dutchMessage UserName = "Gebruikersnaam" -- FIXME by Google Translate "user name" dutchMessage Password = "Wachtwoord" dutchMessage Register = "Registreren" dutchMessage RegisterLong = "Registreer een nieuw account"@@ -647,5 +675,6 @@ dutchMessage PasswordResetPrompt = "Voer uw e-mailadres of gebruikersnaam hieronder in, er zal een e-mail naar u worden verzonden waarmee u uw wachtwoord kunt wijzigen." dutchMessage InvalidUsernamePass = "Ongeldige gebruikersnaam/wachtwoord combinatie" dutchMessage (IdentifierNotFound ident) = "Inloggegevens niet gevonden: " `mappend` ident-dutchMessage Logout = "Logout" -- FIXME NOT TRANSLATED+dutchMessage Logout = "Log Out" -- FIXME NOT TRANSLATED+dutchMessage LogoutTitle = "Log Out" -- FIXME NOT TRANSLATED dutchMessage AuthError = "Verificatiefout" -- FIXME by Google Translate
yesod-auth.cabal view
@@ -1,5 +1,5 @@ name:            yesod-auth-version:         1.4.8+version:         1.4.11 license:         MIT license-file:    LICENSE author:          Michael Snoyman, Patrick Brisbin@@ -75,6 +75,7 @@                      Yesod.Auth.Message                      Yesod.Auth.GoogleEmail                      Yesod.Auth.GoogleEmail2+                     Yesod.Auth.Hardcoded     other-modules:   Yesod.Auth.Routes                      Yesod.PasswordStore     ghc-options:     -Wall