Add nodeinfo

This commit is contained in:
Mirai Kumiko 2025-06-12 23:22:42 +02:00
parent eecdf86849
commit 4a890a39f4
Signed by: miraikumiko
GPG key ID: 3F178B1B5E0CB278
4 changed files with 83 additions and 9 deletions

View file

@ -137,8 +137,7 @@ defmodule Nulla.ActivityPub do
id: "https://#{domain}/activities/#{activity.id}",
type: activity.type,
actor: activity.actor,
object: activity.object,
to: activity.to
object: activity.object
)
end
@ -244,6 +243,7 @@ defmodule Nulla.ActivityPub do
Jason.OrderedObject.new(data)
end
@spec webfinger(String.t(), String.t(), String.t()) :: Jason.OrderedObject.t()
def webfinger(domain, username, resource) do
Jason.OrderedObject.new(
subject: resource,
@ -256,4 +256,52 @@ defmodule Nulla.ActivityPub do
]
)
end
@spec nodeinfo(String.t()) :: Jason.OrderedObject.t()
def nodeinfo(domain) do
Jason.OrderedObject.new(
links: [
Jason.OrderedObject.new(
rel: "http://nodeinfo.diaspora.software/ns/schema/2.0",
href: "https://#{domain}/nodeinfo/2.0"
)
]
)
end
@spec nodeinfo(String.t(), Map.t(), Nulla.Models.InstanceSettings.t()) ::
Jason.OrderedObject.t()
def nodeinfo(version, users, instance) do
Jason.OrderedObject.new(
version: "2.0",
software:
Jason.OrderedObject.new(
name: "nulla",
version: version
),
protocols: [
"activitypub"
],
services:
Jason.OrderedObject.new(
outbound: [],
inbound: []
),
usage:
Jason.OrderedObject.new(
users:
Jason.OrderedObject.new(
total: users.total,
activeMonth: users.month,
activeHalfyear: users.halfyear
)
),
openRegistrations: instance.registration,
metadata:
Jason.OrderedObject.new(
nodeName: instance.name,
nodeDescription: instance.description
)
)
end
end

View file

@ -0,0 +1,28 @@
defmodule NullaWeb.NodeinfoController do
use NullaWeb, :controller
alias Nulla.Repo
alias Nulla.ActivityPub
alias Nulla.Models.User
alias Nulla.Models.InstanceSettings
def index(conn, _params) do
instance_settings = InstanceSettings.get_instance_settings!()
domain = instance_settings.domain
json(conn, ActivityPub.nodeinfo(domain))
end
def show(conn, _params) do
version = Application.spec(:nulla, :vsn) |> to_string()
users = %{
total: 0,
month: 0,
halfyear: 0
}
instance_settings = InstanceSettings.get_instance_settings!()
json(conn, ActivityPub.nodeinfo(version, users, instance_settings))
end
end

View file

@ -5,7 +5,7 @@ defmodule NullaWeb.WebfingerController do
alias Nulla.Models.User
alias Nulla.Models.InstanceSettings
def show(conn, %{"resource" => resource}) do
def index(conn, %{"resource" => resource}) do
case Regex.run(~r/^acct:([^@]+)@(.+)$/, resource) do
[_, username, domain] ->
case User.get_user_by_username(username) do

View file

@ -11,17 +11,15 @@ defmodule NullaWeb.Router do
end
pipeline :api do
plug :accepts, ["activity+json", "ld+json"]
post "/inbox", InboxController, :receive
post "/@:username/inbox", InboxController, :receive
get "/@:username/outbox", OutboxController, :index
plug :accepts, ["json"]
end
scope "/", NullaWeb do
pipe_through :browser
get "/.well-known/webfinger", WebfingerController, :show
get "/.well-known/webfinger", WebfingerController, :index
get "/.well-known/nodeinfo", NodeinfoController, :index
get "/nodeinfo/2.0", NodeinfoController, :show
get "/@:username", UserController, :show
get "/@:username/following", FollowController, :following