more refactoring
This commit is contained in:
+127
-140
@@ -1,167 +1,154 @@
|
||||
'use server'
|
||||
"use server";
|
||||
|
||||
import { APIError, attemptAPIAction } from "@/util/api/error";
|
||||
import { sequelize, Bucket, Auth, Post, PostTag, Tag, User, dbSync } from "@/models";
|
||||
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 { UUID } from "crypto";
|
||||
import { mkdir, mkdirSync, writeFile } from "fs";
|
||||
import { where } from "@sequelize/core";
|
||||
import { addToNewBucketForPost } from "../../lib/actions/entityManagement/attachment/attachmentActions";
|
||||
|
||||
async function writeFilesToFS(uuid: UUID, files: any[]): Promise<{ success: boolean, filePaths: string[] }> {
|
||||
|
||||
type FileArrayEntryWithPromise = {
|
||||
name: string;
|
||||
content: Promise<ReadableStreamReadResult<Uint8Array>> | ReadableStreamReadResult<Uint8Array>
|
||||
}
|
||||
type FileArrayEntry = {
|
||||
name: string;
|
||||
content: ReadableStreamReadResult<Uint8Array>
|
||||
};
|
||||
|
||||
// Resolve promises
|
||||
const fileArray: FileArrayEntryWithPromise[] = await Promise.all(files.map((file: File) => {
|
||||
return { 'name': (() => file.name)(), 'content': file.stream().getReader().read() };
|
||||
}));
|
||||
|
||||
|
||||
|
||||
let finalFileArray: FileArrayEntry[] = await (
|
||||
async () => {
|
||||
for (let file in fileArray) {
|
||||
fileArray[file].content = await fileArray[file].content
|
||||
}
|
||||
return [...fileArray as FileArrayEntry[]]
|
||||
})();
|
||||
|
||||
// Make Bucket Directory
|
||||
mkdirSync(`./bucket/${uuid}/`, { recursive: true })
|
||||
|
||||
// Write files to filesystem
|
||||
for (let file in finalFileArray) {
|
||||
writeFile(`./bucket/${uuid}/${finalFileArray[file].name}`
|
||||
, Buffer.from(finalFileArray[file].content.value as Uint8Array)
|
||||
, (e) => { console.log(e) });
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
filePaths: finalFileArray.map((e) => e.name)
|
||||
}
|
||||
}
|
||||
|
||||
async function addToExistingBucket(bucketid: number): Promise<Bucket> {
|
||||
const bucket = await Bucket.findOne({
|
||||
where: { id: bucketid }, include: { association: Bucket.associations.posts }
|
||||
});
|
||||
if (!bucket) throw new APIError({ status: 500, responseText: "invalid bucketid" });
|
||||
return bucket;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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");
|
||||
|
||||
// Prepare data
|
||||
const formData = await request.formData();
|
||||
const requestData: string | Object | undefined = formData.get('data')?.valueOf();
|
||||
const files: FormDataEntryValue[] = formData.getAll('files')
|
||||
const authCkie = await cookies().get("auth");
|
||||
// Sanity check auth cookie
|
||||
if (!authCkie || !authCkie.value)
|
||||
throw new APIError({
|
||||
status: 500,
|
||||
responseText: "missing auth cookie",
|
||||
});
|
||||
|
||||
// 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);
|
||||
|
||||
// Get JSON from the Cookie
|
||||
const cookieJSON = authCkie.value;
|
||||
const authObject = 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 },
|
||||
});
|
||||
|
||||
// Fetch User Auth from the 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);
|
||||
|
||||
// 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" });
|
||||
// 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",
|
||||
});
|
||||
|
||||
// Parse JSON
|
||||
const data = JSON.parse(requestData);
|
||||
// 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;
|
||||
|
||||
// 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 }
|
||||
);
|
||||
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();
|
||||
|
||||
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 });
|
||||
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);
|
||||
return await attemptAPIAction(tryFetchAttachments, request);
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
return await attemptAPIAction(tryCreateAttachment, request);
|
||||
return await attemptAPIAction(tryCreateAttachment, request);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user