wiki_ghostguild/app/server/api/articles/[slug].put.ts

109 lines
3 KiB
TypeScript

import { Article } from "../../models/Article";
import { requireAuth } from "../../utils/auth";
import { Types } from "mongoose";
export default defineEventHandler(async (event) => {
const slug = getRouterParam(event, "slug");
const user = await requireAuth(event);
const body = await readBody(event);
if (!slug) {
throw createError({
statusCode: 400,
statusMessage: "Slug is required",
});
}
// Find article
const article = await Article.findOne({ slug });
if (!article) {
throw createError({
statusCode: 404,
statusMessage: "Article not found",
});
}
// Check permissions
const isAuthor = article.author.toString() === user.userId;
const isAdmin = user.permissions.canAdmin;
const isModerator = user.permissions.canModerate;
const canEdit = user.permissions.canEdit;
if (!isAuthor && !isAdmin && !isModerator) {
throw createError({
statusCode: 403,
statusMessage: "You do not have permission to edit this article",
});
}
// Check if article is locked by another user
if (article.lockedBy && article.lockedBy.toString() !== user.userId) {
const lockExpired =
article.lockedAt &&
new Date().getTime() - article.lockedAt.getTime() > 30 * 60 * 1000; // 30 minutes
if (!lockExpired) {
throw createError({
statusCode: 423,
statusMessage: "Article is currently being edited by another user",
});
}
}
// Update fields
if (body.title) article.title = body.title;
if (body.description) article.description = body.description;
if (body.content) {
// Add to revision history
article.revisions.push({
content: body.content,
author: new Types.ObjectId(user.userId),
message: body.revisionMessage || "Content updated",
createdAt: new Date(),
});
article.content = body.content;
}
if (body.category) article.category = body.category;
if (body.tags) article.tags = body.tags;
if (body.accessLevel && (isAdmin || isModerator)) {
article.accessLevel = body.accessLevel;
}
if (body.cohorts && (isAdmin || isModerator)) {
article.cohorts = body.cohorts;
}
if (body.status) {
article.status = body.status;
if (body.status === "published" && !article.publishedAt) {
article.publishedAt = new Date();
}
}
// Add contributor if not already listed
const userObjectId = new Types.ObjectId(user.userId);
if (!article.contributors.some((c: any) => c.toString() === user.userId)) {
article.contributors.push(userObjectId);
}
// Clear lock
article.lockedBy = undefined;
article.lockedAt = undefined;
// Save changes
try {
await article.save();
return {
success: true,
slug: article.slug,
message: "Article updated successfully",
revision: article.revisions.length,
};
} catch (error) {
console.error("Error updating article:", error);
throw createError({
statusCode: 500,
statusMessage: "Failed to update article",
});
}
});