module Web.Slack.Experimental.RequestVerificationSpec where import Data.Aeson import Data.Aeson.KeyMap qualified as KeyMap import Data.Time.Clock.POSIX import TestImport import Web.Slack.Experimental.RequestVerification spec :: Spec spec = do let timestamp = SlackRequestTimestamp "1665615887" -- Oct 12 2022 23:04:47 GMT+0000 let sig = SlackSignature "v0=f7f0a2f48ae5fe2c923813af0a7c7636396fea6e03edb3d73580a99cd1913575" let slackSigningSecret = SlackSigningSecret "SIGNING_SECRET" -- matches the test timestamp within one minute goodUtcTime = utcTimeToPOSIXSeconds $ UTCTime (fromGregorian 2022 10 12) (23 * 60 * 60 + 5 * 60) -- back to the future someoneGotATimeMachineUtcTime = utcTimeToPOSIXSeconds $ UTCTime (fromGregorian 2020 1 1) 0 oldUtcTime = utcTimeToPOSIXSeconds $ UTCTime (fromGregorian 2025 10 12) (23 * 60 * 60 + 5 * 60) -- the simplest possible JSON; this thing just parses it straight through -- anyway requestBody = "{}" describe "Slack Webhook" $ do it "Correctly validates webhooks" $ do validateRequest' goodUtcTime slackSigningSecret sig timestamp requestBody `shouldBe` (Right $ Object KeyMap.empty) it "Handles incorrect timestamp" $ do validateRequest' @Value goodUtcTime slackSigningSecret sig (SlackRequestTimestamp "bad") requestBody `shouldBe` Left (VerificationMalformedTimestamp "bad") it "Handles invalid signature" $ do validateRequest' @Value goodUtcTime slackSigningSecret (SlackSignature "the_v0_prefix_missing") timestamp requestBody `shouldBe` Left (VerificationUnknownSignatureVersion "the_v0_prefix_missing") it "Handles signature mismatch" $ do let badSignature = SlackSignature "v0=bad0bad0bad0bad0bad0bad0bad0bad0bad0bad0bad0bad0bad0bad0bad0bad0" validateRequest' @Value goodUtcTime slackSigningSecret badSignature timestamp requestBody `shouldBe` Left VerificationSignatureMismatch it "Handles timestamp in the future" $ do -- it's "in 2020" and someone gave us a 2022 timestamp validateRequest' @Value someoneGotATimeMachineUtcTime slackSigningSecret sig timestamp requestBody `shouldBe` Left (VerificationTimestampOutOfRange 1665615887) it "Handles timestamp in the past" $ do -- it's "in 2025" and someone gave us a 2022 timestamp validateRequest' @Value oldUtcTime slackSigningSecret sig timestamp requestBody `shouldBe` (Left (VerificationTimestampOutOfRange 1665615887))