diff --git a/src/common/passport/jwtStrategy.js b/src/common/passport/jwtStrategy.js index 36b2f52..aee2e4e 100644 --- a/src/common/passport/jwtStrategy.js +++ b/src/common/passport/jwtStrategy.js @@ -12,7 +12,6 @@ module.exports = () => { passport.use( new JwtStrategy(opts, async (jwtPayload, done) => { try { - console.log(jwtPayload); const user = await User.findById(jwtPayload.userId); if (user) { return done(null, user); diff --git a/src/routes/user/user.controller.js b/src/routes/user/user.controller.js index 45e883f..5ed490b 100755 --- a/src/routes/user/user.controller.js +++ b/src/routes/user/user.controller.js @@ -268,17 +268,19 @@ exports.postWords = async (req, res) => { const validData = validateRequest(requestBodySchema, req.body); const { _id } = req.user; const { formData, type, nickname } = validData; - console.log(formData); const result = await userService.postWords(_id, formData, nickname, type); sendResponse.ok(res, { message: SuccessMessage.REGISTER_WORDS_SUCCESS, data: result, }); } catch (error) { - console.log('Error during postWords:', error); + console.log(error); if (error?.type === 'ajv') { return sendResponse.badRequest(res, ErrorMessage.ADD_REQUEST_WORDS_ERROR); } + if (error.message === '이미 같은 단어 수정 요청이 존재합니다.') { + return sendResponse.badRequest(res, error.message); + } sendResponse.fail(req, res, ErrorMessage.REGISTER_WORDS_ERROR); } }; @@ -292,7 +294,6 @@ exports.UserRequests = async (req, res) => { data: { requests }, }); } catch (err) { - console.log(err); sendResponse.fail(req, res, ErrorMessage.GET_REQUESTS_ERROR); } }; diff --git a/src/routes/user/user.model.js b/src/routes/user/user.model.js index ad510f6..c78f7e6 100644 --- a/src/routes/user/user.model.js +++ b/src/routes/user/user.model.js @@ -3,20 +3,18 @@ const bcrypt = require('bcrypt'); const requestSchema = new mongoose.Schema( { - word: { - type: String, + word: { + type: String, required: true, - match: /^[a-zA-Z0-9\s!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*$/ }, awkPron: { type: String }, - comPron: - { - type: String, - required: function () { - return this.type === 'mod'; - }, + comPron: { + type: String, + required: function () { + return this.type === 'mod'; }, - + }, + info: { type: String }, suggestedBy: { type: String, required: true }, type: { type: String, enum: ['add', 'mod'], required: true }, diff --git a/src/routes/user/user.repository.js b/src/routes/user/user.repository.js index fe10352..afe2db4 100644 --- a/src/routes/user/user.repository.js +++ b/src/routes/user/user.repository.js @@ -1,6 +1,4 @@ const User = require('./user.model'); -const mongoose = require('mongoose'); -const { ObjectId } = mongoose.Types; exports.createUser = async (userData) => { try { @@ -93,16 +91,6 @@ exports.postWords = async (userId, formData, nickname, type) => { if (!user) { throw new Error('User not found'); } - - console.log('User before modification:', JSON.stringify(user.requests, null, 2)); - - // 이미 존재하는 단어 요청 확인 (status가 'pend'인 경우에만 중복 확인) - const existingRequest = user.requests.find((req) => req.word === formData.devTerm && req.status === 'pend'); - if (existingRequest) { - console.log('이미 같은 단어 요청이 존재합니다.'); - throw new Error('Word request already exists'); - } - if (type === 'add') { user.requests.push({ word: formData.devTerm, @@ -115,30 +103,32 @@ exports.postWords = async (userId, formData, nickname, type) => { suggestedBy: nickname, // nickname 추가 }); } else if (type === 'mod') { - user.requests.push({ - word: formData.devTerm, - info: formData.addInfo, - awkPron: formData.awkPron, - comPron: formData.commonPron, - deletedAt: null, - status: 'pend', - type: 'mod', - suggestedBy: nickname, // nickname 추가 - }); + const requestExists = user.requests.some((req) => req.word === formData.devTerm); + + if (!requestExists) { + user.requests.push({ + word: formData.devTerm, + info: formData.addInfo, + awkPron: formData.awkPron, + comPron: formData.commonPron, + deletedAt: null, + status: 'pend', + type: 'mod', + suggestedBy: nickname, // nickname 추가 + }); + } else { + throw new Error('이미 같은 단어 수정 요청이 존재합니다.'); + } } else { throw new Error('Invalid type'); } await user.save(); - console.log('User after modification:', JSON.stringify(user.requests, null, 2)); return user.requests.find((req) => req.word === formData.devTerm); } catch (err) { - console.error(err); throw err; } }; - - exports.getUserRequests = async (userId) => { try { const user = await User.findById(userId).select('requests').exec(); diff --git a/src/routes/user/user.schema.js b/src/routes/user/user.schema.js index d81a9f2..f5d626a 100644 --- a/src/routes/user/user.schema.js +++ b/src/routes/user/user.schema.js @@ -17,7 +17,7 @@ const commonSchemas = { }, word: { type: 'string', - pattern: '^[a-zA-Z0-9 !@#$%^&*()_+\\-=\\[\\]{};:\'",.<>/?~`/]+$', + pattern: '^[\\s\\S]*$', }, }; @@ -72,15 +72,19 @@ const requestBodySchema = { devTerm: { type: 'string' }, commonPron: { type: 'string' }, awkPron: { type: 'string' }, - addInfo: { type: 'string' } + addInfo: { type: 'string' }, }, - additionalProperties: false - } + additionalProperties: false, + }, }, required: ['word', 'type', 'nickname', 'formData'], additionalProperties: false, }; - - -module.exports = { registerBodySchema, nicknameCheckReqQuerySchema, emailCheckReqQuerySchema, loginBodySchema, requestBodySchema }; +module.exports = { + registerBodySchema, + nicknameCheckReqQuerySchema, + emailCheckReqQuerySchema, + loginBodySchema, + requestBodySchema, +}; diff --git a/src/routes/user/user.service.js b/src/routes/user/user.service.js index ca2e8a8..b32d9d1 100644 --- a/src/routes/user/user.service.js +++ b/src/routes/user/user.service.js @@ -47,13 +47,8 @@ exports.updateRecentSearch = async (userID, searchTerm) => { // 단어 추가 및 수정 exports.postWords = async (userId, formData, nickname, type) => { - try { - const word = await userRepository.postWords(userId, formData, nickname, type); - return word; - } catch (error) { - console.error('Error in userService.postWords:', error.message); - throw new Error('Error processing word: ' + error.message); - } + const word = await userRepository.postWords(userId, formData, nickname, type); + return word; }; exports.getUserRequests = async (userId) => { const requests = await userRepository.getUserRequests(userId); diff --git a/src/routes/word/word.controller.js b/src/routes/word/word.controller.js index 74e0dd0..907f7e4 100644 --- a/src/routes/word/word.controller.js +++ b/src/routes/word/word.controller.js @@ -49,14 +49,14 @@ exports.getRankWords = async (req, res) => { // 연관검색어 : 쿼리스트링으로 전달받은 검색어 searchTerm을 포함하는 단어 조회 exports.getRelatedWords = async (req, res) => { try { - let { searchTerm, limit } = req.query; - searchTerm = validateRequest(relatedTermSchema, searchTerm); + const { searchTerm, limit } = validateRequest(relatedTermSchema, req.query); const data = await wordService.getRelatedWords(searchTerm, limit); sendResponse.ok(res, { message: SuccessMessage.RELATED_WORDS_SUCCESS, data, }); } catch (error) { + console.log(error); sendResponse.fail(req, res, ErrorMessage.RELATED_WORDS_ERROR); } }; @@ -92,12 +92,12 @@ exports.getAllWords = async (req, res) => { exports.checkDuplicateWord = async (req, res) => { try { const { word } = req.body; // req.body 에서 word 추출 - console.log("전달된 중복 검수 단어", ); + console.log('전달된 중복 검수 단어'); const isDataExist = await wordService.checkDuplicateWord(word); data = { isDataExist }; - console.log("중복검수 결과", data); + console.log('중복검수 결과', data); - // 중복 단어가 있는 경우 + // 중복 단어가 있는 경우 if (isDataExist) { return sendResponse.ok(res, { message: ErrorMessage.EXIST_WORD, @@ -109,9 +109,7 @@ exports.checkDuplicateWord = async (req, res) => { message: SuccessMessage.CHECK_DUPLICATE_REQUEST_SUCCESS, data, }); - } catch (error) { sendResponse.fail(req, res, ErrorMessage.CHECK_DUPLICATE_REQUEST_ERROR); } -} - +}; diff --git a/src/routes/word/word.repository.js b/src/routes/word/word.repository.js index f6a56b6..ca84c75 100644 --- a/src/routes/word/word.repository.js +++ b/src/routes/word/word.repository.js @@ -10,7 +10,6 @@ exports.getSearchWords = async (searchTerm) => { if (!searchWords) { console.log('Search term not found in Word collection'); } - console.log(888, searchWords); return searchWords; } catch (error) { console.log('Error while getting search words:', error); @@ -31,7 +30,8 @@ exports.getRankWords = async () => { exports.getRelatedWords = async (searchTerm, limit) => { try { - const relatedWords = await Word.find({ word: new RegExp(searchTerm, 'i') }) + const escapedTerm = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const relatedWords = await Word.find({ word: new RegExp(escapedTerm, 'i') }) .sort({ freq: -1 }) .limit(parseInt(limit)); const wordNames = relatedWords.map((word) => word.word); @@ -162,7 +162,8 @@ exports.deleteWordContributor = async (_id) => { }; exports.checkDuplicateWord = async (word) => { try { - const wordExists = await Word.findOne({ word: { $regex: new RegExp(`^${word}$`, 'i') } }); + const escapedTerm = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const wordExists = await Word.findOne({ word: { $regex: new RegExp(`^${escapedTerm}$`, 'i') } }); console.log('wordExists:', wordExists); return wordExists; } catch (error) { diff --git a/src/routes/word/word.schema.js b/src/routes/word/word.schema.js index db74f93..b11089e 100644 --- a/src/routes/word/word.schema.js +++ b/src/routes/word/word.schema.js @@ -1,10 +1,13 @@ const relatedTermSchema = { - type: 'string', + type: 'object', properties: { searchTerm: { type: 'string', maxLength: 50, }, + limit: { + type: 'string', + }, }, required: ['searchTerm'], additionalProperties: false,