# frozen_string_literal: true # client-server ['/inbox/threads', '/outbox/threads'].each do |path| get path do protected! box = path.sub('/', '').sub('/threads', '') 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 200 end post '/follow' do protected! params['id'] = actor params['mention'] if params['mention'] outbox 'Follow', params['id'], [params['id']] 200 end post '/unfollow' do protected! params['id'] = actor params['mention'] if params['mention'] following = Dir[File.join(OUTBOX[:dir], 'follow', '*.json')].collect { |f| JSON.parse(File.read(f)) } activity = following.find { |a| a['object'] == params['id'] } activity ||= save_activity({ 'type' => 'Follow', 'actor' => ACTOR, 'object' => params['id'] }, OUTBOX) # recreate activity for old/deleted follows outbox 'Undo', activity, [params['id']] update_collection FOLLOWING, params['id'], true 200 end post '/share' do # TODO protected! src = find_file 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 200 end post '/login' do session['client'] = (OpenSSL::Digest::SHA256.base64digest(params['secret']) == File.read('.digest').chomp) 200 end helpers do def protected! halt 403 unless session['client'] end def find_file(id) Dir[File.join('*', 'object', '*', '*.json')].find do |f| JSON.parse(File.read(f))['id'] == id end 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