Skip to content

Commit 9bd9039

Browse files
authored
Merge pull request #146 from BEMINE-UMC/develop
main 배포
2 parents 94993e0 + 7a5f228 commit 9bd9039

20 files changed

Lines changed: 1981 additions & 223 deletions

middleware.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const s3 = new S3Client({
1515
});
1616

1717
// 확장자 검사 목록
18-
const allowedExtensions = [".png", ".jpg", ".jpeg", ".bmp", ".gif",".TXT"];
18+
const allowedExtensions = [".png", ".jpg", ".jpeg", ".bmp", ".gif",".TXT", '.pdf','.PDF'];
1919

2020
export const imageUploader = multer({
2121
storage: multerS3({

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"multer": "^1.4.5-lts.1",
3232
"multer-s3": "^3.0.1",
3333
"mysql2": "^3.12.0",
34+
"nodemailer": "^6.10.0",
3435
"passport": "^0.7.0",
3536
"swagger-autogen": "^2.23.7",
3637
"swagger-ui-express": "^5.0.1",
@@ -40,4 +41,4 @@
4041
"nodemon": "^3.1.9",
4142
"prisma": "^6.2.0"
4243
}
43-
}
44+
}

prisma/schema.prisma

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ model ScrapPost {
9696
model Template {
9797
id Int @id @default(autoincrement()) @db.Int
9898
userId Int @map("user_id")
99+
tCategoryId Int @map("t_categoryId")
99100
title String @db.VarChar(120)
100101
filePPT String? @db.VarChar(255) @map("file_ppt")
101102
filePDF String? @db.VarChar(255) @map("file_pdf")
@@ -107,11 +108,21 @@ model Template {
107108
updatedAt DateTime? @db.DateTime(6) @map("updated_at")
108109
109110
user User @relation(fields: [userId], references: [id])
111+
templateCategory TemplateCategory @relation(fields: [tCategoryId], references: [id])
110112
likedTemplates LikedTemplate[]
111113
112114
@@map("template")
113115
}
114116

117+
model TemplateCategory{
118+
id Int @id @default(autoincrement())
119+
name String @db.VarChar(50)
120+
121+
templates Template[]
122+
123+
@@map("template_category")
124+
}
125+
115126
model LikedTemplate {
116127
id Int @id @default(autoincrement()) @db.Int
117128
templateId Int @map("template_id")

src/controllers/auth.controller.js

Lines changed: 176 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import bcrypt from 'bcrypt';
22
import { StatusCodes } from "http-status-codes";
3-
import { postUserInfo } from "../services/auth.service.js";
4-
import { getLoginInfo } from "../services/auth.service.js";
5-
import { handleTokenRefreshService } from "../services/auth.service.js";
6-
import { PasswordLengthError } from "../errors/auth.error.js";
7-
import { createdGetLoginInfoDTO } from '../dtos/auth.dto.js';
3+
import { postUserInfo, getLoginInfo, handleTokenRefreshService, sendVerificationEmail, verifyEmailCode } from "../services/auth.service.js";
4+
import { PasswordLengthError, CodeNotValidateError } from "../errors/auth.error.js";
85

96
// 회원가입
107
export const handleSignUp = async (req, res) => {
@@ -252,7 +249,7 @@ export const handleLogin = async (req, res) => {
252249

253250
const { email, password } = req.body;
254251

255-
const userInfo = await getLoginInfo({email, password});
252+
const userInfo = await getLoginInfo({ email, password });
256253

257254
res.status(StatusCodes.OK).success(userInfo);
258255

@@ -335,15 +332,113 @@ export const handleTokenRefresh = async (req, res) => {
335332

336333
}
337334

338-
// 이메일 인증
335+
// 인증번호 발송
336+
export const handlesendEmail = async (req, res) => {
337+
338+
/*
339+
#swagger.summary = '인증번호 발송 API';
340+
#swagger.tags = ['Auth']
341+
342+
#swagger.requestBody = {
343+
required: true,
344+
content: {
345+
"application/json": {
346+
schema: {
347+
type: "object",
348+
properties: {
349+
email: { type: "string", example: "user@example.com" }
350+
},
351+
required: ["email"]
352+
}
353+
}
354+
}
355+
}
356+
357+
#swagger.responses[200] = {
358+
description: "인증번호 발송 성공 응답",
359+
content: {
360+
"application/json": {
361+
schema: {
362+
type: "object",
363+
properties: {
364+
resultType: { type: "string", example: "SUCCESS" },
365+
error: { type: "object", nullable: true, example: null },
366+
success: {
367+
type: "object",
368+
properties: {
369+
message: { type: "string", example: "인증번호가 전송되었습니다!" }
370+
}
371+
}
372+
}
373+
}
374+
}
375+
}
376+
}
377+
378+
#swagger.responses[400] = {
379+
description: "인증번호 발송 실패 응답",
380+
content: {
381+
"application/json": {
382+
schema: {
383+
type: "object",
384+
properties: {
385+
resultType: { type: "string", example: "FAIL" },
386+
error: {
387+
type: "object",
388+
properties: {
389+
errorCode: { type: "string", example: "A018" },
390+
reason: { type: "string", example: "이메일은 '@'를 포함하는 문자열이어야 합니다." },
391+
data: {
392+
type: "object",
393+
properties: {
394+
email: { type: "string", example: "user!example.com" }
395+
}
396+
}
397+
}
398+
},
399+
success: { type: "object", nullable: true, example: null }
400+
}
401+
}
402+
}
403+
}
404+
}
405+
*/
406+
407+
console.log("인증번호 발송 요청");
408+
409+
const { email } = req.body;
410+
411+
await sendVerificationEmail(email);
412+
413+
res.status(StatusCodes.OK).success({ message: '인증번호가 전송되었습니다!' });
414+
415+
}
416+
417+
// 인증번호 검증
339418
export const handlecheckEmail = async (req, res) => {
340419

341420
/*
342-
#swagger.summary = '이메일 인증 API';
421+
#swagger.summary = '인증번호 검증 API';
343422
#swagger.tags = ['Auth']
344423
424+
#swagger.requestBody = {
425+
required: true,
426+
content: {
427+
"application/json": {
428+
schema: {
429+
type: "object",
430+
properties: {
431+
email: { type: "string", example: "user@example.com" },
432+
code: { type: "string", example: "123456" }
433+
},
434+
required: ["email", "code"]
435+
}
436+
}
437+
}
438+
}
439+
345440
#swagger.responses[200] = {
346-
description: "이메일 인증 성공 응답",
441+
description: "인증번호 검증 성공 응답",
347442
content: {
348443
"application/json": {
349444
schema: {
@@ -354,9 +449,7 @@ export const handlecheckEmail = async (req, res) => {
354449
success: {
355450
type: "object",
356451
properties: {
357-
email: { type: "string", example: "user@example.com" },
358-
accessToken: { type: "string", example: "accessToken" },
359-
refreshToken: { type: "string", example: "refreshToken" }
452+
message: { type: "string", example: "인증되었습니다." }
360453
}
361454
}
362455
}
@@ -366,7 +459,63 @@ export const handlecheckEmail = async (req, res) => {
366459
}
367460
368461
#swagger.responses[400] = {
369-
description: "이메일 인증 실패 응답",
462+
description: "인증번호 검증 실패 응답",
463+
content: {
464+
"application/json": {
465+
schema: {
466+
type: "object",
467+
properties: {
468+
resultType: { type: "string", example: "FAIL" },
469+
error: {
470+
type: "object",
471+
properties: {
472+
errorCode: { type: "string", example: "A018" },
473+
reason: { type: "string", example: "이메일은 '@'를 포함하는 문자열이어야 합니다." },
474+
data: {
475+
type: "object",
476+
properties: {
477+
email: { type: "string", example: "user!example.com" }
478+
}
479+
}
480+
}
481+
},
482+
success: { type: "object", nullable: true, example: null }
483+
}
484+
}
485+
}
486+
}
487+
}
488+
489+
#swagger.responses[401] = {
490+
description: "인증번호 검증 실패 응답",
491+
content: {
492+
"application/json": {
493+
schema: {
494+
type: "object",
495+
properties: {
496+
resultType: { type: "string", example: "FAIL" },
497+
error: {
498+
type: "object",
499+
properties: {
500+
errorCode: { type: "string", example: "A019" },
501+
reason: { type: "string", example: "인증번호는 6자리 숫자입니다." },
502+
data: {
503+
type: "object",
504+
properties: {
505+
code: { type: "string", example: "1234567" }
506+
}
507+
}
508+
}
509+
},
510+
success: { type: "object", nullable: true, example: null }
511+
}
512+
}
513+
}
514+
}
515+
}
516+
517+
#swagger.responses[402] = {
518+
description: "인증번호 검증 실패 응답",
370519
content: {
371520
"application/json": {
372521
schema: {
@@ -376,9 +525,9 @@ export const handlecheckEmail = async (req, res) => {
376525
error: {
377526
type: "object",
378527
properties: {
379-
errorCode: { type: "string", example: "L003" },
380-
reason: { type: "string", example: "이메일 인증 실패" },
381-
data: { type: "object", nullable: true, example: {} }
528+
errorCode: { type: "string", example: "A020" },
529+
reason: { type: "string", example: "인증번호가 올바르지 않습니다." },
530+
data: { type: "object", example: {} }
382531
}
383532
},
384533
success: { type: "object", nullable: true, example: null }
@@ -389,5 +538,16 @@ export const handlecheckEmail = async (req, res) => {
389538
}
390539
*/
391540

541+
console.log("인증번호 검증 요청");
542+
543+
const { email, code } = req.body;
544+
545+
const isVerified = await verifyEmailCode(email, code);
546+
547+
if (isVerified) {
548+
return res.status(StatusCodes.OK).success({ message: '인증되었습니다.'});
549+
} else {
550+
throw new CodeNotValidateError("인증번호가 올바르지 않습니다.");
551+
}
392552

393553
}

0 commit comments

Comments
 (0)