71 lines
No EOL
1.7 KiB
TypeScript
71 lines
No EOL
1.7 KiB
TypeScript
import { Article } from '../../models/Article'
|
|
import { checkAccessLevel, verifyAuth } from '../../utils/auth'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const slug = getRouterParam(event, 'slug')
|
|
|
|
if (!slug) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Slug is required'
|
|
})
|
|
}
|
|
|
|
// Find article
|
|
const article = await Article.findOne({ slug })
|
|
.populate('author', 'username displayName avatar')
|
|
.populate('contributors', 'username displayName avatar')
|
|
|
|
if (!article) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
statusMessage: 'Article not found'
|
|
})
|
|
}
|
|
|
|
// Check access
|
|
const hasAccess = await checkAccessLevel(
|
|
event,
|
|
article.accessLevel,
|
|
article.cohorts
|
|
)
|
|
|
|
if (!hasAccess) {
|
|
// For protected content, return limited preview
|
|
if (article.accessLevel !== 'admin') {
|
|
return {
|
|
slug: article.slug,
|
|
title: article.title,
|
|
description: article.description.substring(0, 200) + '...',
|
|
category: article.category,
|
|
tags: article.tags,
|
|
accessLevel: article.accessLevel,
|
|
restricted: true,
|
|
message: 'This content requires authentication'
|
|
}
|
|
}
|
|
|
|
throw createError({
|
|
statusCode: 403,
|
|
statusMessage: 'Access denied'
|
|
})
|
|
}
|
|
|
|
// Increment view count
|
|
article.views += 1
|
|
await article.save()
|
|
|
|
// Get user to check if they've liked
|
|
const user = await verifyAuth(event)
|
|
const userLiked = false // TODO: Implement likes tracking
|
|
|
|
return {
|
|
...article.toObject(),
|
|
userLiked,
|
|
revisionCount: article.revisions.length,
|
|
commentCount: article.comments.length,
|
|
// Don't send full revisions and comments in main response
|
|
revisions: undefined,
|
|
comments: undefined
|
|
}
|
|
}) |