Skip to content

Commit

Permalink
Merge pull request #55 from DevKor-github/feature/auth
Browse files Browse the repository at this point in the history
Feature/auth
  • Loading branch information
KimSeongHyeonn authored Jul 31, 2024
2 parents 62d1720 + ec5c97b commit cdd4127
Show file tree
Hide file tree
Showing 16 changed files with 185 additions and 100 deletions.
14 changes: 1 addition & 13 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { AuthService } from './auth.service';
import { LocalStrategy } from './strategies/local.strategy';
import { JwtStrategy } from './strategies/jwt.strategy';
import { JwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { RefreshStrategy } from './strategies/refresh.strategy';
import { VerifyStrategy } from './strategies/verify.strategy';
import { TypeOrmModule } from '@nestjs/typeorm';
import { KuVerificationEntity } from 'src/entities/ku-verification.entity';
import { KuVerificationRepository } from './ku-verification.repository';
Expand All @@ -17,16 +15,7 @@ import { OptionalJwtAuthGuard } from './guards/optional-jwt-auth.guard';

@Module({
imports: [
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
return {
secret: configService.get('JWT_SECRET'),
signOptions: { expiresIn: '30m' },
};
},
}),
JwtModule.register({}),
TypeOrmModule.forFeature([KuVerificationEntity]),
UserModule,
CommonModule,
Expand All @@ -38,7 +27,6 @@ import { OptionalJwtAuthGuard } from './guards/optional-jwt-auth.guard';
LocalStrategy,
JwtStrategy,
RefreshStrategy,
VerifyStrategy,
AdminStrategy,
OptionalJwtAuthGuard,
],
Expand Down
10 changes: 8 additions & 2 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export class AuthService {
username: user.username,
};
return this.jwtService.sign(payload, {
secret: this.configService.get('JWT_ACCESS_SECRET'),
expiresIn: '5m',
});
}
Expand All @@ -97,6 +98,7 @@ export class AuthService {
return this.jwtService.sign(
{ id, keepingLogin },
{
secret: this.configService.get('JWT_REFRESH_SECRET'),
expiresIn: expiresIn,
},
);
Expand Down Expand Up @@ -261,8 +263,9 @@ export class AuthService {
verify: boolean,
): Promise<VerifyScreenshotResponseDto> {
const request = await this.kuVerificationRepository.findRequestById(id);
const userId = request.user.id;
const user = await this.userService.findUserById(userId);
if (verify) {
const userId = request.user.id;
const isVerified = await this.userService.verifyUser(userId, verify);
if (!isVerified) {
throw new NotImplementedException('reqeust allow failed!');
Expand All @@ -281,13 +284,16 @@ export class AuthService {
} else {
await this.deleteRequest(request.id);
}

await this.emailService.sendVerifyCompleteEmail(user.email, verify);

return new VerifyScreenshotResponseDto(true);
}

async deleteRequest(requestId: number): Promise<void> {
const request =
await this.kuVerificationRepository.findRequestById(requestId);
await this.userService.deleteUser(request.user.id);
await this.userService.hardDeleteUser(request.user.id);
await this.fileService.deleteFile(request.imgDir);
}

Expand Down
5 changes: 0 additions & 5 deletions src/auth/guards/verify-auth.guard.ts

This file was deleted.

5 changes: 1 addition & 4 deletions src/auth/strategies/jwt.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,11 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
passReqToCallback: true,
secretOrKey: configService.get('JWT_SECRET'),
secretOrKey: configService.get('JWT_ACCESS_SECRET'),
});
}

