Module: Telnyx::Lib::WebhookVerification
- Defined in:
- lib/telnyx/lib/webhook_verification.rb
Overview
Telnyx Ed25519 webhook verification over the exact raw payload bytes.
Constant Summary collapse
- SIGNATURE_HEADER =
"telnyx-signature-ed25519"- TIMESTAMP_HEADER =
"telnyx-timestamp"- DEFAULT_TOLERANCE =
300- ED25519_SPKI_PREFIX =
["302a300506032b6570032100"].pack("H*").freeze
Class Method Summary collapse
-
.verify_signature!(payload, headers, public_key) ⇒ true
Verify a Telnyx webhook signature before the caller parses the payload.
Class Method Details
.verify_signature!(payload, headers, public_key) ⇒ true
Verify a Telnyx webhook signature before the caller parses the payload.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/telnyx/lib/webhook_verification.rb', line 23 def verify_signature!(payload, headers, public_key) signature_header = get_header(headers, SIGNATURE_HEADER) = get_header(headers, TIMESTAMP_HEADER) fail_verification("Missing required header: telnyx-signature-ed25519") if signature_header.nil? || signature_header.empty? fail_verification("Missing required header: telnyx-timestamp") if .nil? || .empty? fail_verification("Public key is required for webhook verification") if public_key.nil? || public_key.empty? = () if (Time.now.to_i - ).abs > DEFAULT_TOLERANCE fail_verification("Webhook timestamp is too old or too far in the future") end key = parse_public_key(public_key) signature = Base64.strict_decode64(signature_header) signed_payload = "#{}|#{payload}" fail_verification("Invalid webhook signature") unless key.verify(nil, signature, signed_payload) true rescue Telnyx::Errors::WebhookVerificationError raise rescue ArgumentError => e fail_verification("Invalid webhook signature or public key encoding: #{e.}") rescue OpenSSL::PKey::PKeyError => e fail_verification("Invalid Ed25519 public key: #{e.}") rescue OpenSSL::OpenSSLError => e fail_verification("Webhook verification failed: #{e.}") end |