check file size in server action
This commit is contained in:
@ -3,11 +3,12 @@ import { Session } from '@util/session.ts';
|
|||||||
import { Permissions } from '@util/permissions.ts';
|
import { Permissions } from '@util/permissions.ts';
|
||||||
import { db } from '@db/database.ts';
|
import { db } from '@db/database.ts';
|
||||||
import { z } from 'astro:schema';
|
import { z } from 'astro:schema';
|
||||||
import { UPLOAD_PATH } from 'astro:env/server';
|
import { MAX_UPLOAD_BYTES, UPLOAD_PATH } from 'astro:env/server';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { sendWebhook, WebhookAction } from '@util/webhook.ts';
|
import { sendWebhook, WebhookAction } from '@util/webhook.ts';
|
||||||
|
import { allowedImageTypes, allowedVideoTypes } from '@util/media.ts';
|
||||||
|
|
||||||
export const report = {
|
export const report = {
|
||||||
submitReport: defineAction({
|
submitReport: defineAction({
|
||||||
@ -15,9 +16,22 @@ export const report = {
|
|||||||
urlHash: z.string(),
|
urlHash: z.string(),
|
||||||
reason: z.string(),
|
reason: z.string(),
|
||||||
body: z.string(),
|
body: z.string(),
|
||||||
files: z.array(z.instanceof(File)).nullable()
|
files: z
|
||||||
|
.array(
|
||||||
|
z
|
||||||
|
.instanceof(File)
|
||||||
|
.refine((f) => [...allowedImageTypes, ...allowedVideoTypes].findIndex((v) => v === f.type) !== -1)
|
||||||
|
)
|
||||||
|
.nullable()
|
||||||
}),
|
}),
|
||||||
handler: async (input) => {
|
handler: async (input) => {
|
||||||
|
const fileSize = input.files?.reduce((prev, curr) => prev + curr.size, 0);
|
||||||
|
if (fileSize && fileSize > MAX_UPLOAD_BYTES) {
|
||||||
|
throw new ActionError({
|
||||||
|
code: 'BAD_REQUEST'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const report = await db.getReportByUrlHash({ urlHash: input.urlHash });
|
const report = await db.getReportByUrlHash({ urlHash: input.urlHash });
|
||||||
if (!report) {
|
if (!report) {
|
||||||
throw new ActionError({
|
throw new ActionError({
|
||||||
|
@ -38,8 +38,7 @@
|
|||||||
{ key: 'report.status?.status', label: 'Bearbeitungsstatus' }
|
{ key: 'report.status?.status', label: 'Bearbeitungsstatus' }
|
||||||
]}
|
]}
|
||||||
onClick={(report) => (activeReport = report)}
|
onClick={(report) => (activeReport = report)}
|
||||||
>
|
/>
|
||||||
</DataTable>
|
|
||||||
|
|
||||||
{#key activeReport}
|
{#key activeReport}
|
||||||
<BottomBar {strikeReasons} report={activeReport} />
|
<BottomBar {strikeReasons} report={activeReport} />
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { popupState } from '@components/popup/Popup.ts';
|
import { popupState } from '@components/popup/Popup.ts';
|
||||||
|
import { allowedImageTypes, allowedVideoTypes } from '@util/media.ts';
|
||||||
|
|
||||||
// bindings
|
// bindings
|
||||||
let containerElem: HTMLDivElement;
|
let containerElem: HTMLDivElement;
|
||||||
let hiddenFileInputElem: HTMLInputElement;
|
let hiddenFileInputElem: HTMLInputElement;
|
||||||
let previewDialogElem: HTMLDialogElement;
|
let previewDialogElem: HTMLDialogElement;
|
||||||
|
|
||||||
// consts
|
|
||||||
const allowedImageTypes = ['image/png', 'image/jpeg', 'image/webp', 'image/avif'];
|
|
||||||
const allowedVideoTypes = ['video/mp4', 'video/webm'];
|
|
||||||
|
|
||||||
// types
|
// types
|
||||||
interface Props {
|
interface Props {
|
||||||
maxFilesBytes: number;
|
maxFilesBytes: number;
|
||||||
|
2
src/util/media.ts
Normal file
2
src/util/media.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const allowedImageTypes = ['image/png', 'image/jpeg', 'image/webp', 'image/avif'];
|
||||||
|
export const allowedVideoTypes = ['video/mp4', 'video/webm'];
|
Reference in New Issue
Block a user