module Servant.Server.Auth.Token.Restore(
getRestoreCode
, guardRestoreCode
, sendRestoreCode
) where
import Control.Monad
import Control.Monad.IO.Class
import Data.Aeson.WithField
import Data.Time.Clock
import Servant.API.Auth.Token
import Servant.Server.Auth.Token.Config
import Servant.Server.Auth.Token.Model
import Servant.Server.Auth.Token.Monad
getRestoreCode :: HasStorage m => IO RestoreCode -> UserImplId -> UTCTime -> m RestoreCode
getRestoreCode generator uid expire = do
t <- liftIO getCurrentTime
mcode <- selectLastRestoreCode uid t
case mcode of
Nothing -> do
code <- liftIO generator
void $ insertUserRestore UserRestore {
userRestoreValue = code
, userRestoreUser = uid
, userRestoreExpire = expire
}
return code
Just code -> return $ userRestoreValue . (\(WithField _ v) -> v) $ code
guardRestoreCode :: AuthHandler m => UserImplId -> RestoreCode -> m ()
guardRestoreCode uid code = do
t <- liftIO getCurrentTime
mcode <- findRestoreCode uid code t
case mcode of
Nothing -> throw400 "Invalid restore code"
Just (WithField i rc) -> replaceRestoreCode i rc { userRestoreExpire = t }
sendRestoreCode :: AuthHandler m => RespUserInfo -> RestoreCode -> m ()
sendRestoreCode user code = do
AuthConfig{..} <- getConfig
liftIO $ restoreCodeSender user code