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

[BE] 회원가입 API 구현 #29

Merged
merged 10 commits into from
Nov 7, 2024
Merged
705 changes: 698 additions & 7 deletions BE/package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions BE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
"@nestjs/swagger": "^8.0.1",
"@nestjs/typeorm": "^10.0.2",
"axios": "^1.7.7",
"bcrypt": "^5.1.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cross-env": "^7.0.3",
"docker": "^1.0.0",
"dotenv": "^16.4.5",
Expand All @@ -41,6 +44,7 @@
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/bcrypt": "^5.0.2",
"@types/express": "^5.0.0",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
Expand Down
5 changes: 4 additions & 1 deletion BE/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { User } from './auth/user.entity';

@Module({
imports: [
Expand All @@ -14,9 +16,10 @@ import { AppService } from './app.service';
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWD,
database: process.env.DB_DATABASE,
entities: [],
entities: [User],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 auth.module에서 user 엔티티로 등록되어있는 것 같은데, 혹시 여기서 한번 더 등록해주어야 할 필요가 있는 건가용...?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 부분에서 등록하는 부분과 auth.module에서 등록하는 부분이 다른 걸로 알고 있습니다.
TypeOrmModule의 옵션인 entities에 포함 해주면 엔티티에 맞춰서 자동으로 데이터 테이블을 생성해 준다고 알고 있습니다!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그렇군요!! 감사합니당

synchronize: true,
}),
AuthModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
31 changes: 31 additions & 0 deletions BE/src/auth/auth.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UserRepository } from './user.repository';

describe('AuthController', () => {
let controller: AuthController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
providers: [
AuthService,
{
provide: UserRepository,
useValue: {
find: jest.fn(),
findOne: jest.fn(),
save: jest.fn(),
},
},
],
}).compile();

controller = module.get<AuthController>(AuthController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
13 changes: 13 additions & 0 deletions BE/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Controller, Post, Body, ValidationPipe } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthCredentialsDto } from './dto/authCredentials.dto';
Copy link
Collaborator

@uuuo3o uuuo3o Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 이런 네이밍 규칙도 나중에 이야기해보면 좋겠네요!
저는 케밥 케이스 방식을 써서
auth-credential.dto 이런 식으로 작성하고 있었거든요!

Copy link
Collaborator Author

@jinddings jinddings Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 네이밍 규칙도 나중에 이야기해보면 좋겠네요! 저는 케밥 케이스 방식을 써서 auth-credential.dto 이런 식으로 작성하고 있었거든요!

어라? 저도 진님이 하신게 기억나서 고쳐논건데 왜 다시 되돌아 왔는지 모르겠네요 ㅎㅎ
한번 이야기 해보면 좋을거 같아요!


@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}

@Post('/signup')
signUp(@Body(ValidationPipe) authCredentialsDto: AuthCredentialsDto) {
return this.authService.signUp(authCredentialsDto);
}
}
13 changes: 13 additions & 0 deletions BE/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { User } from './user.entity';
import { UserRepository } from './user.repository';

@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [AuthController],
providers: [AuthService, UserRepository],
})
export class AuthModule {}
31 changes: 31 additions & 0 deletions BE/src/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserRepository } from './user.repository';

describe('AuthService', () => {
let service: AuthService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
providers: [
AuthService,
{
provide: UserRepository,
useValue: {
find: jest.fn(),
findOne: jest.fn(),
save: jest.fn(),
},
},
],
}).compile();

service = module.get<AuthService>(AuthService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
16 changes: 16 additions & 0 deletions BE/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
import { AuthCredentialsDto } from './dto/authCredentials.dto';

@Injectable()
export class AuthService {
constructor(
@InjectRepository(UserRepository)
private userRepository: UserRepository,
) {}

async signUp(authCredentialsDto: AuthCredentialsDto) {
return this.userRepository.registerUser(authCredentialsDto);
}
}
14 changes: 14 additions & 0 deletions BE/src/auth/dto/authCredentials.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { IsString, Matches, MaxLength, MinLength } from 'class-validator';

export class AuthCredentialsDto {
@IsString()
@MinLength(4)
@MaxLength(20)
email: string;

@IsString()
@MinLength(4)
@MaxLength(20)
@Matches(/^[a-zA-Z0-9]*$/)
password: string;
}
19 changes: 19 additions & 0 deletions BE/src/auth/user.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;

@Column()
email: string;

@Column()
password: string;

@Column({ default: false })
tutorial: boolean;

@Column({ default: -1 })
kakaoId: number;
}
21 changes: 21 additions & 0 deletions BE/src/auth/user.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import * as bcrypt from 'bcrypt';
import { User } from './user.entity';
import { AuthCredentialsDto } from './dto/authCredentials.dto';

@Injectable()
export class UserRepository extends Repository<User> {
constructor(@InjectDataSource() dataSource: DataSource) {
super(User, dataSource.createEntityManager());
}

async registerUser(authCredentialsDto: AuthCredentialsDto) {
const { email, password } = authCredentialsDto;
const salt: string = await bcrypt.genSalt();
const hashedPassword: string = await bcrypt.hash(password, salt);
const user = this.create({ email, password: hashedPassword });
await this.save(user);
}
}