From b63eaa34be79ecc3b469c20cc82fc5a365d9e00c Mon Sep 17 00:00:00 2001 From: miraikumiko Date: Thu, 12 Jun 2025 16:05:18 +0200 Subject: [PATCH] Add Webfinger --- lib/nulla/activitypub.ex | 13 +++++++ lib/nulla/models/user.ex | 2 ++ .../controllers/webfinger_controller.ex | 34 +++++++++++++++++++ lib/nulla_web/router.ex | 2 ++ 4 files changed, 51 insertions(+) create mode 100644 lib/nulla_web/controllers/webfinger_controller.ex diff --git a/lib/nulla/activitypub.ex b/lib/nulla/activitypub.ex index e3c93f8..2e58798 100644 --- a/lib/nulla/activitypub.ex +++ b/lib/nulla/activitypub.ex @@ -243,4 +243,17 @@ defmodule Nulla.ActivityPub do Jason.OrderedObject.new(data) end + + def webfinger(domain, username, resource) do + Jason.OrderedObject.new( + subject: resource, + links: [ + Jason.OrderedObject.new( + rel: "self", + type: "application/activity+json", + href: "https://#{domain}/@#{username}" + ) + ] + ) + end end diff --git a/lib/nulla/models/user.ex b/lib/nulla/models/user.ex index cd20f48..caf90c5 100644 --- a/lib/nulla/models/user.ex +++ b/lib/nulla/models/user.ex @@ -77,5 +77,7 @@ defmodule Nulla.Models.User do ]) end + def get_user_by_username(username), do: Repo.get_by(User, username: username) + def get_user_by_username!(username), do: Repo.get_by!(User, username: username) end diff --git a/lib/nulla_web/controllers/webfinger_controller.ex b/lib/nulla_web/controllers/webfinger_controller.ex new file mode 100644 index 0000000..ab6e2bf --- /dev/null +++ b/lib/nulla_web/controllers/webfinger_controller.ex @@ -0,0 +1,34 @@ +defmodule NullaWeb.WebfingerController do + use NullaWeb, :controller + alias Nulla.Repo + alias Nulla.ActivityPub + alias Nulla.Models.User + alias Nulla.Models.InstanceSettings + + def show(conn, %{"resource" => resource}) do + case Regex.run(~r/^acct:([^@]+)@(.+)$/, resource) do + [_, username, domain] -> + case User.get_user_by_username(username) do + nil -> + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + + user -> + instance_settings = InstanceSettings.get_instance_settings!() + + if domain == instance_settings.domain do + json(conn, ActivityPub.webfinger(domain, username, resource)) + else + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + end + end + _ -> + conn + |> put_status(:bad_request) + |> json(%{error: "Bad Request"}) + end + end +end diff --git a/lib/nulla_web/router.ex b/lib/nulla_web/router.ex index 04268ed..0ad10df 100644 --- a/lib/nulla_web/router.ex +++ b/lib/nulla_web/router.ex @@ -21,6 +21,8 @@ defmodule NullaWeb.Router do scope "/", NullaWeb do pipe_through :browser + get "/.well-known/webfinger", WebfingerController, :show + get "/@:username", UserController, :show get "/@:username/following", FollowController, :following get "/@:username/followers", FollowController, :followers