{-# LANGUAGE LambdaCase #-} module Main (main) where import Control.Applicative (optional, (<**>)) import Control.Exception (throwIO) import LnUrl.Authenticator ( AuthenticatorError (..), handleAuth, handleInit, handleList, handleLog, ) import qualified Options.Applicative as Opt import System.Clipboard (getClipboardString) import System.Environment (getEnv) data CliOptions = CliOptions { identityFile :: Maybe FilePath , command :: Command } deriving (Eq, Show) data Command = Init | Auth AuthOptions | Log LogOptions | List deriving (Eq, Show) newtype AuthOptions = AuthOptions {authOptionsURL :: Maybe String} deriving (Eq, Show) newtype LogOptions = LogOptions {logOptionsDomain :: String} deriving (Eq, Show) getOptions :: IO CliOptions getOptions = Opt.execParser $ Opt.info (opts <**> Opt.helper) desc where opts = CliOptions <$> optional optIdentFile <*> optCommand optIdentFile = Opt.strOption $ Opt.long "file" <> Opt.short 'f' <> Opt.help ( "File in which to store identity (default: ~" <> defaultIdentFilePath <> ")" ) optCommand = Opt.hsubparser $ Opt.command "init" cmdInit <> Opt.command "auth" cmdRun <> Opt.command "log" cmdLog <> Opt.command "list" cmdList cmdInit = Opt.info (pure Init) descInit descInit = Opt.progDesc "Initialize a new identity" cmdRun = Opt.info optsRun descRun descRun = Opt.progDesc "Identify to a service using LNURL-auth" optsRun = fmap Auth $ AuthOptions <$> optional optURL optURL = Opt.strOption $ Opt.long "url" <> Opt.help "Service URL (default is to take the URL from the clipboard)" cmdLog = Opt.info optsLog descLog descLog = Opt.progDesc "Print an activity log for a domain" optsLog = fmap Log $ LogOptions <$> optDomain optDomain = Opt.strArgument $ Opt.metavar "DOMAIN" cmdList = Opt.info (pure List) descList descList = Opt.progDesc "List all domains with which we have interacted" desc = Opt.progDesc "LNURL-auth helper" defaultIdentFile :: IO FilePath defaultIdentFile = identFile <$> getEnv "HOME" where identFile = (<> defaultIdentFilePath) defaultIdentFilePath :: FilePath defaultIdentFilePath = "/.lnurl-auth/default.auth" getIdentFile :: CliOptions -> IO FilePath getIdentFile = maybe defaultIdentFile pure . identityFile main :: IO () main = do options <- getOptions identFile <- getIdentFile options case command options of Init -> handleInit identFile Auth theOpts -> maybe getUrlFromClipboard pure (authOptionsURL theOpts) >>= handleAuth identFile Log theOpts -> handleLog identFile $ logOptionsDomain theOpts List -> handleList identFile where getUrlFromClipboard = getClipboardString >>= maybe noURL pure noURL = throwIO NoUrl