federails 0.2.0 → 0.3.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -2
  3. data/app/controllers/federails/client/activities_controller.rb +8 -2
  4. data/app/controllers/federails/client/actors_controller.rb +4 -1
  5. data/app/controllers/federails/client/followings_controller.rb +4 -2
  6. data/app/controllers/federails/client_controller.rb +9 -0
  7. data/app/controllers/federails/server/activities_controller.rb +6 -1
  8. data/app/controllers/federails/server/actors_controller.rb +5 -1
  9. data/app/controllers/federails/server/followings_controller.rb +1 -1
  10. data/app/controllers/federails/server/nodeinfo_controller.rb +11 -5
  11. data/app/controllers/federails/server/web_finger_controller.rb +5 -1
  12. data/app/controllers/federails/{application_controller.rb → server_controller.rb} +6 -3
  13. data/app/helpers/federails/{application_helper.rb → server_helper.rb} +1 -1
  14. data/app/models/concerns/federails/entity.rb +55 -14
  15. data/app/models/federails/actor.rb +3 -1
  16. data/app/policies/federails/client/activity_policy.rb +3 -0
  17. data/app/policies/federails/client/actor_policy.rb +1 -1
  18. data/app/policies/federails/client/following_policy.rb +2 -2
  19. data/app/policies/federails/federails_policy.rb +4 -0
  20. data/app/policies/federails/server/activity_policy.rb +3 -0
  21. data/app/views/federails/client/activities/_activity.html.erb +1 -1
  22. data/app/views/federails/client/activities/feed.html.erb +8 -1
  23. data/app/views/federails/client/activities/index.html.erb +1 -1
  24. data/app/views/federails/client/actors/index.html.erb +14 -0
  25. data/app/views/federails/client/actors/show.html.erb +101 -89
  26. data/app/views/federails/client/common/_client_links.html.erb +24 -0
  27. data/app/views/federails/client/followings/_follow_actions.html.erb +32 -0
  28. data/app/views/federails/client/followings/_form.html.erb +1 -0
  29. data/app/views/federails/server/actors/_actor.activitypub.jbuilder +7 -2
  30. data/app/views/federails/server/nodeinfo/show.nodeinfo.jbuilder +8 -7
  31. data/config/initializers/mime_types.rb +1 -1
  32. data/config/routes.rb +6 -2
  33. data/db/migrate/20200712133150_create_federails_actors.rb +3 -5
  34. data/lib/federails/configuration.rb +9 -30
  35. data/lib/federails/version.rb +1 -1
  36. data/lib/federails.rb +11 -4
  37. data/lib/fediverse/inbox.rb +33 -37
  38. data/lib/fediverse/notifier.rb +1 -1
  39. data/lib/generators/federails/copy_client_views/USAGE +8 -0
  40. data/lib/generators/federails/copy_client_views/copy_client_views_generator.rb +9 -0
  41. data/lib/generators/federails/install/install_generator.rb +2 -2
  42. data/lib/generators/federails/install/templates/federails.yml +2 -0
  43. metadata +10 -7
  44. data/app/controllers/federails/server/server_controller.rb +0 -17
  45. data/db/migrate/20240731145400_change_actor_entity_rel_to_polymorphic.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 070da5d2cc3d016475a69f797c6280595618d5f60de95cf7506bb2a1e9cbce4c
4
- data.tar.gz: a954535a092fa71fdb911f973363d8372b6d56e42b32190394e92026567c6913
3
+ metadata.gz: e489a0088b05ef80d9cc112164f054a030f0cb007406cb14789372a5a52c490f
4
+ data.tar.gz: b6832c622e5c33bf85f520839604a9e6e516821097d70bb6c6acb7df92f0d4b3
5
5
  SHA512:
6
- metadata.gz: 69fba1438beef26a150079c2a39eb185903025dcad3c24f5dfee941d844710d12938cf5546f0dc488f725096a2c4e6f32dfba4d1d3c825b9ba9418f063bb4ec9
7
- data.tar.gz: 01ef6821f7b1aa9422f013e23ed20b1225f0e630d4925ca81c7490f43d790a1d77a3b93e8d72783d93aee59f1760b48bbdd71a59feca353bca0a1277a6bd03c0
6
+ metadata.gz: 59e24e51b83545daabfa7dc0c878183d8b0bc14276b559b529fb5ee48183739c49b1a1987eb4a5e8d0d795dcfbe6970d6a3478691f9a13cd12c399903df61695
7
+ data.tar.gz: 01f6e7bef60bd2d15e142b7b55fecf25dd76ab67571c994c3c8aae1eba23fbcc75d02fb03775131a070b3cc6c18021d33ce91bb8645e937d94c1425a0a7433a3
data/README.md CHANGED
@@ -92,7 +92,7 @@ With `routes_path = 'federation'`, routes will be:
92
92
 
93
93
  Some routes can be disabled in configuration if you don't want to expose particular features:
94
94
 
95
- ```
95
+ ```rb
96
96
  Federails.configure do |config|
97
97
  # Disable routing for .well-known and nodeinfo
98
98
  config.enable_discovery = false
@@ -107,7 +107,7 @@ end
107
107
  By default, remote follow requests (where you press a follow button on another server and get redirected home to complete the follow)
108
108
  will use the built-in client paths. If you're not using the client, or want to provide your own user interface, you can set the path like this, assuming that `new_follow_url` is a valid route in your app. A `uri` query parameter template will be automatically appended, you don't need to specify that.
109
109
 
110
- ```
110
+ ```rb
111
111
  Federails.configure do |config|
112
112
  config.remote_follow_url_method = :new_follow_url
113
113
  end
@@ -154,6 +154,32 @@ actor.following
154
154
  #...
