federails 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -1
  3. data/app/controllers/federails/client/actors_controller.rb +18 -4
  4. data/app/controllers/federails/server/actors_controller.rb +4 -1
  5. data/app/controllers/federails/server/published_controller.rb +1 -1
  6. data/app/controllers/federails/server/web_finger_controller.rb +9 -6
  7. data/app/controllers/federails/server_controller.rb +7 -0
  8. data/app/models/concerns/federails/actor_entity.rb +40 -8
  9. data/app/models/concerns/federails/data_entity.rb +49 -22
  10. data/app/models/concerns/federails/handles_delete_requests.rb +31 -0
  11. data/app/models/federails/activity.rb +15 -4
  12. data/app/models/federails/actor.rb +87 -31
  13. data/app/models/federails/following.rb +28 -9
  14. data/app/views/federails/client/actors/_actor.json.jbuilder +4 -1
  15. data/app/views/federails/client/actors/gone.html.erb +1 -0
  16. data/app/views/federails/client/actors/index.html.erb +7 -1
  17. data/app/views/federails/server/activities/_activity.activitypub.jbuilder +8 -3
  18. data/app/views/federails/server/actors/_actor.activitypub.jbuilder +2 -2
  19. data/app/views/federails/server/actors/_tombstone.activitypub.jbuilder +9 -0
  20. data/app/views/federails/server/actors/show.activitypub.jbuilder +5 -1
  21. data/app/views/federails/server/published/_tombstone.activitypub.jbuilder +9 -0
  22. data/app/views/federails/server/published/show.activitypub.jbuilder +5 -1
  23. data/db/migrate/20250122160618_add_extensions_to_federails_actors.rb +5 -0
  24. data/db/migrate/20250301082500_add_local_to_actors.rb +11 -0
  25. data/db/migrate/20250329123939_add_actor_type_to_actors.rb +5 -0
  26. data/db/migrate/20250329123940_add_tombstoned_at_to_actors.rb +5 -0
  27. data/lib/federails/configuration.rb +5 -1
  28. data/lib/federails/data_transformer/note.rb +1 -1
  29. data/lib/federails/maintenance/actors_updater.rb +67 -0
  30. data/lib/federails/utils/actor.rb +53 -0
  31. data/lib/federails/utils/object.rb +25 -0
  32. data/lib/federails/version.rb +1 -1
  33. data/lib/fediverse/inbox.rb +25 -4
  34. data/lib/fediverse/webfinger.rb +19 -23
  35. data/lib/tasks/federails_tasks.rake +8 -4
  36. metadata +13 -6
@@ -9,17 +9,21 @@ module Federails
9
9
 
10
10
  belongs_to :actor
11
11
  belongs_to :target_actor, class_name: 'Federails::Actor'
12
- # FIXME: Handle this with something like undelete
13
12
  has_many :activities, as: :entity, dependent: :destroy
14
13
 
15
14
  after_create :after_follow
16
- after_create :create_activity
17
- after_destroy :destroy_activity
15
+ after_create :create_activity, if: :locally_instigated?
16
+ after_update :after_follow_accepted
17
+ after_destroy :destroy_activity, if: :locally_instigated?
18
+
19
+ define_callbacks :on_federails_delete_requested
20
+
21
+ set_callback :on_federails_delete_requested, -> { destroy! unless locally_instigated? }
18
22
 
19
23
  scope :with_actor, ->(actor) { where(actor_id: actor.id).or(where(target_actor_id: actor.id)) }
20
24
 
21
25
  def federated_url
22
- attributes['federated_url'].presence || Federails::Engine.routes.url_helpers.server_actor_following_url(actor_id: actor_id, id: id)
26
+ attributes['federated_url'].presence || Federails::Engine.routes.url_helpers.server_actor_following_url(actor_id: actor.to_param, id: to_param)
23
27
  end
24
28
 
25
29
  def accept!
@@ -27,6 +31,10 @@ module Federails
27
31
  Activity.create! actor: target_actor, action: 'Accept', entity: self
28
32
  end
29
33
 
