mastodon/app/models/web/push_subscription.rb
David Roetzel 05f23df3b7
Some checks are pending
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.1) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / Libvips tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.1) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.1) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.1, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Add endpoint to remove web push subscription (#32626)
2024-10-23 08:02:31 +00:00

98 lines
3.0 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, dependent: nil
validates :endpoint, presence: true, url: true
validates :key_p256dh, presence: true
validates :key_auth, presence: true
validates_with WebPushKeyValidator
delegate :locale, to: :associated_user
generates_token_for :unsubscribe, expires_in: Web::PushNotificationWorker::TTL
def pushable?(notification)
policy_allows_notification?(notification) && alert_enabled_for_notification_type?(notification)
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).not_revoked.pluck(:id)
where(access_token_id: access_token_ids).delete_all
end
end
private
def find_or_create_access_token
Doorkeeper::AccessToken.find_or_create_for(
application: Doorkeeper::Application.find_by(superapp: true),
resource_owner: user_id || 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
def alert_enabled_for_notification_type?(notification)
truthy?(data&.dig('alerts', notification.type.to_s))
end
def policy_allows_notification?(notification)
case data&.dig('policy')
when nil, 'all'
true
when 'none'
false
when 'followed'
notification.account.following?(notification.from_account)
when 'follower'
notification.from_account.following?(notification.account)
end
end
def truthy?(val)
ActiveModel::Type::Boolean.new.cast(val)
end
end