mirror of
https://git.pleroma.social/pleroma/relay.git
synced 2024-11-22 14:38:00 +00:00
use api for instances admin page
This commit is contained in:
parent
aeb84d7a72
commit
f775335e80
|
@ -1,29 +1,32 @@
|
||||||
-extends "base.haml"
|
-extends "base.haml"
|
||||||
-set page="Instances"
|
-set page="Instances"
|
||||||
|
|
||||||
|
-block head
|
||||||
|
%script(type="application/javascript" src="/static/instance.js" nonce="{{view.request['hash']}}")
|
||||||
|
|
||||||
-block content
|
-block content
|
||||||
%details.section
|
%details.section
|
||||||
%summary << Add Instance
|
%summary << Add Instance
|
||||||
%form(action="/admin/instances" method="POST")
|
#add-item
|
||||||
#add-item
|
%label(for="new-actor") << Actor
|
||||||
%label(for="domain") << Domain
|
%input(type="url" id="new-actor" placeholder="Actor URL")
|
||||||
%input(type="domain" id="domain" name="domain" placeholder="Domain")
|
|
||||||
|
|
||||||
%label(for="actor") << Actor URL
|
%label(for="new-inbox") << Inbox
|
||||||
%input(type="url" id="actor" name="actor" placeholder="Actor URL")
|
%input(type="url" id="new-inbox" placeholder="Inbox URL")
|
||||||
|
|
||||||
%label(for="inbox") << Inbox URL
|
%label(for="new-followid") << Follow ID
|
||||||
%input(type="url" id="inbox" name="inbox" placeholder="Inbox URL")
|
%input(type="url" id="new-followid" placeholder="Follow ID URL")
|
||||||
|
|
||||||
%label(for="software") << Software
|
%label(for="new-software") << Software
|
||||||
%input(name="software" id="software" placeholder="software")
|
%input(id="new-software" placeholder="software")
|
||||||
|
|
||||||
%input(type="submit" value="Add Instance")
|
%input(type="button" value="Add Instance", onclick="add_instance()")
|
||||||
|
|
||||||
-if requests
|
-if requests
|
||||||
%fieldset.section
|
%fieldset.section.requests
|
||||||
%legend << Follow Requests
|
%legend << Follow Requests
|
||||||
.data-table
|
.data-table
|
||||||
%table
|
%table#requests
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%td.instance << Instance
|
%td.instance << Instance
|
||||||
|
@ -34,7 +37,7 @@
|
||||||
|
|
||||||
%tbody
|
%tbody
|
||||||
-for request in requests
|
-for request in requests
|
||||||
%tr
|
%tr(id="{{request.domain}}")
|
||||||
%td.instance
|
%td.instance
|
||||||
%a(href="https://{{request.domain}}" target="_new") -> =request.domain
|
%a(href="https://{{request.domain}}" target="_new") -> =request.domain
|
||||||
|
|
||||||
|
@ -45,16 +48,16 @@
|
||||||
=request.created.strftime("%Y-%m-%d")
|
=request.created.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
%td.approve
|
%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
|
%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
|
%legend << Instances
|
||||||
|
|
||||||
.data-table
|
.data-table
|
||||||
%table
|
%table#instances
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%td.instance << Instance
|
%td.instance << Instance
|
||||||
|
@ -64,7 +67,7 @@
|
||||||
|
|
||||||
%tbody
|
%tbody
|
||||||
-for instance in instances
|
-for instance in instances
|
||||||
%tr
|
%tr(id="{{instance.domain}}")
|
||||||
%td.instance
|
%td.instance
|
||||||
%a(href="https://{{instance.domain}}/" target="_new") -> =instance.domain
|
%a(href="https://{{instance.domain}}/" target="_new") -> =instance.domain
|
||||||
|
|
||||||
|
@ -75,4 +78,4 @@
|
||||||
=instance.created.strftime("%Y-%m-%d")
|
=instance.created.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
%td.remove
|
%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);
|
throw new Error(message.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.hasOwn(message, "created")) {
|
if (Array.isArray(message)) {
|
||||||
message.created = new Date(message.created);
|
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;
|
return message;
|
||||||
|
|
|
@ -15,8 +15,6 @@ function create_ban_object(domain, reason, note) {
|
||||||
|
|
||||||
async function ban() {
|
async function ban() {
|
||||||
var table = document.querySelector("table");
|
var table = document.querySelector("table");
|
||||||
var row = table.insertRow(-1);
|
|
||||||
|
|
||||||
var elems = {
|
var elems = {
|
||||||
domain: document.getElementById("new-domain"),
|
domain: document.getElementById("new-domain"),
|
||||||
reason: document.getElementById("new-reason"),
|
reason: document.getElementById("new-reason"),
|
||||||
|
@ -42,7 +40,9 @@ async function ban() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var row = table.insertRow(-1);
|
||||||
row.id = ban.domain;
|
row.id = ban.domain;
|
||||||
|
|
||||||
var new_domain = row.insertCell(0);
|
var new_domain = row.insertCell(0);
|
||||||
var new_date = row.insertCell(1);
|
var new_date = row.insertCell(1);
|
||||||
var new_remove = row.insertCell(2);
|
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 .. import __version__
|
||||||
from ..database import ConfigData
|
from ..database import ConfigData
|
||||||
from ..misc import Message, Response, get_app
|
from ..misc import Message, Response, boolean, get_app
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
from aiohttp.web import Request
|
from aiohttp.web import Request
|
||||||
|
@ -161,7 +161,7 @@ class Config(View):
|
||||||
class Inbox(View):
|
class Inbox(View):
|
||||||
async def get(self, request: Request) -> Response:
|
async def get(self, request: Request) -> Response:
|
||||||
with self.database.session() as conn:
|
with self.database.session() as conn:
|
||||||
data = tuple(conn.execute('SELECT * FROM inboxes').all())
|
data = conn.get_inboxes()
|
||||||
|
|
||||||
return Response.new(data, ctype = 'json')
|
return Response.new(data, ctype = 'json')
|
||||||
|
|
||||||
|
@ -186,6 +186,12 @@ class Inbox(View):
|
||||||
|
|
||||||
data['inbox'] = actor_data.shared_inbox
|
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)
|
row = conn.put_inbox(**data)
|
||||||
|
|
||||||
return Response.new(row, ctype = 'json')
|
return Response.new(row, ctype = 'json')
|
||||||
|
@ -206,7 +212,7 @@ class Inbox(View):
|
||||||
return Response.new(instance, ctype = 'json')
|
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:
|
with self.database.session() as conn:
|
||||||
data = await self.get_api_data(['domain'], [])
|
data = await self.get_api_data(['domain'], [])
|
||||||
|
|
||||||
|
@ -232,10 +238,7 @@ class RequestView(View):
|
||||||
|
|
||||||
async def post(self, request: Request) -> Response:
|
async def post(self, request: Request) -> Response:
|
||||||
data = await self.get_api_data(['domain', 'accept'], [])
|
data = await self.get_api_data(['domain', 'accept'], [])
|
||||||
|
data['accept'] = boolean(data['accept'])
|
||||||
if not isinstance(data['accept'], bool):
|
|
||||||
atype = type(data['accept']).__name__
|
|
||||||
return Response.new_error(400, f'Invalid type for "accept": {atype}', 'json')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with self.database.session(True) as conn:
|
with self.database.session(True) as conn:
|
||||||
|
|
Loading…
Reference in a new issue