diff --git a/src/controllers/userController.ts b/src/controllers/userController.ts index f82fada..a635cb9 100644 --- a/src/controllers/userController.ts +++ b/src/controllers/userController.ts @@ -7,7 +7,8 @@ import { } from '../intefaces/exception'; import { CreateUserCommand, - CreateUserReq + CreateUserReq, + toCommand } from '../intefaces/createUserCommand'; import { PostBaseResponseDto } from '../intefaces/PostBaseResponseDto'; import { UserLoginDto } from '../intefaces/user/UserLoginDto'; @@ -37,6 +38,7 @@ import { SocialVendor } from '../models/socialVendor'; import IUser from '../models/interface/IUser'; import { AgeGroup } from '../models/user/ageGroup'; import { Gender } from '../models/user/gender'; +import { createUser, validateNewLocalEmail } from '../services/userService'; /** * @route GET /email @@ -168,7 +170,7 @@ const verifyEmailTest = async ( }; /** - * @route /users + * @route POST /users * @desc 회원가입 api * @access Public */ @@ -183,18 +185,9 @@ const postUser = async ( throw new IllegalArgumentException('필요한 값이 없습니다.'); } - const createUserCommand: CreateUserCommand = { - email: req.body.email, - password: req.body.password, - nickname: req.body.nickname, - ageGroup: req.body.ageGroup - ? AgeGroup[req.body.ageGroup] - : AgeGroup.UNDEFINED, - gender: req.body.gender ? Gender[req.body.gender] : Gender.ETC, - profileImgUrl: (req?.file as Express.MulterS3.File)?.location - }; - - const createdUser = await UserService.createUser(createUserCommand); + const createUserCommand = toCommand(req); + await validateNewLocalEmail(createUserCommand.email); + const createdUser = await createUser(createUserCommand); const jwt = getToken(createdUser._id); diff --git a/src/intefaces/createUserCommand.ts b/src/intefaces/createUserCommand.ts index c8f5a2c..441bcee 100644 --- a/src/intefaces/createUserCommand.ts +++ b/src/intefaces/createUserCommand.ts @@ -1,5 +1,6 @@ import { AgeGroup, AgeGroupKey } from '../models/user/ageGroup'; import { Gender, GenderKey } from '../models/user/gender'; +import { TypedRequest } from '../types/TypedRequest'; interface CreateUserCommand { email: string; @@ -18,4 +19,18 @@ interface CreateUserReq { gender?: GenderKey; } -export { CreateUserCommand, CreateUserReq }; +const toCommand = (req: TypedRequest) => { + const createUserCommand: CreateUserCommand = { + email: req.body.email, + password: req.body.password, + nickname: req.body.nickname, + ageGroup: req.body.ageGroup + ? AgeGroup[req.body.ageGroup] + : AgeGroup.UNDEFINED, + gender: req.body.gender ? Gender[req.body.gender] : Gender.ETC, + profileImgUrl: (req?.file as Express.MulterS3.File)?.location + }; + return createUserCommand; +}; + +export { CreateUserCommand, CreateUserReq, toCommand }; diff --git a/src/models/user/user.ts b/src/models/user/user.ts index 0237d6d..ddacd60 100644 --- a/src/models/user/user.ts +++ b/src/models/user/user.ts @@ -11,8 +11,7 @@ type UserDocument = IUser & IDocument; const userSchema = new Schema( { email: { - type: String, - unique: true + type: String }, socialId: { type: String, @@ -60,7 +59,7 @@ const userSchema = new Schema( } ); -userSchema.index({ socialVendor: 1, socialId: 1 }, { unique: true }); +userSchema.index({ socialVendor: 1, email: 1 }, { unique: true }); const User = model('User', userSchema); diff --git a/src/services/socialAuthService.ts b/src/services/socialAuthService.ts index 8e53191..784fd78 100644 --- a/src/services/socialAuthService.ts +++ b/src/services/socialAuthService.ts @@ -63,15 +63,22 @@ const findUserBySocial = async ( return user; }; -const join = async (socialMember: IUser): Promise => { - if (socialMember.email) { - const alreadyEmail = await UserService.isEmailExisting(socialMember.email); - if (alreadyEmail) { - throw new IllegalArgumentException( - `같은 이메일로 가입된 유저가 있습니다. email: ${socialMember.email}` - ); - } +const validateMemberState = async (preMember: IUser) => { + const alreadyUser = await User.findOne({ + socialVendor: '$preMember.socialVendor', + socialId: '$preMember.socialId' + }); + if (alreadyUser) { + throw new IllegalArgumentException( + `해당 소셜에 같은 이메일로 가입된 유저가 있습니다. email: ${ + preMember.email || '이메일 알 수 없음' + }` + ); } +}; + +const join = async (socialMember: IUser): Promise => { + await validateMemberState(socialMember); socialMember.nickname = await UserService.autoGenerateNicknameFrom( socialMember.nickname ); @@ -98,26 +105,7 @@ const findSocialUser = async (socialMember: IUser) => { return alreadyMember; }; -const findOrCreateUserBySocialToken = async (vendor: string, token: string) => { - const response: SocialLoginResponse = await getUserFromSocialVendor( - token, - vendor - ); - const socialVendor = SocialVendorExtension.getVendorByValue(vendor); - const socialMember: IUser = convertSocialToPiickle(socialVendor, response); - const isAlreadyMember = await isAlreadySocialMember(socialMember); - if (isAlreadyMember) { - const alreadyMember = await findUserBySocial( - socialVendor, - socialMember.socialId! - ); - return alreadyMember; - } - return join(socialMember); -}; - export { - findOrCreateUserBySocialToken, findUserBySocial, getPiickleUser, isAlreadySocialMember, diff --git a/src/services/userService.ts b/src/services/userService.ts index 081af64..8f3f2ec 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -30,9 +30,10 @@ const isEmailExisting = async (email: string): Promise => { return false; }; -const validateEmail = async (email: string) => { +const validateNewLocalEmail = async (email: string) => { const alreadyUser = await User.findOne({ - email + email, + socialVendor: null }); if (alreadyUser) { throw new IllegalArgumentException('이미 존재하는 이메일입니다.'); @@ -48,7 +49,6 @@ const createUser = async (command: CreateUserCommand) => { gender, profileImgUrl: profileImageUrl } = command; - await validateEmail(email); const user = new User({ email, @@ -241,5 +241,6 @@ export { createOrDeleteBookmark, nicknameAlreadyExists, autoGenerateNicknameFrom, - deleteUser + deleteUser, + validateNewLocalEmail };