Skip to content
Open
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
33 changes: 15 additions & 18 deletions src/activity/activity.controller.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { Controller, Get, Param, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiOkResponse, ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
import { Controller, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from 'src/auth/guard/auth.guard';
import { BaseResponse } from 'src/global/base/base-response';
import { ExtractPayload } from 'src/global/decorator/extract-payload.decorator';
import { ActivityService } from './activity.service';
import { ActivityDetailResponse } from './dto/activity-detail-response.dto';

@Controller('api/activities')
@UseGuards(JwtAuthGuard)
Expand All @@ -13,17 +10,17 @@ import { ActivityDetailResponse } from './dto/activity-detail-response.dto';
export class ActivityController {
constructor(private readonly activityService: ActivityService) {}

@Get(':activityId')
@ApiOperation({
summary: '활동 세부 정보 조회',
description: '활동 세부 정보를 조회한다. 리뷰는 따로 API 호출 해주세요!',
})
@ApiParam({ name: 'activityId', description: '세부 정보를 조회할 활동 아이디' })
@ApiOkResponse({ type: ActivityDetailResponse })
async getActivityDetail(
@ExtractPayload() userId: number,
@Param('activityId') activityId: number,
): Promise<BaseResponse<ActivityDetailResponse>> {
return BaseResponse.of(await this.activityService.getActivityDetail(userId, activityId));
}
// @Get(':activityId')
// @ApiOperation({
// summary: '활동 세부 정보 조회',
// description: '활동 세부 정보를 조회한다. 리뷰는 따로 API 호출 해주세요!',
// })
// @ApiParam({ name: 'activityId', description: '세부 정보를 조회할 활동 아이디' })
// @ApiOkResponse({ type: ActivityDetailResponse })
// async getActivityDetail(
// @ExtractPayload() userId: number,
// @Param('activityId') activityId: number,
// ): Promise<BaseResponse<ActivityDetailResponse>> {
// return BaseResponse.of(await this.activityService.getActivityDetail(userId, activityId));
// }
}
12 changes: 3 additions & 9 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Body, Controller, Get, HttpCode, HttpStatus, Post, UseGuards } from '@nestjs/common';
import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
import { ApiBearerAuth, ApiHeaders, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { BaseResponse } from 'src/global/base/base-response';
import { ExtractPayload } from 'src/global/decorator/extract-payload.decorator';
import { ExtractToken } from 'src/global/decorator/extract-token.decorator';
import { AuthService } from './auth.service';
import { AppleOAuthRequest } from './dto/apple-oauth-request.dto';
Expand All @@ -12,7 +11,6 @@ import { JwtResponse } from './dto/jwt-response.dto';
import { KakaoOAuthRequest } from './dto/kakao-oauth-request.dto';
import { KakaoOAuthResponse } from './dto/kakao-oauth-response.dto';
import { LoginRequest } from './dto/login-request.dto';
import { JwtAuthGuard } from './guard/auth.guard';

@Controller('api/auth')
@ApiTags('auth')
Expand All @@ -31,19 +29,15 @@ export class AuthController {
}

@Get('reissue')
@UseGuards(JwtAuthGuard)
@ApiOperation({
summary: 'Access Token 만료시 재발급',
description: 'Access Token과 Refresh Token을 재발급한다.',
})
@ApiBearerAuth()
@ApiHeaders([{ name: 'Authorization', description: 'Refresh Token' }])
@ApiOkResponse({ type: JwtResponse, description: '재발급 성공' })
async reissueToken(
@ExtractPayload() userId: number,
@ExtractToken() refreshToken: string,
): Promise<BaseResponse<JwtResponse>> {
return BaseResponse.of(await this.authService.reissueToken(userId, refreshToken));
async reissueToken(@ExtractToken() refreshToken: string): Promise<BaseResponse<JwtResponse>> {
return BaseResponse.of(await this.authService.reissueToken(refreshToken));
}

@Post('email-check')
Expand Down
3 changes: 2 additions & 1 deletion src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from 'src/user/entity/user.entity';
import { UserModule } from 'src/user/user.module';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtStrategy } from './strategy/jwt.strategy';

@Module({
imports: [JwtModule.register({}), TypeOrmModule.forFeature([User]), PassportModule],
imports: [JwtModule.register({}), TypeOrmModule.forFeature([User]), PassportModule, UserModule],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
Expand Down
14 changes: 5 additions & 9 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { BaseException } from 'src/global/base/base-exception';
import { Password } from 'src/user/entity/password';
import { User } from 'src/user/entity/user.entity';
import { SocialType } from 'src/user/enum/social-type';
import { UserResponseCode } from 'src/user/exception/user-response-code';
import { Repository } from 'typeorm';
import { AppleOAuthResponse } from './dto/apple-oauth-response.dto';
import { JwtResponse } from './dto/jwt-response.dto';
Expand Down Expand Up @@ -107,18 +106,15 @@ export class AuthService {
return await this.userRepository.exist({ where: { email } });
}

async reissueToken(userId: number, refreshToken: string) {
const user = await this.userRepository.findOneBy({ userId });
if (!user) {
throw BaseException.of(UserResponseCode.USER_NOT_FOUND);
}
async reissueToken(refreshToken: string) {
const user = await this.userRepository.findOneBy({ refreshToken });

if (user.refreshToken !== refreshToken) {
if (!user) {
throw BaseException.of(AuthResponseCode.INVALID_TOKEN);
}

const newAccessToken = await this.generateAccessToken(userId);
const newRefreshToken = await this.generateRefreshToken(userId);
const newAccessToken = await this.generateAccessToken(user.userId);
const newRefreshToken = await this.generateRefreshToken(user.userId);

user.refreshToken = newRefreshToken;
await this.userRepository.save(user);
Expand Down
11 changes: 8 additions & 3 deletions src/auth/strategy/jwt.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Config } from 'src/global/config/config.type';
import { User } from 'src/user/entity/user.entity';
import { UserService } from 'src/user/user.service';
import { JwtPayloadType } from './type/jwt-payload.type';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(private configService: ConfigService<Config>) {
constructor(
private configService: ConfigService<Config>,
private readonly userService: UserService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: configService.get('auth.secret', { infer: true }),
});
}

public validate(payload: JwtPayloadType): JwtPayloadType {
return payload;
public async validate(payload: JwtPayloadType): Promise<User> {
return await this.userService.findUserById(payload.sub);
}
}
2 changes: 1 addition & 1 deletion src/auth/strategy/type/jwt-payload.type.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type JwtPayloadType = {
userId: number;
sub: number;
iat: number;
exp: number;
iss: string;
Expand Down
9 changes: 9 additions & 0 deletions src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ export class UserService {
return this.userRepository.exist({ where: { userId } });
}

async findUserById(userId: number): Promise<User> {
const user = await this.userRepository.findOneBy({ userId });
if (!user) {
throw BaseException.of(UserResponseCode.USER_NOT_FOUND);
}

return user;
}

async create(request: SignUpRequest, profileImage: Express.Multer.File): Promise<User> {
const newUser = this.userRepository.save(await UserConverter.toUser(request, profileImage));

Expand Down