Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/socialink optional #139 #140

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions api-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -369,7 +366,8 @@ paths:
patch:
summary: Activate or Deactivate mentorProfiles
description: |
mentorProfiled을 활성화/비활성화합니다.
mentorProfile을 활성화/비활성화합니다.
활성화 하기 위해선 category/hashtag가 각각 1개 이상 등록되어있어야합니다.
tags:
- Mentor Profiles
security:
Expand All @@ -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:
Expand Down
10 changes: 0 additions & 10 deletions src/database/repository/mentorProfile.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -162,7 +157,6 @@ export class MentorProfileRepository {
* @detail 멘토 프로필을 활성화 시키는 함수입니다.
* - 멘토 프로필 활성화위해선 카테고리가 최소 1개 이상 존재해야합니다.
* - 멘토 프로필 활성화위해선 해시태그가 최소 1개 이상 존재해야합니다.
* - 멘토 프로필 활성화위해선 소셜링크가 최소 1개 이상 존재해야합니다.
*/
async activateMentorProfile(userId: number) {
return this.prisma.$transaction(async (prisma) => {
Expand All @@ -173,7 +167,6 @@ export class MentorProfileRepository {
select: {
hashtags: true,
categories: true,
socialLink: true,
},
});

Expand All @@ -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,
Expand Down
12 changes: 12 additions & 0 deletions src/database/repository/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ export class UserRepository {
});
}

async updateLastLogin(id: number): Promise<UserGetResponseDto> {
return this.prisma.user.update({
where: {
id: id,
},
data: {
updatedAt: new Date(),
},
select: UserSelectQuery,
});
}

/**
* @brief get reservation(mentee, mentor) by user id
*
Expand Down
6 changes: 5 additions & 1 deletion src/models/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Array<UserGetResponseDto>> {
return this.userRepository.findMany(take, page);
}
Expand All @@ -26,7 +27,6 @@ export class UserService {
return this.userRepository.findByNickname(nickname);
}

// only for admin
async create(data: UserCreatePayloadDto): Promise<UserGetResponseDto> {
return this.userRepository.create(data);
}
Expand All @@ -35,6 +35,10 @@ export class UserService {
return this.userRepository.update(id, data);
}

async updateLastLogin(id: number): Promise<UserGetResponseDto> {
return this.userRepository.updateLastLogin(id);
}

async findUserReservation(
id: number,
take: number,
Expand Down
8 changes: 5 additions & 3 deletions src/modules/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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}`);
}

Expand Down
16 changes: 10 additions & 6 deletions src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<UserGetResponseDto> {
async verifyOrCreateUser(user: UserCreatePayloadDto): Promise<UserGetResponseDto> {
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<string> {
Expand Down
23 changes: 18 additions & 5 deletions src/modules/dev/dev.controller.ts
Original file line number Diff line number Diff line change
@@ -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')
Expand All @@ -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}`,
);
}
}
3 changes: 1 addition & 2 deletions src/modules/dev/dev.module.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -28,6 +27,6 @@ import { AppConfigModule } from 'src/config/app/config.module';
}),
],
controllers: [DevController],
providers: [DevService, UserService],
providers: [DevService],
})
export class DevModule {}
28 changes: 12 additions & 16 deletions src/modules/dev/dev.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<UserGetResponseDto> {
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<string> {
Expand Down