update: remove the blog from the response of the update or create blog
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Patch, Post, Query } from "@nestjs/common";
|
||||
import { CacheInterceptor, CacheTTL } from "@nestjs/cache-manager";
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Patch, Post, Query, UseInterceptors } from "@nestjs/common";
|
||||
import { ApiOperation } from "@nestjs/swagger";
|
||||
|
||||
import { BlogCommentQueryDto } from "./DTO/blog-comment-query.dto";
|
||||
@@ -18,7 +19,7 @@ import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||
import { Pagination } from "../../common/decorators/pagination.decorator";
|
||||
import { PermissionsDec } from "../../common/decorators/permission.decorator";
|
||||
import { SkipAuth } from "../../common/decorators/skip-auth.decorator";
|
||||
import { UserDec } from "../../common/decorators/user.decorator";
|
||||
import { IUserIpAndHeaders, UserDec, UserIpAndHeaders } from "../../common/decorators/user.decorator";
|
||||
import { ParamDto } from "../../common/DTO/param.dto";
|
||||
import { CategoryListSearchQueryDto } from "../danak-services/DTO/category-search-query.dto";
|
||||
import { PermissionEnum } from "../users/enums/permission.enum";
|
||||
@@ -31,6 +32,8 @@ export class BlogsController {
|
||||
) {}
|
||||
|
||||
@ApiOperation({ summary: "Get all public and active blogs with category id" })
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheTTL(120 * 1000)
|
||||
@SkipAuth()
|
||||
@Get()
|
||||
getBlogsPublic(@Query() queryDto: BlogSearchQueryDto) {
|
||||
@@ -38,6 +41,8 @@ export class BlogsController {
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Get most visited and pinned blogs" })
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheTTL(120 * 1000)
|
||||
@SkipAuth()
|
||||
@Get("combined")
|
||||
getCombinedBlogs() {
|
||||
@@ -53,6 +58,8 @@ export class BlogsController {
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Get a blog by id" })
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheTTL(120 * 1000)
|
||||
@SkipAuth()
|
||||
@Get(":id")
|
||||
getBlog(@Param() paramDto: ParamDto, @UserDec("isAdmin") isAdmin: boolean) {
|
||||
@@ -60,6 +67,8 @@ export class BlogsController {
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Get a blog by slug" })
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheTTL(120 * 1000)
|
||||
@SkipAuth()
|
||||
@Get("slug/:slug")
|
||||
getBlogBySlug(@Param() paramDto: BlogSlugDto, @UserDec("isAdmin") isAdmin: boolean) {
|
||||
@@ -67,6 +76,8 @@ export class BlogsController {
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Get most visited blogs" })
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheTTL(120 * 1000)
|
||||
@SkipAuth()
|
||||
@Get("most-visited")
|
||||
getMostVisitedBlogs() {
|
||||
@@ -82,6 +93,8 @@ export class BlogsController {
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Get most pinned blogs" })
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheTTL(120 * 1000)
|
||||
@SkipAuth()
|
||||
@Get("pinned")
|
||||
getPinnedBlogs() {
|
||||
@@ -100,24 +113,24 @@ export class BlogsController {
|
||||
@Post()
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.BLOGS)
|
||||
createBlog(@Body() createBlogDto: CreateBlogDto, @UserDec("id") userId: string) {
|
||||
return this.blogsService.createBlog(createBlogDto, userId);
|
||||
createBlog(@Body() createBlogDto: CreateBlogDto, @UserIpAndHeaders() userIpAndHeaders: IUserIpAndHeaders) {
|
||||
return this.blogsService.createBlog(createBlogDto, userIpAndHeaders);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Update a blog (admin route)" })
|
||||
@Patch(":id")
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.BLOGS)
|
||||
updateBlog(@Param() paramDto: ParamDto, @Body() updateBlogDto: UpdateBlogDto, @UserDec("id") userId: string) {
|
||||
return this.blogsService.updateBlog(paramDto.id, updateBlogDto, userId);
|
||||
updateBlog(@Param() paramDto: ParamDto, @Body() updateBlogDto: UpdateBlogDto, @UserIpAndHeaders() userIpAndHeaders: IUserIpAndHeaders) {
|
||||
return this.blogsService.updateBlog(paramDto.id, updateBlogDto, userIpAndHeaders);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Delete a blog (admin route) " })
|
||||
@Delete(":id")
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.BLOGS)
|
||||
deleteBlog(@Param() paramDto: ParamDto, @UserDec("id") userId: string) {
|
||||
return this.blogsService.deleteBlog(paramDto.id, userId);
|
||||
deleteBlog(@Param() paramDto: ParamDto, @UserIpAndHeaders() userIpAndHeaders: IUserIpAndHeaders) {
|
||||
return this.blogsService.deleteBlog(paramDto.id, userIpAndHeaders);
|
||||
}
|
||||
|
||||
//-------------- comments --------------
|
||||
@@ -200,15 +213,15 @@ export class BlogsController {
|
||||
@Delete("categories/:id")
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.BLOGS)
|
||||
deleteCategory(@Param() paramDto: ParamDto, @UserDec("id") userId: string) {
|
||||
return this.blogsService.deleteCategory(paramDto.id, userId);
|
||||
deleteCategory(@Param() paramDto: ParamDto, @UserIpAndHeaders() userIpAndHeaders: IUserIpAndHeaders) {
|
||||
return this.blogsService.deleteCategory(paramDto.id, userIpAndHeaders);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "toggle status of categories (admin route)" })
|
||||
@PermissionsDec(PermissionEnum.BLOGS)
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post("categories/toggle-status/:id")
|
||||
toggleCategoryStatus(@Param() paramDto: ParamDto) {
|
||||
return this.blogsService.toggleCategoryStatus(paramDto.id);
|
||||
toggleCategoryStatus(@Param() paramDto: ParamDto, @UserIpAndHeaders() userIpAndHeaders: IUserIpAndHeaders) {
|
||||
return this.blogsService.toggleCategoryStatus(paramDto.id, userIpAndHeaders);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import { Not } from "typeorm";
|
||||
|
||||
import { IUserIpAndHeaders } from "../../../common/decorators/user.decorator";
|
||||
import { AdminMessage, BlogMessage, CommonMessage } from "../../../common/enums/message.enum";
|
||||
import { UserType } from "../../access-logs/enums/user-type.enum";
|
||||
import { AccessLogService } from "../../access-logs/providers/access-log.service";
|
||||
@@ -49,13 +50,13 @@ export class BlogsService {
|
||||
|
||||
return {
|
||||
message: CommonMessage.UPDATE_SUCCESS,
|
||||
category,
|
||||
categoryId: category.id,
|
||||
};
|
||||
}
|
||||
//*********************************** */
|
||||
|
||||
async deleteCategory(id: string, userId: string) {
|
||||
const isSuperAdmin = await this.usersService.isSuperAdmin(userId);
|
||||
async deleteCategory(id: string, userIpAndHeaders: IUserIpAndHeaders) {
|
||||
const isSuperAdmin = await this.usersService.isSuperAdmin(userIpAndHeaders.userId);
|
||||
if (!isSuperAdmin) throw new BadRequestException(AdminMessage.NOT_ALLOWED);
|
||||
|
||||
const category = await this.blogCategoriesRepository.findOneBy({ id });
|
||||
@@ -65,23 +66,45 @@ export class BlogsService {
|
||||
if (blogs.length > 0) throw new BadRequestException(BlogMessage.CATEGORY_HAS_BLOGS);
|
||||
|
||||
await this.blogCategoriesRepository.remove(category);
|
||||
|
||||
await this.accessLogService.logDelete("BlogCategory", category.id, UserType.ADMIN, {
|
||||
user: { id: userIpAndHeaders.userId },
|
||||
endpoint: "/blogs/categories",
|
||||
requestId: userIpAndHeaders.headers["x-request-id"],
|
||||
ipAddress: userIpAndHeaders.ip,
|
||||
userAgent: userIpAndHeaders.headers["user-agent"],
|
||||
actionDescription: `Admin deleted blog category: ${category.title}`,
|
||||
metadata: {
|
||||
categoryId: category.id,
|
||||
},
|
||||
});
|
||||
return {
|
||||
message: CommonMessage.DELETED,
|
||||
};
|
||||
}
|
||||
//*********************************** */
|
||||
|
||||
async toggleCategoryStatus(id: string) {
|
||||
async toggleCategoryStatus(id: string, userIpAndHeaders: IUserIpAndHeaders) {
|
||||
const category = await this.findCategoryById(id);
|
||||
|
||||
//
|
||||
category.isActive = !category.isActive;
|
||||
await this.blogCategoriesRepository.save(category);
|
||||
|
||||
//
|
||||
await this.accessLogService.logUpdate("BlogCategory", category.id, UserType.ADMIN, {
|
||||
user: { id: userIpAndHeaders.userId },
|
||||
endpoint: "/blogs/categories",
|
||||
requestId: userIpAndHeaders.headers["x-request-id"],
|
||||
ipAddress: userIpAndHeaders.ip,
|
||||
userAgent: userIpAndHeaders.headers["user-agent"],
|
||||
actionDescription: `Admin updated blog category status: ${category.title}`,
|
||||
metadata: {
|
||||
categoryId: category.id,
|
||||
},
|
||||
});
|
||||
return {
|
||||
message: CommonMessage.UPDATE_SUCCESS,
|
||||
category,
|
||||
categoryId: category.id,
|
||||
};
|
||||
}
|
||||
//*********************************** */
|
||||
@@ -104,7 +127,7 @@ export class BlogsService {
|
||||
}
|
||||
//*********************************** */
|
||||
|
||||
async createBlog(createBlogDto: CreateBlogDto, authorId: string) {
|
||||
async createBlog(createBlogDto: CreateBlogDto, userIpAndHeaders: IUserIpAndHeaders) {
|
||||
const existingBlog = await this.blogsRepository.findOne({ where: { title: createBlogDto.title } });
|
||||
if (existingBlog) throw new BadRequestException(BlogMessage.BLOG_ALREADY_EXISTS);
|
||||
|
||||
@@ -117,38 +140,36 @@ export class BlogsService {
|
||||
|
||||
const blog = this.blogsRepository.create({
|
||||
...createBlogDto,
|
||||
author: { id: authorId },
|
||||
author: { id: userIpAndHeaders.userId },
|
||||
category,
|
||||
slug,
|
||||
});
|
||||
|
||||
await this.blogsRepository.save(blog);
|
||||
|
||||
await this.accessLogService.logCreate(
|
||||
"Blog",
|
||||
blog.id,
|
||||
{ blog: createBlogDto.title },
|
||||
{
|
||||
user: { id: authorId },
|
||||
userType: UserType.ADMIN,
|
||||
actionDescription: `Admin created blog: ${createBlogDto.title}`,
|
||||
metadata: {
|
||||
categoryId: createBlogDto.categoryId,
|
||||
slug: slug,
|
||||
authorId: authorId,
|
||||
},
|
||||
await this.accessLogService.logCreate("Blog", UserType.ADMIN, {
|
||||
user: { id: userIpAndHeaders.userId },
|
||||
endpoint: "/blogs",
|
||||
requestId: userIpAndHeaders.headers["x-request-id"],
|
||||
ipAddress: userIpAndHeaders.ip,
|
||||
userAgent: userIpAndHeaders.headers["user-agent"],
|
||||
actionDescription: `Admin created blog: ${createBlogDto.title}`,
|
||||
metadata: {
|
||||
categoryId: createBlogDto.categoryId,
|
||||
slug: slug,
|
||||
authorId: userIpAndHeaders.userId,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
return {
|
||||
message: CommonMessage.CREATED,
|
||||
blog,
|
||||
blogId: blog.id,
|
||||
};
|
||||
}
|
||||
|
||||
//*********************************** */
|
||||
|
||||
async updateBlog(id: string, updateBlogDto: UpdateBlogDto, userId: string) {
|
||||
async updateBlog(id: string, updateBlogDto: UpdateBlogDto, userIpAndHeaders: IUserIpAndHeaders) {
|
||||
const blog = await this.findBlogById(id);
|
||||
|
||||
if (updateBlogDto.title) {
|
||||
@@ -172,30 +193,29 @@ export class BlogsService {
|
||||
slug: this.generateSlug(updateBlogDto.slug ?? blog.slug),
|
||||
});
|
||||
|
||||
await this.accessLogService.logUpdate(
|
||||
"Blog",
|
||||
blog.id,
|
||||
{ blog: blog.title },
|
||||
{ blog: updateBlogDto.title },
|
||||
{
|
||||
user: { id: userId },
|
||||
userType: UserType.ADMIN,
|
||||
actionDescription: `Admin updated blog: ${blog.title}`,
|
||||
metadata: {
|
||||
categoryId: updateBlogDto.categoryId,
|
||||
},
|
||||
await this.accessLogService.logUpdate("Blog", blog.id, UserType.ADMIN, {
|
||||
user: { id: userIpAndHeaders.userId },
|
||||
endpoint: "/blogs",
|
||||
requestId: userIpAndHeaders.headers["x-request-id"],
|
||||
ipAddress: userIpAndHeaders.ip,
|
||||
userAgent: userIpAndHeaders.headers["user-agent"],
|
||||
actionDescription: `Admin updated blog: ${blog.title}`,
|
||||
metadata: {
|
||||
categoryId: updateBlogDto.categoryId,
|
||||
},
|
||||
);
|
||||
oldValues: JSON.stringify({ ...blog }),
|
||||
newValues: JSON.stringify({ ...updateBlogDto }),
|
||||
});
|
||||
|
||||
return {
|
||||
message: CommonMessage.UPDATE_SUCCESS,
|
||||
blog,
|
||||
blogId: blog.id,
|
||||
};
|
||||
}
|
||||
//*********************************** */
|
||||
|
||||
async deleteBlog(id: string, userId: string) {
|
||||
const isSuperAdmin = await this.usersService.isSuperAdmin(userId);
|
||||
async deleteBlog(id: string, userIpAndHeaders: IUserIpAndHeaders) {
|
||||
const isSuperAdmin = await this.usersService.isSuperAdmin(userIpAndHeaders.userId);
|
||||
if (!isSuperAdmin) throw new BadRequestException(AdminMessage.NOT_ALLOWED);
|
||||
|
||||
const blog = await this.blogsRepository.findOneBy({ id });
|
||||
@@ -203,19 +223,19 @@ export class BlogsService {
|
||||
|
||||
await this.blogsRepository.softDelete({ id });
|
||||
|
||||
await this.accessLogService.logDelete(
|
||||
"Blog",
|
||||
blog.id,
|
||||
{ blog: blog.title },
|
||||
{
|
||||
user: { id: userId },
|
||||
userType: UserType.ADMIN,
|
||||
actionDescription: `Admin deleted blog: ${blog.title}`,
|
||||
metadata: {
|
||||
categoryId: blog.category.id,
|
||||
},
|
||||
await this.accessLogService.logDelete("Blog", blog.id, UserType.ADMIN, {
|
||||
user: { id: userIpAndHeaders.userId },
|
||||
endpoint: "/blogs",
|
||||
requestId: userIpAndHeaders.headers["x-request-id"],
|
||||
ipAddress: userIpAndHeaders.ip,
|
||||
userAgent: userIpAndHeaders.headers["user-agent"],
|
||||
actionDescription: `Admin deleted blog: ${blog.title}`,
|
||||
metadata: {
|
||||
categoryId: blog.category.id,
|
||||
},
|
||||
);
|
||||
oldValues: JSON.stringify({ ...blog }),
|
||||
newValues: JSON.stringify({ ...blog }),
|
||||
});
|
||||
return {
|
||||
message: CommonMessage.DELETED,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user