diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,17 @@
-## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.6.3.4...main)
+## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.0.0...main)
 
 None
+
+## [v0.7.0.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.6.3.4...v0.7.0.0)
+
+- Support `hoauth2-2.0`
+
+  The `OAuth2` type's fields have changed. If you are not defining your own
+  Local Providers (i.e. you're not constructing any `OAuth2` values) you should
+  not be affected by this change. If you are, you should update to the [new
+  field names][oauth2].
+
+  [oauth2]: https://hackage.haskell.org/package/hoauth2-2.0.0/docs/Network-OAuth-OAuth2-Internal.html#t:OAuth2
 
 ## [v0.6.3.4](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.6.3.1...v0.6.3.4)
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -91,11 +91,11 @@
             }
   where
     oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint = "https://mysite.com/oauth/authorize"
-        , oauthAccessTokenEndpoint = "https://mysite.com/oauth/token"
-        , oauthCallback = Nothing
+        { oauth2ClientId = clientId
+        , oauth2ClientSecret = Just clientSecret
+        , oauth2AuthorizeEndpoint = "https://mysite.com/oauth/authorize"
+        , oauth2TokenEndpoint = "https://mysite.com/oauth/token"
+        , oauth2RedirectUri = Nothing
         }
 ```
 
diff --git a/src/Network/OAuth/OAuth2/Compat.hs b/src/Network/OAuth/OAuth2/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/OAuth/OAuth2/Compat.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE CPP #-}
+
+module Network.OAuth.OAuth2.Compat
+    ( OAuth2(..)
+    , authorizationUrl
+    , fetchAccessToken
+    , fetchAccessToken2
+    , module Network.OAuth.OAuth2
+    ) where
+
+import Network.HTTP.Conduit (Manager)
+import Network.OAuth.OAuth2 hiding
+    (OAuth2(..), authorizationUrl, fetchAccessToken, fetchAccessToken2)
+import qualified Network.OAuth.OAuth2 as OAuth2
+import Network.OAuth.OAuth2.TokenRequest (Errors)
+import URI.ByteString
+
+#if MIN_VERSION_hoauth2(2,0,0)
+import Network.OAuth.OAuth2 (OAuth2(..))
+
+getOAuth2 :: OAuth2 -> OAuth2
+getOAuth2 = id
+
+#else
+import Data.Text (Text)
+
+data OAuth2 = OAuth2
+    { oauth2ClientId :: Text
+    , oauth2ClientSecret :: Maybe Text
+    , oauth2AuthorizeEndpoint :: URIRef Absolute
+    , oauth2TokenEndpoint :: URIRef Absolute
+    , oauth2RedirectUri :: Maybe (URIRef Absolute)
+    }
+
+getOAuth2 :: OAuth2 -> OAuth2.OAuth2
+getOAuth2 o = OAuth2.OAuth2
+    { OAuth2.oauthClientId = oauth2ClientId o
+    , OAuth2.oauthClientSecret = oauth2ClientSecret o
+    , OAuth2.oauthOAuthorizeEndpoint = oauth2AuthorizeEndpoint o
+    , OAuth2.oauthAccessTokenEndpoint = oauth2TokenEndpoint o
+    , OAuth2.oauthCallback = oauth2RedirectUri o
+    }
+
+#endif
+
+authorizationUrl :: OAuth2 -> URI
+authorizationUrl = OAuth2.authorizationUrl . getOAuth2
+
+fetchAccessToken
+    :: Manager
+    -> OAuth2
+    -> ExchangeToken
+    -> IO (OAuth2Result Errors OAuth2Token)
+fetchAccessToken m = OAuth2.fetchAccessToken m . getOAuth2
+
+fetchAccessToken2
+    :: Manager
+    -> OAuth2
+    -> ExchangeToken
+    -> IO (OAuth2Result Errors OAuth2Token)
+fetchAccessToken2 m = OAuth2.fetchAccessToken2 m . getOAuth2
diff --git a/src/Yesod/Auth/OAuth2.hs b/src/Yesod/Auth/OAuth2.hs
--- a/src/Yesod/Auth/OAuth2.hs
+++ b/src/Yesod/Auth/OAuth2.hs
@@ -8,26 +8,25 @@
 -- See @"Yesod.Auth.OAuth2.GitHub"@ for example usage.
 --
 module Yesod.Auth.OAuth2
-    ( OAuth2(..)
-    , FetchCreds
-    , Manager
-    , OAuth2Token(..)
-    , Creds(..)
-    , oauth2Url
-    , authOAuth2
-    , authOAuth2Widget
+  ( OAuth2(..)
+  , FetchCreds
+  , Manager
+  , OAuth2Token(..)
+  , Creds(..)
+  , oauth2Url
+  , authOAuth2
+  , authOAuth2Widget
 
     -- * Alternatives that use 'fetchAccessToken2'
-    , authOAuth2'
-    , authOAuth2Widget'
+  , authOAuth2'
+  , authOAuth2Widget'
 
     -- * Reading our @'credsExtra'@ keys
-    , getAccessToken
-    , getRefreshToken
-    , getUserResponse
-    , getUserResponseJSON
-    )
-where
+  , getAccessToken
+  , getRefreshToken
+  , getUserResponse
+  , getUserResponseJSON
+  ) where
 
 import Control.Error.Util (note)
 import Control.Monad ((<=<))
@@ -36,7 +35,7 @@
 import Data.Text (Text)
 import Data.Text.Encoding (encodeUtf8)
 import Network.HTTP.Conduit (Manager)
-import Network.OAuth.OAuth2
+import Network.OAuth.OAuth2.Compat
 import Yesod.Auth
 import Yesod.Auth.OAuth2.Dispatch
 import Yesod.Core.Widget
@@ -64,12 +63,12 @@
 -- example.
 --
 authOAuth2Widget
-    :: YesodAuth m
-    => WidgetFor m ()
-    -> Text
-    -> OAuth2
-    -> FetchCreds m
-    -> AuthPlugin m
+  :: YesodAuth m
+  => WidgetFor m ()
+  -> Text
+  -> OAuth2
+  -> FetchCreds m
+  -> AuthPlugin m
 authOAuth2Widget = buildPlugin fetchAccessToken
 
 -- | A version of 'authOAuth2Widget' that uses 'fetchAccessToken2'
@@ -77,27 +76,27 @@
 -- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129>
 --
 authOAuth2Widget'
-    :: YesodAuth m
-    => WidgetFor m ()
-    -> Text
-    -> OAuth2
-    -> FetchCreds m
-    -> AuthPlugin m
+  :: YesodAuth m
+  => WidgetFor m ()
+  -> Text
+  -> OAuth2
+  -> FetchCreds m
+  -> AuthPlugin m
 authOAuth2Widget' = buildPlugin fetchAccessToken2
 
 buildPlugin
-    :: YesodAuth m
-    => FetchToken
-    -> WidgetFor m ()
-    -> Text
-    -> OAuth2
-    -> FetchCreds m
-    -> AuthPlugin m
+  :: YesodAuth m
+  => FetchToken
+  -> WidgetFor m ()
+  -> Text
+  -> OAuth2
+  -> FetchCreds m
+  -> AuthPlugin m
 buildPlugin getToken widget name oauth getCreds = AuthPlugin
-    name
-    (dispatchAuthRequest name oauth getToken getCreds)
-    login
-    where login tm = [whamlet|<a href=@{tm $ oauth2Url name}>^{widget}|]
+  name
+  (dispatchAuthRequest name oauth getToken getCreds)
+  login
+  where login tm = [whamlet|<a href=@{tm $ oauth2Url name}>^{widget}|]
 
 -- | Read the @'AccessToken'@ from the values set via @'setExtra'@
 getAccessToken :: Creds m -> Maybe AccessToken
@@ -113,9 +112,9 @@
 -- | Read the original profile response from the values set via @'setExtra'@
 getUserResponse :: Creds m -> Maybe ByteString
 getUserResponse =
-    (fromStrict . encodeUtf8 <$>) . lookup "userResponse" . credsExtra
+  (fromStrict . encodeUtf8 <$>) . lookup "userResponse" . credsExtra
 
 -- | @'getUserResponse'@, and decode as JSON
 getUserResponseJSON :: FromJSON a => Creds m -> Either String a
 getUserResponseJSON =
-    eitherDecode <=< note "userResponse key not present" . getUserResponse
+  eitherDecode <=< note "userResponse key not present" . getUserResponse
diff --git a/src/Yesod/Auth/OAuth2/AzureAD.hs b/src/Yesod/Auth/OAuth2/AzureAD.hs
--- a/src/Yesod/Auth/OAuth2/AzureAD.hs
+++ b/src/Yesod/Auth/OAuth2/AzureAD.hs
@@ -7,10 +7,9 @@
 -- * Uses email as credentials identifier
 --
 module Yesod.Auth.OAuth2.AzureAD
-    ( oauth2AzureAD
-    , oauth2AzureADScoped
-    )
-where
+  ( oauth2AzureAD
+  , oauth2AzureADScoped
+  ) where
 
 import Prelude
 import Yesod.Auth.OAuth2.Prelude
@@ -18,7 +17,7 @@
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "mail"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "mail"
 
 pluginName :: Text
 pluginName = "azuread"
@@ -31,28 +30,26 @@
 
 oauth2AzureADScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
 oauth2AzureADScoped scopes clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "https://graph.microsoft.com/v1.0/me"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "https://graph.microsoft.com/v1.0/me"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://login.windows.net/common/oauth2/authorize"
-                `withQuery` [ scopeParam "," scopes
-                            , ("resource", "https://graph.microsoft.com")
-                            ]
-        , oauthAccessTokenEndpoint =
-            "https://login.windows.net/common/oauth2/token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint =
+      "https://login.windows.net/common/oauth2/authorize"
+        `withQuery` [ scopeParam "," scopes
+                    , ("resource", "https://graph.microsoft.com")
+                    ]
+    , oauth2TokenEndpoint     = "https://login.windows.net/common/oauth2/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/BattleNet.hs b/src/Yesod/Auth/OAuth2/BattleNet.hs
--- a/src/Yesod/Auth/OAuth2/BattleNet.hs
+++ b/src/Yesod/Auth/OAuth2/BattleNet.hs
@@ -9,10 +9,9 @@
 -- * Returns user's battletag in extras.
 --
 module Yesod.Auth.OAuth2.BattleNet
-    ( oauth2BattleNet
-    , oAuth2BattleNet
-    )
-where
+  ( oauth2BattleNet
+  , oAuth2BattleNet
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -22,52 +21,48 @@
 newtype User = User Int
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "id"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "id"
 
 pluginName :: Text
 pluginName = "battle.net"
 
 oauth2BattleNet
-    :: YesodAuth m
-    => WidgetFor m () -- ^ Login widget
-    -> Text -- ^ User region (e.g. "eu", "cn", "us")
-    -> Text -- ^ Client ID
-    -> Text -- ^ Client Secret
-    -> AuthPlugin m
+  :: YesodAuth m
+  => WidgetFor m () -- ^ Login widget
+  -> Text -- ^ User region (e.g. "eu", "cn", "us")
+  -> Text -- ^ Client ID
+  -> Text -- ^ Client Secret
+  -> AuthPlugin m
 oauth2BattleNet widget region clientId clientSecret =
-    authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <-
-            authGetProfile pluginName manager token
-                $ fromRelative
-                      "https"
-                      (apiHost $ T.toLower region)
-                      "/account/user"
+  authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <-
+      authGetProfile pluginName manager token
+        $ fromRelative "https" (apiHost $ T.toLower region) "/account/user"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = T.pack $ show userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    host = wwwHost $ T.toLower region
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint = fromRelative "https" host "/oauth/authorize"
-        , oauthAccessTokenEndpoint = fromRelative "https" host "/oauth/token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = T.pack $ show userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  host   = wwwHost $ T.toLower region
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = fromRelative "https" host "/oauth/authorize"
+    , oauth2TokenEndpoint     = fromRelative "https" host "/oauth/token"
+    , oauth2RedirectUri       = Nothing
+    }
 
 
 apiHost :: Text -> Host
-apiHost "cn" = "api.battlenet.com.cn"
+apiHost "cn"   = "api.battlenet.com.cn"
 apiHost region = Host $ encodeUtf8 $ region <> ".api.battle.net"
 
 wwwHost :: Text -> Host
-wwwHost "cn" = "www.battlenet.com.cn"
+wwwHost "cn"   = "www.battlenet.com.cn"
 wwwHost region = Host $ encodeUtf8 $ region <> ".battle.net"
 
 oAuth2BattleNet
-    :: YesodAuth m => Text -> Text -> Text -> WidgetFor m () -> AuthPlugin m
+  :: YesodAuth m => Text -> Text -> Text -> WidgetFor m () -> AuthPlugin m
 oAuth2BattleNet i s r w = oauth2BattleNet w r i s
 {-# DEPRECATED oAuth2BattleNet "Use oauth2BattleNet" #-}
diff --git a/src/Yesod/Auth/OAuth2/Bitbucket.hs b/src/Yesod/Auth/OAuth2/Bitbucket.hs
--- a/src/Yesod/Auth/OAuth2/Bitbucket.hs
+++ b/src/Yesod/Auth/OAuth2/Bitbucket.hs
@@ -7,10 +7,9 @@
 -- * Uses bitbucket uuid as credentials identifier
 --
 module Yesod.Auth.OAuth2.Bitbucket
-    ( oauth2Bitbucket
-    , oauth2BitbucketScoped
-    )
-where
+  ( oauth2Bitbucket
+  , oauth2BitbucketScoped
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -19,7 +18,7 @@
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "uuid"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "uuid"
 
 pluginName :: Text
 pluginName = "bitbucket"
@@ -32,32 +31,29 @@
 
 oauth2BitbucketScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
 oauth2BitbucketScoped scopes clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "https://api.bitbucket.com/2.0/user"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "https://api.bitbucket.com/2.0/user"
 
-        pure Creds
-            { credsPlugin = pluginName
-            -- FIXME: Preserved bug. This should just be userId (it's already
-            -- a Text), but because this code was shipped, folks likely have
-            -- Idents in their database like @"\"...\""@, and if we fixed this
-            -- they would need migrating. We're keeping it for now as it's a
-            -- minor wart. Breaking typed APIs is one thing, causing data to go
-            -- invalid is another.
-            , credsIdent = T.pack $ show userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://bitbucket.com/site/oauth2/authorize"
-                `withQuery` [scopeParam "," scopes]
-        , oauthAccessTokenEndpoint =
-            "https://bitbucket.com/site/oauth2/access_token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+        -- FIXME: Preserved bug. This should just be userId (it's already
+        -- a Text), but because this code was shipped, folks likely have
+        -- Idents in their database like @"\"...\""@, and if we fixed this
+        -- they would need migrating. We're keeping it for now as it's a
+        -- minor wart. Breaking typed APIs is one thing, causing data to go
+        -- invalid is another.
+               , credsIdent  = T.pack $ show userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://bitbucket.com/site/oauth2/authorize"
+                                  `withQuery` [scopeParam "," scopes]
+    , oauth2TokenEndpoint     = "https://bitbucket.com/site/oauth2/access_token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/ClassLink.hs b/src/Yesod/Auth/OAuth2/ClassLink.hs
--- a/src/Yesod/Auth/OAuth2/ClassLink.hs
+++ b/src/Yesod/Auth/OAuth2/ClassLink.hs
@@ -1,10 +1,9 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 module Yesod.Auth.OAuth2.ClassLink
-    ( oauth2ClassLink
-    , oauth2ClassLinkScoped
-    )
-where
+  ( oauth2ClassLink
+  , oauth2ClassLinkScoped
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -13,7 +12,7 @@
 newtype User = User Int
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "UserId"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "UserId"
 
 pluginName :: Text
 pluginName = "classlink"
@@ -26,26 +25,23 @@
 
 oauth2ClassLinkScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
 oauth2ClassLinkScoped scopes clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "https://nodeapi.classlink.com/v2/my/info"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "https://nodeapi.classlink.com/v2/my/info"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = T.pack $ show userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://launchpad.classlink.com/oauth2/v2/auth"
-                `withQuery` [scopeParam "," scopes]
-        , oauthAccessTokenEndpoint =
-            "https://launchpad.classlink.com/oauth2/v2/token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = T.pack $ show userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://launchpad.classlink.com/oauth2/v2/auth"
+                                  `withQuery` [scopeParam "," scopes]
+    , oauth2TokenEndpoint = "https://launchpad.classlink.com/oauth2/v2/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/Dispatch.hs b/src/Yesod/Auth/OAuth2/Dispatch.hs
--- a/src/Yesod/Auth/OAuth2/Dispatch.hs
+++ b/src/Yesod/Auth/OAuth2/Dispatch.hs
@@ -5,19 +5,19 @@
 {-# LANGUAGE TypeFamilies #-}
 
 module Yesod.Auth.OAuth2.Dispatch
-    ( FetchToken
-    , fetchAccessToken
-    , fetchAccessToken2
-    , FetchCreds
-    , dispatchAuthRequest
-    ) where
+  ( FetchToken
+  , fetchAccessToken
+  , fetchAccessToken2
+  , FetchCreds
+  , dispatchAuthRequest
+  ) where
 
 import Control.Monad.Except
 import Data.Text (Text)
 import qualified Data.Text as T
 import Data.Text.Encoding (encodeUtf8)
 import Network.HTTP.Conduit (Manager)
-import Network.OAuth.OAuth2
+import Network.OAuth.OAuth2.Compat
 import Network.OAuth.OAuth2.TokenRequest (Errors)
 import URI.ByteString.Extension
 import UnliftIO.Exception
@@ -32,24 +32,24 @@
 -- This will be 'fetchAccessToken' or 'fetchAccessToken2'
 --
 type FetchToken
-    = Manager -> OAuth2 -> ExchangeToken -> IO (OAuth2Result Errors OAuth2Token)
+  = Manager -> OAuth2 -> ExchangeToken -> IO (OAuth2Result Errors OAuth2Token)
 
 -- | How to take an @'OAuth2Token'@ and retrieve user credentials
 type FetchCreds m = Manager -> OAuth2Token -> IO (Creds m)
 
 -- | Dispatch the various OAuth2 handshake routes
 dispatchAuthRequest
-    :: Text             -- ^ Name
-    -> OAuth2           -- ^ Service details
-    -> FetchToken       -- ^ How to get a token
-    -> FetchCreds m     -- ^ How to get credentials
-    -> Text             -- ^ Method
-    -> [Text]           -- ^ Path pieces
-    -> AuthHandler m TypedContent
+  :: Text             -- ^ Name
+  -> OAuth2           -- ^ Service details
+  -> FetchToken       -- ^ How to get a token
+  -> FetchCreds m     -- ^ How to get credentials
+  -> Text             -- ^ Method
+  -> [Text]           -- ^ Path pieces
+  -> AuthHandler m TypedContent
 dispatchAuthRequest name oauth2 _ _ "GET" ["forward"] =
-    handleDispatchError $ dispatchForward name oauth2
+  handleDispatchError $ dispatchForward name oauth2
 dispatchAuthRequest name oauth2 getToken getCreds "GET" ["callback"] =
-    handleDispatchError $ dispatchCallback name oauth2 getToken getCreds
+  handleDispatchError $ dispatchCallback name oauth2 getToken getCreds
 dispatchAuthRequest _ _ _ _ _ _ = notFound
 
 -- | Handle @GET \/forward@
@@ -58,14 +58,14 @@
 -- 2. Redirect to the Provider's authorization URL
 --
 dispatchForward
-    :: (MonadError DispatchError m, MonadAuthHandler site m)
-    => Text
-    -> OAuth2
-    -> m TypedContent
+  :: (MonadError DispatchError m, MonadAuthHandler site m)
+  => Text
+  -> OAuth2
+  -> m TypedContent
 dispatchForward name oauth2 = do
-    csrf <- setSessionCSRF $ tokenSessionKey name
-    oauth2' <- withCallbackAndState name oauth2 csrf
-    redirect $ toText $ authorizationUrl oauth2'
+  csrf    <- setSessionCSRF $ tokenSessionKey name
+  oauth2' <- withCallbackAndState name oauth2 csrf
+  redirect $ toText $ authorizationUrl oauth2'
 
 -- | Handle @GET \/callback@
 --
@@ -74,41 +74,40 @@
 -- 3. Use the AccessToken to construct a @'Creds'@ value for the Provider
 --
 dispatchCallback
-    :: (MonadError DispatchError m, MonadAuthHandler site m)
-    => Text
-    -> OAuth2
-    -> FetchToken
-    -> FetchCreds site
-    -> m TypedContent
+  :: (MonadError DispatchError m, MonadAuthHandler site m)
+  => Text
+  -> OAuth2
+  -> FetchToken
+  -> FetchCreds site
+  -> m TypedContent
 dispatchCallback name oauth2 getToken getCreds = do
-    onErrorResponse $ throwError . OAuth2HandshakeError
-    csrf <- verifySessionCSRF $ tokenSessionKey name
-    code <- requireGetParam "code"
-    manager <- authHttpManager
-    oauth2' <- withCallbackAndState name oauth2 csrf
-    token <- either (throwError . OAuth2ResultError) pure
-        =<< liftIO (getToken manager oauth2' $ ExchangeToken code)
-    creds <-
-        liftIO (getCreds manager token)
-        `catch` (throwError . FetchCredsIOException)
-        `catch` (throwError . FetchCredsYesodOAuth2Exception)
-    setCredsRedirect creds
+  onErrorResponse $ throwError . OAuth2HandshakeError
+  csrf    <- verifySessionCSRF $ tokenSessionKey name
+  code    <- requireGetParam "code"
+  manager <- authHttpManager
+  oauth2' <- withCallbackAndState name oauth2 csrf
+  token   <- either (throwError . OAuth2ResultError) pure
+    =<< liftIO (getToken manager oauth2' $ ExchangeToken code)
+  creds <-
+    liftIO (getCreds manager token)
+    `catch` (throwError . FetchCredsIOException)
+    `catch` (throwError . FetchCredsYesodOAuth2Exception)
+  setCredsRedirect creds
 
 withCallbackAndState
-    :: (MonadError DispatchError m, MonadAuthHandler site m)
-    => Text
-    -> OAuth2
-    -> Text
-    -> m OAuth2
+  :: (MonadError DispatchError m, MonadAuthHandler site m)
+  => Text
+  -> OAuth2
+  -> Text
+  -> m OAuth2
 withCallbackAndState name oauth2 csrf = do
-    uri <- ($ PluginR name ["callback"]) <$> getParentUrlRender
-    callback <- maybe (throwError $ InvalidCallbackUri uri) pure $ fromText uri
-    pure oauth2
-        { oauthCallback = Just callback
-        , oauthOAuthorizeEndpoint =
-            oauthOAuthorizeEndpoint oauth2
-                `withQuery` [("state", encodeUtf8 csrf)]
-        }
+  uri      <- ($ PluginR name ["callback"]) <$> getParentUrlRender
+  callback <- maybe (throwError $ InvalidCallbackUri uri) pure $ fromText uri
+  pure oauth2
+    { oauth2RedirectUri       = Just callback
+    , oauth2AuthorizeEndpoint = oauth2AuthorizeEndpoint oauth2
+                                  `withQuery` [("state", encodeUtf8 csrf)]
+    }
 
 getParentUrlRender :: MonadHandler m => m (Route (SubHandlerSite m) -> Text)
 getParentUrlRender = (.) <$> getUrlRender <*> getRouteToParent
@@ -124,25 +123,24 @@
 --
 setSessionCSRF :: MonadHandler m => Text -> m Text
 setSessionCSRF sessionKey = do
-    csrfToken <- liftIO randomToken
-    csrfToken <$ setSession sessionKey csrfToken
-    where randomToken = T.filter (/= '+') <$> randomText 64
+  csrfToken <- liftIO randomToken
+  csrfToken <$ setSession sessionKey csrfToken
+  where randomToken = T.filter (/= '+') <$> randomText 64
 
 -- | Verify the callback provided the same CSRF token as in our session
 verifySessionCSRF
-    :: (MonadError DispatchError m, MonadHandler m) => Text -> m Text
+  :: (MonadError DispatchError m, MonadHandler m) => Text -> m Text
 verifySessionCSRF sessionKey = do
-    token <- requireGetParam "state"
-    sessionToken <- lookupSession sessionKey
-    deleteSession sessionKey
-    token <$ unless
-        (sessionToken == Just token)
-        (throwError $ InvalidStateToken sessionToken token)
+  token        <- requireGetParam "state"
+  sessionToken <- lookupSession sessionKey
+  deleteSession sessionKey
+  token <$ unless (sessionToken == Just token)
+                  (throwError $ InvalidStateToken sessionToken token)
 
 requireGetParam
-    :: (MonadError DispatchError m, MonadHandler m) => Text -> m Text
+  :: (MonadError DispatchError m, MonadHandler m) => Text -> m Text
 requireGetParam key =
-    maybe (throwError $ MissingParameter key) pure =<< lookupGetParam key
+  maybe (throwError $ MissingParameter key) pure =<< lookupGetParam key
 
 tokenSessionKey :: Text -> Text
 tokenSessionKey name = "_yesod_oauth2_" <> name
diff --git a/src/Yesod/Auth/OAuth2/EveOnline.hs b/src/Yesod/Auth/OAuth2/EveOnline.hs
--- a/src/Yesod/Auth/OAuth2/EveOnline.hs
+++ b/src/Yesod/Auth/OAuth2/EveOnline.hs
@@ -8,11 +8,10 @@
 -- * Uses EVEs unique account-user-char-hash as credentials identifier
 --
 module Yesod.Auth.OAuth2.EveOnline
-    ( oauth2Eve
-    , oauth2EveScoped
-    , WidgetType(..)
-    )
-where
+  ( oauth2Eve
+  , oauth2EveScoped
+  , WidgetType(..)
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -22,7 +21,7 @@
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "CharacterOwnerHash"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "CharacterOwnerHash"
 
 data WidgetType m
     = Plain -- ^ Simple "Login via eveonline" text
@@ -35,13 +34,13 @@
 asWidget :: YesodAuth m => WidgetType m -> WidgetFor m ()
 asWidget Plain = [whamlet|Login via eveonline|]
 asWidget BigWhite =
-    [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/4PTzeiAshqiM8osU2giO0Y/5cc4cb60bac52422da2e45db87b6819c/EVE_SSO_Login_Buttons_Large_White.png?w=270&h=45">|]
+  [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/4PTzeiAshqiM8osU2giO0Y/5cc4cb60bac52422da2e45db87b6819c/EVE_SSO_Login_Buttons_Large_White.png?w=270&h=45">|]
 asWidget BigBlack
-    = [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/4fSjj56uD6CYwYyus4KmES/4f6385c91e6de56274d99496e6adebab/EVE_SSO_Login_Buttons_Large_Black.png?w=270&h=45">|]
+  = [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/4fSjj56uD6CYwYyus4KmES/4f6385c91e6de56274d99496e6adebab/EVE_SSO_Login_Buttons_Large_Black.png?w=270&h=45">|]
 asWidget SmallWhite
-    = [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/18BxKSXCymyqY4QKo8KwKe/c2bdded6118472dd587c8107f24104d7/EVE_SSO_Login_Buttons_Small_White.png?w=195&h=30">|]
+  = [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/18BxKSXCymyqY4QKo8KwKe/c2bdded6118472dd587c8107f24104d7/EVE_SSO_Login_Buttons_Small_White.png?w=195&h=30">|]
 asWidget SmallBlack
-    = [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/12vrPsIMBQi28QwCGOAqGk/33234da7672c6b0cdca394fc8e0b1c2b/EVE_SSO_Login_Buttons_Small_Black.png?w=195&h=30">|]
+  = [whamlet|<img src="https://images.contentful.com/idjq7aai9ylm/12vrPsIMBQi28QwCGOAqGk/33234da7672c6b0cdca394fc8e0b1c2b/EVE_SSO_Login_Buttons_Small_Black.png?w=195&h=30">|]
 asWidget (Custom a) = a
 
 pluginName :: Text
@@ -54,29 +53,29 @@
 oauth2Eve = oauth2EveScoped defaultScopes
 
 oauth2EveScoped
-    :: YesodAuth m => [Text] -> WidgetType m -> Text -> Text -> AuthPlugin m
+  :: YesodAuth m => [Text] -> WidgetType m -> Text -> Text -> AuthPlugin m
 oauth2EveScoped scopes widgetType clientId clientSecret =
-    authOAuth2Widget (asWidget widgetType) pluginName oauth2
-        $ \manager token -> do
-              (User userId, userResponse) <- authGetProfile
-                  pluginName
-                  manager
-                  token
-                  "https://login.eveonline.com/oauth/verify"
+  authOAuth2Widget (asWidget widgetType) pluginName oauth2 $ \manager token ->
+    do
+      (User userId, userResponse) <- authGetProfile
+        pluginName
+        manager
+        token
+        "https://login.eveonline.com/oauth/verify"
 
-              pure Creds
-                  { credsPlugin = "eveonline"
-                  -- FIXME: Preserved bug. See similar comment in Bitbucket provider.
-                  , credsIdent = T.pack $ show userId
-                  , credsExtra = setExtra token userResponse
-                  }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://login.eveonline.com/oauth/authorize"
-                `withQuery` [("response_type", "code"), scopeParam " " scopes]
-        , oauthAccessTokenEndpoint = "https://login.eveonline.com/oauth/token"
-        , oauthCallback = Nothing
-        }
+      pure Creds { credsPlugin = "eveonline"
+          -- FIXME: Preserved bug. See similar comment in Bitbucket provider.
+                 , credsIdent  = T.pack $ show userId
+                 , credsExtra  = setExtra token userResponse
+                 }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://login.eveonline.com/oauth/authorize"
+                                  `withQuery` [ ("response_type", "code")
+                                              , scopeParam " " scopes
+                                              ]
+    , oauth2TokenEndpoint     = "https://login.eveonline.com/oauth/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/GitHub.hs b/src/Yesod/Auth/OAuth2/GitHub.hs
--- a/src/Yesod/Auth/OAuth2/GitHub.hs
+++ b/src/Yesod/Auth/OAuth2/GitHub.hs
@@ -7,10 +7,9 @@
 -- * Uses github user id as credentials identifier
 --
 module Yesod.Auth.OAuth2.GitHub
-    ( oauth2GitHub
-    , oauth2GitHubScoped
-    )
-where
+  ( oauth2GitHub
+  , oauth2GitHubScoped
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -19,7 +18,7 @@
 newtype User = User Int
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "id"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "id"
 
 pluginName :: Text
 pluginName = "github"
@@ -32,26 +31,23 @@
 
 oauth2GitHubScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
 oauth2GitHubScoped scopes clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "https://api.github.com/user"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "https://api.github.com/user"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = T.pack $ show userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://github.com/login/oauth/authorize"
-                `withQuery` [scopeParam "," scopes]
-        , oauthAccessTokenEndpoint =
-            "https://github.com/login/oauth/access_token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = T.pack $ show userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://github.com/login/oauth/authorize"
+                                  `withQuery` [scopeParam "," scopes]
+    , oauth2TokenEndpoint     = "https://github.com/login/oauth/access_token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/GitLab.hs b/src/Yesod/Auth/OAuth2/GitLab.hs
--- a/src/Yesod/Auth/OAuth2/GitLab.hs
+++ b/src/Yesod/Auth/OAuth2/GitLab.hs
@@ -1,11 +1,10 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Yesod.Auth.OAuth2.GitLab
-    ( oauth2GitLab
-    , oauth2GitLabHostScopes
-    , defaultHost
-    , defaultScopes
-    )
-where
+  ( oauth2GitLab
+  , oauth2GitLabHostScopes
+  , defaultHost
+  , defaultScopes
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -14,7 +13,7 @@
 newtype User = User Int
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "id"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "id"
 
 pluginName :: Text
 pluginName = "gitlab"
@@ -38,27 +37,23 @@
 oauth2GitLab = oauth2GitLabHostScopes defaultHost defaultScopes
 
 oauth2GitLabHostScopes
-    :: YesodAuth m => URI -> [Text] -> Text -> Text -> AuthPlugin m
+  :: YesodAuth m => URI -> [Text] -> Text -> Text -> AuthPlugin m
 oauth2GitLabHostScopes host scopes clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <-
-            authGetProfile pluginName manager token
-            $ host
-            `withPath` "/api/v4/user"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <-
+      authGetProfile pluginName manager token $ host `withPath` "/api/v4/user"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = T.pack $ show userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            host
-            `withPath` "/oauth/authorize"
-            `withQuery` [scopeParam " " scopes]
-        , oauthAccessTokenEndpoint = host `withPath` "/oauth/token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = T.pack $ show userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = host
+                                `withPath`  "/oauth/authorize"
+                                `withQuery` [scopeParam " " scopes]
+    , oauth2TokenEndpoint     = host `withPath` "/oauth/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/Google.hs b/src/Yesod/Auth/OAuth2/Google.hs
--- a/src/Yesod/Auth/OAuth2/Google.hs
+++ b/src/Yesod/Auth/OAuth2/Google.hs
@@ -25,12 +25,11 @@
 -- >     -- continue normally with updatedCreds
 --
 module Yesod.Auth.OAuth2.Google
-    ( oauth2Google
-    , oauth2GoogleWidget
-    , oauth2GoogleScoped
-    , oauth2GoogleScopedWidget
-    )
-where
+  ( oauth2Google
+  , oauth2GoogleWidget
+  , oauth2GoogleScoped
+  , oauth2GoogleScopedWidget
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 import Yesod.Core (WidgetFor, whamlet)
@@ -38,10 +37,10 @@
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON =
-        withObject "User" $ \o -> User
-        -- Required for data backwards-compatibility
-                                       <$> (("google-uid:" <>) <$> o .: "sub")
+  parseJSON =
+    withObject "User" $ \o -> User
+      -- Required for data backwards-compatibility
+                                   <$> (("google-uid:" <>) <$> o .: "sub")
 
 pluginName :: Text
 pluginName = "google"
@@ -52,34 +51,34 @@
 oauth2Google :: YesodAuth m => Text -> Text -> AuthPlugin m
 oauth2Google = oauth2GoogleScoped defaultScopes
 
-oauth2GoogleWidget :: YesodAuth m => WidgetFor m () -> Text -> Text -> AuthPlugin m
+oauth2GoogleWidget
+  :: YesodAuth m => WidgetFor m () -> Text -> Text -> AuthPlugin m
 oauth2GoogleWidget widget = oauth2GoogleScopedWidget widget defaultScopes
 
 oauth2GoogleScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
-oauth2GoogleScoped = oauth2GoogleScopedWidget [whamlet|Login via #{pluginName}|]
+oauth2GoogleScoped =
+  oauth2GoogleScopedWidget [whamlet|Login via #{pluginName}|]
 
-oauth2GoogleScopedWidget :: YesodAuth m => WidgetFor m () -> [Text] -> Text -> Text -> AuthPlugin m
+oauth2GoogleScopedWidget
+  :: YesodAuth m => WidgetFor m () -> [Text] -> Text -> Text -> AuthPlugin m
 oauth2GoogleScopedWidget widget scopes clientId clientSecret =
-    authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "https://www.googleapis.com/oauth2/v3/userinfo"
+  authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "https://www.googleapis.com/oauth2/v3/userinfo"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://accounts.google.com/o/oauth2/auth"
-                `withQuery` [scopeParam " " scopes]
-        , oauthAccessTokenEndpoint =
-            "https://www.googleapis.com/oauth2/v3/token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://accounts.google.com/o/oauth2/auth"
+                                  `withQuery` [scopeParam " " scopes]
+    , oauth2TokenEndpoint     = "https://www.googleapis.com/oauth2/v3/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/Nylas.hs b/src/Yesod/Auth/OAuth2/Nylas.hs
--- a/src/Yesod/Auth/OAuth2/Nylas.hs
+++ b/src/Yesod/Auth/OAuth2/Nylas.hs
@@ -1,9 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 module Yesod.Auth.OAuth2.Nylas
-    ( oauth2Nylas
-    )
-where
+  ( oauth2Nylas
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -16,7 +15,7 @@
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "id"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "id"
 
 pluginName :: Text
 pluginName = "nylas"
@@ -26,44 +25,42 @@
 
 oauth2Nylas :: YesodAuth m => Text -> Text -> AuthPlugin m
 oauth2Nylas clientId clientSecret =
-    authOAuth2 pluginName oauth $ \manager token -> do
-        req <- applyBasicAuth (encodeUtf8 $ atoken $ accessToken token) ""
-            <$> parseRequest "https://api.nylas.com/account"
-        resp <- httpLbs req manager
-        let userResponse = responseBody resp
+  authOAuth2 pluginName oauth $ \manager token -> do
+    req <- applyBasicAuth (encodeUtf8 $ atoken $ accessToken token) ""
+      <$> parseRequest "https://api.nylas.com/account"
+    resp <- httpLbs req manager
+    let userResponse = responseBody resp
 
-        -- FIXME: was this working? I'm 95% sure that the client will throw its
-        -- own exception on unsuccessful status codes.
-        unless (HT.statusIsSuccessful $ responseStatus resp)
-            $ throwIO
-            $ YesodOAuth2Exception.GenericError pluginName
-            $ "Unsuccessful HTTP response: "
-            <> BL8.unpack userResponse
+    -- FIXME: was this working? I'm 95% sure that the client will throw its
+    -- own exception on unsuccessful status codes.
+    unless (HT.statusIsSuccessful $ responseStatus resp)
+      $  throwIO
+      $  YesodOAuth2Exception.GenericError pluginName
+      $  "Unsuccessful HTTP response: "
+      <> BL8.unpack userResponse
 
-        either
-                (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
-                (\(User userId) -> pure Creds
-                    { credsPlugin = pluginName
-                    , credsIdent = userId
-                    , credsExtra = setExtra token userResponse
-                    }
-                )
-            $ eitherDecode userResponse
-  where
-    oauth = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://api.nylas.com/oauth/authorize"
-                `withQuery` [ ("response_type", "code")
-                            , ( "client_id"
-                              , encodeUtf8 clientId
-                              )
-            -- N.B. The scopes delimeter is unknown/untested. Verify that before
-            -- extracting this to an argument and offering a Scoped function. In
-            -- its current state, it doesn't matter because it's only one scope.
-                            , scopeParam "," defaultScopes
-                            ]
-        , oauthAccessTokenEndpoint = "https://api.nylas.com/oauth/token"
-        , oauthCallback = Nothing
-        }
+    either
+        (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
+        (\(User userId) -> pure Creds { credsPlugin = pluginName
+                                      , credsIdent = userId
+                                      , credsExtra = setExtra token userResponse
+                                      }
+        )
+      $ eitherDecode userResponse
+ where
+  oauth = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://api.nylas.com/oauth/authorize"
+                                  `withQuery` [ ("response_type", "code")
+                                              , ( "client_id"
+                                                , encodeUtf8 clientId
+                                                )
+          -- N.B. The scopes delimeter is unknown/untested. Verify that before
+          -- extracting this to an argument and offering a Scoped function. In
+          -- its current state, it doesn't matter because it's only one scope.
+                                              , scopeParam "," defaultScopes
+                                              ]
+    , oauth2TokenEndpoint     = "https://api.nylas.com/oauth/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/Prelude.hs b/src/Yesod/Auth/OAuth2/Prelude.hs
--- a/src/Yesod/Auth/OAuth2/Prelude.hs
+++ b/src/Yesod/Auth/OAuth2/Prelude.hs
@@ -6,56 +6,55 @@
 -- implementations. May also be useful for writing local providers.
 --
 module Yesod.Auth.OAuth2.Prelude
-    (
+  (
       -- * Provider helpers
-      authGetProfile
-    , scopeParam
-    , setExtra
+    authGetProfile
+  , scopeParam
+  , setExtra
 
     -- * Text
-    , Text
-    , decodeUtf8
-    , encodeUtf8
+  , Text
+  , decodeUtf8
+  , encodeUtf8
 
     -- * JSON
-    , (.:)
-    , (.:?)
-    , (.=)
-    , (<>)
-    , FromJSON(..)
-    , ToJSON(..)
-    , eitherDecode
-    , withObject
+  , (.:)
+  , (.:?)
+  , (.=)
+  , (<>)
+  , FromJSON(..)
+  , ToJSON(..)
+  , eitherDecode
+  , withObject
 
     -- * Exceptions
-    , throwIO
+  , throwIO
 
     -- * OAuth2
-    , OAuth2(..)
-    , OAuth2Token(..)
-    , AccessToken(..)
-    , RefreshToken(..)
+  , OAuth2(..)
+  , OAuth2Token(..)
+  , AccessToken(..)
+  , RefreshToken(..)
 
     -- * HTTP
-    , Manager
+  , Manager
 
     -- * Yesod
-    , YesodAuth(..)
-    , AuthPlugin(..)
-    , Creds(..)
+  , YesodAuth(..)
+  , AuthPlugin(..)
+  , Creds(..)
 
     -- * Bytestring URI types
-    , URI
-    , Host(..)
+  , URI
+  , Host(..)
 
     -- * Bytestring URI extensions
-    , module URI.ByteString.Extension
+  , module URI.ByteString.Extension
 
     -- * Temporary, until I finish re-structuring modules
-    , authOAuth2
-    , authOAuth2Widget
-    )
-where
+  , authOAuth2
+  , authOAuth2Widget
+  ) where
 
 import Control.Exception.Safe
 import Data.Aeson
@@ -65,7 +64,7 @@
 import qualified Data.Text as T
 import Data.Text.Encoding
 import Network.HTTP.Conduit
-import Network.OAuth.OAuth2
+import Network.OAuth.OAuth2.Compat
 import URI.ByteString
 import URI.ByteString.Extension
 import Yesod.Auth
@@ -79,28 +78,28 @@
 -- fetched via additional requests by consumers.
 --
 authGetProfile
-    :: FromJSON a
-    => Text
-    -> Manager
-    -> OAuth2Token
-    -> URI
-    -> IO (a, BL.ByteString)
+  :: FromJSON a
+  => Text
+  -> Manager
+  -> OAuth2Token
+  -> URI
+  -> IO (a, BL.ByteString)
 authGetProfile name manager token url = do
-    resp <- fromAuthGet name =<< authGetBS manager (accessToken token) url
-    decoded <- fromAuthJSON name resp
-    pure (decoded, resp)
+  resp    <- fromAuthGet name =<< authGetBS manager (accessToken token) url
+  decoded <- fromAuthJSON name resp
+  pure (decoded, resp)
 
 -- | Throws a @Left@ result as an @'YesodOAuth2Exception'@
 fromAuthGet :: Text -> Either BL.ByteString BL.ByteString -> IO BL.ByteString
 fromAuthGet _ (Right bs) = pure bs -- nice
 fromAuthGet name (Left err) =
-    throwIO $ YesodOAuth2Exception.OAuth2Error name err
+  throwIO $ YesodOAuth2Exception.OAuth2Error name err
 
 -- | Throws a decoding error as an @'YesodOAuth2Exception'@
 fromAuthJSON :: FromJSON a => Text -> BL.ByteString -> IO a
 fromAuthJSON name =
-    either (throwIO . YesodOAuth2Exception.JSONDecodingError name) pure
-        . eitherDecode
+  either (throwIO . YesodOAuth2Exception.JSONDecodingError name) pure
+    . eitherDecode
 
 -- | A tuple of @\"scope\"@ and the given scopes separated by a delimiter
 scopeParam :: Text -> [Text] -> (ByteString, ByteString)
diff --git a/src/Yesod/Auth/OAuth2/Salesforce.hs b/src/Yesod/Auth/OAuth2/Salesforce.hs
--- a/src/Yesod/Auth/OAuth2/Salesforce.hs
+++ b/src/Yesod/Auth/OAuth2/Salesforce.hs
@@ -7,19 +7,18 @@
 -- * Uses Salesforce user id as credentials identifier
 --
 module Yesod.Auth.OAuth2.Salesforce
-    ( oauth2Salesforce
-    , oauth2SalesforceScoped
-    , oauth2SalesforceSandbox
-    , oauth2SalesforceSandboxScoped
-    )
-where
+  ( oauth2Salesforce
+  , oauth2SalesforceScoped
+  , oauth2SalesforceSandbox
+  , oauth2SalesforceSandboxScoped
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "user_id"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "user_id"
 
 pluginName :: Text
 pluginName = "salesforce"
@@ -32,51 +31,45 @@
 
 oauth2SalesforceScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
 oauth2SalesforceScoped = salesforceHelper
-    pluginName
-    "https://login.salesforce.com/services/oauth2/userinfo"
-    "https://login.salesforce.com/services/oauth2/authorize"
-    "https://login.salesforce.com/services/oauth2/token"
+  pluginName
+  "https://login.salesforce.com/services/oauth2/userinfo"
+  "https://login.salesforce.com/services/oauth2/authorize"
+  "https://login.salesforce.com/services/oauth2/token"
 
 oauth2SalesforceSandbox :: YesodAuth m => Text -> Text -> AuthPlugin m
 oauth2SalesforceSandbox = oauth2SalesforceSandboxScoped defaultScopes
 
 oauth2SalesforceSandboxScoped
-    :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
+  :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
 oauth2SalesforceSandboxScoped = salesforceHelper
-    (pluginName <> "-sandbox")
-    "https://test.salesforce.com/services/oauth2/userinfo"
-    "https://test.salesforce.com/services/oauth2/authorize"
-    "https://test.salesforce.com/services/oauth2/token"
+  (pluginName <> "-sandbox")
+  "https://test.salesforce.com/services/oauth2/userinfo"
+  "https://test.salesforce.com/services/oauth2/authorize"
+  "https://test.salesforce.com/services/oauth2/token"
 
 salesforceHelper
-    :: YesodAuth m
-    => Text
-    -> URI -- ^ User profile
-    -> URI -- ^ Authorize
-    -> URI -- ^ Token
-    -> [Text]
-    -> Text
-    -> Text
-    -> AuthPlugin m
+  :: YesodAuth m
+  => Text
+  -> URI -- ^ User profile
+  -> URI -- ^ Authorize
+  -> URI -- ^ Token
+  -> [Text]
+  -> Text
+  -> Text
+  -> AuthPlugin m
 salesforceHelper name profileUri authorizeUri tokenUri scopes clientId clientSecret
-    = authOAuth2 name oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            name
-            manager
-            token
-            profileUri
+  = authOAuth2 name oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile name manager token profileUri
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            authorizeUri `withQuery` [scopeParam " " scopes]
-        , oauthAccessTokenEndpoint = tokenUri
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes]
+    , oauth2TokenEndpoint     = tokenUri
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/Slack.hs b/src/Yesod/Auth/OAuth2/Slack.hs
--- a/src/Yesod/Auth/OAuth2/Slack.hs
+++ b/src/Yesod/Auth/OAuth2/Slack.hs
@@ -6,11 +6,10 @@
 -- * Uses slack user id as credentials identifier
 --
 module Yesod.Auth.OAuth2.Slack
-    ( SlackScope(..)
-    , oauth2Slack
-    , oauth2SlackScoped
-    )
-where
+  ( SlackScope(..)
+  , oauth2Slack
+  , oauth2SlackScoped
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -25,17 +24,17 @@
     | SlackAvatarScope
 
 scopeText :: SlackScope -> Text
-scopeText SlackBasicScope = "identity.basic"
-scopeText SlackEmailScope = "identity.email"
-scopeText SlackTeamScope = "identity.team"
+scopeText SlackBasicScope  = "identity.basic"
+scopeText SlackEmailScope  = "identity.email"
+scopeText SlackTeamScope   = "identity.team"
 scopeText SlackAvatarScope = "identity.avatar"
 
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \root -> do
-        o <- root .: "user"
-        User <$> o .: "id"
+  parseJSON = withObject "User" $ \root -> do
+    o <- root .: "user"
+    User <$> o .: "id"
 
 pluginName :: Text
 pluginName = "slack"
@@ -46,30 +45,31 @@
 oauth2Slack :: YesodAuth m => Text -> Text -> AuthPlugin m
 oauth2Slack = oauth2SlackScoped defaultScopes
 
-oauth2SlackScoped :: YesodAuth m => [SlackScope] -> Text -> Text -> AuthPlugin m
+oauth2SlackScoped
+  :: YesodAuth m => [SlackScope] -> Text -> Text -> AuthPlugin m
 oauth2SlackScoped scopes clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        let param = encodeUtf8 $ atoken $ accessToken token
-        req <- setQueryString [("token", Just param)]
-            <$> parseUrlThrow "https://slack.com/api/users.identity"
-        userResponse <- responseBody <$> httpLbs req manager
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    let param = encodeUtf8 $ atoken $ accessToken token
+    req <- setQueryString [("token", Just param)]
+      <$> parseUrlThrow "https://slack.com/api/users.identity"
+    userResponse <- responseBody <$> httpLbs req manager
 
-        either
-                (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
-                (\(User userId) -> pure Creds
-                    { credsPlugin = pluginName
-                    , credsIdent = userId
-                    , credsExtra = setExtra token userResponse
-                    }
-                )
-            $ eitherDecode userResponse
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://slack.com/oauth/authorize"
-                `withQuery` [scopeParam "," $ map scopeText scopes]
-        , oauthAccessTokenEndpoint = "https://slack.com/api/oauth.access"
-        , oauthCallback = Nothing
-        }
+    either
+        (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
+        (\(User userId) -> pure Creds { credsPlugin = pluginName
+                                      , credsIdent = userId
+                                      , credsExtra = setExtra token userResponse
+                                      }
+        )
+      $ eitherDecode userResponse
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://slack.com/oauth/authorize"
+                                  `withQuery` [ scopeParam ","
+                                                  $ map scopeText scopes
+                                              ]
+    , oauth2TokenEndpoint     = "https://slack.com/api/oauth.access"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/Spotify.hs b/src/Yesod/Auth/OAuth2/Spotify.hs
--- a/src/Yesod/Auth/OAuth2/Spotify.hs
+++ b/src/Yesod/Auth/OAuth2/Spotify.hs
@@ -4,41 +4,38 @@
 -- OAuth2 plugin for http://spotify.com
 --
 module Yesod.Auth.OAuth2.Spotify
-    ( oauth2Spotify
-    )
-where
+  ( oauth2Spotify
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
 newtype User = User Text
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \o -> User <$> o .: "id"
+  parseJSON = withObject "User" $ \o -> User <$> o .: "id"
 
 pluginName :: Text
 pluginName = "spotify"
 
 oauth2Spotify :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
 oauth2Spotify scopes clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "https://api.spotify.com/v1/me"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "https://api.spotify.com/v1/me"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://accounts.spotify.com/authorize"
-                `withQuery` [scopeParam " " scopes]
-        , oauthAccessTokenEndpoint = "https://accounts.spotify.com/api/token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "https://accounts.spotify.com/authorize"
+                                  `withQuery` [scopeParam " " scopes]
+    , oauth2TokenEndpoint     = "https://accounts.spotify.com/api/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/Upcase.hs b/src/Yesod/Auth/OAuth2/Upcase.hs
--- a/src/Yesod/Auth/OAuth2/Upcase.hs
+++ b/src/Yesod/Auth/OAuth2/Upcase.hs
@@ -7,9 +7,8 @@
 -- * Uses upcase user id as credentials identifier
 --
 module Yesod.Auth.OAuth2.Upcase
-    ( oauth2Upcase
-    )
-where
+  ( oauth2Upcase
+  ) where
 
 import Yesod.Auth.OAuth2.Prelude
 
@@ -18,32 +17,31 @@
 newtype User = User Int
 
 instance FromJSON User where
-    parseJSON = withObject "User" $ \root -> do
-        o <- root .: "user"
-        User <$> o .: "id"
+  parseJSON = withObject "User" $ \root -> do
+    o <- root .: "user"
+    User <$> o .: "id"
 
 pluginName :: Text
 pluginName = "upcase"
 
 oauth2Upcase :: YesodAuth m => Text -> Text -> AuthPlugin m
 oauth2Upcase clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (User userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "http://upcase.com/api/v1/me.json"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (User userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "http://upcase.com/api/v1/me.json"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = T.pack $ show userId
-            , credsExtra = setExtra token userResponse
-            }
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint = "http://upcase.com/oauth/authorize"
-        , oauthAccessTokenEndpoint = "http://upcase.com/oauth/token"
-        , oauthCallback = Nothing
-        }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = T.pack $ show userId
+               , credsExtra  = setExtra token userResponse
+               }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint = "http://upcase.com/oauth/authorize"
+    , oauth2TokenEndpoint     = "http://upcase.com/oauth/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/src/Yesod/Auth/OAuth2/WordPressDotCom.hs b/src/Yesod/Auth/OAuth2/WordPressDotCom.hs
--- a/src/Yesod/Auth/OAuth2/WordPressDotCom.hs
+++ b/src/Yesod/Auth/OAuth2/WordPressDotCom.hs
@@ -1,9 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 module Yesod.Auth.OAuth2.WordPressDotCom
-    ( oauth2WordPressDotCom
-    )
-where
+  ( oauth2WordPressDotCom
+  ) where
 
 import qualified Data.Text as T
 import Yesod.Auth.OAuth2.Prelude
@@ -14,35 +13,33 @@
 newtype WpUser = WpUser Int
 
 instance FromJSON WpUser where
-    parseJSON = withObject "WpUser" $ \o -> WpUser <$> o .: "ID"
+  parseJSON = withObject "WpUser" $ \o -> WpUser <$> o .: "ID"
 
 oauth2WordPressDotCom
-    :: (YesodAuth m)
-    => Text -- ^ Client Id
-    -> Text -- ^ Client Secret
-    -> AuthPlugin m
+  :: (YesodAuth m)
+  => Text -- ^ Client Id
+  -> Text -- ^ Client Secret
+  -> AuthPlugin m
 oauth2WordPressDotCom clientId clientSecret =
-    authOAuth2 pluginName oauth2 $ \manager token -> do
-        (WpUser userId, userResponse) <- authGetProfile
-            pluginName
-            manager
-            token
-            "https://public-api.wordpress.com/rest/v1/me/"
+  authOAuth2 pluginName oauth2 $ \manager token -> do
+    (WpUser userId, userResponse) <- authGetProfile
+      pluginName
+      manager
+      token
+      "https://public-api.wordpress.com/rest/v1/me/"
 
-        pure Creds
-            { credsPlugin = pluginName
-            , credsIdent = T.pack $ show userId
-            , credsExtra = setExtra token userResponse
-            }
+    pure Creds { credsPlugin = pluginName
+               , credsIdent  = T.pack $ show userId
+               , credsExtra  = setExtra token userResponse
+               }
 
-  where
-    oauth2 = OAuth2
-        { oauthClientId = clientId
-        , oauthClientSecret = Just clientSecret
-        , oauthOAuthorizeEndpoint =
-            "https://public-api.wordpress.com/oauth2/authorize"
-                `withQuery` [scopeParam "," ["auth"]]
-        , oauthAccessTokenEndpoint =
-            "https://public-api.wordpress.com/oauth2/token"
-        , oauthCallback = Nothing
-        }
+ where
+  oauth2 = OAuth2
+    { oauth2ClientId          = clientId
+    , oauth2ClientSecret      = Just clientSecret
+    , oauth2AuthorizeEndpoint =
+      "https://public-api.wordpress.com/oauth2/authorize"
+        `withQuery` [scopeParam "," ["auth"]]
+    , oauth2TokenEndpoint     = "https://public-api.wordpress.com/oauth2/token"
+    , oauth2RedirectUri       = Nothing
+    }
diff --git a/yesod-auth-oauth2.cabal b/yesod-auth-oauth2.cabal
--- a/yesod-auth-oauth2.cabal
+++ b/yesod-auth-oauth2.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.12
 name:               yesod-auth-oauth2
-version:            0.6.3.4
+version:            0.7.0.0
 license:            MIT
 license-file:       LICENSE
 maintainer:         engineering@freckle.com
@@ -31,6 +31,7 @@
 
 library
     exposed-modules:
+        Network.OAuth.OAuth2.Compat
         UnliftIO.Except
         URI.ByteString.Extension
         Yesod.Auth.OAuth2
@@ -70,12 +71,12 @@
         http-conduit >=2.0,
         http-types >=0.8,
         memory >=0.15.0,
-        microlens >=0.4.11.2,
+        microlens >=0.4.12.0,
         mtl >=2.2.2,
-        safe-exceptions >=0.1.7.1,
+        safe-exceptions >=0.1.7.2,
         text >=0.7,
-        unliftio >=0.2.14,
-        uri-bytestring >=0.3.3.0,
+        unliftio >=0.2.20,
+        uri-bytestring >=0.3.3.1,
         yesod-auth >=1.6.0,
         yesod-core >=1.6.0
 
@@ -87,15 +88,15 @@
     ghc-options:      -Wall -threaded -rtsopts -with-rtsopts=-N
     build-depends:
         aeson >=0.6,
-        aeson-pretty >=0.8.8,
+        aeson-pretty >=0.8.9,
         base >=4.9.0.0 && <5,
         bytestring >=0.9.1.4,
-        containers >=0.6.2.1,
+        containers >=0.6.5.1,
         http-conduit >=2.0,
         load-env >=0.2.1.0,
         text >=0.7,
-        warp >=3.3.14,
-        yesod >=1.6.1.0,
+        warp >=3.3.18,
+        yesod >=1.6.1.2,
         yesod-auth >=1.6.0,
         yesod-auth-oauth2 -any
 
@@ -114,6 +115,6 @@
     ghc-options:      -Wall
     build-depends:
         base >=4.9.0.0 && <5,
-        hspec >=2.7.8,
-        uri-bytestring >=0.3.3.0,
+        hspec >=2.7.10,
+        uri-bytestring >=0.3.3.1,
         yesod-auth-oauth2 -any
