From 5a83d7e79baddd90ad3ca12fdba0b8f8fa6ecc16 Mon Sep 17 00:00:00 2001 From: mashukov Date: Wed, 24 Jul 2024 16:30:05 +0300 Subject: [PATCH 1/2] feat/add CRUD messages --- src/controllers/message.ts | 32 ++++++++++++++++++++++++++++++++ src/models/Message.ts | 14 ++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/controllers/message.ts create mode 100644 src/models/Message.ts diff --git a/src/controllers/message.ts b/src/controllers/message.ts new file mode 100644 index 00000000..e512c23f --- /dev/null +++ b/src/controllers/message.ts @@ -0,0 +1,32 @@ +import { Body, Controller, Delete, Get, Params, Post, Put } from 'amala' +import { MessageModel } from '@/models/Message' + +@Controller('/messages') +export default class MessageController { + @Post('/') + async createMessage(@Body() { body, userId }: { body: string, userId: string }) { + const message = new MessageModel({ body, userId }) + await message.save() + return message + } + + @Get('/') + async getMessages() { + return await MessageModel.find() + } + + @Get('/:id') + async getMessage(@Params('id') id: string) { + return await MessageModel.findById(id) + } + + @Put('/:id') + async updateMessage(@Params('id') id: string, @Body() { content }: { content: string }) { + return await MessageModel.findByIdAndUpdate(id, { content }, { new: true }) + } + + @Delete('/:id') + async deleteMessage(@Params('id') id: string) { + return await MessageModel.findByIdAndDelete + } +} diff --git a/src/models/Message.ts b/src/models/Message.ts new file mode 100644 index 00000000..3dbfa00e --- /dev/null +++ b/src/models/Message.ts @@ -0,0 +1,14 @@ +import { prop, getModelForClass, modelOptions } from '@typegoose/typegoose' + +@modelOptions({ + schemaOptions: { timestamps: true }, +}) +export class Message { + @prop({ required: true }) + body!: string + + @prop({ required: true }) + userId!: string +} + +export const MessageModel = getModelForClass(Message) From b01f1c3d354a93b70ed435d61421a0d7098dc89a Mon Sep 17 00:00:00 2001 From: mashukov Date: Mon, 29 Jul 2024 00:56:22 +0300 Subject: [PATCH 2/2] feat/add CRUD messages v2 --- src/controllers/message.ts | 41 +++++++++++++++++++++++------------- src/middlewares/checkAuth.ts | 34 ++++++++++++++++++++++++++++++ src/models/Message.ts | 8 ++++--- 3 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 src/middlewares/checkAuth.ts diff --git a/src/controllers/message.ts b/src/controllers/message.ts index e512c23f..a732f361 100644 --- a/src/controllers/message.ts +++ b/src/controllers/message.ts @@ -1,32 +1,43 @@ -import { Body, Controller, Delete, Get, Params, Post, Put } from 'amala' -import { MessageModel } from '@/models/Message' +import { Body, Controller, Delete, Get, Post, Put,Flow,CurrentUser,State } from 'amala' +import { DocumentType } from '@typegoose/typegoose' +import checkAuth from '@/middlewares/checkAuth' +import { Message, MessageModel } from '@/models/Message' +import { User } from '@/models/User' + @Controller('/messages') +@Flow([checkAuth]) export default class MessageController { @Post('/') - async createMessage(@Body() { body, userId }: { body: string, userId: string }) { - const message = new MessageModel({ body, userId }) - await message.save() - return message + createMessage( + @CurrentUser() user: User, + @Body({ required: true }) { body }: { body: string } + ) { + return MessageModel.create({ body, user}) } @Get('/') - async getMessages() { - return await MessageModel.find() + getMessages( @CurrentUser() user: User,) { + return MessageModel.find({user}) } @Get('/:id') - async getMessage(@Params('id') id: string) { - return await MessageModel.findById(id) + getMessage(@State('message') message: Message) { + return message } @Put('/:id') - async updateMessage(@Params('id') id: string, @Body() { content }: { content: string }) { - return await MessageModel.findByIdAndUpdate(id, { content }, { new: true }) + updateMessage( + @State('message') message: DocumentType, + @Body({ required: true }) { body }: { body: string } + ) { + return MessageModel.findByIdAndUpdate(message.id, + { body }, + { new: true }) } - @Delete('/:id') - async deleteMessage(@Params('id') id: string) { - return await MessageModel.findByIdAndDelete + @Delete('/:messageId') + deleteMessage(@State('message') message: DocumentType) { + return MessageModel.findByIdAndDelete(message.id) } } diff --git a/src/middlewares/checkAuth.ts b/src/middlewares/checkAuth.ts new file mode 100644 index 00000000..82223aa4 --- /dev/null +++ b/src/middlewares/checkAuth.ts @@ -0,0 +1,34 @@ +import { Context, Next } from 'koa' +import { UserModel } from '@/models/User' +import { badRequest, forbidden, notFound } from '@hapi/boom' +import { verify } from '@/helpers/jwt' + +export default async (ctx: Context, next: Next) => { + const token = ctx.header['token'] + + if (!token) { + return ctx.throw(forbidden('authentication failed')) + } + + if (typeof token !== 'string') { + return ctx.throw(badRequest()) + } + + try { + const { id } = verify(token) + if (!id) { + return ctx.throw(forbidden()) + } + } catch (error) { + return ctx.throw(badRequest()) + } + + const user = await UserModel.findOne({ token }) + if (!user) { + return ctx.throw(notFound()) + } + + ctx.state['user'] = user + + return next() +} diff --git a/src/models/Message.ts b/src/models/Message.ts index 3dbfa00e..27a688ce 100644 --- a/src/models/Message.ts +++ b/src/models/Message.ts @@ -1,4 +1,5 @@ -import { prop, getModelForClass, modelOptions } from '@typegoose/typegoose' +import { Ref, prop, getModelForClass, modelOptions } from '@typegoose/typegoose' +import {User} from '@/models/User'; @modelOptions({ schemaOptions: { timestamps: true }, @@ -7,8 +8,9 @@ export class Message { @prop({ required: true }) body!: string - @prop({ required: true }) - userId!: string + @prop({ required: true, ref: () => User }) + user!:Ref + } export const MessageModel = getModelForClass(Message)