The async-refresh-tokens package

[Tags:bsd3, library, test]

This package can be used for renewal of expiring access tokens according to user-provided actions. Tokens will be stored in a transactional variable (TVar).

[Skip to Readme]


Versions 0.1.0
Dependencies async-refresh, base (>=4.7 && <5), bytestring, formatting, lens, lifted-async, monad-control, monad-logger, safe-exceptions, stm, text [details]
License BSD3
Copyright (c) 2017 Moritz Schulte
Author Moritz Schulte
Category Control
Home page
Source repository head: git clone
Uploaded Tue Apr 11 14:36:04 UTC 2017 by mtesseract
Distributions LTSHaskell:0.1.0, NixOS:0.1.0, Stackage:0.1.0, Tumbleweed:0.1.0
Downloads 62 total (6 in the last 30 days)
0 []
Status Docs not available [build log]
All reported builds failed as of 2017-04-11 [all 2 reports]
Hackage Matrix CI


  • Control
    • Concurrent
      • Async
        • Refresh
          • Control.Concurrent.Async.Refresh.Tokens


Maintainer's Corner

For package maintainers and hackage trustees

Readme for async-refresh-tokens

Readme for async-refresh-tokens-0.1.0



This is Haskell library built on top of the async-refresh package implementing the logic for refreshing of expiring access tokens.


  • Create new token types. Using the DataKinds extension we can do this via data MyAppTokens = TokenFoo | TokenBar.

  • Make the tokens be instances of the IsToken type classes by defining the tokenScopes method and (optionally) tokenName (a human readable label for this token).

  • Create new token stores (which are basically TVar's containing the tokens wrapped inEither SomeException) usingnewEmptyTokenStore`.

  • Create a new configuration by adjusting defaultTokenConf using the functions tokenConfAddRequest and tokenConfSetFactor. The function tokenConfAddRequest expects values of type RequestToken — these values encapsulate the token stores together with a token-refreshing action.

  • Use newTokenRefresher to initiate token refreshing for each registered token refreshing request.


{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE PolyKinds           #-}

data MyAppTokens = TokenFoo | TokenBar

instance IsToken 'TokenFoo where
  tokenScopes _ = ["", "foo.write"]

createTokenStoreFoo :: IO (TokenStore 'TokenFoo)
createTokenStoreFoo = runStderrLoggingT $ do
  tokenFoo <- newEmptyTokenStore (Proxy :: Proxy 'TokenFoo)
  let conf = defaultTokenConf
             & tokenConfAddRequest (RequestToken tokenFoo actionFoo)
  _ <- newTokenRefresher conf
  return tokenFoo

  where actionFoo :: (MonadIO m, IsToken t) => m (RefreshResult (Token t))
        actionFoo =
          return $ RefreshResult (Token "secret-foo-token") Nothing