From 711bf7f86daddd0209244f9640d8a3f27d958e3a Mon Sep 17 00:00:00 2001 From: pdp8 Date: Fri, 21 Jul 2023 00:52:49 +0200 Subject: inbox and outbox unified --- helpers.rb | 77 +++++++++++++++----------------------------------------------- 1 file changed, 18 insertions(+), 59 deletions(-) (limited to 'helpers.rb') diff --git a/helpers.rb b/helpers.rb index 0c668e9..45c58df 100644 --- a/helpers.rb +++ b/helpers.rb @@ -3,73 +3,32 @@ require 'English' helpers do - def outbox(type, object, recipients, add_recipients = false) - activity = { - '@context' => 'https://www.w3.org/ns/activitystreams', - 'type' => type, - 'actor' => ACTOR, - 'object' => object - } + # add date and id, save + def complete_and_save(activity) + box = activity['id'] ? INBOX : OUTBOX + date = Time.now.utc.iso8601 + activity['published'] = date if box == OUTBOX + basename = "#{activity['published']}_#{mention(activity['actor'])}.json" + activity_rel_path = File.join(activity['type'].downcase, basename) + activity_path = File.join(box[:dir], activity_rel_path) + activity['id'] = File.join(box[:url], activity_rel_path) if box == OUTBOX - now = Time.now - date = now.strftime('%Y-%m-%dT%H:%M:%S.%N') - httpdate = now.utc.httpdate - basename = "#{date}.json" - activity_rel_path = File.join(type.downcase, basename) - activity_path = File.join(OUTBOX_DIR, activity_rel_path) - activity['id'] = File.join(OUTBOX_URL, activity_rel_path) - activity['published'] = httpdate - # assumes that recipient collections have been expanded by sender - # put all recipients into 'to', avoid 'cc' 'bto' 'bcc' 'audience' !! - activity['to'] = recipients if add_recipients - - # save object if activity['object'] && activity['object']['type'] && !activity['object']['id'] - + # save object object = activity['object'] object['@context'] = 'https://www.w3.org/ns/activitystreams' - object_rel_path = File.join activity['object']['type'].downcase, basename - object_path = File.join OUTBOX_DIR, object_rel_path - object['id'] = File.join OUTBOX_URL, object_rel_path - object['published'] = httpdate + object_rel_path = File.join 'object', activity['object']['type'].downcase, basename + if box == OUTBOX + object['id'] = File.join box[:url], object_rel_path + object['published'] = date + end + object_path = File.join box[:dir], object_rel_path FileUtils.mkdir_p File.dirname(object_path) File.open(object_path, 'w+') { |f| f.puts object.to_json } end # save activity FileUtils.mkdir_p File.dirname(activity_path) File.open(activity_path, 'w+') { |f| f.puts activity.to_json } - update_collection OUTBOX, activity['id'] if %w[Create Announce].include?(type) - - # send - # https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb - keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) - body = activity.to_json - sha256 = OpenSSL::Digest.new('SHA256') - digest = "SHA-256=#{sha256.base64digest(body)}" - - inboxes = [] - recipients.uniq.each do |url| - next if [ACTOR, 'https://www.w3.org/ns/activitystreams#Public'].include? url - - actor = fetch url - next unless actor - - if actor['endpoints'] and actor['endpoints']['sharedInbox'] - inboxes << actor['endpoints']['sharedInbox'] - elsif actor['inbox'] - inboxes << actor['inbox'] - end - end - inboxes.compact.uniq.each do |inbox| - uri = URI(inbox) - string = "(request-target): post #{uri.request_uri}\nhost: #{uri.host}\ndate: #{httpdate}\ndigest: #{digest}\ncontent-type: application/activity+json" - signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), string)) - signed_header = "keyId=\"#{ACTOR}#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest content-type\",signature=\"#{signature}\"" - - curl( - "-X POST -H 'Content-Type: application/activity+json' -H 'Host: #{uri.host}' -H 'Date: #{httpdate}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}'", inbox - ) - end activity end @@ -154,11 +113,11 @@ helpers do end def people - File.read('private/people.tsv').split("\n").collect { |l| l.chomp.split("\t") } + File.read('public/people.tsv').split("\n").collect { |l| l.chomp.split("\t") } end def cache(mention, actor, a) sharedInbox = a['endpoints']['sharedInbox'] if a['endpoints'] && a['endpoints']['sharedInbox'] - File.open('private/people.tsv', 'a') { |f| f.puts "#{mention}\t#{actor}\t#{sharedInbox}" } + File.open('public/people.tsv', 'a') { |f| f.puts "#{mention}\t#{actor}\t#{sharedInbox}" } end end -- cgit v1.2.3