async validate(request: Request, payload: any): Promise<AuthorizedUserDto> {
if (payload.keepingLogin) {
throw new BadRequestException("Don't use RefreshToken as AccessToken!");
}
if (request.url !== '/auth/logout') {
const isVerified = await this.userService.checkUserVerified(payload.id);
if (!isVerified) {
Expand Down
2 changes: 1 addition & 1 deletion src/auth/strategies/refresh.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class RefreshStrategy extends PassportStrategy(Strategy, 'refresh') {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
passReqToCallback: true,
secretOrKey: configService.get('JWT_SECRET'),
secretOrKey: configService.get('JWT_REFRESH_SECRET'),
});
}

Expand Down
28 changes: 0 additions & 28 deletions src/auth/strategies/verify.strategy.ts

This file was deleted.

39 changes: 39 additions & 0 deletions src/common/email.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,43 @@ export class EmailService {

return await this.transporter.sendMail(mailOptions);
}

async sendVerifyCompleteEmail(
email: string,
isVerified: boolean,
): Promise<any> {
const title = isVerified
? '[Ku-Key] Your account has been verified!'
: '[Ku-Key] Your account verification failed!';
//프론트 사이트 배포되면 연결 url 바꿔주기
const content = isVerified
? `<div style="text-align: center;">
<h1>🍪School Verification Complete!</h1>
<p>Now you can use KU-key service right now.</p>
<p>We hope this service will help you a lot in your exchange student life.</p>
<a href="https://ku-key.devkor.club">
<button style="width: 209px; padding: 12px 0px; margin: 5px 0px; border-radius: 24px; border: 1px solid #E70000; background: #E70000; color: white";>
Start now
</button>
</a>
</div>`
: `<div style="text-align: center;">
<h1>🍪School Verification Failed!</h1>
<p>We have some difficulty verifying you as a Korea University student in your screenshot.</p>
<p>Please try to sign up again with a clearer screen shot.</p>
<a href="https://ku-key.devkor.club/register">
<button style="width: 209px; padding: 12px 0px; margin: 5px 0px; border-radius: 24px; border: 1px solid #E70000; background: #E70000; color: white";>
Try again
</button>
</a>
</div>`;
const mailOptions: EmailOptions = {
from: this.configService.get('EMAIL_USER'),
to: email,
subject: title,
html: content,
};

return await this.transporter.sendMail(mailOptions);
}
}
30 changes: 17 additions & 13 deletions src/community/comment/dto/get-comment.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@ export class GetCommentResponseDto {
this.updatedAt = commentEntity.updatedAt;
this.isMyComment = commentEntity.userId === userId;
this.content = commentEntity.content;
this.username = commentEntity.isAnonymous
? anonymousNumber === 0
? 'Author'
: `Anonymous ${anonymousNumber}`
: commentEntity.user.username.substring(
0,
Math.floor(commentEntity.user.username.length / 2),
) +
'*'.repeat(
commentEntity.user.username.length -
Math.floor(commentEntity.user.username.length / 2),
);
this.username =
commentEntity.user == null || commentEntity.user.deletedAt
? 'Deleted'
: commentEntity.isAnonymous
? anonymousNumber === 0
? 'Author'
: `Anonymous ${anonymousNumber}`
: commentEntity.user.username.substring(
0,
Math.floor(commentEntity.user.username.length / 2),
) +
'*'.repeat(
commentEntity.user.username.length -
Math.floor(commentEntity.user.username.length / 2),
);

this.likeCount = commentEntity.likeCount;
}
}
Expand All @@ -47,7 +51,7 @@ export class GetCommentResponseDto {
@ApiProperty({ description: '댓글 내용' })
content?: string;

@ApiProperty({ description: '댓글을 작성한 사용자(익명이면 null)' })
@ApiProperty({ description: '댓글을 작성한 사용자' })
username?: string | null;

@ApiProperty({ description: '좋아요 수' })
Expand Down
28 changes: 16 additions & 12 deletions src/community/post/dto/get-post-list-with-board.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,20 @@ export class PostPreview {
this.title = postEntity.title;
this.content = postEntity.content.substring(0, 100);
this.createdAt = postEntity.createdAt;
this.username = postEntity.isAnonymous
? null
: postEntity.user.username.substring(
0,
Math.floor(postEntity.user.username.length / 2),
) +
'*'.repeat(
postEntity.user.username.length -
Math.floor(postEntity.user.username.length / 2),
);
console.log(postEntity);
this.username =
postEntity.user == null || postEntity.user.deletedAt
? 'Deleted'
: postEntity.isAnonymous
? 'Anonymous'
: postEntity.user.username.substring(
0,
Math.floor(postEntity.user.username.length / 2),
) +
'*'.repeat(
postEntity.user.username.length -
Math.floor(postEntity.user.username.length / 2),
);
this.commentCount = postEntity.commentCount;
this.scrapCount = postEntity.scrapCount;
this.thumbnailDir =
Expand All @@ -69,8 +73,8 @@ export class PostPreview {
@ApiProperty({ description: '게시글 생성 시간' })
createdAt: Date;

@ApiProperty({ description: '게시글을 생성한 사용자(익명이면 null)' })
username: string | null;
@ApiProperty({ description: '게시글을 생성한 사용자' })
username: string;

@ApiProperty({ description: '댓글 수' })
commentCount: number;
Expand Down
27 changes: 15 additions & 12 deletions src/community/post/dto/get-post.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,19 @@ export class GetPostResponseDto {
this.content = postEntity.content;
this.createdAt = postEntity.createdAt;
this.updatedAt = postEntity.updatedAt;
this.username = postEntity.isAnonymous
? null
: postEntity.user.username.substring(
0,
Math.floor(postEntity.user.username.length / 2),
) +
'*'.repeat(
postEntity.user.username.length -
Math.floor(postEntity.user.username.length / 2),
);
this.username =
postEntity.user == null || postEntity.user.deletedAt
? 'Deleted'
: postEntity.isAnonymous
? 'Anonymous'
: postEntity.user.username.substring(
0,
Math.floor(postEntity.user.username.length / 2),
) +
'*'.repeat(
postEntity.user.username.length -
Math.floor(postEntity.user.username.length / 2),
);
this.views = postEntity.views;
this.scrapCount = postEntity.scrapCount;
this.reaction = new ReactionCount();
Expand Down Expand Up @@ -119,8 +122,8 @@ export class GetPostResponseDto {
@ApiProperty({ description: '게시글 수정 시간' })
updatedAt: Date;

@ApiProperty({ description: '게시글을 생성한 사용자(익명이면 null)' })
username: string | null;
@ApiProperty({ description: '게시글을 생성한 사용자' })
username: string;

@ApiProperty({ description: '조회수' })
views: number;
Expand Down
8 changes: 6 additions & 2 deletions src/entities/friendship.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ export class FriendshipEntity extends CommonEntity {
@PrimaryGeneratedColumn({ type: 'bigint' })
id: number;

@ManyToOne(() => UserEntity, (user) => user.sentFriendRequests)
@ManyToOne(() => UserEntity, (user) => user.sentFriendRequests, {
onDelete: 'CASCADE',
})
fromUser: UserEntity;

@ManyToOne(() => UserEntity, (user) => user.receivedFriendRequests)
@ManyToOne(() => UserEntity, (user) => user.receivedFriendRequests, {
onDelete: 'CASCADE',
})
toUser: UserEntity;

@Column('boolean', { nullable: false })
Expand Down
14 changes: 10 additions & 4 deletions src/entities/user.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,19 @@ export class UserEntity extends CommonEntity {
)
kuVerification: KuVerificationEntity;

@OneToMany(() => FriendshipEntity, (friendship) => friendship.fromUser)
@OneToMany(() => FriendshipEntity, (friendship) => friendship.fromUser, {
cascade: true,
})
sentFriendRequests: FriendshipEntity[];

@OneToMany(() => FriendshipEntity, (friendship) => friendship.toUser)
@OneToMany(() => FriendshipEntity, (friendship) => friendship.toUser, {
cascade: true,
})
receivedFriendRequests: FriendshipEntity[];

@OneToMany(() => TimetableEntity, (timetableEntity) => timetableEntity.user)
@OneToMany(() => TimetableEntity, (timetableEntity) => timetableEntity.user, {
cascade: true,
})
timetables: TimetableEntity[];

@OneToMany(() => PostEntity, (postEntity) => postEntity.user)
Expand All @@ -99,7 +105,6 @@ export class UserEntity extends CommonEntity {
@OneToMany(
() => CourseReviewRecommendEntity,
(courseReviewRecommendEntity) => courseReviewRecommendEntity.user,
{ cascade: true },
)
courseReviewRecommends: CourseReviewRecommendEntity[];

Expand Down Expand Up @@ -131,6 +136,7 @@ export class UserEntity extends CommonEntity {
@OneToMany(
() => CommentAnonymousNumberEntity,
(commentAnonymousNumberEntity) => commentAnonymousNumberEntity.user,
{ cascade: true },
)
commentAnonymousNumbers: CommentAnonymousNumberEntity[];

Expand Down
10 changes: 10 additions & 0 deletions src/user/dto/delete-user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ApiProperty } from '@nestjs/swagger';

export class DeleteUserResponseDto {
constructor(deleted: boolean) {
this.deleted = deleted;
}

@ApiProperty({ description: '회원 탈퇴 성공 여부' })
deleted: boolean;
}
Loading

0 comments on commit cdd4127

Please sign in to comment.