Compare commits

...

22 Commits

Author SHA1 Message Date
patrick brisbin
a4c3d9f049 Fix STACK_YAML in release
Some checks failed
CI / generate (push) Has been cancelled
CI / lint (push) Has been cancelled
Release / release (push) Has been cancelled
CI / test (push) Has been cancelled
We removed some resolvers, so we need to update the minimum that's used
here.
2026-01-07 12:22:51 -05:00
freckle-automation-app[bot]
3dd2318067 Remove .github/workflows/add-asana-comment.yml
Some checks are pending
CI / lint (push) Waiting to run
CI / generate (push) Waiting to run
CI / test (push) Blocked by required conditions
Release / release (push) Waiting to run
2026-01-06 17:02:42 -05:00
patrick brisbin
3e5dbdec77 Version bump 2026-01-06 16:47:57 -05:00
patrick brisbin
a8de561848 Change interface to support newer hoauth2
This adds support for `ghc-9.12` / `hoauth2-2.15` and drops support for
`ghc < 9.4` / `hoauth2 < 2.8`.

Since this would be a major version bump no matter what, I've changed
the interface we present to align with `hoauth2-2.15`. This means using
the newer `fetch` functions, and `TokenResponse{,Error}` type names.

I've maintained our own `OAuth2` type so that the redirect-uri can
remain a `Maybe` field. The way plugins are constructed, we need to
build an `OAuth2` value in a pure context without one, which is then
supplied later, when we have `MonadHandler` and so can render URLs.
2026-01-06 16:47:57 -05:00
devin-ai-integration[bot]
a179049522
chore(ci): add permissions to workflow files (#198)
Some checks failed
CI / generate (push) Has been cancelled
CI / test (push) Has been cancelled
CI / lint (push) Has been cancelled
Release / release (push) Has been cancelled
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-15 11:17:18 -04:00
renovate[bot]
36bc61fa27
chore(deps): update actions/checkout action to v5 (#197)
Some checks failed
CI / generate (push) Has been cancelled
CI / test (push) Has been cancelled
CI / lint (push) Has been cancelled
Release / release (push) Has been cancelled
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-24 12:29:06 -04:00
freckle-automation-app[bot]
09cda079d4 Remove .github/workflows/mergeabot.yml 2025-07-07 09:27:42 -04:00
freckle-automation-app[bot]
560647fb01 Remove .github/dependabot.yml 2025-07-07 09:27:42 -04:00
freckle-automation-app[bot]
7f6096079f Update renovate.json 2025-07-03 12:29:36 -04:00
Joris Buchou
4e123a9482
🤖 Fix: CODEOWNERS (#192)
* Update .github/CODEOWNERS

* Update CODEOWNERS

---------

Co-authored-by: Chris Martin <ch.martin@gmail.com>
2025-01-09 18:05:46 +00:00
Joris Buchou
a916af9688
Update .github/workflows/mergeabot.yml (#190)
Co-authored-by: Chris Martin <ch.martin@gmail.com>
2025-01-03 17:18:45 +00:00
freckle-automation-app[bot]
3b55cee63b
Update .github/workflows/add-asana-comment.yml (#193)
Co-authored-by: freckle-automation-app[bot] <176077675+freckle-automation-app[bot]@users.noreply.github.com>
Co-authored-by: Chris Martin <ch.martin@gmail.com>
2025-01-03 01:18:53 +00:00
Joris Buchou
fa54bc36aa
Update .github/dependabot.yml (#191) 2025-01-02 18:04:52 -07:00
patrick brisbin
e79d174821 Version bump 2024-11-05 14:29:49 -05:00
jaanisfehling
51c6574183
Add custom widget functions to Azure AD v2 2024-11-04 14:08:22 -05:00
patrick brisbin
50cc0ea49b Version bump 2024-07-08 12:29:34 -04:00
patrick brisbin
56c2d0a30d Fix import sorting in Main 2024-07-08 12:29:34 -04:00
Ding
624b2be5aa Add ORCID OAuth provider 2024-07-08 12:29:34 -04:00
patrick brisbin
87a0231a6d Update CI for removed lts-14 configuration 2024-07-08 12:08:24 -04:00
patrick brisbin
7b0d4f6243 HLint 2024-07-08 12:08:24 -04:00
patrick brisbin
07c6ea6875 Remove incorrect comment 2024-07-08 12:08:24 -04:00
patrick brisbin
433e8b324b Replace cryptonite with crypton
https://github.com/commercialhaskell/stackage/issues/7474#issuecomment-2208142024
2024-07-08 12:08:24 -04:00
61 changed files with 283 additions and 438 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1 @@
* @freckle/backenders

View File

@ -0,0 +1,16 @@
name: Asana
on:
pull_request:
types: [opened]
jobs:
link-asana-task:
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
steps:
- uses: Asana/create-app-attachment-github-action@v1.3
id: postAttachment
with:
asana-secret: ${{ secrets.ASANA_API_ACCESS_KEY }}
- run: echo "Status is ${{ steps.postAttachment.outputs.status }}"

View File

@ -9,38 +9,40 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs: permissions:
test: contents: read
runs-on: ubuntu-latest
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- id: generate
uses: freckle/stack-action/generate-matrix@v5
outputs:
stack-yamls: ${{ steps.generate.outputs.stack-yamls }}
test:
needs: generate
strategy: strategy:
matrix: matrix:
stack-yaml: stack-yaml: ${{ fromJSON(needs.generate.outputs.stack-yamls) }}
- stack-nightly.yaml # ghc-9.8
- stack.yaml # ghc-9.6
- stack-lts-21.25.yaml # ghc-9.4
- stack-lts-20.26.yaml # ghc-9.2
- stack-lts-19.33.yaml # ghc-9.0
- stack-lts-18.28.yaml # ghc-8.10
- stack-lts-16.31.yaml # ghc-8.8
- stack-lts-14.27.yaml # ghc-8.6 + hoauth2-1.14.0
- stack-hoauth2-2.6.yaml # ghc-9.4 (nightly-2022-12-09)
- stack-hoauth2-2.3.yaml # ghc-9.0 (nightly-2022-02-25)
- stack-hoauth2-2.2.yaml # ghc-9.0 (nightly-2022-02-25)
- stack-hoauth2-2.0.yaml # ghc-8.10
fail-fast: false fail-fast: false
runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: freckle/stack-action@v5 - uses: freckle/stack-action@v5
with: with:
stack-yaml: ${{ matrix.stack-yaml }}
stack-build-arguments: --flag yesod-auth-oauth2:example stack-build-arguments: --flag yesod-auth-oauth2:example
env:
STACK_YAML: ${{ matrix.stack-yaml }}
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: haskell-actions/hlint-setup@v2 - uses: haskell-actions/hlint-setup@v2
- uses: haskell-actions/hlint-run@v2 - uses: haskell-actions/hlint-run@v2
with: with:

View File

@ -8,7 +8,7 @@ jobs:
release: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- id: tag - id: tag
uses: freckle/haskell-tag-action@v1 uses: freckle/haskell-tag-action@v1
@ -19,4 +19,4 @@ jobs:
HACKAGE_KEY: ${{ secrets.HACKAGE_UPLOAD_API_KEY }} HACKAGE_KEY: ${{ secrets.HACKAGE_UPLOAD_API_KEY }}
# Use minimum LTS to set lowest lower bounds # Use minimum LTS to set lowest lower bounds
STACK_YAML: stack-lts-14.27.yaml STACK_YAML: stack-lts21.yaml

2
.stack-all Normal file
View File

@ -0,0 +1,2 @@
[versions]
oldest = lts-21

View File

@ -1,4 +1,27 @@
## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.2.0...main) ## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.8.0.0...main)
## [v0.8.0.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.4.0...v0.8.0.0)
- Drop support for GHC < 9.4 and hoauth2 < 2.8
- Add support for GHC 9.12 and hoauth2-2.15
- To align our interfaces with hoauth2-2.15:
- Make `OAuth2 {clientSecret}` non-`Maybe`
- Replace `OAuthToken` with `TokenResponse`
- Replace `Errors` with `TokenResponseError`
- Replace `fetchAccessToken{,2}` with `fetchAccessToken{Basic,Post}`
While technically a major version bump, this change should only affect those
users that maintain their own plugins.
## [v0.7.4.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.3.0...v0.7.4.0)
- Add `oauth2AzureADv2Widget` and `oauth2AzureADv2ScopedWidget`
## [v0.7.3.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.2.0...v0.7.3.0)
- Add ORCID provider
- Drop support for LTS-12 / GHC-8.6
- Replace `cryptonite` with `crypton`
## [v0.7.2.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.3...v0.7.2.0) ## [v0.7.2.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.3...v0.7.2.0)

View File

@ -34,6 +34,7 @@ import Yesod.Auth.OAuth2.GitHub
import Yesod.Auth.OAuth2.GitLab import Yesod.Auth.OAuth2.GitLab
import Yesod.Auth.OAuth2.Google import Yesod.Auth.OAuth2.Google
import Yesod.Auth.OAuth2.Nylas import Yesod.Auth.OAuth2.Nylas
import Yesod.Auth.OAuth2.ORCID
import Yesod.Auth.OAuth2.Salesforce import Yesod.Auth.OAuth2.Salesforce
import Yesod.Auth.OAuth2.Slack import Yesod.Auth.OAuth2.Slack
import Yesod.Auth.OAuth2.Spotify import Yesod.Auth.OAuth2.Spotify
@ -149,6 +150,7 @@ mkFoundation = do
, loadPlugin (oauth2Spotify []) "SPOTIFY" , loadPlugin (oauth2Spotify []) "SPOTIFY"
, loadPlugin oauth2Twitch "TWITCH" , loadPlugin oauth2Twitch "TWITCH"
, loadPlugin oauth2WordPressDotCom "WORDPRESS_DOT_COM" , loadPlugin oauth2WordPressDotCom "WORDPRESS_DOT_COM"
, loadPlugin oauth2ORCID "ORCID"
, loadPlugin oauth2Upcase "UPCASE" , loadPlugin oauth2Upcase "UPCASE"
] ]

View File

@ -1,6 +1,6 @@
--- ---
name: yesod-auth-oauth2 name: yesod-auth-oauth2
version: 0.7.2.0 version: 0.8.0.0
synopsis: OAuth 2.0 authentication plugins synopsis: OAuth 2.0 authentication plugins
description: Library to authenticate with OAuth 2.0 for Yesod web applications. description: Library to authenticate with OAuth 2.0 for Yesod web applications.
category: Web category: Web
@ -27,9 +27,9 @@ library:
dependencies: dependencies:
- aeson >=0.6 - aeson >=0.6
- bytestring >=0.9.1.4 - bytestring >=0.9.1.4
- cryptonite >=0.25 - crypton
- errors - errors
- hoauth2 >=1.11.0 - hoauth2 >=2.8.0 # TokenRequestError
- http-client >=0.4.0 - http-client >=0.4.0
- http-conduit >=2.0 - http-conduit >=2.0
- http-types >=0.8 - http-types >=0.8

7
renovate.json Normal file
View File

@ -0,0 +1,7 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>freckle/renovate-config"
],
"minimumReleaseAge": "0 days"
}

View File

@ -2,170 +2,117 @@
module Network.OAuth.OAuth2.Compat module Network.OAuth.OAuth2.Compat
( OAuth2 (..) ( OAuth2 (..)
, OAuth2Result
, Errors
, authorizationUrl , authorizationUrl
, fetchAccessToken , fetchAccessTokenBasic
, fetchAccessToken2 , fetchAccessTokenPost
, authGetBS , authGetBS
-- * Re-exports -- * Re-exports
, module Network.OAuth.OAuth2 , AccessToken (..)
, ExchangeToken (..)
, RefreshToken (..)
, TokenResponse
, accessToken
, refreshToken
, expiresIn
, tokenType
, idToken
, TokenResponseError
) where ) where
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Trans.Except (runExceptT)
import Data.ByteString.Lazy (ByteString) import Data.ByteString.Lazy (ByteString)
import Data.Text (Text) import Data.Text (Text)
import Network.HTTP.Conduit (Manager) import Network.HTTP.Conduit (Manager)
import URI.ByteString
#if MIN_VERSION_hoauth2(2,15,0)
import Network.OAuth2
( AccessToken (..)
, ExchangeToken (..)
, RefreshToken (..)
, TokenResponse (..)
, TokenResponseError
)
import qualified Network.OAuth2 as OAuth2
#elif MIN_VERSION_hoauth2(2,9,0)
import Network.OAuth.OAuth2 import Network.OAuth.OAuth2
( AccessToken (..) ( AccessToken (..)
, ExchangeToken (..) , ExchangeToken (..)
, OAuth2Token (..)
, RefreshToken (..) , RefreshToken (..)
, OAuth2Token (..)
, TokenResponseError
) )
import qualified Network.OAuth.OAuth2 as OAuth2 import qualified Network.OAuth.OAuth2 as OAuth2
import URI.ByteString
#if MIN_VERSION_hoauth2(2,2,0) type TokenResponse = OAuth2Token
import Control.Monad.Trans.Except (ExceptT, runExceptT)
import Data.Maybe (fromMaybe)
#endif
#if MIN_VERSION_hoauth2(2,9,0)
import Network.OAuth.OAuth2.TokenRequest (TokenResponseError)
type Errors = TokenResponseError
#elif MIN_VERSION_hoauth2(2,7,0)
import Network.OAuth.OAuth2.TokenRequest (TokenRequestError)
type Errors = TokenRequestError
#else #else
import qualified Network.OAuth.OAuth2.TokenRequest as LegacyTokenRequest -- hoauth2-2.8
import Network.OAuth.OAuth2 (OAuth2Error) import Network.OAuth.OAuth2
type Errors = OAuth2Error LegacyTokenRequest.Errors ( AccessToken (..)
#endif , ExchangeToken (..)
, RefreshToken (..)
, OAuth2Token (..)
)
import Network.OAuth.OAuth2.TokenRequest (TokenRequestError)
import qualified Network.OAuth.OAuth2 as OAuth2
{-# ANN module ("HLint: ignore Use fewer imports" :: String) #-} type TokenResponse = OAuth2Token
type TokenResponseError = TokenRequestError
#endif
data OAuth2 = OAuth2 data OAuth2 = OAuth2
{ oauth2ClientId :: Text { oauth2ClientId :: Text
, oauth2ClientSecret :: Maybe Text , oauth2ClientSecret :: Text
, oauth2AuthorizeEndpoint :: URIRef Absolute , oauth2AuthorizeEndpoint :: URIRef Absolute
, oauth2TokenEndpoint :: URIRef Absolute , oauth2TokenEndpoint :: URIRef Absolute
, oauth2RedirectUri :: Maybe (URIRef Absolute) , oauth2RedirectUri :: Maybe (URIRef Absolute)
} }
type OAuth2Result err a = Either err a
authorizationUrl :: OAuth2 -> URI authorizationUrl :: OAuth2 -> URI
authorizationUrl = OAuth2.authorizationUrl . getOAuth2 authorizationUrl = OAuth2.authorizationUrl . getOAuth2
fetchAccessToken
:: Manager
-> OAuth2
-> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token)
fetchAccessToken = fetchAccessTokenBasic
fetchAccessToken2
:: Manager
-> OAuth2
-> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token)
fetchAccessToken2 = fetchAccessTokenPost
authGetBS :: Manager -> AccessToken -> URI -> IO (Either ByteString ByteString)
authGetBS m a u = runOAuth2 $ OAuth2.authGetBS m a u
-- Normalize the rename of record fields at hoauth2-2.0. Our type is the newer
-- names and we up-convert if hoauth2-1.x is in use. getClientSecret and
-- getRedirectUri handle the differences in hoauth2-2.2 and 2.3.
#if MIN_VERSION_hoauth2(2,0,0)
getOAuth2 :: OAuth2 -> OAuth2.OAuth2
getOAuth2 o = OAuth2.OAuth2
{ OAuth2.oauth2ClientId = oauth2ClientId o
, OAuth2.oauth2ClientSecret = getClientSecret $ oauth2ClientSecret o
, OAuth2.oauth2AuthorizeEndpoint = oauth2AuthorizeEndpoint o
, OAuth2.oauth2TokenEndpoint = oauth2TokenEndpoint o
, OAuth2.oauth2RedirectUri = getRedirectUri $ oauth2RedirectUri o
}
#else
getOAuth2 :: OAuth2 -> OAuth2.OAuth2
getOAuth2 o = OAuth2.OAuth2
{ OAuth2.oauthClientId = oauth2ClientId o
, OAuth2.oauthClientSecret = getClientSecret $ oauth2ClientSecret o
, OAuth2.oauthOAuthorizeEndpoint = oauth2AuthorizeEndpoint o
, OAuth2.oauthAccessTokenEndpoint = oauth2TokenEndpoint o
, OAuth2.oauthCallback = getRedirectUri $ oauth2RedirectUri o
}
#endif
-- hoauth2-2.2 made oauth2ClientSecret non-Maybe, after 2.0 had just made it
-- Maybe so we have to adjust, twice. TODO: change ours type to non-Maybe (major
-- bump) and reverse this to up-convert with Just in pre-2.2.
#if MIN_VERSION_hoauth2(2,2,0)
getClientSecret :: Maybe Text -> Text
getClientSecret =
fromMaybe $ error "Cannot use OAuth2.oauth2ClientSecret with Nothing"
#else
getClientSecret :: Maybe Text -> Maybe Text
getClientSecret = id
#endif
-- hoauth2-2.3 then made oauth2RedirectUri non-Maybe too. We logically rely on
-- instantiating with Nothing at definition-time, then setting it to the
-- callback at use-time, which means we can't just change our type and invert
-- this shim; we'll have to do something much more pervasive to avoid this
-- fromMaybe.
#if MIN_VERSION_hoauth2(2,3,0)
getRedirectUri :: Maybe (URIRef Absolute) -> (URIRef Absolute)
getRedirectUri =
fromMaybe $ error "Cannot use OAuth2.oauth2RedirectUri with Nothing"
#else
getRedirectUri :: Maybe (URIRef Absolute) -> Maybe (URIRef Absolute)
getRedirectUri = id
#endif
-- hoauth-2.2 moved most IO-Either functions to ExceptT. This reverses that.
#if MIN_VERSION_hoauth2(2,2,0)
runOAuth2 :: ExceptT e m a -> m (Either e a)
runOAuth2 = runExceptT
#else
runOAuth2 :: IO (Either e a) -> IO (Either e a)
runOAuth2 = id
#endif
-- The fetchAccessToken functions grew a nicer interface in hoauth2-2.3. This
-- up-converts the older ones. We should update our code to use these functions
-- directly.
fetchAccessTokenBasic fetchAccessTokenBasic
:: Manager :: Manager
-> OAuth2 -> OAuth2
-> ExchangeToken -> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token) -> IO (Either TokenResponseError TokenResponse)
fetchAccessTokenBasic m o e = runOAuth2 $ f m (getOAuth2 o) e fetchAccessTokenBasic =
where runFetchAccessToken OAuth2.ClientSecretBasic
#if MIN_VERSION_hoauth2(2,6,0)
f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretBasic
#elif MIN_VERSION_hoauth2(2,3,0)
f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretBasic
#else
f = OAuth2.fetchAccessToken
#endif
fetchAccessTokenPost fetchAccessTokenPost
:: Manager :: Manager
-> OAuth2 -> OAuth2
-> ExchangeToken -> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token) -> IO (Either TokenResponseError TokenResponse)
fetchAccessTokenPost m o e = runOAuth2 $ f m (getOAuth2 o) e fetchAccessTokenPost =
where runFetchAccessToken OAuth2.ClientSecretPost
#if MIN_VERSION_hoauth2(2, 6, 0)
f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretPost authGetBS :: Manager -> AccessToken -> URI -> IO (Either ByteString ByteString)
#elif MIN_VERSION_hoauth2(2,3,0) authGetBS m a u = runExceptT $ OAuth2.authGetBS m a u
f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretPost
#else getOAuth2 :: OAuth2 -> OAuth2.OAuth2
f = OAuth2.fetchAccessToken2 getOAuth2 o =
#endif OAuth2.OAuth2
{ OAuth2.oauth2ClientId = oauth2ClientId o
, OAuth2.oauth2ClientSecret = oauth2ClientSecret o
, OAuth2.oauth2AuthorizeEndpoint = oauth2AuthorizeEndpoint o
, OAuth2.oauth2TokenEndpoint = oauth2TokenEndpoint o
, OAuth2.oauth2RedirectUri = case oauth2RedirectUri o of
Nothing ->
error
"programmer error: yesod-auth-oauth2:OAuth2 must have a Just value set as oauth2RedirectUri before using as an hauth2:OAuth2 value"
Just uri -> uri
}
runFetchAccessToken
:: MonadIO m
=> OAuth2.ClientAuthenticationMethod
-> Manager
-> OAuth2
-> ExchangeToken
-> m (Either TokenResponseError TokenResponse)
runFetchAccessToken am m o e = runExceptT $ OAuth2.fetchAccessTokenWithAuthMethod am m (getOAuth2 o) e

View File

@ -11,13 +11,13 @@ module Yesod.Auth.OAuth2
( OAuth2 (..) ( OAuth2 (..)
, FetchCreds , FetchCreds
, Manager , Manager
, OAuth2Token (..) , TokenResponse
, Creds (..) , Creds (..)
, oauth2Url , oauth2Url
, authOAuth2 , authOAuth2
, authOAuth2Widget , authOAuth2Widget
-- * Alternatives that use 'fetchAccessToken2' -- * Alternatives that use 'fetchAccessTokenPost'
, authOAuth2' , authOAuth2'
, authOAuth2Widget' , authOAuth2Widget'
@ -49,7 +49,7 @@ oauth2Url name = PluginR name ["forward"]
authOAuth2 :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m authOAuth2 :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m
authOAuth2 name = authOAuth2Widget [whamlet|Login via #{name}|] name authOAuth2 name = authOAuth2Widget [whamlet|Login via #{name}|] name
-- | A version of 'authOAuth2' that uses 'fetchAccessToken2' -- | A version of 'authOAuth2' that uses 'fetchAccessTokenPost'
-- --
-- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129> -- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129>
authOAuth2' :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m authOAuth2' :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m
@ -66,9 +66,9 @@ authOAuth2Widget
-> OAuth2 -> OAuth2
-> FetchCreds m -> FetchCreds m
-> AuthPlugin m -> AuthPlugin m
authOAuth2Widget = buildPlugin fetchAccessToken authOAuth2Widget = buildPlugin fetchAccessTokenBasic
-- | A version of 'authOAuth2Widget' that uses 'fetchAccessToken2' -- | A version of 'authOAuth2Widget' that uses 'fetchAccessTokenPost'
-- --
-- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129> -- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129>
authOAuth2Widget' authOAuth2Widget'
@ -78,7 +78,7 @@ authOAuth2Widget'
-> OAuth2 -> OAuth2
-> FetchCreds m -> FetchCreds m
-> AuthPlugin m -> AuthPlugin m
authOAuth2Widget' = buildPlugin fetchAccessToken2 authOAuth2Widget' = buildPlugin fetchAccessTokenPost
buildPlugin buildPlugin
:: YesodAuth m :: YesodAuth m

View File

@ -52,7 +52,7 @@ oauth2Auth0HostScopes host scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
host `withPath` "/authorize" `withQuery` [scopeParam " " scopes] host `withPath` "/authorize" `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = host `withPath` "/oauth/token" , oauth2TokenEndpoint = host `withPath` "/oauth/token"

View File

@ -48,7 +48,7 @@ oauth2AzureADScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://login.windows.net/common/oauth2/authorize" "https://login.windows.net/common/oauth2/authorize"
`withQuery` [ scopeParam "," scopes `withQuery` [ scopeParam "," scopes

View File

@ -1,4 +1,5 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
-- | -- |
-- --
@ -9,9 +10,12 @@
module Yesod.Auth.OAuth2.AzureADv2 module Yesod.Auth.OAuth2.AzureADv2
( oauth2AzureADv2 ( oauth2AzureADv2
, oauth2AzureADv2Scoped , oauth2AzureADv2Scoped
, oauth2AzureADv2Widget
, oauth2AzureADv2ScopedWidget
) where ) where
import Yesod.Auth.OAuth2.Prelude import Yesod.Auth.OAuth2.Prelude
import Yesod.Core (WidgetFor, whamlet)
import Prelude import Prelude
import Data.String import Data.String
@ -41,9 +45,21 @@ oauth2AzureADv2
-> AuthPlugin m -> AuthPlugin m
oauth2AzureADv2 = oauth2AzureADv2Scoped defaultScopes oauth2AzureADv2 = oauth2AzureADv2Scoped defaultScopes
oauth2AzureADv2Widget
:: YesodAuth m => WidgetFor m () -> Text -> Text -> Text -> AuthPlugin m
oauth2AzureADv2Widget widget =
oauth2AzureADv2ScopedWidget widget defaultScopes
oauth2AzureADv2Scoped oauth2AzureADv2Scoped
:: YesodAuth m => [Text] -> Text -> Text -> Text -> AuthPlugin m
oauth2AzureADv2Scoped =
oauth2AzureADv2ScopedWidget [whamlet|Login via #{pluginName}|]
oauth2AzureADv2ScopedWidget
:: YesodAuth m :: YesodAuth m
=> [Text] => WidgetFor m ()
-- ^ Widget
-> [Text]
-- ^ Scopes -- ^ Scopes
-> Text -> Text
-- ^ Tenant Id -- ^ Tenant Id
@ -54,8 +70,8 @@ oauth2AzureADv2Scoped
-> Text -> Text
-- ^ Client Secret -- ^ Client Secret
-> AuthPlugin m -> AuthPlugin m
oauth2AzureADv2Scoped scopes tenantId clientId clientSecret = oauth2AzureADv2ScopedWidget widget scopes tenantId clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
(User userId, userResponse) <- (User userId, userResponse) <-
authGetProfile authGetProfile
pluginName pluginName
@ -73,7 +89,7 @@ oauth2AzureADv2Scoped scopes tenantId clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
tenantUrl "/authorize" `withQuery` [scopeParam " " scopes] tenantUrl "/authorize" `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = tenantUrl "/token" , oauth2TokenEndpoint = tenantUrl "/token"

View File

@ -53,7 +53,7 @@ oauth2BattleNet widget region clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = fromRelative "https" host "/oauth/authorize" , oauth2AuthorizeEndpoint = fromRelative "https" host "/oauth/authorize"
, oauth2TokenEndpoint = fromRelative "https" host "/oauth/token" , oauth2TokenEndpoint = fromRelative "https" host "/oauth/token"
, oauth2RedirectUri = Nothing , oauth2RedirectUri = Nothing

View File

@ -55,7 +55,7 @@ oauth2BitbucketScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://bitbucket.com/site/oauth2/authorize" "https://bitbucket.com/site/oauth2/authorize"
`withQuery` [scopeParam "," scopes] `withQuery` [scopeParam "," scopes]

View File

@ -43,7 +43,7 @@ oauth2ClassLinkScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://launchpad.classlink.com/oauth2/v2/auth" "https://launchpad.classlink.com/oauth2/v2/auth"
`withQuery` [scopeParam "," scopes] `withQuery` [scopeParam "," scopes]

View File

@ -6,8 +6,8 @@
module Yesod.Auth.OAuth2.Dispatch module Yesod.Auth.OAuth2.Dispatch
( FetchToken ( FetchToken
, fetchAccessToken , fetchAccessTokenBasic
, fetchAccessToken2 , fetchAccessTokenPost
, FetchCreds , FetchCreds
, dispatchAuthRequest , dispatchAuthRequest
) where ) where
@ -31,10 +31,13 @@ import Yesod.Core hiding (ErrorResponse)
-- --
-- This will be 'fetchAccessToken' or 'fetchAccessToken2' -- This will be 'fetchAccessToken' or 'fetchAccessToken2'
type FetchToken = type FetchToken =
Manager -> OAuth2 -> ExchangeToken -> IO (OAuth2Result Errors OAuth2Token) Manager
-> OAuth2
-> ExchangeToken
-> IO (Either TokenResponseError TokenResponse)
-- | How to take an @'OAuth2Token'@ and retrieve user credentials -- | How to take an @'OAuth2Token'@ and retrieve user credentials
type FetchCreds m = Manager -> OAuth2Token -> IO (Creds m) type FetchCreds m = Manager -> TokenResponse -> IO (Creds m)
-- | Dispatch the various OAuth2 handshake routes -- | Dispatch the various OAuth2 handshake routes
dispatchAuthRequest dispatchAuthRequest

View File

@ -16,7 +16,7 @@ module Yesod.Auth.OAuth2.DispatchError
import Control.Monad.Except import Control.Monad.Except
import Data.Text (Text, pack) import Data.Text (Text, pack)
import Network.OAuth.OAuth2.Compat (Errors) import Network.OAuth.OAuth2.Compat (TokenResponseError)
import UnliftIO.Except () import UnliftIO.Except ()
import UnliftIO.Exception import UnliftIO.Exception
import Yesod.Auth hiding (ServerError) import Yesod.Auth hiding (ServerError)
@ -30,7 +30,7 @@ data DispatchError
| InvalidStateToken (Maybe Text) Text | InvalidStateToken (Maybe Text) Text
| InvalidCallbackUri Text | InvalidCallbackUri Text
| OAuth2HandshakeError ErrorResponse | OAuth2HandshakeError ErrorResponse
| OAuth2ResultError Errors | OAuth2ResultError TokenResponseError
| FetchCredsIOException IOException | FetchCredsIOException IOException
| FetchCredsYesodOAuth2Exception YesodOAuth2Exception | FetchCredsYesodOAuth2Exception YesodOAuth2Exception
| OtherDispatchError Text | OtherDispatchError Text

View File

@ -76,7 +76,7 @@ oauth2EveScoped scopes widgetType clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://login.eveonline.com/oauth/authorize" "https://login.eveonline.com/oauth/authorize"
`withQuery` [("response_type", "code"), scopeParam " " scopes] `withQuery` [("response_type", "code"), scopeParam " " scopes]

View File

@ -1,5 +1,3 @@
{-# LANGUAGE DeriveDataTypeable #-}
module Yesod.Auth.OAuth2.Exception module Yesod.Auth.OAuth2.Exception
( YesodOAuth2Exception (..) ( YesodOAuth2Exception (..)
) where ) where
@ -21,6 +19,6 @@ data YesodOAuth2Exception
-- --
-- Plugin name and error message. -- Plugin name and error message.
GenericError Text String GenericError Text String
deriving (Show, Typeable) deriving (Show)
instance Exception YesodOAuth2Exception instance Exception YesodOAuth2Exception

View File

@ -61,7 +61,7 @@ oauth2GitHubScopedWidget widget scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://github.com/login/oauth/authorize" "https://github.com/login/oauth/authorize"
`withQuery` [scopeParam "," scopes] `withQuery` [scopeParam "," scopes]

View File

@ -53,7 +53,7 @@ oauth2GitLabHostScopes host scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
host `withPath` "/oauth/authorize" `withQuery` [scopeParam " " scopes] host `withPath` "/oauth/authorize" `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = host `withPath` "/oauth/token" , oauth2TokenEndpoint = host `withPath` "/oauth/token"

View File

@ -39,9 +39,8 @@ newtype User = User Text
instance FromJSON User where instance FromJSON User where
parseJSON = parseJSON =
withObject "User" $ \o -> withObject "User" $ \o ->
User -- Required for data backwards-compatibility
-- Required for data backwards-compatibility User . ("google-uid:" <>) <$> o .: "sub"
<$> (("google-uid:" <>) <$> o .: "sub")
pluginName :: Text pluginName :: Text
pluginName = "google" pluginName = "google"
@ -81,7 +80,7 @@ oauth2GoogleScopedWidget widget scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://accounts.google.com/o/oauth2/auth" "https://accounts.google.com/o/oauth2/auth"
`withQuery` [scopeParam " " scopes] `withQuery` [scopeParam " " scopes]

View File

@ -55,7 +55,7 @@ oauth2Nylas clientId clientSecret =
oauth = oauth =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://api.nylas.com/oauth/authorize" "https://api.nylas.com/oauth/authorize"
`withQuery` [ ("response_type", "code") `withQuery` [ ("response_type", "code")

View File

@ -0,0 +1,50 @@
{-# LANGUAGE OverloadedStrings #-}
module Yesod.Auth.OAuth2.ORCID
( oauth2ORCID
) where
import qualified Data.Text as T
import Yesod.Auth.OAuth2.Prelude
pluginName :: Text
pluginName = "orcid"
newtype User = User Text
instance FromJSON User where
parseJSON = withObject "User" $ \o -> User <$> o .: "sub"
oauth2ORCID
:: YesodAuth m
=> Text
-- ^ Client Id
-> Text
-- ^ Client Secret
-> AuthPlugin m
oauth2ORCID clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
(User userId, userResponse) <-
authGetProfile
pluginName
manager
token
"https://orcid.org/oauth/userinfo"
pure
Creds
{ credsPlugin = pluginName
, credsIdent = T.pack $ show userId
, credsExtra = setExtra token userResponse
}
where
oauth2 =
OAuth2
{ oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint =
"https://orcid.org/oauth/authorize"
`withQuery` [scopeParam " " ["openid"]]
, oauth2TokenEndpoint = "https://orcid.org/oauth/token"
, oauth2RedirectUri = Nothing
}

View File

@ -30,7 +30,12 @@ module Yesod.Auth.OAuth2.Prelude
-- * OAuth2 -- * OAuth2
, OAuth2 (..) , OAuth2 (..)
, OAuth2Token (..) , TokenResponse
, accessToken
, refreshToken
, expiresIn
, tokenType
, idToken
, AccessToken (..) , AccessToken (..)
, RefreshToken (..) , RefreshToken (..)
@ -78,7 +83,7 @@ authGetProfile
:: FromJSON a :: FromJSON a
=> Text => Text
-> Manager -> Manager
-> OAuth2Token -> TokenResponse
-> URI -> URI
-> IO (a, BL.ByteString) -> IO (a, BL.ByteString)
authGetProfile name manager token url = do authGetProfile name manager token url = do
@ -114,7 +119,7 @@ scopeParam d = ("scope",) . encodeUtf8 . T.intercalate d
-- May set the following keys: -- May set the following keys:
-- --
-- - @refreshToken@: if the provider supports refreshing the @accessToken@ -- - @refreshToken@: if the provider supports refreshing the @accessToken@
setExtra :: OAuth2Token -> BL.ByteString -> [(Text, Text)] setExtra :: TokenResponse -> BL.ByteString -> [(Text, Text)]
setExtra token userResponse = setExtra token userResponse =
[ ("accessToken", atoken $ accessToken token) [ ("accessToken", atoken $ accessToken token)
, ("userResponse", decodeUtf8 $ BL.toStrict userResponse) , ("userResponse", decodeUtf8 $ BL.toStrict userResponse)

View File

@ -76,7 +76,7 @@ salesforceHelper name profileUri authorizeUri tokenUri scopes clientId clientSec
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes] , oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = tokenUri , oauth2TokenEndpoint = tokenUri
, oauth2RedirectUri = Nothing , oauth2RedirectUri = Nothing

View File

@ -74,7 +74,7 @@ oauth2SlackScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://slack.com/oauth/authorize" "https://slack.com/oauth/authorize"
`withQuery` [scopeParam "," $ map scopeText scopes] `withQuery` [scopeParam "," $ map scopeText scopes]

View File

@ -37,7 +37,7 @@ oauth2Spotify scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://accounts.spotify.com/authorize" "https://accounts.spotify.com/authorize"
`withQuery` [scopeParam " " scopes] `withQuery` [scopeParam " " scopes]

View File

@ -49,7 +49,7 @@ oauth2TwitchScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://id.twitch.tv/oauth2/authorize" "https://id.twitch.tv/oauth2/authorize"
`withQuery` [scopeParam " " scopes] `withQuery` [scopeParam " " scopes]

View File

@ -44,7 +44,7 @@ oauth2Upcase clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = "http://upcase.com/oauth/authorize" , oauth2AuthorizeEndpoint = "http://upcase.com/oauth/authorize"
, oauth2TokenEndpoint = "http://upcase.com/oauth/token" , oauth2TokenEndpoint = "http://upcase.com/oauth/token"
, oauth2RedirectUri = Nothing , oauth2RedirectUri = Nothing

View File

@ -41,7 +41,7 @@ oauth2WordPressDotCom clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret , oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://public-api.wordpress.com/oauth2/authorize" "https://public-api.wordpress.com/oauth2/authorize"
`withQuery` [scopeParam "," ["auth"]] `withQuery` [scopeParam "," ["auth"]]

View File

@ -1,3 +0,0 @@
resolver: lts-18.28
extra-deps:
- hoauth2-2.0.0

View File

@ -1,19 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.0.0@sha256:4686d776272d4c57d3c8dbeb9e58b04afe4d2b410382011bd78a3d2bfb08a3fe,5662
pantry-tree:
sha256: 291b3dd90854ef44f270519ec17e34b6778f8430f6d6517bd67b0128bd549553
size: 2171
original:
hackage: hoauth2-2.0.0
snapshots:
- completed:
sha256: 428ec8d5ce932190d3cbe266b9eb3c175cd81e984babf876b64019e2cbe4ea68
size: 590100
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml
original: lts-18.28

View File

@ -1,3 +0,0 @@
resolver: nightly-2022-02-25
extra-deps:
- hoauth2-2.2.0

View File

@ -1,19 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.2.0@sha256:83a96156717d9e2c93394b35bef4151f82b90dc88b83d0e35c0bf1158bd41c6c,2801
pantry-tree:
sha256: d6e2d12e0e66eb9392301ec97d50677afb71608568f3664eb466a4451c66ba59
size: 593
original:
hackage: hoauth2-2.2.0
snapshots:
- completed:
sha256: b18614ab8986a4ba6d469921a2c18decab244af78309effa3d2dab85dbdfef80
size: 611886
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/2/25.yaml
original: nightly-2022-02-25

View File

@ -1,3 +0,0 @@
resolver: nightly-2022-02-25
extra-deps:
- hoauth2-2.3.0

View File

@ -1,19 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.3.0@sha256:213744356007a4686ff3bb72105843d478bc0ba6229659429cbe241a99f55095,2816
pantry-tree:
sha256: e559c811165a2e75cfe649b68396466b3bd0b6a5353a9d6476605e6a40e0eb37
size: 594
original:
hackage: hoauth2-2.3.0
snapshots:
- completed:
sha256: b18614ab8986a4ba6d469921a2c18decab244af78309effa3d2dab85dbdfef80
size: 611886
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/2/25.yaml
original: nightly-2022-02-25

View File

@ -1,11 +0,0 @@
resolver: nightly-2022-12-09
extra-deps:
- hoauth2-2.6.0
allow-newer: true
allow-newer-deps:
- hoauth2 # specifying the package itself is not necessary in the newest
# stack, and in fact doens't make conceptual sense. But it is
# required on the version of stack on GHA or you get a warning about
# ignoreing the bounds (as desired) but it still fails on them...
- memory
- text

View File

@ -1,19 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.6.0@sha256:168321df73bf75dc7cdda8e72725e9f3f624a9776b1fe59ae46c29c45029dc5d,2262
pantry-tree:
sha256: 5d39759b171cfaaf5842069a5548c2c1a41c0978645d018da7df713a186192b5
size: 859
original:
hackage: hoauth2-2.6.0
snapshots:
- completed:
sha256: b77e2c2b7988ed34cd317c01eb1958a8b8c234c3cc17e44077616c212959bed0
size: 558756
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/12/9.yaml
original: nightly-2022-12-09

View File

@ -1,3 +0,0 @@
resolver: lts-14.27
extra-deps:
- hoauth2-1.14.0

View File

@ -1,19 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-1.14.0@sha256:fcb4284fc78950c91d5b548317c51bd99a5ced84f4bb9e6153624b5783e4215f,5628
pantry-tree:
sha256: f25e2c2c101312196159dad5a3e2a4c8f549ed2d036d9566b66786d758db7dba
size: 2046
original:
hackage: hoauth2-1.14.0
snapshots:
- completed:
sha256: 7ea31a280c56bf36ff591a7397cc384d0dff622e7f9e4225b47d8980f019a0f0
size: 524996
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/14/27.yaml
original: lts-14.27

View File

@ -1 +0,0 @@
resolver: lts-16.31

View File

@ -1,12 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 637fb77049b25560622a224845b7acfe81a09fdb6a96a3c75997a10b651667f6
size: 534126
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/31.yaml
original: lts-16.31

View File

@ -1 +0,0 @@
resolver: lts-18.28

View File

@ -1,12 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 428ec8d5ce932190d3cbe266b9eb3c175cd81e984babf876b64019e2cbe4ea68
size: 590100
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml
original: lts-18.28

View File

@ -1 +0,0 @@
resolver: lts-19.33

View File

@ -1,12 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4
size: 619204
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml
original: lts-19.33

View File

@ -1 +0,0 @@
resolver: lts-20.26

View File

@ -1,12 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 5a59b2a405b3aba3c00188453be172b85893cab8ebc352b1ef58b0eae5d248a2
size: 650475
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/26.yaml
original: lts-20.26

View File

@ -1,12 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: a81fb3877c4f9031e1325eb3935122e608d80715dc16b586eb11ddbff8671ecd
size: 640086
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/25.yaml
original: lts-21.25

1
stack-lts22.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-22.44

1
stack-lts23.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-23.28

1
stack-lts24.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-24.26

View File

@ -1,12 +1,4 @@
resolver: nightly-2024-02-27 resolver: nightly-2026-01-05
extra-deps: extra-deps:
- yesod-auth-1.6.11.2 - cryptonite-0.30
- yesod-auth-1.6.11.3
# For yesod-auth
- email-validate-2.3.2.19
- yesod-form-1.7.6
- yesod-1.6.2.1
allow-newer: true
allow-newer-deps:
- email-validate

View File

@ -1,40 +0,0 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: yesod-auth-1.6.11.2@sha256:c580afaccc311ad90fc8a90210b5cf998d95350ddffb622e45282d9b640cf519,3108
pantry-tree:
sha256: 58e36ca675fc01109915342d4df9cb2680fd37ff20919d84694cdd1d52eb7dc3
size: 1013
original:
hackage: yesod-auth-1.6.11.2
- completed:
hackage: email-validate-2.3.2.19@sha256:206a835fe99a79f2360c576e3594d8add82d2f1e001d58b49a60f60233da2bf5,1380
pantry-tree:
sha256: 391475ca7c84d59b1d8de362856acd2f56321d29d54ffcd05ed2a170d4e62692
size: 419
original:
hackage: email-validate-2.3.2.19
- completed:
hackage: yesod-form-1.7.6@sha256:42219f2c4feaa2de32280c0b8f98db818f993152693a79960808fd3001a4c0e2,3434
pantry-tree:
sha256: 8a48fc861796a61cf6abd2087fedd86844ba5c3e11c89c74d2d04c4656d69997
size: 1797
original:
hackage: yesod-form-1.7.6
- completed:
hackage: yesod-1.6.2.1@sha256:504bc888257dae9bb40f4cd1e1110c4e80dfe7b867e8e207b22c4ca4dbd87f9a,2030
pantry-tree:
sha256: 5a78fa0c6e7dcb46c9acd687ab9409c8fcda0d59b930e2a93e5dc44128c740ec
size: 618
original:
hackage: yesod-1.6.2.1
snapshots:
- completed:
sha256: e596f5467d31095fd7b9f750e82aeffe012e38e795c13e1cdc945c9cab928085
size: 604415
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2024/2/27.yaml
original: nightly-2024-02-27

View File

@ -1 +0,0 @@
resolver: lts-22.12

1
stack.yaml Symbolic link
View File

@ -0,0 +1 @@
stack-lts24.yaml

View File

@ -1,12 +1,12 @@
# This file was autogenerated by Stack. # This file was autogenerated by Stack.
# You should not edit this file by hand. # You should not edit this file by hand.
# For more information, please see the documentation at: # For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files # https://docs.haskellstack.org/en/stable/topics/lock_files
packages: [] packages: []
snapshots: snapshots:
- completed: - completed:
sha256: e2c529ccfb21501f98f639e056cbde50470b86256d9849d7a82d414ca23e4276 sha256: d90eb1418667a225998b173817300e5ae2e1500ed03c0a9457cc2a0e78a0122a
size: 712898 size: 726337
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/12.yaml url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/24/26.yaml
original: lts-22.12 original: lts-24.26

View File

@ -1,13 +1,13 @@
cabal-version: 1.18 cabal-version: 1.18
-- This file has been generated from package.yaml by hpack version 0.36.0. -- This file has been generated from package.yaml by hpack version 0.38.1.
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
-- --
-- hash: 0bef4a9a180a48d0f0187fb359f4a27027166f3a0dd3827b76a6accb71753a27 -- hash: d595b9569ed34feddc8c41cf6f1f8cabbd8a37fa14b6afeeb24ad651ca689011
name: yesod-auth-oauth2 name: yesod-auth-oauth2
version: 0.7.2.0 version: 0.8.0.0
synopsis: OAuth 2.0 authentication plugins synopsis: OAuth 2.0 authentication plugins
description: Library to authenticate with OAuth 2.0 for Yesod web applications. description: Library to authenticate with OAuth 2.0 for Yesod web applications.
category: Web category: Web
@ -54,6 +54,7 @@ library
Yesod.Auth.OAuth2.GitLab Yesod.Auth.OAuth2.GitLab
Yesod.Auth.OAuth2.Google Yesod.Auth.OAuth2.Google
Yesod.Auth.OAuth2.Nylas Yesod.Auth.OAuth2.Nylas
Yesod.Auth.OAuth2.ORCID
Yesod.Auth.OAuth2.Prelude Yesod.Auth.OAuth2.Prelude
Yesod.Auth.OAuth2.Random Yesod.Auth.OAuth2.Random
Yesod.Auth.OAuth2.Salesforce Yesod.Auth.OAuth2.Salesforce
@ -71,9 +72,9 @@ library
aeson >=0.6 aeson >=0.6
, base >=4.9.0.0 && <5 , base >=4.9.0.0 && <5
, bytestring >=0.9.1.4 , bytestring >=0.9.1.4
, cryptonite >=0.25 , crypton
, errors , errors
, hoauth2 >=1.11.0 , hoauth2 >=2.8.0
, http-client >=0.4.0 , http-client >=0.4.0
, http-conduit >=2.0 , http-conduit >=2.0
, http-types >=0.8 , http-types >=0.8