never executed always true always false
    1 module PureClaw.Security.Secrets
    2   ( -- * Secret types (constructors intentionally NOT exported)
    3     ApiKey
    4   , BearerToken
    5   , PairingCode
    6   , SecretKey
    7     -- * Smart constructors
    8   , mkApiKey
    9   , mkBearerToken
   10   , mkPairingCode
   11   , mkSecretKey
   12     -- * CPS-style accessors (prevents secret from escaping via binding)
   13   , withApiKey
   14   , withBearerToken
   15   , withPairingCode
   16   , withSecretKey
   17   ) where
   18 
   19 import Data.ByteString (ByteString)
   20 import Data.Text (Text)
   21 
   22 -- | API key for provider authentication.
   23 -- Constructor unexported — use 'mkApiKey'.
   24 -- No ToJSON, FromJSON, or ToTOML instances — secrets cannot be serialized.
   25 newtype ApiKey = ApiKey { unApiKey :: ByteString }
   26 
   27 instance Show ApiKey where
   28   show _ = "ApiKey <redacted>"
   29 
   30 -- | Bearer token for authenticated requests.
   31 -- Constructor unexported — use 'mkBearerToken'.
   32 newtype BearerToken = BearerToken { unBearerToken :: ByteString }
   33 
   34 instance Show BearerToken where
   35   show _ = "BearerToken <redacted>"
   36 
   37 -- | Pairing code for device/client pairing.
   38 -- Constructor unexported — use 'mkPairingCode'.
   39 newtype PairingCode = PairingCode { unPairingCode :: Text }
   40 
   41 instance Show PairingCode where
   42   show _ = "PairingCode <redacted>"
   43 
   44 -- | Secret key for encryption operations.
   45 -- Constructor unexported — use 'mkSecretKey'.
   46 newtype SecretKey = SecretKey { unSecretKey :: ByteString }
   47 
   48 instance Show SecretKey where
   49   show _ = "SecretKey <redacted>"
   50 
   51 -- Smart constructors
   52 
   53 mkApiKey :: ByteString -> ApiKey
   54 mkApiKey = ApiKey
   55 
   56 mkBearerToken :: ByteString -> BearerToken
   57 mkBearerToken = BearerToken
   58 
   59 mkPairingCode :: Text -> PairingCode
   60 mkPairingCode = PairingCode
   61 
   62 mkSecretKey :: ByteString -> SecretKey
   63 mkSecretKey = SecretKey
   64 
   65 -- CPS-style accessors — the continuation receives the secret but cannot
   66 -- store it without explicitly choosing to. This is safer than a direct
   67 -- unwrap function because the secret's scope is limited to the continuation.
   68 
   69 withApiKey :: ApiKey -> (ByteString -> r) -> r
   70 withApiKey k f = f (unApiKey k)
   71 
   72 withBearerToken :: BearerToken -> (ByteString -> r) -> r
   73 withBearerToken t f = f (unBearerToken t)
   74 
   75 withPairingCode :: PairingCode -> (Text -> r) -> r
   76 withPairingCode p f = f (unPairingCode p)
   77 
   78 withSecretKey :: SecretKey -> (ByteString -> r) -> r
   79 withSecretKey k f = f (unSecretKey k)