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
 |