server dashboard api and whatever
This commit is contained in:
parent
46802f995d
commit
a1095f7c5c
8 changed files with 129 additions and 9 deletions
|
@ -26,6 +26,7 @@ export { logger, app, db, PORT, SESSION_LIFETIME }
|
||||||
import('./routes/root'),
|
import('./routes/root'),
|
||||||
import('./routes/login'),
|
import('./routes/login'),
|
||||||
import('./routes/dash/servers'),
|
import('./routes/dash/servers'),
|
||||||
|
import('./routes/dash/server'),
|
||||||
]);
|
]);
|
||||||
logger.done('All routes and middlewares loaded');
|
logger.done('All routes and middlewares loaded');
|
||||||
})();
|
})();
|
||||||
|
|
32
api/src/routes/dash/server.ts
Normal file
32
api/src/routes/dash/server.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { app } from '../..';
|
||||||
|
import { Request, Response } from 'express';
|
||||||
|
import { badRequest, isAuthenticated, unauthorized } from '../../utils';
|
||||||
|
import { botReq } from '../internal/ws';
|
||||||
|
|
||||||
|
type ServerDetails = {
|
||||||
|
id: string,
|
||||||
|
perms: 0|1|2,
|
||||||
|
name: string,
|
||||||
|
description?: string,
|
||||||
|
iconURL?: string,
|
||||||
|
bannerURL?: string,
|
||||||
|
serverConfig: any,
|
||||||
|
}
|
||||||
|
|
||||||
|
app.get('/dash/server/:server', async (req: Request, res: Response) => {
|
||||||
|
const user = await isAuthenticated(req, res, true);
|
||||||
|
if (!user) return unauthorized(res);
|
||||||
|
|
||||||
|
const { server } = req.params;
|
||||||
|
if (!server || typeof server != 'string') return badRequest(res);
|
||||||
|
|
||||||
|
const response = await botReq('getUserServerDetails', { user, server });
|
||||||
|
if (!response.success) {
|
||||||
|
return res.status(response.statusCode ?? 500).send({ error: response.error });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response.server) return res.status(404).send({ error: 'Not found' });
|
||||||
|
|
||||||
|
const s: ServerDetails = response.server;
|
||||||
|
res.send({ server: s });
|
||||||
|
});
|
|
@ -1,13 +1,13 @@
|
||||||
import { app } from '../..';
|
import { app } from '../..';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { isAuthenticated } from '../../utils';
|
import { isAuthenticated, unauthorized } from '../../utils';
|
||||||
import { botReq } from '../internal/ws';
|
import { botReq } from '../internal/ws';
|
||||||
|
|
||||||
type Server = { id: string, perms: 0|1|2, name: string, iconURL?: string, bannerURL?: string }
|
type Server = { id: string, perms: 0|1|2, name: string, iconURL?: string, bannerURL?: string }
|
||||||
|
|
||||||
app.get('/dash/servers', async (req: Request, res: Response) => {
|
app.get('/dash/servers', async (req: Request, res: Response) => {
|
||||||
const user = await isAuthenticated(req, res, true);
|
const user = await isAuthenticated(req, res, true);
|
||||||
if (!user) return;
|
if (!user) return unauthorized(res);
|
||||||
|
|
||||||
const response = await botReq('getUserServers', { user });
|
const response = await botReq('getUserServers', { user });
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { Request, Response } from 'express';
|
||||||
import { botReq } from './internal/ws';
|
import { botReq } from './internal/ws';
|
||||||
import { db } from '..';
|
import { db } from '..';
|
||||||
import { FindOneResult } from 'monk';
|
import { FindOneResult } from 'monk';
|
||||||
|
import { badRequest } from '../utils';
|
||||||
|
|
||||||
class BeginReqBody {
|
class BeginReqBody {
|
||||||
user: string;
|
user: string;
|
||||||
|
@ -61,7 +62,3 @@ app.post('/login/complete', async (req: Request, res: Response) => {
|
||||||
|
|
||||||
res.status(200).send({ success: true, user: body.user.toUpperCase(), token: sessionToken });
|
res.status(200).send({ success: true, user: body.user.toUpperCase(), token: sessionToken });
|
||||||
});
|
});
|
||||||
|
|
||||||
function badRequest(res: Response) {
|
|
||||||
res.status(400).send(JSON.stringify({ "error": "Invalid request body" }, null, 4));
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,4 +36,12 @@ async function getSessionInfo(user: string, token: string): Promise<SessionInfo>
|
||||||
return { exists: !!session, valid: !!(session && !session.invalid && session.expires > Date.now()), nonce: session?.nonce }
|
return { exists: !!session, valid: !!(session && !session.invalid && session.expires > Date.now()), nonce: session?.nonce }
|
||||||
}
|
}
|
||||||
|
|
||||||
export { isAuthenticated, getSessionInfo }
|
function badRequest(res: Response) {
|
||||||
|
res.status(400).send(JSON.stringify({ "error": "Invalid request body" }, null, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
function unauthorized(res: Response) {
|
||||||
|
res.status(401).send(JSON.stringify({ "error": "Unauthorized" }, null, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
export { isAuthenticated, getSessionInfo, badRequest, unauthorized }
|
||||||
|
|
61
bot/src/bot/modules/api/server_details.ts
Normal file
61
bot/src/bot/modules/api/server_details.ts
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
import { Member } from "revolt.js/dist/maps/Members";
|
||||||
|
import { User } from "revolt.js/dist/maps/Users";
|
||||||
|
import { client } from "../../..";
|
||||||
|
import AutomodSettings from "../../../struct/antispam/AutomodSettings";
|
||||||
|
import ServerConfig from "../../../struct/ServerConfig";
|
||||||
|
import { getPermissionLevel } from "../../util";
|
||||||
|
import { wsEvents, WSResponse } from "../api_communication";
|
||||||
|
|
||||||
|
type ReqData = { user: string, server: string }
|
||||||
|
|
||||||
|
type ServerDetails = {
|
||||||
|
id: string,
|
||||||
|
perms: 0|1|2,
|
||||||
|
name: string,
|
||||||
|
description?: string,
|
||||||
|
iconURL?: string,
|
||||||
|
bannerURL?: string,
|
||||||
|
serverConfig?: ServerConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSResponse) => void) => {
|
||||||
|
try {
|
||||||
|
const server = client.servers.get(data.server);
|
||||||
|
if (!server) return cb({ success: false, error: 'The requested server could not be found', statusCode: 404 });
|
||||||
|
|
||||||
|
let user: User;
|
||||||
|
try {
|
||||||
|
user = client.users.get(data.user) || await client.users.fetch(data.user);
|
||||||
|
} catch(e) {
|
||||||
|
cb({ success: false, error: 'The requested user could not be found', statusCode: 404 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let member: Member;
|
||||||
|
try {
|
||||||
|
member = await server.fetchMember(user);
|
||||||
|
} catch(e) {
|
||||||
|
cb({ success: false, error: 'The requested user is not a member of that server', statusCode: 401 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const serverConfig: ServerConfig = await client.db.get('servers').findOne({ id: server._id });
|
||||||
|
|
||||||
|
// todo: remove unwanted keys from server config
|
||||||
|
|
||||||
|
const response: ServerDetails = {
|
||||||
|
id: server._id,
|
||||||
|
name: server.name,
|
||||||
|
perms: await getPermissionLevel(member, server),
|
||||||
|
description: server.description ?? undefined,
|
||||||
|
bannerURL: server.generateBannerURL(),
|
||||||
|
iconURL: server.generateIconURL(),
|
||||||
|
serverConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
cb({ success: true, server: response });
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
cb({ success: false, error: `${e}` });
|
||||||
|
}
|
||||||
|
});
|
|
@ -134,3 +134,4 @@ wsEvents.on('req:requestLogin', async (data: any, cb: (data: WSResponse) => void
|
||||||
export { wsEvents, wsSend, WSResponse }
|
export { wsEvents, wsSend, WSResponse }
|
||||||
|
|
||||||
import('./api/servers');
|
import('./api/servers');
|
||||||
|
import('./api/server_details');
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { FunctionComponent, useCallback, useEffect, useState } from "react";
|
||||||
import { Button } from '@revoltchat/ui/lib/components/atoms/inputs/Button';
|
import { Button } from '@revoltchat/ui/lib/components/atoms/inputs/Button';
|
||||||
import { InputBox } from '@revoltchat/ui/lib/components/atoms/inputs/InputBox';
|
import { InputBox } from '@revoltchat/ui/lib/components/atoms/inputs/InputBox';
|
||||||
import { H1 } from '@revoltchat/ui/lib/components/atoms/heading/H1';
|
import { H1 } from '@revoltchat/ui/lib/components/atoms/heading/H1';
|
||||||
import { H2 } from '@revoltchat/ui/lib/components/atoms/heading/H2';
|
import { H4 } from '@revoltchat/ui/lib/components/atoms/heading/H4';
|
||||||
import { API_URL } from "../App";
|
import { API_URL } from "../App";
|
||||||
import { getAuthHeaders } from "../utils";
|
import { getAuthHeaders } from "../utils";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
@ -12,10 +12,30 @@ import { useParams } from "react-router-dom";
|
||||||
type Server = { id: string, perms: 0|1|2, name: string, iconURL?: string, bannerURL?: string }
|
type Server = { id: string, perms: 0|1|2, name: string, iconURL?: string, bannerURL?: string }
|
||||||
|
|
||||||
const ServerDashboard: FunctionComponent = () => {
|
const ServerDashboard: FunctionComponent = () => {
|
||||||
|
const [serverInfo, setServerInfo] = useState({} as any);
|
||||||
|
const [status, setStatus] = useState('');
|
||||||
const { serverid } = useParams();
|
const { serverid } = useParams();
|
||||||
|
|
||||||
|
const loadInfo = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const res = await axios.get(`${API_URL}/dash/server/${serverid}`, { headers: await getAuthHeaders() });
|
||||||
|
setServerInfo(res.data.server);
|
||||||
|
} catch(e: any) {
|
||||||
|
console.error(e);
|
||||||
|
setStatus(`${e?.message ?? e}`);
|
||||||
|
}
|
||||||
|
}, [serverInfo]);
|
||||||
|
|
||||||
|
useEffect(() => { loadInfo() }, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a>sus</a>
|
<>
|
||||||
|
<H1>{serverInfo?.name ?? 'Loading...'}</H1>
|
||||||
|
{status.length ? <a>{status}</a> : <br/>}
|
||||||
|
<div hidden={Object.keys(serverInfo).length == 0}>
|
||||||
|
<H4>{serverInfo.description ?? ''}</H4>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue