Skip to content

Commit 0ba0126

Browse files
authored
Merge pull request #387 from Quickchive/feat/add-provider-to-user
Feat/add provider to user
2 parents 9eb0bd5 + b0541c5 commit 0ba0126

File tree

3 files changed

+109
-75
lines changed

3 files changed

+109
-75
lines changed

src/auth/oauth.service.ts

Lines changed: 70 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { RedisService } from '../infra/redis/redis.service';
2121
import { REFRESH_TOKEN_KEY } from './constants';
2222
import { KakaoLoginRequest } from './dtos/request/kakao-login.request.dto';
2323
import { KakaoLoginDto } from './dtos/kakao-login.dto';
24+
import { PROVIDER } from '../users/constant/provider.constant';
2425

2526
@Injectable()
2627
export class OAuthService {
@@ -97,61 +98,56 @@ export class OAuthService {
9798
throw new BadRequestException('Please Agree to share your email');
9899
}
99100

100-
let user = await this.userRepository.findOneByEmail(email);
101+
const user = await this.userRepository.findOneByEmail(email);
102+
if (user) {
103+
return this.oauthLogin(user.email);
104+
}
101105

102106
// 회원가입인 경우 기본 카테고리 생성 작업 진행
103-
if (!user) {
104-
user = new User();
105-
user.email = email;
106-
user.name = userInfo.kakao_account.profile.nickname;
107-
user.profileImage = userInfo.kakao_account.profile?.profile_image_url;
108-
user.password = this.encodePasswordFromEmail(
109-
email,
110-
process.env.KAKAO_JS_KEY,
111-
);
107+
const newUser = User.of({
108+
email,
109+
name: userInfo.kakao_account.profile.nickname,
110+
profileImage: userInfo.kakao_account.profile?.profile_image_url,
111+
password: this.encodePasswordFromEmail(email, process.env.KAKAO_JS_KEY),
112+
provider: PROVIDER.KAKAO,
113+
});
112114

113-
await this.userRepository.createOne(user);
114-
await this.categoryRepository.createDefaultCategories(user);
115-
}
115+
await this.userRepository.createOne(newUser);
116+
await this.categoryRepository.createDefaultCategories(newUser);
116117

117-
return this.oauthLogin(user.email);
118+
return this.oauthLogin(newUser.email);
118119
} catch (e) {
119120
throw e;
120121
}
121122
}
122123

