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
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/shedcloud/partner_api/webhooks.rb', line 23
def verify_signature_at(secret, , body, now, tolerance_seconds = 0)
raise ArgumentError, 'webhook signature verification failed: secret is required' if secret.to_s.empty?
raise ArgumentError, 'webhook signature verification failed: signature header is missing' if .to_s.strip.empty?
tolerance_seconds = DEFAULT_TOLERANCE_SECONDS if tolerance_seconds <= 0
timestamp = 0
signatures = []
.to_s.split(',').each do |part|
part = part.strip
next unless part.include?('=')
key, value = part.split('=', 2)
case key
when 't'
unless value.match?(/\A\d+\z/)
raise ArgumentError, 'webhook signature verification failed: invalid timestamp in signature header'
end
timestamp = value.to_i
when 'v1'
signatures << value
end
end
if timestamp.zero? || signatures.empty?
raise ArgumentError, 'webhook signature verification failed: signature header missing t= or v1='
end
delta = (now - timestamp).abs
if delta > tolerance_seconds
raise ArgumentError, 'webhook signature verification failed: signature timestamp outside tolerance'
end
expected = compute_signature(secret, timestamp, body)
return nil if signatures.any? { |signature| secure_compare(signature.downcase, expected) }
raise ArgumentError, 'webhook signature verification failed: signature mismatch'
end
|