# frozen_string_literal: true class ActivityPub::Dereferencer include JsonLdHelper def initialize(uri, permitted_origin: nil, signature_account: nil) @uri = uri @permitted_origin = permitted_origin @signature_account = signature_account end def object @object ||= fetch_object! end private def bear_cap? @uri.start_with?('bear:') end def fetch_object! if bear_cap? fetch_with_token! else fetch_with_signature! end end def fetch_with_token! perform_request(bear_cap['u'], headers: { 'Authorization' => "Bearer #{bear_cap['t']}" }) end def fetch_with_signature! perform_request(@uri) end def bear_cap @bear_cap ||= Addressable::URI.parse(@uri).query_values end def perform_request(uri, headers: nil) return if invalid_origin?(uri) req = Request.new(:get, uri) req.add_headers('Accept' => 'application/activity+json, application/ld+json') req.add_headers(headers) if headers req.on_behalf_of(@signature_account) if @signature_account req.perform do |res| if res.code == 200 json = body_to_json(res.body_with_limit) json if json.present? && json['id'] == uri else raise Mastodon::UnexpectedResponseError, res unless response_successful?(res) || response_error_unsalvageable?(res) end end end def invalid_origin?(uri) return true if unsupported_uri_scheme?(uri) needle = Addressable::URI.parse(uri).host haystack = Addressable::URI.parse(@permitted_origin).host !haystack.casecmp(needle).zero? end end