This commit is contained in:
parent
9e282cf61b
commit
8cb1e8bec5
@ -4,6 +4,7 @@ export class Permissions {
|
|||||||
static readonly Reports = 2 << 2;
|
static readonly Reports = 2 << 2;
|
||||||
static readonly Feedback = 2 << 3;
|
static readonly Feedback = 2 << 3;
|
||||||
static readonly Settings = 2 << 4;
|
static readonly Settings = 2 << 4;
|
||||||
|
static readonly Tools = 2 << 5;
|
||||||
|
|
||||||
readonly value: number;
|
readonly value: number;
|
||||||
|
|
||||||
@ -31,7 +32,8 @@ export class Permissions {
|
|||||||
Permissions.Users,
|
Permissions.Users,
|
||||||
Permissions.Reports,
|
Permissions.Reports,
|
||||||
Permissions.Feedback,
|
Permissions.Feedback,
|
||||||
Permissions.Settings
|
Permissions.Settings,
|
||||||
|
Permissions.Tools
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +53,9 @@ export class Permissions {
|
|||||||
settings(): boolean {
|
settings(): boolean {
|
||||||
return (this.value & Permissions.Reports) != 0;
|
return (this.value & Permissions.Reports) != 0;
|
||||||
}
|
}
|
||||||
|
tools(): boolean {
|
||||||
|
return (this.value & Permissions.Tools) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
asArray(): number[] {
|
asArray(): number[] {
|
||||||
const array = [];
|
const array = [];
|
||||||
|
@ -21,6 +21,7 @@ export const load: LayoutServerLoad = async ({ route, cookies }) => {
|
|||||||
: null,
|
: null,
|
||||||
adminCount: session?.permissions.admin() ? await Admin.count() : null,
|
adminCount: session?.permissions.admin() ? await Admin.count() : null,
|
||||||
settingsRead: session?.permissions.settings(),
|
settingsRead: session?.permissions.settings(),
|
||||||
|
toolsRead: session?.permissions.tools(),
|
||||||
self: session
|
self: session
|
||||||
? JSON.parse(JSON.stringify(await Admin.findOne({ where: { id: session.userId } })))
|
? JSON.parse(JSON.stringify(await Admin.findOne({ where: { id: session.userId } })))
|
||||||
: null
|
: null
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
Flag,
|
Flag,
|
||||||
UserGroup,
|
UserGroup,
|
||||||
Users,
|
Users,
|
||||||
BookOpen
|
BookOpen,
|
||||||
|
WrenchScrewdriver
|
||||||
} from 'svelte-heros-v2';
|
} from 'svelte-heros-v2';
|
||||||
import { buttonTriggeredRequest } from '$lib/components/utils';
|
import { buttonTriggeredRequest } from '$lib/components/utils';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
@ -69,6 +70,13 @@
|
|||||||
name: 'Website Einstellungen',
|
name: 'Website Einstellungen',
|
||||||
badge: null,
|
badge: null,
|
||||||
enabled: data.settingsRead
|
enabled: data.settingsRead
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `${env.PUBLIC_BASE_PATH}/admin/tools`,
|
||||||
|
icon: WrenchScrewdriver,
|
||||||
|
name: 'Tools',
|
||||||
|
badge: null,
|
||||||
|
enabled: data.toolsRead
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
Users: Permissions.Users,
|
Users: Permissions.Users,
|
||||||
Reports: Permissions.Reports,
|
Reports: Permissions.Reports,
|
||||||
Feedback: Permissions.Feedback,
|
Feedback: Permissions.Feedback,
|
||||||
Settings: Permissions.Settings
|
Settings: Permissions.Settings,
|
||||||
|
Tools: Permissions.Tools
|
||||||
};
|
};
|
||||||
|
|
||||||
let newAdminUsername = $state('');
|
let newAdminUsername = $state('');
|
||||||
|
3
src/routes/admin/tools/+layout.svelte
Normal file
3
src/routes/admin/tools/+layout.svelte
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div class="flex justify-center">
|
||||||
|
<slot />
|
||||||
|
</div>
|
11
src/routes/admin/tools/+page.server.ts
Normal file
11
src/routes/admin/tools/+page.server.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
import { getSession } from '$lib/server/session';
|
||||||
|
import { Permissions } from '$lib/permissions';
|
||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
import { env } from '$env/dynamic/public';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ cookies }) => {
|
||||||
|
if (getSession(cookies, { permissions: [Permissions.Settings] }) == null) {
|
||||||
|
throw redirect(302, `${env.PUBLIC_BASE_PATH}/admin`);
|
||||||
|
}
|
||||||
|
};
|
15
src/routes/admin/tools/+page.svelte
Normal file
15
src/routes/admin/tools/+page.svelte
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import UuidFinder from './UuidFinder.svelte';
|
||||||
|
|
||||||
|
let tools = [{ label: 'Account UUID finder', component: UuidFinder }];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
{#each tools as tool}
|
||||||
|
{@const Component = tool.component}
|
||||||
|
<fieldset class="border border-solid rounded border-gray-700 py-3 px-6">
|
||||||
|
<legend class="text-sm px-1">{tool.label}</legend>
|
||||||
|
<Component />
|
||||||
|
</fieldset>
|
||||||
|
{/each}
|
||||||
|
</div>
|
71
src/routes/admin/tools/+server.ts
Normal file
71
src/routes/admin/tools/+server.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { getSession } from '$lib/server/session';
|
||||||
|
import { Permissions } from '$lib/permissions';
|
||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import {
|
||||||
|
ApiError,
|
||||||
|
getBedrockUuid,
|
||||||
|
getJavaUuid,
|
||||||
|
RateLimitError,
|
||||||
|
UserNotFoundError
|
||||||
|
} from '$lib/server/minecraft';
|
||||||
|
import type { ZodType } from 'zod';
|
||||||
|
import { FindUuidSchema } from './schema';
|
||||||
|
|
||||||
|
export const POST = (async ({ url, request, cookies }) => {
|
||||||
|
if (getSession(cookies, { permissions: [Permissions.Tools] }) == null) {
|
||||||
|
return new Response(null, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = url.searchParams.get('action');
|
||||||
|
if (!action) {
|
||||||
|
return new Response(null, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (action) {
|
||||||
|
case 'getuuid': {
|
||||||
|
const data = await parseData(FindUuidSchema, await request.json());
|
||||||
|
return new Response(await findUuid(data.username, data.edition), { status: 200 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Response(null, { status: 400 });
|
||||||
|
} catch (error) {
|
||||||
|
return new Response(JSON.stringify({ error: error }), { status: 400 });
|
||||||
|
}
|
||||||
|
}) satisfies RequestHandler;
|
||||||
|
|
||||||
|
async function parseData<Output>(schema: ZodType<Output>, json: string): Promise<Output> {
|
||||||
|
const parseResult = await schema.safeParseAsync(json);
|
||||||
|
if (!parseResult.success) throw new Error(parseResult.error.toString());
|
||||||
|
|
||||||
|
return parseResult.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findUuid(username: string, edition: 'java' | 'bedrock'): Promise<string> {
|
||||||
|
let uuid = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (edition) {
|
||||||
|
case 'java':
|
||||||
|
uuid = await getJavaUuid(username);
|
||||||
|
break;
|
||||||
|
case 'bedrock':
|
||||||
|
uuid = await getBedrockUuid(username);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof UserNotFoundError) {
|
||||||
|
throw `Der Spielername ${username} existiert nicht`;
|
||||||
|
} else if (e instanceof ApiError) {
|
||||||
|
throw (e as Error).message;
|
||||||
|
} else if (e instanceof RateLimitError) {
|
||||||
|
throw 'Rate limit exceeded, bitte versuche es erneut';
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.stringify({
|
||||||
|
uuid: uuid
|
||||||
|
});
|
||||||
|
}
|
44
src/routes/admin/tools/UuidFinder.svelte
Normal file
44
src/routes/admin/tools/UuidFinder.svelte
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
|
import Select from '$lib/components/Input/Select.svelte';
|
||||||
|
import { sendRequest } from './tools';
|
||||||
|
|
||||||
|
let username = $state('');
|
||||||
|
let edition = $state('java');
|
||||||
|
let uuid = $state('');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col items-center space-y-4">
|
||||||
|
<div class="flex flex-row space-x-2">
|
||||||
|
<Input type="text" size="sm" bind:value={username}>
|
||||||
|
{#snippet label()}
|
||||||
|
<span>Username</span>
|
||||||
|
{/snippet}
|
||||||
|
</Input>
|
||||||
|
<Select label="Edition" size="sm" bind:value={edition}>
|
||||||
|
<option value="java">Java Edition</option>
|
||||||
|
<option value="bedrock">Bedrock Edition</option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
type="submit"
|
||||||
|
size="sm"
|
||||||
|
disabled={!username}
|
||||||
|
value="UUID finden"
|
||||||
|
onclick={() =>
|
||||||
|
sendRequest('getuuid', { username, edition })
|
||||||
|
.then((data) => (uuid = data.uuid))
|
||||||
|
.catch(() => (uuid = ''))}
|
||||||
|
/>
|
||||||
|
<div class="w-full">
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
size="sm"
|
||||||
|
readonly={true}
|
||||||
|
disabled={!uuid}
|
||||||
|
pickyWidth={false}
|
||||||
|
placeholder="UUID... "
|
||||||
|
value={uuid}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
6
src/routes/admin/tools/schema.ts
Normal file
6
src/routes/admin/tools/schema.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const FindUuidSchema = z.object({
|
||||||
|
username: z.string(),
|
||||||
|
edition: z.enum(['java', 'bedrock'])
|
||||||
|
});
|
22
src/routes/admin/tools/tools.ts
Normal file
22
src/routes/admin/tools/tools.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { env } from '$env/dynamic/public';
|
||||||
|
import { errorMessage } from '$lib/stores';
|
||||||
|
|
||||||
|
type Actions = 'getuuid';
|
||||||
|
|
||||||
|
export async function sendRequest<T = any>(action: Actions, data: any): Promise<T> {
|
||||||
|
const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/tools?action=${action}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
if (Object.hasOwn(data, 'error')) {
|
||||||
|
errorMessage.set(data['error']);
|
||||||
|
} else {
|
||||||
|
errorMessage.set('Ein Fehler ist aufgetreten');
|
||||||
|
}
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user