34
+ def follow_activity
35
+ Activity.find_by actor: actor, action: 'Follow', entity: target_actor
36
+ end
37
+
30
38
  class << self
31
39
  def new_from_account(account, actor:)
32
40
  target_actor = Actor.find_or_create_by_account account
@@ -36,18 +44,29 @@ module Federails
36
44
 
37
45
  private
38
46
 
47
+ def locally_instigated?
48
+ actor.local?
49
+ end
50
+
39
51
  def after_follow
40
- target_actor&.entity&.run_callbacks :followed, :after do
41
- self
42
- end
52
+ return unless target_actor&.entity
53
+
54
+ target_actor.entity.class.send(:dispatch_callback, :after_followed, target_actor.entity, self)
55
+ end
56
+
57
+ def after_follow_accepted
58
+ return unless status_previously_changed? && status == 'accepted'
59
+ return unless actor&.entity
60
+
61
+ actor.entity.class.send(:dispatch_callback, :after_follow_accepted, actor.entity, self)
43
62
  end
44
63
 
45
64
  def create_activity
46
- Activity.create! actor: actor, action: 'Create', entity: self
65
+ Activity.create! actor: actor, action: 'Follow', entity: target_actor
47
66
  end
48
67
 
49
68
  def destroy_activity
50
- Activity.create! actor: actor, action: 'Undo', entity: self
69
+ Activity.create! actor: actor, action: 'Undo', entity: follow_activity
51
70
  end
52
71
  end
53
72
  end
@@ -9,6 +9,9 @@ json.extract! actor,
9
9
  :followings_url,
10
10
  :profile_url,
11
11
  :at_address,
12
- :user_id,
12
+ :local,
13
+ :entity_id,
14
+ :entity_type,
15
+ :tombstoned_at,
13
16
  :created_at,
14
17
  :updated_at
@@ -0,0 +1 @@
1
+ <%= t('.gone') %>
@@ -27,7 +27,13 @@
27
27
  <% end %>
28
28
  <% @actors.each do |actor| %>
29
29
  <tr>
30
- <td><%= actor.name %></td>
30
+ <td>
31
+ <% if actor.tombstoned? %>
32
+ <del><%= actor.name %></del>
33
+ <% else %>
34
+ <%= actor.name %>
35
+ <% end %>
36
+ </td>
31
37
  <td><%= actor.username %></td>
32
38
  <td><%= actor.at_address %></td>
33
39
  <td><%= actor.local? %></td>
@@ -1,13 +1,18 @@
1
1
  context = true unless context == false
2
+ addressing = true unless addressing == false
2
3
  json.set! '@context', 'https://www.w3.org/ns/activitystreams' if context
3
4
 
4
5
  json.id Federails::Engine.routes.url_helpers.server_actor_activity_url activity.actor, activity
5
6
  json.type activity.action
6
7
  json.actor activity.actor.federated_url
7
- json.to ['https://www.w3.org/ns/activitystreams#Public']
8
- json.cc [activity.actor.followers_url]
8
+ if addressing
9
+ json.to ['https://www.w3.org/ns/activitystreams#Public']
10
+ json.cc [activity.actor.followers_url]
11
+ end
9
12
 
10
- if activity.entity.respond_to? :to_activitypub_object
13
+ if activity.entity.is_a? Federails::Activity
14
+ json.object { json.partial!('federails/server/activities/activity', activity: activity.entity, context: false, addressing: false) }
15
+ elsif activity.entity.respond_to? :to_activitypub_object
11
16
  json.object activity.entity.to_activitypub_object
12
17
  elsif activity.entity.respond_to? :federated_url
13
18
  json.object activity.entity.federated_url
@@ -1,4 +1,4 @@
1
- actor_data = actor.entity.to_activitypub_object
1
+ actor_data = actor.entity&.to_activitypub_object || {}
2
2
 
