You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.4 KiB
72 lines
1.4 KiB
# 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
|
|
|