line-1.0.0.0: src/Line/Messaging/Webhook/Validation.hs
{-|
This module provides a function to check if a webhook request has a correct
signature.
-}
{-# LANGUAGE OverloadedStrings #-}
module Line.Messaging.Webhook.Validation (
-- * Signature validation
validateSignature,
) where
import Crypto.Hash.SHA256 (hmaclazy)
import Data.Text.Encoding (encodeUtf8)
import Line.Messaging.Types
import Network.Wai
import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as Base64
import qualified Data.ByteString.Lazy as BL
getSignature :: Request -> Maybe B.ByteString
getSignature req = lookup "X-Line-Signature" headers
where
headers = requestHeaders req
-- | Provided a channel secret, WAI request and request body, it determines
-- the request is properly signatured, which probably means it is sent
-- from a valid LINE server.
--
-- For more details of webhook authentication, please refer to
-- <https://devdocs.line.me/en/#webhook-authentication the LINE documentation>.
validateSignature :: ChannelSecret -> Request -> BL.ByteString -> Bool
validateSignature secret req body = case getSignature req of
Nothing -> False
Just signature -> hash == signature
where
hash = Base64.encode $ hmaclazy (encodeUtf8 secret) body