support iframing dashboard
This commit is contained in:
parent
6b5df8c33a
commit
bc10c3d014
5 changed files with 87 additions and 34 deletions
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"editor.formatOnSave": false
|
||||
}
|
|
@ -34,7 +34,7 @@ app.get('/dash/server/:server/automod',requireAuth({ permission: 2 }) , async (r
|
|||
const serverConfig: FindOneResult<any> = await db.get('servers').findOne({ id: server });
|
||||
|
||||
const result = {
|
||||
antispam: (serverConfig.automodSettings?.spam as AntispamRule[]|undefined)
|
||||
antispam: (serverConfig?.automodSettings?.spam as AntispamRule[]|undefined)
|
||||
?.map(r => ({ // Removing unwanted fields from response
|
||||
action: r.action,
|
||||
channels: r.channels,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { ulid } from "ulid";
|
||||
import crypto from "crypto";
|
||||
import { client, dbs } from "../..";
|
||||
import Infraction from "../../struct/antispam/Infraction";
|
||||
import InfractionType from "../../struct/antispam/InfractionType";
|
||||
|
@ -7,6 +8,8 @@ import logger from "../logger";
|
|||
import { hasPermForChannel, storeInfraction } from "../util";
|
||||
import { DEFAULT_PREFIX } from "./command_handler";
|
||||
|
||||
const DM_SESSION_LIFETIME = 1000 * 60 * 60 * 24 * 30;
|
||||
|
||||
// Listen to system messages
|
||||
client.on('message', async message => {
|
||||
if (typeof message.content != 'object') {
|
||||
|
@ -81,6 +84,36 @@ client.on('message', async message => {
|
|||
}
|
||||
});
|
||||
|
||||
// DM message based API session token retrieval
|
||||
client.on('message', async message => {
|
||||
console.log(message.channel?.channel_type, message.nonce, message.content)
|
||||
if (
|
||||
message.channel?.channel_type == "DirectMessage" &&
|
||||
message.nonce?.startsWith("REQUEST_SESSION_TOKEN-") &&
|
||||
message.content?.toLowerCase().startsWith("requesting session token.")
|
||||
) {
|
||||
logger.info('Received session token request in DMs.');
|
||||
|
||||
const token = crypto.randomBytes(48).toString('base64').replace(/=/g, '');
|
||||
|
||||
await client.db.get('sessions').insert({
|
||||
user: message.author_id,
|
||||
token: token,
|
||||
nonce: message.nonce,
|
||||
invalid: false,
|
||||
expires: Date.now() + DM_SESSION_LIFETIME,
|
||||
})
|
||||
|
||||
// Don't need to risk exposing the user to the token, so we'll send it in the nonce
|
||||
await message.channel.sendMessage({
|
||||
content: 'Token request granted.',
|
||||
nonce: `${ulid()}; TOKEN:${token}`,
|
||||
replies: [ { id: message.author_id, mention: false } ],
|
||||
});
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
// Send a message when added to a server
|
||||
client.on('member/join', (member) => {
|
||||
if (member._id.user != client.user?._id) return;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Route, BrowserRouter, Routes } from 'react-router-dom';
|
||||
import { Route, BrowserRouter, Routes, useLocation } from 'react-router-dom';
|
||||
import Home from './pages/Home';
|
||||
import './App.css';
|
||||
import '@revoltchat/ui/src/styles/dark.css';
|
||||
|
@ -6,6 +6,7 @@ import '@revoltchat/ui/src/styles/common.css';
|
|||
import RequireAuth from './components/RequireAuth';
|
||||
import DashboardHome from './pages/DashboardHome';
|
||||
import ServerDashboard from './pages/ServerDashboard/ServerDashboard';
|
||||
import localforage from 'localforage';
|
||||
|
||||
const API_URL = import.meta.env.VITE_API_URL?.toString()
|
||||
|| 'http://localhost:9000';
|
||||
|
@ -14,6 +15,18 @@ const BOT_PREFIX = import.meta.env.VITE_BOT_PREFIX?.toString()
|
|||
|| '/';
|
||||
|
||||
function App() {
|
||||
const authConfig = new URLSearchParams(window.location.search).get('setAuth');
|
||||
|
||||
if (authConfig) {
|
||||
console.log('Using provided auth data');
|
||||
|
||||
const [ user, token ] = authConfig.split(':');
|
||||
localforage.setItem('auth', {
|
||||
user: decodeURIComponent(user),
|
||||
token: decodeURIComponent(token),
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
|
|
|
@ -74,6 +74,8 @@ const ServerDashboard: FunctionComponent = () => {
|
|||
|
||||
const { serverid } = useParams();
|
||||
|
||||
const embedded = !!(new URLSearchParams(window.location.search).get('embedded'));
|
||||
|
||||
const saveConfig = useCallback(async () => {
|
||||
if (Object.values(changed).filter(i => i).length == 0) return;
|
||||
|
||||
|
@ -135,43 +137,45 @@ const ServerDashboard: FunctionComponent = () => {
|
|||
return (
|
||||
<>
|
||||
{status.length ? <a>{status}</a> : <></>}
|
||||
<div
|
||||
style={{
|
||||
marginTop: '8px',
|
||||
marginLeft: '8px',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
color: 'var(--secondary-foreground)',
|
||||
maxWidth: 'calc(100% - 20px)',
|
||||
}}
|
||||
>
|
||||
<Link to='/dashboard' style={{ float: 'left' }}>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Icon path={mdiChevronLeft} style={{ height: '25px' }} />
|
||||
<span>Back</span>
|
||||
</div>
|
||||
</Link>
|
||||
<span
|
||||
{!embedded && (
|
||||
<div
|
||||
style={{
|
||||
color: 'var(--foreground)',
|
||||
marginTop: '8px',
|
||||
marginLeft: '8px',
|
||||
}}
|
||||
>
|
||||
{serverInfo?.name ?? 'Loading...'}
|
||||
</span>
|
||||
<span style={{ color: 'var(--secondary-foreground)', marginLeft: '6px' }}>
|
||||
•
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
color: 'var(--secondary-foreground)',
|
||||
marginLeft: '6px',
|
||||
maxWidth: 'calc(100% - 20px)',
|
||||
}}
|
||||
>
|
||||
{serverInfo.description || <i>No server description set</i>}
|
||||
</span>
|
||||
</div>
|
||||
<Link to='/dashboard' style={{ float: 'left' }}>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Icon path={mdiChevronLeft} style={{ height: '25px' }} />
|
||||
<span>Back</span>
|
||||
</div>
|
||||
</Link>
|
||||
<span
|
||||
style={{
|
||||
color: 'var(--foreground)',
|
||||
marginLeft: '8px',
|
||||
}}
|
||||
>
|
||||
{serverInfo?.name ?? 'Loading...'}
|
||||
</span>
|
||||
<span style={{ color: 'var(--secondary-foreground)', marginLeft: '6px' }}>
|
||||
•
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
color: 'var(--secondary-foreground)',
|
||||
marginLeft: '6px',
|
||||
}}
|
||||
>
|
||||
{serverInfo.description || <i>No server description set</i>}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CategorySelector
|
||||
keys={[
|
||||
|
|
Loading…
Reference in a new issue