diff --git a/api-docs.yml b/api-docs.yml index b1b21d2..f5c809d 100644 --- a/api-docs.yml +++ b/api-docs.yml @@ -327,12 +327,9 @@ paths: patch: summary: Update mentor profile description: | - update mentor profiles. - **NOTE**: **hashtags** and **categories** are replaced with the new ones - **NOTE**: 프로필 활성화 조건에 위배되는 경우 isHide가 해제됩니다. - **사용법**: **description/shortDescription** - description이 **missing** **property** 인 경우, 무시(제외하고 업데이트) - description이 **""** 인 경우, ""로 업데이트됩니다. + **NOTE**: **hashtags** and **categories** are replaced with the new ones + **NOTE**: 프로필 활성화 조건에 위배되는 경우 isHide가 해제됩니다. + **프로필 활성화 조건**: 해시태그와 카테고리가 1개 이상. tags: - Mentor Profiles security: @@ -369,7 +366,8 @@ paths: patch: summary: Activate or Deactivate mentorProfiles description: | - mentorProfiled을 활성화/비활성화합니다. + mentorProfile을 활성화/비활성화합니다. + 활성화 하기 위해선 category/hashtag가 각각 1개 이상 등록되어있어야합니다. tags: - Mentor Profiles security: @@ -396,11 +394,12 @@ paths: schema: $ref: '#/components/schemas/MentorProfileGet' '400': - description: Invalid request parameter + description: | + activation: 카테고리는 최소 1개 이상 선택해주세요. + activation: 해시태그는 최소 1개 이상 선택해주세요. '404': - description: Mentor profile not found - - + description: | + 업데이트할 프로필이 없습니다. /reservations: get: diff --git a/src/database/repository/mentorProfile.repository.ts b/src/database/repository/mentorProfile.repository.ts index f17c206..b4e7f3d 100644 --- a/src/database/repository/mentorProfile.repository.ts +++ b/src/database/repository/mentorProfile.repository.ts @@ -128,11 +128,6 @@ export class MentorProfileRepository { if (data.categories.length == 0) isHide = true; // 업데이트할 해시태그가 0개인 경우 if (data.hashtags.length == 0) isHide = true; - // 업데이트할 소셜링크가 null인 경우 - if (!data.socialLink) { - isHide = true; - data.socialLink = ''; - } return prisma.mentorProfile.update({ where: { @@ -162,7 +157,6 @@ export class MentorProfileRepository { * @detail 멘토 프로필을 활성화 시키는 함수입니다. * - 멘토 프로필 활성화위해선 카테고리가 최소 1개 이상 존재해야합니다. * - 멘토 프로필 활성화위해선 해시태그가 최소 1개 이상 존재해야합니다. - * - 멘토 프로필 활성화위해선 소셜링크가 최소 1개 이상 존재해야합니다. */ async activateMentorProfile(userId: number) { return this.prisma.$transaction(async (prisma) => { @@ -173,7 +167,6 @@ export class MentorProfileRepository { select: { hashtags: true, categories: true, - socialLink: true, }, }); @@ -187,9 +180,6 @@ export class MentorProfileRepository { if (profile.hashtags.length === 0) throw new BadRequestException('해시태그는 최소 1개 이상 선택해주세요.'); - // 현재 프로필에 소셜링크가 없는 경우 - if (profile.socialLink.length === 0) - throw new BadRequestException('소셜 링크를 입력해주세요.'); return prisma.mentorProfile.update({ where: { userId: userId, diff --git a/src/database/repository/user.repository.ts b/src/database/repository/user.repository.ts index 4647ae4..8a5ff64 100644 --- a/src/database/repository/user.repository.ts +++ b/src/database/repository/user.repository.ts @@ -71,6 +71,18 @@ export class UserRepository { }); } + async updateLastLogin(id: number): Promise { + return this.prisma.user.update({ + where: { + id: id, + }, + data: { + updatedAt: new Date(), + }, + select: UserSelectQuery, + }); + } + /** * @brief get reservation(mentee, mentor) by user id * diff --git a/src/models/user/user.service.ts b/src/models/user/user.service.ts index b2848ec..ea1ba8c 100644 --- a/src/models/user/user.service.ts +++ b/src/models/user/user.service.ts @@ -10,6 +10,7 @@ import { ReservationRole } from 'src/common/enums'; @Injectable() export class UserService { constructor(private readonly userRepository: UserRepository) {} + async findMany(take: number, page: number): Promise> { return this.userRepository.findMany(take, page); } @@ -26,7 +27,6 @@ export class UserService { return this.userRepository.findByNickname(nickname); } - // only for admin async create(data: UserCreatePayloadDto): Promise { return this.userRepository.create(data); } @@ -35,6 +35,10 @@ export class UserService { return this.userRepository.update(id, data); } + async updateLastLogin(id: number): Promise { + return this.userRepository.updateLastLogin(id); + } + async findUserReservation( id: number, take: number, diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index a18db13..eb8e1bd 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -1,9 +1,10 @@ -import { Controller, Get, InternalServerErrorException, Req, Res, UseGuards } from '@nestjs/common'; +import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common'; import { AuthService } from './auth.service'; import { FtGuard } from '../../common/guards/ft/ft.guard'; import { JwtGuard } from '../../common/guards/jwt/jwt.guard'; import { JwtPayloadInterface } from '../../common/interfaces/jwt/jwtPayload.interface'; import { AppConfigService } from '../../config/app/config.service'; +import { Request, Response } from 'express'; @Controller('auth') export class AuthController { @@ -18,13 +19,14 @@ export class AuthController { @UseGuards(FtGuard) @Get('42/callback') - async get42AuthCallback(@Req() req, @Res() res) { + async get42AuthCallback(@Req() req, @Res() res: Response) { if (!req.user || !req.user.nickname) { res.redirect(`${this.appConfigService.accessUrl}?uid=0`); } + const user = await this.authService.verifyOrCreateUser(req.user); - if (!user) throw new InternalServerErrorException(); const accessToken = await this.authService.createToken(user); + res.redirect(`${this.appConfigService.accessUrl}/SignIn?uid=${user.id}&token=${accessToken}`); } diff --git a/src/modules/auth/auth.service.ts b/src/modules/auth/auth.service.ts index 56d3aac..a230465 100644 --- a/src/modules/auth/auth.service.ts +++ b/src/modules/auth/auth.service.ts @@ -3,19 +3,23 @@ import { UserService } from '../../models/user/user.service'; import { JwtService } from '@nestjs/jwt'; import { JwtPayloadInterface } from '../../common/interfaces/jwt/jwtPayload.interface'; import { UserGetResponseDto } from '../../models/user/dto/response/userGetResponse.dto'; +import { UserCreatePayloadDto } from 'src/models/user/dto/request/userCreatePayload.dto'; @Injectable() export class AuthService { - constructor(private readonly userService: UserService, private readonly jwtService: JwtService) {} + constructor( + private readonly userService: UserService, + private readonly jwtService: JwtService, + ) {} - async verifyOrCreateUser(user: any): Promise { + async verifyOrCreateUser(user: UserCreatePayloadDto): Promise { const { nickname } = user; - let userExist = await this.userService.findByNickname(nickname); + const userExist = await this.userService.findByNickname(nickname); if (!userExist) { - await this.userService.create(user); - userExist = await this.userService.findByNickname(nickname); + return await this.userService.create(user); + } else { + return await this.userService.updateLastLogin(userExist.id); } - return userExist; } async createToken(user: UserGetResponseDto): Promise { diff --git a/src/modules/dev/dev.controller.ts b/src/modules/dev/dev.controller.ts index fbe8b7b..5633635 100644 --- a/src/modules/dev/dev.controller.ts +++ b/src/modules/dev/dev.controller.ts @@ -1,6 +1,8 @@ import { Controller, Get, Param, Res, UnauthorizedException } from '@nestjs/common'; -import * as process from 'process'; +import { UserRole } from '@prisma/client'; +import { Response } from 'express'; import { AppConfigService } from 'src/config/app/config.service'; +import { UserCreatePayloadDto } from 'src/models/user/dto/request/userCreatePayload.dto'; import { DevService } from './dev.service'; @Controller('dev') @@ -11,11 +13,22 @@ export class DevController { ) {} @Get('/login/:id') - async loginDev(@Param('id') id: number, @Res() res) { + async loginDev(@Param('id') id: number, @Res() res: Response) { if (process.env.NODE_ENV !== 'dev' && process.env.NODE_ENV !== 'test') throw new UnauthorizedException(); - const user = await this.devService.createOrGetUser(id); - const accessToken = await this.devService.createToken(user); - res.redirect(`${this.appConfigService.accessUrl}/SignIn?uid=${user.id}&token=${accessToken}`); + + // fixed fake user for dev + const newFakeUser: UserCreatePayloadDto = { + nickname: `manitoDevUser${id}`, + email: `42manito${id}@gmail.com`, + profileImage: 'https://cdn.intra.42.fr/users/medium_manito.jpg', + role: UserRole.USER, + }; + const fakeUser = await this.devService.verifyOrCreateFakeUser(newFakeUser); + const accessToken = await this.devService.createToken(fakeUser); + + res.redirect( + `${this.appConfigService.accessUrl}/SignIn?uid=${fakeUser.id}&token=${accessToken}`, + ); } } diff --git a/src/modules/dev/dev.module.ts b/src/modules/dev/dev.module.ts index 3857663..dccee38 100644 --- a/src/modules/dev/dev.module.ts +++ b/src/modules/dev/dev.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { DevController } from './dev.controller'; import { DevService } from './dev.service'; -import { UserService } from '../../models/user/user.service'; import { UserModule } from '../../models/user/user.module'; import { PrismaModule } from '../../database/services/prisma.module'; import { JwtModule } from '@nestjs/jwt'; @@ -28,6 +27,6 @@ import { AppConfigModule } from 'src/config/app/config.module'; }), ], controllers: [DevController], - providers: [DevService, UserService], + providers: [DevService], }) export class DevModule {} diff --git a/src/modules/dev/dev.service.ts b/src/modules/dev/dev.service.ts index 08d1b75..2abd54b 100644 --- a/src/modules/dev/dev.service.ts +++ b/src/modules/dev/dev.service.ts @@ -2,29 +2,25 @@ import { Injectable } from '@nestjs/common'; import { UserGetResponseDto } from '../../models/user/dto/response/userGetResponse.dto'; import { JwtPayloadInterface } from '../../common/interfaces/jwt/jwtPayload.interface'; import { JwtService } from '@nestjs/jwt'; -import { UserRepository } from 'src/database/repository/user.repository'; -import { UserRole } from '@prisma/client'; +import { UserCreatePayloadDto } from 'src/models/user/dto/request/userCreatePayload.dto'; +import { UserService } from 'src/models/user/user.service'; + @Injectable() export class DevService { constructor( private readonly jwtService: JwtService, - private readonly userRepository: UserRepository, + private readonly userService: UserService, ) {} - async createOrGetUser(userId: number) { - // check if user exists - const user = await this.userRepository.findById(userId); - if (user) { - return user; + // fixed fake user for dev + async verifyOrCreateFakeUser(newFakeUser: UserCreatePayloadDto): Promise { + const { nickname } = newFakeUser; + const userExist = await this.userService.findByNickname(nickname); + if (!userExist) { + return await this.userService.create(newFakeUser); + } else { + return await this.userService.updateLastLogin(userExist.id); } - // create user - const newUser = await this.userRepository.create({ - nickname: `manitoDevUser${userId}`, - email: `42manito${userId}@gmail.com`, - profileImage: 'https://cdn.intra.42.fr/users/medium_manito.jpg', - role: UserRole.USER, - }); - return newUser; } async createToken(user: UserGetResponseDto): Promise {