Module: WorkOS::Util::Signature
- Defined in:
- lib/workos/util/signature.rb
Class Method Summary collapse
-
.compute(payload:, timestamp:, secret:) ⇒ String
Computes the expected signature hash for a webhook or action payload.
-
.parse_header(sig_header) ⇒ Array(String, String)
Parses the WorkOS signature header.
-
.secure_compare(a, b) ⇒ Boolean
Compares two signature hashes in constant time.
Class Method Details
.compute(payload:, timestamp:, secret:) ⇒ String
Computes the expected signature hash for a webhook or action payload.
17 18 19 |
# File 'lib/workos/util/signature.rb', line 17 def compute(payload:, timestamp:, secret:) OpenSSL::HMAC.hexdigest("SHA256", secret, "#{}.#{payload}") end |
.parse_header(sig_header) ⇒ Array(String, String)
Parses the WorkOS signature header.
26 27 28 29 30 31 32 33 34 35 |
# File 'lib/workos/util/signature.rb', line 26 def parse_header(sig_header) raise ArgumentError, "Signature header missing" if sig_header.nil? || sig_header.empty? parts = sig_header.split(",").map(&:strip) = parts.find { |part| part.start_with?("t=") }&.sub(/\At=/, "") signature = parts.find { |part| part.start_with?("v1=") }&.sub(/\Av1=/, "") raise ArgumentError, "Unable to extract timestamp and signature hash from header" if .nil? || signature.nil? [, signature] end |
.secure_compare(a, b) ⇒ Boolean
Compares two signature hashes in constant time.
42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/workos/util/signature.rb', line 42 def secure_compare(a, b) return false if a.bytesize != b.bytesize OpenSSL.fixed_length_secure_compare(a, b) rescue NoMethodError left = a.unpack("C*") result = 0 index = -1 b.each_byte { |byte| result |= byte ^ left[index += 1] } result.zero? end |