basic sharex stuff, api key auth

This commit is contained in:
cirroskais 2024-08-02 10:34:38 -04:00
parent 7745b07418
commit 4c3f4d719f
No known key found for this signature in database
GPG key ID: 5FC73EBF2678E33D
7 changed files with 107 additions and 36 deletions

View file

@ -1,21 +1,16 @@
import { error, redirect } from '@sveltejs/kit';
import { getSession } from '$lib/server/database';
import { redirect } from '@sveltejs/kit';
import { getSession, getUserApiKey } from '$lib/server/database';
import { COOKIE } from '$lib/config';
const PUBLIC_RESOURCES = [
'/',
'/api',
'/api/auth/register',
'/api/auth/login',
'/terms',
'/privacy'
];
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
const { cookies, locals } = event;
const session = await getSession(cookies.get(COOKIE) || '');
const { cookies, locals, request } = event;
let cookie = cookies.get(COOKIE);
let bearer = request.headers.get('Authorization');
if (bearer) bearer = bearer.replace('Bearer ', '');
if (cookie) {
const session = await getSession(cookie);
if (session && session.user) {
locals.user = {
id: session.user.id,
@ -24,17 +19,30 @@ export async function handle({ event, resolve }) {
maxUploadMB: session.user.maxUploadMB,
role: session.user.role
};
} else {
if (event.route.id) {
if (event.route.id.includes('(app)')) return redirect(303, '/');
}
}
if (bearer && !locals.user) {
const apiKey = await getUserApiKey(bearer);
if (apiKey && apiKey.user) {
locals.user = {
id: apiKey.user.id,
username: apiKey.user.username,
email: apiKey.user.email,
maxUploadMB: apiKey.user.maxUploadMB,
role: apiKey.user.role
};
}
}
if (!locals.user && event.route.id) {
if (event.route.id.includes('(app)')) return redirect(303, '/');
}
return await resolve(event);
}
/** @type {import('@sveltejs/kit').HandleServerError} */
export async function handleError({ error, event, status, message }) {
export async function handleError({ error, status, message }) {
console.log(error);
return {

View file

@ -60,7 +60,7 @@
type={'email'}
name={'email'}
id={'email'}
placeholder={'user@example.com'}
placeholder={'john@doefamily.com'}
bind:value={email}
required={true}
>

View file

@ -80,7 +80,7 @@
type={'email'}
name={'email'}
id={'email'}
placeholder={'user@example.com'}
placeholder={'jane@doefamily.com'}
bind:value={email}
required={true}
>

View file

@ -11,8 +11,8 @@
-->
{#if type === 'username'}
<div class="flex p-2 space-x-1 rounded-lg shadow-md bg-crust">
<div class="py-0.5 pr-1 border-r-2 border-overlay2">
<div class="flex p-2 space-x-2 rounded-lg shadow-md bg-crust">
<div class="py-0.5 pr-2 border-r-2 border-overlay0">
<slot />
</div>
<input
@ -26,8 +26,8 @@
/>
</div>
{:else if type === 'email'}
<div class="flex p-2 space-x-1 rounded-lg shadow-md bg-crust">
<div class="py-0.5 pr-1 border-r-2 border-overlay2">
<div class="flex p-2 space-x-2 rounded-lg shadow-md bg-crust">
<div class="py-0.5 pr-2 border-r-2 border-overlay0">
<slot />
</div>
<input
@ -41,8 +41,8 @@
/>
</div>
{:else if type === 'password'}
<div class="flex p-2 space-x-1 rounded-lg shadow-md bg-crust">
<div class="py-0.5 pr-1 border-r-2 border-overlay2">
<div class="flex p-2 space-x-2 rounded-lg shadow-md bg-crust">
<div class="py-0.5 pr-2 border-r-2 border-overlay0">
<slot />
</div>
<input

View file

@ -172,3 +172,28 @@ export async function deleteUserApiKey(userId: number, id: string) {
}
});
}
export async function getUserApiKey(id: string) {
if (!id) return false;
return await prisma.aPIKey.findFirst({
where: {
id
},
include: {
user: {
select: {
id: true,
username: true,
email: true,
password: true,
role: true,
createdAt: true,
lastSeen: true,
maxUploadMB: true,
settings: true
}
}
}
});
}

View file

@ -16,7 +16,7 @@ const ApiKeyLimits = {
setInterval(function resetMinute() {}, 1000 * 60);
setInterval(function resetHour() {}, 1000 * 60 * 60);
function hash(input) {
function hash(input: string) {
createHash('sha256').update(input).digest('hex');
}

View file

@ -0,0 +1,38 @@
<script lang="ts">
import { page } from '$app/stores';
import Button from '$lib/components/Inputs/Button.svelte';
import { API_KEY_PERMISSIONS } from '$lib/config';
import { get } from 'svelte/store';
let awesome = '';
async function click() {
const response = await fetch('/api/v1/keys');
const body = (await response.json()) as { id: string; permissions: number }[];
const key = body.find((key) => key.permissions & API_KEY_PERMISSIONS.CREATE_UPLOADS);
if (!key) return (awesome = 'What the fuck did i tell you');
awesome = `{
"Version": "14.0.0",
"Name": "cirros file uploader",
"DestinationType": "ImageUploader, FileUploader",
"RequestMethod": "POST",
"RequestURL": "${get(page).url.origin}/api/v1/upload",
"Headers": {
"Authorization": "Bearer ${key.id}",
},
"Body": "MultipartFormData",
"FileFormName": "file",
"URL": "${get(page).url.origin}{response}",
}`;
}
</script>
<p>I'll make real documentation later but for now have this ShareX button</p>
<p class="mb-2">
MAKE SURE TO HAVE A VALID API KEY WITH THE CREATE_UPLOADS PERMISSION ( 1 &lt;&lt; 0 )
</p>
<Button {click}>The sharex button in question</Button>
<tt class="block mt-3 whitespace-pre-wrap">{awesome}</tt>