packages feed

signet 0.2025.5.9 → 0.2025.5.12

raw patch · 140 files changed

+1988/−2005 lines, 140 filesdep ~tastyPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependency ranges changed: tasty

API changes (from Hackage documentation)

+ Signet.Unstable: parseId :: ByteString -> Either InvalidId Id
+ Signet.Unstable: parseMessage :: ByteString -> Either InvalidMessage Message
+ Signet.Unstable: parseSignatures :: ByteString -> Either InvalidSignature ([UnknownSignature], Signatures)
+ Signet.Unstable: parseSigner :: ByteString -> Either InvalidSigner Signer
+ Signet.Unstable: parseTimestamp :: ByteString -> Either InvalidTimestamp Timestamp
+ Signet.Unstable: parseVerifier :: ByteString -> Either InvalidVerifier Verifier
+ Signet.Unstable: pattern AsymmetricSignature :: AsymmetricSignature -> Signature
+ Signet.Unstable: pattern AsymmetricSigner :: SecretKey -> Signer
+ Signet.Unstable: pattern AsymmetricVerifier :: PublicKey -> Verifier
+ Signet.Unstable: pattern SymmetricSignature :: SymmetricSignature -> Signature
+ Signet.Unstable: pattern SymmetricSigner :: Secret -> Signer
+ Signet.Unstable: pattern SymmetricVerifier :: Secret -> Verifier
+ Signet.Unstable: signWebhook :: Signer -> Message -> Signature
+ Signet.Unstable: typicalTolerance :: Tolerance
+ Signet.Unstable: verifyWebhook :: (MonadIO m, MonadThrow m) => Verifier -> Message -> Signatures -> m Signature
+ Signet.Unstable: verifyWebhookByteString :: (MonadIO m, MonadThrow m) => ByteString -> ByteString -> ByteString -> ByteString -> ByteString -> m Signature
+ Signet.Unstable: verifyWebhookText :: (MonadIO m, MonadThrow m) => Text -> Text -> Text -> Text -> Text -> m Signature
+ Signet.Unstable: verifyWebhookWith :: Tolerance -> UTCTime -> Verifier -> Message -> Signatures -> Either SignetException Signature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: MkInvalidAsymmetricSignature :: ByteString -> InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: instance GHC.Show.Show Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: newtype InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: unwrap :: InvalidAsymmetricSignature -> ByteString
+ Signet.Unstable.Exception.InvalidAsymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidId: MkInvalidId :: ByteString -> InvalidId
+ Signet.Unstable.Exception.InvalidId: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidId.InvalidId
+ Signet.Unstable.Exception.InvalidId: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidId.InvalidId
+ Signet.Unstable.Exception.InvalidId: instance GHC.Show.Show Signet.Unstable.Exception.InvalidId.InvalidId
+ Signet.Unstable.Exception.InvalidId: newtype InvalidId
+ Signet.Unstable.Exception.InvalidId: unwrap :: InvalidId -> ByteString
+ Signet.Unstable.Exception.InvalidIdTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidMessage: InvalidId :: InvalidId -> InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: InvalidTimestamp :: InvalidTimestamp -> InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: data InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidMessage.InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidMessage.InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: instance GHC.Show.Show Signet.Unstable.Exception.InvalidMessage.InvalidMessage
+ Signet.Unstable.Exception.InvalidMessageTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidPublicKey: MkInvalidPublicKey :: ByteString -> InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: instance GHC.Show.Show Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: newtype InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: unwrap :: InvalidPublicKey -> ByteString
+ Signet.Unstable.Exception.InvalidPublicKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSecret: MkInvalidSecret :: ByteString -> InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSecret.InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSecret.InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSecret.InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: newtype InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: unwrap :: InvalidSecret -> ByteString
+ Signet.Unstable.Exception.InvalidSecretKey: MkInvalidSecretKey :: ByteString -> InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: newtype InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: unwrap :: InvalidSecretKey -> ByteString
+ Signet.Unstable.Exception.InvalidSecretKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSecretTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSignature: InvalidAsymmetricSignature :: InvalidAsymmetricSignature -> InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: InvalidSymmetricSignature :: InvalidSymmetricSignature -> InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: data InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSignature.InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSignature.InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSignature.InvalidSignature
+ Signet.Unstable.Exception.InvalidSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSigner: MkInvalidSigner :: ByteString -> InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSigner.InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSigner.InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSigner.InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: newtype InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: unwrap :: InvalidSigner -> ByteString
+ Signet.Unstable.Exception.InvalidSignerTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSymmetricSignature: MkInvalidSymmetricSignature :: ByteString -> InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: newtype InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: unwrap :: InvalidSymmetricSignature -> ByteString
+ Signet.Unstable.Exception.InvalidSymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidTimestamp: MkInvalidTimestamp :: ByteString -> InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: instance GHC.Show.Show Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: newtype InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: unwrap :: InvalidTimestamp -> ByteString
+ Signet.Unstable.Exception.InvalidTimestampTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidVerifier: MkInvalidVerifier :: ByteString -> InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: instance GHC.Show.Show Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: newtype InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: unwrap :: InvalidVerifier -> ByteString
+ Signet.Unstable.Exception.InvalidVerifierTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.SignetException: ToleranceException :: ToleranceException -> SignetException
+ Signet.Unstable.Exception.SignetException: VerificationException :: VerificationException -> SignetException
+ Signet.Unstable.Exception.SignetException: data SignetException
+ Signet.Unstable.Exception.SignetException: instance GHC.Classes.Eq Signet.Unstable.Exception.SignetException.SignetException
+ Signet.Unstable.Exception.SignetException: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.SignetException.SignetException
+ Signet.Unstable.Exception.SignetException: instance GHC.Show.Show Signet.Unstable.Exception.SignetException.SignetException
+ Signet.Unstable.Exception.SignetExceptionTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.ToleranceException: MkToleranceException :: Timestamp -> ToleranceException
+ Signet.Unstable.Exception.ToleranceException: instance GHC.Classes.Eq Signet.Unstable.Exception.ToleranceException.ToleranceException
+ Signet.Unstable.Exception.ToleranceException: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.ToleranceException.ToleranceException
+ Signet.Unstable.Exception.ToleranceException: instance GHC.Show.Show Signet.Unstable.Exception.ToleranceException.ToleranceException
+ Signet.Unstable.Exception.ToleranceException: newtype ToleranceException
+ Signet.Unstable.Exception.ToleranceException: unwrap :: ToleranceException -> Timestamp
+ Signet.Unstable.Exception.ToleranceExceptionTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.VerificationException: MkVerificationException :: Id -> VerificationException
+ Signet.Unstable.Exception.VerificationException: instance GHC.Classes.Eq Signet.Unstable.Exception.VerificationException.VerificationException
+ Signet.Unstable.Exception.VerificationException: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.VerificationException.VerificationException
+ Signet.Unstable.Exception.VerificationException: instance GHC.Show.Show Signet.Unstable.Exception.VerificationException.VerificationException
+ Signet.Unstable.Exception.VerificationException: newtype VerificationException
+ Signet.Unstable.Exception.VerificationException: unwrap :: VerificationException -> Id
+ Signet.Unstable.Exception.VerificationExceptionTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Extra.Either: hush :: Either x a -> Maybe a
+ Signet.Unstable.Extra.Either: throw :: (Exception e, MonadThrow m) => Either e a -> m a
+ Signet.Unstable.Extra.EitherTest: MkTestException :: TestException
+ Signet.Unstable.Extra.EitherTest: data TestException
+ Signet.Unstable.Extra.EitherTest: instance GHC.Classes.Eq Signet.Unstable.Extra.EitherTest.TestException
+ Signet.Unstable.Extra.EitherTest: instance GHC.Exception.Type.Exception Signet.Unstable.Extra.EitherTest.TestException
+ Signet.Unstable.Extra.EitherTest: instance GHC.Show.Show Signet.Unstable.Extra.EitherTest.TestException
+ Signet.Unstable.Extra.EitherTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Extra.Http: hWebhookId :: HeaderName
+ Signet.Unstable.Extra.Http: hWebhookSignature :: HeaderName
+ Signet.Unstable.Extra.Http: hWebhookTimestamp :: HeaderName
+ Signet.Unstable.Extra.HttpTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Extra.Maybe: note :: e -> Maybe a -> Either e a
+ Signet.Unstable.Extra.MaybeTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.AsymmetricSignature: MkAsymmetricSignature :: Signature -> AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: instance GHC.Show.Show Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: newtype AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: parse :: ByteString -> Either InvalidAsymmetricSignature AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: render :: AsymmetricSignature -> ByteString
+ Signet.Unstable.Type.AsymmetricSignature: unwrap :: AsymmetricSignature -> Signature
+ Signet.Unstable.Type.AsymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Id: MkId :: ByteString -> Id
+ Signet.Unstable.Type.Id: instance GHC.Classes.Eq Signet.Unstable.Type.Id.Id
+ Signet.Unstable.Type.Id: instance GHC.Show.Show Signet.Unstable.Type.Id.Id
+ Signet.Unstable.Type.Id: newtype Id
+ Signet.Unstable.Type.Id: parse :: ByteString -> Either InvalidId Id
+ Signet.Unstable.Type.Id: render :: Id -> ByteString
+ Signet.Unstable.Type.Id: separator :: Word8
+ Signet.Unstable.Type.Id: unwrap :: Id -> ByteString
+ Signet.Unstable.Type.IdTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Message: MkMessage :: Id -> Timestamp -> Payload -> Message
+ Signet.Unstable.Type.Message: [id_] :: Message -> Id
+ Signet.Unstable.Type.Message: [payload] :: Message -> Payload
+ Signet.Unstable.Type.Message: [timestamp] :: Message -> Timestamp
+ Signet.Unstable.Type.Message: data Message
+ Signet.Unstable.Type.Message: instance GHC.Classes.Eq Signet.Unstable.Type.Message.Message
+ Signet.Unstable.Type.Message: instance GHC.Show.Show Signet.Unstable.Type.Message.Message
+ Signet.Unstable.Type.Message: parse :: ByteString -> Either InvalidMessage Message
+ Signet.Unstable.Type.Message: render :: Message -> ByteString
+ Signet.Unstable.Type.MessageTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Payload: MkPayload :: ByteString -> Payload
+ Signet.Unstable.Type.Payload: instance GHC.Classes.Eq Signet.Unstable.Type.Payload.Payload
+ Signet.Unstable.Type.Payload: instance GHC.Show.Show Signet.Unstable.Type.Payload.Payload
+ Signet.Unstable.Type.Payload: newtype Payload
+ Signet.Unstable.Type.Payload: unwrap :: Payload -> ByteString
+ Signet.Unstable.Type.PayloadTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.PublicKey: MkPublicKey :: PublicKey -> PublicKey
+ Signet.Unstable.Type.PublicKey: instance GHC.Classes.Eq Signet.Unstable.Type.PublicKey.PublicKey
+ Signet.Unstable.Type.PublicKey: instance GHC.Show.Show Signet.Unstable.Type.PublicKey.PublicKey
+ Signet.Unstable.Type.PublicKey: newtype PublicKey
+ Signet.Unstable.Type.PublicKey: parse :: ByteString -> Either InvalidPublicKey PublicKey
+ Signet.Unstable.Type.PublicKey: prefix :: ByteString
+ Signet.Unstable.Type.PublicKey: render :: PublicKey -> ByteString
+ Signet.Unstable.Type.PublicKey: unwrap :: PublicKey -> PublicKey
+ Signet.Unstable.Type.PublicKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Secret: MkSecret :: ScrubbedBytes -> Secret
+ Signet.Unstable.Type.Secret: instance GHC.Classes.Eq Signet.Unstable.Type.Secret.Secret
+ Signet.Unstable.Type.Secret: instance GHC.Show.Show Signet.Unstable.Type.Secret.Secret
+ Signet.Unstable.Type.Secret: newtype Secret
+ Signet.Unstable.Type.Secret: parse :: ByteString -> Either InvalidSecret Secret
+ Signet.Unstable.Type.Secret: prefix :: ByteString
+ Signet.Unstable.Type.Secret: render :: Secret -> ByteString
+ Signet.Unstable.Type.Secret: unwrap :: Secret -> ScrubbedBytes
+ Signet.Unstable.Type.SecretKey: MkSecretKey :: SecretKey -> SecretKey
+ Signet.Unstable.Type.SecretKey: instance GHC.Classes.Eq Signet.Unstable.Type.SecretKey.SecretKey
+ Signet.Unstable.Type.SecretKey: instance GHC.Show.Show Signet.Unstable.Type.SecretKey.SecretKey
+ Signet.Unstable.Type.SecretKey: newtype SecretKey
+ Signet.Unstable.Type.SecretKey: parse :: ByteString -> Either InvalidSecretKey SecretKey
+ Signet.Unstable.Type.SecretKey: prefix :: ByteString
+ Signet.Unstable.Type.SecretKey: render :: SecretKey -> ByteString
+ Signet.Unstable.Type.SecretKey: unwrap :: SecretKey -> SecretKey
+ Signet.Unstable.Type.SecretKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.SecretTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Signature: Asymmetric :: AsymmetricSignature -> Signature
+ Signet.Unstable.Type.Signature: Symmetric :: SymmetricSignature -> Signature
+ Signet.Unstable.Type.Signature: asymmetricPrefix :: ByteString
+ Signet.Unstable.Type.Signature: data Signature
+ Signet.Unstable.Type.Signature: instance GHC.Classes.Eq Signet.Unstable.Type.Signature.Signature
+ Signet.Unstable.Type.Signature: instance GHC.Show.Show Signet.Unstable.Type.Signature.Signature
+ Signet.Unstable.Type.Signature: parse :: ByteString -> Either InvalidSignature (Either UnknownSignature Signature)
+ Signet.Unstable.Type.Signature: render :: Signature -> ByteString
+ Signet.Unstable.Type.Signature: separator :: Word8
+ Signet.Unstable.Type.Signature: symmetricPrefix :: ByteString
+ Signet.Unstable.Type.SignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Signatures: MkSignatures :: [Signature] -> Signatures
+ Signet.Unstable.Type.Signatures: instance GHC.Classes.Eq Signet.Unstable.Type.Signatures.Signatures
+ Signet.Unstable.Type.Signatures: instance GHC.Show.Show Signet.Unstable.Type.Signatures.Signatures
+ Signet.Unstable.Type.Signatures: newtype Signatures
+ Signet.Unstable.Type.Signatures: parse :: ByteString -> Either InvalidSignature ([UnknownSignature], Signatures)
+ Signet.Unstable.Type.Signatures: render :: Signatures -> ByteString
+ Signet.Unstable.Type.Signatures: separator :: Word8
+ Signet.Unstable.Type.Signatures: unwrap :: Signatures -> [Signature]
+ Signet.Unstable.Type.SignaturesTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Signer: Asymmetric :: SecretKey -> Signer
+ Signet.Unstable.Type.Signer: Symmetric :: Secret -> Signer
+ Signet.Unstable.Type.Signer: asymmetric :: SecretKey -> Message -> AsymmetricSignature
+ Signet.Unstable.Type.Signer: data Signer
+ Signet.Unstable.Type.Signer: instance GHC.Classes.Eq Signet.Unstable.Type.Signer.Signer
+ Signet.Unstable.Type.Signer: instance GHC.Show.Show Signet.Unstable.Type.Signer.Signer
+ Signet.Unstable.Type.Signer: parse :: ByteString -> Either InvalidSigner Signer
+ Signet.Unstable.Type.Signer: render :: Signer -> ByteString
+ Signet.Unstable.Type.Signer: sign :: Signer -> Message -> Signature
+ Signet.Unstable.Type.Signer: symmetric :: Secret -> Message -> SymmetricSignature
+ Signet.Unstable.Type.SignerTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.SymmetricSignature: MkSymmetricSignature :: Digest SHA256 -> SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Type.SymmetricSignature.SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: instance GHC.Show.Show Signet.Unstable.Type.SymmetricSignature.SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: newtype SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: parse :: ByteString -> Either InvalidSymmetricSignature SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: render :: SymmetricSignature -> ByteString
+ Signet.Unstable.Type.SymmetricSignature: unwrap :: SymmetricSignature -> Digest SHA256
+ Signet.Unstable.Type.SymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Test: MkTest :: (HasCallStack => String -> IO Void) -> (String -> spec () -> spec ()) -> (String -> IO () -> spec ()) -> Test (spec :: Type -> Type)
+ Signet.Unstable.Type.Test: [assertFailure] :: Test (spec :: Type -> Type) -> HasCallStack => String -> IO Void
+ Signet.Unstable.Type.Test: [describe] :: Test (spec :: Type -> Type) -> String -> spec () -> spec ()
+ Signet.Unstable.Type.Test: [it] :: Test (spec :: Type -> Type) -> String -> IO () -> spec ()
+ Signet.Unstable.Type.Test: assertEq :: forall a (tree :: Type -> Type). (HasCallStack, Eq a, Show a) => Test tree -> a -> a -> IO ()
+ Signet.Unstable.Type.Test: data Test (spec :: Type -> Type)
+ Signet.Unstable.Type.Timestamp: MkTimestamp :: UTCTime -> Timestamp
+ Signet.Unstable.Type.Timestamp: format :: String
+ Signet.Unstable.Type.Timestamp: instance GHC.Classes.Eq Signet.Unstable.Type.Timestamp.Timestamp
+ Signet.Unstable.Type.Timestamp: instance GHC.Show.Show Signet.Unstable.Type.Timestamp.Timestamp
+ Signet.Unstable.Type.Timestamp: newtype Timestamp
+ Signet.Unstable.Type.Timestamp: parse :: ByteString -> Either InvalidTimestamp Timestamp
+ Signet.Unstable.Type.Timestamp: render :: Timestamp -> ByteString
+ Signet.Unstable.Type.Timestamp: unwrap :: Timestamp -> UTCTime
+ Signet.Unstable.Type.TimestampTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Tolerance: MkTolerance :: NominalDiffTime -> Tolerance
+ Signet.Unstable.Type.Tolerance: check :: Tolerance -> UTCTime -> Timestamp -> Either ToleranceException ()
+ Signet.Unstable.Type.Tolerance: instance GHC.Classes.Eq Signet.Unstable.Type.Tolerance.Tolerance
+ Signet.Unstable.Type.Tolerance: instance GHC.Show.Show Signet.Unstable.Type.Tolerance.Tolerance
+ Signet.Unstable.Type.Tolerance: newtype Tolerance
+ Signet.Unstable.Type.Tolerance: typical :: Tolerance
+ Signet.Unstable.Type.Tolerance: unwrap :: Tolerance -> NominalDiffTime
+ Signet.Unstable.Type.ToleranceTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.UnknownSignature: MkUnknownSignature :: ByteString -> UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: instance GHC.Classes.Eq Signet.Unstable.Type.UnknownSignature.UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: instance GHC.Show.Show Signet.Unstable.Type.UnknownSignature.UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: newtype UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: unwrap :: UnknownSignature -> ByteString
+ Signet.Unstable.Type.UnknownSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Verifier: Asymmetric :: PublicKey -> Verifier
+ Signet.Unstable.Type.Verifier: Symmetric :: Secret -> Verifier
+ Signet.Unstable.Type.Verifier: asymmetric :: PublicKey -> Message -> Signatures -> Either VerificationException AsymmetricSignature
+ Signet.Unstable.Type.Verifier: data Verifier
+ Signet.Unstable.Type.Verifier: instance GHC.Classes.Eq Signet.Unstable.Type.Verifier.Verifier
+ Signet.Unstable.Type.Verifier: instance GHC.Show.Show Signet.Unstable.Type.Verifier.Verifier
+ Signet.Unstable.Type.Verifier: parse :: ByteString -> Either InvalidVerifier Verifier
+ Signet.Unstable.Type.Verifier: render :: Verifier -> ByteString
+ Signet.Unstable.Type.Verifier: symmetric :: Secret -> Message -> Signatures -> Either VerificationException SymmetricSignature
+ Signet.Unstable.Type.Verifier: verify :: Verifier -> Message -> Signatures -> Either VerificationException Signature
+ Signet.Unstable.Type.VerifierTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.UnstableTest: spec :: Monad tree => Test tree -> tree ()
+ SignetTest: spec :: Monad tree => Test tree -> tree ()

