Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
students
survey
Commits
6b56633c
Commit
6b56633c
authored
Jul 16, 2022
by
Yoon, Daeki
😅
Browse files
아바타 파일 업로드 로직 구현
parent
a0a0c03e
Changes
12
Show whitespace changes
Inline
Side-by-side
migrations/create.admin.ts
0 → 100644
View file @
6b56633c
import
{
connect
}
from
"
mongoose
"
;
import
{
mongoUri
}
from
"
../src/config
"
;
import
{
Role
,
User
}
from
"
../src/models
"
;
import
{
userDb
}
from
"
../src/db
"
;
const
roles
=
[
[
"
admin
"
,
1
],
[
"
manager
"
,
10
],
[
"
staff
"
,
100
],
[
"
user
"
,
1000
],
[
"
guest
"
,
10000
],
];
connect
(
mongoUri
)
.
then
(
async
(
mongoose
)
=>
{
const
adminRole
=
await
Role
.
findOne
({
name
:
"
admin
"
});
await
userDb
.
createUser
({
email
:
"
admin@example.com
"
,
name
:
"
admin
"
,
role
:
adminRole
?.
_id
,
password
:
"
asdfasdf
"
,
});
await
mongoose
.
disconnect
();
})
.
catch
((
error
)
=>
console
.
log
(
"
롤 초기 생성 에러
"
,
error
));
src/controllers/auth.controller.ts
View file @
6b56633c
...
@@ -50,7 +50,11 @@ export const hasRole = (roleName: string) => {
...
@@ -50,7 +50,11 @@ export const hasRole = (roleName: string) => {
if
(
!
req
.
auth
)
{
if
(
!
req
.
auth
)
{
return
res
.
status
(
401
).
send
(
"
로그인이 필요합니다
"
);
return
res
.
status
(
401
).
send
(
"
로그인이 필요합니다
"
);
}
}
const
{
userId
}
=
req
.
auth
;
const
{
userId
}
=
req
.
auth
;
if
(
!
(
await
userDb
.
isValidUserId
(
userId
)))
{
return
res
.
status
(
401
).
send
(
"
유효한 사용자가 아닙니다
"
);
}
const
userRole
=
await
roleDb
.
findRoleByUserId
(
userId
);
const
userRole
=
await
roleDb
.
findRoleByUserId
(
userId
);
const
maxRole
=
await
roleDb
.
findRoleByName
(
roleName
);
const
maxRole
=
await
roleDb
.
findRoleByName
(
roleName
);
if
(
maxRole
&&
Number
(
maxRole
.
priority
)
>=
Number
(
userRole
.
priority
))
{
if
(
maxRole
&&
Number
(
maxRole
.
priority
)
>=
Number
(
userRole
.
priority
))
{
...
...
src/controllers/file.controller.ts
View file @
6b56633c
import
{
NextFunction
,
Request
,
Response
}
from
"
express
"
;
import
formidable
from
"
formidable
"
;
import
formidable
from
"
formidable
"
;
import
{
isEmpty
}
from
"
../helpers
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
import
{
TypedRequest
}
from
"
../types
"
;
interface
TypedRequest
extends
Request
{
export
const
uploadAvatar
=
asyncWrap
(
async
(
reqExp
,
res
,
next
)
=>
{
auth
:
any
;
const
req
=
reqExp
as
TypedRequest
;
user
:
any
;
const
form
=
formidable
({
multiples
:
false
,
uploadDir
:
"
uploads
"
});
files
:
any
;
}
export
const
fileUpload
=
asyncWrap
(
async
(
req
,
res
,
next
)
=>
{
const
typedReq
=
req
as
TypedRequest
;
const
form
=
formidable
();
await
new
Promise
((
resolve
,
reject
)
=>
{
await
new
Promise
((
resolve
,
reject
)
=>
{
form
.
parse
(
req
,
(
err
,
fields
,
files
)
=>
{
form
.
parse
(
req
,
(
err
,
fields
,
files
)
=>
{
if
(
err
)
{
if
(
err
)
{
...
@@ -20,15 +13,11 @@ export const fileUpload = asyncWrap(async (req, res, next) => {
...
@@ -20,15 +13,11 @@ export const fileUpload = asyncWrap(async (req, res, next) => {
return
;
return
;
}
}
console
.
log
(
"
fields
"
,
fields
);
// console.log("fields", fields);
console
.
log
(
"
files
"
,
files
);
// console.log("files", files);
typedReq
.
body
=
fields
;
req
.
body
=
fields
;
req
.
files
=
files
;
if
(
isEmpty
(
files
))
{
typedReq
.
files
=
null
;
}
else
{
typedReq
.
files
=
files
;
}
resolve
(
files
);
resolve
(
files
);
});
});
});
});
...
...
src/controllers/user.controller.ts
View file @
6b56633c
import
{
NextFunction
,
Request
,
Response
}
from
"
express
"
;
import
{
NextFunction
,
Request
,
Response
}
from
"
express
"
;
import
{
userDb
}
from
"
../db
"
;
import
formidable
from
"
formidable
"
;
import
fs
from
"
fs/promises
"
;
import
{
fileDb
,
userDb
}
from
"
../db
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
import
{
FileInfo
}
from
"
../models
"
;
import
{
TypedRequest
}
from
"
../types
"
;
import
{
TypedRequestAuth
}
from
"
./auth.controller
"
;
import
{
TypedRequestAuth
}
from
"
./auth.controller
"
;
interface
TypedRequest
extends
Request
{
auth
:
any
;
user
:
any
;
files
:
any
;
}
export
const
createUser
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
export
const
createUser
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
const
req
=
reqExp
as
TypedRequest
;
const
req
=
reqExp
as
TypedRequest
;
const
user
=
req
.
body
;
const
user
=
req
.
body
;
console
.
log
(
"
user body
"
,
user
);
// console.log("user body", user);
console
.
log
(
"
files
"
,
req
.
files
);
// console.log("files ", req.files);
const
file
=
req
.
files
.
avatar
as
formidable
.
File
;
let
avatar
;
try
{
// 1) 아바타 이미지 저장
if
(
file
)
{
avatar
=
new
FileInfo
({
name
:
file
.
originalFilename
,
url
:
file
.
newFilename
,
isNew
:
true
,
});
await
fileDb
.
save
(
avatar
);
// 2) 사용자에 아바타 항목 추가
user
.
avatar
=
avatar
;
}
// 3) 사용자 만들기
const
newUser
=
await
userDb
.
createUser
(
user
);
const
newUser
=
await
userDb
.
createUser
(
user
);
// 주의: ref는 반드시 save를 해야 디비에 생성이 됩니다.
return
res
.
json
(
newUser
);
return
res
.
json
(
newUser
);
}
catch
(
error
:
any
)
{
console
.
log
(
"
error in create user:
"
,
error
);
// 오류 발생시 저장된 파일 제거
if
(
file
)
{
avatar
&&
(
await
fileDb
.
deleteFileById
(
avatar
.
_id
.
toString
()));
await
fs
.
unlink
(
file
.
filepath
);
}
res
.
status
(
422
).
send
(
error
.
message
||
"
사용자 생성 오류
"
);
}
});
});
export
const
deleteUser
=
asyncWrap
(
async
(
req
,
res
)
=>
{
export
const
deleteUser
=
asyncWrap
(
async
(
req
,
res
)
=>
{
...
...
src/db/file.db.ts
0 → 100644
View file @
6b56633c
import
formidable
from
"
formidable
"
;
import
{
HydratedDocument
}
from
"
mongoose
"
;
import
{
FileInfo
,
IFileInfo
}
from
"
../models
"
;
export
const
createFile
=
async
(
file
:
formidable
.
File
)
=>
{
const
newFile
=
new
FileInfo
({
name
:
file
.
originalFilename
,
url
:
file
.
newFilename
,
});
const
retFile
=
await
newFile
.
save
();
return
retFile
;
};
export
const
deleteFileById
=
async
(
fileId
:
string
)
=>
{
return
await
FileInfo
.
findByIdAndDelete
(
fileId
);
};
export
const
save
=
async
(
fileInfo
:
HydratedDocument
<
IFileInfo
>
)
=>
{
return
await
fileInfo
.
save
();
};
src/db/index.ts
View file @
6b56633c
export
*
as
ro
leDb
from
"
./
ro
le.db
"
;
export
*
as
fi
leDb
from
"
./
fi
le.db
"
;
export
*
as
questionDb
from
"
./question.db
"
;
export
*
as
questionDb
from
"
./question.db
"
;
export
*
as
roleDb
from
"
./role.db
"
;
export
*
as
surveyDb
from
"
./survey.db
"
;
export
*
as
surveyDb
from
"
./survey.db
"
;
export
*
as
userDb
from
"
./user.db
"
;
export
*
as
userDb
from
"
./user.db
"
;
src/db/user.db.ts
View file @
6b56633c
...
@@ -15,6 +15,7 @@ export const createUser = async (user: IUser) => {
...
@@ -15,6 +15,7 @@ export const createUser = async (user: IUser) => {
email
:
user
.
email
,
email
:
user
.
email
,
password
:
hash
,
password
:
hash
,
role
:
userRole
,
role
:
userRole
,
avatar
:
user
.
avatar
,
isNew
:
true
,
isNew
:
true
,
});
});
const
retUser
=
await
newUser
.
save
();
const
retUser
=
await
newUser
.
save
();
...
@@ -45,7 +46,10 @@ export const findUserByEmail = async (
...
@@ -45,7 +46,10 @@ export const findUserByEmail = async (
};
};
export
const
getUsers
=
async
()
=>
{
export
const
getUsers
=
async
()
=>
{
const
users
=
await
User
.
find
({});
const
users
=
await
User
.
find
({}).
populate
({
path
:
"
avatar
"
,
select
:
"
_id name url
"
,
});
return
users
;
return
users
;
};
};
...
@@ -57,3 +61,12 @@ export const isUser = async (email: string) => {
...
@@ -57,3 +61,12 @@ export const isUser = async (email: string) => {
return
false
;
return
false
;
}
}
};
};
export
const
isValidUserId
=
async
(
userId
:
string
)
=>
{
const
user
=
await
User
.
findById
(
userId
);
if
(
user
)
{
return
true
;
}
else
{
return
false
;
}
};
src/models/file.model.ts
→
src/models/file
info
.model.ts
View file @
6b56633c
import
{
model
,
Schema
}
from
"
mongoose
"
;
import
{
model
,
Schema
}
from
"
mongoose
"
;
interface
IFile
{
export
interface
IFile
Info
{
name
:
string
;
name
:
string
;
path
:
string
;
url
:
string
;
}
}
const
schema
=
new
Schema
<
IFile
>
(
const
schema
=
new
Schema
<
IFile
Info
>
(
{
{
name
:
{
type
:
String
},
name
:
{
type
:
String
},
path
:
{
type
:
String
},
url
:
{
type
:
String
},
},
},
{
timestamps
:
true
,
toJSON
:
{
versionKey
:
false
}
}
{
timestamps
:
true
,
toJSON
:
{
versionKey
:
false
}
}
);
);
export
default
model
<
IFile
>
(
"
File
"
,
schema
);
export
default
model
<
IFile
Info
>
(
"
File
Info
"
,
schema
);
src/models/index.ts
View file @
6b56633c
export
{
default
as
File
}
from
"
./file.model
"
;
export
{
default
as
File
Info
,
IFileInfo
}
from
"
./file
info
.model
"
;
export
{
default
as
Question
,
IQuestion
}
from
"
./question.model
"
;
export
{
default
as
Question
,
IQuestion
}
from
"
./question.model
"
;
export
{
default
as
Role
}
from
"
./role.model
"
;
export
{
default
as
Role
}
from
"
./role.model
"
;
export
{
default
as
Survey
,
ISurvey
}
from
"
./survey.model
"
;
export
{
default
as
Survey
,
ISurvey
}
from
"
./survey.model
"
;
...
...
src/models/user.model.ts
View file @
6b56633c
...
@@ -24,7 +24,7 @@ const schema = new Schema<IUser>(
...
@@ -24,7 +24,7 @@ const schema = new Schema<IUser>(
name
:
{
type
:
String
},
name
:
{
type
:
String
},
password
:
{
type
:
String
,
required
:
true
,
select
:
false
},
password
:
{
type
:
String
,
required
:
true
,
select
:
false
},
role
:
{
type
:
Schema
.
Types
.
ObjectId
,
ref
:
"
Role
"
},
role
:
{
type
:
Schema
.
Types
.
ObjectId
,
ref
:
"
Role
"
},
avatar
:
{
type
:
Schema
.
Types
.
ObjectId
,
ref
:
"
File
"
},
avatar
:
{
type
:
Schema
.
Types
.
ObjectId
,
ref
:
"
File
Info
"
},
},
},
{
{
toJSON
:
{
toJSON
:
{
...
...
src/routes/user.route.ts
View file @
6b56633c
...
@@ -6,7 +6,12 @@ const router = express.Router();
...
@@ -6,7 +6,12 @@ const router = express.Router();
router
router
.
route
(
"
/
"
)
.
route
(
"
/
"
)
.
get
(
authCtrl
.
requireLogin
,
userCtrl
.
getUsers
)
.
get
(
authCtrl
.
requireLogin
,
userCtrl
.
getUsers
)
.
post
(
authCtrl
.
requireLogin
,
fileCtrl
.
fileUpload
,
userCtrl
.
createUser
);
.
post
(
authCtrl
.
requireLogin
,
authCtrl
.
hasRole
(
"
admin
"
),
fileCtrl
.
uploadAvatar
,
userCtrl
.
createUser
);
router
router
.
route
(
"
/:userId
"
)
.
route
(
"
/:userId
"
)
...
...
src/types/index.ts
0 → 100644
View file @
6b56633c
import
{
Request
}
from
"
express
"
;
import
{
Files
}
from
"
formidable
"
;
export
interface
TypedRequest
extends
Request
{
auth
:
any
;
user
:
any
;
files
:
Files
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment