progress bar + better ui (fix)
This commit is contained in:
@@ -77,7 +77,13 @@ export function UploadProgressForm({ csrfToken }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="form-grid" onSubmit={handleSubmit} encType="multipart/form-data">
|
<form
|
||||||
|
className="form-grid"
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
action="/manage/api/upload"
|
||||||
|
method="post"
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
<input type="hidden" name="csrfToken" value={csrfToken} />
|
<input type="hidden" name="csrfToken" value={csrfToken} />
|
||||||
|
|
||||||
<label className="field">
|
<label className="field">
|
||||||
|
|||||||
@@ -101,38 +101,57 @@ function dashboardHref(params = {}) {
|
|||||||
: `${managementBasePath}/dashboard`;
|
: `${managementBasePath}/dashboard`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function jsonError(message, status = 400) {
|
function expectsHtml(request) {
|
||||||
|
return String(request.headers.get('accept') || '').includes('text/html');
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorResponse(request, message, status = 400) {
|
||||||
|
if (expectsHtml(request)) {
|
||||||
|
const target = new URL(dashboardHref({ error: message }), request.url);
|
||||||
|
return NextResponse.redirect(target, { status: 303 });
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json({ ok: false, error: message }, { status });
|
return NextResponse.json({ ok: false, error: message }, { status });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function successResponse(request, message) {
|
||||||
|
const redirectPath = dashboardHref({ success: message });
|
||||||
|
if (expectsHtml(request)) {
|
||||||
|
const target = new URL(redirectPath, request.url);
|
||||||
|
return NextResponse.redirect(target, { status: 303 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ ok: true, redirect: redirectPath });
|
||||||
|
}
|
||||||
|
|
||||||
export async function POST(request) {
|
export async function POST(request) {
|
||||||
await runCleanupIfNeeded();
|
await runCleanupIfNeeded();
|
||||||
|
|
||||||
const user = await getAuthenticatedUser();
|
const user = await getAuthenticatedUser();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return jsonError('Nicht angemeldet.', 401);
|
return errorResponse(request, 'Nicht angemeldet.', 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
let formData;
|
let formData;
|
||||||
try {
|
try {
|
||||||
formData = await request.formData();
|
formData = await request.formData();
|
||||||
} catch {
|
} catch {
|
||||||
return jsonError('Ungültige Formulardaten.', 400);
|
return errorResponse(request, 'Ungültige Formulardaten.', 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await verifyCsrf(formData);
|
await verifyCsrf(formData);
|
||||||
} catch {
|
} catch {
|
||||||
return jsonError('CSRF-Prüfung fehlgeschlagen.', 403);
|
return errorResponse(request, 'CSRF-Prüfung fehlgeschlagen.', 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadedFile = uploadedFileFromForm(formData, 'file');
|
const uploadedFile = uploadedFileFromForm(formData, 'file');
|
||||||
if (!uploadedFile || Number(uploadedFile.size || 0) <= 0) {
|
if (!uploadedFile || Number(uploadedFile.size || 0) <= 0) {
|
||||||
return jsonError('Keine Datei hochgeladen.', 400);
|
return errorResponse(request, 'Keine Datei hochgeladen.', 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxUploadBytes > 0 && Number(uploadedFile.size || 0) > maxUploadBytes) {
|
if (maxUploadBytes > 0 && Number(uploadedFile.size || 0) > maxUploadBytes) {
|
||||||
return jsonError(`Datei überschreitet das Größenlimit (${maxUploadBytes} Bytes).`, 413);
|
return errorResponse(request, `Datei überschreitet das Größenlimit (${maxUploadBytes} Bytes).`, 413);
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@@ -156,7 +175,7 @@ export async function POST(request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!storedName || !storedPath) {
|
if (!storedName || !storedPath) {
|
||||||
return jsonError('Upload-ID konnte nicht erzeugt werden.', 500);
|
return errorResponse(request, 'Upload-ID konnte nicht erzeugt werden.', 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -183,11 +202,8 @@ export async function POST(request) {
|
|||||||
await getRequestMeta()
|
await getRequestMeta()
|
||||||
);
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return jsonError('Upload fehlgeschlagen.', 500);
|
return errorResponse(request, 'Upload fehlgeschlagen.', 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({
|
return successResponse(request, 'Upload abgeschlossen.');
|
||||||
ok: true,
|
|
||||||
redirect: dashboardHref({ success: 'Upload abgeschlossen.' }),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,6 @@ export async function clearAuthCookie() {
|
|||||||
export async function requireAuthenticatedUser() {
|
export async function requireAuthenticatedUser() {
|
||||||
const user = await getAuthenticatedUser();
|
const user = await getAuthenticatedUser();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
await clearAuthCookie();
|
|
||||||
redirect('/manage/login');
|
redirect('/manage/login');
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
@@ -162,7 +161,6 @@ export async function requireAuthenticatedUser() {
|
|||||||
export async function requireAdminUser() {
|
export async function requireAdminUser() {
|
||||||
const user = await getAuthenticatedUser();
|
const user = await getAuthenticatedUser();
|
||||||
if (!user || !user.admin) {
|
if (!user || !user.admin) {
|
||||||
await clearAuthCookie();
|
|
||||||
redirect('/manage/admin');
|
redirect('/manage/admin');
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
|
|||||||
Reference in New Issue
Block a user