This commit is contained in:
parent
9e282cf61b
commit
8cb1e8bec5
@ -4,6 +4,7 @@ export class Permissions {
|
||||
static readonly Reports = 2 << 2;
|
||||
static readonly Feedback = 2 << 3;
|
||||
static readonly Settings = 2 << 4;
|
||||
static readonly Tools = 2 << 5;
|
||||
|
||||
readonly value: number;
|
||||
|
||||
@ -31,7 +32,8 @@ export class Permissions {
|
||||
Permissions.Users,
|
||||
Permissions.Reports,
|
||||
Permissions.Feedback,
|
||||
Permissions.Settings
|
||||
Permissions.Settings,
|
||||
Permissions.Tools
|
||||
];
|
||||
}
|
||||
|
||||
@ -51,6 +53,9 @@ export class Permissions {
|
||||
settings(): boolean {
|
||||
return (this.value & Permissions.Reports) != 0;
|
||||
}
|
||||
tools(): boolean {
|
||||
return (this.value & Permissions.Tools) != 0;
|
||||
}
|
||||
|
||||
asArray(): number[] {
|
||||
const array = [];
|
||||
|
@ -21,6 +21,7 @@ export const load: LayoutServerLoad = async ({ route, cookies }) => {
|
||||
: null,
|
||||
adminCount: session?.permissions.admin() ? await Admin.count() : null,
|
||||
settingsRead: session?.permissions.settings(),
|
||||
toolsRead: session?.permissions.tools(),
|
||||
self: session
|
||||
? JSON.parse(JSON.stringify(await Admin.findOne({ where: { id: session.userId } })))
|
||||
: null
|
||||
|
@ -8,7 +8,8 @@
|
||||
Flag,
|
||||
UserGroup,
|
||||
Users,
|
||||
BookOpen
|
||||
BookOpen,
|
||||
WrenchScrewdriver
|
||||
} from 'svelte-heros-v2';
|
||||
import { buttonTriggeredRequest } from '$lib/components/utils';
|
||||
import { goto } from '$app/navigation';
|
||||
@ -69,6 +70,13 @@
|
||||
name: 'Website Einstellungen',
|
||||
badge: null,
|
||||
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,
|
||||
Reports: Permissions.Reports,
|
||||
Feedback: Permissions.Feedback,
|
||||
Settings: Permissions.Settings
|
||||
Settings: Permissions.Settings,
|
||||
Tools: Permissions.Tools
|
||||
};
|
||||
|
||||
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