411 lines
10 KiB
JavaScript
411 lines
10 KiB
JavaScript
const { v4: uuid } = require('uuid')
|
||
const ObjectId = require('mongodb').ObjectID
|
||
|
||
const { getDB } = require('../../utils/mongo')
|
||
const { _idToId, checkDB, _idToIdArray, filterId } = require('./utils')
|
||
|
||
let db = null
|
||
|
||
const USERS_COLL = 'ep_users'
|
||
const PROJECTS_COLL = 'ep_all_projects'
|
||
const PROJECT_TASKS_COLL = 'ep_projects_tasks'
|
||
const PROJECT_MEMBERS_COLL = 'ep_projects_members'
|
||
const PROJECT_STATUSES_COLL = 'ep_projects_statuses'
|
||
const PROJECT_TYPES_COLL = 'ep_projects_types'
|
||
|
||
const connect = async () => {
|
||
db = await getDB('easy-project')
|
||
if (db === null) throw new Error('Нет подключения к базе данных')
|
||
}
|
||
|
||
connect()
|
||
|
||
const hashPassword = (password, salt = uuid(), salt2 = uuid(), salt3 = uuid()) => ({
|
||
password: (password.split('').join(salt) + salt2 + password.split('').join(salt3)).split('-').reverse().join('-'),
|
||
salt,
|
||
salt2,
|
||
salt3,
|
||
})
|
||
|
||
const registrationUser = async ({ email, login, password, ...rest }) => {
|
||
checkDB(db)
|
||
const usersCollection = db.collection(USERS_COLL)
|
||
const userExist = await usersCollection.find({
|
||
$or: [{
|
||
login,
|
||
}, {
|
||
email,
|
||
}],
|
||
}).toArray()
|
||
|
||
if (userExist.length) {
|
||
if (userExist[0].login === login) {
|
||
throw new Error('Логин уже занят')
|
||
}
|
||
if (userExist[0].email === email) {
|
||
throw new Error('Email уже занят')
|
||
}
|
||
}
|
||
|
||
const { password: hash, salt, salt2, salt3 } = hashPassword(password)
|
||
|
||
const user = {
|
||
salt,
|
||
salt2,
|
||
salt3,
|
||
hash,
|
||
login,
|
||
email,
|
||
...rest,
|
||
}
|
||
|
||
const { insertedId } = await usersCollection.insertOne(user)
|
||
user.id = insertedId
|
||
}
|
||
|
||
const signInUser = async ({ email, password }) => {
|
||
checkDB(db)
|
||
|
||
const usersCollection = db.collection(USERS_COLL)
|
||
|
||
const [userCandidate] = await usersCollection.find({
|
||
email,
|
||
}).toArray()
|
||
|
||
if (!userCandidate) {
|
||
throw new Error('Email или пароль не корректный')
|
||
}
|
||
const { salt, salt2, salt3, hash, ...cleanUser } = userCandidate
|
||
const { password: hashFromDb } = hashPassword(password, salt, salt2, salt3)
|
||
|
||
if (hash !== hashFromDb) {
|
||
throw new Error('Email или пароль не корректный')
|
||
}
|
||
|
||
return cleanUser
|
||
}
|
||
|
||
const getMyProjects = async (userId) => {
|
||
checkDB(db)
|
||
|
||
const userFilterById = filterId(userId)
|
||
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
const usersCollection = db.collection(USERS_COLL)
|
||
|
||
let projectList = await projectCollection.find({
|
||
$or: [{
|
||
userId,
|
||
}, {
|
||
members: {
|
||
$in: [userId],
|
||
},
|
||
}],
|
||
}).toArray()
|
||
|
||
if (projectList) {
|
||
const [userAuthor] = await usersCollection.find(userFilterById).toArray()
|
||
for (let index = 0; index < projectList.length; index++) {
|
||
projectList[index].author = userAuthor
|
||
projectList[index] = _idToId(projectList[index])
|
||
}
|
||
return projectList
|
||
}
|
||
return []
|
||
}
|
||
|
||
const deleteProjectById = async (projectId) => {
|
||
checkDB(db)
|
||
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
const projectFilterById = filterId(projectId)
|
||
const deleted = await projectCollection.deleteOne(projectFilterById)
|
||
return deleted
|
||
}
|
||
|
||
const getMyProjectById = async (userId, projectId) => {
|
||
checkDB(db)
|
||
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
const usersCollection = db.collection(USERS_COLL)
|
||
|
||
const userFilterById = filterId(userId)
|
||
|
||
const [userAuthor] = await usersCollection.find(userFilterById).toArray()
|
||
|
||
const projectFilter = filterId(projectId)
|
||
|
||
let [projectMyExist] = await projectCollection.find(projectFilter).toArray()
|
||
|
||
const members = await usersCollection.find({
|
||
_id: {
|
||
$in: projectMyExist.members.map((memberId) => new ObjectId(memberId)),
|
||
},
|
||
}).toArray()
|
||
|
||
projectMyExist.members = members.map((m) => ({
|
||
value: m._id, label: m.email,
|
||
}))
|
||
projectMyExist.author = userAuthor
|
||
|
||
projectMyExist = _idToId(projectMyExist)
|
||
|
||
return projectMyExist
|
||
}
|
||
|
||
const newProject = async ({
|
||
title,
|
||
code,
|
||
userId,
|
||
members,
|
||
}) => {
|
||
checkDB(db)
|
||
|
||
if (!title || !code) {
|
||
throw new Error('Fields can\'t be empty')
|
||
}
|
||
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
|
||
const project = {
|
||
title,
|
||
code,
|
||
userId,
|
||
created: Date.now(),
|
||
changed: Date.now(),
|
||
changedBy: userId,
|
||
taskIndex: 0,
|
||
members,
|
||
}
|
||
|
||
await projectCollection.insertOne(project)
|
||
|
||
return _idToId(project)
|
||
}
|
||
|
||
const updateProject = async ({ projectId, title, code, members }) => {
|
||
checkDB(db)
|
||
|
||
if (!title || !code) {
|
||
throw new Error('Fields can\'t be empty')
|
||
}
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
|
||
const projectFilterById = filterId(projectId)
|
||
|
||
const updatedProject = await projectCollection.updateOne(projectFilterById, {
|
||
$set: {
|
||
title,
|
||
code,
|
||
changed: Date.now(),
|
||
members,
|
||
},
|
||
})
|
||
|
||
return updatedProject
|
||
}
|
||
|
||
// TODO: Совмещение projectId с userId ИЛИ поиск по memberIds
|
||
const getProjectById = async ({ projectId }) => {
|
||
checkDB(db)
|
||
|
||
const projectFilterById = filterId(projectId)
|
||
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
const [projectExist] = await projectCollection.find(projectFilterById).toArray()
|
||
|
||
return projectExist
|
||
}
|
||
|
||
const getTaskById = async ({ taskId, userId }) => {
|
||
checkDB(db)
|
||
if (taskId) {
|
||
const userFilterById = filterId(userId)
|
||
const taskFilterById = filterId(taskId)
|
||
|
||
const taskCollection = db.collection(PROJECT_TASKS_COLL)
|
||
const usersCollection = db.collection(USERS_COLL)
|
||
let [taskExist] = await taskCollection.find(taskFilterById).toArray()
|
||
|
||
if (taskExist) {
|
||
const [userAuthor] = await usersCollection.find(userFilterById).toArray()
|
||
taskExist.author = userAuthor
|
||
return _idToId(taskExist)
|
||
}
|
||
}
|
||
return {
|
||
}
|
||
}
|
||
|
||
const createTask = async ({ taskData, authorId, projectId }) => {
|
||
checkDB(db)
|
||
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
const projectFilterById = filterId(projectId)
|
||
|
||
const [projectExist] = await projectCollection.find(projectFilterById).toArray()
|
||
|
||
if (!projectExist) {
|
||
throw new Error('The project not exists [createTask]')
|
||
}
|
||
|
||
const nextIndex = projectExist.taskIndex + 1
|
||
|
||
const taskCollection = db.collection(PROJECT_TASKS_COLL)
|
||
|
||
const { type, status, ...taskRest } = taskData
|
||
|
||
const task = {
|
||
...taskRest,
|
||
type: Number(type),
|
||
status: Number(status),
|
||
changed: Date.now(),
|
||
created: Date.now(),
|
||
taskIndex: nextIndex,
|
||
authorId,
|
||
projectId,
|
||
}
|
||
|
||
await projectCollection.updateOne(projectFilterById, {
|
||
$set: {
|
||
taskIndex: nextIndex,
|
||
projectChanged: Date.now(),
|
||
},
|
||
})
|
||
|
||
await taskCollection.insertOne(task)
|
||
|
||
return _idToId(task)
|
||
}
|
||
|
||
const getTaskListByProjectId = async ({ projectId }) => {
|
||
checkDB(db)
|
||
|
||
const projectFilterById = filterId(projectId)
|
||
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
const [projectExist] = await projectCollection.find(projectId).toArray()
|
||
|
||
if (!projectExist) {
|
||
throw new Error('The project not exists [getTaskListByProjectId]')
|
||
}
|
||
|
||
const taskCollection = db.collection(PROJECT_TASKS_COLL)
|
||
let taskListCandidate = await taskCollection.find({
|
||
projectId,
|
||
}).toArray()
|
||
|
||
// if (taskListCandidate.length > 0) {
|
||
// for (let index = 0; index < taskListCandidate.length; index++) {
|
||
// // const [userAuthor] = await usersCollection.find(userFilterById).toArray()
|
||
// // taskListCandidate[index].author = userAuthor
|
||
// projectExist[index] = _idToId(projectExist[index])
|
||
// }
|
||
// }
|
||
|
||
taskListCandidate = _idToIdArray(taskListCandidate)
|
||
|
||
return taskListCandidate
|
||
}
|
||
|
||
const editTask = async ({ taskData, projectId, authorId, taskId }) => {
|
||
checkDB(db)
|
||
|
||
const taskCollection = db.collection(PROJECT_TASKS_COLL)
|
||
const projectCollection = db.collection(PROJECTS_COLL)
|
||
|
||
const taskFilterById = filterId(taskId)
|
||
const projectFilterById = filterId(projectId)
|
||
|
||
const { type, status, ...taskRest } = taskData
|
||
|
||
const updatedTask = await taskCollection.updateOne(taskFilterById, {
|
||
$set: {
|
||
type: Number(type),
|
||
status: Number(status),
|
||
...taskRest,
|
||
},
|
||
})
|
||
|
||
await projectCollection.updateOne(projectFilterById, {
|
||
$set: {
|
||
projectChanged: Date.now(),
|
||
},
|
||
})
|
||
|
||
return updatedTask
|
||
}
|
||
|
||
const deleteTaskById = async (taskId) => {
|
||
checkDB(db)
|
||
|
||
const taskCollection = db.collection(PROJECT_TASKS_COLL)
|
||
const taskFilterById = filterId(taskId)
|
||
const deleted = await taskCollection.deleteOne(taskFilterById)
|
||
return deleted
|
||
}
|
||
|
||
const getAllUsers = async () => {
|
||
checkDB(db)
|
||
|
||
const usersCollection = db.collection(USERS_COLL)
|
||
|
||
let allUsers = await usersCollection.find().toArray()
|
||
|
||
return _idToIdArray(allUsers)
|
||
}
|
||
|
||
// const getProjectMember = async () => {
|
||
// checkDB(db)
|
||
|
||
// const usersCollection = db.collection(USERS_COLL)
|
||
|
||
// let allUsers = await usersCollection.find().toArray()
|
||
|
||
// return _idToIdArray(allUsers)
|
||
// }
|
||
|
||
const updateProjectMembers = async (projectData, members) => {
|
||
checkDB(db)
|
||
|
||
const memberCollection = db.collection(PROJECT_MEMBERS_COLL)
|
||
|
||
await memberCollection.deleteMany({
|
||
projectId: projectData.id,
|
||
})
|
||
|
||
const membersAdd = []
|
||
|
||
for (let memberIndex = 0; memberIndex < members.length; memberIndex++) {
|
||
const member = {
|
||
projectId: projectData.id,
|
||
memberId: members[memberIndex].value,
|
||
}
|
||
membersAdd.push(member)
|
||
}
|
||
const { insertedData } = await memberCollection.insertMany(membersAdd)
|
||
|
||
return insertedData
|
||
}
|
||
|
||
module.exports = {
|
||
connect,
|
||
registrationUser,
|
||
signInUser,
|
||
getMyProjects,
|
||
deleteProjectById,
|
||
newProject,
|
||
createTask,
|
||
editTask,
|
||
deleteTaskById,
|
||
getTaskListByProjectId,
|
||
getProjectById,
|
||
getMyProjectById,
|
||
getTaskById,
|
||
updateProject,
|
||
|
||
getAllUsers,
|
||
|
||
updateProjectMembers,
|
||
}
|