mirror of
https://git.pleroma.social/pleroma/relay.git
synced 2024-12-23 03:31:07 +00:00
use api for instances admin page
This commit is contained in:
parent
aeb84d7a72
commit
f775335e80
|
@ -1,29 +1,32 @@
|
|||
-extends "base.haml"
|
||||
-set page="Instances"
|
||||
|
||||
-block head
|
||||
%script(type="application/javascript" src="/static/instance.js" nonce="{{view.request['hash']}}")
|
||||
|
||||
-block content
|
||||
%details.section
|
||||
%summary << Add Instance
|
||||
%form(action="/admin/instances" method="POST")
|
||||
#add-item
|
||||
%label(for="domain") << Domain
|
||||
%input(type="domain" id="domain" name="domain" placeholder="Domain")
|
||||
#add-item
|
||||
%label(for="new-actor") << Actor
|
||||
%input(type="url" id="new-actor" placeholder="Actor URL")
|
||||
|
||||
%label(for="actor") << Actor URL
|
||||
%input(type="url" id="actor" name="actor" placeholder="Actor URL")
|
||||
%label(for="new-inbox") << Inbox
|
||||
%input(type="url" id="new-inbox" placeholder="Inbox URL")
|
||||
|
||||
%label(for="inbox") << Inbox URL
|
||||
%input(type="url" id="inbox" name="inbox" placeholder="Inbox URL")
|
||||
%label(for="new-followid") << Follow ID
|
||||
%input(type="url" id="new-followid" placeholder="Follow ID URL")
|
||||
|
||||
%label(for="software") << Software
|
||||
%input(name="software" id="software" placeholder="software")
|
||||
%label(for="new-software") << Software
|
||||
%input(id="new-software" placeholder="software")
|
||||
|
||||
%input(type="submit" value="Add Instance")
|
||||
%input(type="button" value="Add Instance", onclick="add_instance()")
|
||||
|
||||
-if requests
|
||||
%fieldset.section
|
||||
%fieldset.section.requests
|
||||
%legend << Follow Requests
|
||||
.data-table
|
||||
%table
|
||||
%table#requests
|
||||
%thead
|
||||
%tr
|
||||
%td.instance << Instance
|
||||
|
@ -34,7 +37,7 @@
|
|||
|
||||
%tbody
|
||||
-for request in requests
|
||||
%tr
|
||||
%tr(id="{{request.domain}}")
|
||||
%td.instance
|
||||
%a(href="https://{{request.domain}}" target="_new") -> =request.domain
|
||||
|
||||
|
@ -45,16 +48,16 @@
|
|||
=request.created.strftime("%Y-%m-%d")
|
||||
|
||||
%td.approve
|
||||
%a(href="/admin/instances/approve/{{request.domain}}" title="Approve Request") << ✓
|
||||
%a(href="#" onclick="req_response('{{request.domain}}', true)" title="Approve Request") << ✓
|
||||
|
||||
%td.deny
|
||||
%a(href="/admin/instances/deny/{{request.domain}}" title="Deny Request") << ✖
|
||||
%a(href="#" onclick="req_response('{{request.domain}}', false)" title="Deny Request") << ✖
|
||||
|
||||
%fieldset.section
|
||||
%fieldset.section.instances
|
||||
%legend << Instances
|
||||
|
||||
.data-table
|
||||
%table
|
||||
%table#instances
|
||||
%thead
|
||||
%tr
|
||||
%td.instance << Instance
|
||||
|
@ -64,7 +67,7 @@
|
|||
|
||||
%tbody
|
||||
-for instance in instances
|
||||
%tr
|
||||
%tr(id="{{instance.domain}}")
|
||||
%td.instance
|
||||
%a(href="https://{{instance.domain}}/" target="_new") -> =instance.domain
|
||||
|
||||
|
@ -75,4 +78,4 @@
|
|||
=instance.created.strftime("%Y-%m-%d")
|
||||
|
||||
%td.remove
|
||||
%a(href="/admin/instances/delete/{{instance.domain}}" title="Remove Instance") << ✖
|
||||
%a(href="#" onclick="del_instance('{{instance.domain}}')" title="Remove Instance") << ✖
|
||||
|
|
|
@ -62,8 +62,17 @@ class Client {
|
|||
throw new Error(message.error);
|
||||
}
|
||||
|
||||
if (Object.hasOwn(message, "created")) {
|
||||
message.created = new Date(message.created);
|
||||
if (Array.isArray(message)) {
|
||||
message.forEach((msg) => {
|
||||
if (Object.hasOwn(msg, "created")) {
|
||||
msg.created = new Date(msg.created);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
if (Object.hasOwn(message, "created")) {
|
||||
message.created = new Date(message.created);
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
|
|
|
@ -15,8 +15,6 @@ function create_ban_object(domain, reason, note) {
|
|||
|
||||
async function ban() {
|
||||
var table = document.querySelector("table");
|
||||
var row = table.insertRow(-1);
|
||||
|
||||
var elems = {
|
||||
domain: document.getElementById("new-domain"),
|
||||
reason: document.getElementById("new-reason"),
|
||||
|
@ -42,7 +40,9 @@ async function ban() {
|
|||
return
|
||||
}
|
||||
|
||||
var row = table.insertRow(-1);
|
||||
row.id = ban.domain;
|
||||
|
||||
var new_domain = row.insertCell(0);
|
||||
var new_date = row.insertCell(1);
|
||||
var new_remove = row.insertCell(2);
|
||||
|
|
105
relay/frontend/static/instance.js
Normal file
105
relay/frontend/static/instance.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
function append_table_row(table, instance) {
|
||||
var row = table.insertRow(-1);
|
||||
row.id = instance.domain;
|
||||
|
||||
var domain = row.insertCell(0);
|
||||
domain.className = "domain";
|
||||
domain.innerHTML = `<a href="https://${instance.domain}/" target="_new">${instance.domain}</a>`;
|
||||
|
||||
var software = row.insertCell(1);
|
||||
software.className = "software";
|
||||
software.innerHTML = instance.software
|
||||
|
||||
var date = row.insertCell(2);
|
||||
date.className = "date";
|
||||
date.innerHTML = get_date_string(instance.created);
|
||||
|
||||
var remove = row.insertCell(3);
|
||||
remove.className = "remove";
|
||||
remove.innerHTML = `<a href="#" onclick="del_instance('${instance.domain}')" title="Remove Instance">✖</a>`;
|
||||
}
|
||||
|
||||
|
||||
async function add_instance() {
|
||||
var elems = {
|
||||
actor: document.getElementById("new-actor"),
|
||||
inbox: document.getElementById("new-inbox"),
|
||||
followid: document.getElementById("new-followid"),
|
||||
software: document.getElementById("new-software")
|
||||
}
|
||||
|
||||
var values = {
|
||||
actor: elems.actor.value.trim(),
|
||||
inbox: elems.inbox.value.trim(),
|
||||
followid: elems.followid.value.trim(),
|
||||
software: elems.software.value.trim()
|
||||
}
|
||||
|
||||
if (values.actor === "") {
|
||||
alert("Domain, actor, and inbox are required");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var instance = await client.request("POST", "v1/instance", values);
|
||||
|
||||
} catch (err) {
|
||||
alert(err);
|
||||
return
|
||||
}
|
||||
|
||||
append_table_row(document.getElementById("instances"), instance);
|
||||
|
||||
elems.actor.value = null;
|
||||
elems.inbox.value = null;
|
||||
elems.followid.value = null;
|
||||
elems.software.value = null;
|
||||
|
||||
document.querySelector("details.section").open = false;
|
||||
}
|
||||
|
||||
|
||||
async function del_instance(domain) {
|
||||
try {
|
||||
await client.request("DELETE", "v1/instance", {"domain": domain});
|
||||
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById(domain).remove();
|
||||
}
|
||||
|
||||
|
||||
async function req_response(domain, accept) {
|
||||
params = {
|
||||
"domain": domain,
|
||||
"accept": accept
|
||||
}
|
||||
|
||||
try {
|
||||
await client.request("POST", "v1/request", params);
|
||||
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById(domain).remove();
|
||||
|
||||
if (document.getElementById("requests").rows.length < 2) {
|
||||
document.querySelector("fieldset.requests").remove()
|
||||
}
|
||||
|
||||
if (!accept) {
|
||||
return;
|
||||
}
|
||||
|
||||
instances = await client.request("GET", `v1/instance`, null);
|
||||
instances.forEach((instance) => {
|
||||
if (instance.domain === domain) {
|
||||
append_table_row(document.getElementById("instances"), instance);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -10,7 +10,7 @@ from .base import View, register_route
|
|||
|
||||
from .. import __version__
|
||||
from ..database import ConfigData
|
||||
from ..misc import Message, Response, get_app
|
||||
from ..misc import Message, Response, boolean, get_app
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from aiohttp.web import Request
|
||||
|
@ -161,7 +161,7 @@ class Config(View):
|
|||
class Inbox(View):
|
||||
async def get(self, request: Request) -> Response:
|
||||
with self.database.session() as conn:
|
||||
data = tuple(conn.execute('SELECT * FROM inboxes').all())
|
||||
data = conn.get_inboxes()
|
||||
|
||||
return Response.new(data, ctype = 'json')
|
||||
|
||||
|
@ -186,6 +186,12 @@ class Inbox(View):
|
|||
|
||||
data['inbox'] = actor_data.shared_inbox
|
||||
|
||||
if not data.get('software'):
|
||||
nodeinfo = await self.client.fetch_nodeinfo(data['domain'])
|
||||
|
||||
if nodeinfo is not None:
|
||||
data['software'] = nodeinfo.sw_name
|
||||
|
||||
row = conn.put_inbox(**data)
|
||||
|
||||
return Response.new(row, ctype = 'json')
|
||||
|
@ -206,7 +212,7 @@ class Inbox(View):
|
|||
return Response.new(instance, ctype = 'json')
|
||||
|
||||
|
||||
async def delete(self, request: Request, domain: str) -> Response:
|
||||
async def delete(self, request: Request) -> Response:
|
||||
with self.database.session() as conn:
|
||||
data = await self.get_api_data(['domain'], [])
|
||||
|
||||
|
@ -232,10 +238,7 @@ class RequestView(View):
|
|||
|
||||
async def post(self, request: Request) -> Response:
|
||||
data = await self.get_api_data(['domain', 'accept'], [])
|
||||
|
||||
if not isinstance(data['accept'], bool):
|
||||
atype = type(data['accept']).__name__
|
||||
return Response.new_error(400, f'Invalid type for "accept": {atype}', 'json')
|
||||
data['accept'] = boolean(data['accept'])
|
||||
|
||||
try:
|
||||
with self.database.session(True) as conn:
|
||||
|
|
Loading…
Reference in a new issue