155
155
  ```
156
156
 
157
+ ### Using the Federails client
158
+
159
+ Federails comes with a client, enabled by default, that provides basic views to display and interact with Federails data,
160
+ accessible on `/app` by default (changeable with the configuration option `client_routes_path`)
161
+
162
+ If it's a good starting point, it might be disabled once you made your own integration by setting `client_routes_path`
163
+ to a `nil` value.
164
+
165
+ If you want to override the client's views, copy them in your application:
166
+
167
+ ```sh
168
+ rails generate federails:copy_client_views
169
+ ```
170
+
171
+ ## Common questions
172
+
173
+ - **I override the base controller and the links breaks in my layout**
174
+
175
+ Use `main_app.<url_helper>` for links to your application; `federails.<federails_url_helper>` for links to the Federails client.
176
+ - **I specified a custom layout and the links breaks in it**
177
+
178
+ Use `main_app.<url_helper>` for links to your application; `federails.<federails_url_helper>` for links to the Federails client.
179
+ - **I specified a custom layout and my helpers are not available**
180
+
181
+ You will have better results if you specify a `base_controller` from your application as Federails base controller is isolated from the main app and does not have access to its helpers.
182
+
157
183
  ## Contributing
158
184
 
159
185
  Contributions are welcome, may it be issues, ideas, code or whatever you want to share. Please note:
@@ -1,8 +1,8 @@
1
1
  module Federails
2
2
  module Client
3
- class ActivitiesController < Federails::ApplicationController
3
+ class ActivitiesController < Federails::ClientController
4
4
  before_action :authenticate_user!, only: [:feed]
5
- # layout 'layouts/application'
5
+ before_action :authorize_action!
6
6
 
7
7
  # GET /app/activities
8
8
  # GET /app/activities.json
@@ -16,6 +16,12 @@ module Federails
16
16
  def feed
17
17
  @activities = Activity.feed_for(current_user.actor)
18
18
  end
19
+
20
+ private
21
+
22
+ def authorize_action!
23
+ authorize(Federails::Activity, policy_class: Federails::Client::ActivityPolicy)
24
+ end
19
25
  end
20
26
  end
21
27
  end
@@ -1,12 +1,15 @@
1
1
  module Federails
2
2
  module Client
3
- class ActorsController < Federails::ApplicationController
3
+ class ActorsController < Federails::ClientController
4
4
  before_action :set_actor, only: [:show]
5
5
 
6
6
  # GET /app/actors
7
7
  # GET /app/actors.json
8
8
  def index
9
+ authorize Federails::Actor, policy_class: Federails::Client::ActorPolicy
10
+
9
11
  @actors = policy_scope(Federails::Actor, policy_scope_class: Federails::Client::ActorPolicy::Scope).all
12
+ @actors = @actors.local if params[:local_only]
10
13
  end
11
14
 
12
15
  # GET /app/actors/1
@@ -1,7 +1,8 @@
1
1
  module Federails
2
2
  module Client
3
- class FollowingsController < Federails::ApplicationController
3
+ class FollowingsController < Federails::ClientController
4
4
  before_action :authenticate_user!
5
+ before_action :skip_authorization, only: [:new, :create]
5
6
  before_action :set_following, only: [:accept, :destroy]
6
7
 
7
8
  # GET /app/followings/new?uri={uri}
@@ -40,9 +41,10 @@ module Federails
40
41
  # POST /app/followings/follow
41
42
  # POST /app/followings/follow.json
42
43
  def follow
44
+ authorize Federails::Following, policy_class: Federails::Client::FollowingPolicy
45
+
43
46
  begin
44
47
  @following = Following.new_from_account following_account_params, actor: current_user.actor
45
- authorize @following, policy_class: Federails::Client::FollowingPolicy
46
48
  rescue ::ActiveRecord::RecordNotFound
47
49
  # Renders a 422 instead of a 404
48
50
  respond_to do |format|
@@ -0,0 +1,9 @@
1
+ module Federails
2
+ class ClientController < Federails.configuration.base_client_controller.constantize
3
+ include Pundit::Authorization
4
+
5
+ after_action :verify_authorized
6
+
7
+ layout Federails.configuration.app_layout if Federails.configuration.app_layout
8
+ end
9
+ end
@@ -2,12 +2,14 @@ require 'fediverse/inbox'
2
2
 
3
3
  module Federails
4
4
  module Server
5
- class ActivitiesController < ServerController
5
+ class ActivitiesController < Federails::ServerController
6
6
  before_action :set_activity, only: [:show]
7
7
 
8
8
  # GET /federation/activities
9
9
  # GET /federation/actors/1/outbox.json
10
10
  def outbox
11
+ authorize Federails::Activity, policy_class: Federails::Server::ActivityPolicy
12
+
11
13
  @actor = Actor.find_param(params[:actor_id])
12
14
  @activities = policy_scope(Federails::Activity, policy_scope_class: Federails::Server::ActivityPolicy::Scope).where(actor: @actor).order(created_at: :desc)
13
15
  @total_activities = @activities.count
@@ -19,6 +21,8 @@ module Federails
19
21
 
20
22
  # POST /federation/actors/1/inbox
21
23
  def create
24
+ skip_authorization
25
+
22
26
  payload = payload_from_params
23
27
  return head :unprocessable_entity unless payload
24
28
 
@@ -34,6 +38,7 @@ module Federails
34
38
  # Use callbacks to share common setup or constraints between actions.
35
39
  def set_activity
36
40
  @activity = Actor.find_param(params[:actor_id]).activities.find_param(params[:id])
41
+ authorize @activity, policy_class: Federails::Server::ActivityPolicy
37
42
  end
38
43
 
39
44
  # Only allow a list of trusted parameters through.
@@ -1,17 +1,21 @@
1
1
  module Federails
2
2
  module Server
3
- class ActorsController < ServerController
3
+ class ActorsController < Federails::ServerController
4
4
  before_action :set_actor, only: [:show, :followers, :following]
5
5
 
6
6
  # GET /federation/actors/1
7
7
  # GET /federation/actors/1.json
8
8
  def show; end
9
9
 
10
+ # GET /federation/actors/:id/followers
11
+ # GET /federation/actors/:id/followers.json
10
12
  def followers
11
13
  @actors = @actor.followers.order(created_at: :desc)
12
14
  followings_queries
13
15
  end
14
16
 
17
+ # GET /federation/actors/:id/followers
18
+ # GET /federation/actors/:id/followers.json
15
19
  def following
16
20
  @actors = @actor.follows.order(created_at: :desc)
17
21
  followings_queries
@@ -1,6 +1,6 @@
1
1
  module Federails
2
2
  module Server
3
- class FollowingsController < ServerController
3
+ class FollowingsController < Federails::ServerController
4
4
  before_action :set_following, only: [:show]
5
5
 
6
6
  # GET /federation/actors/1/followings/1.json
@@ -1,19 +1,25 @@
1
1
  module Federails
2
2
  module Server
3
- class NodeinfoController < ServerController
3
+ class NodeinfoController < Federails::ServerController
4
4
  def index
5
+ skip_authorization
6
+
5
7
  render formats: [:nodeinfo]
6
8
  end
7
9
 
8
10
  def show # rubocop:todo Metrics/AbcSize
11
+ skip_authorization
12
+
9
13
  @total = @active_halfyear = @active_month = 0
14
+ @has_user_counts = false
10
15
  Federails::Configuration.entity_types.each_value do |config|
11
- next unless config[:include_in_user_count]
16
+ next unless (method = config[:user_count_method]&.to_sym)
12
17
 
18
+ @has_user_counts = true
13
19
  model = config[:class]
14
- @total += model.count
15
- @active_month += model.where(created_at: ((30.days.ago)...Time.current)).count
16
- @active_halfyear += model.where(created_at: ((180.days.ago)...Time.current)).count
20
+ @total += model.send(method, nil)
21
+ @active_month += model.send(method, ((30.days.ago)...Time.current))
22
+ @active_halfyear += model.send(method, ((180.days.ago)...Time.current))
17
23
  end
18
24
  render formats: [:nodeinfo]
19
25
  end
@@ -2,8 +2,10 @@ require 'fediverse/webfinger'
2
2
 
3
3
  module Federails
4
4
  module Server
5
- class WebFingerController < ServerController
5
+ class WebFingerController < Federails::ServerController
6
6
  def find
7
+ skip_authorization
8
+
7
9
  resource = params.require(:resource)
8
10
  case resource
9
11
  when %r{^https?://.+}
@@ -19,6 +21,8 @@ module Federails
19
21
  end
20
22
 
21
23
  def host_meta
24
+ skip_authorization
25
+
22
26
  render formats: [:xrd]
23
27
  end
24
28
 
@@ -1,10 +1,13 @@
1
1
  module Federails
2
- class ApplicationController < ActionController::Base
2
+ class ServerController < ::ActionController::Base # rubocop:disable Rails/ApplicationController
3
3
  include Pundit::Authorization
4
4
 
5
- rescue_from ActiveRecord::RecordNotFound, with: :error_not_found
5
+ after_action :verify_authorized
6
+
7
+ protect_from_forgery with: :null_session
8
+ helper Federails::ServerHelper
6
9
 
7
- layout Federails.configuration.app_layout if Federails.configuration.app_layout
10
+ rescue_from ActiveRecord::RecordNotFound, with: :error_not_found
8
11
 
9
12
  private
10
13
 
@@ -1,5 +1,5 @@
1
1
  module Federails
2
- module ApplicationHelper
2
+ module ServerHelper
3
3
  def remote_follow_url
4
4
  method_name = Federails.configuration.remote_follow_url_method.to_s
5
5
  if method_name.starts_with? 'federails.'
@@ -14,38 +14,79 @@ module Federails
14
14
  set_callback :followed, :after, method
15
15
  end
16
16
 
17
+ # Define a method that will be called after an activity has been received
18
+ # @param activity_type [String] The activity action to handle, e.g. 'Create'. If you specify '*', the handler will be called for any activity type.
19
+ # @param object_type [String] The object type to handle, e.g. 'Note'. If you specify '*', the handler will be called for any object type.
20
+ # @param method [Symbol] The name of the class method to call. The method will receive the complete activity payload as a parameter.
21
+ # @example
22
+ # after_activity_received 'Create', 'Note', :create_note
23
+ def self.after_activity_received(activity_type, object_type, method)
24
+ Fediverse::Inbox.register_handler(activity_type, object_type, self, method)
25
+ end
26
+
17
27
  has_one :actor, class_name: 'Federails::Actor', as: :entity, dependent: :destroy
18
28
 
19
- after_create :create_actor
29
+ after_create :create_actor, if: lambda {
30
+ raise("Entity not configured for #{self.class.name}. Did you use \"acts_as_federails_actor\"?") unless Federails::Configuration.entity_types.key? self.class.name
31
+
32
+ Federails::Configuration.entity_types[self.class.name][:auto_create_actors]
33
+ }
20
34
 
21
35
  # Configures the mapping between entity and actor
22
36
  # @param username_field [Symbol] The method or attribute name that returns the preferred username for ActivityPub
23
37
  # @param name_field [Symbol] The method or attribute name that returns the preferred name for ActivityPub
24
38
  # @param profile_url_method [Symbol] The route method name that will generate the profile URL for ActivityPub
25
39
  # @param actor_type [String] The ActivityStreams Actor type for this entity; defaults to 'Person'
26
- # @param include_in_user_count [boolean] Should this entity be included in the nodeinfo user count? Defaults to true
40
+ # @param user_count_method [Symbol] A class method to call to count active users. Leave unspecified to leave this
41
+ # entity out of user counts. Method signature should accept a single parameter which will specify a date range
42
+ # If parameter is nil, the total user count should be returned. If the parameter is specified, the number of users
43
+ # active during the time period should be returned.
44
+ # @param auto_create_actors [Boolean] Whether to automatically create an actor when the entity is created
27
45
  # @example
28
46
  # acts_as_federails_actor username_field: :username, name_field: :display_name, profile_url_method: :url_for, actor_type: 'Person'
47
+ # rubocop:disable Metrics/ParameterLists
29
48
  def self.acts_as_federails_actor(
30
- username_field: Federails::Configuration.user_username_field,
31
- name_field: Federails::Configuration.user_name_field,
32
- profile_url_method: Federails.configuration.user_profile_url_method,
49
+ name_field:,
50
+ username_field:,
51
+ profile_url_method: nil,
33
52
  actor_type: 'Person',
34
- include_in_user_count: true
53
+ user_count_method: nil,
54
+ auto_create_actors: true
35
55
  )
36
56
  Federails::Configuration.register_entity(
37
57
  self,
38
- username_field: username_field,
39
- name_field: name_field,
40
- profile_url_method: profile_url_method,
41
- actor_type: actor_type,
42
- include_in_user_count: include_in_user_count
58
+ username_field: username_field,
59
+ name_field: name_field,
60
+ profile_url_method: profile_url_method,
61
+ actor_type: actor_type,
62
+ user_count_method: user_count_method,
63
+ auto_create_actors: auto_create_actors
43
64
  )
44
65
  end
66
+ # rubocop:enable Metrics/ParameterLists
45
67
 
46
- # Automatically run default acts_as_federails_actor
47
- # this can be optionally called again with different configuration in the entity
48
- acts_as_federails_actor
68
+ # Add custom data to actor responses.
69
+ # Override in your own model to add extra data, which will be merged into the actor response
70
+ # generated by Federails. You can include extra `@context` for activitypub extensions and it will
71
+ # be merged with the main response context.
72
+ # @example
73
+ # def to_activitypub_object
74
+ # {
75
+ # "@context": {
76
+ # toot: "http://joinmastodon.org/ns#",
77
+ # attributionDomains: {
78
+ # "@id": "toot:attributionDomains",
79
+ # "@type": "@id"
80
+ # }
81
+ # },
82
+ # attributionDomains: [
83
+ # "example.com"
84
+ # ]
85
+ # }
86
+ # end
87
+ def to_activitypub_object
88
+ {}
89
+ end
49
90
 
50
91
  private
51
92
 
@@ -91,7 +91,9 @@ module Federails
91
91
  end
92
92
 
93
93
  def entity_configuration
94
- Federails::Configuration.entity_types[entity.class.name]
94
+ raise("Entity not configured for #{entity_type}. Did you use \"acts_as_federails_actor\"?") unless Federails::Configuration.entity_types.key? entity_type
95
+
96
+ Federails::Configuration.entity_types[entity_type]
95
97
  end
96
98
 
97
99
  class << self
@@ -1,6 +1,9 @@
1
1
  module Federails
2
2
  module Client
3
3
  class ActivityPolicy < Federails::FederailsPolicy
4
+ def feed?
5
+ user_with_actor?
6
+ end
4
7
  end
5
8
  end
6
9
  end
@@ -7,7 +7,7 @@ module Federails
7
7
 
8
8
  class Scope < Scope
9
9
  def resolve
10
- scope.local
10
+ scope
11
11
  end
12
12
  end
13
13
  end
@@ -26,9 +26,9 @@ module Federails
26
26
  private
27
27
 
28
28
  def in_following?
29
- return false if @user.blank?
29
+ return false unless user_with_actor?
30
30
 
31
- @record.actor_id == @user.actor.id || @record.target_actor_id == @user.actor.id
31
+ @record.actor_id == @user.actor&.id || @record.target_actor_id == @user.actor&.id
32
32
  end
33
33
  end
34
34
  end
@@ -55,5 +55,9 @@ module Federails
55
55
 
56
56
  @record.actor_id == @user.actor.id
57
57
  end
58
+
59
+ def user_with_actor?
60
+ @user && Federails.actor_entity?(@user) && !!@user.actor
61
+ end
58
62
  end
59
63
  end
@@ -1,6 +1,9 @@
1
1
  module Federails
2
2
  module Server
3
3
  class ActivityPolicy < Federails::FederailsPolicy
4
+ def outbox?
5
+ true
6
+ end
4
7
  end
5
8
  end
6
9
  end
@@ -1,5 +1,5 @@
1
1
  <div>
2
- <b><%= activity.actor.name %></b>
2
+ <b><%= link_to activity.actor.name, federails.client_actor_url(activity.actor) %></b>
3
3
  <code><%= activity.action %></code>
4
4
  <!-- < %= link_to activity.entity_type, activity.entity %>-->
5
5
  </div>
@@ -1,4 +1,11 @@
1
- <h1>Your feed !</h1>
1
+ <h1>Your feed</h1>
2
+ <p>
3
+ This is the list of activities from actors you follow.
4
+ </p>
5
+
6
+ <% if @activities.size.zero? %>
7
+ <p>There is nothing to display. Start following things!</p>
8
+ <% end %>
2
9
  <% @activities.each do |activity| %>
3
10
  <%= render 'activity', activity: activity %>
4
11
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h1>Listing activities</h1>
2
2
 
3
- <%= @activities.each do |activity| %>
3
+ <% @activities.each do |activity| %>
4
4
  <%= render 'activity', activity: activity %>
5
5
  <% end %>
@@ -1,5 +1,14 @@
1
1
  <h1>Listing actors</h1>
2
2
 
3
+ <section>
4
+ Filters:
5
+ <% if params[:local_only] %>
6
+ <%= link_to 'All actors', federails.client_actors_url %>
7
+ <% else %>
8
+ <%= link_to 'Only local actors', federails.client_actors_url(local_only: true) %>
9
+ <% end %>
10
+ </section>
11
+
3
12
  <table>
4
13
  <thead>
5
14
  <tr>
@@ -11,6 +20,11 @@
11
20
  </tr>
12
21
  </thead>
13
22
  <tbody>
23
+ <% if @actors.size.zero? %>
24
+ <tr>
25
+ <td colspan="5">There are no actors to display</td>
26
+ </tr>
27
+ <% end %>
14
28
  <% @actors.each do |actor| %>
15
29
  <tr>
16
30
  <td><%= actor.name %></td>
@@ -1,100 +1,112 @@
1
- <h2><%= @actor.name %></h2>
1
+ <h1><%= @actor.name %></h1>
2
+
3
+ <section>
4
+ <%= render 'federails/client/followings/follow_actions', user: current_user, actor: @actor %>
5
+ </section>
6
+
7
+ <section>
8
+ <% if @actor.local? %>
9
+ <%= link_to 'All activities', federails.client_actor_activities_path(@actor) %>
10
+ <% elsif @actor.profile_url %>
11
+ <%= link_to 'Visit profile', @actor.profile_url %>
12
+ <% end %>
13
+ </section>
14
+
15
+ <section>
16
+ <h2>Actor details</h2>
17
+
18
+ <p>
19
+ <b>Federated url:</b>
20
+ <%= @actor.federated_url %>
21
+ </p>
22
+
23
+ <p>
24
+ <b>Username:</b>
25
+ <%= @actor.username %>
26
+ </p>
27
+
28
+ <p>
29
+ <b>Inbox URL:</b>
30
+ <%= @actor.inbox_url %>
31
+ </p>
32
+
33
+ <p>
34
+ <b>Outbox URL:</b>
35
+ <%= @actor.outbox_url %>
36
+ </p>
37
+
38
+ <p>
39
+ <b>Followers URL:</b>
40
+ <%= @actor.followers_url %>
41
+ </p>
42
+
43
+ <p>
44
+ <b>Followings URL:</b>
45
+ <%= @actor.followings_url %>
46
+ </p>
47
+
48
+ <p>
49
+ <b>Profile url:</b>
50
+ <% if @actor.profile_url %>
51
+ <%= link_to 'Profile', @actor.profile_url %>
52
+ <% end %>
53
+ </p>
2
54
 
3
- <% if Federails::Client::FollowingPolicy.new(current_user, Federails::Following).create? %>
4
55
  <p>
5
- <%
6
- follow = current_user.actor.follows? @actor
7
- if @actor.entity == current_user
8
- %>
9
- <button role="button" disabled="disabled">That's you</button>
10
- <% elsif follow %>
11
- Already following (<%= follow.status %>)
12
- <%= button_to 'Revoke', federails.client_following_path(follow), method: :delete %>
56
+ <b>Federation address:</b>
57
+ <%= @actor.at_address %>
58
+ </p>
59
+
60
+ <p>
61
+ <% if @actor.local? && @actor.entity_configuration[:profile_url_method] %>
62
+ <b>Home page:</b>
63
+ <%= link_to @actor.entity.send(@actor.entity_configuration[:username_field]),
64
+ Rails.application.routes.url_helpers.send(@actor.entity_configuration[:profile_url_method], @actor.entity)
65
+ %>
66
+ <% elsif @actor.profile_url %>
67
+ <b>Federation profile URL (JSON):</b>
68
+ <%= link_to @actor.name, @actor.profile_url %>
13
69
  <% else %>
14
- <%= button_to 'Follow!', federails.follow_client_followings_path, params: { account: @actor.at_address }, method: :post %>
70
+ (No homepage)
15
71
  <% end %>
16
72
  </p>
17
- <% end %>
18
-
19
- <p>
20
- <b>Federated url:</b>
21
- <%= @actor.federated_url %>
22
- </p>
23
-
24
- <p>
25
- <b>Username:</b>
26
- <%= @actor.username %>
27
- </p>
28
-
29
- <p>
30
- <b>Inbox URL:</b>
31
- <%= @actor.inbox_url %>
32
- </p>
33
-
34
- <p>
35
- <b>Outbox URL:</b>
36
- <%= @actor.outbox_url %>
37
- </p>
38
-
39
- <p>
40
- <b>Followers URL:</b>
41
- <%= @actor.followers_url %>
42
- </p>
43
-
44
- <p>
45
- <b>Followings URL:</b>
46
- <%= @actor.followings_url %>
47
- </p>
48
-
49
- <p>
50
- <b>Profile url:</b>
51
- <% if @actor.profile_url %>
52
- <%= link_to 'Profile', @actor.profile_url %>
73
+ </section>
74
+
75
+ <hr>
76
+
77
+ <section>
78
+ <h2>Follows <small>(<em>Who is followed?</em>)</small></h2>
79
+
80
+ <% if @actor.following_follows.size.zero? %>
81
+ <p><%= @actor.username %> follows nothing</p>
53
82
  <% end %>
54
- </p>
55
83
 
56
- <p>
57
- <b>Federation address:</b>
58
- <%= @actor.at_address %>
59
- </p>
84
+ <% @actor.following_follows.each do |following| %>
85
+ <%= render 'federails/client/followings/follow', following: following %>
86
+ <% end %>
87
+ </section>
60
88
 
61
- <p>
62
- <b>Home page:</b>
63
- <% if @actor.local? && Federails::Configuration.user_profile_url_method %>
64
- <%= link_to @actor.send(Federails::Configuration.user_username_field), Rails.application.routes.url_helpers.send(Federails::Configuration.user_profile_url_method, @actor.user) %>
65
- <% elsif @actor.profile_url %>
66
- <%= link_to @actor.name, @actor.profile_url %>
67
- <% else %>
68
- (No homepage)
89
+ <section>
90
+ <h2>Followers <small>(<em>Who follows?</em>)</small></h2>
91
+
92
+ <% if @actor.following_followers.size.zero? %>
93
+ <p>Nothing follows <%= @actor.username %></p>
69
94
  <% end %>
70
- </p>
71
95
 
72
- <hr>
96
+ <% @actor.following_followers.each do |following| %>
97
+ <%= render 'federails/client/followings/follower', following: following %>
98
+ <% end %>
99
+ </section>
100
+
101
+ <section>
102
+ <%# FIXME: Fetch distant content somehow %>
103
+ <h2>10 last activities</h2>
73
104
 
74
- <h2>Follows</h2>
75
- <% if current_user && current_user == @actor.entity %>
76
- <%= render 'federails/client/followings/form', following: Federails::Following.new %>
77
- <% end %>
78
-
79
- <% @actor.following_follows.each do |following| %>
80
- <%= render 'federails/client/followings/follow', following: following %>
81
- <% end %>
82
-
83
- <h2>Followers</h2>
84
- <% @actor.following_followers.each do |following| %>
85
- <%= render 'federails/client/followings/follower', following: following %>
86
- <% end %>
87
-
88
- <%= link_to 'Back', federails.client_actors_url %>
89
-
90
- <!-- FIXME: Fetch distant content somehow -->
91
- <h2>10 last activities</h2>
92
- <% if @actor.local? %>
93
- <%= link_to 'All', federails.client_actor_activities_path(@actor) %>
94
- <% elsif @actor.profile_url %>
95
- <%= link_to 'Visit profile', @actor.profile_url %>
96
- <% end %>
97
-
98
- <% @actor.activities.last(10).each do |activity| %>
99
- <%= render 'federails/client/activities/activity', activity: activity %>
100
- <% end %>
105
+ <% activities = @actor.activities.last(10) %>
106
+ <% if activities.size.zero? %>
107
+ <p>No activity to display</p>
108
+ <% end %>
109
+ <% activities.each do |activity| %>
110
+ <%= render 'federails/client/activities/activity', activity: activity %>
111
+ <% end %>
112
+ </section>
@@ -0,0 +1,24 @@
1
+ Federation:
2
+
3
+ <ul>
4
+ <%# Available publicly %>
5
+ <li><%= link_to 'Actors', federails.client_actors_url %></li>
6
+ <li><%= link_to 'Activities', federails.client_activities_url %></li>
7
+
8
+ <%# Available when user has an associated actor %>
9
+ <% if Federails::Client::ActivityPolicy.new(user, nil).feed? %>
10
+ <li><%= link_to 'Feed', federails.client_feed_url %></li>
11
+ <%end %>
12
+
13
+ <%# Available when user has an associated actor. The actor must exist to create the link %>
14
+ <% if Federails.actor_entity?(user) && user.actor.present? %>
15
+ <li><%= link_to "You (#{user.actor.username})", federails.client_actor_path(user.actor) %></li>
16
+ <% end %>
17
+ </ul>
18
+
19
+ <%# Debug information%>
20
+ <% if !Federails::actor_entity?(user) %>
21
+ <p><%= user.class.name %> is not configured to have an associated actor; you won't be allowed to follow or be followed</p>
22
+ <% elsif !user.actor.present? %>
23
+ <p>Your account does not have an associated actor; you won't be allowed to follow or be followed</p>
24
+ <% end %>
@@ -0,0 +1,32 @@
1
+ <%#
2
+ Displays buttons to follow/revoke following on a given actor.
3
+ Requires variables:
4
+ - user (usually user)
5
+ - actor (target actor)
6
+ %>
7
+ <p>
8
+ <% if Federails::Client::FollowingPolicy.new(user, Federails::Following).create? %>
9
+ <% follow = user.actor.follows? actor %>
10
+ <% if actor.entity == user %>
11
+ <button type="button" role="button" disabled="disabled">That's you</button>
12
+ <% elsif follow %>
13
+ Already following (<%= follow.status %>)
14
+ <%= button_to 'Cancel', federails.client_following_path(follow), method: :delete %>
15
+ <% else %>
16
+ <%= button_to "Follow #{actor.username}", federails.follow_client_followings_path, params: { account: actor.at_address }, method: :post %>
17
+ <% end %>
18
+
19
+ <% followed = actor.follows? user.actor %>
20
+ <% if followed %>
21
+ <% if followed.pending? %>
22
+ <%= actor.username %> wants to follow you.
23
+ <%= button_to 'Accept request', federails.accept_client_following_path(followed), method: :put %>
24
+ <% else %>
25
+ <%= actor.username %> follows you.
26
+ <%= button_to 'Revoke', federails.client_following_path(followed), method: :delete %>
27
+ <% end %>
28
+ <% end %>
29
+ <% else %>
30
+ <%= user.class.name %> is not configured to follow/be followed, or has no associated actor.
31
+ <% end %>
32
+ </p>
@@ -1,4 +1,5 @@
1
1
  <%= form_for following, url: federails.client_following_url do |f| %>
2
+ <h1>DELETE ME</h1>
2
3
  <% if following.errors.any? %>
3
4
  <div class="error_explanation">
4
5
  <h2><%= pluralize(following.errors.count, 'error') %> prohibited this following from being saved:</h2>
@@ -1,7 +1,11 @@
1
- json.set! '@context', [
1
+ actor_data = actor.entity.to_activitypub_object
2
+
3
+ json.set! '@context', ([
2
4
  'https://www.w3.org/ns/activitystreams',
3
5
  'https://w3id.org/security/v1',
4
- ]
6
+ ] + [
7
+ actor_data&.delete(:@context),
8
+ ].flatten).compact
5
9
 
6
10
  json.id actor.federated_url
7
11
  json.name actor.name
@@ -19,3 +23,4 @@ if actor.public_key
19
23
  json.publicKeyPem actor.public_key
20
24
  end
21
25
  end
26
+ json.merge! actor_data
@@ -9,11 +9,12 @@ json.protocols [
9
9
  # http://nodeinfo.diaspora.software/ns/schema/2.0 for possible values
10
10
  json.services inbound: [],
11
11
  outbound: []
12
- # FIXME: Don't hardcode this
13
- json.openRegistrations true
14
- json.usage users: {
15
- total: @total,
16
- activeMonth: @active_month,
17
- activeHalfyear: @active_halfyear,
18
- }
12
+ json.openRegistrations Federails::Configuration.open_registrations
13
+ if @has_user_counts
14
+ json.usage users: {
15
+ total: @total,
16
+ activeMonth: @active_month,
17
+ activeHalfyear: @active_halfyear,
18
+ }
19
+ end
19
20
  json.metadata({})
@@ -3,7 +3,7 @@ Mime::Type.register 'application/jrd+json', :jrd
3
3
  Mime::Type.register 'application/xrd+xml', :xrd
4
4
 
5
5
  # ActivityPub: https://www.w3.org/TR/activitypub/#retrieving-objects
6
- Mime::Type.register 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', :activitypub, ['application/activity+json', 'application/json']
6
+ Mime::Type.register 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', :activitypub, ['application/activity+json']
7
7
 
8
8
  # Nodeinfo: https://github.com/jhass/nodeinfo/blob/main/PROTOCOL.md#retrieval
9
9
  Mime::Type.register 'application/json; profile="http://nodeinfo.diaspora.software/ns/schema/2.0#"', :nodeinfo
data/config/routes.rb CHANGED
@@ -10,7 +10,11 @@ Federails::Engine.routes.draw do
10
10
 
11
11
  if Federails.configuration.client_routes_path
12
12
  scope Federails.configuration.client_routes_path, module: :client, as: :client do
13
- resources :activities, only: [:index, :feed]
13
+ resources :activities, only: [:index] do
14
+ collection do
15
+ get :feed, to: 'activities#feed'
16
+ end
17
+ end
14
18
  resources :actors, only: [:index, :show] do
15
19
  collection do
16
20
  get :lookup, to: 'actors#lookup'
@@ -30,7 +34,7 @@ Federails::Engine.routes.draw do
30
34
  end
31
35
  end
32
36
 
33
- scope Federails.configuration.server_routes_path, module: :server, as: :server do
37
+ scope Federails.configuration.server_routes_path, module: :server, as: :server, defaults: { format: :activitypub } do
34
38
  resources :actors, only: [:show] do
35
39
  member do
36
40
  get :followers
@@ -11,14 +11,12 @@ class CreateFederailsActors < ActiveRecord::Migration[7.0]
11
11
  t.string :followings_url
12
12
  t.string :profile_url
13
13
 
14
- t.references :user, null: true, foreign_key: { to_table: Federails.configuration.user_table }
14
+ t.integer :entity_id, null: true
15
+ t.string :entity_type, null: true
15
16
 
16
17
  t.timestamps
17
18
  t.index :federated_url, unique: true
19
+ t.index [:entity_type, :entity_id], name: 'index_federails_actors_on_entity', unique: true
18
20
  end
19
- remove_foreign_key :federails_actors, :users if foreign_key_exists?(:federails_actors, :users)
20
- remove_index :federails_actors, :user_id
21
- add_index :federails_actors, :user_id, unique: true
22
- add_foreign_key :federails_actors, :users
23
21
  end
24
22
  end
@@ -25,15 +25,14 @@ module Federails
25
25
  mattr_accessor :enable_discovery
26
26
  @@enable_discovery = true
27
27
 
28
- # Site port
28
+ # Does the site allow open registrations? (only used for nodeinfo reporting)
29
+ mattr_accessor :open_registrations
30
+ @@open_registrations = false
31
+
32
+ # Application layout
29
33
  mattr_accessor :app_layout
30
34
  @@app_layout = nil
31
35
 
32
- # User class name
33
- # @deprecated Kept for upgrade compatibility only
34
- mattr_accessor :user_class
35
- @@user_class = '::User'
36
-
37
36
  # Route path for the federation URLs (to "Federails::Server::*" controllers)
38
37
  mattr_accessor :server_routes_path
39
38
  @@server_routes_path = :federation
@@ -42,34 +41,14 @@ module Federails
42
41
  mattr_accessor :client_routes_path
43
42
  @@client_routes_path = :app
44
43
 
44
+ # Default controller to use as base for client controllers
45
+ mattr_accessor :base_client_controller
46
+ @@base_client_controller = 'ActionController::Base'
47
+
45
48
  # Route method for remote-following requests
46
49
  mattr_accessor :remote_follow_url_method
47
50
  @@remote_follow_url_method = 'federails.new_client_following_url'
48
51
 
49
- # Method to use for links to user profiles
50
- # @deprecated Set profile_url_method option on acts_as_federails_actor instead
51
- mattr_accessor :user_profile_url_method
52
- @@user_profile_url_method = nil
53
-
54
- # Attribute in the user model to use as the user's name
55
- # @deprecated Set name_field option on acts_as_federails_actor instead
56
- #
57
- # It only have sense if you have a separate username attribute
58
- mattr_accessor :user_name_field
59
- @@user_name_field = nil
60
-
61
- # Attribute in the user model to use as the username for local actors
62
- # @deprecated Set username_field option on acts_as_federails_actor instead
63
- mattr_accessor :user_username_field
64
- @@user_username_field = :id
65
-
66
- ##
67
- # @return [String] Table used for user model
68
- # @deprecated Kept for upgrade compatibility only
69
- def self.user_table
70
- @@user_class&.constantize&.table_name
71
- end
72
-
73
52
  def self.site_host=(value)
74
53
  @@site_host = value
75
54
  Federails::Engine.routes.default_url_options[:host] = value
@@ -1,3 +1,3 @@
1
1
  module Federails
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
data/lib/federails.rb CHANGED
@@ -23,15 +23,22 @@ module Federails
23
23
  :site_host,
24
24
  :site_port,
25
25
  :enable_discovery,
26
+ :open_registrations,
26
27
  :app_layout,
27
- :user_class, # @deprecated
28
28
  :server_routes_path,
29
29
  :client_routes_path,
30
30
  :remote_follow_url_method,
31
- :user_profile_url_method, # @deprecated
32
- :user_name_field, # @deprecated
33
- :user_username_field, # @deprecated
31
+ :base_client_controller,
34
32
  ].each { |key| Configuration.send :"#{key}=", config[key] if config.key?(key) }
35
33
  end
34
+
35
+ # @return [Boolean] True if the given model is a possible entity
36
+ #
37
+ # @example
38
+ # puts "Follow #{some_actor.name}" if actor_entity? current_user
39
+ def self.actor_entity?(class_or_instance)
40
+ klass = class_or_instance.is_a?(Class) ? class_or_instance.name : class_or_instance.class.name
41
+ Configuration.entity_types.key? klass
42
+ end
36
43
  end
37
44
  # rubocop:enable Style/ClassVars
@@ -2,34 +2,33 @@ require 'fediverse/request'
2
2
 
3
3
  module Fediverse
4
4
  class Inbox
5
+ @@handlers = {} # rubocop:todo Style/ClassVars
5
6
  class << self
7
+ def register_handler(activity_type, object_type, klass, method)
8
+ @@handlers[activity_type] ||= {}
9
+ @@handlers[activity_type][object_type] ||= {}
10
+ @@handlers[activity_type][object_type][klass] = method
11
+ end
12
+
6
13
  def dispatch_request(payload)
7
- case payload['type']
8
- when 'Create'
9
- handle_create_request payload
10
- when 'Follow'
11
- handle_create_follow_request payload
12
- when 'Accept'
13
- handle_accept_request payload
14
- when 'Undo'
15
- handle_undo_request payload
16
- else
17
- # FIXME: Fails silently
18
- # raise NotImplementedError
19
- Rails.logger.debug { "Unhandled activity type: #{payload['type']}" }
14
+ handlers = get_handlers(payload['type'], payload['object'].is_a?(Hash) ? payload.dig('object', 'type') : nil)
15
+ handlers.each_pair do |klass, method|
16
+ klass.send method, payload
20
17
  end
18
+ return unless handlers.empty?
19
+
20
+ # FIXME: Fails silently
21
+ # raise NotImplementedError
22
+ Rails.logger.debug { "Unhandled activity type: #{payload['type']}" }
21
23
  end
22
24
 
23
25
  private
24
26
 
25
- def handle_create_request(payload)
26
- activity = Request.get(payload['object'])
27
- case activity['type']
28
- when 'Follow'
29
- handle_create_follow_request activity
30
- when 'Note'
31
- handle_create_note activity
32
- end
27
+ def get_handlers(activity_type, object_type)
28
+ {}.merge(@@handlers.dig(activity_type, object_type) || {})
29
+ .merge(@@handlers.dig(activity_type, '*') || {})
30
+ .merge(@@handlers.dig('*', '*') || {})
31
+ .merge(@@handlers.dig('*', object_type) || {})
33
32
  end
34
33
 
35
34
  def handle_create_follow_request(activity)
@@ -39,33 +38,30 @@ module Fediverse
39
38
  Federails::Following.create! actor: actor, target_actor: target_actor, federated_url: activity['id']
40
39
  end
41
40
 
42
- def handle_create_note(activity)
43
- actor = Federails::Actor.find_or_create_by_object activity['attributedTo']
44
- Note.create! actor: actor, content: activity['content'], federated_url: activity['id']
45
- end
41
+ def handle_accept_request(activity)
42
+ original_activity = Request.get(activity['object'])
46
43
 
47
- def handle_accept_request(payload)
48
- activity = Request.get(payload['object'])
49
- raise "Can't accept things that are not Follow" unless activity['type'] == 'Follow'
50
-
51
- actor = Federails::Actor.find_or_create_by_object activity['actor']
52
- target_actor = Federails::Actor.find_or_create_by_object activity['object']
53
- raise 'Follow not accepted by target actor but by someone else' if payload['actor'] != target_actor.federated_url
44
+ actor = Federails::Actor.find_or_create_by_object original_activity['actor']
45
+ target_actor = Federails::Actor.find_or_create_by_object original_activity['object']
46
+ raise 'Follow not accepted by target actor but by someone else' if activity['actor'] != target_actor.federated_url
54
47
 
55
48
  follow = Federails::Following.find_by actor: actor, target_actor: target_actor
56
49
  follow.accept!
57
50
  end
58
51
 
59
- def handle_undo_request(payload)
60
- activity = payload['object']
61
- raise "Can't undo things that are not Follow" unless activity['type'] == 'Follow'
52
+ def handle_undo_request(activity)
53
+ original_activity = activity['object']
62
54
 
63
- actor = Federails::Actor.find_or_create_by_object activity['actor']
64
- target_actor = Federails::Actor.find_or_create_by_object activity['object']
55
+ actor = Federails::Actor.find_or_create_by_object original_activity['actor']
56
+ target_actor = Federails::Actor.find_or_create_by_object original_activity['object']
65
57
 
66
58
  follow = Federails::Following.find_by actor: actor, target_actor: target_actor
67
59
  follow&.destroy
68
60
  end
69
61
  end
62
+
63
+ register_handler 'Follow', '*', self, :handle_create_follow_request
64
+ register_handler 'Accept', 'Follow', self, :handle_accept_request
65
+ register_handler 'Undo', 'Follow', self, :handle_undo_request
70
66
  end
71
67
  end
@@ -17,7 +17,7 @@ module Fediverse
17
17
  private
18
18
 
19
19
  def payload(activity)
20
- Federails::ApplicationController.renderer.new.render(
20
+ Federails::ServerController.renderer.new.render(
21
21
  template: 'federails/server/activities/show',
22
22
  assigns: { activity: activity },
23
23
  format: :json
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Copies the client views to be overridden in main application
3
+
4
+ Example:
5
+ bin/rails generate copy_client_views
6
+
7
+ This will create:
8
+ app/views/federails/client/**/*
@@ -0,0 +1,9 @@
1
+ module Federails
2
+ class CopyClientViewsGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../../../../app/views', __dir__)
4
+
5
+ def copy_views
6
+ directory 'federails/client', Rails.root.join('app', 'views', 'federails', 'client')
7
+ end
8
+ end
9
+ end
@@ -3,8 +3,8 @@ module Federails
3
3
  source_root File.expand_path('templates', __dir__)
4
4
 
5
5
  def copy_files
6
- copy_file 'federails.yml', 'config/federails.yml'
7
- copy_file 'federails.rb', 'config/initializers/federails.rb'
6
+ copy_file 'federails.yml', Rails.root.join('config', 'federails.yml')
7
+ copy_file 'federails.rb', Rails.root.join('config', 'initializers', 'federails.rb')
8
8
  end
9
9
  end
10
10
  end
@@ -6,9 +6,11 @@ defaults: &defaults
6
6
  site_host: http://localhost
7
7
  site_port: 3000
8
8
  enable_discovery: true
9
+ open_registrations: false
9
10
  app_layout: 'layouts/application'
10
11
  server_routes_path: federation
11
12
  client_routes_path: app
13
+ #base_client_controller: ::ActionController::Base
12
14
 
13
15
  development:
14
16
  <<: *defaults
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: federails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Tancoigne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-13 00:00:00.000000000 Z
11
+ date: 2024-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -119,17 +119,17 @@ files:
119
119
  - Rakefile
120
120
  - app/assets/config/federails_manifest.js
121
121
  - app/assets/stylesheets/federails/application.css
122
- - app/controllers/federails/application_controller.rb
123
122
  - app/controllers/federails/client/activities_controller.rb
124
123
  - app/controllers/federails/client/actors_controller.rb
125
124
  - app/controllers/federails/client/followings_controller.rb
125
+ - app/controllers/federails/client_controller.rb
126
126
  - app/controllers/federails/server/activities_controller.rb
127
127
  - app/controllers/federails/server/actors_controller.rb
128
128
  - app/controllers/federails/server/followings_controller.rb
129
129
  - app/controllers/federails/server/nodeinfo_controller.rb
130
- - app/controllers/federails/server/server_controller.rb
131
130
  - app/controllers/federails/server/web_finger_controller.rb
132
- - app/helpers/federails/application_helper.rb
131
+ - app/controllers/federails/server_controller.rb
132
+ - app/helpers/federails/server_helper.rb
133
133
  - app/jobs/federails/application_job.rb
134
134
  - app/jobs/federails/notify_inbox_job.rb
135
135
  - app/mailers/federails/application_mailer.rb
@@ -159,7 +159,9 @@ files:
159
159
  - app/views/federails/client/actors/index.json.jbuilder
160
160
  - app/views/federails/client/actors/show.html.erb
161
161
  - app/views/federails/client/actors/show.json.jbuilder
162
+ - app/views/federails/client/common/_client_links.html.erb
162
163
  - app/views/federails/client/followings/_follow.html.erb
164
+ - app/views/federails/client/followings/_follow_actions.html.erb
163
165
  - app/views/federails/client/followings/_follower.html.erb
164
166
  - app/views/federails/client/followings/_following.json.jbuilder
165
167
  - app/views/federails/client/followings/_form.html.erb
@@ -185,7 +187,6 @@ files:
185
187
  - db/migrate/20200712133150_create_federails_actors.rb
186
188
  - db/migrate/20200712143127_create_federails_followings.rb
187
189
  - db/migrate/20200712174938_create_federails_activities.rb
188
- - db/migrate/20240731145400_change_actor_entity_rel_to_polymorphic.rb
189
190
  - db/migrate/20241002094500_add_uuids.rb
190
191
  - db/migrate/20241002094501_add_keypair_to_actors.rb
191
192
  - lib/federails.rb
@@ -198,6 +199,8 @@ files:
198
199
  - lib/fediverse/request.rb
199
200
  - lib/fediverse/signature.rb
200
201
  - lib/fediverse/webfinger.rb
202
+ - lib/generators/federails/copy_client_views/USAGE
203
+ - lib/generators/federails/copy_client_views/copy_client_views_generator.rb
201
204
  - lib/generators/federails/install/USAGE
202
205
  - lib/generators/federails/install/install_generator.rb
203
206
  - lib/generators/federails/install/templates/federails.rb
@@ -227,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
230
  - !ruby/object:Gem::Version
228
231
  version: '0'
229
232
  requirements: []
230
- rubygems_version: 3.4.15
233
+ rubygems_version: 3.3.7
231
234
  signing_key:
232
235
  specification_version: 4
233
236
  summary: An ActivityPub engine for Ruby on Rails
@@ -1,17 +0,0 @@
1
- module Federails
2
- module Server
3
- class ServerController < Federails::ApplicationController
4
- protect_from_forgery with: :null_session
5
-
6
- # def policy_scope(scope, policy_scope_class: nil)
7
- # scope = [scope, :server] unless policy_scope_class
8
- # super(scope, policy_scope_class: policy_scope_class)
9
- # end
10
-
11
- # def authorize(record, query = nil, policy_class: nil)
12
- # record = [:server, record] unless policy_class
13
- # super(record, query, policy_class: policy_class)
14
- # end
15
- end
16
- end
17
- end
@@ -1,11 +0,0 @@
1
- class ChangeActorEntityRelToPolymorphic < ActiveRecord::Migration[7.0]
2
- def change
3
- remove_foreign_key :federails_actors, column: :user_id, to_table: Federails::Configuration.user_table
4
- remove_index :federails_actors, :user_id, unique: true
5
- change_table :federails_actors do |t|
6
- t.rename :user_id, :entity_id
7
- t.string :entity_type, null: true, default: Federails::Configuration.user_class&.demodulize
8
- t.index [:entity_type, :entity_id], name: 'index_federails_actors_on_entity', unique: true
9
- end
10
- end
11
- end