The code powering m.abunchtell.com https://m.abunchtell.com
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

98 行
2.9 KiB

  1. # frozen_string_literal: true
  2. # == Schema Information
  3. #
  4. # Table name: web_push_subscriptions
  5. #
  6. # id :bigint(8) not null, primary key
  7. # endpoint :string not null
  8. # key_p256dh :string not null
  9. # key_auth :string not null
  10. # data :json
  11. # created_at :datetime not null
  12. # updated_at :datetime not null
  13. # access_token_id :bigint(8)
  14. # user_id :bigint(8)
  15. #
  16. class Web::PushSubscription < ApplicationRecord
  17. belongs_to :user, optional: true
  18. belongs_to :access_token, class_name: 'Doorkeeper::AccessToken', optional: true
  19. has_one :session_activation
  20. def push(notification)
  21. I18n.with_locale(associated_user&.locale || I18n.default_locale) do
  22. push_payload(payload_for_notification(notification), 48.hours.seconds)
  23. end
  24. end
  25. def pushable?(notification)
  26. data&.key?('alerts') && ActiveModel::Type::Boolean.new.cast(data['alerts'][notification.type.to_s])
  27. end
  28. def associated_user
  29. return @associated_user if defined?(@associated_user)
  30. @associated_user = if user_id.nil?
  31. session_activation.user
  32. else
  33. user
  34. end
  35. end
  36. def associated_access_token
  37. return @associated_access_token if defined?(@associated_access_token)
  38. @associated_access_token = if access_token_id.nil?
  39. find_or_create_access_token.token
  40. else
  41. access_token.token
  42. end
  43. end
  44. class << self
  45. def unsubscribe_for(application_id, resource_owner)
  46. access_token_ids = Doorkeeper::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id, revoked_at: nil)
  47. .pluck(:id)
  48. where(access_token_id: access_token_ids).delete_all
  49. end
  50. end
  51. private
  52. def push_payload(message, ttl = 5.minutes.seconds)
  53. Webpush.payload_send(
  54. message: Oj.dump(message),
  55. endpoint: endpoint,
  56. p256dh: key_p256dh,
  57. auth: key_auth,
  58. ttl: ttl,
  59. vapid: {
  60. subject: "mailto:#{::Setting.site_contact_email}",
  61. private_key: Rails.configuration.x.vapid_private_key,
  62. public_key: Rails.configuration.x.vapid_public_key,
  63. }
  64. )
  65. end
  66. def payload_for_notification(notification)
  67. ActiveModelSerializers::SerializableResource.new(
  68. notification,
  69. serializer: Web::NotificationSerializer,
  70. scope: self,
  71. scope_name: :current_push_subscription
  72. ).as_json
  73. end
  74. def find_or_create_access_token
  75. Doorkeeper::AccessToken.find_or_create_for(
  76. Doorkeeper::Application.find_by(superapp: true),
  77. session_activation.user_id,
  78. Doorkeeper::OAuth::Scopes.from_string('read write follow push'),
  79. Doorkeeper.configuration.access_token_expires_in,
  80. Doorkeeper.configuration.refresh_token_enabled?
  81. )
  82. end
  83. end