From 12411c9ce66236685e3c0139d7530eb5d2b296a7 Mon Sep 17 00:00:00 2001 From: Gervasio Marchand Date: Sat, 3 Dec 2022 20:48:52 -0300 Subject: [PATCH] Add README and redirect --- README.md | 107 ++++++++++++++++++ src/FakeRelay.Core/Config.cs | 7 +- .../Controllers/ApiController.cs | 4 +- .../Controllers/HomeController.cs | 18 +++ 4 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 README.md create mode 100644 src/FakeRelay.Web/Controllers/HomeController.cs diff --git a/README.md b/README.md new file mode 100644 index 0000000..02c61b3 --- /dev/null +++ b/README.md @@ -0,0 +1,107 @@ +# What is this? + +FakeRelay is a tool for Mastodon admins to load statuses into their instances. + +## Why is it needed? + +If you're on a small or solo instance, following a hashtag doesn't provide a lot of value. This is because you'll only see stuff that's on the instance's federated timeline... but if you're the only user, the federated timeline is the same as your timeline. + +Discovering what to index isn't hard (I'm hitting big instances' `/tags/{interestingTag}.json` routes to fetch the content I want), but telling my instance that I want to bring over a toot isn't straightforward. + +One thing any user can do is hit the `/api/v2/search` endpoint using `resolve=true`. That does accomplish the goal of fetching the status, but it's a synchronous call so it can take some seconds. + +This project uses the ActivityPub `/inbox` endpoint as if it were a relay. And then, the request is queued and eventually processed. + +## How can I use it? + +### You need to get an api key + +Ask the operator for an api key. If you want an api key for fakerelay.gervas.io, I'm `@g3rv4@mastodonte.tech`. Send me a toot with your instance domain and I'll get you one. The API key will be associated with your domain. + +### Add the relay to your instance + +Your instance will receive traffic from this site as if it were a relay. But don't worry, it won't send anything except from the statuses you tell it to index. + +You need to go to `/admin/relays` and add `https://fakerelay.gervas.io` as a relay. That's it! and you can remove it whenever you want. + +### Figure what you want to index + +Use whatever logic you want to find stuff to index. On this example, I want to index `https://mastodonte.tech/users/g3rv4/statuses/109370844647385274` + +### Do a simple request + +And all you need to do is a post asking for the site to index it to your site! + +``` +curl -X "POST" "https://fakerelay.gervas.io/index" \ + -H 'Authorization: Bearer {apiKey}' \ + -H 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' \ + --data-urlencode "statusUrl=https://mastodonte.tech/users/g3rv4/statuses/109370844647385274" +``` + +## I want to run this myself! + +Sure thing! The easiest way is doing so via `docker-compose`. + +### Setting up docker compose + +I'm using this `docker-compose.yml`: + +``` +version: '2' +services: + fakerelay: + image: 'ghcr.io/g3rv4/fakerelay:1.0.3' + command: 'web' + hostname: fakerelay + environment: + - ASPNETCORE_ENVIRONMENT=Production + - ASPNETCORE_URLS=http://+:5000 + - CONFIG_PATH=/data/config.json + restart: always + volumes: + - '/local/path/to/data:/data' + cli: + image: 'ghcr.io/g3rv4/fakerelay:1.0.2' + volumes: + - '/local/path/to/data:/data' +``` + +That will store the configuration files at `/local/path/to/data` (they are a couple json files). + +### Configure the app + +The first time you run this it needs to create a key, you can trigger that using: + +``` +docker-compose run --rm cli config {relayHost} +``` + +### Add authorized hosts + +You can add hosts, and that will generate their tokens using the `add-host` command. That will output the key: + +``` +g3rv4@s1:~/docker/FakeRelay$ docker-compose run --rm cli add-host mastodon.social +Key generated for mastodon.social +vti7J0MDDw1O5EPRwfuUafJJjpErhXTwECGEvuw/G4UVWgLXtnrnmPIRRsOcvMD0juwSlvUnchIzgla030AIRw== +``` + +### Rotate a key + +You can use `update-host` to rotate a hosts' key: + +``` +g3rv4@s1:~/docker/FakeRelay$ docker-compose run --rm cli update-host mastodon.social +Key generated for mastodon.social +wpSX9xpPgX0gjgAxO0Jc+GLSOXubVgv73FOvAihR2EmgK/AfDHz21sF72uqrLnVGzcq2BDXosMeKdFR76q6fpg== +``` + +### Remove a host + +If you want to revoke a host's key, you can use `delete-host`: + +``` +g3rv4@s1:~/docker/FakeRelay$ docker-compose run --rm cli delete-host mastodon.social +Key deleted for mastodon.social +``` \ No newline at end of file diff --git a/src/FakeRelay.Core/Config.cs b/src/FakeRelay.Core/Config.cs index c92d123..9400183 100644 --- a/src/FakeRelay.Core/Config.cs +++ b/src/FakeRelay.Core/Config.cs @@ -12,13 +12,15 @@ public class Config public string Host { get; } public string ConfigPath { get; } + public string? HomeRedirect { get; } - private Config(string publicKey, byte[] privateKey, string host, string configPath) + private Config(string publicKey, byte[] privateKey, string host, string configPath, string? homeRedirect) { PrivateKey = privateKey; PublicKey = publicKey; Host = host; ConfigPath = configPath; + HomeRedirect = homeRedirect; } public static void Init(string path) @@ -37,7 +39,7 @@ public class Config using var rsa = RSA.Create(); rsa.ImportFromPem(data.PrivateKey.ToCharArray()); - Instance = new Config(data.PublicKey, rsa.ExportRSAPrivateKey(), data.Host, path); + Instance = new Config(data.PublicKey, rsa.ExportRSAPrivateKey(), data.Host, path, data.HomeRedirect); } public static void CreateConfig(string path, string host, string publicKey, string privateKey) @@ -56,5 +58,6 @@ public class Config public string? PublicKey { get; set; } public string? PrivateKey { get; set; } public string? Host { get; set; } + public string? HomeRedirect { get; set; } } } diff --git a/src/FakeRelay.Web/Controllers/ApiController.cs b/src/FakeRelay.Web/Controllers/ApiController.cs index d344d8e..75070dc 100644 --- a/src/FakeRelay.Web/Controllers/ApiController.cs +++ b/src/FakeRelay.Web/Controllers/ApiController.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Immutable; -using System.Threading.Tasks; using FakeRelay.Core.Helpers; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; @@ -38,7 +36,7 @@ public class ApiController : Controller return host; } - [Route("index")] + [Route("index"), HttpPost] public async Task DoIndex(string statusUrl) { var host = await GetHostFromRequest(); diff --git a/src/FakeRelay.Web/Controllers/HomeController.cs b/src/FakeRelay.Web/Controllers/HomeController.cs new file mode 100644 index 0000000..291b872 --- /dev/null +++ b/src/FakeRelay.Web/Controllers/HomeController.cs @@ -0,0 +1,18 @@ +using FakeRelay.Core; +using Microsoft.AspNetCore.Mvc; + +namespace FakeRelay.Web.Controllers; + +public class HomeController : Controller +{ + [Route("")] + public ActionResult Index() + { + if (Config.Instance.HomeRedirect != null) + { + return Redirect(Config.Instance.HomeRedirect); + } + + return Content("Hi! I'm FakeRelay. You can learn more about me at fakerelay.gervas.io"); + } +}