lib/fediverse/notifier.rb in federails-0.1.0 vs lib/fediverse/notifier.rb in federails-0.2.0

- old
+ new

@@ -1,21 +1,60 @@ +require 'fediverse/signature' + module Fediverse class Notifier class << self def post_to_inboxes(activity) actors = activity.recipients - Rails.logger.debug('Nobody to notice') && return if actors.count.zero? - message = Federails::ApplicationController.renderer.new.render( + message = payload(activity) + actors.each do |recipient| + Rails.logger.debug { "Sending activity ##{activity.id} to #{recipient.inbox_url}" } + post_to_inbox(to: recipient, message: message, from: activity.actor) + end + end + + private + + def payload(activity) + Federails::ApplicationController.renderer.new.render( template: 'federails/server/activities/show', assigns: { activity: activity }, format: :json ) - actors.each do |actor| - Rails.logger.debug { "Sending activity ##{activity.id} to #{actor.inbox_url}" } - Faraday.post actor.inbox_url, message, 'Content-Type' => 'application/json', 'Accept' => 'application/json' + end + + def post_to_inbox(to:, message:, from: nil) + conn = Faraday.default_connection + conn.builder.build_response( + conn, + signed_request(to: to, message: message, from: from) + ) + end + + def signed_request(to:, message:, from:) + req = request(to: to, message: message) + req.headers['Signature'] = Fediverse::Signature.sign(sender: from, request: req) if from + req + end + + def request(to:, message:) # rubocop:todo Metrics/AbcSize + Faraday.default_connection.build_request(:post) do |req| + req.url to.inbox_url + req.body = message + req.headers['Content-Type'] = Mime[:activitypub].to_s + req.headers['Accept'] = Mime[:activitypub].to_s + req.headers['Host'] = URI.parse(to.inbox_url).host + req.headers['Date'] = Time.now.utc.httpdate + req.headers['Digest'] = digest(message) end + end + + def digest(message) + "SHA-256=#{Base64.strict_encode64( + OpenSSL::Digest.new('SHA256').digest(message) + )}" end end end end