1
0

web_push_request.rb 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # frozen_string_literal: true
  2. class WebPushRequest
  3. SIGNATURE_ALGORITHM = 'p256ecdsa'
  4. AUTH_HEADER = 'WebPush'
  5. PAYLOAD_EXPIRATION = 24.hours
  6. JWT_ALGORITHM = 'ES256'
  7. JWT_TYPE = 'JWT'
  8. attr_reader :web_push_subscription
  9. delegate(
  10. :endpoint,
  11. :key_auth,
  12. :key_p256dh,
  13. to: :web_push_subscription
  14. )
  15. def initialize(web_push_subscription)
  16. @web_push_subscription = web_push_subscription
  17. end
  18. def audience
  19. @audience ||= Addressable::URI.parse(endpoint).normalized_site
  20. end
  21. def authorization_header
  22. [AUTH_HEADER, encoded_json_web_token].join(' ')
  23. end
  24. def crypto_key_header
  25. [SIGNATURE_ALGORITHM, vapid_key.public_key_for_push_header].join('=')
  26. end
  27. def encrypt(payload)
  28. Webpush::Encryption.encrypt(payload, key_p256dh, key_auth)
  29. end
  30. private
  31. def encoded_json_web_token
  32. JWT.encode(
  33. web_token_payload,
  34. vapid_key.curve,
  35. JWT_ALGORITHM,
  36. typ: JWT_TYPE
  37. )
  38. end
  39. def web_token_payload
  40. {
  41. aud: audience,
  42. exp: PAYLOAD_EXPIRATION.from_now.to_i,
  43. sub: payload_subject,
  44. }
  45. end
  46. def payload_subject
  47. [:mailto, contact_email].join(':')
  48. end
  49. def vapid_key
  50. @vapid_key ||= Webpush::VapidKey.from_keys(
  51. Rails.configuration.x.vapid_public_key,
  52. Rails.configuration.x.vapid_private_key
  53. )
  54. end
  55. def contact_email
  56. @contact_email ||= ::Setting.site_contact_email
  57. end
  58. end