Skip to content

Commit

Permalink
Add TPEN user to a Project (#130)
Browse files Browse the repository at this point in the history
* Development (#124)

* hot fix for dbTests

* Fixed the end to end and functionality tests (#98)

Co-authored-by: BhanuKandula5030 <[email protected]>

* WIP on issue  71-simple-getuserprofile-workflow (#74)

* Initialize Endpoints (#51)

* /manifest route prototype (#6) (#10)

* More set up for testing

* Now this is something worth bringing to the table to talk about.

* Now this is something worth bringing to the table to talk about.

* Hands up, no further until after stand up.  Make sure this is on a better looking track.

* Better organization.  Better notes and textual queues to what is going on.

* oo get that low hanging coverage

* test wording hint

* If I typed out this comment your would TLDR and move on so...here's some stuff.

* Fancy.  Tests are segregated and can be called individually or all together.

* Cleaning up

* cleanup getting ready for PR

* Documentation for sanity

Co-authored-by: Bryan Haberberger <[email protected]>

* WIP on issue 19 (#32)

* added initial code for issue19 page/id

* removed the test cases package in page/tests-not required now

* updated on the previous comments on issue

* WIP on Issue 21 (#33)

* Added the initial codebase to implement the GET/line/{lineid} and REST responses

* Added the Code Changes Documentation

* Delete Code Changes Documnetation.md

* Updated the code with the requested comments and added the end to end,exists and functionality test cases

* Added the Read me file , updated the code for the requested changes

---------

Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Bryan Haberberger <[email protected]>

* WIP on Issue 2 (#34)

* Initial commit on Issue #2, largely duplicating /manifest code to new /project directory

* /project sends local dummy JSON data

* Added tests to project directory

* Addressed comment on mockPause() in project.mjs

---------

Co-authored-by: Bryan Haberberger <[email protected]>

* Manifest endpoint cleanup (#47)

* clean it up!

* documentation

* documentation and cleanup

* documentation and cleanup

* big merge cleanup

---------

Co-authored-by: Patrick Cuba <[email protected]>
Co-authored-by: Sandeep Kumar Sutharapu <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>

* validating name

package name was invalid. Space and CAPS removed

* license hotfix

* WIP on issue 56-extend-page-web-api (#63)

* updated the code and written test cases initially failing

* updated the changes for the issue 56 Added all the changes that will mock the Database functionality for now If the db connection provided just need to connect

* added put route

* added few more test cases to check differnt query params conditions

* updated on the review comments

* removed ";"

* updated unit tests

* updated just for draft

* updating merge

* updating the userProfiles functionality defining its seperate package and tests with in

* updating on top of review comments

* updating the page code back to dev

* updating on the top of review comments

* updated and corrected

* updated the test cases

* removed semicollans

* roll back page to orginal

* Update index.mjs

* Update index.mjs

* Update page.mjs

* Update functionality_unit.test.mjs

* Update functionality_unit.test.mjs

* added based the filtration comments

---------

Co-authored-by: Bryan Haberberger <[email protected]>
Co-authored-by: Patrick Cuba <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>

* WIP on Issue #69 (#75)

* Slightly improved commenting clarity on respondWithProject()

* Very basic skeleton of /projects endpoint

* Added query param parsing for /projects, begun work on /projects tests

* Partial implementation of query params for /projects, mock data for /projects. Commented out /projects unit tests (not yet working)

* Resolved issue with authentication middleware implementation in /projects route

* /projects files now read environment variables

* commented out failing tests, added support for /projects hasRoles and exceptRoles queries

* Addressed some comments

* Query validation for /projects endpoint

* Addressed comments, fixed failing tests, and added lots more tests.

* weak getProjects() cleanup

The code works and is cleaner, but the sample projects are not ideal and it is tough to prove the filtering (which is incomplete anyway) works.

---------

Co-authored-by: Patrick Cuba <[email protected]>

* WIP on Issue 70 simple getuserprojects workflow (#73)

* Initialize Endpoints (#51)

* /manifest route prototype (#6) (#10)

* More set up for testing

* Now this is something worth bringing to the table to talk about.

* Now this is something worth bringing to the table to talk about.

* Hands up, no further until after stand up.  Make sure this is on a better looking track.

* Better organization.  Better notes and textual queues to what is going on.

* oo get that low hanging coverage

* test wording hint

* If I typed out this comment your would TLDR and move on so...here's some stuff.

* Fancy.  Tests are segregated and can be called individually or all together.

* Cleaning up

* cleanup getting ready for PR

* Documentation for sanity

Co-authored-by: Bryan Haberberger <[email protected]>

* WIP on issue 19 (#32)

* added initial code for issue19 page/id

* removed the test cases package in page/tests-not required now

* updated on the previous comments on issue

* WIP on Issue 21 (#33)

* Added the initial codebase to implement the GET/line/{lineid} and REST responses

* Added the Code Changes Documentation

* Delete Code Changes Documnetation.md

* Updated the code with the requested comments and added the end to end,exists and functionality test cases

* Added the Read me file , updated the code for the requested changes

---------

Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Bryan Haberberger <[email protected]>

* WIP on Issue 2 (#34)

* Initial commit on Issue #2, largely duplicating /manifest code to new /project directory

* /project sends local dummy JSON data

* Added tests to project directory

* Addressed comment on mockPause() in project.mjs

---------

Co-authored-by: Bryan Haberberger <[email protected]>

* Manifest endpoint cleanup (#47)

* clean it up!

* documentation

* documentation and cleanup

* documentation and cleanup

* big merge cleanup

---------

Co-authored-by: Patrick Cuba <[email protected]>
Co-authored-by: Sandeep Kumar Sutharapu <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>

* validating name

package name was invalid. Space and CAPS removed

* license hotfix

* WIP on issue 56-extend-page-web-api (#63)

* updated the code and written test cases initially failing

* updated the changes for the issue 56 Added all the changes that will mock the Database functionality for now If the db connection provided just need to connect

* added put route

* added few more test cases to check differnt query params conditions

* updated on the review comments

* removed ";"

* updated unit tests

* Slightly improved commenting clarity on respondWithProject()

* Integrated getUserProjects function into the project endpoint along with authenticateUser middleware for token validation. Updated response formatting and error handling, included dbController import, introduced getUserProjects function to fetch projects based on user ID, and modified findLineById to include a simulated database delay while returning line objects by ID

* Very basic skeleton of /projects endpoint

* Added query param parsing for /projects, begun work on /projects tests

* resolving merge

* resolving

* Partial implementation of query params for /projects, mock data for /projects. Commented out /projects unit tests (not yet working)

* Resolved issue with authentication middleware implementation in /projects route

* /projects files now read environment variables

* commented out failing tests, added support for /projects hasRoles and exceptRoles queries

* Updated the code cloned from development and added the services at get /project ,added the parameter handling,appllied filters ,returned as json ,surfaces the errors.

* Addressed some comments

* Query validation for /projects endpoint

* updated the code with requested changes , added the old code , updated the issue requirements

* Updated the code based on the requested changes ,added the documentation

* Addressed comments, fixed failing tests, and added lots more tests.

* weak getProjects() cleanup

The code works and is cleaner, but the sample projects are not ideal and it is tough to prove the filtering (which is incomplete anyway) works.

* moving tests to /projects

and combining with #69

* remove from /project

* skipping auth until auth is universal

---------

Co-authored-by: Bryan Haberberger <[email protected]>
Co-authored-by: Patrick Cuba <[email protected]>
Co-authored-by: Sandeep Kumar Sutharapu <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>
Co-authored-by: Sandeep Naidu <[email protected]>

* reserveId

tests passing

* upsidedown letter

* set variable timeout for tests (#100)

* set variable timeout for tests

* hot fix

* undiff to avoid conflicts

* undiff to avoid conflicts

---------

Co-authored-by: Bryan Haberberger <[email protected]>

* 101 isvalidid for db controller (#109)

* Initialize Endpoints (#51)

* /manifest route prototype (#6) (#10)

* More set up for testing

* Now this is something worth bringing to the table to talk about.

* Now this is something worth bringing to the table to talk about.

* Hands up, no further until after stand up.  Make sure this is on a better looking track.

* Better organization.  Better notes and textual queues to what is going on.

* oo get that low hanging coverage

* test wording hint

* If I typed out this comment your would TLDR and move on so...here's some stuff.

* Fancy.  Tests are segregated and can be called individually or all together.

* Cleaning up

* cleanup getting ready for PR

* Documentation for sanity

Co-authored-by: Bryan Haberberger <[email protected]>

* WIP on issue 19 (#32)

* added initial code for issue19 page/id

* removed the test cases package in page/tests-not required now

* updated on the previous comments on issue

* WIP on Issue 21 (#33)

* Added the initial codebase to implement the GET/line/{lineid} and REST responses

* Added the Code Changes Documentation

* Delete Code Changes Documnetation.md

* Updated the code with the requested comments and added the end to end,exists and functionality test cases

* Added the Read me file , updated the code for the requested changes

---------

Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Bryan Haberberger <[email protected]>

* WIP on Issue 2 (#34)

* Initial commit on Issue #2, largely duplicating /manifest code to new /project directory

* /project sends local dummy JSON data

* Added tests to project directory

* Addressed comment on mockPause() in project.mjs

---------

Co-authored-by: Bryan Haberberger <[email protected]>

* Manifest endpoint cleanup (#47)

* clean it up!

* documentation

* documentation and cleanup

* documentation and cleanup

* big merge cleanup

---------

Co-authored-by: Patrick Cuba <[email protected]>
Co-authored-by: Sandeep Kumar Sutharapu <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>

* validating name

package name was invalid. Space and CAPS removed

* license hotfix

* WIP on issue 56-extend-page-web-api (#63)

* updated the code and written test cases initially failing

* updated the changes for the issue 56 Added all the changes that will mock the Database functionality for now If the db connection provided just need to connect

* added put route

* added few more test cases to check differnt query params conditions

* updated on the review comments

* removed ";"

* updated unit tests

* Code fixes for passing tests (#99)

* hot fix for dbTests

* Fixed the end to end and functionality tests (#98)

Co-authored-by: BhanuKandula5030 <[email protected]>

---------

Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>

* hotfix to get this working.

Continue work on this branch

* tests in

these are useless but should break later correctly

* real validation

` expect(database.isValidId(123)).toBeTruthy()` is still false somehow

* import for validation

* https://youtu.be/tgGAHzvDyGU?si=4Gnih3pU6KipSMdZ

---------

Co-authored-by: Bryan Haberberger <[email protected]>
Co-authored-by: Sandeep Kumar Sutharapu <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>

* add changes from user class, skip mongo unit tests

* line:169 was saving a Promise

* only used once

* make sure its new for reasons

* unskip tests

* exact test

* Get me Wayne Brady

* from comments

* WIP on Issue #93 (#103)

* Added /project/create route and logic to add project to database

* Fixed bug that took way too long to diagnose. I hate programming

* Validations for some project keys

* More object validation in /project/create and some unit tests for the endpoint

* Useful comments

* Restructuring project/index.mjs

* Project endpoints now expect hexadecimal string id instead of numeric id

* Check for @type in new Project, new unit tests

* Fixed weird issue with tests and made slight fixes to other tests

* URL validation for "manifest" key of new Project

* helpful comment

* Implement database.isValidId()

* add private router for authenticated requests

* add agent to new user object

* unnested logic

* Private user routes (#116)

* add private router for authenticated requests

* add agent to new user object

* unnested logic

---------

Co-authored-by: Patrick Cuba <[email protected]>

* READONLY typo and node version

* adjust error

* move agent to where it is expected

* punt this test

* Update auth_unit_test.mjs

* Update auth_unit_test.mjs

* move auth application to specific route

* auth test

* match project creator with user agent

* add error handling to privateProfile

* Add error handling

* pass non-auth error onward as is

* 9 simplify cors (#117)

* Added common_cors.json file to put all reused CORS headers in one file

* Fixed missing import statement

* Updated common_cors.json import to include type assertion

* Added common_cors to more files that use the same CORS headers

* Undid mysterious package-lock change from previous commit

* clean up

* import project class

* create project from manifest

* add project class

* modify importProject to use Page and Project

* import project

* CATCH ERRORS

* reduce dependencies

* modify import pipeline

* noDiff

* private user routes (#118)

* move auth application to specific route

* auth test

* match project creator with user agent

* add error handling to privateProfile

* Add error handling

* pass non-auth error onward as is

* clean up

* Using the `getByID()` method

* combined methods

* getById

* collection default

* fix auto format

* test user class

* updated tests with mock data/methods

* test API existence

* add test cases

---------

Co-authored-by: cubap <[email protected]>

* clean up

* refactor check block

* restructure project; layers-pages-lines

* clean up

* cleanup

* skip tests that use TEST_TOKEN for now.

* Import projects route and tests (#121)

* add importProject route

* add member elements

* add class and api tests

* move import project from /projects to /project

* delete /projects directory and route

* create manifest from URL

* Update tests to suite new import project structure

* Hot fix

* add URL validation function

* User cleanup (#122)

* remove redundant file

* refactor error responder

* cleanup, rewrite /:id

* replace stubs with actual tests

* Project cleanup (#123)

* remove redundant file

* refactor error responder

* cleanup, rewrite /:id

* replace stubs with actual tests

* project cleanup -- Use Project class to create and get

* Authenticated /projects

* Authenticated /projects

* cleanup

* notify improper request methods

* add ProjectFactory

* add saveProject

* rewrite tests

* add findOne(), cleanup resp[0] occurrences]

* Skip Tests (#125)

* remove redundant file

* refactor error responder

* cleanup, rewrite /:id

* replace stubs with actual tests

* project cleanup -- Use Project class to create and get

* Authenticated /projects

* Authenticated /projects

* cleanup

* notify improper request methods

* add ProjectFactory

* add saveProject

* rewrite tests

* add findOne(), cleanup resp[0] occurrences]

* skip auth-dependent tests

* nodiff

* Update package-lock.json

* 126 error fixes (#127)

* skip auth-dependent tests

* error fix from issue 126

* add/fix test cases

* cleanup

* cleanup

* skip auth-dependent tests

* modify /project/:id test

* cleanup

---------

Co-authored-by: Bryan Haberberger <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Sandeep Kumar Sutharapu <[email protected]>
Co-authored-by: Patrick Cuba <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>
Co-authored-by: Sandeep Naidu <[email protected]>

* Add roles and permissions

* add existing TPEN user to TPEN project

* check user access for permissions to modify project members

* update access check

* add payload validation

* add non-existing TPEN user to project

* add non-TPEN user to project

* clean up

---------

Co-authored-by: Bryan Haberberger <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: BhanuKandula5030 <[email protected]>
Co-authored-by: Sandeep Kumar Sutharapu <[email protected]>
Co-authored-by: Patrick Cuba <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>
Co-authored-by: Leandru Martin <[email protected]>
Co-authored-by: Sandeep Naidu <[email protected]>
  • Loading branch information
9 people authored Aug 28, 2024
1 parent 77e7ffd commit 6ae5215
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 56 deletions.
157 changes: 135 additions & 22 deletions classes/Project/Project.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import dbDriver from "../../database/driver.mjs"
import Permissions from "../../project/groups/permissions.mjs"
import Roles from "../../project/groups/roles.mjs"
import {sendMail} from "../../utilities/mailer/index.mjs"
import {validateProjectPayload} from "../../utilities/validatePayload.mjs"

import {User} from "../User/User.mjs"
import crypto from "crypto"

const database = new dbDriver("mongo")

export default class Project {
Expand Down Expand Up @@ -45,55 +50,163 @@ export default class Project {
return database.remove(projectId)
}

checkUserAccess(userAgent) {
async addMember(email, rolesString) {
try {
let user = await User.getByEmail(email)
const roles = this.parseRoles(rolesString)
let updatedProject
let message = `You have been invited to the TPEN project ${this.projectData?.name}. View project <a href=https://www.tpen.org/project/${this.projectData._id}>here</a>.`

if (user) {
updatedProject = await this.inviteExistingTPENUser(user, roles)
} else {
let {newUser, projectData} = await this.inviteNewTPENUser(email, roles)
// We will replace this URL with the correct url
const url = `https://cubap.auth0.com/u/signup?invite-code=${newUser.inviteCode}`
updatedProject = projectData
user = newUser
message += `<p>Click the button below to get started with your project</p>
<button class = "buttonStyle" ><a href=${url} >Get Started</a> </button>
or copy the following link into your web browser <a href=${url}>${url}</a> </p>`
}

sendMail(user, `Invitation to ${this.projectData?.name}`, message)
return updatedProject
} catch (error) {
throw {
status: error.status || 500,
message: error.message || "An error occurred while adding the member."
}
}
}

checkUserAccess(userId) {
if (!this.projectData) {
return {
hasAccess: false,
message: "Project data is not loaded."
}
}

if (this.projectData.creator === userAgent) {
const isProjectOwner =
this.projectData.contributors[userId]?.roles?.includes("OWNER")

if (isProjectOwner) {
return {
hasAccess: true,
message: "User is the creator of the project and has access."
permissions: {
members: "MODIFY_ALL",
project: "MODIFY_ALL",
annotations: "MODIFY_ALL"
},
message: "User is the creator of the project and has full access."
}
}

if (!this.projectData.groups) {
if (!this.projectData.contributors) {
return {
hasAccess: false,
message: "Project structure is incomplete. Missing groups information."
message:
"Project structure is incomplete. Missing contributors information."
}
}

if (
!this.projectData.groups.members ||
this.projectData.groups.members.length === 0
) {
return {
hasAccess: false,
message: "Project has no members."
}
}
const permissions = this.projectData.contributors[userId]?.permissions

for (const member of this.projectData.groups.members) {
if (member.agent === userAgent) {
return {
return permissions
? {
hasAccess: true,
message: "User is a member of the project and has access."
permissions: permissions,
message: "User has access to the project"
}
: {
hasAccess: false,
message: "User is not a member of this project."
}
}

getCombinedPermissions(roles) {
const combinedPermissions = {
members: "NONE",
project: "NONE",
annotations: "NONE"
}

roles.forEach((role) => {
const rolePermissions = Permissions[role] || {}
Object.keys(rolePermissions).forEach((key) => {
combinedPermissions[key] = rolePermissions[key]
})
})

return combinedPermissions
}

parseRoles(rolesString) {
const roles = rolesString.toUpperCase().split(" ")

roles.forEach((role) => {
if (!Object.values(Roles).includes(role)) {
console.warn(`uUnrecognized role: ${role}. Update roles with appropraite permissions`)
}
})

return roles
}

async inviteExistingTPENUser(user, roles) {
this.projectData.contributors = this.projectData.contributors || {}
this.projectData.contributors[user._id] = {
displayName: user.displayName ?? user.nickname,
email: user?.email,
agent:
user.agent ??
user["http://store.rerum.io/agent"] ??
`https://store.rerum.io/v1/id/${user._id}`,
roles: roles,
permissions: this.getCombinedPermissions(roles)
}

return {
hasAccess: false,
message: "User has no access to this project."
return await database.update(this.projectData)
}

async inviteNewTPENUser(email, roles) {
const userPayload = {
inviteCode: Date.now(),
email
}
const userObj = new User()
const newUser = await userObj.create(userPayload)
newUser.agent = `https://store.rerum.io/v1/id/${newUser._id}`
newUser.inviteCode = this.#encryptInviteCode(newUser._id)

await userObj.updateRecord(newUser)

const projectData = await this.inviteExistingTPENUser(newUser, roles)

return {newUser, projectData}
}

#encryptInviteCode(userId) {
const date = Date.now().toString()
const data = `${date}:${userId}`

const iv = Buffer.from(process.env.INVITE_CODE_IV, "hex")
const secretKey = Buffer.from(process.env.INVITE_CODE_SECRET, "hex")

const cipher = crypto.createCipheriv("aes-256-cbc", secretKey, iv)

let encrypted = cipher.update(data)
encrypted = Buffer.concat([encrypted, cipher.final()])

return iv.toString("hex") + ":" + encrypted.toString("hex")
}

async #getById(projectId) {
return database.getById(projectId, "Project").then((resp) => {
this.projectData = resp
})
}


}
26 changes: 25 additions & 1 deletion classes/User/User.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import dbDriver from "../../database/driver.mjs"
import {includeOnly} from "../../utilities/removeProperties.mjs"
import Roles from "../../project/groups/roles.mjs"
import Permissions from "../../project/groups/permissions.mjs"

const database = new dbDriver("mongo")
export class User {
Expand Down Expand Up @@ -60,7 +62,7 @@ export class User {
}
}

const previousUser = await this.getSelf()
const previousUser = await this.getSelf(data._id)
const newRecord = {...previousUser, ...data}

return database
Expand Down Expand Up @@ -99,7 +101,29 @@ export class User {
throw err
})
}
static async getByEmail(email){
if (!email) {
throw {
status: 400,
message: "No email provided"
}
}

return database
.findOne({
email,
"@type": "User"
})
.then((resp) => {
if (resp instanceof Error) {
throw resp
}
return resp
})
.catch((err) => {
throw err
})
}
async create(data) {
// POST requests
if (!data) {
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

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

26 changes: 26 additions & 0 deletions project/groups/permissions.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Roles from "./roles.mjs"

const Permissions = {
[Roles.OWNER]: {
members: "MODIFY_ALL",
project: "MODIFY_ALL",
annotations: "MODIFY_ALL"
},
[Roles.LEADER]: {
members: "MODIFY_ALL",
project: "MODIFY_PAGES ADD_COLLECTIONS",
annotations: "MODIFY_ALL"
},
[Roles.CONTRIBUTOR]: {
members: "NONE",
project: "MODIFY_PAGES ADD_COLLECTIONS",
annotations: "MODIFY_ALL"
},
[Roles.VIEWER]: {
members: "NONE",
project: "READ_ONLY",
annotations: "READ_ONLY"
}
}

export default Permissions
10 changes: 10 additions & 0 deletions project/groups/roles.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const Roles = {
OWNER: 'OWNER',
LEADER: 'LEADER',
CONTRIBUTOR: 'CONTRIBUTOR',
VIEWER: 'VIEWER',
INSTRUCTOR: 'INSTRUCTOR',
STUDENT: 'STUDENT',
};

export default Roles;
80 changes: 64 additions & 16 deletions project/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import validateURL from "../utilities/validateURL.mjs"
import Project from "../classes/Project/Project.mjs"
import {User} from "../classes/User/User.mjs"
import getHash from "../utilities/getHash.mjs"
import {isValidEmail} from "../utilities/validateEmail.mjs"

const database = new DatabaseDriver("mongo")
let router = express.Router()
Expand Down Expand Up @@ -111,22 +112,30 @@ router
(async () => {
try {
const projectObj = await new Project(id)
const project = projectObj.projectData
const accessCheck = projectObj.checkUserAccess(user.agent);
if (!project) {
return respondWithError(
res,
404,
`No TPEN3 project with ID '${id}' found`
)
} else if (!accessCheck.hasAccess) {
return respondWithError(
res,
401,
accessCheck.message
)
}
return res.status(200).json(project)
const project = projectObj.projectData
const accessInfo = projectObj.checkUserAccess(user._id)
if (!project) {
return respondWithError(
res,
404,
`No TPEN3 project with ID '${id}' found`
)
} else if (!accessInfo.hasAccess) {
return respondWithError(res, 401, accessInfo.message)
}
const userPermissions = accessInfo.permissions
const errorMessage = "User has no required access for this action"

if (
userPermissions["project"] &&
userPermissions["project"].toUpperCase() !== "NONE"
) {
res.status(200).json(project)
} else {
respondWithError(res, 403, errorMessage)
}


} catch (error) {
return respondWithError(
res,
Expand All @@ -141,6 +150,45 @@ router
respondWithError(res, 405, "Improper request method. Use GET instead")
})

router
.route("/:id/invite-member")
.post(auth0Middleware(), async (req, res) => {
const user = req.user
const {id: projectId} = req.params
const {email, roles} = req.body

if (!user) {
return respondWithError(res, 401, "Unauthenticated request")
} else if (!email || !roles) {
return respondWithError(
res,
400,
"Invitee's email and role(s) are required"
)
} else if (!isValidEmail(email)) {
return respondWithError(res, 400, "Invitee email is invalid")
}

try {
const project = await new Project(projectId)
const accessInfo = project.checkUserAccess(user._id)

if (
accessInfo.hasAccess &&
accessInfo.permissions["members"].includes("MODIFY_ALL")
) {
const response = await project.addMember(email, roles)
res.status(200).json(response)
} else {
res
.status(403)
.send("You have no permissions to modify members of this project")
}
} catch (error) {
res.status(error.status || 500).send(error.message.toString())
}
})

router.all((req, res) => {
respondWithError(res, 405, "Improper request method. Use POST instead")
})
Expand Down
Loading

0 comments on commit 6ae5215

Please sign in to comment.