catstodon/app/models/web/push_subscription.rb
dependabot-preview[bot] 78202e9138
Bump doorkeeper from 5.3.3 to 5.4.0 (#13733)
* Bump doorkeeper from 5.3.3 to 5.4.0

Bumps [doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) from 5.3.3 to 5.4.0.
- [Release notes](https://github.com/doorkeeper-gem/doorkeeper/releases)
- [Changelog](https://github.com/doorkeeper-gem/doorkeeper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/doorkeeper-gem/doorkeeper/compare/v5.3.3...v5.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Fix tests

* Fix use of Doorkeeper::AccessToken.find_or_create_for

* Fix tests?

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Thibaut Girka <thib@sitedethib.com>
2020-05-12 15:25:33 +02:00

104 lines
3.3 KiB
Ruby

# frozen_string_literal: true
# == Schema Information
#
# Table name: web_push_subscriptions
#
# id :bigint(8) not null, primary key
# endpoint :string not null
# key_p256dh :string not null
# key_auth :string not null
# data :json
# created_at :datetime not null
# updated_at :datetime not null
# access_token_id :bigint(8)
# user_id :bigint(8)
#
class Web::PushSubscription < ApplicationRecord
belongs_to :user, optional: true
belongs_to :access_token, class_name: 'Doorkeeper::AccessToken', optional: true
has_one :session_activation, foreign_key: 'web_push_subscription_id', inverse_of: :web_push_subscription
validates :endpoint, presence: true
validates :key_p256dh, presence: true
validates :key_auth, presence: true
def push(notification)
I18n.with_locale(associated_user&.locale || I18n.default_locale) do
push_payload(payload_for_notification(notification), 48.hours.seconds)
end
end
def pushable?(notification)
data&.key?('alerts') && ActiveModel::Type::Boolean.new.cast(data['alerts'][notification.type.to_s])
end
def associated_user
return @associated_user if defined?(@associated_user)
@associated_user = if user_id.nil?
session_activation.user
else
user
end
end
def associated_access_token
return @associated_access_token if defined?(@associated_access_token)
@associated_access_token = if access_token_id.nil?
find_or_create_access_token.token
else
access_token.token
end
end
class << self
def unsubscribe_for(application_id, resource_owner)
access_token_ids = Doorkeeper::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id, revoked_at: nil)
.pluck(:id)
where(access_token_id: access_token_ids).delete_all
end
end
private
def push_payload(message, ttl = 5.minutes.seconds)
Webpush.payload_send(
message: Oj.dump(message),
endpoint: endpoint,
p256dh: key_p256dh,
auth: key_auth,
ttl: ttl,
ssl_timeout: 10,
open_timeout: 10,
read_timeout: 10,
vapid: {
subject: "mailto:#{::Setting.site_contact_email}",
private_key: Rails.configuration.x.vapid_private_key,
public_key: Rails.configuration.x.vapid_public_key,
}
)
end
def payload_for_notification(notification)
ActiveModelSerializers::SerializableResource.new(
notification,
serializer: Web::NotificationSerializer,
scope: self,
scope_name: :current_push_subscription
).as_json
end
def find_or_create_access_token
Doorkeeper::AccessToken.find_or_create_for(
application: Doorkeeper::Application.find_by(superapp: true),
resource_owner: session_activation.user_id,
scopes: Doorkeeper::OAuth::Scopes.from_string('read write follow push'),
expires_in: Doorkeeper.configuration.access_token_expires_in,
use_refresh_token: Doorkeeper.configuration.refresh_token_enabled?
)
end
end