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)