73 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| class WebPushRequest
 | |
|   SIGNATURE_ALGORITHM = 'p256ecdsa'
 | |
|   AUTH_HEADER = 'WebPush'
 | |
|   PAYLOAD_EXPIRATION = 24.hours
 | |
|   JWT_ALGORITHM = 'ES256'
 | |
|   JWT_TYPE = 'JWT'
 | |
| 
 | |
|   attr_reader :web_push_subscription
 | |
| 
 | |
|   delegate(
 | |
|     :endpoint,
 | |
|     :key_auth,
 | |
|     :key_p256dh,
 | |
|     to: :web_push_subscription
 | |
|   )
 | |
| 
 | |
|   def initialize(web_push_subscription)
 | |
|     @web_push_subscription = web_push_subscription
 | |
|   end
 | |
| 
 | |
|   def audience
 | |
|     @audience ||= Addressable::URI.parse(endpoint).normalized_site
 | |
|   end
 | |
| 
 | |
|   def authorization_header
 | |
|     [AUTH_HEADER, encoded_json_web_token].join(' ')
 | |
|   end
 | |
| 
 | |
|   def crypto_key_header
 | |
|     [SIGNATURE_ALGORITHM, vapid_key.public_key_for_push_header].join('=')
 | |
|   end
 | |
| 
 | |
|   def encrypt(payload)
 | |
|     Webpush::Encryption.encrypt(payload, key_p256dh, key_auth)
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def encoded_json_web_token
 | |
|     JWT.encode(
 | |
|       web_token_payload,
 | |
|       vapid_key.curve,
 | |
|       JWT_ALGORITHM,
 | |
|       typ: JWT_TYPE
 | |
|     )
 | |
|   end
 | |
| 
 | |
|   def web_token_payload
 | |
|     {
 | |
|       aud: audience,
 | |
|       exp: PAYLOAD_EXPIRATION.from_now.to_i,
 | |
|       sub: payload_subject,
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   def payload_subject
 | |
|     [:mailto, contact_email].join(':')
 | |
|   end
 | |
| 
 | |
|   def vapid_key
 | |
|     @vapid_key ||= Webpush::VapidKey.from_keys(
 | |
|       Rails.configuration.x.vapid_public_key,
 | |
|       Rails.configuration.x.vapid_private_key
 | |
|     )
 | |
|   end
 | |
| 
 | |
|   def contact_email
 | |
|     @contact_email ||= ::Setting.site_contact_email
 | |
|   end
 | |
| end
 |