3
3
  json.set! '@context', ([
4
4
  'https://www.w3.org/ns/activitystreams',
@@ -9,7 +9,7 @@ json.set! '@context', ([
9
9
 
10
10
  json.id actor.federated_url
11
11
  json.name actor.name
12
- json.type actor.entity_configuration[:actor_type]
12
+ json.type actor.actor_type
13
13
  json.preferredUsername actor.username
14
14
  json.inbox actor.inbox_url
15
15
  json.outbox actor.outbox_url
@@ -0,0 +1,9 @@
1
+ json.set! '@context', [
2
+ 'https://www.w3.org/ns/activitystreams',
3
+ 'https://w3id.org/security/v1',
4
+ ]
5
+
6
+ json.id actor.federated_url
7
+ json.type 'Tombstone'
8
+ json.deleted actor.tombstoned_at
9
+ json.formerType actor.actor_type
@@ -1 +1,5 @@
1
- json.partial! 'federails/server/actors/actor', actor: @actor
1
+ if @actor.tombstoned?
2
+ json.partial! 'federails/server/actors/tombstone', actor: @actor
3
+ else
4
+ json.partial! 'federails/server/actors/actor', actor: @actor
5
+ end
@@ -0,0 +1,9 @@
1
+ json.set! '@context', [
2
+ 'https://www.w3.org/ns/activitystreams',
3
+ 'https://w3id.org/security/v1',
4
+ ]
5
+
6
+ json.id publishable.federated_url
7
+ json.type 'Tombstone'
8
+ json.deleted publishable.federails_tombstoned_at
9
+ json.formerType publishable.federails_data_configuration[:handles]
@@ -1 +1,5 @@
1
- json.partial! 'federails/server/published/publishable', publishable: @publishable
1
+ if @publishable.federails_tombstoned?
2
+ json.partial! 'federails/server/published/tombstone', publishable: @publishable
3
+ else
4
+ json.partial! 'federails/server/published/publishable', publishable: @publishable
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddExtensionsToFederailsActors < ActiveRecord::Migration[7.1]
2
+ def change
3
+ add_column :federails_actors, :extensions, :json, default: nil, null: true
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class AddLocalToActors < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :federails_actors, :local, :boolean, null: false, default: false
4
+
5
+ reversible do |dir|
6
+ dir.up do
7
+ exec_update 'UPDATE federails_actors SET local=true WHERE entity_type IS NOT NULL'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddActorTypeToActors < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :federails_actors, :actor_type, :string, null: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddTombstonedAtToActors < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :federails_actors, :tombstoned_at, :datetime, default: nil
4
+ end
5
+ end
@@ -28,8 +28,12 @@ module Federails
28
28
  @@enable_discovery = true
29
29
 
30
30
  # Does the site allow open registrations? (only used for nodeinfo reporting)
31
- mattr_accessor :open_registrations
31
+ # Can either be a static boolean, or a Proc which will be called to get the state.
32
+ mattr_writer :open_registrations
32
33
  @@open_registrations = false
34
+ def self.open_registrations
35
+ @@open_registrations.is_a?(Proc) ? @@open_registrations.call : @@open_registrations
36
+ end
33
37
 
34
38
  # Application layout
35
39
  mattr_accessor :app_layout
@@ -3,7 +3,7 @@ module Federails
3
3
  module Note
4
4
  # Renders a Note. The entity is used to determine actor and generic fields data
5
5
  #
6
- # @param entity [#federail_actor] A model instance
6
+ # @param entity [#federail_actor, #federated_url, #created_at, #updated_at] A model instance
7
7
  # @param content [String] Note content
8
8
  # @param name [String, nil] Optional name/title
9
9
  # @param custom [Hash] Optional additional keys (e.g.: attachment, icon, ...). Defaults will override these.
@@ -0,0 +1,67 @@
1
+ module Federails
2
+ module Maintenance
3
+ class ActorsUpdater
4
+ class << self
5
+ # Fetches all distant actors again and update their local copy
6
+ #
7
+ # A block can be passed with two arguments: the actor being updated and the update status
8
+ #
9
+ # @param actors [Integer, Federails::Actor, Array<Federails::Actor>, nil] Actor ID, Actor or list of actors to update.
10
+ # If nothing is passed, all distant actors are processed
11
+ # @example
12
+ # Update all distant actors
13
+ # Federails::Maintenance::ActorUpdater.run
14
+ # With an actor id:
15
+ # Federails::Maintenance::ActorUpdater.run 1
16
+ # With a federated URL:
17
+ # Federails::Maintenance::ActorUpdater.run 'https://example.com/actor'
18
+ # With a federated URL:
19
+ # Federails::Maintenance::ActorUpdater.run ['https://example.com/actors/1', 'https://example.com/actors/1']
20
+ # With actors:
21
+ # Federails::Maintenance::ActorUpdater.run Federails::Actor.last(10)
22
+ # Update all distant actors and puts status for each actor
23
+ # Federails::Maintenance::ActorUpdater.run {|actor, status| puts "#{actor.federated_url}: #{status}"}
24
+ def run(actors = nil, &block)
25
+ actors_list(actors).each do |actor|
26
+ status = update(actor)
27
+
28
+ yield(actor, status) if block
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # Make a list of actors to update from the passed attribute
35
+ def actors_list(param) # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize
36
+ if param.nil?
37
+ Federails::Actor.distant
38
+ elsif param.is_a? String
39
+ [Federails::Actor.distant.find_by!(federated_url: param)]
40
+ elsif param.is_a? Integer
41
+ [Federails::Actor.distant.find(param)]
42
+ elsif param.is_a?(Federails::Actor)
43
+ [param]
44
+ elsif param.respond_to?(:pluck) && param.first.is_a?(Federails::Actor)
45
+ param
46
+ elsif param.is_a?(Array) && param.first.is_a?(String)
47
+ Federails::Actor.distant.where(federated_url: param)
48
+ else
49
+ raise "Cannot extract actors from #{param.class}"
50
+ end
51
+ end
52
+
53
+ # @param actor [Federails::Actor]
54
+ def update(actor)
55
+ return :ignored_local if actor.local?
56
+
57
+ response = Fediverse::Webfinger.fetch_actor_url(actor.federated_url)
58
+ new_attributes = response.attributes.except 'id', 'uuid', 'created_at', 'updated_at', 'local'
59
+
60
+ actor.update(new_attributes) ? :updated : :failed
61
+ rescue ActiveRecord::RecordNotFound
62
+ :not_found
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,53 @@
1
+ module Federails
2
+ module Utils
3
+ class Actor
4
+ # List of the attributes computed for local actors
5
+ COMPUTED_ATTRIBUTES = [
6
+ :federated_url,
7
+ :username,
8
+ :name,
9
+ :server,
10
+ :inbox_url,
11
+ :outbox_url,
12
+ :followers_url,
13
+ :followings_url,
14
+ :profile_url,
15
+ ].freeze
16
+
17
+ class << self
18
+ # @param actor [Federails::Actor]
19
+ # @return [Federails::Actor]
20
+ def tombstone!(actor)
21
+ if actor.local?
22
+ tombstone_local_actor actor
23
+ else
24
+ tombstone_distant_actor actor
25
+ end
26
+
27
+ actor
28
+ end
29
+
30
+ private
31
+
32
+ def tombstone_local_actor(actor)
33
+ Federails::Actor.transaction do
34
+ hash = {
35
+ tombstoned_at: Time.current,
36
+ entity: nil,
37
+ }
38
+ # Hardcode attributes depending on the actor's entity
39
+ COMPUTED_ATTRIBUTES.each { |attribute| hash[attribute] = actor.send(attribute) }
40
+
41
+ actor.update! hash
42
+
43
+ Activity.create! actor: actor, action: 'Delete', entity: actor
44
+ end
45
+ end
46
+
47
+ def tombstone_distant_actor(actor)
48
+ actor.update! tombstoned_at: Time.current
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -20,6 +20,31 @@ module Federails
20
20
  from_distant_server(object_or_id)
21
21
  end
22
22
 
23
+ # Search for a distant object in actors and configured data entities.
24
+ #
25
+ # This is useful to find something when the type is unknown, as an object from a Delete activity.
26
+ #
27
+ # @param federated_url [String] Object identifier
28
+ # @return [Federails::Actor, Federails::DataEntity, Federails::Following, nil]
29
+ def find_distant_object_in_all(federated_url)
30
+ # Search in actors
31
+ object = Federails::Actor.find_by federated_url: federated_url
32
+ return object if object.present?
33
+
34
+ # Search in followings
35
+ object = Federails::Following.find_by federated_url: federated_url
36
+ return object if object.present?
37
+
38
+ # Search in data entities
39
+ Federails.configuration.data_types.keys.sort.each do |klass|
40
+ object = klass.constantize.find_by federated_url: federated_url
41
+
42
+ break if object.present?
43
+ end
44
+
45
+ object
46
+ end
47
+
23
48
  # Finds or initializes an entity from an ActivityPub object or id
24
49
  #
25
50
  # @see .find_or_initialize
@@ -1,3 +1,3 @@
1
1
  module Federails
2
- VERSION = '0.5.0'.freeze
2
+ VERSION = '0.6.0'.freeze
3
3
  end
@@ -6,6 +6,9 @@ module Fediverse
6
6
  class << self
7
7
  # Registers a handler for incoming data
8
8
  #
9
+ # Unless a specific type is not implemented in Federails, you should leave the 'Delete' activity to Federails:
10
+ # it will dispatch a `on_federails_delete_requested` event on the right objects.
11
+ #
9
12
  # @param activity_type [String] Target activity type ('Create', 'Follow', 'Like', ...)
10
13
  # See https://www.w3.org/TR/activitystreams-vocabulary/#activity-types for a list of common ones
11
14
  # @param object_type [String] Type of the related object ('Article', 'Note', ...)
@@ -22,6 +25,8 @@ module Fediverse
22
25
  #
23
26
  # @param payload [Hash] Dereferenced activity
24
27
  def dispatch_request(payload)
28
+ return dispatch_delete_request(payload) if payload['type'] == 'Delete'
29
+
25
30
  payload['object'] = Fediverse::Request.dereference(payload['object']) if payload.key? 'object'
26
31
 
27
32
  handlers = get_handlers(payload['type'], payload.dig('object', 'type'))
@@ -36,6 +41,14 @@ module Fediverse
36
41
 
37
42
  private
38
43
 
44
+ def dispatch_delete_request(payload)
45
+ payload['object'] = payload['object']['id'] unless payload['object'].is_a? String
46
+ object = Federails::Utils::Object.find_distant_object_in_all payload['object']
47
+ return if object.blank?
48
+
49
+ object.run_callbacks :on_federails_delete_requested
50
+ end
51
+
39
52
  def get_handlers(activity_type, object_type)
40
53
  {}.merge(@@handlers.dig(activity_type, object_type) || {})
41
54
  .merge(@@handlers.dig(activity_type, '*') || {})
@@ -50,7 +63,7 @@ module Fediverse
50
63
  Federails::Following.create! actor: actor, target_actor: target_actor, federated_url: activity['id']
51
64
  end
52
65
 
53
- def handle_accept_request(activity)
66
+ def handle_accept_follow_request(activity)
54
67
  original_activity = Request.dereference(activity['object'])
55
68
 
56
69
  actor = Federails::Actor.find_or_create_by_object original_activity['actor']
@@ -61,7 +74,7 @@ module Fediverse
61
74
  follow.accept!
62
75
  end
63
76
 
64
- def handle_undo_request(activity)
77
+ def handle_undo_follow_request(activity)
65
78
  original_activity = activity['object']
66
79
 
67
80
  actor = Federails::Actor.find_or_create_by_object original_activity['actor']
@@ -70,10 +83,18 @@ module Fediverse
70
83
  follow = Federails::Following.find_by actor: actor, target_actor: target_actor
71
84
  follow&.destroy
72
85
  end
86
+
87
+ def handle_delete_request(activity)
88
+ object = Federails::Utils::Object.find_distant_object_in_all(activity['object'])
89
+ return if object.blank?
90
+
91
+ object.run_callbacks :on_federails_delete_requested
92
+ end
73
93
  end
74
94
 
75
95
  register_handler 'Follow', '*', self, :handle_create_follow_request
76
- register_handler 'Accept', 'Follow', self, :handle_accept_request
77
- register_handler 'Undo', 'Follow', self, :handle_undo_request
96
+ register_handler 'Accept', 'Follow', self, :handle_accept_follow_request
97
+ register_handler 'Undo', 'Follow', self, :handle_undo_follow_request
98
+ register_handler 'Delete', '*', self, :handle_delete_request
78
99
  end
79
100
  end
@@ -9,22 +9,14 @@ module Fediverse
9
9
  class << self
10
10
  ACCOUNT_REGEX = /(?<username>[a-z0-9\-_.]+)(?:@(?<domain>.*))?/
11
11
 
12
- # Extracts username and domain from a "acct:username@domain" string
13
- #
14
- # @param account [String] Account string
15
- #
16
- # @return [MatchData, nil] Matches with +:username+ and +:domain+ or +nil+
17
- def split_resource_account(account)
18
- /\Aacct:#{ACCOUNT_REGEX}\z/io.match account
19
- end
20
-
21
- # Extracts username and domain from a "username@domain" string
12
+ # Extracts username and domain from an account string.
13
+ # Accepts forms "user@domain", "@user@domain" and "acct:user@domain"
22
14
  #
23
15
  # @param account [String] Account string
24
16
  #
25
17
  # @return [MatchData, nil] Matches with +:username+ and +:domain+ or +nil+
26
18
  def split_account(account)
27
- /\A#{ACCOUNT_REGEX}\z/io.match account
19
+ /\A(acct:|@)?#{ACCOUNT_REGEX}\z/io.match account
28
20
  end
29
21
 
30
22
  # Determines if a given account string should be a local account (same host as configured one)
@@ -63,7 +55,7 @@ module Fediverse
63
55
  # @return [String, nil] Federation URL if found
64
56
  def webfinger(username, domain)
65
57
  json = webfinger_response(username, domain)
66
- link = json['links'].find { |l| l['type'] == 'application/activity+json' }
58
+ link = json['links'].find { |l| Mime::Type.lookup(l['type']).to_sym == :activitypub }
67
59
 
68
60
  link['href'] if link
69
61
  end
@@ -110,17 +102,21 @@ module Fediverse
110
102
  # Builds a +Federails::Actor+ from a Webfinger response
111
103
  # @param data [Hash] Webfinger response
112
104
  # @return [Federails::Actor]
113
- def webfinger_to_actor(data)
114
- Federails::Actor.new federated_url: data['id'],
115
- username: data['preferredUsername'],
116
- name: data['name'],
117
- server: server_and_port(data['id']),
118
- inbox_url: data['inbox'],
119
- outbox_url: data['outbox'],
120
- followers_url: data['followers'],
121
- followings_url: data['following'],
122
- profile_url: data['url'],
123
- public_key: data.dig('publicKey', 'publicKeyPem')
105
+ def webfinger_to_actor(data) # rubocop:disable Metrics/MethodLength
106
+ data = data.clone
107
+ id = data.delete('id')
108
+ Federails::Actor.new federated_url: id,
109
+ username: data.delete('preferredUsername'),
110
+ actor_type: data.delete('type'),
111
+ name: data.delete('name'),
112
+ server: server_and_port(id),
113
+ inbox_url: data.delete('inbox'),
114
+ outbox_url: data.delete('outbox'),
115
+ followers_url: data.delete('followers'),
116
+ followings_url: data.delete('following'),
117
+ profile_url: data.delete('url'),
118
+ public_key: data.delete('publicKey')&.dig('publicKeyPem'),
119
+ extensions: data.except('@context')
124
120
  end
125
121
 
126
122
  # Makes a simple GET request and returns a +Hash+ from the parsed body
@@ -1,4 +1,8 @@
1
- # desc "Explaining what the task does"
2
- # task :federails do
3
- # # Task goes here
4
- # end
1
+ namespace :federails do
2
+ desc 'Re-fetches every remote actors to update database'
3
+ task sync_actors: :environment do
4
+ Federails::Maintenance::ActorUpdater.run do |actor, status|
5
+ puts "#{actor.federated_url}: #{status}"
6
+ end
7
+ end
8
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: federails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Tancoigne
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-01-22 00:00:00.000000000 Z
10
+ date: 2025-04-07 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -137,6 +136,7 @@ files:
137
136
  - app/mailers/federails/application_mailer.rb
138
137
  - app/models/concerns/federails/actor_entity.rb
139
138
  - app/models/concerns/federails/data_entity.rb
139
+ - app/models/concerns/federails/handles_delete_requests.rb
140
140
  - app/models/concerns/federails/has_uuid.rb
141
141
  - app/models/federails/activity.rb
142
142
  - app/models/federails/actor.rb
@@ -159,6 +159,7 @@ files:
159
159
  - app/views/federails/client/activities/index.json.jbuilder
160
160
  - app/views/federails/client/actors/_actor.json.jbuilder
161
161
  - app/views/federails/client/actors/_lookup_form.html.erb
162
+ - app/views/federails/client/actors/gone.html.erb
162
163
  - app/views/federails/client/actors/index.html.erb
163
164
  - app/views/federails/client/actors/index.json.jbuilder
164
165
  - app/views/federails/client/actors/show.html.erb
@@ -177,6 +178,7 @@ files:
177
178
  - app/views/federails/server/activities/outbox.activitypub.jbuilder
178
179
  - app/views/federails/server/activities/show.activitypub.jbuilder
179
180
  - app/views/federails/server/actors/_actor.activitypub.jbuilder
181
+ - app/views/federails/server/actors/_tombstone.activitypub.jbuilder
180
182
  - app/views/federails/server/actors/followers.activitypub.jbuilder
181
183
  - app/views/federails/server/actors/following.activitypub.jbuilder
182
184
  - app/views/federails/server/actors/show.activitypub.jbuilder
@@ -185,6 +187,7 @@ files:
185
187
  - app/views/federails/server/nodeinfo/index.nodeinfo.jbuilder
186
188
  - app/views/federails/server/nodeinfo/show.nodeinfo.jbuilder
187
189
  - app/views/federails/server/published/_publishable.activitypub.jbuilder
190
+ - app/views/federails/server/published/_tombstone.activitypub.jbuilder
188
191
  - app/views/federails/server/published/show.activitypub.jbuilder
189
192
  - app/views/federails/server/web_finger/find.jrd.jbuilder
190
193
  - app/views/federails/server/web_finger/host_meta.xrd.erb
@@ -195,10 +198,16 @@ files:
195
198
  - db/migrate/20200712174938_create_federails_activities.rb
196
199
  - db/migrate/20241002094500_add_uuids.rb
197
200
  - db/migrate/20241002094501_add_keypair_to_actors.rb
201
+ - db/migrate/20250122160618_add_extensions_to_federails_actors.rb
202
+ - db/migrate/20250301082500_add_local_to_actors.rb
203
+ - db/migrate/20250329123939_add_actor_type_to_actors.rb
204
+ - db/migrate/20250329123940_add_tombstoned_at_to_actors.rb
198
205
  - lib/federails.rb
199
206
  - lib/federails/configuration.rb
200
207
  - lib/federails/data_transformer/note.rb
201
208
  - lib/federails/engine.rb
209
+ - lib/federails/maintenance/actors_updater.rb
210
+ - lib/federails/utils/actor.rb
202
211
  - lib/federails/utils/host.rb
203
212
  - lib/federails/utils/object.rb
204
213
  - lib/federails/version.rb
@@ -224,7 +233,6 @@ metadata:
224
233
  homepage_uri: https://experimentslabs.com
225
234
  source_code_uri: https://gitlab.com/experimentslabs/federails/
226
235
  changelog_uri: https://gitlab.com/experimentslabs/federails/-/blob/main/CHANGELOG.md
227
- post_install_message:
228
236
  rdoc_options: []
229
237
  require_paths:
230
238
  - lib
@@ -239,8 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
239
247
  - !ruby/object:Gem::Version
240
248
  version: '0'
241
249
  requirements: []
242
- rubygems_version: 3.5.23
243
- signing_key:
250
+ rubygems_version: 3.6.5
244
251
  specification_version: 4
245
252
  summary: An ActivityPub engine for Ruby on Rails
246
253
  test_files: []