yesod-recaptcha2 0.2.4 → 0.3.0
raw patch · 3 files changed
+107/−14 lines, 3 filesdep +aesondep +classy-preludedep +yesod-coredep −classy-prelude-yesodPVP ok
version bump matches the API change (PVP)
Dependencies added: aeson, classy-prelude, yesod-core, yesod-form
Dependencies removed: classy-prelude-yesod
API changes (from Hackage documentation)
+ Yesod.ReCaptcha2: mReCaptchaInvisible :: YesodReCaptcha site => MForm (HandlerFor site) (FormResult ())
+ Yesod.ReCaptcha2: reCaptchaInvisible :: YesodReCaptcha site => AForm (HandlerFor site) ()
+ Yesod.ReCaptcha2: reCaptchaInvisibleForm :: YesodReCaptcha site => Maybe Text -> Maybe Text -> HandlerFor site (Text, WidgetFor site (), [(Text, Text)])
Files
- README.md +1/−0
- src/Yesod/ReCaptcha2.hs +96/−7
- yesod-recaptcha2.cabal +10/−7
README.md view
@@ -1,6 +1,7 @@ # yesod-recaptcha2 +[](https://travis-ci.org/ncaq/yesod-recaptcha2) [hackage](https://hackage.haskell.org/package/yesod-recaptcha2)
src/Yesod/ReCaptcha2.hs view
@@ -3,11 +3,29 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-}-module Yesod.ReCaptcha2 (YesodReCaptcha(..), reCaptcha, mReCaptcha) where+{-# LANGUAGE TupleSections #-}+module Yesod.ReCaptcha2+ ( YesodReCaptcha(..)+ -- * ReCaptcha V2+ , reCaptcha+ , mReCaptcha+ -- * Invisible ReCaptcha+ -- $invisibleReCaptcha+ , reCaptchaInvisible+ , mReCaptchaInvisible+ , reCaptchaInvisibleForm+ ) where -import ClassyPrelude.Yesod+import ClassyPrelude+import Data.Aeson import Network.HTTP.Simple import Yesod.Auth+import Yesod.Core+import Yesod.Core.Handler+import Yesod.Core.Types+import Yesod.Core.Widget+import Yesod.Form.Functions+import Yesod.Form.Types -- | default key is testing. you should impl reCaptchaSiteKey and reCaptchaSecretKey class YesodAuth site => YesodReCaptcha site where@@ -15,7 +33,8 @@ reCaptchaSiteKey = pure "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" reCaptchaSecretKey :: HandlerFor site Text reCaptchaSecretKey = pure "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe"- -- | with specific language from <https://developers.google.com/recaptcha/docs/language>+ -- | with specific language from+ -- <https://developers.google.com/recaptcha/docs/language> -- -- > reCaptchaLanguage = pure (Just "ru") reCaptchaLanguage :: HandlerFor site (Maybe Text)@@ -32,7 +51,9 @@ reCaptcha = formToAForm mReCaptcha -- | for Monadic style form-mReCaptcha :: YesodReCaptcha site => MForm (HandlerFor site) (FormResult (), [FieldView site])+mReCaptcha+ :: YesodReCaptcha site =>+ MForm (HandlerFor site) (FormResult (), [FieldView site]) mReCaptcha = do result <- lift formResult return (result, [fieldViewSite])@@ -43,10 +64,15 @@ Just response -> do secret <- reCaptchaSecretKey SiteverifyResponse{success} <- liftIO $ do- req <- parseRequest "POST https://www.google.com/recaptcha/api/siteverify"+ req <-+ parseRequest+ "POST https://www.google.com/recaptcha/api/siteverify" res <- httpJSON $ setRequestBodyURLEncoded- [("secret", encodeUtf8 secret), ("response", encodeUtf8 response)] req+ [ ("secret", encodeUtf8 secret)+ , ("response", encodeUtf8 response)+ ]+ req return $ getResponseBody res return $ if success then FormSuccess ()@@ -61,9 +87,72 @@ Nothing -> addScriptRemote "https://www.google.com/recaptcha/api.js" Just hl ->- addScriptRemote $ "https://www.google.com/recaptcha/api.js?hl=" <> hl+ addScriptRemote $+ "https://www.google.com/recaptcha/api.js?hl=" <> hl siteKey <- handlerToWidget reCaptchaSiteKey [whamlet|<div .g-recaptcha data-sitekey=#{siteKey}>|] , fvErrors = Nothing , fvRequired = True }++-- $invisibleReCaptcha+--+-- The Invisible ReCaptcha is not as easy as the V2.+--+-- 1. Function to check the response: 'reCaptchaInvisible' or 'mReCaptchaInvisible'.+--+-- 2. Add the following to the code which creates the form:+--+-- > (reCaptchaFormId, reCaptchaWidget, reCaptchaButtonAttributes) <-+-- > reCaptchaInvisibleForm Nothing+--+-- 3. Add the id to the form, class and attributes to the button and the widget somewhere.+-- Example:+--+-- @+-- \<form \#\#{reCaptchaFormId} method=post action=@{route} enctype=#{enctype}\>+-- ^{widget}+-- ^{reCaptchaWidget}+--+-- \<button .g-recaptcha *{reCaptchaButtonAttributes}\>+-- Submit+-- @++-- | check for Applicative style form+reCaptchaInvisible :: YesodReCaptcha site => AForm (HandlerFor site) ()+reCaptchaInvisible = formToAForm ((,[]) <$> mReCaptchaInvisible)++-- | check for Monadic style form+mReCaptchaInvisible+ :: YesodReCaptcha site => MForm (HandlerFor site) (FormResult ())+mReCaptchaInvisible = fst <$> mReCaptcha++-- | generate all required parts (except the check) for a Invisible ReCaptcha+reCaptchaInvisibleForm+ :: YesodReCaptcha site+ => Maybe Text -- ^ The id of the form, a new will be created when 'Nothing' is passed+ -> Maybe Text+ -- ^ The javascript to call after a successful captcha,+ -- it has to submit the form, a simple one will be generated when 'Nothing' is passed+ -> HandlerFor site (Text, WidgetFor site (), [(Text, Text)])+reCaptchaInvisibleForm mIdent mScript = do+ mReCaptchaLanguage <- reCaptchaLanguage+ siteKey <- reCaptchaSiteKey+ identForm <- maybe newIdent return mIdent+ scriptName <- maybe (("reCaptchaOnSubmit_" <>) <$> newIdent) return mScript+ let+ widget = do+ case mReCaptchaLanguage of+ Nothing ->+ addScriptRemote "https://www.google.com/recaptcha/api.js"+ Just hl ->+ addScriptRemote $ "https://www.google.com/recaptcha/api.js?hl=" <> hl+ when (isNothing mScript) $+ toWidgetHead [hamlet|+<script>function #{scriptName}(token) { document.getElementById("#{identForm}").submit(); }+|]+ return+ ( identForm+ , widget+ , [("data-sitekey", siteKey), ("data-callback", scriptName)]+ )
yesod-recaptcha2.cabal view
@@ -1,11 +1,13 @@--- This file has been generated from package.yaml by hpack version 0.20.0.+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.0. -- -- see: https://github.com/sol/hpack ----- hash: d33d7c41317f538fc8619b0117572564e3a742273756bae5f8ae1271aa6f36b4+-- hash: 2b3e3fe3c6054faefe316aba4920104bb8025b052b3857c3ff5444752b269ae7 name: yesod-recaptcha2-version: 0.2.4+version: 0.3.0 synopsis: yesod recaptcha2 description: recaptcha2 for yesod-form category: Web@@ -17,8 +19,6 @@ license: MIT license-file: LICENSE build-type: Simple-cabal-version: >= 1.10- extra-source-files: README.md @@ -30,10 +30,13 @@ hs-source-dirs: src build-depends:- base >=4.7 && <5- , classy-prelude-yesod+ aeson+ , base >=4.7 && <5+ , classy-prelude , http-conduit , yesod-auth+ , yesod-core+ , yesod-form exposed-modules: Yesod.ReCaptcha2 other-modules: