Skip to content

Commit

Permalink
strenghten logics security b00tc4mp#427, add new Permission Error b00…
Browse files Browse the repository at this point in the history
  • Loading branch information
pankelix committed Feb 29, 2024
1 parent cb8720f commit 6f6fb5b
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 54 deletions.
9 changes: 2 additions & 7 deletions staff/miguel-arias/project/api/handlers/assignTaskHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,10 @@ export default async (req, res) => {
const payload = jwt.verify(token, process.env.JWT_SECRET)
const sessionProfileId = payload.sub

const { profileId, taskId } = req.body

let realProfileId = profileId

if (profileId === null)
realProfileId = sessionProfileId
const { taskId, profileId } = req.params

try {
await logic.assignTask(taskId, realProfileId)
await logic.assignTask(sessionProfileId, taskId, profileId)
} catch (error) {
let status = 500

Expand Down
19 changes: 10 additions & 9 deletions staff/miguel-arias/project/api/handlers/delayTaskHandler.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
/* import jwt from 'jsonwebtoken'
const { JsonWebTokenError } = jwt */
import jwt from 'jsonwebtoken'

import { errors } from 'com'
const { NotFoundError, ContentError/* , TokenError */ } = errors
const { NotFoundError, ContentError, TokenError } = errors

import logic from '../logic/index.js'

export default async (req, res) => {
/* const token = req.headers.authorization.substring(7)
const token = req.headers.authorization.substring(7)
const payload = jwt.verify(token, process.env.JWT_SECRET)
const sessionProfileId = payload.sub */
const profileId = payload.sub

const { taskId, date } = req.body
const { date } = req.body

const { taskId } = req.params

try {
await logic.delayTask(taskId, date)
await logic.delayTask(profileId, taskId, date)
} catch (error) {
let status = 500

/* if (error instanceof JsonWebTokenError) {
if (error instanceof JsonWebTokenError) {
status = 401
error = new TokenError(error.message)
} */
}

if (error instanceof NotFoundError)
status = 404
Expand Down
4 changes: 2 additions & 2 deletions staff/miguel-arias/project/api/handlers/deleteTaskHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import logic from '../logic/index.js'
const { NotFoundError, ContentError, TokenError } = errors

export default async (req, res) => {
const { taskId } = req.body

const token = req.headers.authorization.substring(7)
const payload = jwt.verify(token, process.env.JWT_SECRET)
const profileId = payload.sub

const { taskId } = req.params

try {
await logic.deleteTask(profileId, taskId)
} catch (error) {
Expand Down
8 changes: 4 additions & 4 deletions staff/miguel-arias/project/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ mongoose.connect(process.env.MONGODB_URL)

server.post('/tasks', jsonBodyParser, createTaskHandler)

server.patch('/tasks', jsonBodyParser, assignTaskHandler)
server.patch('/tasks/:taskId/assign/:profileId', assignTaskHandler)

server.patch('/tasks/delay', jsonBodyParser, delayTaskHandler)
server.patch('/tasks/:taskId/delay', jsonBodyParser, delayTaskHandler)

server.post('/tasks/delete', jsonBodyParser, deleteTaskHandler)
server.post('/tasks/:taskId/delete', deleteTaskHandler)

server.get('/tasks', retrieveTasksHandler)

server.get('/profiles', retrieveProfilesHandler)

server.get('/profiles/role', retrieveRoleHandler)
server.get('/profiles/:profileId/role', retrieveRoleHandler)

server.get('/templates', retrieveTemplatesHandler)

Expand Down
14 changes: 11 additions & 3 deletions staff/miguel-arias/project/api/logic/assignTask.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { validate, errors } from 'com'
const { SystemError, NotFoundError } = errors
const { SystemError, NotFoundError, PermissionError } = errors

import { Task, Profile } from '../data/models.js'

function assignTask(taskId, profileId) {
function assignTask(sessionProfileId, taskId, profileId) {
validate.id(sessionProfileId, 'session profile id')
validate.id(taskId, 'task id')
validate.id(profileId, 'profile id')

Expand All @@ -19,6 +20,10 @@ function assignTask(taskId, profileId) {
throw new NotFoundError('task not found')

let profile

if (profileId === null)
profile = sessionProfileId

try {
profile = await Profile.findById(profileId).lean()
} catch (error) {
Expand All @@ -28,7 +33,10 @@ function assignTask(taskId, profileId) {
if (!profile)
throw new NotFoundError('profile not found')

task.assignee = profileId
if (profile.role !== 'admin')
throw new PermissionError('profile is not admin')

task.assignee = profileId

try {
await task.save()
Expand Down
4 changes: 2 additions & 2 deletions staff/miguel-arias/project/api/logic/completeTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ function completeTask(profileId, taskId, pincode, date) {
if (!profile)
throw new NotFoundError('profile not found')

if (!profile.role !== 'admin')
throw new CredentialsError('this profile is not admin')
if (profile.role !== 'admin')
throw new CredentialsError('profile is not admin')

let match
try {
Expand Down
5 changes: 2 additions & 3 deletions staff/miguel-arias/project/api/logic/createTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ const { SystemError, NotFoundError } = errors

import { Task, Home } from '../data/models.js'

function createTask(homeId, templateId, date/*, assigneeId */) {
function createTask(homeId, templateId, date) {
validate.id(homeId, 'home id')
validate.id(templateId, 'template id')
/* validate.id(assigneeId, 'assignee id') */

return (async () => {
let home
Expand All @@ -20,7 +19,7 @@ function createTask(homeId, templateId, date/*, assigneeId */) {
throw new NotFoundError('home not found')

try {
const task = await Task.create({ home: homeId, template: templateId, date: date/*, assignee: assigneeId */ })
const task = await Task.create({ home: homeId, template: templateId, date: date })

return task
} catch (error) {
Expand Down
15 changes: 13 additions & 2 deletions staff/miguel-arias/project/api/logic/delayTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@ const { SystemError, NotFoundError } = errors

import { Task } from '../data/models.js'

function assignTask(taskId, date) {
function delayTask(profileId, taskId, date) {
validate.id(profileId, 'profile id')
validate.id(taskId, 'task id')

return (async () => {
let profile
try {
profile = await Profile.findById(profileId).lean()
} catch (error) {
throw new SystemError(error.message)
}

if (!profile)
throw new NotFoundError('profile not found')

let task
try {
task = await Task.findById(taskId)
Expand All @@ -27,4 +38,4 @@ function assignTask(taskId, date) {
})()
}

export default assignTask
export default delayTask
5 changes: 4 additions & 1 deletion staff/miguel-arias/project/api/logic/deleteTask.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Profile, Task } from '../data/models.js'
import { validate, errors } from 'com'
const { SystemError, NotFoundError } = errors
const { SystemError, NotFoundError, PermissionError } = errors

function deleteTask(profileId, taskId) {
validate.id(profileId, 'profile id')
Expand All @@ -17,6 +17,9 @@ function deleteTask(profileId, taskId) {
if (!profile)
throw new NotFoundError('profile not found')

if (profile.role !== 'admin')
throw new PermissionError('profile is not admin')

let task
try {
task = await Task.findById(taskId)
Expand Down
16 changes: 8 additions & 8 deletions staff/miguel-arias/project/app/src/components/Calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,20 @@ function Calendar(props) {
}
}

const handleAssignThisTask = async (taskId, profileId) => {
const handleAssignThisTaskTo = () => {
setView('assign-task-view')
}

const handleAssignThisTask = async (profileId) => {
try {
await logic.assignTask(taskId, profileId)
await logic.assignTask(task.id, profileId)
refreshTasks()
setView(null)
} catch (error) {
context.handleError(error)
}
}

const handleAssignThisTaskTo = () => {
setView('assign-task-view')
}

const handleDelayTaskClick = () => {
setView('delay-task-view')
}
Expand Down Expand Up @@ -176,7 +176,7 @@ function Calendar(props) {
{<h3>{helper.arrangeText(task.template.name)}</h3>}
{<h3>{helper.arrangeDate(task.date)}</h3>}
<h3>{profiles.map(profile => profile.id === task.assignee ? profile.name : '')}</h3>
{role !== null && <Button onClick={() => handleAssignThisTask(task, null)}>Take this task</Button>}
{role !== null && <Button onClick={() => handleAssignThisTask(null)}>Take this task</Button>}
{role === 'admin' && <Button onClick={handleAssignThisTaskTo}>Assign this task to...</Button>}
{role !== null && <Button onClick={handleCompleteTaskClick}>Complete this task</Button>}
{role !== null && <Button onClick={handleDelayTaskClick}>Delay this task</Button>}
Expand All @@ -185,7 +185,7 @@ function Calendar(props) {
</Container>}

{view === 'assign-task-view' && <Container>
{profiles.map(profile => <Button onClick={() => handleAssignThisTask(task, profile.id)}>{profile.name}</Button>)}
{profiles.map(profile => <Button onClick={() => handleAssignThisTask(profile.id)}>{profile.name}</Button>)}
</Container>}

{view === 'pin-code-view' && <Container>
Expand Down
5 changes: 2 additions & 3 deletions staff/miguel-arias/project/app/src/logic/assignTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ const assignTask = (taskId, profileId) => {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${session.profileToken}`
},
body: JSON.stringify({ taskId, profileId })
}
}

return (async () => {
let res
try {
res = await fetch(`${import.meta.env.VITE_API_URL}/tasks`, req)
res = await fetch(`${import.meta.env.VITE_API_URL}/tasks/${taskId}/assign/${profileId}`, req)
} catch (error) {
throw new SystemError(error.message)
}
Expand Down
8 changes: 4 additions & 4 deletions staff/miguel-arias/project/app/src/logic/delayTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ const { SystemError } = errors

import session from './session'

const delayTask = (taskId, date) => {
const delayTask = (date) => {
validate.id(taskId, 'task id')
validate.date(date)

const req = {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
/* Authorization: `Bearer ${session.profileToken}` */
Authorization: `Bearer ${session.profileToken}`
},
body: JSON.stringify({ taskId, date })
body: JSON.stringify({ date })
}

return (async () => {
let res
try {
res = await fetch(`${import.meta.env.VITE_API_URL}/tasks/delay`, req)
res = await fetch(`${import.meta.env.VITE_API_URL}/tasks/${taskId}/delay`, req)
} catch (error) {
throw new SystemError(error.message)
}
Expand Down
5 changes: 2 additions & 3 deletions staff/miguel-arias/project/app/src/logic/deleteTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ const deleteTask = (taskId) => {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${session.profileToken}`
},
body: JSON.stringify({ taskId })
}
}

return (async () => {
let res
try {
res = await fetch(`${import.meta.env.VITE_API_URL}/tasks/delete`, req)
res = await fetch(`${import.meta.env.VITE_API_URL}/tasks/${taskId}/delete`, req)
} catch (error) {
throw new SystemError(error.message)
}
Expand Down
2 changes: 1 addition & 1 deletion staff/miguel-arias/project/app/src/logic/retrieveRole.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const retrieveRole = () => {
return (async () => {
let res
try {
res = await fetch(`${import.meta.env.VITE_API_URL}/profiles/role`, req)
res = await fetch(`${import.meta.env.VITE_API_URL}/profiles/${session.profileId}/role`, req)
} catch (error) {
throw new SystemError(error.message)
}
Expand Down
14 changes: 12 additions & 2 deletions staff/miguel-arias/project/com/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ class TokenError extends Error {
}
}

class PermissionError extends Error {
constructor(message) {
super(message)

this.name = this.constructor.name
}
}

// 404
class NotFoundError extends Error {
constructor(message) {
Expand Down Expand Up @@ -66,7 +74,8 @@ export {
ContentError,
DuplicityError,
SystemError,
TypeError
TypeError,
PermissionError
}

const errors = {
Expand All @@ -76,7 +85,8 @@ const errors = {
ContentError,
DuplicityError,
SystemError,
TypeError
TypeError,
PermissionError
}

export default errors

0 comments on commit 6f6fb5b

Please sign in to comment.