diff --git a/js/src/components/Admin/FollowDetails.vue b/js/src/components/Admin/FollowDetails.vue
new file mode 100644
index 000000000..3c1d70705
--- /dev/null
+++ b/js/src/components/Admin/FollowDetails.vue
@@ -0,0 +1,26 @@
+
+
+
+
diff --git a/js/src/components/Admin/Followers.vue b/js/src/components/Admin/Followers.vue
index f8472c042..076695a86 100644
--- a/js/src/components/Admin/Followers.vue
+++ b/js/src/components/Admin/Followers.vue
@@ -143,14 +143,14 @@ export default class Followers extends Mixins(RelayMixin) {
formatDistanceToNow = formatDistanceToNow;
- async acceptRelays(): Promise {
- await this.checkedRows.forEach((row: IFollower) => {
+ acceptRelays(): void {
+ this.checkedRows.forEach((row: IFollower) => {
this.acceptRelay(`${row.actor.preferredUsername}@${row.actor.domain}`);
});
}
- async rejectRelays(): Promise {
- await this.checkedRows.forEach((row: IFollower) => {
+ rejectRelays(): void {
+ this.checkedRows.forEach((row: IFollower) => {
this.rejectRelay(`${row.actor.preferredUsername}@${row.actor.domain}`);
});
}
diff --git a/js/src/graphql/admin.ts b/js/src/graphql/admin.ts
index f6aa1978a..c597e8d15 100644
--- a/js/src/graphql/admin.ts
+++ b/js/src/graphql/admin.ts
@@ -37,6 +37,7 @@ export const DASHBOARD = gql`
export const RELAY_FRAGMENT = gql`
fragment relayFragment on Follower {
+ id
actor {
id
preferredUsername
@@ -83,6 +84,15 @@ export const RELAY_FOLLOWINGS = gql`
${RELAY_FRAGMENT}
`;
+export const RELAY_FOLLOW = gql`
+ query relayFollow($id: ID!) {
+ relayFollow(id: $id) {
+ ...relayFragment
+ }
+ }
+ ${RELAY_FRAGMENT}
+`;
+
export const ADD_RELAY = gql`
mutation addRelay($address: String!) {
addRelay(address: $address) {
diff --git a/js/src/router/settings.ts b/js/src/router/settings.ts
index 26b453a04..8cfc590b9 100644
--- a/js/src/router/settings.ts
+++ b/js/src/router/settings.ts
@@ -13,6 +13,7 @@ export enum SettingsRouteName {
RELAYS = "Relays",
RELAY_FOLLOWINGS = "Followings",
RELAY_FOLLOWERS = "Followers",
+ RELAY_FOLLOW = "RELAY_FOLLOW",
USERS = "USERS",
PROFILES = "PROFILES",
ADMIN_PROFILE = "ADMIN_PROFILE",
@@ -186,6 +187,16 @@ export const settingsRoutes: RouteConfig[] = [
],
props: true,
},
+ {
+ path: "admin/relays/follow/:id",
+ name: SettingsRouteName.RELAY_FOLLOW,
+ component: (): Promise =>
+ import(
+ /* webpackChunkName: "RelayFollow" */ "@/components/Admin/FollowDetails.vue"
+ ),
+ props: true,
+ meta: { requiredAuth: true },
+ },
{
path: "/moderation",
name: SettingsRouteName.MODERATION,
diff --git a/lib/graphql/resolvers/admin.ex b/lib/graphql/resolvers/admin.ex
index 9bdbe4901..919cd0fca 100644
--- a/lib/graphql/resolvers/admin.ex
+++ b/lib/graphql/resolvers/admin.ex
@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
import Mobilizon.Users.Guards
alias Mobilizon.{Actors, Admin, Config, Events}
- alias Mobilizon.Actors.Actor
+ alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Admin.{ActionLog, Setting}
alias Mobilizon.Cldr.Language
alias Mobilizon.Config
@@ -304,6 +304,35 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
{:error, :unauthenticated}
end
+ @doc """
+ Get a relay follow
+ """
+ def get_relay_follow(
+ _parent,
+ %{id: id},
+ %{context: %{current_user: %User{role: role}}}
+ )
+ when is_admin(role) do
+ %Actor{id: relay_actor_id} = Relay.get_actor()
+
+ case Actors.get_follower(id) do
+ %Follower{target_actor_id: target_actor_id, actor_id: actor_id} = follow
+ when relay_actor_id in [target_actor_id, actor_id] ->
+ {:ok, follow}
+
+ _ ->
+ {:error, :not_found}
+ end
+ end
+
+ def get_relay_follow(_parent, _args, %{context: %{current_user: %User{}}}) do
+ {:error, :unauthorized}
+ end
+
+ def get_relay_follow(_parent, _args, _resolution) do
+ {:error, :unauthenticated}
+ end
+
def create_relay(_parent, %{address: address}, %{context: %{current_user: %User{role: role}}})
when is_admin(role) do
case Relay.follow(address) do
diff --git a/lib/graphql/schema/admin.ex b/lib/graphql/schema/admin.ex
index 22689f322..61c67e73d 100644
--- a/lib/graphql/schema/admin.ex
+++ b/lib/graphql/schema/admin.ex
@@ -215,6 +215,11 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
arg(:direction, :string, default_value: :desc, description: "The sorting direction")
resolve(&Admin.list_relay_followings/3)
end
+
+ field :relay_follow, type: :follower do
+ arg(:id, non_null(:id), description: "The follow ID")
+ resolve(&Admin.get_relay_follow/3)
+ end
end
object :admin_mutations do