diff --git a/prisma/migrations/20240119212433_cascade_added/migration.sql b/prisma/migrations/20240119212433_cascade_added/migration.sql new file mode 100644 index 0000000..09960f8 --- /dev/null +++ b/prisma/migrations/20240119212433_cascade_added/migration.sql @@ -0,0 +1,35 @@ +-- DropForeignKey +ALTER TABLE `EmployeeOnTeams` DROP FOREIGN KEY `EmployeeOnTeams_employeeId_fkey`; + +-- DropForeignKey +ALTER TABLE `EmployeeOnTeams` DROP FOREIGN KEY `EmployeeOnTeams_teamId_fkey`; + +-- DropForeignKey +ALTER TABLE `Project` DROP FOREIGN KEY `Project_employeeId_fkey`; + +-- DropForeignKey +ALTER TABLE `Project` DROP FOREIGN KEY `Project_teamId_fkey`; + +-- DropForeignKey +ALTER TABLE `Task` DROP FOREIGN KEY `Task_projectId_fkey`; + +-- DropForeignKey +ALTER TABLE `Task` DROP FOREIGN KEY `Task_userId_fkey`; + +-- AddForeignKey +ALTER TABLE `EmployeeOnTeams` ADD CONSTRAINT `EmployeeOnTeams_teamId_fkey` FOREIGN KEY (`teamId`) REFERENCES `Team`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `EmployeeOnTeams` ADD CONSTRAINT `EmployeeOnTeams_employeeId_fkey` FOREIGN KEY (`employeeId`) REFERENCES `Employee`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Project` ADD CONSTRAINT `Project_teamId_fkey` FOREIGN KEY (`teamId`) REFERENCES `Team`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Project` ADD CONSTRAINT `Project_employeeId_fkey` FOREIGN KEY (`employeeId`) REFERENCES `Employee`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Task` ADD CONSTRAINT `Task_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `Employee`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Task` ADD CONSTRAINT `Task_projectId_fkey` FOREIGN KEY (`projectId`) REFERENCES `Project`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 077550a..c909201 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -28,8 +28,8 @@ model Team { model EmployeeOnTeams { teamId Int employeeId Int - team Team @relation(fields: [teamId], references: [id]) - employee Employee @relation(fields: [employeeId], references: [id]) + team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) + employee Employee @relation(fields: [employeeId], references: [id], onDelete: Cascade) @@id([teamId, employeeId]) } @@ -41,8 +41,8 @@ model Project { tasks Task[] teamId Int employeeId Int? - team Team @relation(fields: [teamId], references: [id]) - employee Employee? @relation(fields: [employeeId], references: [id]) + team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) + employee Employee? @relation(fields: [employeeId], references: [id], onDelete: Cascade) } model Task { @@ -54,7 +54,7 @@ model Task { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt userId Int - employee Employee @relation(fields: [userId], references: [id]) + employee Employee @relation(fields: [userId], references: [id], onDelete: Cascade) projectId Int? - project Project? @relation(fields: [projectId], references: [id]) + project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade) } diff --git a/src/app.module.ts b/src/app.module.ts index 45a4339..b392214 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -6,6 +6,7 @@ import { EmployeeModule } from './employee/employee.module' import { TasksModule } from './tasks/tasks.module' import { TeamModule } from './team/team.module' import { ProjectModule } from './project/project.module' +import { AuthModule } from './auth/auth.module'; @Module({ imports: [ @@ -13,7 +14,8 @@ import { ProjectModule } from './project/project.module' EmployeeModule, TasksModule, TeamModule, - ProjectModule + ProjectModule, + AuthModule ], controllers: [AppController], providers: [AppService] diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts new file mode 100644 index 0000000..2308828 --- /dev/null +++ b/src/auth/auth.controller.ts @@ -0,0 +1,57 @@ +import { + Body, + Controller, + Get, + Post, + Req, + Res, + UnauthorizedException +} from '@nestjs/common' +import { AuthService } from './auth.service' +import { Prisma } from '@prisma/client' +import { Request, Response } from 'express' + +@Controller('auth') +export class AuthController { + constructor(private readonly authService: AuthService) {} + + @Post('/signup') + async signup( + @Body() createUserDto: Prisma.EmployeeCreateInput, + @Req() request: Request + ) { + const userData = await this.authService.signup(createUserDto) + + // @ts-ignore- + request.session.userId = userData.userId + // @ts-ignore- + request.session.teamId = userData.teamId + } + + @Post('/signin') + async login( + @Body() loginData: Partial, + @Req() request: Request + ) { + const userData = await this.authService.signin(loginData) + + if (userData) { + // @ts-ignore- + request.session.userId = userData.userId + // @ts-ignore- + request.session.teamId = userData.teamId + return { teamId: userData.teamId, userId: userData.userId } + } + + throw new UnauthorizedException('Invalid credentials') + } + + @Get() + async logout(@Req() req: Request, @Res() res: Response) { + req.session.destroy(err => { + res + .clearCookie('sessionCookie', { domain: 'auth-test.site' }) + .sendStatus(200) + }) + } +} diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts new file mode 100644 index 0000000..46e183a --- /dev/null +++ b/src/auth/auth.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { AuthService } from './auth.service'; +import { AuthController } from './auth.controller'; + +@Module({ + controllers: [AuthController], + providers: [AuthService], +}) +export class AuthModule {} diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts new file mode 100644 index 0000000..77e06a3 --- /dev/null +++ b/src/auth/auth.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@nestjs/common' +import { Prisma } from '@prisma/client' +import { DatabaseService } from 'src/database/database.service' + +@Injectable() +export class AuthService { + constructor(private readonly databaseService: DatabaseService) {} + + async signup(createUserDto: Prisma.EmployeeCreateInput) { + const user = await this.databaseService.employee.create({ + data: { + ...createUserDto, + teams: { create: { team: { create: { name: 'My Team' } } } } + }, + + include: { teams: { include: { team: true } } } + }) + + return { userId: user.id, teamId: user.teams[0].teamId } + } + + async signin({ email, password }: Partial) { + const user = await this.databaseService.employee.findUnique({ + where: { email, password }, + include: { teams: { include: { team: true } } } + }) + + return user ? { userId: user.id, teamId: user.teams[0].teamId } : false + } +} diff --git a/src/session/session.module.ts b/src/config/sessionConfig.ts similarity index 85% rename from src/session/session.module.ts rename to src/config/sessionConfig.ts index 8548c79..5789225 100644 --- a/src/session/session.module.ts +++ b/src/config/sessionConfig.ts @@ -1,9 +1,5 @@ -// src/session/session.module.ts - -import { Module } from '@nestjs/common' const RedisStore = require('connect-redis').default import { createClient } from 'redis' -import * as session from 'express-session' const redisClient = createClient({ password: '3JluMijpNIdRLNlgqVdyLE6HnhNClCTC', @@ -38,7 +34,7 @@ export const sessionOptions = { // cookie: { // path: '/', // // domain: "auth-test.site", - // maxAge: 1000 * 60 * 30 + // maxAge: 1000 * 60 * 60 // // sameSite: "none", // // secure: true, // // httpOnly: true, diff --git a/src/employee/employee.controller.ts b/src/employee/employee.controller.ts index 8f638d8..99bbb49 100644 --- a/src/employee/employee.controller.ts +++ b/src/employee/employee.controller.ts @@ -18,53 +18,29 @@ import { Request } from 'express' export class EmployeeController { constructor(private readonly employeeService: EmployeeService) {} - @Post() - create( - @Body() createEmployeeDto: Prisma.EmployeeCreateInput, - @Req() request: Request - ) { - request.session.userMail = createEmployeeDto.email - return this.employeeService.create(createEmployeeDto) - } - - @Get('/getUserId') - findUserId(@Req() request: Request) { - if (request.session.userMail) { - const mailAdress = request.session.userMail - return this.employeeService.findUserId(mailAdress) - } else { - return 'No access' - } - } - - // login( - // @Body() createEmployeeDto: Prisma.EmployeeCreateInput, - // @Req() request: Request - // ) { - // return this.employeeService.login() - // } - @Get() findAll() { return this.employeeService.findAll() } - @Get('/only-mails') + @Get('/get-all-only-mails') findAllWithMails() { return this.employeeService.findAllWithMails() } - @Get(':id') + @Get('/getData') findOne(@Param('id') id: string, @Req() request: Request) { - return this.employeeService.findOne(+id) + const userId = request.session.userId + return this.employeeService.findOne(userId) } - @Patch(':id') + @Patch('/update') update( - @Param('id') id: number, - @Body() updateEmployeeDto: Prisma.EmployeeUpdateInput + @Body() updateEmployeeDto: Prisma.EmployeeUpdateInput, + @Req() request: Request ) { - return this.employeeService.update(Number(id), updateEmployeeDto) + const userId = request.session.userId + return this.employeeService.update(userId, updateEmployeeDto) } @Patch(':id/assignTask/:taskId') @@ -72,10 +48,6 @@ export class EmployeeController { return this.employeeService.assignTask(+id, +taskId) } - @Delete(':id') - remove(@Param('id') id: string) { - return this.employeeService.remove() - } @Delete('/remove-all') remove() { return this.employeeService.removeAll() diff --git a/src/main.ts b/src/main.ts index ac1d023..d3ddde7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,12 +3,13 @@ import { NestFactory } from '@nestjs/core' import { AppModule } from './app.module' import * as session from 'express-session' -import { sessionOptions } from './session/session.module' +import { sessionOptions } from './config/sessionConfig' async function bootstrap() { const app = await NestFactory.create(AppModule) app.enableCors({ origin: 'https://app.taskermanager.online', + // origin: 'http://localhost:3000', credentials: true }) @@ -16,7 +17,7 @@ async function bootstrap() { app.enable('trust proxy') app.use(session(sessionOptions)) - console.log(`--- app is listening oooon ${process.env.PORT}`) - await app.listen(process.env.PORT ?? 3005) + console.log(`--- app is listening on ${process.env.PORT}`) + await app.listen(process.env.PORT ?? 3001) } bootstrap() diff --git a/src/project/project.controller.ts b/src/project/project.controller.ts index 29cd0c3..4614e05 100644 --- a/src/project/project.controller.ts +++ b/src/project/project.controller.ts @@ -18,11 +18,17 @@ export class ProjectController { @Post() create( - @Body() createProjectDto: Prisma.ProjectCreateInput, + @Body() body: { name: string; description: string }, @Req() request: Request ) { - console.log(request.session) - return this.projectService.create(createProjectDto) + //@ts-ignore + const { userId, teamId } = request.session + const data = { + ...body, + teamId: teamId, + employeeId: userId + } + return this.projectService.create(data) } @Get() diff --git a/src/project/project.service.ts b/src/project/project.service.ts index 5633d5d..a41ef96 100644 --- a/src/project/project.service.ts +++ b/src/project/project.service.ts @@ -5,7 +5,7 @@ import { DatabaseService } from 'src/database/database.service' @Injectable() export class ProjectService { constructor(private readonly databaseService: DatabaseService) {} - create(createProjectDto: Prisma.ProjectCreateInput) { + create(createProjectDto) { return this.databaseService.project.create({ data: createProjectDto }) } @@ -14,7 +14,10 @@ export class ProjectService { } findOne(id: number) { - return this.databaseService.project.findUnique({ where: { id } }) + return this.databaseService.project.findUnique({ + where: { id }, + include: { employee: true, tasks: { include: { employee: true } } } + }) } update(id: number, updateProjectDto: Prisma.ProjectUpdateInput) { diff --git a/src/session/session.controller.spec.ts b/src/session/session.controller.spec.ts deleted file mode 100644 index be7117c..0000000 --- a/src/session/session.controller.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { SessionController } from './session.controller'; -import { SessionService } from './session.service'; - -describe('SessionController', () => { - let controller: SessionController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [SessionController], - providers: [SessionService], - }).compile(); - - controller = module.get(SessionController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/src/session/session.service.spec.ts b/src/session/session.service.spec.ts deleted file mode 100644 index a351693..0000000 --- a/src/session/session.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { SessionService } from './session.service'; - -describe('SessionService', () => { - let service: SessionService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [SessionService], - }).compile(); - - service = module.get(SessionService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/src/session/session.service.ts b/src/session/session.service.ts deleted file mode 100644 index d7938d1..0000000 --- a/src/session/session.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Injectable } from '@nestjs/common' - -@Injectable() -export class SessionService { - // create(createSessionDto: CreateSessionDto) { - // return 'This action adds a new session' - // } - // findAll() { - // return `This action returns all session` - // } - // findOne(id: number) { - // return `This action returns a #${id} session` - // } - // update(id: number, updateSessionDto: UpdateSessionDto) { - // return `This action updates a #${id} session` - // } - // remove(id: number) { - // return `This action removes a #${id} session` - // } -} diff --git a/src/team/team.controller.ts b/src/team/team.controller.ts index fe3ab1f..473ddc5 100644 --- a/src/team/team.controller.ts +++ b/src/team/team.controller.ts @@ -5,10 +5,12 @@ import { Body, Patch, Param, - Delete + Delete, + Req } from '@nestjs/common' import { TeamService } from './team.service' import { Prisma } from '@prisma/client' +import { Request } from 'express' @Controller('team') export class TeamController { @@ -29,12 +31,15 @@ export class TeamController { return this.teamService.findOne(+id) } - @Patch('/:teamId/employee/:employeeId') + @Patch('/employee/:employeeId') async addEmployeeToTeam( - @Param('teamId') teamId: number, - @Param('employeeId') employeeId: number + @Param('employeeId') employeeId: number, + @Req() request: Request ) { - return this.teamService.addEmployee(+teamId, +employeeId) + //@ts-ignore + const { teamId } = request.session + + return this.teamService.addEmployee(teamId, +employeeId) } @Patch(':id/projects/:projectId')