Skip to content

Commit

Permalink
Feat: feature 브렌치 pull
Browse files Browse the repository at this point in the history
  • Loading branch information
[pyola4981] committed May 5, 2023
1 parent ce19c84 commit c03b47b
Show file tree
Hide file tree
Showing 27 changed files with 242 additions and 172 deletions.
15 changes: 15 additions & 0 deletions BackEnd/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [1.3.3](https://github.com/CSW-Study-Group/BOARD/compare/v1.3.1...v1.3.3) (2023-05-03)


### Features

* 특정 ip 차단 코드 ([255543b](https://github.com/CSW-Study-Group/BOARD/commit/255543b3621471105aaadaf0a46033fe2c5df91e))
* bootstrap 4.6 업데이트 ([a660481](https://github.com/CSW-Study-Group/BOARD/commit/a660481904d220bc654a32c9268895a14d0346fd))
* ip logging ([ad91d97](https://github.com/CSW-Study-Group/BOARD/commit/ad91d97859c437a17a40d6a3c8ab6c3d6535e6b1))
* sentry 에러 트래킹 & 모니터링 ([f773b9d](https://github.com/CSW-Study-Group/BOARD/commit/f773b9d36061ce8c8752d12bf63399e5da1fdae2))


### Bug Fixes

* 게시글 수정 논리오류 ([9f2a54e](https://github.com/CSW-Study-Group/BOARD/commit/9f2a54e1b7ff80b4e6d2809c842c603c01cb2846))

### [1.3.1](https://github.com/SoN-B/Node.JS-Practice/compare/v1.2.1...v1.3.1) (2023-04-10)


Expand Down
4 changes: 2 additions & 2 deletions BackEnd/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion BackEnd/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "backend",
"version": "1.3.1",
"version": "1.3.3",
"description": "",
"main": "index.js",
"scripts": {
Expand Down
64 changes: 45 additions & 19 deletions BackEnd/src/controllers/board.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
searchByPostId,
editPost,
deletePost,
countPost,
recommandBoard,
authCheckPost,
recommandCheckBoard,
Expand All @@ -25,15 +26,41 @@ const { Op } = require('sequelize');
* 검색어가 있을 경우, 검색어에 해당하는 게시글을 조회한다. (없을 경우, 모든 게시글을 조회)
* 검색어: 제목, 내용, 작성자로 검색할 수 있다.
*
* limit 값이 5, 10, 20이 아닐 경우, 5로 설정하고, 에러 메시지를 반환한다.
* page 값이 1000 이상일 경우, 1로 설정하고, 에러 메시지를 반환한다.
*
* DB에서 조회한 글의 수보다 page * limit 값이 클 경우, page 값을 마지막 페이지로 설정한다.
*
* @returns {Object} 게시글 정보
*/
const boardGet = async (req, res) => {
let { page, limit, searchType, searchText } = req.query;
let where_content = null,
where_user = null;
page = parseInt(page);
limit = parseInt(limit);

let where_content = null, where_user = null;

const rendering = (res, posts, message, currentPage = 1, maxPage = 1, limit = 5) => {
return res.render('post/index', {
posts: posts,
currentPage: currentPage,
maxPage: maxPage,
limit: limit,
searchType: searchType,
searchText: searchText,
error: message,
});
};

page = !isNaN(page) ? page : 1;
if (page > 1000) {
return rendering(res, [], 'Page can only be a number less than 1000.');
}

limit = !isNaN(limit) ? limit : 10;
if ([5, 10, 20].indexOf(limit) === -1) {
return rendering(res, [], 'Limit can only be 5, 10, 20.');
}

try {
let searchQuery = await createSearchQuery(req.query);
Expand All @@ -60,15 +87,11 @@ const boardGet = async (req, res) => {
}
}

const post_count = await countPost();
if (page * limit > post_count) page = post_count / limit; // 마지막 페이지

await getBoard(where_user, where_content, limit, page).then((data) => {
res.render('post/index', {
posts: data.rows,
currentPage: page,
maxPage: Math.ceil(data.count / Math.max(1, parseInt(limit))),
limit: limit,
searchType: searchType,
searchText: searchText,
});
return rendering(res, data.rows, null, page, Math.ceil(data.count / Math.max(1, limit)), limit);
});
} catch (err) {
return fail(res, 500, `${err.message}`);
Expand All @@ -85,12 +108,14 @@ const boardGetByPostId = async (req, res) => {

try {
let data = await searchByPostId(post_id);
if (data == null) {
return fail(res, 500, 'non-existent id');
}

res.render('post/read', { post: data });
} catch (err) {
return fail(res, 500, `${err.message}`);
if (err.message === 'No data.') {
return res.status(404).json({ code: 404, message: err.message });
} else {
return res.status(500).json({ code: 500, message: err.message });
}
}
};

Expand All @@ -114,9 +139,10 @@ const boardPost = (req, res) => {
* 유저로부터, 게시글의 제목과 내용을 받아 글을 수정한다.
*/
const boardEditByPostId = (req, res) => {
const { title, content, id } = req.body;
const { title, content } = req.body;
const { id: post_id } = req.params;
try {
editPost(title, content, id).then(() => {
editPost(title, content, post_id).then(() => {
return res.status(200).json({ code: 200 });
});
} catch (err) {
Expand All @@ -128,9 +154,9 @@ const boardEditByPostId = (req, res) => {
* 해당하는 id의 게시글을 삭제한다.
*/
const boardDeleteByPostId = (req, res) => {
const { id: id } = req.params;
const { id: post_id } = req.params;
try {
deletePost(id).then(() => {
deletePost(post_id).then(() => {
res.redirect('/board' + res.locals.getPostQueryString(false, { page: 1, searchText: '' }));
});
} catch (err) {
Expand Down Expand Up @@ -163,7 +189,7 @@ const postAuthCheck = (req, res) => {
try {
authCheckPost(content_id).then((data) => {
if (user_id === data.user_id) {
return success(res, 200, 'authorized');
return success(res, 200, 'authorized')
} else {
return success(res, 401, 'unauthorized');
}
Expand Down
87 changes: 5 additions & 82 deletions BackEnd/src/functions/winston.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*'use strict';
'use strict';

const config = require('config');

Expand All @@ -18,16 +18,16 @@ class CustomTransport extends Transport {
log(info, callback) {
const level = info.level;
const method = info.message.split(' ')[0];
const message = info.message.split(' ')[1].replace(/"/g, '');
const message = info.message.split(' ')[1];
const status = parseInt(info.message.split(' ')[3]);
const response_time = parseFloat(info.message.split(' ')[4]);
const ip = info.message.split(' ')[6];

if (!/^\/(js|css)/.test(message)) { // '/js' 또는 '/css'가 앞에 없는 경우
if (message && !/^\/(js|css)/.test(message)) { // '/js' 또는 '/css'가 앞에 없는 경우
Log.create({
level: level,
method: method,
message: message,
message: message.replace(/"/g, ''),
status: status,
response_time: response_time,
ip: ip,
Expand Down Expand Up @@ -105,81 +105,4 @@ logger.stream = {
write: (message) => logger.info(message),
};

module.exports = logger;
*/

'use strict';

const _config = require('config');

const _winstonDaily = require('winston-daily-rotate-file');
const { createLogger, transports, format } = require('winston');
const { combine, timestamp, colorize, printf, label } = format;

const log_dir = 'logs';

// 사용자 지정 포맷
const print_format = printf(({ timestamp, label, level, message }) => {
return `${timestamp} [${label}] ${level} : ${message}`;
});

const print_log_format = {
default: combine(
label({
label: 'RE:SPEC',
}),

timestamp({
format: 'YYYY-MM-DD HH:mm:dd',
}),
print_format,
),
};

const logger = createLogger({
format: print_log_format.default,
transports: [
// info 레벨 로그를 저장할 파일 설정
new _winstonDaily({
level: 'info',
datePattern: 'YYYY-MM-DD',
dirname: log_dir,
filename: `%DATE%.log`,
maxFiles: 30,
zippedArchive: true,
}),
// warn 레벨 로그를 저장할 파일 설정
new _winstonDaily({
level: 'warn',
datePattern: 'YYYY-MM-DD',
dirname: log_dir + '/warn',
filename: `%DATE%.warn.log`,
maxFiles: 30,
zippedArchive: true,
}),
// error 레벨 로그를 저장할 파일 설정
new _winstonDaily({
level: 'error',
datePattern: 'YYYY-MM-DD',
dirname: log_dir + '/error',
filename: `%DATE%.error.log`,
maxFiles: 30,
zippedArchive: true,
}),
],
});

//실제 서비스중인 서버가 아니면
if (_config.get('server.status') !== 'production') {
logger.add(
new transports.Console({
format: combine(colorize({ all: true }), print_format),
}),
);
}

logger.stream = {
write: (message) => logger.info(message),
};

module.exports = logger;
module.exports = logger;
2 changes: 1 addition & 1 deletion BackEnd/src/models/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = class Log extends Sequelize.Model {
allowNull: false,
},
message: {
type: Sequelize.STRING(255),
type: Sequelize.TEXT,
allowNull: false,
},
status: {
Expand Down
33 changes: 27 additions & 6 deletions BackEnd/src/routes/board.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,47 @@ router.post(
);

router.get('/:id', [check('id').isInt().withMessage('Post ID must be a number.'), validator], ctrl.boardGetByPostId);
router.delete('/:id', ctrl.boardDeleteByPostId);
router.delete(
'/:id',
[check('id').isInt().withMessage('Post ID must be a number.'), validator],
ctrl.boardDeleteByPostId,
);
router.patch(
'/:id',
[
auth,
check('id').isInt().withMessage('Post ID must be a number.'),
check('title').notEmpty().withMessage('Title is required.'),
check('content').notEmpty().withMessage('Content is required.'),
validator,
],
ctrl.boardEditByPostId,
);

router.post('/:id/recommand', auth, ctrl.boardRecommand);
router.post(
'/:id/recommand',
[auth, check('id').isInt().withMessage('Post ID must be a number.'), validator],
ctrl.boardRecommand,
);

// check auth, recommand status
router.get('/:id/auth', auth, ctrl.postAuthCheck);
router.get('/:id/recommand', auth, ctrl.boardRecommandCheck);
router.get(
'/:id/auth',
[auth, check('id').isInt().withMessage('Post ID must be a number.'), validator],
ctrl.postAuthCheck,
);
router.get(
'/:id/recommand',
[auth, check('id').isInt().withMessage('Post ID must be a number.'), validator],
ctrl.boardRecommandCheck,
);

// rendering page
router.get('/post/new', ctrl.postView);
router.get('/:id/edit', ctrl.editViewByPostId);
router.get(
'/:id/edit',
[check('id').isInt().withMessage('Post ID must be a number.'), validator],
ctrl.editViewByPostId,
);

module.exports = router;
module.exports = router;
Loading

0 comments on commit c03b47b

Please sign in to comment.