123124
async createOneWithKakao({ authorizationToken }: KakaoLoginDto) {
124-
try {
125-
const { userInfo } = await this.oauthUtil.getKakaoUserInfo(
126-
authorizationToken,
127-
);
125+
const { userInfo } =
126+
await this.oauthUtil.getKakaoUserInfo(authorizationToken);
128127

129-
const email = userInfo.kakao_account.email;
130-
if (!email) {
131-
throw new BadRequestException('Please Agree to share your email');
132-
}
133-
134-
let user = await this.userRepository.findOneByEmail(email);
135-
136-
// 회원가입인 경우 기본 카테고리 생성 작업 진행
137-
if (!user) {
138-
user = new User();
139-
user.email = email;
140-
user.name = userInfo.kakao_account.profile.nickname;
141-
user.profileImage = userInfo.kakao_account.profile?.profile_image_url;
142-
user.password = this.encodePasswordFromEmail(
143-
email,
144-
process.env.KAKAO_JS_KEY,
145-
);
128+
const email = userInfo.kakao_account.email;
129+
if (!email) {
130+
throw new BadRequestException('Please Agree to share your email');
131+
}
146132

147-
await this.userRepository.createOne(user);
148-
await this.categoryRepository.createDefaultCategories(user);
149-
}
133+
const user = await this.userRepository.findOneByEmail(email);
150134

135+
if (user) {
151136
return this.oauthLogin(user.email);
152-
} catch (e) {
153-
throw e;
154137
}
138+
139+
// 회원가입인 경우 기본 카테고리 생성 작업 진행
140+
const newUser = User.of({
141+
email,
142+
name: userInfo.kakao_account.profile.nickname,
143+
profileImage: userInfo.kakao_account.profile?.profile_image_url,
144+
password: this.encodePasswordFromEmail(email, process.env.KAKAO_JS_KEY),
145+
provider: PROVIDER.KAKAO,
146+
});
147+
148+
await this.userRepository.createOne(newUser);
149+
await this.categoryRepository.createDefaultCategories(newUser);
150+
return this.oauthLogin(newUser.email);
155151
}
156152

157153
// Login with Google account info
@@ -160,28 +156,28 @@ export class OAuthService {
160156
name,
161157
picture,
162158
}: googleUserInfo): Promise<LoginOutput> {
163-
try {
164-
let user = await this.userRepository.findOneByEmail(email);
165-
166-
// 회원가입인 경우 기본 카테고리 생성 작업 진행
167-
if (!user) {
168-
user = new User();
169-
user.email = email;
170-
user.name = name;
171-
user.profileImage = picture;
172-
user.password = this.encodePasswordFromEmail(
173-
email,
174-
process.env.GOOGLE_CLIENT_ID,
175-
);
176-
177-
await this.userRepository.createOne(user);
178-
await this.categoryRepository.createDefaultCategories(user);
179-
}
159+
const user = await this.userRepository.findOneByEmail(email);
180160

161+
if (user) {
181162
return this.oauthLogin(user.email);
182-
} catch (e) {
183-
throw e;
184163
}
164+
165+
// 회원가입인 경우 기본 카테고리 생성 작업 진행
166+
const newUser = User.of({
167+
email,
168+
name,
169+
profileImage: picture,
170+
password: this.encodePasswordFromEmail(
171+
email,
172+
process.env.GOOGLE_CLIENT_ID,
173+
),
174+
provider: PROVIDER.GOOGLE,
175+
});
176+
177+
await this.userRepository.createOne(newUser);
178+
await this.categoryRepository.createDefaultCategories(newUser);
179+
180+
return this.oauthLogin(newUser.email);
185181
}
186182

187183
private encodePasswordFromEmail(email: string, key?: string): string {
@@ -229,21 +225,25 @@ export class OAuthService {
229225

230226
const { sub: id, email } = this.jwtService.decode(data.id_token);
231227

232-
let user = await this.userRepository.findOneByEmail(email);
228+
const user = await this.userRepository.findOneByEmail(email);
233229

234-
if (!user) {
235-
user = new User();
236-
user.email = email;
237-
user.name = email.split('@')[0];
238-
user.password = this.encodePasswordFromEmail(
230+
if (user) {
231+
return this.oauthLogin(user.email);
232+
}
233+
234+
const newUser = User.of({
235+
email,
236+
name: email.split('@')[0],
237+
password: this.encodePasswordFromEmail(
239238
email,
240239
process.env.APPLE_CLIENT_ID,
241-
);
240+
),
241+
provider: PROVIDER.APPLE,
242+
});
242243

243-
await this.userRepository.createOne(user);
244-
await this.categoryRepository.createDefaultCategories(user);
245-
}
244+
await this.userRepository.createOne(newUser);
245+
await this.categoryRepository.createDefaultCategories(newUser);
246246

247-
return this.oauthLogin(user.email);
247+
return this.oauthLogin(newUser.email);
248248
}
249249
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const PROVIDER = {
2+
GOOGLE: 'google',
3+
KAKAO: 'kakao',
4+
APPLE: 'apple',
5+
} as const;
6+
7+
export type PROVIDER = (typeof PROVIDER)[keyof typeof PROVIDER];

src/users/entities/user.entity.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Category } from '../../categories/category.entity';
1515
import { Collection } from '../../collections/entities/collection.entity';
1616
import { CoreEntity } from '../../common/entities/core.entity';
1717
import { PaidPlan } from './paid-plan.entity';
18+
import { PROVIDER } from '../constant/provider.constant';
1819

1920
export enum UserRole {
2021
Client = 'Client',
@@ -26,12 +27,12 @@ export class User extends CoreEntity {
2627
@ApiProperty({ example: 'tester', description: 'User Name' })
2728
@Column()
2829
@IsString()
29-
name!: string;
30+
name: string;
3031

3132
@ApiProperty({ example: '[email protected]', description: 'User Email' })
3233
@Column({ unique: true })
3334
@IsEmail()
34-
email!: string;
35+
email: string;
3536

3637
@ApiProperty({ example: 'https://ex.com', description: 'User Profile Image' })
3738
@Column({ nullable: true })
@@ -44,7 +45,7 @@ export class User extends CoreEntity {
4445
@Matches(/^(?=.*\d)[A-Za-z\d@$!%*?&]{8,}$/, {
4546
message: 'Password must be at least 8 characters long, contain 1 number',
4647
})
47-
password!: string;
48+
password: string;
4849

4950
@ApiProperty({
5051
example: 'Client',
@@ -53,12 +54,15 @@ export class User extends CoreEntity {
5354
})
5455
@Column({ type: 'enum', enum: UserRole, default: UserRole.Client })
5556
@IsEnum(UserRole)
56-
role!: UserRole;
57+
role: UserRole;
58+
59+
@Column({ type: 'enum', enum: PROVIDER })
60+
provider: PROVIDER;
5761

5862
@ApiProperty({ description: 'User Verified' })
5963
@Column({ default: false })
6064
@IsBoolean()
61-
verified!: boolean;
65+
verified: boolean;
6266

6367
@ApiProperty({
6468
description: 'User Content List',
@@ -121,4 +125,27 @@ export class User extends CoreEntity {
121125
throw new InternalServerErrorException();
122126
}
123127
}
128+
129+
static of({
130+
email,
131+
name,
132+
profileImage,
133+
password,
134+
provider,
135+
}: {
136+
email: string;
137+
name: string;
138+
profileImage?: string;
139+
password: string;
140+
provider: PROVIDER;
141+
}): User {
142+
const user = new User();
143+
user.email = email;
144+
user.name = name;
145+
user.profileImage = profileImage;
146+
user.password = password;
147+
user.provider = provider;
148+
149+
return user;
150+
}
124151
}

0 commit comments

Comments
 (0)