Files

signet.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: signet-version: 0.2025.5.9+version: 0.2025.5.12 synopsis: Standard Webhooks description:   Signet is a Haskell library for working with Standard Webhooks.@@ -32,6 +32,7 @@     -Wno-missing-deriving-strategies     -Wno-missing-export-lists     -Wno-missing-kind-signatures+    -Wno-missing-role-annotations     -Wno-missing-safe-haskell-mode     -Wno-prepositive-qualified-module     -Wno-safe@@ -40,127 +41,103 @@   if flag(pedantic)     ghc-options: -Werror -common executable+library   import: library-  ghc-options:-    -rtsopts-    -threaded--common dependencies   build-depends:     bytestring ^>=0.12,     case-insensitive ^>=1.2.1.0,     crypton ^>=0.34 || ^>=1.0.4,     exceptions ^>=0.10.7,-    memory ^>=0.18.0,-    time ^>=1.12.2,--library unstable-  import: library, dependencies-  build-depends:     http-types ^>=0.12.4,+    memory ^>=0.18.0,     text ^>=2.0 || ^>=2.1,+    time ^>=1.12.2, -  -- cabal-gild: discover source/libraries/unstable+  -- cabal-gild: discover source/library   exposed-modules:+    Signet     Signet.Unstable     Signet.Unstable.Exception.InvalidAsymmetricSignature+    Signet.Unstable.Exception.InvalidAsymmetricSignatureTest     Signet.Unstable.Exception.InvalidId+    Signet.Unstable.Exception.InvalidIdTest     Signet.Unstable.Exception.InvalidMessage+    Signet.Unstable.Exception.InvalidMessageTest     Signet.Unstable.Exception.InvalidPublicKey+    Signet.Unstable.Exception.InvalidPublicKeyTest     Signet.Unstable.Exception.InvalidSecret     Signet.Unstable.Exception.InvalidSecretKey-    Signet.Unstable.Exception.InvalidSignature-    Signet.Unstable.Exception.InvalidSigner-    Signet.Unstable.Exception.InvalidSymmetricSignature-    Signet.Unstable.Exception.InvalidTimestamp-    Signet.Unstable.Exception.InvalidVerifier-    Signet.Unstable.Exception.SignetException-    Signet.Unstable.Exception.ToleranceException-    Signet.Unstable.Exception.VerificationException-    Signet.Unstable.Extra.Either-    Signet.Unstable.Extra.Http-    Signet.Unstable.Extra.Maybe-    Signet.Unstable.Type.AsymmetricSignature-    Signet.Unstable.Type.Id-    Signet.Unstable.Type.Message-    Signet.Unstable.Type.Payload-    Signet.Unstable.Type.PublicKey-    Signet.Unstable.Type.Secret-    Signet.Unstable.Type.SecretKey-    Signet.Unstable.Type.Signature-    Signet.Unstable.Type.Signatures-    Signet.Unstable.Type.Signer-    Signet.Unstable.Type.SymmetricSignature-    Signet.Unstable.Type.Timestamp-    Signet.Unstable.Type.Tolerance-    Signet.Unstable.Type.UnknownSignature-    Signet.Unstable.Type.Verifier--  hs-source-dirs: source/libraries/unstable-  visibility: public--library-  import: library-  build-depends: signet:unstable-  -- cabal-gild: discover source/libraries/signet-  exposed-modules: Signet-  hs-source-dirs: source/libraries/signet--library test-  import: library, dependencies-  build-depends:-    signet:unstable,-    tasty ^>=1.4 || ^>=1.5.3,-    tasty-hunit ^>=0.10.2,-    transformers ^>=0.6.1.0,--  -- cabal-gild: discover source/libraries/test-  exposed-modules:-    Signet.Unstable.Exception.InvalidAsymmetricSignatureTest-    Signet.Unstable.Exception.InvalidIdTest-    Signet.Unstable.Exception.InvalidMessageTest-    Signet.Unstable.Exception.InvalidPublicKeyTest     Signet.Unstable.Exception.InvalidSecretKeyTest     Signet.Unstable.Exception.InvalidSecretTest+    Signet.Unstable.Exception.InvalidSignature     Signet.Unstable.Exception.InvalidSignatureTest+    Signet.Unstable.Exception.InvalidSigner     Signet.Unstable.Exception.InvalidSignerTest+    Signet.Unstable.Exception.InvalidSymmetricSignature     Signet.Unstable.Exception.InvalidSymmetricSignatureTest+    Signet.Unstable.Exception.InvalidTimestamp     Signet.Unstable.Exception.InvalidTimestampTest+    Signet.Unstable.Exception.InvalidVerifier     Signet.Unstable.Exception.InvalidVerifierTest+    Signet.Unstable.Exception.SignetException     Signet.Unstable.Exception.SignetExceptionTest+    Signet.Unstable.Exception.ToleranceException     Signet.Unstable.Exception.ToleranceExceptionTest+    Signet.Unstable.Exception.VerificationException     Signet.Unstable.Exception.VerificationExceptionTest+    Signet.Unstable.Extra.Either     Signet.Unstable.Extra.EitherTest+    Signet.Unstable.Extra.Http     Signet.Unstable.Extra.HttpTest+    Signet.Unstable.Extra.Maybe     Signet.Unstable.Extra.MaybeTest-    Signet.Unstable.Extra.Tasty+    Signet.Unstable.Type.AsymmetricSignature     Signet.Unstable.Type.AsymmetricSignatureTest+    Signet.Unstable.Type.Id     Signet.Unstable.Type.IdTest+    Signet.Unstable.Type.Message     Signet.Unstable.Type.MessageTest+    Signet.Unstable.Type.Payload     Signet.Unstable.Type.PayloadTest+    Signet.Unstable.Type.PublicKey     Signet.Unstable.Type.PublicKeyTest+    Signet.Unstable.Type.Secret+    Signet.Unstable.Type.SecretKey     Signet.Unstable.Type.SecretKeyTest     Signet.Unstable.Type.SecretTest+    Signet.Unstable.Type.Signature     Signet.Unstable.Type.SignatureTest+    Signet.Unstable.Type.Signatures     Signet.Unstable.Type.SignaturesTest+    Signet.Unstable.Type.Signer     Signet.Unstable.Type.SignerTest+    Signet.Unstable.Type.SymmetricSignature     Signet.Unstable.Type.SymmetricSignatureTest+    Signet.Unstable.Type.Test+    Signet.Unstable.Type.Timestamp     Signet.Unstable.Type.TimestampTest+    Signet.Unstable.Type.Tolerance     Signet.Unstable.Type.ToleranceTest+    Signet.Unstable.Type.UnknownSignature     Signet.Unstable.Type.UnknownSignatureTest+    Signet.Unstable.Type.Verifier     Signet.Unstable.Type.VerifierTest     Signet.UnstableTest     SignetTest -  hs-source-dirs: source/libraries/test-  visibility: public+  hs-source-dirs: source/library  test-suite signet-test-suite-  import: executable+  import: library   build-depends:-    signet:test,-    tasty,+    signet,+    tasty ^>=1.4 || ^>=1.5.3,+    tasty-hunit ^>=0.10.2,+    transformers ^>=0.6.1.0,++  ghc-options:+    -rtsopts+    -threaded    hs-source-dirs: source/test-suite   main-is: Main.hs
− source/libraries/signet/Signet.hs
@@ -1,88 +0,0 @@-module Signet-  ( -- * Verification-    Signet.Unstable.verifyWebhookText,-    Signet.Unstable.verifyWebhookByteString,-    Signet.Unstable.verifyWebhook,-    Signet.Unstable.verifyWebhookWith,--    -- * Signing-    Signet.Unstable.signWebhook,--    -- * Headers-    Signet.Unstable.Extra.Http.hWebhookId,-    Signet.Unstable.Extra.Http.hWebhookTimestamp,-    Signet.Unstable.Extra.Http.hWebhookSignature,--    -- * Types-    Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature (..),-    Signet.Unstable.Type.Id.Id (..),-    Signet.Unstable.parseId,-    Signet.Unstable.Type.Message.Message (..),-    Signet.Unstable.parseMessage,-    Signet.Unstable.Type.Payload.Payload (..),-    Signet.Unstable.Type.PublicKey.PublicKey (..),-    Signet.Unstable.Type.Secret.Secret (..),-    Signet.Unstable.Type.SecretKey.SecretKey (..),-    Signet.Unstable.Type.Signature.Signature (Signet.Unstable.AsymmetricSignature, Signet.Unstable.SymmetricSignature),-    Signet.Unstable.Type.Signatures.Signatures (..),-    Signet.Unstable.parseSignatures,-    Signet.Unstable.Type.Signer.Signer (Signet.Unstable.AsymmetricSigner, Signet.Unstable.SymmetricSigner),-    Signet.Unstable.parseSigner,-    Signet.Unstable.Type.SymmetricSignature.SymmetricSignature (..),-    Signet.Unstable.Type.Timestamp.Timestamp (..),-    Signet.Unstable.parseTimestamp,-    Signet.Unstable.Type.Tolerance.Tolerance (..),-    Signet.Unstable.typicalTolerance,-    Signet.Unstable.Type.UnknownSignature.UnknownSignature (..),-    Signet.Unstable.Type.Verifier.Verifier (Signet.Unstable.AsymmetricVerifier, Signet.Unstable.SymmetricVerifier),-    Signet.Unstable.parseVerifier,--    -- * Exceptions-    Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature (..),-    Signet.Unstable.Exception.InvalidId.InvalidId (..),-    Signet.Unstable.Exception.InvalidMessage.InvalidMessage (..),-    Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey (..),-    Signet.Unstable.Exception.InvalidSecret.InvalidSecret (..),-    Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey (..),-    Signet.Unstable.Exception.InvalidSignature.InvalidSignature (..),-    Signet.Unstable.Exception.InvalidSigner.InvalidSigner (..),-    Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature (..),-    Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp (..),-    Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier (..),-    Signet.Unstable.Exception.SignetException.SignetException (..),-    Signet.Unstable.Exception.ToleranceException.ToleranceException (..),-    Signet.Unstable.Exception.VerificationException.VerificationException (..),-  )-where--import qualified Signet.Unstable-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidId-import qualified Signet.Unstable.Exception.InvalidMessage-import qualified Signet.Unstable.Exception.InvalidPublicKey-import qualified Signet.Unstable.Exception.InvalidSecret-import qualified Signet.Unstable.Exception.InvalidSecretKey-import qualified Signet.Unstable.Exception.InvalidSignature-import qualified Signet.Unstable.Exception.InvalidSigner-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature-import qualified Signet.Unstable.Exception.InvalidTimestamp-import qualified Signet.Unstable.Exception.InvalidVerifier-import qualified Signet.Unstable.Exception.SignetException-import qualified Signet.Unstable.Exception.ToleranceException-import qualified Signet.Unstable.Exception.VerificationException-import qualified Signet.Unstable.Extra.Http-import qualified Signet.Unstable.Type.AsymmetricSignature-import qualified Signet.Unstable.Type.Id-import qualified Signet.Unstable.Type.Message-import qualified Signet.Unstable.Type.Payload-import qualified Signet.Unstable.Type.PublicKey-import qualified Signet.Unstable.Type.Secret-import qualified Signet.Unstable.Type.SecretKey-import qualified Signet.Unstable.Type.Signature-import qualified Signet.Unstable.Type.Signatures-import qualified Signet.Unstable.Type.Signer-import qualified Signet.Unstable.Type.SymmetricSignature-import qualified Signet.Unstable.Type.Timestamp-import qualified Signet.Unstable.Type.Tolerance-import qualified Signet.Unstable.Type.UnknownSignature-import qualified Signet.Unstable.Type.Verifier
− source/libraries/test/Signet/Unstable/Exception/InvalidAsymmetricSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidAsymmetricSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidAsymmetricSignature" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidIdTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidIdTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidId" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidMessageTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidMessageTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidMessage" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidPublicKeyTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidPublicKeyTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidPublicKey" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSecretKeyTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSecretKeyTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSecretKey" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSecretTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSecretTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSecret" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSignature" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSignerTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSignerTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSigner" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSymmetricSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSymmetricSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSymmetricSignature" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidTimestampTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidTimestampTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidTimestamp" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidVerifierTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidVerifierTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidVerifier" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/SignetExceptionTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.SignetExceptionTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.SignetException" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/ToleranceExceptionTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.ToleranceExceptionTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.ToleranceException" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Exception/VerificationExceptionTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.VerificationExceptionTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.VerificationException" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Extra/EitherTest.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Extra.EitherTest where--import qualified Control.Monad.Catch as Exception-import qualified Data.Void as Void-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Extra.Either" $ do-  Tasty.describe "hush" $ do-    Tasty.it "works with Left" $ do-      Either.hush (Left () :: Either () Void.Void) @?= Nothing--    Tasty.it "works with Right" $ do-      Either.hush (Right () :: Either Void.Void ()) @?= Just ()--  Tasty.describe "throw" $ do-    Tasty.it "throws an exception for Left" $ do-      result <- Exception.try . Either.throw $ Left MkTestException-      result @?= (Left MkTestException :: Either TestException Void.Void)--    Tasty.it "returns the value for Right" $ do-      value <- Either.throw (Right () :: Either Void.Void ())-      value @?= ()--data TestException-  = MkTestException-  deriving (Eq, Show)--instance Exception.Exception TestException
− source/libraries/test/Signet/Unstable/Extra/HttpTest.hs
@@ -1,21 +0,0 @@-module Signet.Unstable.Extra.HttpTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.CaseInsensitive as CI-import qualified Signet.Unstable.Extra.Http as Http-import qualified Signet.Unstable.Extra.Tasty as Tasty-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Extra.Http" $ do-  Tasty.describe "hWebhookId" $ do-    Tasty.it "creates the correct header name" $ do-      Http.hWebhookId @?= CI.mk (Ascii.pack "webhook-id")--  Tasty.describe "hWebhookSignature" $ do-    Tasty.it "creates the correct header name" $ do-      Http.hWebhookSignature @?= CI.mk (Ascii.pack "webhook-signature")--  Tasty.describe "hWebhookTimestamp" $ do-    Tasty.it "creates the correct header name" $ do-      Http.hWebhookTimestamp @?= CI.mk (Ascii.pack "webhook-timestamp")
− source/libraries/test/Signet/Unstable/Extra/MaybeTest.hs
@@ -1,15 +0,0 @@-module Signet.Unstable.Extra.MaybeTest where--import qualified Data.Void as Void-import qualified Signet.Unstable.Extra.Maybe as Maybe-import qualified Signet.Unstable.Extra.Tasty as Tasty-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Extra.Maybe" $ do-  Tasty.describe "note" $ do-    Tasty.it "works with nothing" $ do-      Maybe.note () (Nothing :: Maybe Void.Void) @?= Left ()--    Tasty.it "works with just" $ do-      Maybe.note () (Just True) @?= Right True
− source/libraries/test/Signet/Unstable/Extra/Tasty.hs
@@ -1,13 +0,0 @@-module Signet.Unstable.Extra.Tasty where--import qualified Control.Monad.Trans.Writer as Writer-import qualified Test.Tasty as Tasty-import qualified Test.Tasty.HUnit as Tasty--type Spec = Writer.Writer [Tasty.TestTree] ()--describe :: Tasty.TestName -> Spec -> Spec-describe testName = Writer.tell . pure . Tasty.testGroup testName . Writer.execWriter--it :: Tasty.TestName -> Tasty.Assertion -> Spec-it testName = Writer.tell . pure . Tasty.testCase testName
− source/libraries/test/Signet/Unstable/Type/AsymmetricSignatureTest.hs
@@ -1,27 +0,0 @@-module Signet.Unstable.Type.AsymmetricSignatureTest where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.AsymmetricSignature" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid input" $ do-      let byteString = Ascii.pack "invalid"-      let result = AsymmetricSignature.parse byteString-      result @?= Left (InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString)--    Tasty.it "succeeds with valid input" $ do-      let result = AsymmetricSignature.parse $ Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="-      signature <- Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"-      result @?= Right (AsymmetricSignature.MkAsymmetricSignature signature)--  Tasty.describe "render" $ do-    Tasty.it "works" $ do-      asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"-      AsymmetricSignature.render asymmetricSignature @?= Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="
− source/libraries/test/Signet/Unstable/Type/IdTest.hs
@@ -1,26 +0,0 @@-module Signet.Unstable.Type.IdTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidId as InvalidId-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Id as Id-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Id" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with input containing separator" $ do-      let byteString = Ascii.pack "invalid.id"-      let result = Id.parse byteString-      result @?= Left (InvalidId.MkInvalidId byteString)--    Tasty.it "succeeds with valid input" $ do-      let byteString = Ascii.pack "valid-id"-      let result = Id.parse byteString-      result @?= Right (Id.MkId byteString)--  Tasty.describe "render" $ do-    Tasty.it "returns the original ByteString" $ do-      let byteString = Ascii.pack "valid-id"-      let id_ = Id.MkId byteString-      Id.render id_ @?= byteString
− source/libraries/test/Signet/Unstable/Type/MessageTest.hs
@@ -1,47 +0,0 @@-module Signet.Unstable.Type.MessageTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Id as Id-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.Payload as Payload-import qualified Signet.Unstable.Type.Timestamp as Timestamp-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Message" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid timestamp" $ do-      let timestamp = Ascii.pack "invalid"-      let byteString = Ascii.pack "i." <> timestamp <> Ascii.pack ".p"-      let result = Message.parse byteString-      result @?= Left (InvalidMessage.InvalidTimestamp $ InvalidTimestamp.MkInvalidTimestamp timestamp)--    Tasty.it "succeeds with valid input" $ do-      let result = Message.parse $ Ascii.pack "i.0.p"-      id_ <- Either.throw . Id.parse $ Ascii.pack "i"-      timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"-      let payload = Payload.MkPayload $ Ascii.pack "p"-      result-        @?= Right-          Message.MkMessage-            { Message.id_ = id_,-              Message.timestamp = timestamp,-              Message.payload = payload-            }--  Tasty.describe "render" $ do-    Tasty.it "returns the correct ByteString representation" $ do-      id_ <- Either.throw . Id.parse $ Ascii.pack "i"-      timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"-      let payload = Payload.MkPayload $ Ascii.pack "p"-      let message =-            Message.MkMessage-              { Message.id_ = id_,-                Message.timestamp = timestamp,-                Message.payload = payload-              }-      Message.render message @?= Ascii.pack "i.0.p"
− source/libraries/test/Signet/Unstable/Type/PayloadTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Type.PayloadTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Payload" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Type/PublicKeyTest.hs
@@ -1,32 +0,0 @@-module Signet.Unstable.Type.PublicKeyTest where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.PublicKey as PublicKey-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.PublicKey" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid prefix" $ do-      let byteString = Ascii.pack "invalid"-      let result = PublicKey.parse byteString-      result @?= Left (InvalidPublicKey.MkInvalidPublicKey byteString)--    Tasty.it "fails with invalid input" $ do-      let byteString = Ascii.pack "whpk_invalid"-      let result = PublicKey.parse byteString-      result @?= Left (InvalidPublicKey.MkInvalidPublicKey byteString)--    Tasty.it "succeeds with valid input" $ do-      let result = PublicKey.parse $ Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="-      publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"-      result @?= Right publicKey--  Tasty.describe "render" $ do-    Tasty.it "works" $ do-      publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"-      PublicKey.render publicKey @?= Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
− source/libraries/test/Signet/Unstable/Type/SecretKeyTest.hs
@@ -1,32 +0,0 @@-module Signet.Unstable.Type.SecretKeyTest where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.SecretKey as SecretKey-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.SecretKey" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid prefix" $ do-      let byteString = Ascii.pack "invalid"-      let result = SecretKey.parse byteString-      result @?= Left (InvalidSecretKey.MkInvalidSecretKey byteString)--    Tasty.it "fails with invalid input" $ do-      let byteString = Ascii.pack "whsk_invalid"-      let result = SecretKey.parse byteString-      result @?= Left (InvalidSecretKey.MkInvalidSecretKey byteString)--    Tasty.it "succeeds with valid input" $ do-      let result = SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="-      secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"-      result @?= Right secretKey--  Tasty.describe "render" $ do-    Tasty.it "works" $ do-      secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"-      SecretKey.render secretKey @?= Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
− source/libraries/test/Signet/Unstable/Type/SecretTest.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Type.SecretTest where--import qualified Data.ByteArray as ByteArray-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Secret as Secret-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Secret" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid prefix" $ do-      let byteString = Ascii.pack "invalid"-      let result = Secret.parse byteString-      result @?= Left (InvalidSecret.MkInvalidSecret byteString)--    Tasty.it "fails with invalid input" $ do-      let byteString = Ascii.pack "whsec_invalid"-      let result = Secret.parse byteString-      result @?= Left (InvalidSecret.MkInvalidSecret byteString)--    Tasty.it "succeeds with valid input" $ do-      let result = Secret.parse $ Ascii.pack "whsec_MDEyMzQ1Njc4OQ=="-      let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"-      result @?= Right secret--  Tasty.describe "render" $ do-    Tasty.it "works" $ do-      let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"-      Secret.render secret @?= Ascii.pack "whsec_MDEyMzQ1Njc4OQ=="
− source/libraries/test/Signet/Unstable/Type/SignatureTest.hs
@@ -1,53 +0,0 @@-module Signet.Unstable.Type.SignatureTest where--import qualified Crypto.Error as Error-import qualified Crypto.Hash as Hash-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Signature" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid asymmetric signature" $ do-      let byteString = Ascii.pack "invalid"-      let result = Signature.parse $ Ascii.pack "v1a," <> byteString-      result @?= Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString)--    Tasty.it "fails with invalid symmetric signature" $ do-      let byteString = Ascii.pack "invalid"-      let result = Signature.parse $ Ascii.pack "v1," <> byteString-      result @?= Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString)--    Tasty.it "returns unknown signature with unrecognized prefix" $ do-      let byteString = Ascii.pack "unknown"-      let result = Signature.parse byteString-      result @?= Right (Left $ UnknownSignature.MkUnknownSignature byteString)--    Tasty.it "succeeds with valid asymmetric signature" $ do-      let byteString = Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="-      signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"-      Signature.parse byteString @?= Right (Right signature)--    Tasty.it "succeeds with valid symmetric signature" $ do-      let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="-      let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      Signature.parse byteString @?= Right (Right signature)--  Tasty.describe "render" $ do-    Tasty.it "renders asymmetric signature correctly" $ do-      signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"-      Signature.render signature @?= Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="--    Tasty.it "renders symmetric signature correctly" $ do-      let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      Signature.render signature @?= Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
− source/libraries/test/Signet/Unstable/Type/SignaturesTest.hs
@@ -1,72 +0,0 @@-module Signet.Unstable.Type.SignaturesTest where--import qualified Crypto.Error as Error-import qualified Crypto.Hash as Hash-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Signatures" $ do-  Tasty.describe "parse" $ do-    Tasty.it "succeeds with no signatures" $ do-      Signatures.parse ByteString.empty @?= Right ([], Signatures.MkSignatures [])--    Tasty.it "succeeds with one signature" $ do-      let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="-      Signatures.parse byteString @?= Right ([], Signatures.MkSignatures [signature])--    Tasty.it "succeeds with many signatures" $ do-      let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"-      let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="-      let signatures =-            Signatures.MkSignatures-              [ Signature.Symmetric symmetricSignature,-                Signature.Asymmetric asymmetricSignature-              ]-      Signatures.parse byteString @?= Right ([], signatures)--    Tasty.it "fails with an invalid symmetric signature" $ do-      let x = Ascii.pack "invalid"-      let byteString = Ascii.pack "v1," <> x-      Signatures.parse byteString @?= Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature x)--    Tasty.it "fails with an invalid asymmetric signature" $ do-      let x = Ascii.pack "invalid"-      let byteString = Ascii.pack "v1a," <> x-      Signatures.parse byteString @?= Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature x)--    Tasty.it "succeeds with an unknown signature" $ do-      let byteString = Ascii.pack "unknown"-      Signatures.parse byteString @?= Right ([UnknownSignature.MkUnknownSignature byteString], Signatures.MkSignatures [])--  Tasty.describe "render" $ do-    Tasty.it "renders no signatures" $ do-      let signatures = Signatures.MkSignatures []-      Signatures.render signatures @?= ByteString.empty--    Tasty.it "renders one signature" $ do-      let signatures = Signatures.MkSignatures . pure . Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      Signatures.render signatures @?= Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="--    Tasty.it "renders many signatures" $ do-      let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"-      let signatures =-            Signatures.MkSignatures-              [ Signature.Symmetric symmetricSignature,-                Signature.Asymmetric asymmetricSignature-              ]-      Signatures.render signatures @?= Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="
− source/libraries/test/Signet/Unstable/Type/SignerTest.hs
@@ -1,76 +0,0 @@-module Signet.Unstable.Type.SignerTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.Secret as Secret-import qualified Signet.Unstable.Type.SecretKey as SecretKey-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signer as Signer-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Signer" $ do-  Tasty.describe "parse" $ do-    Tasty.it "succeeds with a valid secret key" $ do-      let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="-      let actual = Signer.parse byteString-      secretKey <- Either.throw $ SecretKey.parse byteString-      actual @?= Right (Signer.Asymmetric secretKey)--    Tasty.it "succeeds with a valid secret" $ do-      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      let actual = Signer.parse byteString-      secret <- Either.throw $ Secret.parse byteString-      actual @?= Right (Signer.Symmetric secret)--    Tasty.it "fails with invalid input" $ do-      let byteString = Ascii.pack "invalid"-      let actual = Signer.parse byteString-      actual @?= Left (InvalidSigner.MkInvalidSigner byteString)--  Tasty.describe "render" $ do-    Tasty.it "works with a secret key" $ do-      let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="-      secretKey <- Either.throw . SecretKey.parse $ byteString-      Signer.render (Signer.Asymmetric secretKey) @?= byteString--    Tasty.it "works with a secret" $ do-      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      secret <- Either.throw . Secret.parse $ byteString-      Signer.render (Signer.Symmetric secret) @?= byteString--  Tasty.describe "sign" $ do-    Tasty.it "works with asymmetric" $ do-      signer <- Either.throw . Signer.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      let actual = Signer.sign signer message-      Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="-      actual @?= expected--    Tasty.it "works with symmetric" $ do-      signer <- Either.throw . Signer.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      let actual = Signer.sign signer message-      Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      actual @?= expected--  Tasty.describe "asymmetric" $ do-    Tasty.it "creates correct asymmetric signature" $ do-      secretKey <- Either.throw . SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      let actual = Signer.asymmetric secretKey message-      expected <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="-      actual @?= expected--  Tasty.describe "symmetric" $ do-    Tasty.it "creates correct symmetric signature" $ do-      secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      let actual = Signer.symmetric secret message-      expected <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      actual @?= expected
− source/libraries/test/Signet/Unstable/Type/SymmetricSignatureTest.hs
@@ -1,27 +0,0 @@-module Signet.Unstable.Type.SymmetricSignatureTest where--import qualified Crypto.Hash as Hash-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.SymmetricSignature" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid symmetric signature" $ do-      let byteString = Ascii.pack "invalid"-      let result = SymmetricSignature.parse byteString-      result @?= Left (InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString)--    Tasty.it "succeeds with valid symmetric signature" $ do-      let byteString = Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="-      let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      SymmetricSignature.parse byteString @?= Right signature--  Tasty.describe "render" $ do-    Tasty.it "renders symmetric signature correctly" $ do-      let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty-      SymmetricSignature.render signature @?= Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
− source/libraries/test/Signet/Unstable/Type/TimestampTest.hs
@@ -1,33 +0,0 @@-module Signet.Unstable.Type.TimestampTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Timestamp as Timestamp-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Timestamp" $ do-  Tasty.describe "parse" $ do-    Tasty.it "fails with invalid timestamp format" $ do-      let byteString = Ascii.pack "invalid-timestamp"-      let result = Timestamp.parse byteString-      result @?= Left (InvalidTimestamp.MkInvalidTimestamp byteString)--    Tasty.it "succeeds with valid timestamp format" $ do-      let byteString = Ascii.pack "1617235200"-      let result = Timestamp.parse byteString-      case result of-        Right timestamp -> do-          let utcTime = Timestamp.unwrap timestamp-          let expectedTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0-          utcTime @?= expectedTime-        Left _ -> fail "Expected Right but got Left"--  Tasty.describe "render" $ do-    Tasty.it "returns the correct ByteString representation" $ do-      let utcTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0-      let timestamp = Timestamp.MkTimestamp utcTime-      let expected = Ascii.pack "1617235200"-      Timestamp.render timestamp @?= expected
− source/libraries/test/Signet/Unstable/Type/ToleranceTest.hs
@@ -1,34 +0,0 @@-module Signet.Unstable.Type.ToleranceTest where--import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Timestamp as Timestamp-import qualified Signet.Unstable.Type.Tolerance as Tolerance-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Tolerance" $ do-  Tasty.describe "check" $ do-    Tasty.it "succeeds when timestamp is within tolerance" $ do-      let tolerance = Tolerance.MkTolerance 1-      let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60-      let timestamp = Timestamp.MkTimestamp utcTime-      let result = Tolerance.check tolerance utcTime timestamp-      result @?= Right ()--    Tasty.it "fails when timestamp is too old" $ do-      let tolerance = Tolerance.MkTolerance 1-      let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60-      let timestamp = Timestamp.MkTimestamp utcTime-      let now = Time.addUTCTime 2 utcTime-      let result = Tolerance.check tolerance now timestamp-      result @?= Left (ToleranceException.MkToleranceException timestamp)--    Tasty.it "fails when timestamp is in the future" $ do-      let tolerance = Tolerance.MkTolerance 1-      let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60-      let timestamp = Timestamp.MkTimestamp utcTime-      let now = Time.addUTCTime (-2) utcTime-      let result = Tolerance.check tolerance now timestamp-      result @?= Left (ToleranceException.MkToleranceException timestamp)
− source/libraries/test/Signet/Unstable/Type/UnknownSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Type.UnknownSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.UnknownSignature" $ do-  pure ()
− source/libraries/test/Signet/Unstable/Type/VerifierTest.hs
@@ -1,110 +0,0 @@-module Signet.Unstable.Type.VerifierTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier-import qualified Signet.Unstable.Exception.VerificationException as VerificationException-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.PublicKey as PublicKey-import qualified Signet.Unstable.Type.Secret as Secret-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.Verifier as Verifier-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Verifier" $ do-  Tasty.describe "parse" $ do-    Tasty.it "succeeds with a valid public key" $ do-      let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="-      let actual = Verifier.parse byteString-      publicKey <- Either.throw $ PublicKey.parse byteString-      actual @?= Right (Verifier.Asymmetric publicKey)--    Tasty.it "succeeds with a valid secret" $ do-      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      let actual = Verifier.parse byteString-      secret <- Either.throw $ Secret.parse byteString-      actual @?= Right (Verifier.Symmetric secret)--    Tasty.it "fails with invalid input" $ do-      let byteString = Ascii.pack "invalid"-      let actual = Verifier.parse byteString-      actual @?= Left (InvalidVerifier.MkInvalidVerifier byteString)--  Tasty.describe "render" $ do-    Tasty.it "works with a public key" $ do-      let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="-      publicKey <- Either.throw . PublicKey.parse $ byteString-      Verifier.render (Verifier.Asymmetric publicKey) @?= byteString--    Tasty.it "works with a secret" $ do-      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      secret <- Either.throw . Secret.parse $ byteString-      Verifier.render (Verifier.Symmetric secret) @?= byteString--  Tasty.describe "verify" $ do-    Tasty.it "succeeds with a valid asymmetric signature" $ do-      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="-      let actual = Verifier.verify verifier message signatures-      Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="-      actual @?= Right signature--    Tasty.it "fails with an invalid asymmetric signature" $ do-      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="-      let actual = Verifier.verify verifier message signatures-      actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)--    Tasty.it "succeeds with a valid symmetric signature" $ do-      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      let actual = Verifier.verify verifier message signatures-      Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      actual @?= Right signature--    Tasty.it "fails with an invalid symmetric signature" $ do-      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="-      let actual = Verifier.verify verifier message signatures-      actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)--  Tasty.describe "asymmetric" $ do-    Tasty.it "succeeds with a valid signature" $ do-      publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="-      let actual = Verifier.asymmetric publicKey message signatures-      asymmetricSignature <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="-      actual @?= Right asymmetricSignature--    Tasty.it "fails with an invalid signature" $ do-      publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="-      let actual = Verifier.asymmetric publicKey message signatures-      actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)--  Tasty.describe "symmetric" $ do-    Tasty.it "succeeds with a valid signature" $ do-      secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      let actual = Verifier.symmetric secret message signatures-      symmetricSignature <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      actual @?= Right symmetricSignature--    Tasty.it "fails with an invalid signature" $ do-      secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="-      let actual = Verifier.symmetric secret message signatures-      actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)
− source/libraries/test/Signet/UnstableTest.hs
@@ -1,57 +0,0 @@-module Signet.UnstableTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.Time as Time-import qualified Signet.Unstable as Signet-import qualified Signet.Unstable.Exception.SignetException as SignetException-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Exception.VerificationException as VerificationException-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.Tolerance as Tolerance-import qualified Signet.Unstable.Type.Verifier as Verifier-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable" $ do-  Tasty.describe "verifyWebhookText" $ do-    pure ()--  Tasty.describe "verifyWebhookByteString" $ do-    pure ()--  Tasty.describe "verifyWebhook" $ do-    pure ()--  Tasty.describe "verifyWebhookWith" $ do-    Tasty.it "succeeds with a valid symmetric signature" $ do-      let tolerance = Tolerance.typical-      let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0-      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      let byteString = Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      (_, signatures) <- Either.throw $ Signatures.parse byteString-      let result = Signet.verifyWebhookWith tolerance now verifier message signatures-      Right signature <- Either.throw $ Signature.parse byteString-      result @?= Right signature--    Tasty.it "fails with an invalid timestamp" $ do-      let tolerance = Tolerance.typical-      let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0-      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.301.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="-      let result = Signet.verifyWebhookWith tolerance now verifier message signatures-      result @?= Left (SignetException.ToleranceException . ToleranceException.MkToleranceException $ Message.timestamp message)--    Tasty.it "fails with an invalid symmetric signature" $ do-      let tolerance = Tolerance.typical-      let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0-      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="-      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"-      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="-      let result = Signet.verifyWebhookWith tolerance now verifier message signatures-      result @?= Left (SignetException.VerificationException . VerificationException.MkVerificationException $ Message.id_ message)
− source/libraries/test/SignetTest.hs
@@ -1,73 +0,0 @@-module SignetTest where--import qualified Control.Monad.Trans.Writer as Writer-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignatureTest-import qualified Signet.Unstable.Exception.InvalidIdTest-import qualified Signet.Unstable.Exception.InvalidMessageTest-import qualified Signet.Unstable.Exception.InvalidPublicKeyTest-import qualified Signet.Unstable.Exception.InvalidSecretKeyTest-import qualified Signet.Unstable.Exception.InvalidSecretTest-import qualified Signet.Unstable.Exception.InvalidSignatureTest-import qualified Signet.Unstable.Exception.InvalidSignerTest-import qualified Signet.Unstable.Exception.InvalidSymmetricSignatureTest-import qualified Signet.Unstable.Exception.InvalidTimestampTest-import qualified Signet.Unstable.Exception.InvalidVerifierTest-import qualified Signet.Unstable.Exception.SignetExceptionTest-import qualified Signet.Unstable.Exception.ToleranceExceptionTest-import qualified Signet.Unstable.Exception.VerificationExceptionTest-import qualified Signet.Unstable.Extra.EitherTest-import qualified Signet.Unstable.Extra.HttpTest-import qualified Signet.Unstable.Extra.MaybeTest-import qualified Signet.Unstable.Type.AsymmetricSignatureTest-import qualified Signet.Unstable.Type.IdTest-import qualified Signet.Unstable.Type.MessageTest-import qualified Signet.Unstable.Type.PayloadTest-import qualified Signet.Unstable.Type.PublicKeyTest-import qualified Signet.Unstable.Type.SecretKeyTest-import qualified Signet.Unstable.Type.SecretTest-import qualified Signet.Unstable.Type.SignatureTest-import qualified Signet.Unstable.Type.SignaturesTest-import qualified Signet.Unstable.Type.SignerTest-import qualified Signet.Unstable.Type.SymmetricSignatureTest-import qualified Signet.Unstable.Type.TimestampTest-import qualified Signet.Unstable.Type.ToleranceTest-import qualified Signet.Unstable.Type.UnknownSignatureTest-import qualified Signet.Unstable.Type.VerifierTest-import qualified Signet.UnstableTest-import qualified Test.Tasty as Tasty--testTree :: Tasty.TestTree-testTree = Tasty.testGroup "signet" . Writer.execWriter $ do-  Signet.Unstable.Exception.InvalidAsymmetricSignatureTest.spec-  Signet.Unstable.Exception.InvalidIdTest.spec-  Signet.Unstable.Exception.InvalidMessageTest.spec-  Signet.Unstable.Exception.InvalidPublicKeyTest.spec-  Signet.Unstable.Exception.InvalidSecretKeyTest.spec-  Signet.Unstable.Exception.InvalidSecretTest.spec-  Signet.Unstable.Exception.InvalidSignatureTest.spec-  Signet.Unstable.Exception.InvalidSignerTest.spec-  Signet.Unstable.Exception.InvalidSymmetricSignatureTest.spec-  Signet.Unstable.Exception.InvalidTimestampTest.spec-  Signet.Unstable.Exception.InvalidVerifierTest.spec-  Signet.Unstable.Exception.SignetExceptionTest.spec-  Signet.Unstable.Exception.ToleranceExceptionTest.spec-  Signet.Unstable.Exception.VerificationExceptionTest.spec-  Signet.Unstable.Extra.EitherTest.spec-  Signet.Unstable.Extra.HttpTest.spec-  Signet.Unstable.Extra.MaybeTest.spec-  Signet.Unstable.Type.AsymmetricSignatureTest.spec-  Signet.Unstable.Type.IdTest.spec-  Signet.Unstable.Type.MessageTest.spec-  Signet.Unstable.Type.PayloadTest.spec-  Signet.Unstable.Type.PublicKeyTest.spec-  Signet.Unstable.Type.SecretKeyTest.spec-  Signet.Unstable.Type.SecretTest.spec-  Signet.Unstable.Type.SignaturesTest.spec-  Signet.Unstable.Type.SignatureTest.spec-  Signet.Unstable.Type.SignerTest.spec-  Signet.Unstable.Type.SymmetricSignatureTest.spec-  Signet.Unstable.Type.TimestampTest.spec-  Signet.Unstable.Type.ToleranceTest.spec-  Signet.Unstable.Type.UnknownSignatureTest.spec-  Signet.Unstable.Type.VerifierTest.spec-  Signet.UnstableTest.spec
− source/libraries/unstable/Signet/Unstable.hs
@@ -1,196 +0,0 @@-{-# LANGUAGE PatternSynonyms #-}--module Signet.Unstable where--import qualified Control.Monad.Catch as Exception-import qualified Control.Monad.IO.Class as MonadIO-import qualified Data.Bifunctor as Bifunctor-import qualified Data.ByteString as ByteString-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text-import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.InvalidId as InvalidId-import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp-import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier-import qualified Signet.Unstable.Exception.SignetException as SignetException-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Id as Id-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.Payload as Payload-import qualified Signet.Unstable.Type.PublicKey as PublicKey-import qualified Signet.Unstable.Type.Secret as Secret-import qualified Signet.Unstable.Type.SecretKey as SecretKey-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.Signer as Signer-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.Timestamp as Timestamp-import qualified Signet.Unstable.Type.Tolerance as Tolerance-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature-import qualified Signet.Unstable.Type.Verifier as Verifier---- | Verifies a webhook with 'Text.Text' values. This is a wrapper around--- 'verifyWebhookByteString' that assumes all values are encoded as UTF-8.-verifyWebhookText ::-  (MonadIO.MonadIO m, Exception.MonadThrow m) =>-  -- | A 'Verifier.Verifier' for the webhook. Typically this will be-  -- @"whsec_..."@ or @"whpk_..."@.-  Text.Text ->-  -- | The webhook's unique 'Id.Id'. Typically this will come from the-  -- 'Signet.Unstable.Extra.Http.hWebhookId' header and look like @"msg_..."@.-  Text.Text ->-  -- | The webhook's 'Timestamp.Timestamp'. This is an integer number of-  -- seconds since the Unix epoch. Typically this will come from the-  -- 'Signet.Unstable.Extra.Http.hWebhookTimestamp' header. For example-  -- @"981173106"@ for @2001-02-03T04:05:06Z@.-  Text.Text ->-  -- | The webhook's raw 'Payload.Payload'. Typically this will be a JSON-  -- object like @{"event_type":"ping",...}@.-  Text.Text ->-  -- | The webhook's 'Signatures.Signatures'. Typically this will come from the-  -- 'Signet.Unstable.Extra.Http.hWebhookSignature' header and look like-  -- @"v1_..."@ or @"v1a_..."@.-  Text.Text ->-  m Signature.Signature-verifyWebhookText v i t p s =-  verifyWebhookByteString-    (Text.encodeUtf8 v)-    (Text.encodeUtf8 i)-    (Text.encodeUtf8 t)-    (Text.encodeUtf8 p)-    (Text.encodeUtf8 s)---- | Verifies a webhook with 'ByteString.ByteString' values. This is a--- wrapper around 'verifyWebhook'. See 'verifyWebhookText' for a description of--- the arguments.-verifyWebhookByteString ::-  (MonadIO.MonadIO m, Exception.MonadThrow m) =>-  -- | 'Verifier.Verifier'-  ByteString.ByteString ->-  -- | 'Id.Id'-  ByteString.ByteString ->-  -- | 'Timestamp.Timestamp'-  ByteString.ByteString ->-  -- | 'Payload.Payload'-  ByteString.ByteString ->-  -- | 'Signatures.Signatures'-  ByteString.ByteString ->-  m Signature.Signature-verifyWebhookByteString v i t p s = do-  verifier <- Either.throw $ parseVerifier v-  id_ <- Either.throw $ parseId i-  timestamp <- Either.throw $ parseTimestamp t-  let payload = Payload.MkPayload p-  let message =-        Message.MkMessage-          { Message.id_ = id_,-            Message.timestamp = timestamp,-            Message.payload = payload-          }-  (_, signatures) <- Either.throw $ parseSignatures s-  verifyWebhook verifier message signatures---- | Verifies a webhook. This is a wrapper around 'verifyWebhookWith' that uses--- 'typicalTolerance' and the current time.------ Throws an exception if the webhook is invalid.-verifyWebhook ::-  (MonadIO.MonadIO m, Exception.MonadThrow m) =>-  Verifier.Verifier ->-  Message.Message ->-  Signatures.Signatures ->-  m Signature.Signature-verifyWebhook verifier message signatures = do-  now <- MonadIO.liftIO Time.getCurrentTime-  Either.throw $ verifyWebhookWith typicalTolerance now verifier message signatures---- | Verifies a webhook. This is the lowest-level function that gives you the--- most control. If you're looking for something that's easier to use and--- assumes some reasonable defaults, consider 'verifyWebhook'.-verifyWebhookWith ::-  -- | Often 'typicalTolerance'.-  Tolerance.Tolerance ->-  -- | Usually 'Time.getCurrentTime'.-  Time.UTCTime ->-  -- | See 'parseVerifier'.-  Verifier.Verifier ->-  -- | See 'parseMessage'. Or 'Message.MkMessage' along with 'parseId',-  -- 'parseTimestamp', and 'Payload.MkPayload'.-  Message.Message ->-  -- | See 'parseSignatures'.-  Signatures.Signatures ->-  Either SignetException.SignetException Signature.Signature-verifyWebhookWith tolerance now verifier message signatures = do-  Bifunctor.first SignetException.ToleranceException-    . Tolerance.check tolerance now-    $ Message.timestamp message-  Bifunctor.first SignetException.VerificationException $-    Verifier.verify verifier message signatures---- | Alias for 'Tolerance.typical'.-typicalTolerance :: Tolerance.Tolerance-typicalTolerance = Tolerance.typical---- | Alias for 'Verifier.parse'.-parseVerifier :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier.Verifier-parseVerifier = Verifier.parse---- | Alias for 'Id.parse'.-parseId :: ByteString.ByteString -> Either InvalidId.InvalidId Id.Id-parseId = Id.parse---- | Alias for 'Timestamp.parse'.-parseTimestamp :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp.Timestamp-parseTimestamp = Timestamp.parse---- | Alias for 'Message.parse'.-parseMessage :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message.Message-parseMessage = Message.parse---- | Alias for 'Signatures.parse'.-parseSignatures ::-  ByteString.ByteString ->-  Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures.Signatures)-parseSignatures = Signatures.parse---- | Alias for 'Verifier.Asymmetric'.-pattern AsymmetricVerifier :: PublicKey.PublicKey -> Verifier.Verifier-pattern AsymmetricVerifier publicKey = Verifier.Asymmetric publicKey---- | Alias for 'Verifier.Symmetric'.-pattern SymmetricVerifier :: Secret.Secret -> Verifier.Verifier-pattern SymmetricVerifier secret = Verifier.Symmetric secret--{-# COMPLETE AsymmetricVerifier, SymmetricVerifier #-}---- | Alias for 'Signer.sign'.-signWebhook :: Signer.Signer -> Message.Message -> Signature.Signature-signWebhook = Signer.sign---- | Alias for 'Signer.parse'.-parseSigner :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer.Signer-parseSigner = Signer.parse---- | Alias for 'Signer.Asymmetric'.-pattern AsymmetricSigner :: SecretKey.SecretKey -> Signer.Signer-pattern AsymmetricSigner secretKey = Signer.Asymmetric secretKey---- | Alias for 'Signer.Symmetric'.-pattern SymmetricSigner :: Secret.Secret -> Signer.Signer-pattern SymmetricSigner secret = Signer.Symmetric secret--{-# COMPLETE AsymmetricSigner, SymmetricSigner #-}---- | Alias for 'Signature.Asymmetric'.-pattern AsymmetricSignature :: AsymmetricSignature.AsymmetricSignature -> Signature.Signature-pattern AsymmetricSignature asymmetricSignature = Signature.Asymmetric asymmetricSignature---- | Alias for 'Signature.Symmetric'.-pattern SymmetricSignature :: SymmetricSignature.SymmetricSignature -> Signature.Signature-pattern SymmetricSignature symmetricSignature = Signature.Symmetric symmetricSignature--{-# COMPLETE AsymmetricSignature, SymmetricSignature #-}
− source/libraries/unstable/Signet/Unstable/Exception/InvalidAsymmetricSignature.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidAsymmetricSignature where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidAsymmetricSignature-  = MkInvalidAsymmetricSignature ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidAsymmetricSignature where-  displayException = mappend "invalid asymmetric signature: " . show . unwrap--unwrap :: InvalidAsymmetricSignature -> ByteString.ByteString-unwrap (MkInvalidAsymmetricSignature byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidId.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidId where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidId-  = MkInvalidId ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidId where-  displayException = mappend "invalid ID: " . show . unwrap--unwrap :: InvalidId -> ByteString.ByteString-unwrap (MkInvalidId byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidMessage.hs
@@ -1,18 +0,0 @@-module Signet.Unstable.Exception.InvalidMessage where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Exception.InvalidId as InvalidId-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp--data InvalidMessage-  = InvalidId InvalidId.InvalidId-  | InvalidTimestamp InvalidTimestamp.InvalidTimestamp-  deriving (Eq, Show)--instance Exception.Exception InvalidMessage where-  displayException invalidMessage =-    "invalid message: " <> case invalidMessage of-      InvalidId invalidId ->-        Exception.displayException invalidId-      InvalidTimestamp invalidTimestamp ->-        Exception.displayException invalidTimestamp
− source/libraries/unstable/Signet/Unstable/Exception/InvalidPublicKey.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidPublicKey where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidPublicKey-  = MkInvalidPublicKey ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidPublicKey where-  displayException = mappend "invalid public key: " . show . unwrap--unwrap :: InvalidPublicKey -> ByteString.ByteString-unwrap (MkInvalidPublicKey byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSecret.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSecret where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSecret-  = MkInvalidSecret ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidSecret where-  displayException = mappend "invalid secret: " . show . unwrap--unwrap :: InvalidSecret -> ByteString.ByteString-unwrap (MkInvalidSecret byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSecretKey.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSecretKey where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSecretKey-  = MkInvalidSecretKey ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidSecretKey where-  displayException = mappend "invalid secret key: " . show . unwrap--unwrap :: InvalidSecretKey -> ByteString.ByteString-unwrap (MkInvalidSecretKey byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSignature.hs
@@ -1,18 +0,0 @@-module Signet.Unstable.Exception.InvalidSignature where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature--data InvalidSignature-  = InvalidAsymmetricSignature InvalidAsymmetricSignature.InvalidAsymmetricSignature-  | InvalidSymmetricSignature InvalidSymmetricSignature.InvalidSymmetricSignature-  deriving (Eq, Show)--instance Exception.Exception InvalidSignature where-  displayException invalidSignature =-    "invalid signature: " <> case invalidSignature of-      InvalidAsymmetricSignature invalidAsymmetricSignature ->-        Exception.displayException invalidAsymmetricSignature-      InvalidSymmetricSignature invalidSymmetricSignature ->-        Exception.displayException invalidSymmetricSignature
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSigner.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSigner where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSigner-  = MkInvalidSigner ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidSigner where-  displayException = mappend "invalid signer: " . show . unwrap--unwrap :: InvalidSigner -> ByteString.ByteString-unwrap (MkInvalidSigner byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSymmetricSignature.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSymmetricSignature where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSymmetricSignature-  = MkInvalidSymmetricSignature ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidSymmetricSignature where-  displayException = mappend "invalid symmetric signature: " . show . unwrap--unwrap :: InvalidSymmetricSignature -> ByteString.ByteString-unwrap (MkInvalidSymmetricSignature byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidTimestamp.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidTimestamp where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidTimestamp-  = MkInvalidTimestamp ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidTimestamp where-  displayException = mappend "invalid timestamp: " . show . unwrap--unwrap :: InvalidTimestamp -> ByteString.ByteString-unwrap (MkInvalidTimestamp byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidVerifier.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidVerifier where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidVerifier-  = MkInvalidVerifier ByteString.ByteString-  deriving (Eq, Show)--instance Exception.Exception InvalidVerifier where-  displayException = mappend "invalid verifier: " . show . unwrap--unwrap :: InvalidVerifier -> ByteString.ByteString-unwrap (MkInvalidVerifier byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/SignetException.hs
@@ -1,18 +0,0 @@-module Signet.Unstable.Exception.SignetException where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Exception.VerificationException as VerificationException--data SignetException-  = ToleranceException ToleranceException.ToleranceException-  | VerificationException VerificationException.VerificationException-  deriving (Eq, Show)--instance Exception.Exception SignetException where-  displayException signetException =-    "failed to verify webhook: " <> case signetException of-      ToleranceException toleranceException ->-        Exception.displayException toleranceException-      VerificationException verificationException ->-        Exception.displayException verificationException
− source/libraries/unstable/Signet/Unstable/Exception/ToleranceException.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.ToleranceException where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Type.Timestamp as Timestamp--newtype ToleranceException-  = MkToleranceException Timestamp.Timestamp-  deriving (Eq, Show)--instance Exception.Exception ToleranceException where-  displayException = mappend "timestamp out of tolerance: " . show . unwrap--unwrap :: ToleranceException -> Timestamp.Timestamp-unwrap (MkToleranceException timestamp) = timestamp
− source/libraries/unstable/Signet/Unstable/Exception/VerificationException.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.VerificationException where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Type.Id as Id--newtype VerificationException-  = MkVerificationException Id.Id-  deriving (Eq, Show)--instance Exception.Exception VerificationException where-  displayException = mappend "verification failed: " . show . unwrap--unwrap :: VerificationException -> Id.Id-unwrap (MkVerificationException id_) = id_
− source/libraries/unstable/Signet/Unstable/Extra/Either.hs
@@ -1,9 +0,0 @@-module Signet.Unstable.Extra.Either where--import qualified Control.Monad.Catch as Exception--hush :: Either x a -> Maybe a-hush = either (const Nothing) Just--throw :: (Exception.Exception e, Exception.MonadThrow m) => Either e a -> m a-throw = either Exception.throwM pure
− source/libraries/unstable/Signet/Unstable/Extra/Http.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Extra.Http where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.CaseInsensitive as CI-import qualified Network.HTTP.Types as Http--hWebhookId :: Http.HeaderName-hWebhookId = CI.mk $ Ascii.pack "webhook-id"--hWebhookSignature :: Http.HeaderName-hWebhookSignature = CI.mk $ Ascii.pack "webhook-signature"--hWebhookTimestamp :: Http.HeaderName-hWebhookTimestamp = CI.mk $ Ascii.pack "webhook-timestamp"
− source/libraries/unstable/Signet/Unstable/Extra/Maybe.hs
@@ -1,4 +0,0 @@-module Signet.Unstable.Extra.Maybe where--note :: e -> Maybe a -> Either e a-note = flip maybe Right . Left
− source/libraries/unstable/Signet/Unstable/Type/AsymmetricSignature.hs
@@ -1,28 +0,0 @@-module Signet.Unstable.Type.AsymmetricSignature where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype AsymmetricSignature-  = MkAsymmetricSignature Ed25519.Signature-  deriving (Eq, Show)--unwrap :: AsymmetricSignature -> Ed25519.Signature-unwrap (MkAsymmetricSignature signature) = signature--parse ::-  ByteString.ByteString ->-  Either InvalidAsymmetricSignature.InvalidAsymmetricSignature AsymmetricSignature-parse encoded = Maybe.note (InvalidAsymmetricSignature.MkInvalidAsymmetricSignature encoded) $ do-  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded-  fmap MkAsymmetricSignature-    . Error.maybeCryptoError-    $ Ed25519.signature (byteString :: ByteString.ByteString)--render :: AsymmetricSignature -> ByteString.ByteString-render = Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Id.hs
@@ -1,26 +0,0 @@-module Signet.Unstable.Type.Id where--import qualified Control.Monad as Monad-import qualified Data.ByteString as ByteString-import qualified Data.Word as Word-import qualified Signet.Unstable.Exception.InvalidId as InvalidId--newtype Id-  = MkId ByteString.ByteString-  deriving (Eq, Show)--unwrap :: Id -> ByteString.ByteString-unwrap (MkId byteString) = byteString--separator :: Word.Word8-separator = 0x2e--parse :: ByteString.ByteString -> Either InvalidId.InvalidId Id-parse byteString = do-  Monad.when (ByteString.any (== separator) byteString)-    . Left-    $ InvalidId.MkInvalidId byteString-  Right $ MkId byteString--render :: Id -> ByteString.ByteString-render = unwrap
− source/libraries/unstable/Signet/Unstable/Type/Message.hs
@@ -1,36 +0,0 @@-module Signet.Unstable.Type.Message where--import qualified Data.Bifunctor as Bifunctor-import qualified Data.ByteString as ByteString-import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage-import qualified Signet.Unstable.Type.Id as Id-import qualified Signet.Unstable.Type.Payload as Payload-import qualified Signet.Unstable.Type.Timestamp as Timestamp--data Message = MkMessage-  { id_ :: Id.Id,-    timestamp :: Timestamp.Timestamp,-    payload :: Payload.Payload-  }-  deriving (Eq, Show)--parse :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message-parse x = do-  let (rawId, y) = ByteString.break (== Id.separator) x-  theId <- Bifunctor.first InvalidMessage.InvalidId $ Id.parse rawId-  let (rawTimestamp, z) =-        ByteString.break (== Id.separator) $-          ByteString.drop 1 y-  theTimestamp <--    Bifunctor.first InvalidMessage.InvalidTimestamp $-      Timestamp.parse rawTimestamp-  let thePayload = Payload.MkPayload $ ByteString.drop 1 z-  pure MkMessage {id_ = theId, timestamp = theTimestamp, payload = thePayload}--render :: Message -> ByteString.ByteString-render message =-  Id.render (id_ message)-    <> ByteString.singleton Id.separator-    <> Timestamp.render (timestamp message)-    <> ByteString.singleton Id.separator-    <> Payload.unwrap (payload message)
− source/libraries/unstable/Signet/Unstable/Type/Payload.hs
@@ -1,10 +0,0 @@-module Signet.Unstable.Type.Payload where--import qualified Data.ByteString as ByteString--newtype Payload-  = MkPayload ByteString.ByteString-  deriving (Eq, Show)--unwrap :: Payload -> ByteString.ByteString-unwrap (MkPayload byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Type/PublicKey.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Type.PublicKey where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype PublicKey-  = MkPublicKey Ed25519.PublicKey-  deriving (Eq, Show)--unwrap :: PublicKey -> Ed25519.PublicKey-unwrap (MkPublicKey publicKey) = publicKey--prefix :: ByteString.ByteString-prefix = Ascii.pack "whpk_"--parse :: ByteString.ByteString -> Either InvalidPublicKey.InvalidPublicKey PublicKey-parse prefixed = Maybe.note (InvalidPublicKey.MkInvalidPublicKey prefixed) $ do-  encoded <- ByteString.stripPrefix prefix prefixed-  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded-  fmap MkPublicKey-    . Error.maybeCryptoError-    $ Ed25519.publicKey (byteString :: ByteString.ByteString)--render :: PublicKey -> ByteString.ByteString-render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Secret.hs
@@ -1,27 +0,0 @@-module Signet.Unstable.Type.Secret where--import qualified Data.ByteArray as ByteArray-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype Secret-  = MkSecret ByteArray.ScrubbedBytes-  deriving (Eq, Show)--unwrap :: Secret -> ByteArray.ScrubbedBytes-unwrap (MkSecret scrubbedBytes) = scrubbedBytes--prefix :: ByteString.ByteString-prefix = Ascii.pack "whsec_"--parse :: ByteString.ByteString -> Either InvalidSecret.InvalidSecret Secret-parse prefixed = Maybe.note (InvalidSecret.MkInvalidSecret prefixed) $ do-  encoded <- ByteString.stripPrefix prefix prefixed-  fmap MkSecret . Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded--render :: Secret -> ByteString.ByteString-render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/SecretKey.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Type.SecretKey where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype SecretKey-  = MkSecretKey Ed25519.SecretKey-  deriving (Eq, Show)--unwrap :: SecretKey -> Ed25519.SecretKey-unwrap (MkSecretKey secretKey) = secretKey--prefix :: ByteString.ByteString-prefix = Ascii.pack "whsk_"--parse :: ByteString.ByteString -> Either InvalidSecretKey.InvalidSecretKey SecretKey-parse prefixed = Maybe.note (InvalidSecretKey.MkInvalidSecretKey prefixed) $ do-  encoded <- ByteString.stripPrefix prefix prefixed-  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded-  fmap MkSecretKey-    . Error.maybeCryptoError-    $ Ed25519.secretKey (byteString :: ByteString.ByteString)--render :: SecretKey -> ByteString.ByteString-render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Signature.hs
@@ -1,49 +0,0 @@-module Signet.Unstable.Type.Signature where--import qualified Data.Bifunctor as Bifunctor-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Data.Word as Word-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature--data Signature-  = Asymmetric AsymmetricSignature.AsymmetricSignature-  | Symmetric SymmetricSignature.SymmetricSignature-  deriving (Eq, Show)--separator :: Word.Word8-separator = 0x2c--asymmetricPrefix :: ByteString.ByteString-asymmetricPrefix = Ascii.pack "v1a"--symmetricPrefix :: ByteString.ByteString-symmetricPrefix = Ascii.pack "v1"--parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature (Either UnknownSignature.UnknownSignature Signature)-parse prefixed = do-  let (prefix, rest) = ByteString.break (== separator) prefixed-  case ByteString.drop 1 rest of-    byteString-      | prefix == asymmetricPrefix ->-          Bifunctor.bimap InvalidSignature.InvalidAsymmetricSignature (Right . Asymmetric) $-            AsymmetricSignature.parse byteString-      | prefix == symmetricPrefix ->-          Bifunctor.bimap InvalidSignature.InvalidSymmetricSignature (Right . Symmetric) $-            SymmetricSignature.parse byteString-    _ -> Right . Left $ UnknownSignature.MkUnknownSignature prefixed--render :: Signature -> ByteString.ByteString-render signature =-  case signature of-    Asymmetric asymmetricSignature ->-      asymmetricPrefix-        <> ByteString.singleton separator-        <> AsymmetricSignature.render asymmetricSignature-    Symmetric symmetricSignature ->-      symmetricPrefix-        <> ByteString.singleton separator-        <> SymmetricSignature.render symmetricSignature
− source/libraries/unstable/Signet/Unstable/Type/Signatures.hs
@@ -1,30 +0,0 @@-module Signet.Unstable.Type.Signatures where--import qualified Data.ByteString as ByteString-import qualified Data.Either as Either-import qualified Data.Word as Word-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature--newtype Signatures-  = MkSignatures [Signature.Signature]-  deriving (Eq, Show)--unwrap :: Signatures -> [Signature.Signature]-unwrap (MkSignatures signatures) = signatures--separator :: Word.Word8-separator = 0x20--parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures)-parse =-  fmap (fmap MkSignatures . Either.partitionEithers)-    . traverse Signature.parse-    . ByteString.split separator--render :: Signatures -> ByteString.ByteString-render =-  ByteString.intercalate (ByteString.singleton separator)-    . fmap Signature.render-    . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Signer.hs
@@ -1,49 +0,0 @@-module Signet.Unstable.Type.Signer where--import qualified Crypto.MAC.HMAC as Hmac-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.Secret as Secret-import qualified Signet.Unstable.Type.SecretKey as SecretKey-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature--data Signer-  = Asymmetric SecretKey.SecretKey-  | Symmetric Secret.Secret-  deriving (Eq, Show)--parse :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer-parse byteString = case SecretKey.parse byteString of-  Right secretKey -> Right $ Asymmetric secretKey-  Left _ -> case Secret.parse byteString of-    Right secret -> Right $ Symmetric secret-    Left _ -> Left $ InvalidSigner.MkInvalidSigner byteString--render :: Signer -> ByteString.ByteString-render signer = case signer of-  Asymmetric secretKey -> SecretKey.render secretKey-  Symmetric secret -> Secret.render secret--sign :: Signer -> Message.Message -> Signature.Signature-sign signer = case signer of-  Asymmetric secretKey -> Signature.Asymmetric . asymmetric secretKey-  Symmetric secret -> Signature.Symmetric . symmetric secret--asymmetric :: SecretKey.SecretKey -> Message.Message -> AsymmetricSignature.AsymmetricSignature-asymmetric secretKey =-  let sk = SecretKey.unwrap secretKey-      pk = Ed25519.toPublic sk-   in AsymmetricSignature.MkAsymmetricSignature-        . Ed25519.sign sk pk-        . Message.render--symmetric :: Secret.Secret -> Message.Message -> SymmetricSignature.SymmetricSignature-symmetric secret =-  SymmetricSignature.MkSymmetricSignature-    . Hmac.hmacGetDigest-    . Hmac.hmac (Secret.unwrap secret)-    . Message.render
− source/libraries/unstable/Signet/Unstable/Type/SymmetricSignature.hs
@@ -1,28 +0,0 @@-module Signet.Unstable.Type.SymmetricSignature where--import qualified Crypto.Hash as Hash-import qualified Data.ByteArray as ByteArray-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.Function as Function-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype SymmetricSignature-  = MkSymmetricSignature (Hash.Digest Hash.SHA256)-  deriving (Show)--instance Eq SymmetricSignature where-  (==) = Function.on ByteArray.constEq unwrap--unwrap :: SymmetricSignature -> Hash.Digest Hash.SHA256-unwrap (MkSymmetricSignature digest) = digest--parse :: ByteString.ByteString -> Either InvalidSymmetricSignature.InvalidSymmetricSignature SymmetricSignature-parse encoded = Maybe.note (InvalidSymmetricSignature.MkInvalidSymmetricSignature encoded) $ do-  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded-  MkSymmetricSignature <$> Hash.digestFromByteString (byteString :: ByteString.ByteString)--render :: SymmetricSignature -> ByteString.ByteString-render = Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Timestamp.hs
@@ -1,33 +0,0 @@-module Signet.Unstable.Type.Timestamp where--import qualified Data.ByteString as ByteString-import qualified Data.Text as Text-import qualified Data.Text.Encoding as Text-import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype Timestamp-  = MkTimestamp Time.UTCTime-  deriving (Eq, Show)--unwrap :: Timestamp -> Time.UTCTime-unwrap (MkTimestamp utcTime) = utcTime--format :: String-format = "%s"--parse :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp-parse byteString = Maybe.note (InvalidTimestamp.MkInvalidTimestamp byteString) $ do-  text <- Either.hush $ Text.decodeUtf8' byteString-  fmap MkTimestamp-    . Time.parseTimeM False Time.defaultTimeLocale format-    $ Text.unpack text--render :: Timestamp -> ByteString.ByteString-render =-  Text.encodeUtf8-    . Text.pack-    . Time.formatTime Time.defaultTimeLocale format-    . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Tolerance.hs
@@ -1,29 +0,0 @@-module Signet.Unstable.Type.Tolerance where--import qualified Control.Monad as Monad-import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Type.Timestamp as Timestamp--newtype Tolerance-  = MkTolerance Time.NominalDiffTime-  deriving (Eq, Show)--unwrap :: Tolerance -> Time.NominalDiffTime-unwrap (MkTolerance nominalDiffTime) = nominalDiffTime--typical :: Tolerance-typical = MkTolerance 300--check ::-  Tolerance ->-  Time.UTCTime ->-  Timestamp.Timestamp ->-  Either ToleranceException.ToleranceException ()-check tolerance utcTime timestamp = do-  let diff = Time.diffUTCTime utcTime $ Timestamp.unwrap timestamp-  let hi = unwrap tolerance-  let lo = negate hi-  Monad.when (lo > diff || diff > hi)-    . Left-    $ ToleranceException.MkToleranceException timestamp
− source/libraries/unstable/Signet/Unstable/Type/UnknownSignature.hs
@@ -1,10 +0,0 @@-module Signet.Unstable.Type.UnknownSignature where--import qualified Data.ByteString as ByteString--newtype UnknownSignature-  = MkUnknownSignature ByteString.ByteString-  deriving (Eq, Show)--unwrap :: UnknownSignature -> ByteString.ByteString-unwrap (MkUnknownSignature byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Type/Verifier.hs
@@ -1,75 +0,0 @@-module Signet.Unstable.Type.Verifier where--import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Data.List as List-import qualified Data.Maybe as Maybe-import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier-import qualified Signet.Unstable.Exception.VerificationException as VerificationException-import qualified Signet.Unstable.Extra.Maybe as Maybe-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.PublicKey as PublicKey-import qualified Signet.Unstable.Type.Secret as Secret-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.Signer as Signer-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature--data Verifier-  = Asymmetric PublicKey.PublicKey-  | Symmetric Secret.Secret-  deriving (Eq, Show)--parse :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier-parse byteString = case PublicKey.parse byteString of-  Right publicKey -> Right $ Asymmetric publicKey-  Left _ -> case Secret.parse byteString of-    Right secret -> Right $ Symmetric secret-    Left _ -> Left $ InvalidVerifier.MkInvalidVerifier byteString--render :: Verifier -> ByteString.ByteString-render verifier = case verifier of-  Asymmetric publicKey -> PublicKey.render publicKey-  Symmetric secret -> Secret.render secret--verify ::-  Verifier ->-  Message.Message ->-  Signatures.Signatures ->-  Either VerificationException.VerificationException Signature.Signature-verify verifier message =-  case verifier of-    Asymmetric publicKey -> fmap Signature.Asymmetric . asymmetric publicKey message-    Symmetric secret -> fmap Signature.Symmetric . symmetric secret message--asymmetric ::-  PublicKey.PublicKey ->-  Message.Message ->-  Signatures.Signatures ->-  Either VerificationException.VerificationException AsymmetricSignature.AsymmetricSignature-asymmetric publicKey message =-  let toAsymmetric signature = case signature of-        Signature.Asymmetric asymmetricSignature -> Just asymmetricSignature-        Signature.Symmetric _ -> Nothing-      pk = PublicKey.unwrap publicKey-      bs = Message.render message-   in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)-        . List.find (Ed25519.verify pk bs . AsymmetricSignature.unwrap)-        . Maybe.mapMaybe toAsymmetric-        . Signatures.unwrap--symmetric ::-  Secret.Secret ->-  Message.Message ->-  Signatures.Signatures ->-  Either VerificationException.VerificationException SymmetricSignature.SymmetricSignature-symmetric secret message =-  let toSymmetric signature = case signature of-        Signature.Asymmetric _ -> Nothing-        Signature.Symmetric symmetricSignature -> Just symmetricSignature-      expected = Signer.symmetric secret message-   in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)-        . List.find (expected ==)-        . Maybe.mapMaybe toSymmetric-        . Signatures.unwrap
+ source/library/Signet.hs view
@@ -0,0 +1,88 @@+module Signet+  ( -- * Verification+    Signet.Unstable.verifyWebhookText,+    Signet.Unstable.verifyWebhookByteString,+    Signet.Unstable.verifyWebhook,+    Signet.Unstable.verifyWebhookWith,++    -- * Signing+    Signet.Unstable.signWebhook,++    -- * Headers+    Signet.Unstable.Extra.Http.hWebhookId,+    Signet.Unstable.Extra.Http.hWebhookTimestamp,+    Signet.Unstable.Extra.Http.hWebhookSignature,++    -- * Types+    Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature (..),+    Signet.Unstable.Type.Id.Id (..),+    Signet.Unstable.parseId,+    Signet.Unstable.Type.Message.Message (..),+    Signet.Unstable.parseMessage,+    Signet.Unstable.Type.Payload.Payload (..),+    Signet.Unstable.Type.PublicKey.PublicKey (..),+    Signet.Unstable.Type.Secret.Secret (..),+    Signet.Unstable.Type.SecretKey.SecretKey (..),+    Signet.Unstable.Type.Signature.Signature (Signet.Unstable.AsymmetricSignature, Signet.Unstable.SymmetricSignature),+    Signet.Unstable.Type.Signatures.Signatures (..),+    Signet.Unstable.parseSignatures,+    Signet.Unstable.Type.Signer.Signer (Signet.Unstable.AsymmetricSigner, Signet.Unstable.SymmetricSigner),+    Signet.Unstable.parseSigner,+    Signet.Unstable.Type.SymmetricSignature.SymmetricSignature (..),+    Signet.Unstable.Type.Timestamp.Timestamp (..),+    Signet.Unstable.parseTimestamp,+    Signet.Unstable.Type.Tolerance.Tolerance (..),+    Signet.Unstable.typicalTolerance,+    Signet.Unstable.Type.UnknownSignature.UnknownSignature (..),+    Signet.Unstable.Type.Verifier.Verifier (Signet.Unstable.AsymmetricVerifier, Signet.Unstable.SymmetricVerifier),+    Signet.Unstable.parseVerifier,++    -- * Exceptions+    Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature (..),+    Signet.Unstable.Exception.InvalidId.InvalidId (..),+    Signet.Unstable.Exception.InvalidMessage.InvalidMessage (..),+    Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey (..),+    Signet.Unstable.Exception.InvalidSecret.InvalidSecret (..),+    Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey (..),+    Signet.Unstable.Exception.InvalidSignature.InvalidSignature (..),+    Signet.Unstable.Exception.InvalidSigner.InvalidSigner (..),+    Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature (..),+    Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp (..),+    Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier (..),+    Signet.Unstable.Exception.SignetException.SignetException (..),+    Signet.Unstable.Exception.ToleranceException.ToleranceException (..),+    Signet.Unstable.Exception.VerificationException.VerificationException (..),+  )+where++import qualified Signet.Unstable+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidId+import qualified Signet.Unstable.Exception.InvalidMessage+import qualified Signet.Unstable.Exception.InvalidPublicKey+import qualified Signet.Unstable.Exception.InvalidSecret+import qualified Signet.Unstable.Exception.InvalidSecretKey+import qualified Signet.Unstable.Exception.InvalidSignature+import qualified Signet.Unstable.Exception.InvalidSigner+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature+import qualified Signet.Unstable.Exception.InvalidTimestamp+import qualified Signet.Unstable.Exception.InvalidVerifier+import qualified Signet.Unstable.Exception.SignetException+import qualified Signet.Unstable.Exception.ToleranceException+import qualified Signet.Unstable.Exception.VerificationException+import qualified Signet.Unstable.Extra.Http+import qualified Signet.Unstable.Type.AsymmetricSignature+import qualified Signet.Unstable.Type.Id+import qualified Signet.Unstable.Type.Message+import qualified Signet.Unstable.Type.Payload+import qualified Signet.Unstable.Type.PublicKey+import qualified Signet.Unstable.Type.Secret+import qualified Signet.Unstable.Type.SecretKey+import qualified Signet.Unstable.Type.Signature+import qualified Signet.Unstable.Type.Signatures+import qualified Signet.Unstable.Type.Signer+import qualified Signet.Unstable.Type.SymmetricSignature+import qualified Signet.Unstable.Type.Timestamp+import qualified Signet.Unstable.Type.Tolerance+import qualified Signet.Unstable.Type.UnknownSignature+import qualified Signet.Unstable.Type.Verifier
+ source/library/Signet/Unstable.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE PatternSynonyms #-}++module Signet.Unstable where++import qualified Control.Monad.Catch as Exception+import qualified Control.Monad.IO.Class as MonadIO+import qualified Data.Bifunctor as Bifunctor+import qualified Data.ByteString as ByteString+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.InvalidId as InvalidId+import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp+import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier+import qualified Signet.Unstable.Exception.SignetException as SignetException+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Id as Id+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.Payload as Payload+import qualified Signet.Unstable.Type.PublicKey as PublicKey+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.SecretKey as SecretKey+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.Signer as Signer+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Timestamp as Timestamp+import qualified Signet.Unstable.Type.Tolerance as Tolerance+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature+import qualified Signet.Unstable.Type.Verifier as Verifier++-- | Verifies a webhook with 'Text.Text' values. This is a wrapper around+-- 'verifyWebhookByteString' that assumes all values are encoded as UTF-8.+verifyWebhookText ::+  (MonadIO.MonadIO m, Exception.MonadThrow m) =>+  -- | A 'Verifier.Verifier' for the webhook. Typically this will be+  -- @"whsec_..."@ or @"whpk_..."@.+  Text.Text ->+  -- | The webhook's unique 'Id.Id'. Typically this will come from the+  -- 'Signet.Unstable.Extra.Http.hWebhookId' header and look like @"msg_..."@.+  Text.Text ->+  -- | The webhook's 'Timestamp.Timestamp'. This is an integer number of+  -- seconds since the Unix epoch. Typically this will come from the+  -- 'Signet.Unstable.Extra.Http.hWebhookTimestamp' header. For example+  -- @"981173106"@ for @2001-02-03T04:05:06Z@.+  Text.Text ->+  -- | The webhook's raw 'Payload.Payload'. Typically this will be a JSON+  -- object like @{"event_type":"ping",...}@.+  Text.Text ->+  -- | The webhook's 'Signatures.Signatures'. Typically this will come from the+  -- 'Signet.Unstable.Extra.Http.hWebhookSignature' header and look like+  -- @"v1_..."@ or @"v1a_..."@.+  Text.Text ->+  m Signature.Signature+verifyWebhookText v i t p s =+  verifyWebhookByteString+    (Text.encodeUtf8 v)+    (Text.encodeUtf8 i)+    (Text.encodeUtf8 t)+    (Text.encodeUtf8 p)+    (Text.encodeUtf8 s)++-- | Verifies a webhook with 'ByteString.ByteString' values. This is a+-- wrapper around 'verifyWebhook'. See 'verifyWebhookText' for a description of+-- the arguments.+verifyWebhookByteString ::+  (MonadIO.MonadIO m, Exception.MonadThrow m) =>+  -- | 'Verifier.Verifier'+  ByteString.ByteString ->+  -- | 'Id.Id'+  ByteString.ByteString ->+  -- | 'Timestamp.Timestamp'+  ByteString.ByteString ->+  -- | 'Payload.Payload'+  ByteString.ByteString ->+  -- | 'Signatures.Signatures'+  ByteString.ByteString ->+  m Signature.Signature+verifyWebhookByteString v i t p s = do+  verifier <- Either.throw $ parseVerifier v+  id_ <- Either.throw $ parseId i+  timestamp <- Either.throw $ parseTimestamp t+  let payload = Payload.MkPayload p+  let message =+        Message.MkMessage+          { Message.id_ = id_,+            Message.timestamp = timestamp,+            Message.payload = payload+          }+  (_, signatures) <- Either.throw $ parseSignatures s+  verifyWebhook verifier message signatures++-- | Verifies a webhook. This is a wrapper around 'verifyWebhookWith' that uses+-- 'typicalTolerance' and the current time.+--+-- Throws an exception if the webhook is invalid.+verifyWebhook ::+  (MonadIO.MonadIO m, Exception.MonadThrow m) =>+  Verifier.Verifier ->+  Message.Message ->+  Signatures.Signatures ->+  m Signature.Signature+verifyWebhook verifier message signatures = do+  now <- MonadIO.liftIO Time.getCurrentTime+  Either.throw $ verifyWebhookWith typicalTolerance now verifier message signatures++-- | Verifies a webhook. This is the lowest-level function that gives you the+-- most control. If you're looking for something that's easier to use and+-- assumes some reasonable defaults, consider 'verifyWebhook'.+verifyWebhookWith ::+  -- | Often 'typicalTolerance'.+  Tolerance.Tolerance ->+  -- | Usually 'Time.getCurrentTime'.+  Time.UTCTime ->+  -- | See 'parseVerifier'.+  Verifier.Verifier ->+  -- | See 'parseMessage'. Or 'Message.MkMessage' along with 'parseId',+  -- 'parseTimestamp', and 'Payload.MkPayload'.+  Message.Message ->+  -- | See 'parseSignatures'.+  Signatures.Signatures ->+  Either SignetException.SignetException Signature.Signature+verifyWebhookWith tolerance now verifier message signatures = do+  Bifunctor.first SignetException.ToleranceException+    . Tolerance.check tolerance now+    $ Message.timestamp message+  Bifunctor.first SignetException.VerificationException $+    Verifier.verify verifier message signatures++-- | Alias for 'Tolerance.typical'.+typicalTolerance :: Tolerance.Tolerance+typicalTolerance = Tolerance.typical++-- | Alias for 'Verifier.parse'.+parseVerifier :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier.Verifier+parseVerifier = Verifier.parse++-- | Alias for 'Id.parse'.+parseId :: ByteString.ByteString -> Either InvalidId.InvalidId Id.Id+parseId = Id.parse++-- | Alias for 'Timestamp.parse'.+parseTimestamp :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp.Timestamp+parseTimestamp = Timestamp.parse++-- | Alias for 'Message.parse'.+parseMessage :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message.Message+parseMessage = Message.parse++-- | Alias for 'Signatures.parse'.+parseSignatures ::+  ByteString.ByteString ->+  Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures.Signatures)+parseSignatures = Signatures.parse++-- | Alias for 'Verifier.Asymmetric'.+pattern AsymmetricVerifier :: PublicKey.PublicKey -> Verifier.Verifier+pattern AsymmetricVerifier publicKey = Verifier.Asymmetric publicKey++-- | Alias for 'Verifier.Symmetric'.+pattern SymmetricVerifier :: Secret.Secret -> Verifier.Verifier+pattern SymmetricVerifier secret = Verifier.Symmetric secret++{-# COMPLETE AsymmetricVerifier, SymmetricVerifier #-}++-- | Alias for 'Signer.sign'.+signWebhook :: Signer.Signer -> Message.Message -> Signature.Signature+signWebhook = Signer.sign++-- | Alias for 'Signer.parse'.+parseSigner :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer.Signer+parseSigner = Signer.parse++-- | Alias for 'Signer.Asymmetric'.+pattern AsymmetricSigner :: SecretKey.SecretKey -> Signer.Signer+pattern AsymmetricSigner secretKey = Signer.Asymmetric secretKey++-- | Alias for 'Signer.Symmetric'.+pattern SymmetricSigner :: Secret.Secret -> Signer.Signer+pattern SymmetricSigner secret = Signer.Symmetric secret++{-# COMPLETE AsymmetricSigner, SymmetricSigner #-}++-- | Alias for 'Signature.Asymmetric'.+pattern AsymmetricSignature :: AsymmetricSignature.AsymmetricSignature -> Signature.Signature+pattern AsymmetricSignature asymmetricSignature = Signature.Asymmetric asymmetricSignature++-- | Alias for 'Signature.Symmetric'.+pattern SymmetricSignature :: SymmetricSignature.SymmetricSignature -> Signature.Signature+pattern SymmetricSignature symmetricSignature = Signature.Symmetric symmetricSignature++{-# COMPLETE AsymmetricSignature, SymmetricSignature #-}
+ source/library/Signet/Unstable/Exception/InvalidAsymmetricSignature.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidAsymmetricSignature where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidAsymmetricSignature+  = MkInvalidAsymmetricSignature ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidAsymmetricSignature where+  displayException = mappend "invalid asymmetric signature: " . show . unwrap++unwrap :: InvalidAsymmetricSignature -> ByteString.ByteString+unwrap (MkInvalidAsymmetricSignature byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidAsymmetricSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidAsymmetricSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidAsymmetricSignature" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidId.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidId where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidId+  = MkInvalidId ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidId where+  displayException = mappend "invalid ID: " . show . unwrap++unwrap :: InvalidId -> ByteString.ByteString+unwrap (MkInvalidId byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidIdTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidIdTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidId" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidMessage.hs view
@@ -0,0 +1,18 @@+module Signet.Unstable.Exception.InvalidMessage where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Exception.InvalidId as InvalidId+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp++data InvalidMessage+  = InvalidId InvalidId.InvalidId+  | InvalidTimestamp InvalidTimestamp.InvalidTimestamp+  deriving (Eq, Show)++instance Exception.Exception InvalidMessage where+  displayException invalidMessage =+    "invalid message: " <> case invalidMessage of+      InvalidId invalidId ->+        Exception.displayException invalidId+      InvalidTimestamp invalidTimestamp ->+        Exception.displayException invalidTimestamp
+ source/library/Signet/Unstable/Exception/InvalidMessageTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidMessageTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidMessage" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidPublicKey.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidPublicKey where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidPublicKey+  = MkInvalidPublicKey ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidPublicKey where+  displayException = mappend "invalid public key: " . show . unwrap++unwrap :: InvalidPublicKey -> ByteString.ByteString+unwrap (MkInvalidPublicKey byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidPublicKeyTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidPublicKeyTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidPublicKey" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidSecret.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSecret where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSecret+  = MkInvalidSecret ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidSecret where+  displayException = mappend "invalid secret: " . show . unwrap++unwrap :: InvalidSecret -> ByteString.ByteString+unwrap (MkInvalidSecret byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSecretKey.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSecretKey where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSecretKey+  = MkInvalidSecretKey ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidSecretKey where+  displayException = mappend "invalid secret key: " . show . unwrap++unwrap :: InvalidSecretKey -> ByteString.ByteString+unwrap (MkInvalidSecretKey byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSecretKeyTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSecretKeyTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSecretKey" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidSecretTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSecretTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSecret" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidSignature.hs view
@@ -0,0 +1,18 @@+module Signet.Unstable.Exception.InvalidSignature where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature++data InvalidSignature+  = InvalidAsymmetricSignature InvalidAsymmetricSignature.InvalidAsymmetricSignature+  | InvalidSymmetricSignature InvalidSymmetricSignature.InvalidSymmetricSignature+  deriving (Eq, Show)++instance Exception.Exception InvalidSignature where+  displayException invalidSignature =+    "invalid signature: " <> case invalidSignature of+      InvalidAsymmetricSignature invalidAsymmetricSignature ->+        Exception.displayException invalidAsymmetricSignature+      InvalidSymmetricSignature invalidSymmetricSignature ->+        Exception.displayException invalidSymmetricSignature
+ source/library/Signet/Unstable/Exception/InvalidSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSignature" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidSigner.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSigner where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSigner+  = MkInvalidSigner ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidSigner where+  displayException = mappend "invalid signer: " . show . unwrap++unwrap :: InvalidSigner -> ByteString.ByteString+unwrap (MkInvalidSigner byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSignerTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSignerTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSigner" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidSymmetricSignature.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSymmetricSignature where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSymmetricSignature+  = MkInvalidSymmetricSignature ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidSymmetricSignature where+  displayException = mappend "invalid symmetric signature: " . show . unwrap++unwrap :: InvalidSymmetricSignature -> ByteString.ByteString+unwrap (MkInvalidSymmetricSignature byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSymmetricSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSymmetricSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSymmetricSignature" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidTimestamp.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidTimestamp where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidTimestamp+  = MkInvalidTimestamp ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidTimestamp where+  displayException = mappend "invalid timestamp: " . show . unwrap++unwrap :: InvalidTimestamp -> ByteString.ByteString+unwrap (MkInvalidTimestamp byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidTimestampTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidTimestampTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidTimestamp" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/InvalidVerifier.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidVerifier where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidVerifier+  = MkInvalidVerifier ByteString.ByteString+  deriving (Eq, Show)++instance Exception.Exception InvalidVerifier where+  displayException = mappend "invalid verifier: " . show . unwrap++unwrap :: InvalidVerifier -> ByteString.ByteString+unwrap (MkInvalidVerifier byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidVerifierTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidVerifierTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidVerifier" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/SignetException.hs view
@@ -0,0 +1,18 @@+module Signet.Unstable.Exception.SignetException where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Exception.VerificationException as VerificationException++data SignetException+  = ToleranceException ToleranceException.ToleranceException+  | VerificationException VerificationException.VerificationException+  deriving (Eq, Show)++instance Exception.Exception SignetException where+  displayException signetException =+    "failed to verify webhook: " <> case signetException of+      ToleranceException toleranceException ->+        Exception.displayException toleranceException+      VerificationException verificationException ->+        Exception.displayException verificationException
+ source/library/Signet/Unstable/Exception/SignetExceptionTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.SignetExceptionTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.SignetException" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/ToleranceException.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.ToleranceException where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Type.Timestamp as Timestamp++newtype ToleranceException+  = MkToleranceException Timestamp.Timestamp+  deriving (Eq, Show)++instance Exception.Exception ToleranceException where+  displayException = mappend "timestamp out of tolerance: " . show . unwrap++unwrap :: ToleranceException -> Timestamp.Timestamp+unwrap (MkToleranceException timestamp) = timestamp
+ source/library/Signet/Unstable/Exception/ToleranceExceptionTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.ToleranceExceptionTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.ToleranceException" $ do+  pure ()
+ source/library/Signet/Unstable/Exception/VerificationException.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.VerificationException where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Type.Id as Id++newtype VerificationException+  = MkVerificationException Id.Id+  deriving (Eq, Show)++instance Exception.Exception VerificationException where+  displayException = mappend "verification failed: " . show . unwrap++unwrap :: VerificationException -> Id.Id+unwrap (MkVerificationException id_) = id_
+ source/library/Signet/Unstable/Exception/VerificationExceptionTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.VerificationExceptionTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.VerificationException" $ do+  pure ()
+ source/library/Signet/Unstable/Extra/Either.hs view
@@ -0,0 +1,9 @@+module Signet.Unstable.Extra.Either where++import qualified Control.Monad.Catch as Exception++hush :: Either x a -> Maybe a+hush = either (const Nothing) Just++throw :: (Exception.Exception e, Exception.MonadThrow m) => Either e a -> m a+throw = either Exception.throwM pure
+ source/library/Signet/Unstable/Extra/EitherTest.hs view
@@ -0,0 +1,30 @@+module Signet.Unstable.Extra.EitherTest where++import qualified Control.Monad.Catch as Exception+import qualified Data.Void as Void+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Extra.Either" $ do+  Test.describe test "hush" $ do+    Test.it test "works with Left" $ do+      Test.assertEq test (Either.hush (Left () :: Either () Void.Void)) Nothing++    Test.it test "works with Right" $ do+      Test.assertEq test (Either.hush (Right () :: Either Void.Void ())) (Just ())++  Test.describe test "throw" $ do+    Test.it test "throws an exception for Left" $ do+      result <- Exception.try . Either.throw $ Left MkTestException+      Test.assertEq test result (Left MkTestException :: Either TestException Void.Void)++    Test.it test "returns the value for Right" $ do+      value <- Either.throw (Right () :: Either Void.Void ())+      Test.assertEq test value ()++data TestException+  = MkTestException+  deriving (Eq, Show)++instance Exception.Exception TestException
+ source/library/Signet/Unstable/Extra/Http.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Extra.Http where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.CaseInsensitive as CI+import qualified Network.HTTP.Types as Http++hWebhookId :: Http.HeaderName+hWebhookId = CI.mk $ Ascii.pack "webhook-id"++hWebhookSignature :: Http.HeaderName+hWebhookSignature = CI.mk $ Ascii.pack "webhook-signature"++hWebhookTimestamp :: Http.HeaderName+hWebhookTimestamp = CI.mk $ Ascii.pack "webhook-timestamp"
+ source/library/Signet/Unstable/Extra/HttpTest.hs view
@@ -0,0 +1,20 @@+module Signet.Unstable.Extra.HttpTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.CaseInsensitive as CI+import qualified Signet.Unstable.Extra.Http as Http+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Extra.Http" $ do+  Test.describe test "hWebhookId" $ do+    Test.it test "creates the correct header name" $ do+      Test.assertEq test Http.hWebhookId (CI.mk (Ascii.pack "webhook-id"))++  Test.describe test "hWebhookSignature" $ do+    Test.it test "creates the correct header name" $ do+      Test.assertEq test Http.hWebhookSignature (CI.mk (Ascii.pack "webhook-signature"))++  Test.describe test "hWebhookTimestamp" $ do+    Test.it test "creates the correct header name" $ do+      Test.assertEq test Http.hWebhookTimestamp (CI.mk (Ascii.pack "webhook-timestamp"))
+ source/library/Signet/Unstable/Extra/Maybe.hs view
@@ -0,0 +1,4 @@+module Signet.Unstable.Extra.Maybe where++note :: e -> Maybe a -> Either e a+note = flip maybe Right . Left
+ source/library/Signet/Unstable/Extra/MaybeTest.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Extra.MaybeTest where++import qualified Data.Void as Void+import qualified Signet.Unstable.Extra.Maybe as Maybe+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Extra.Maybe" $ do+  Test.describe test "note" $ do+    Test.it test "works with nothing" $ do+      Test.assertEq test (Maybe.note () (Nothing :: Maybe Void.Void)) (Left ())++    Test.it test "works with just" $ do+      Test.assertEq test (Maybe.note () (Just True)) (Right True)
+ source/library/Signet/Unstable/Type/AsymmetricSignature.hs view
@@ -0,0 +1,28 @@+module Signet.Unstable.Type.AsymmetricSignature where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype AsymmetricSignature+  = MkAsymmetricSignature Ed25519.Signature+  deriving (Eq, Show)++unwrap :: AsymmetricSignature -> Ed25519.Signature+unwrap (MkAsymmetricSignature signature) = signature++parse ::+  ByteString.ByteString ->+  Either InvalidAsymmetricSignature.InvalidAsymmetricSignature AsymmetricSignature+parse encoded = Maybe.note (InvalidAsymmetricSignature.MkInvalidAsymmetricSignature encoded) $ do+  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+  fmap MkAsymmetricSignature+    . Error.maybeCryptoError+    $ Ed25519.signature (byteString :: ByteString.ByteString)++render :: AsymmetricSignature -> ByteString.ByteString+render = Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/AsymmetricSignatureTest.hs view
@@ -0,0 +1,26 @@+module Signet.Unstable.Type.AsymmetricSignatureTest where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.AsymmetricSignature" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid input" $ do+      let byteString = Ascii.pack "invalid"+      let result = AsymmetricSignature.parse byteString+      Test.assertEq test result (Left $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString)++    Test.it test "succeeds with valid input" $ do+      let result = AsymmetricSignature.parse $ Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="+      signature <- Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+      Test.assertEq test result (Right $ AsymmetricSignature.MkAsymmetricSignature signature)++  Test.describe test "render" $ do+    Test.it test "works" $ do+      asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+      Test.assertEq test (AsymmetricSignature.render asymmetricSignature) (Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==")
+ source/library/Signet/Unstable/Type/Id.hs view
@@ -0,0 +1,26 @@+module Signet.Unstable.Type.Id where++import qualified Control.Monad as Monad+import qualified Data.ByteString as ByteString+import qualified Data.Word as Word+import qualified Signet.Unstable.Exception.InvalidId as InvalidId++newtype Id+  = MkId ByteString.ByteString+  deriving (Eq, Show)++unwrap :: Id -> ByteString.ByteString+unwrap (MkId byteString) = byteString++separator :: Word.Word8+separator = 0x2e++parse :: ByteString.ByteString -> Either InvalidId.InvalidId Id+parse byteString = do+  Monad.when (ByteString.any (== separator) byteString)+    . Left+    $ InvalidId.MkInvalidId byteString+  Right $ MkId byteString++render :: Id -> ByteString.ByteString+render = unwrap
+ source/library/Signet/Unstable/Type/IdTest.hs view
@@ -0,0 +1,25 @@+module Signet.Unstable.Type.IdTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidId as InvalidId+import qualified Signet.Unstable.Type.Id as Id+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Id" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with input containing separator" $ do+      let byteString = Ascii.pack "invalid.id"+      let result = Id.parse byteString+      Test.assertEq test result (Left $ InvalidId.MkInvalidId byteString)++    Test.it test "succeeds with valid input" $ do+      let byteString = Ascii.pack "valid-id"+      let result = Id.parse byteString+      Test.assertEq test result (Right $ Id.MkId byteString)++  Test.describe test "render" $ do+    Test.it test "returns the original ByteString" $ do+      let byteString = Ascii.pack "valid-id"+      let id_ = Id.MkId byteString+      Test.assertEq test (Id.render id_) byteString
+ source/library/Signet/Unstable/Type/Message.hs view
@@ -0,0 +1,36 @@+module Signet.Unstable.Type.Message where++import qualified Data.Bifunctor as Bifunctor+import qualified Data.ByteString as ByteString+import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage+import qualified Signet.Unstable.Type.Id as Id+import qualified Signet.Unstable.Type.Payload as Payload+import qualified Signet.Unstable.Type.Timestamp as Timestamp++data Message = MkMessage+  { id_ :: Id.Id,+    timestamp :: Timestamp.Timestamp,+    payload :: Payload.Payload+  }+  deriving (Eq, Show)++parse :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message+parse x = do+  let (rawId, y) = ByteString.break (== Id.separator) x+  theId <- Bifunctor.first InvalidMessage.InvalidId $ Id.parse rawId+  let (rawTimestamp, z) =+        ByteString.break (== Id.separator) $+          ByteString.drop 1 y+  theTimestamp <-+    Bifunctor.first InvalidMessage.InvalidTimestamp $+      Timestamp.parse rawTimestamp+  let thePayload = Payload.MkPayload $ ByteString.drop 1 z+  pure MkMessage {id_ = theId, timestamp = theTimestamp, payload = thePayload}++render :: Message -> ByteString.ByteString+render message =+  Id.render (id_ message)+    <> ByteString.singleton Id.separator+    <> Timestamp.render (timestamp message)+    <> ByteString.singleton Id.separator+    <> Payload.unwrap (payload message)
+ source/library/Signet/Unstable/Type/MessageTest.hs view
@@ -0,0 +1,49 @@+module Signet.Unstable.Type.MessageTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.Id as Id+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.Payload as Payload+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Timestamp as Timestamp++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Message" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid timestamp" $ do+      let timestamp = Ascii.pack "invalid"+      let byteString = Ascii.pack "i." <> timestamp <> Ascii.pack ".p"+      let result = Message.parse byteString+      Test.assertEq test result (Left (InvalidMessage.InvalidTimestamp $ InvalidTimestamp.MkInvalidTimestamp timestamp))++    Test.it test "succeeds with valid input" $ do+      let result = Message.parse $ Ascii.pack "i.0.p"+      id_ <- Either.throw . Id.parse $ Ascii.pack "i"+      timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"+      let payload = Payload.MkPayload $ Ascii.pack "p"+      Test.assertEq+        test+        result+        ( Right+            Message.MkMessage+              { Message.id_ = id_,+                Message.timestamp = timestamp,+                Message.payload = payload+              }+        )++  Test.describe test "render" $ do+    Test.it test "returns the correct ByteString representation" $ do+      id_ <- Either.throw . Id.parse $ Ascii.pack "i"+      timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"+      let payload = Payload.MkPayload $ Ascii.pack "p"+      let message =+            Message.MkMessage+              { Message.id_ = id_,+                Message.timestamp = timestamp,+                Message.payload = payload+              }+      Test.assertEq test (Message.render message) (Ascii.pack "i.0.p")
+ source/library/Signet/Unstable/Type/Payload.hs view
@@ -0,0 +1,10 @@+module Signet.Unstable.Type.Payload where++import qualified Data.ByteString as ByteString++newtype Payload+  = MkPayload ByteString.ByteString+  deriving (Eq, Show)++unwrap :: Payload -> ByteString.ByteString+unwrap (MkPayload byteString) = byteString
+ source/library/Signet/Unstable/Type/PayloadTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Type.PayloadTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Payload" $ do+  pure ()
+ source/library/Signet/Unstable/Type/PublicKey.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.PublicKey where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype PublicKey+  = MkPublicKey Ed25519.PublicKey+  deriving (Eq, Show)++unwrap :: PublicKey -> Ed25519.PublicKey+unwrap (MkPublicKey publicKey) = publicKey++prefix :: ByteString.ByteString+prefix = Ascii.pack "whpk_"++parse :: ByteString.ByteString -> Either InvalidPublicKey.InvalidPublicKey PublicKey+parse prefixed = Maybe.note (InvalidPublicKey.MkInvalidPublicKey prefixed) $ do+  encoded <- ByteString.stripPrefix prefix prefixed+  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+  fmap MkPublicKey+    . Error.maybeCryptoError+    $ Ed25519.publicKey (byteString :: ByteString.ByteString)++render :: PublicKey -> ByteString.ByteString+render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/PublicKeyTest.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.PublicKeyTest where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey+import qualified Signet.Unstable.Type.PublicKey as PublicKey+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.PublicKey" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid prefix" $ do+      let byteString = Ascii.pack "invalid"+      let result = PublicKey.parse byteString+      Test.assertEq test result (Left (InvalidPublicKey.MkInvalidPublicKey byteString))++    Test.it test "fails with invalid input" $ do+      let byteString = Ascii.pack "whpk_invalid"+      let result = PublicKey.parse byteString+      Test.assertEq test result (Left (InvalidPublicKey.MkInvalidPublicKey byteString))++    Test.it test "succeeds with valid input" $ do+      let result = PublicKey.parse $ Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+      publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+      Test.assertEq test result (Right publicKey)++  Test.describe test "render" $ do+    Test.it test "works" $ do+      publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+      Test.assertEq test (PublicKey.render publicKey) (Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU=")
+ source/library/Signet/Unstable/Type/Secret.hs view
@@ -0,0 +1,27 @@+module Signet.Unstable.Type.Secret where++import qualified Data.ByteArray as ByteArray+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype Secret+  = MkSecret ByteArray.ScrubbedBytes+  deriving (Eq, Show)++unwrap :: Secret -> ByteArray.ScrubbedBytes+unwrap (MkSecret scrubbedBytes) = scrubbedBytes++prefix :: ByteString.ByteString+prefix = Ascii.pack "whsec_"++parse :: ByteString.ByteString -> Either InvalidSecret.InvalidSecret Secret+parse prefixed = Maybe.note (InvalidSecret.MkInvalidSecret prefixed) $ do+  encoded <- ByteString.stripPrefix prefix prefixed+  fmap MkSecret . Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded++render :: Secret -> ByteString.ByteString+render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/SecretKey.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.SecretKey where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype SecretKey+  = MkSecretKey Ed25519.SecretKey+  deriving (Eq, Show)++unwrap :: SecretKey -> Ed25519.SecretKey+unwrap (MkSecretKey secretKey) = secretKey++prefix :: ByteString.ByteString+prefix = Ascii.pack "whsk_"++parse :: ByteString.ByteString -> Either InvalidSecretKey.InvalidSecretKey SecretKey+parse prefixed = Maybe.note (InvalidSecretKey.MkInvalidSecretKey prefixed) $ do+  encoded <- ByteString.stripPrefix prefix prefixed+  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+  fmap MkSecretKey+    . Error.maybeCryptoError+    $ Ed25519.secretKey (byteString :: ByteString.ByteString)++render :: SecretKey -> ByteString.ByteString+render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/SecretKeyTest.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.SecretKeyTest where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey+import qualified Signet.Unstable.Type.SecretKey as SecretKey+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.SecretKey" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid prefix" $ do+      let byteString = Ascii.pack "invalid"+      let result = SecretKey.parse byteString+      Test.assertEq test result (Left (InvalidSecretKey.MkInvalidSecretKey byteString))++    Test.it test "fails with invalid input" $ do+      let byteString = Ascii.pack "whsk_invalid"+      let result = SecretKey.parse byteString+      Test.assertEq test result (Left (InvalidSecretKey.MkInvalidSecretKey byteString))++    Test.it test "succeeds with valid input" $ do+      let result = SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+      secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+      Test.assertEq test result (Right secretKey)++  Test.describe test "render" $ do+    Test.it test "works" $ do+      secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+      Test.assertEq test (SecretKey.render secretKey) (Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU=")
+ source/library/Signet/Unstable/Type/SecretTest.hs view
@@ -0,0 +1,30 @@+module Signet.Unstable.Type.SecretTest where++import qualified Data.ByteArray as ByteArray+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Secret" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid prefix" $ do+      let byteString = Ascii.pack "invalid"+      let result = Secret.parse byteString+      Test.assertEq test result (Left (InvalidSecret.MkInvalidSecret byteString))++    Test.it test "fails with invalid input" $ do+      let byteString = Ascii.pack "whsec_invalid"+      let result = Secret.parse byteString+      Test.assertEq test result (Left (InvalidSecret.MkInvalidSecret byteString))++    Test.it test "succeeds with valid input" $ do+      let result = Secret.parse $ Ascii.pack "whsec_MDEyMzQ1Njc4OQ=="+      let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"+      Test.assertEq test result (Right secret)++  Test.describe test "render" $ do+    Test.it test "works" $ do+      let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"+      Test.assertEq test (Secret.render secret) (Ascii.pack "whsec_MDEyMzQ1Njc4OQ==")
+ source/library/Signet/Unstable/Type/Signature.hs view
@@ -0,0 +1,49 @@+module Signet.Unstable.Type.Signature where++import qualified Data.Bifunctor as Bifunctor+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Data.Word as Word+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++data Signature+  = Asymmetric AsymmetricSignature.AsymmetricSignature+  | Symmetric SymmetricSignature.SymmetricSignature+  deriving (Eq, Show)++separator :: Word.Word8+separator = 0x2c++asymmetricPrefix :: ByteString.ByteString+asymmetricPrefix = Ascii.pack "v1a"++symmetricPrefix :: ByteString.ByteString+symmetricPrefix = Ascii.pack "v1"++parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature (Either UnknownSignature.UnknownSignature Signature)+parse prefixed = do+  let (prefix, rest) = ByteString.break (== separator) prefixed+  case ByteString.drop 1 rest of+    byteString+      | prefix == asymmetricPrefix ->+          Bifunctor.bimap InvalidSignature.InvalidAsymmetricSignature (Right . Asymmetric) $+            AsymmetricSignature.parse byteString+      | prefix == symmetricPrefix ->+          Bifunctor.bimap InvalidSignature.InvalidSymmetricSignature (Right . Symmetric) $+            SymmetricSignature.parse byteString+    _ -> Right . Left $ UnknownSignature.MkUnknownSignature prefixed++render :: Signature -> ByteString.ByteString+render signature =+  case signature of+    Asymmetric asymmetricSignature ->+      asymmetricPrefix+        <> ByteString.singleton separator+        <> AsymmetricSignature.render asymmetricSignature+    Symmetric symmetricSignature ->+      symmetricPrefix+        <> ByteString.singleton separator+        <> SymmetricSignature.render symmetricSignature
+ source/library/Signet/Unstable/Type/SignatureTest.hs view
@@ -0,0 +1,52 @@+module Signet.Unstable.Type.SignatureTest where++import qualified Crypto.Error as Error+import qualified Crypto.Hash as Hash+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Signature" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid asymmetric signature" $ do+      let byteString = Ascii.pack "invalid"+      let result = Signature.parse $ Ascii.pack "v1a," <> byteString+      Test.assertEq test result (Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString))++    Test.it test "fails with invalid symmetric signature" $ do+      let byteString = Ascii.pack "invalid"+      let result = Signature.parse $ Ascii.pack "v1," <> byteString+      Test.assertEq test result (Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString))++    Test.it test "returns unknown signature with unrecognized prefix" $ do+      let byteString = Ascii.pack "unknown"+      let result = Signature.parse byteString+      Test.assertEq test result (Right (Left $ UnknownSignature.MkUnknownSignature byteString))++    Test.it test "succeeds with valid asymmetric signature" $ do+      let byteString = Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="+      signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+      Test.assertEq test (Signature.parse byteString) (Right (Right signature))++    Test.it test "succeeds with valid symmetric signature" $ do+      let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="+      let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      Test.assertEq test (Signature.parse byteString) (Right (Right signature))++  Test.describe test "render" $ do+    Test.it test "renders asymmetric signature correctly" $ do+      signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+      Test.assertEq test (Signature.render signature) (Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==")++    Test.it test "renders symmetric signature correctly" $ do+      let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      Test.assertEq test (Signature.render signature) (Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
+ source/library/Signet/Unstable/Type/Signatures.hs view
@@ -0,0 +1,30 @@+module Signet.Unstable.Type.Signatures where++import qualified Data.ByteString as ByteString+import qualified Data.Either as Either+import qualified Data.Word as Word+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++newtype Signatures+  = MkSignatures [Signature.Signature]+  deriving (Eq, Show)++unwrap :: Signatures -> [Signature.Signature]+unwrap (MkSignatures signatures) = signatures++separator :: Word.Word8+separator = 0x20++parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures)+parse =+  fmap (fmap MkSignatures . Either.partitionEithers)+    . traverse Signature.parse+    . ByteString.split separator++render :: Signatures -> ByteString.ByteString+render =+  ByteString.intercalate (ByteString.singleton separator)+    . fmap Signature.render+    . unwrap
+ source/library/Signet/Unstable/Type/SignaturesTest.hs view
@@ -0,0 +1,71 @@+module Signet.Unstable.Type.SignaturesTest where++import qualified Crypto.Error as Error+import qualified Crypto.Hash as Hash+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Signatures" $ do+  Test.describe test "parse" $ do+    Test.it test "succeeds with no signatures" $ do+      Test.assertEq test (Signatures.parse ByteString.empty) (Right ([], Signatures.MkSignatures []))++    Test.it test "succeeds with one signature" $ do+      let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="+      Test.assertEq test (Signatures.parse byteString) (Right ([], Signatures.MkSignatures [signature]))++    Test.it test "succeeds with many signatures" $ do+      let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+      let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="+      let signatures =+            Signatures.MkSignatures+              [ Signature.Symmetric symmetricSignature,+                Signature.Asymmetric asymmetricSignature+              ]+      Test.assertEq test (Signatures.parse byteString) (Right ([], signatures))++    Test.it test "fails with an invalid symmetric signature" $ do+      let x = Ascii.pack "invalid"+      let byteString = Ascii.pack "v1," <> x+      Test.assertEq test (Signatures.parse byteString) (Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature x))++    Test.it test "fails with an invalid asymmetric signature" $ do+      let x = Ascii.pack "invalid"+      let byteString = Ascii.pack "v1a," <> x+      Test.assertEq test (Signatures.parse byteString) (Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature x))++    Test.it test "succeeds with an unknown signature" $ do+      let byteString = Ascii.pack "unknown"+      Test.assertEq test (Signatures.parse byteString) (Right ([UnknownSignature.MkUnknownSignature byteString], Signatures.MkSignatures []))++  Test.describe test "render" $ do+    Test.it test "renders no signatures" $ do+      let signatures = Signatures.MkSignatures []+      Test.assertEq test (Signatures.render signatures) ByteString.empty++    Test.it test "renders one signature" $ do+      let signatures = Signatures.MkSignatures . pure . Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      Test.assertEq test (Signatures.render signatures) (Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")++    Test.it test "renders many signatures" $ do+      let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+      let signatures =+            Signatures.MkSignatures+              [ Signature.Symmetric symmetricSignature,+                Signature.Asymmetric asymmetricSignature+              ]+      Test.assertEq test (Signatures.render signatures) (Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==")
+ source/library/Signet/Unstable/Type/Signer.hs view
@@ -0,0 +1,49 @@+module Signet.Unstable.Type.Signer where++import qualified Crypto.MAC.HMAC as Hmac+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.SecretKey as SecretKey+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature++data Signer+  = Asymmetric SecretKey.SecretKey+  | Symmetric Secret.Secret+  deriving (Eq, Show)++parse :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer+parse byteString = case SecretKey.parse byteString of+  Right secretKey -> Right $ Asymmetric secretKey+  Left _ -> case Secret.parse byteString of+    Right secret -> Right $ Symmetric secret+    Left _ -> Left $ InvalidSigner.MkInvalidSigner byteString++render :: Signer -> ByteString.ByteString+render signer = case signer of+  Asymmetric secretKey -> SecretKey.render secretKey+  Symmetric secret -> Secret.render secret++sign :: Signer -> Message.Message -> Signature.Signature+sign signer = case signer of+  Asymmetric secretKey -> Signature.Asymmetric . asymmetric secretKey+  Symmetric secret -> Signature.Symmetric . symmetric secret++asymmetric :: SecretKey.SecretKey -> Message.Message -> AsymmetricSignature.AsymmetricSignature+asymmetric secretKey =+  let sk = SecretKey.unwrap secretKey+      pk = Ed25519.toPublic sk+   in AsymmetricSignature.MkAsymmetricSignature+        . Ed25519.sign sk pk+        . Message.render++symmetric :: Secret.Secret -> Message.Message -> SymmetricSignature.SymmetricSignature+symmetric secret =+  SymmetricSignature.MkSymmetricSignature+    . Hmac.hmacGetDigest+    . Hmac.hmac (Secret.unwrap secret)+    . Message.render
+ source/library/Signet/Unstable/Type/SignerTest.hs view
@@ -0,0 +1,75 @@+module Signet.Unstable.Type.SignerTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.SecretKey as SecretKey+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signer as Signer+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Signer" $ do+  Test.describe test "parse" $ do+    Test.it test "succeeds with a valid secret key" $ do+      let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+      let actual = Signer.parse byteString+      secretKey <- Either.throw $ SecretKey.parse byteString+      Test.assertEq test actual (Right (Signer.Asymmetric secretKey))++    Test.it test "succeeds with a valid secret" $ do+      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      let actual = Signer.parse byteString+      secret <- Either.throw $ Secret.parse byteString+      Test.assertEq test actual (Right (Signer.Symmetric secret))++    Test.it test "fails with invalid input" $ do+      let byteString = Ascii.pack "invalid"+      let actual = Signer.parse byteString+      Test.assertEq test actual (Left (InvalidSigner.MkInvalidSigner byteString))++  Test.describe test "render" $ do+    Test.it test "works with a secret key" $ do+      let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+      secretKey <- Either.throw . SecretKey.parse $ byteString+      Test.assertEq test (Signer.render (Signer.Asymmetric secretKey)) byteString++    Test.it test "works with a secret" $ do+      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      secret <- Either.throw . Secret.parse $ byteString+      Test.assertEq test (Signer.render (Signer.Symmetric secret)) byteString++  Test.describe test "sign" $ do+    Test.it test "works with asymmetric" $ do+      signer <- Either.throw . Signer.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      let actual = Signer.sign signer message+      Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+      Test.assertEq test actual expected++    Test.it test "works with symmetric" $ do+      signer <- Either.throw . Signer.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      let actual = Signer.sign signer message+      Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      Test.assertEq test actual expected++  Test.describe test "asymmetric" $ do+    Test.it test "creates correct asymmetric signature" $ do+      secretKey <- Either.throw . SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      let actual = Signer.asymmetric secretKey message+      expected <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+      Test.assertEq test actual expected++  Test.describe test "symmetric" $ do+    Test.it test "creates correct symmetric signature" $ do+      secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      let actual = Signer.symmetric secret message+      expected <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      Test.assertEq test actual expected
+ source/library/Signet/Unstable/Type/SymmetricSignature.hs view
@@ -0,0 +1,28 @@+module Signet.Unstable.Type.SymmetricSignature where++import qualified Crypto.Hash as Hash+import qualified Data.ByteArray as ByteArray+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.Function as Function+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype SymmetricSignature+  = MkSymmetricSignature (Hash.Digest Hash.SHA256)+  deriving (Show)++instance Eq SymmetricSignature where+  (==) = Function.on ByteArray.constEq unwrap++unwrap :: SymmetricSignature -> Hash.Digest Hash.SHA256+unwrap (MkSymmetricSignature digest) = digest++parse :: ByteString.ByteString -> Either InvalidSymmetricSignature.InvalidSymmetricSignature SymmetricSignature+parse encoded = Maybe.note (InvalidSymmetricSignature.MkInvalidSymmetricSignature encoded) $ do+  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+  MkSymmetricSignature <$> Hash.digestFromByteString (byteString :: ByteString.ByteString)++render :: SymmetricSignature -> ByteString.ByteString+render = Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/SymmetricSignatureTest.hs view
@@ -0,0 +1,26 @@+module Signet.Unstable.Type.SymmetricSignatureTest where++import qualified Crypto.Hash as Hash+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.SymmetricSignature" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid symmetric signature" $ do+      let byteString = Ascii.pack "invalid"+      let result = SymmetricSignature.parse byteString+      Test.assertEq test result (Left (InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString))++    Test.it test "succeeds with valid symmetric signature" $ do+      let byteString = Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="+      let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      Test.assertEq test (SymmetricSignature.parse byteString) (Right signature)++  Test.describe test "render" $ do+    Test.it test "renders symmetric signature correctly" $ do+      let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+      Test.assertEq test (SymmetricSignature.render signature) (Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
+ source/library/Signet/Unstable/Type/Test.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE RankNTypes #-}++module Signet.Unstable.Type.Test where++import qualified Control.Monad as Monad+import qualified Data.Void as Void+import qualified GHC.Stack as Stack++data Test spec = MkTest+  { assertFailure :: (Stack.HasCallStack) => String -> IO Void.Void,+    describe :: String -> spec () -> spec (),+    it :: String -> IO () -> spec ()+  }++assertEq :: (Stack.HasCallStack, Eq a, Show a) => Test tree -> a -> a -> IO ()+assertEq test expected actual =+  Monad.when (expected /= actual)+    . Monad.void+    . assertFailure test+    $ "expected " <> show expected <> " but got " <> show actual
+ source/library/Signet/Unstable/Type/Timestamp.hs view
@@ -0,0 +1,33 @@+module Signet.Unstable.Type.Timestamp where++import qualified Data.ByteString as ByteString+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype Timestamp+  = MkTimestamp Time.UTCTime+  deriving (Eq, Show)++unwrap :: Timestamp -> Time.UTCTime+unwrap (MkTimestamp utcTime) = utcTime++format :: String+format = "%s"++parse :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp+parse byteString = Maybe.note (InvalidTimestamp.MkInvalidTimestamp byteString) $ do+  text <- Either.hush $ Text.decodeUtf8' byteString+  fmap MkTimestamp+    . Time.parseTimeM False Time.defaultTimeLocale format+    $ Text.unpack text++render :: Timestamp -> ByteString.ByteString+render =+  Text.encodeUtf8+    . Text.pack+    . Time.formatTime Time.defaultTimeLocale format+    . unwrap
+ source/library/Signet/Unstable/Type/TimestampTest.hs view
@@ -0,0 +1,32 @@+module Signet.Unstable.Type.TimestampTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Timestamp as Timestamp++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Timestamp" $ do+  Test.describe test "parse" $ do+    Test.it test "fails with invalid timestamp format" $ do+      let byteString = Ascii.pack "invalid-timestamp"+      let result = Timestamp.parse byteString+      Test.assertEq test result (Left (InvalidTimestamp.MkInvalidTimestamp byteString))++    Test.it test "succeeds with valid timestamp format" $ do+      let byteString = Ascii.pack "1617235200"+      let result = Timestamp.parse byteString+      case result of+        Right timestamp -> do+          let utcTime = Timestamp.unwrap timestamp+          let expectedTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0+          Test.assertEq test utcTime expectedTime+        Left _ -> fail "Expected Right but got Left"++  Test.describe test "render" $ do+    Test.it test "returns the correct ByteString representation" $ do+      let utcTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0+      let timestamp = Timestamp.MkTimestamp utcTime+      let expected = Ascii.pack "1617235200"+      Test.assertEq test (Timestamp.render timestamp) expected
+ source/library/Signet/Unstable/Type/Tolerance.hs view
@@ -0,0 +1,29 @@+module Signet.Unstable.Type.Tolerance where++import qualified Control.Monad as Monad+import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Type.Timestamp as Timestamp++newtype Tolerance+  = MkTolerance Time.NominalDiffTime+  deriving (Eq, Show)++unwrap :: Tolerance -> Time.NominalDiffTime+unwrap (MkTolerance nominalDiffTime) = nominalDiffTime++typical :: Tolerance+typical = MkTolerance 300++check ::+  Tolerance ->+  Time.UTCTime ->+  Timestamp.Timestamp ->+  Either ToleranceException.ToleranceException ()+check tolerance utcTime timestamp = do+  let diff = Time.diffUTCTime utcTime $ Timestamp.unwrap timestamp+  let hi = unwrap tolerance+  let lo = negate hi+  Monad.when (lo > diff || diff > hi)+    . Left+    $ ToleranceException.MkToleranceException timestamp
+ source/library/Signet/Unstable/Type/ToleranceTest.hs view
@@ -0,0 +1,33 @@+module Signet.Unstable.Type.ToleranceTest where++import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Timestamp as Timestamp+import qualified Signet.Unstable.Type.Tolerance as Tolerance++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Tolerance" $ do+  Test.describe test "check" $ do+    Test.it test "succeeds when timestamp is within tolerance" $ do+      let tolerance = Tolerance.MkTolerance 1+      let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60+      let timestamp = Timestamp.MkTimestamp utcTime+      let result = Tolerance.check tolerance utcTime timestamp+      Test.assertEq test result (Right ())++    Test.it test "fails when timestamp is too old" $ do+      let tolerance = Tolerance.MkTolerance 1+      let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60+      let timestamp = Timestamp.MkTimestamp utcTime+      let now = Time.addUTCTime 2 utcTime+      let result = Tolerance.check tolerance now timestamp+      Test.assertEq test result (Left (ToleranceException.MkToleranceException timestamp))++    Test.it test "fails when timestamp is in the future" $ do+      let tolerance = Tolerance.MkTolerance 1+      let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60+      let timestamp = Timestamp.MkTimestamp utcTime+      let now = Time.addUTCTime (-2) utcTime+      let result = Tolerance.check tolerance now timestamp+      Test.assertEq test result (Left (ToleranceException.MkToleranceException timestamp))
+ source/library/Signet/Unstable/Type/UnknownSignature.hs view
@@ -0,0 +1,10 @@+module Signet.Unstable.Type.UnknownSignature where++import qualified Data.ByteString as ByteString++newtype UnknownSignature+  = MkUnknownSignature ByteString.ByteString+  deriving (Eq, Show)++unwrap :: UnknownSignature -> ByteString.ByteString+unwrap (MkUnknownSignature byteString) = byteString
+ source/library/Signet/Unstable/Type/UnknownSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Type.UnknownSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.UnknownSignature" $ do+  pure ()
+ source/library/Signet/Unstable/Type/Verifier.hs view
@@ -0,0 +1,75 @@+module Signet.Unstable.Type.Verifier where++import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier+import qualified Signet.Unstable.Exception.VerificationException as VerificationException+import qualified Signet.Unstable.Extra.Maybe as Maybe+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.PublicKey as PublicKey+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.Signer as Signer+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature++data Verifier+  = Asymmetric PublicKey.PublicKey+  | Symmetric Secret.Secret+  deriving (Eq, Show)++parse :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier+parse byteString = case PublicKey.parse byteString of+  Right publicKey -> Right $ Asymmetric publicKey+  Left _ -> case Secret.parse byteString of+    Right secret -> Right $ Symmetric secret+    Left _ -> Left $ InvalidVerifier.MkInvalidVerifier byteString++render :: Verifier -> ByteString.ByteString+render verifier = case verifier of+  Asymmetric publicKey -> PublicKey.render publicKey+  Symmetric secret -> Secret.render secret++verify ::+  Verifier ->+  Message.Message ->+  Signatures.Signatures ->+  Either VerificationException.VerificationException Signature.Signature+verify verifier message =+  case verifier of+    Asymmetric publicKey -> fmap Signature.Asymmetric . asymmetric publicKey message+    Symmetric secret -> fmap Signature.Symmetric . symmetric secret message++asymmetric ::+  PublicKey.PublicKey ->+  Message.Message ->+  Signatures.Signatures ->+  Either VerificationException.VerificationException AsymmetricSignature.AsymmetricSignature+asymmetric publicKey message =+  let toAsymmetric signature = case signature of+        Signature.Asymmetric asymmetricSignature -> Just asymmetricSignature+        Signature.Symmetric _ -> Nothing+      pk = PublicKey.unwrap publicKey+      bs = Message.render message+   in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)+        . List.find (Ed25519.verify pk bs . AsymmetricSignature.unwrap)+        . Maybe.mapMaybe toAsymmetric+        . Signatures.unwrap++symmetric ::+  Secret.Secret ->+  Message.Message ->+  Signatures.Signatures ->+  Either VerificationException.VerificationException SymmetricSignature.SymmetricSignature+symmetric secret message =+  let toSymmetric signature = case signature of+        Signature.Asymmetric _ -> Nothing+        Signature.Symmetric symmetricSignature -> Just symmetricSignature+      expected = Signer.symmetric secret message+   in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)+        . List.find (expected ==)+        . Maybe.mapMaybe toSymmetric+        . Signatures.unwrap
+ source/library/Signet/Unstable/Type/VerifierTest.hs view
@@ -0,0 +1,109 @@+module Signet.Unstable.Type.VerifierTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier+import qualified Signet.Unstable.Exception.VerificationException as VerificationException+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.PublicKey as PublicKey+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Verifier as Verifier++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Verifier" $ do+  Test.describe test "parse" $ do+    Test.it test "succeeds with a valid public key" $ do+      let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+      let actual = Verifier.parse byteString+      publicKey <- Either.throw $ PublicKey.parse byteString+      Test.assertEq test actual (Right (Verifier.Asymmetric publicKey))++    Test.it test "succeeds with a valid secret" $ do+      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      let actual = Verifier.parse byteString+      secret <- Either.throw $ Secret.parse byteString+      Test.assertEq test actual (Right (Verifier.Symmetric secret))++    Test.it test "fails with invalid input" $ do+      let byteString = Ascii.pack "invalid"+      let actual = Verifier.parse byteString+      Test.assertEq test actual (Left (InvalidVerifier.MkInvalidVerifier byteString))++  Test.describe test "render" $ do+    Test.it test "works with a public key" $ do+      let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+      publicKey <- Either.throw . PublicKey.parse $ byteString+      Test.assertEq test (Verifier.render (Verifier.Asymmetric publicKey)) byteString++    Test.it test "works with a secret" $ do+      let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      secret <- Either.throw . Secret.parse $ byteString+      Test.assertEq test (Verifier.render (Verifier.Symmetric secret)) byteString++  Test.describe test "verify" $ do+    Test.it test "succeeds with a valid asymmetric signature" $ do+      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+      let actual = Verifier.verify verifier message signatures+      Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+      Test.assertEq test actual (Right signature)++    Test.it test "fails with an invalid asymmetric signature" $ do+      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="+      let actual = Verifier.verify verifier message signatures+      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))++    Test.it test "succeeds with a valid symmetric signature" $ do+      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      let actual = Verifier.verify verifier message signatures+      Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      Test.assertEq test actual (Right signature)++    Test.it test "fails with an invalid symmetric signature" $ do+      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="+      let actual = Verifier.verify verifier message signatures+      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))++  Test.describe test "asymmetric" $ do+    Test.it test "succeeds with a valid signature" $ do+      publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+      let actual = Verifier.asymmetric publicKey message signatures+      asymmetricSignature <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+      Test.assertEq test actual (Right asymmetricSignature)++    Test.it test "fails with an invalid signature" $ do+      publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="+      let actual = Verifier.asymmetric publicKey message signatures+      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))++  Test.describe test "symmetric" $ do+    Test.it test "succeeds with a valid signature" $ do+      secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      let actual = Verifier.symmetric secret message signatures+      symmetricSignature <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      Test.assertEq test actual (Right symmetricSignature)++    Test.it test "fails with an invalid signature" $ do+      secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="+      let actual = Verifier.symmetric secret message signatures+      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))
+ source/library/Signet/UnstableTest.hs view
@@ -0,0 +1,56 @@+module Signet.UnstableTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.Time as Time+import qualified Signet.Unstable as Signet+import qualified Signet.Unstable.Exception.SignetException as SignetException+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Exception.VerificationException as VerificationException+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Tolerance as Tolerance+import qualified Signet.Unstable.Type.Verifier as Verifier++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable" $ do+  Test.describe test "verifyWebhookText" $ do+    pure ()++  Test.describe test "verifyWebhookByteString" $ do+    pure ()++  Test.describe test "verifyWebhook" $ do+    pure ()++  Test.describe test "verifyWebhookWith" $ do+    Test.it test "succeeds with a valid symmetric signature" $ do+      let tolerance = Tolerance.typical+      let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0+      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      let byteString = Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      (_, signatures) <- Either.throw $ Signatures.parse byteString+      let result = Signet.verifyWebhookWith tolerance now verifier message signatures+      Right signature <- Either.throw $ Signature.parse byteString+      Test.assertEq test result (Right signature)++    Test.it test "fails with an invalid timestamp" $ do+      let tolerance = Tolerance.typical+      let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0+      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.301.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+      let result = Signet.verifyWebhookWith tolerance now verifier message signatures+      Test.assertEq test result (Left (SignetException.ToleranceException . ToleranceException.MkToleranceException $ Message.timestamp message))++    Test.it test "fails with an invalid symmetric signature" $ do+      let tolerance = Tolerance.typical+      let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0+      verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="+      let result = Signet.verifyWebhookWith tolerance now verifier message signatures+      Test.assertEq test result (Left (SignetException.VerificationException . VerificationException.MkVerificationException $ Message.id_ message))
+ source/library/SignetTest.hs view
@@ -0,0 +1,72 @@+module SignetTest where++import qualified Signet.Unstable.Exception.InvalidAsymmetricSignatureTest+import qualified Signet.Unstable.Exception.InvalidIdTest+import qualified Signet.Unstable.Exception.InvalidMessageTest+import qualified Signet.Unstable.Exception.InvalidPublicKeyTest+import qualified Signet.Unstable.Exception.InvalidSecretKeyTest+import qualified Signet.Unstable.Exception.InvalidSecretTest+import qualified Signet.Unstable.Exception.InvalidSignatureTest+import qualified Signet.Unstable.Exception.InvalidSignerTest+import qualified Signet.Unstable.Exception.InvalidSymmetricSignatureTest+import qualified Signet.Unstable.Exception.InvalidTimestampTest+import qualified Signet.Unstable.Exception.InvalidVerifierTest+import qualified Signet.Unstable.Exception.SignetExceptionTest+import qualified Signet.Unstable.Exception.ToleranceExceptionTest+import qualified Signet.Unstable.Exception.VerificationExceptionTest+import qualified Signet.Unstable.Extra.EitherTest+import qualified Signet.Unstable.Extra.HttpTest+import qualified Signet.Unstable.Extra.MaybeTest+import qualified Signet.Unstable.Type.AsymmetricSignatureTest+import qualified Signet.Unstable.Type.IdTest+import qualified Signet.Unstable.Type.MessageTest+import qualified Signet.Unstable.Type.PayloadTest+import qualified Signet.Unstable.Type.PublicKeyTest+import qualified Signet.Unstable.Type.SecretKeyTest+import qualified Signet.Unstable.Type.SecretTest+import qualified Signet.Unstable.Type.SignatureTest+import qualified Signet.Unstable.Type.SignaturesTest+import qualified Signet.Unstable.Type.SignerTest+import qualified Signet.Unstable.Type.SymmetricSignatureTest+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.TimestampTest+import qualified Signet.Unstable.Type.ToleranceTest+import qualified Signet.Unstable.Type.UnknownSignatureTest+import qualified Signet.Unstable.Type.VerifierTest+import qualified Signet.UnstableTest++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = do+  Signet.Unstable.Exception.InvalidAsymmetricSignatureTest.spec test+  Signet.Unstable.Exception.InvalidIdTest.spec test+  Signet.Unstable.Exception.InvalidMessageTest.spec test+  Signet.Unstable.Exception.InvalidPublicKeyTest.spec test+  Signet.Unstable.Exception.InvalidSecretKeyTest.spec test+  Signet.Unstable.Exception.InvalidSecretTest.spec test+  Signet.Unstable.Exception.InvalidSignatureTest.spec test+  Signet.Unstable.Exception.InvalidSignerTest.spec test+  Signet.Unstable.Exception.InvalidSymmetricSignatureTest.spec test+  Signet.Unstable.Exception.InvalidTimestampTest.spec test+  Signet.Unstable.Exception.InvalidVerifierTest.spec test+  Signet.Unstable.Exception.SignetExceptionTest.spec test+  Signet.Unstable.Exception.ToleranceExceptionTest.spec test+  Signet.Unstable.Exception.VerificationExceptionTest.spec test+  Signet.Unstable.Extra.EitherTest.spec test+  Signet.Unstable.Extra.HttpTest.spec test+  Signet.Unstable.Extra.MaybeTest.spec test+  Signet.Unstable.Type.AsymmetricSignatureTest.spec test+  Signet.Unstable.Type.IdTest.spec test+  Signet.Unstable.Type.MessageTest.spec test+  Signet.Unstable.Type.PayloadTest.spec test+  Signet.Unstable.Type.PublicKeyTest.spec test+  Signet.Unstable.Type.SecretKeyTest.spec test+  Signet.Unstable.Type.SecretTest.spec test+  Signet.Unstable.Type.SignaturesTest.spec test+  Signet.Unstable.Type.SignatureTest.spec test+  Signet.Unstable.Type.SignerTest.spec test+  Signet.Unstable.Type.SymmetricSignatureTest.spec test+  Signet.Unstable.Type.TimestampTest.spec test+  Signet.Unstable.Type.ToleranceTest.spec test+  Signet.Unstable.Type.UnknownSignatureTest.spec test+  Signet.Unstable.Type.VerifierTest.spec test+  Signet.UnstableTest.spec test
source/test-suite/Main.hs view
@@ -1,5 +1,19 @@+import qualified Control.Monad.Trans.Writer as Writer+import qualified Signet.Unstable.Type.Test as Test import qualified SignetTest import qualified Test.Tasty as Tasty+import qualified Test.Tasty.HUnit as Unit  main :: IO ()-main = Tasty.defaultMain SignetTest.testTree+main = Tasty.defaultMain testTree++testTree :: Tasty.TestTree+testTree = Tasty.testGroup "signet" . Writer.execWriter $ SignetTest.spec tasty++tasty :: Test.Test (Writer.Writer [Tasty.TestTree])+tasty =+  Test.MkTest+    { Test.assertFailure = Unit.assertFailure,+      Test.describe = \x -> Writer.tell . pure . Tasty.testGroup x . Writer.execWriter,+      Test.it = \x -> Writer.tell . pure . Unit.testCase x+    }