# frozen_string_literal: true # client-server ['/inbox', '/outbox'].each do |path| get path do protected! box = path.sub('/', '') collection = Dir[File.join(box, 'object', '*', '*.json')].collect { |f| JSON.parse(File.read(f)) } threads = [] collection.collect! do |object| object.is_a?(String) && object.match(/^http/) ? fetch(object) : object end collection.compact! collection.each do |object| object['mention'] = mention object['attributedTo'] if object['type'] == 'Audio' audio_url = object['url'].select { |url| url['mediaType'].match('audio') }[0] object['attachment'] = [{ 'url' => audio_url['href'], 'mediaType' => audio_url['mediaType'] }] end object['replies'] = [] threads << object if object['inReplyTo'].nil? || collection.select do |o| o['id'] == object['inReplyTo'] end.empty? end collection.each do |object| collection.select { |o| o['id'] == object['inReplyTo'] }.each do |o| o['replies'] << object end end threads.sort_by { |o| o['published'] }.to_json end end post '/delete' do protected! params['id'].each do |id| file = find_file id FileUtils.rm(file) if File.exist? file end end post '/follow' do protected! actor, = parse_follow params['follow'] outbox 'Follow', actor, [actor] end post '/unfollow' do protected! actor, mention = parse_follow params['follow'] Dir[File.join(OUTBOX[:dir], 'follow', '*.json')].each do |f| activity = JSON.parse(File.read(f)) if activity['object'] == actor outbox 'Undo', activity, [actor] update_collection FOLLOWING, actor, true end end end post '/share' do # TODO protected! src = find_file INBOX, params['id'] object = JSON.parse(File.read(src)) recipients = public recipients << object['attributedTo'] # outbox 'Announce', object, recipients dest = src.sub('/inbox/', '/outbox/') FileUtils.mkdir_p File.dirname(dest) FileUtils.mv src, dest end post '/login' do session['client'] = (OpenSSL::Digest::SHA256.base64digest(params['secret']) == File.read('.digest').chomp) end helpers do def protected! halt 403 unless session['client'] end def find_file(id) Dir[File.join('*', 'object', '*', '*.json')].select do |f| JSON.parse(File.read(f))['id'] == id end[0] end def public recipients = ['https://www.w3.org/ns/activitystreams#Public'] recipients += JSON.parse(File.read(FOLLOWERS))['orderedItems'] recipients.delete ACTOR recipients.uniq end def parse_follow(follow) case follow when /^#/ actor = "https://relay.fedi.buzz/tag/#{follow.sub(/^#/, '')}" mention = follow when /^http/ actor = follow mention = mention(actor) when /^@*\w+@\w+/ mention = follow actor = actor(follow) return 502 unless actor end [actor, mention] end end