2024-07-02 09:08:49 +02:00

155 lines
3.8 KiB
TypeScript

"use server";
import { APIError, attemptAPIAction } from "@/util";
import {
sequelize,
Bucket,
Auth,
Post,
PostTag,
Tag,
User,
dbSync,
} from "@/models";
import { cookies } from "next/headers";
import { Attachment } from "@/models";
import {
addToExistingBucket,
addToNewBucketForPost,
writeFilesToFS,
} from "@/app/lib/actions/entityManagement/attachment/attachmentActions";
import { Attributes } from "@sequelize/core";
import { RequestCookie } from "next/dist/compiled/@edge-runtime/cookies";
export async function tryCreateAttachment(request: Request) {
// Make sure the DB is ready
await dbSync;
// Prepare data
const formData = await request.formData();
const requestData: string | Object | undefined = formData
.get("data")
?.valueOf();
const files: FormDataEntryValue[] = formData.getAll("files");
const authCkie: RequestCookie | undefined = await cookies().get("auth");
// Sanity check auth cookie
if (!authCkie || !authCkie.value)
throw new APIError({
status: 500,
responseText: "missing auth cookie",
});
// Get JSON from the Cookie
const cookieJSON: string = authCkie.value;
const authObject:Attributes<Auth> = JSON.parse(cookieJSON);
// Fetch User Auth from thse database
const auth = await Auth.findOne({
include: [
{
model: User.withScope(["withPerms"]),
attributes: {
exclude: ["username", "password", "updatedAt", "createdAt"],
},
},
],
where: { token: authObject.token },
});
// Sanity check the auth and associated user for authorization
if (!auth || !auth.user)
throw new APIError({
status: 401,
responseText: "Authentication Error",
});
if (!auth.user.id)
throw new APIError({ status: 401, responseText: "Missing user id" });
if (!auth.user.perms || !auth.user.perms.isAdmin)
throw new APIError({ status: 401, responseText: `Unauthorized` });
// Handle incomplete data or other problems
if (!files)
throw new APIError({ status: 500, responseText: "Missing file" });
if (!formData)
throw new APIError({ status: 500, responseText: "Empty request body" });
if (!requestData)
throw new APIError({
status: 500,
responseText: "Missing request data",
});
if (!(typeof requestData == "string"))
throw new APIError({
status: 500,
responseText: "Malformed request data",
});
// Parse JSON
const data = JSON.parse(requestData);
// Get or create bucket
const bucket: Bucket =
data.postid && !data.bucketid
? await addToNewBucketForPost(data.postid)
: await addToExistingBucket(data.bucketid);
// Write files to bucket and store as attachments in DB
const writeResult = await writeFilesToFS(bucket.id, files);
// Handle failure
if (!writeResult.success)
throw new APIError({
status: 500,
responseText: "Error writing files to Bucket",
});
// Write attachments to db
const attachments = writeResult.filePaths.map(async (fp) => {
return await Attachment.create(
{
bucket_id: bucket.id,
filename: fp,
},
{ include: Attachment.associations.bucket }
);
});
attachments;
return new Response(
JSON.stringify({
bucket: await Bucket.findOne({
where: { id: bucket.id },
include: [
Bucket.associations.posts,
Bucket.associations.attachments,
],
}),
}),
{ status: 200 }
);
}
export async function tryFetchAttachments(request: Request) {
await Post.sync();
const foundPosts = await Post.findAll({
include: [
{
association: Post.associations.user,
attributes: { exclude: ["password", "createdAt", "updatedAt"] },
},
{
association: Post.associations.postTags,
},
],
});
return new Response(JSON.stringify(foundPosts), { status: 200 });
}
export async function GET(request: Request) {
return await attemptAPIAction(tryFetchAttachments, request);
}
export async function POST(request: Request) {
return await attemptAPIAction(tryCreateAttachment, request);
}