This commit is contained in:
Mirai Kumiko 2025-07-05 15:20:40 +02:00
parent 188bc08494
commit 4af88f3e1d
Signed by: miraikumiko
GPG key ID: 3F178B1B5E0CB278
44 changed files with 1041 additions and 34 deletions

View file

@ -0,0 +1,18 @@
defmodule NullaWeb.Generic.HostmetaController do
use NullaWeb, :controller
def index(conn, _params) do
url = NullaWeb.Endpoint.url()
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
<Link rel="lrdd" type="application/xrd+xml" template="#{url}/.well-known/webfinger?resource={uri}"/>
</XRD>
"""
conn
|> put_resp_content_type("application/xrd+xml")
|> send_resp(200, xml)
end
end

View file

@ -0,0 +1,28 @@
defmodule NullaWeb.Generic.NodeinfoController do
use NullaWeb, :controller
alias Nulla.Accounts
alias NullaWeb.Generic.NodeinfoJSON
def index(conn, _params) do
url = NullaWeb.Endpoint.url()
json(conn, NodeinfoJSON.index(url))
end
def show(conn, _params) do
version = Application.spec(:nulla, :vsn) |> to_string()
total = Accounts.get_total_users_count()
month = Accounts.get_active_users_count(30)
halfyear = Accounts.get_active_users_count(180)
users = %{
total: total,
month: month,
halfyear: halfyear
}
instance = Application.get_env(:nulla, :instance) |> Map.new()
json(conn, NodeinfoJSON.show(version, users, instance))
end
end

View file

@ -0,0 +1,52 @@
defmodule NullaWeb.Generic.NodeinfoJSON do
@doc """
Renders a nodeinfo.
"""
def index(url) do
Jason.OrderedObject.new(
links: [
Jason.OrderedObject.new(
rel: "http://nodeinfo.diaspora.software/ns/schema/2.0",
href: "#{url}/nodeinfo/2.0"
)
]
)
end
@doc """
Renders a nodeinfo.
"""
def show(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,32 @@
defmodule NullaWeb.Generic.WebfingerController do
use NullaWeb, :controller
alias Nulla.Actors
alias Nulla.Actors.Actor
alias NullaWeb.Generic.WebfingerJSON
def index(conn, %{"resource" => resource}) do
case Regex.run(~r/^acct:(.+)$/, resource) do
[_, acct] ->
case Actors.get_actor_by(acct: acct) do
nil ->
conn
|> put_resp_content_type("text/plain")
|> send_resp(404, "")
%Actor{} = actor ->
json(conn, WebfingerJSON.show(actor))
end
_ ->
conn
|> put_resp_content_type("text/plain")
|> send_resp(400, "")
end
end
def index(conn, _params) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(400, "")
end
end

View file

@ -0,0 +1,50 @@
defmodule NullaWeb.Generic.WebfingerJSON do
alias Nulla.Actors.Actor
@doc """
Renders a webfinger.
"""
def show(actor) do
data(actor)
end
defp data(%Actor{} = actor) do
data = [
subject: actor.acct,
aliases: [
actor.url,
actor.ap_id
],
links: [
Jason.OrderedObject.new(
rel: "http://webfinger.net/rel/profile-page",
type: "text/html",
href: actor.url
),
Jason.OrderedObject.new(
rel: "self",
type: "application/activity+json",
href: actor.ap_id
)
]
]
data =
if actor.icon do
Keyword.update!(data, :links, fn links ->
links ++
[
Jason.OrderedObject.new(
rel: "http://webfinger.net/rel/avatar",
type: Map.get(actor.icon, :mediaType),
href: Map.get(actor.icon, :url)
)
]
end)
else
data
end
Jason.OrderedObject.new(data)
end
end