app/models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_and_belongs_to_many :projects
before_create :generate_api_token
has_many :comments
has_many :likes
has_many :merge_requests, foreign_key: :author_id
has_many :patches, through: :merge_requests
has_many :locked_branches, foreign_key: :who_id
validates :name, presence: true, allow_blank: false
validates :api_token, uniqueness: true
scope(:webpush_enabled, lambda do
where('webpush_endpoint IS NOT NULL AND webpush_p256dh IS NOT NULL AND webpush_auth IS NOT NULL')
end)
WEBPUSH_TTL = 8.hours.to_i
WEBPUSH_TIMEOUT = 15
def self.valid_token?(token)
User.exists?(api_token: token)
end
def self.all_names
User.all.map(&:name)
end
def email_address
"#{name} <#{email}>"
end
def webpush_notification_enabled?
webpush_endpoint.present? && webpush_p256dh.present? && webpush_auth.present?
end
def self.send_webpush(users, title, body, url = '/')
users.each do |user|
user.send_webpush_assync(title, body, url)
end
end
def send_webpush_assync(title, body, url = '/')
return unless webpush_notification_enabled?
Thread.new do
send_webpush(title, body, url)
ensure
ActiveRecord::Base.connection.close
end
end
def send_webpush(title, body, url = '/')
return unless webpush_notification_enabled?
Timeout.timeout(WEBPUSH_TIMEOUT) do
Webpush.payload_send(
message: { title: title, body: body, tag: 'reviewit', url: url }.to_json,
endpoint: webpush_endpoint,
p256dh: webpush_p256dh,
auth: webpush_auth,
ttl: WEBPUSH_TTL,
vapid: {
subject: "mailto:#{ReviewitConfig.mail.sender}",
public_key: ReviewitConfig.webpush_public_key,
private_key: ReviewitConfig.webpush_private_key
}
)
end
rescue Timeout::Error
nil
rescue Webpush::InvalidSubscription, Webpush::ResponseError
update_attributes(webpush_endpoint: nil, webpush_p256dh: nil, webpush_auth: nil)
end
def generate_api_token
loop do
self.api_token = SecureRandom.urlsafe_base64
break unless User.exists?(api_token: api_token)
end
end
end