From 3278c4f3c2db78610396c63b369c6ee47e58c5f3 Mon Sep 17 00:00:00 2001 From: "Jessica Ann Williams (Williams)" Date: Fri, 6 Jan 2023 19:23:01 -0500 Subject: [PATCH 1/4] deleted instances of okta auth and cleaned up with prettier --- api/calendarEvents/calendarEventsRouter.js | 34 ++++---- api/children/childrenRouter.js | 26 ++---- api/classroom/classroomRouter.js | 44 +++++----- api/courses/coursesRouter.js | 35 ++++---- api/dsService/dsRouter.js | 5 +- api/inbox/inboxRouter.js | 11 ++- api/instructor/instructorRouter.js | 21 ++--- temp.js => api/middleware/auth0Middleware.js | 0 api/middleware/authRequired.js | 88 ++++++++++---------- api/newsfeed/newsfeedRouter.js | 12 +-- api/parent/parentRouter.js | 9 +- api/profile/profileRouter.js | 20 ++--- api/programs/programTypesRouter.js | 29 +++---- api/user/userRouter.js | 8 +- config/okta.js | 20 ++--- lib/oktaClient.js | 12 +-- package-lock.json | 33 ++++++++ package.json | 1 + server.js | 34 +++++++- 19 files changed, 228 insertions(+), 214 deletions(-) rename temp.js => api/middleware/auth0Middleware.js (100%) diff --git a/api/calendarEvents/calendarEventsRouter.js b/api/calendarEvents/calendarEventsRouter.js index 5056e7dd..0e23d950 100644 --- a/api/calendarEvents/calendarEventsRouter.js +++ b/api/calendarEvents/calendarEventsRouter.js @@ -1,5 +1,5 @@ const router = require('express').Router(); -const authRequired = require('../middleware/authRequired'); + const { checkCalendarEventExists, validateCalendarEvent, @@ -7,7 +7,7 @@ const { const CalendarEvents = require('./calendarEventsModel'); -router.get('/', authRequired, (req, res, next) => { +router.get('/', (req, res, next) => { CalendarEvents.getAllCalendarEvents() .then((events) => { res.status(200).json(events); @@ -15,7 +15,7 @@ router.get('/', authRequired, (req, res, next) => { .catch(next); }); -router.get('/user', authRequired, (req, res, next) => { +router.get('/user', (req, res, next) => { CalendarEvents.getCalendarEventsByProfileId(req.profile.profile_id) .then((events) => { res.status(200).json({ @@ -26,11 +26,11 @@ router.get('/user', authRequired, (req, res, next) => { .catch(next); }); -router.get('/:event_id', authRequired, checkCalendarEventExists, (req, res) => { +router.get('/:event_id', checkCalendarEventExists, (req, res) => { res.status(200).json(req.calendarEvent); }); -router.post('/', authRequired, validateCalendarEvent, (req, res, next) => { +router.post('/', validateCalendarEvent, (req, res, next) => { CalendarEvents.addCalendarEvent(req.validatedCalendarEvent) .then((newEvent) => { res.status(201).json({ @@ -43,7 +43,6 @@ router.post('/', authRequired, validateCalendarEvent, (req, res, next) => { router.put( '/:event_id', - authRequired, checkCalendarEventExists, validateCalendarEvent, (req, res, next) => { @@ -61,19 +60,14 @@ router.put( } ); -router.delete( - '/:event_id', - authRequired, - checkCalendarEventExists, - (req, res, next) => { - CalendarEvents.delCalendarEventById(req.params.event_id) - .then( - res.json({ - message: 'Calendar Event sucessfully deleted', - }) - ) - .catch(next); - } -); +router.delete('/:event_id', checkCalendarEventExists, (req, res, next) => { + CalendarEvents.delCalendarEventById(req.params.event_id) + .then( + res.json({ + message: 'Calendar Event sucessfully deleted', + }) + ) + .catch(next); +}); module.exports = router; diff --git a/api/children/childrenRouter.js b/api/children/childrenRouter.js index 6911a3c8..fb3d7e68 100644 --- a/api/children/childrenRouter.js +++ b/api/children/childrenRouter.js @@ -1,6 +1,6 @@ const express = require('express'); const Children = require('./childrenModel'); -const authRequired = require('../middleware/authRequired'); + const { roleAuthenticationParent, } = require('../middleware/roleAuthentication'); @@ -13,7 +13,7 @@ const { const router = express.Router(); -router.get('/', authRequired, function (req, res) { +router.get('/', function (req, res) { Children.getChildren() .then((child) => { res.status(200).json(child); @@ -25,7 +25,6 @@ router.get('/', authRequired, function (req, res) { router.post( '/', - authRequired, roleAuthenticationParent, checkChildObject, async function (req, res, next) { @@ -39,22 +38,16 @@ router.post( } ); -router.get( - '/:child_id', - authRequired, - checkChildExist, - async function (req, res, next) { - try { - res.status(200).json(req.child); - } catch (error) { - next(error); - } +router.get('/:child_id', checkChildExist, async function (req, res, next) { + try { + res.status(200).json(req.child); + } catch (error) { + next(error); } -); +}); router.put( '/:child_id', - authRequired, roleAuthenticationParent, checkChildExist, isChildParent, @@ -71,7 +64,6 @@ router.put( router.delete( '/:child_id', - authRequired, roleAuthenticationParent, checkChildExist, isChildParent, @@ -90,7 +82,6 @@ router.delete( // middleware for enrollments ready to implement checkChildExist2, checkIfCourseExist, checkChildAge, checkCourseSize router.get( '/:id/enrollments', - authRequired, checkChildExist, async function (req, res, next) { try { @@ -106,7 +97,6 @@ router.get( // middleware for enrollments ready to implement checkChildExist2, checkIfCourseExist, checkChildAge, checkCourseSize router.post( '/:id/enrollments', - authRequired, checkChildExist, isChildAlreadyEnrolled, async (req, res) => { diff --git a/api/classroom/classroomRouter.js b/api/classroom/classroomRouter.js index 9b052d30..1d964765 100644 --- a/api/classroom/classroomRouter.js +++ b/api/classroom/classroomRouter.js @@ -1,9 +1,9 @@ const express = require('express'); -const authRequired = require('../middleware/authRequired'); + const Classroom = require('./classroomModel'); const router = express.Router(); -router.get('/students/:course_id', authRequired, function (req, res) { +router.get('/students/:course_id', function (req, res) { const course_id = parseInt(req.params.course_id); Classroom.getStudentsByClassId(course_id) .then((students) => { @@ -14,7 +14,7 @@ router.get('/students/:course_id', authRequired, function (req, res) { }); }); -router.get('/badges', authRequired, function (req, res, next) { +router.get('/badges', function (req, res, next) { Classroom.getBadges() .then((badges) => { res.status(200).json(badges); @@ -22,7 +22,7 @@ router.get('/badges', authRequired, function (req, res, next) { .catch(next); }); -router.get('/badges/:child_id', authRequired, function (req, res, next) { +router.get('/badges/:child_id', function (req, res, next) { const child_id = parseInt(req.params.child_id); Classroom.getBadgesByChildId(child_id) .then((badges) => { @@ -31,7 +31,7 @@ router.get('/badges/:child_id', authRequired, function (req, res, next) { .catch(next); }); -router.post('/assign', authRequired, function (req, res, next) { +router.post('/assign', function (req, res, next) { const child_id = req.body.child_id; const badge_id = req.body.badge_id; Classroom.assignBadgeByIds({ child_id, badge_id }) @@ -41,26 +41,22 @@ router.post('/assign', authRequired, function (req, res, next) { .catch(next); }); -router.delete( - '/remove/:badge_id/:child_id', - authRequired, - async function (req, res, next) { - const child_id = parseInt(req.params.child_id); - const badge_id = parseInt(req.params.badge_id); - const student_badge_id = await Classroom.getStudentBadgeId( - badge_id, - child_id - ); - try { - Classroom.removeBadge(student_badge_id[0].student_badge_id).then(() => { - res.status(200).json({ - message: 'Student badge removed', - }); +router.delete('/remove/:badge_id/:child_id', async function (req, res, next) { + const child_id = parseInt(req.params.child_id); + const badge_id = parseInt(req.params.badge_id); + const student_badge_id = await Classroom.getStudentBadgeId( + badge_id, + child_id + ); + try { + Classroom.removeBadge(student_badge_id[0].student_badge_id).then(() => { + res.status(200).json({ + message: 'Student badge removed', }); - } catch (err) { - next(err); - } + }); + } catch (err) { + next(err); } -); +}); module.exports = router; diff --git a/api/courses/coursesRouter.js b/api/courses/coursesRouter.js index a66c8348..2344607d 100644 --- a/api/courses/coursesRouter.js +++ b/api/courses/coursesRouter.js @@ -1,5 +1,5 @@ const express = require('express'); -const authRequired = require('../middleware/authRequired'); + // const ownerAuthorization = require('../middleware/ownerAuthorization'); needs to be refactored const { roleAuthenticationInstructor, @@ -157,7 +157,7 @@ const { * $ref: '#/components/responses/UnauthorizedError' */ -router.get('/', authRequired, function (req, res, next) { +router.get('/', function (req, res, next) { Courses.getAllCourses() .then((scheduleList) => { res.status(200).json(scheduleList); @@ -225,11 +225,11 @@ router.get('/', authRequired, function (req, res, next) { * description: 'Course Instance with id {course_id} does not exist' */ -router.get('/:course_id', authRequired, checkCourseExists, (req, res) => { +router.get('/:course_id', checkCourseExists, (req, res) => { res.status(200).json(req.course); }); -router.get('/students/:course_id', authRequired, function (req, res, next) { +router.get('/students/:course_id', function (req, res, next) { Courses.getStudentsById() .then((students) => { res.status(200).json(students); @@ -306,7 +306,6 @@ router.get('/students/:course_id', authRequired, function (req, res, next) { router.post( '/', - authRequired, roleAuthenticationInstructor, validateCourseObject, checkInstructorExists, @@ -404,7 +403,6 @@ router.put( '/:course_id', validateCourseObject, checkInstructorExists, - authRequired, checkCourseExists, (req, res, next) => { const course_id = parseInt(req.params.course_id); @@ -452,22 +450,17 @@ router.put( * example: Course instances with id:'${course_id}' was deleted */ -router.delete( - '/:course_id', - authRequired, - checkCourseExists, - (req, res, next) => { - const course_id = parseInt(req.params.course_id); - try { - Courses.removeCourse(course_id).then(() => { - res.status(200).json({ - message: `Course instance with id:'${course_id}' was deleted.`, - }); +router.delete('/:course_id', checkCourseExists, (req, res, next) => { + const course_id = parseInt(req.params.course_id); + try { + Courses.removeCourse(course_id).then(() => { + res.status(200).json({ + message: `Course instance with id:'${course_id}' was deleted.`, }); - } catch (err) { - next(err); - } + }); + } catch (err) { + next(err); } -); +}); module.exports = router; diff --git a/api/dsService/dsRouter.js b/api/dsService/dsRouter.js index 0616f1dc..52acf5d7 100644 --- a/api/dsService/dsRouter.js +++ b/api/dsService/dsRouter.js @@ -1,7 +1,6 @@ const express = require('express'); const router = express.Router(); const dsModel = require('./dsModel'); -const authRequired = require('../middleware/authRequired'); /** * @swagger @@ -60,7 +59,7 @@ const authRequired = require('../middleware/authRequired'); * 500: * description: 'Error making prediction' */ -router.get('/predict/:x1/:x2/:3', authRequired, function (req, res) { +router.get('/predict/:x1/:x2/:3', function (req, res) { const x1 = String(req.params.x1); const x2 = String(req.params.x2); const x3 = String(req.params.x3); @@ -103,7 +102,7 @@ router.get('/predict/:x1/:x2/:3', authRequired, function (req, res) { * 500: * description: 'Error making prediction' */ -router.get('/viz/:state', authRequired, function (req, res) { +router.get('/viz/:state', function (req, res) { const state = String(req.params.state); dsModel diff --git a/api/inbox/inboxRouter.js b/api/inbox/inboxRouter.js index 11007a2a..64a029b5 100644 --- a/api/inbox/inboxRouter.js +++ b/api/inbox/inboxRouter.js @@ -1,9 +1,8 @@ const express = require('express'); const Inboxes = require('./inboxModel'); const router = express.Router(); -const authRequired = require('../middleware/authRequired'); -router.get('/', authRequired, function (req, res) { +router.get('/', function (req, res) { Inboxes.getConversations() .then((conversation) => { res.status(200).json(conversation); @@ -14,7 +13,7 @@ router.get('/', authRequired, function (req, res) { }); }); -router.get('/:conversation_id', authRequired, function (req, res) { +router.get('/:conversation_id', function (req, res) { Inboxes.findByConversationId(req.params.conversation_id) .then((conversation) => { if (conversation.length) { @@ -45,7 +44,7 @@ router.post('/', async (req, res) => { }); }); -router.post('/messages', authRequired, async (req, res) => { +router.post('/messages', async (req, res) => { Inboxes.addMessage(req.body) .then((message) => { if (!req.body) { @@ -63,7 +62,7 @@ router.post('/messages', authRequired, async (req, res) => { }); }); -router.put('/:messages_id', authRequired, (req, res) => { +router.put('/:messages_id', (req, res) => { if (!req.body.title) { res.status(200).json({ message: 'title is required' }); } else if (!req.body.message) { @@ -98,7 +97,7 @@ router.put('/:messages_id', authRequired, (req, res) => { } }); -router.delete('/:conversation_id', authRequired, (req, res) => { +router.delete('/:conversation_id', (req, res) => { Inboxes.removeConversation(req.params.conversation_id) .then((conversation) => { if (conversation) { diff --git a/api/instructor/instructorRouter.js b/api/instructor/instructorRouter.js index 1e4db16a..a9cf251e 100644 --- a/api/instructor/instructorRouter.js +++ b/api/instructor/instructorRouter.js @@ -1,5 +1,5 @@ const express = require('express'); -const authRequired = require('../middleware/authRequired'); + const Instructors = require('./instructorModel'); const router = express.Router(); const Profiles = require('../profile/profileModel'); @@ -41,7 +41,7 @@ router.post('/register', (req, res) => { }); }); -router.get('/courses', authRequired, getInstructorId, (req, res, next) => { +router.get('/courses', getInstructorId, (req, res, next) => { Instructors.findInstructorCourses(req.instructor_id) .then((courses) => { if (courses) { @@ -53,18 +53,13 @@ router.get('/courses', authRequired, getInstructorId, (req, res, next) => { .catch(next); }); -router.get( - '/:instructor_id', - authRequired, - checkInstructorExist, - (req, res) => { - if (req.instructor) { - res.status(200).json(req.instructor); - } else { - res.status(404).json({ error: 'Instructor not found.' }); - } +router.get('/:instructor_id', checkInstructorExist, (req, res) => { + if (req.instructor) { + res.status(200).json(req.instructor); + } else { + res.status(404).json({ error: 'Instructor not found.' }); } -); +}); router.use('*', errorhandler); //eslint-disable-next-line diff --git a/temp.js b/api/middleware/auth0Middleware.js similarity index 100% rename from temp.js rename to api/middleware/auth0Middleware.js diff --git a/api/middleware/authRequired.js b/api/middleware/authRequired.js index 596bfcae..a3d210cc 100644 --- a/api/middleware/authRequired.js +++ b/api/middleware/authRequired.js @@ -1,48 +1,48 @@ -const createError = require('http-errors'); -const OktaJwtVerifier = require('@okta/jwt-verifier'); -const oktaVerifierConfig = require('../../config/okta'); -const Profiles = require('../profile/profileModel'); -const oktaJwtVerifier = new OktaJwtVerifier(oktaVerifierConfig.config); +// const createError = require('http-errors'); +// const OktaJwtVerifier = require('@okta/jwt-verifier'); +// const oktaVerifierConfig = require('../../config/okta'); +// const Profiles = require('../profile/profileModel'); +// const oktaJwtVerifier = new OktaJwtVerifier(oktaVerifierConfig.config); -const makeProfileObj = (claims) => { - return { - okta_id: claims.sub, - email: claims.email, - name: claims.name, - }; -}; -/** - * A simple middleware that asserts valid Okta idToken and sends 401 responses - * if the token is not present or fails validation. If the token is valid its - * contents are attached to req.profile - */ -const authRequired = async (req, res, next) => { - try { - const authHeader = req.headers.authorization || ''; - const match = authHeader.match(/Bearer (.+)/); +// const makeProfileObj = (claims) => { +// return { +// okta_id: claims.sub, +// email: claims.email, +// name: claims.name, +// }; +// }; +// /** +// * A simple middleware that asserts valid Okta idToken and sends 401 responses +// * if the token is not present or fails validation. If the token is valid its +// * contents are attached to req.profile +// */ +// const authRequired = async (req, res, next) => { +// try { +// const authHeader = req.headers.authorization || ''; +// const match = authHeader.match(/Bearer (.+)/); - if (!match) throw new Error('Missing idToken'); +// if (!match) throw new Error('Missing idToken'); - const idToken = match[1]; - oktaJwtVerifier - .verifyAccessToken(idToken, oktaVerifierConfig.expectedAudience) - .then(async (data) => { - const jwtUserObj = makeProfileObj(data.claims); - const profile = await Profiles.findOrCreateProfile(jwtUserObj); - if (profile) { - req.profile = profile; - } else { - throw new Error('Unable to process idToken'); - } - next(); - }) - .catch((err) => { - console.error(err); - next(createError(401, err.message)); - }); - } catch (err) { - next(createError(401, err.message)); - } -}; +// const idToken = match[1]; +// oktaJwtVerifier +// .verifyAccessToken(idToken, oktaVerifierConfig.expectedAudience) +// .then(async (data) => { +// const jwtUserObj = makeProfileObj(data.claims); +// const profile = await Profiles.findOrCreateProfile(jwtUserObj); +// if (profile) { +// req.profile = profile; +// } else { +// throw new Error('Unable to process idToken'); +// } +// next(); +// }) +// .catch((err) => { +// console.error(err); +// next(createError(401, err.message)); +// }); +// } catch (err) { +// next(createError(401, err.message)); +// } +// }; -module.exports = authRequired; +// module.exports = authRequired; diff --git a/api/newsfeed/newsfeedRouter.js b/api/newsfeed/newsfeedRouter.js index 865a6cee..79923e78 100644 --- a/api/newsfeed/newsfeedRouter.js +++ b/api/newsfeed/newsfeedRouter.js @@ -1,9 +1,9 @@ const express = require('express'); -const authRequired = require('../middleware/authRequired'); + const Newsfeed = require('./newsfeedModel'); const router = express.Router(); -router.get('/', authRequired, function (req, res) { +router.get('/', function (req, res) { Newsfeed.getNewsfeed() .then((feed) => { res.status(200).json(feed); @@ -14,7 +14,7 @@ router.get('/', authRequired, function (req, res) { }); }); -router.get('/:newsfeed_id', authRequired, function (req, res) { +router.get('/:newsfeed_id', function (req, res) { Newsfeed.findByNewsfeedId(req.params.newsfeed_id) .then((feed) => { if (!feed) { @@ -29,7 +29,7 @@ router.get('/:newsfeed_id', authRequired, function (req, res) { }); }); -router.post('/', authRequired, (req, res) => { +router.post('/', (req, res) => { Newsfeed.addNewsfeed(req.body) .then((newFeed) => { if (!req.body) { @@ -52,7 +52,7 @@ router.post('/', authRequired, (req, res) => { }); }); -router.put('/:newsfeed_id', authRequired, (req, res) => { +router.put('/:newsfeed_id', (req, res) => { Newsfeed.updateNewsfeed(req.params.newsfeed_id, req.body) .then((updatedFeed) => { if (updatedFeed) { @@ -67,7 +67,7 @@ router.put('/:newsfeed_id', authRequired, (req, res) => { }); }); -router.delete('/:newsfeed_id', authRequired, (req, res) => { +router.delete('/:newsfeed_id', (req, res) => { Newsfeed.removeNewsfeed(req.params.newsfeed_id) .then((deletedFeed) => { if (!deletedFeed) { diff --git a/api/parent/parentRouter.js b/api/parent/parentRouter.js index 15c2e620..23039bd2 100644 --- a/api/parent/parentRouter.js +++ b/api/parent/parentRouter.js @@ -1,5 +1,5 @@ const express = require('express'); -const authRequired = require('../middleware/authRequired'); + const { roleAuthenticationParent, } = require('../middleware/roleAuthentication.js'); @@ -13,7 +13,6 @@ const router = express.Router(); router.post( '/', - authRequired, roleAuthenticationParent, checkChildObject, async function (req, res, next) { @@ -29,7 +28,6 @@ router.post( router.put( '/:child_id', - authRequired, roleAuthenticationParent, checkChildExist, async function (req, res, next) { @@ -45,7 +43,6 @@ router.put( router.delete( '/:child_id', - authRequired, roleAuthenticationParent, checkChildExist, async function (req, res, next) { @@ -59,7 +56,7 @@ router.delete( } ); -router.get('/:profile_id/children', authRequired, function (req, res) { +router.get('/:profile_id/children', function (req, res) { const { profile_id } = req.params; Parents.getParentChildren(profile_id) @@ -75,7 +72,7 @@ router.get('/:profile_id/children', authRequired, function (req, res) { }); }); -router.get('/:profile_id/schedules', authRequired, function (req, res) { +router.get('/:profile_id/schedules', function (req, res) { const { profile_id } = req.params; Parents.getChildSchedules(profile_id) .then((schedules) => { diff --git a/api/profile/profileRouter.js b/api/profile/profileRouter.js index 403b499f..7ac99d6e 100644 --- a/api/profile/profileRouter.js +++ b/api/profile/profileRouter.js @@ -1,5 +1,5 @@ const express = require('express'); -const authRequired = require('../middleware/authRequired'); + const ownerAuthorization = require('../middleware/ownerAuthorization'); const Profiles = require('./profileModel'); const router = express.Router(); @@ -10,7 +10,7 @@ const { checkProfileExist, } = require('./profileMiddleware'); -router.get('/role/:role_id', authRequired, checkRoleExist, function (req, res) { +router.get('/role/:role_id', checkRoleExist, function (req, res) { const role_id = req.params.role_id; Profiles.findByRoleId(role_id) .then((roleList) => { @@ -24,7 +24,6 @@ router.get('/role/:role_id', authRequired, checkRoleExist, function (req, res) { router.get( '/users/:profile_id', - authRequired, checkProfileExist, async function (req, res, next) { const profile_id = req.params.profile_id; @@ -99,7 +98,7 @@ router.get( * 403: * $ref: '#/components/responses/UnauthorizedError' */ -router.get('/', authRequired, function (req, res) { +router.get('/', function (req, res) { Profiles.findAll() .then((profiles) => { res.status(200).json(profiles); @@ -146,14 +145,9 @@ router.get('/', authRequired, function (req, res) { * description: 'Profile not found' */ -router.get( - '/:okta_id', - authRequired, - checkProfileExists(true), - function (req, res) { - res.status(200).json(req.user); - } -); +router.get('/:okta_id', checkProfileExists(true), function (req, res) { + res.status(200).json(req.user); +}); /*p* * @swagger @@ -246,7 +240,6 @@ router.post('/', checkProfileObject, async (req, res) => { */ router.put( '/', - authRequired, checkProfileObject, checkProfileExists(false), ownerAuthorization('user'), @@ -299,7 +292,6 @@ router.put( */ router.delete( '/:okta_id', - authRequired, checkProfileExists(true), ownerAuthorization('user'), (req, res) => { diff --git a/api/programs/programTypesRouter.js b/api/programs/programTypesRouter.js index f5857503..e42afb99 100644 --- a/api/programs/programTypesRouter.js +++ b/api/programs/programTypesRouter.js @@ -1,6 +1,6 @@ const express = require('express'); const Programs = require('./programTypesModel'); -const authRequired = require('../middleware/authRequired'); + // const { // roleAuthentication, // roles, @@ -58,7 +58,7 @@ const { * $ref: '#/components/responses/UnauthorizedError' */ -router.get('/', authRequired, async function (req, res, next) { +router.get('/', async function (req, res, next) { try { const programs = await Programs.getAll(); res.status(200).json(programs); @@ -111,7 +111,7 @@ router.get('/', authRequired, async function (req, res, next) { * description: 'Program with id {program_id} not found.' */ -router.get('/:id', authRequired, checkProgramExists, async function (req, res) { +router.get('/:id', checkProgramExists, async function (req, res) { res.status(200).json(req.programFromDB); }); @@ -152,7 +152,6 @@ router.get('/:id', authRequired, checkProgramExists, async function (req, res) { router.post( '/', validateProgramObject, - authRequired, checkIfProgramIsUnique, async (req, res, next) => { try { @@ -213,7 +212,6 @@ router.post( router.put( '/:id', - authRequired, checkProgramExists, validateProgramObject, async (req, res, next) => { @@ -256,20 +254,15 @@ router.put( * example: Codersitters has been deleted successfully */ -router.delete( - '/:id', - authRequired, - checkProgramExists, - async (req, res, next) => { - const id = Number(req.params.id); - try { - const deletionMessage = await Programs.remove(id); - res.status(200).json(deletionMessage); - } catch (error) { - next(error); - } +router.delete('/:id', checkProgramExists, async (req, res, next) => { + const id = Number(req.params.id); + try { + const deletionMessage = await Programs.remove(id); + res.status(200).json(deletionMessage); + } catch (error) { + next(error); } -); +}); router.use('*', errorhandler); //eslint-disable-next-line diff --git a/api/user/userRouter.js b/api/user/userRouter.js index 49d7ea7a..e8491e6a 100644 --- a/api/user/userRouter.js +++ b/api/user/userRouter.js @@ -1,5 +1,5 @@ const express = require('express'); -const authRequired = require('../middleware/authRequired'); + const Profiles = require('../profile/profileModel'); const User = require('./userModel'); const router = express.Router(); @@ -37,7 +37,7 @@ router.post('/register', (req, res) => { }); }); -router.get('/', authRequired, function (req, res) { +router.get('/', function (req, res) { const { role_id, profile_id } = req.profile; User.findUserData(role_id, profile_id) .then((user) => { @@ -49,7 +49,7 @@ router.get('/', authRequired, function (req, res) { }); }); -router.get('/schedules', authRequired, function (req, res) { +router.get('/schedules', function (req, res) { const { profile_id } = req.profile; User.getSchedule(profile_id) .then((schedule) => { @@ -61,7 +61,7 @@ router.get('/schedules', authRequired, function (req, res) { }); }); -router.put('/', authRequired, function (req, res) { +router.put('/', function (req, res) { const { profile_id } = req.profile; User.updateUserData(profile_id, req.body) .then((user) => { diff --git a/config/okta.js b/config/okta.js index 1dbb5897..839429c4 100644 --- a/config/okta.js +++ b/config/okta.js @@ -1,10 +1,10 @@ -module.exports = { - expectedAudience: ['api://default', `${process.env.OKTA_CLIENT_ID}`], - config: { - issuer: `${process.env.OKTA_URL_ISSUER}`, - clientId: `${process.env.OKTA_CLIENT_ID}`, - assertClaims: { - aud: `${process.env.OKTA_CLIENT_ID}`, - }, - }, -}; +// module.exports = { +// expectedAudience: ['api://default', `${process.env.OKTA_CLIENT_ID}`], +// config: { +// issuer: `${process.env.OKTA_URL_ISSUER}`, +// clientId: `${process.env.OKTA_CLIENT_ID}`, +// assertClaims: { +// aud: `${process.env.OKTA_CLIENT_ID}`, +// }, +// }, +// }; diff --git a/lib/oktaClient.js b/lib/oktaClient.js index 69cd1fb6..01528054 100644 --- a/lib/oktaClient.js +++ b/lib/oktaClient.js @@ -1,8 +1,8 @@ -const okta = require('@okta/okta-sdk-nodejs'); +// const okta = require('@okta/okta-sdk-nodejs'); -const client = new okta.Client({ - orgUrl: `${process.env.OKTA_ORG_URL}`, // changed from OKTA_URL_ISSUER - token: `${process.env.OKTA_API_TOKEN}`, -}); +// const client = new okta.Client({ +// orgUrl: `${process.env.OKTA_ORG_URL}`, // changed from OKTA_URL_ISSUER +// token: `${process.env.OKTA_API_TOKEN}`, +// }); -module.exports = client; +// module.exports = client; diff --git a/package-lock.json b/package-lock.json index 5c8f40d3..fecdd4c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "debug": "~2.6.9", "dotenv": "^8.2.0", "express": "~4.16.1", + "express-oauth2-jwt-bearer": "^1.3.0", "faker": "^4.1.0", "helmet": "^3.23.1", "http-errors": "~1.6.3", @@ -4278,6 +4279,17 @@ "node": ">= 0.10.0" } }, + "node_modules/express-oauth2-jwt-bearer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.3.0.tgz", + "integrity": "sha512-m8UyAxL9eHpDDmSxWEaKLEPlE+6lfRCT/z3i2Cm0MYajUP4L/WFaZ66ch5KrPPiHEy91op6fhzZ0RTN8Ldap1Q==", + "dependencies": { + "jose": "^4.9.2" + }, + "engines": { + "node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0" + } + }, "node_modules/express/node_modules/cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", @@ -7031,6 +7043,14 @@ "node": ">= 8.3" } }, + "node_modules/jose": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.11.2.tgz", + "integrity": "sha512-njj0VL2TsIxCtgzhO+9RRobBvws4oYyCM8TpvoUQwl/MbIM3NFJRR9+e6x0sS5xXaP1t6OCBkaBME98OV9zU5A==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -15558,6 +15578,14 @@ } } }, + "express-oauth2-jwt-bearer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.3.0.tgz", + "integrity": "sha512-m8UyAxL9eHpDDmSxWEaKLEPlE+6lfRCT/z3i2Cm0MYajUP4L/WFaZ66ch5KrPPiHEy91op6fhzZ0RTN8Ldap1Q==", + "requires": { + "jose": "^4.9.2" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -17649,6 +17677,11 @@ "supports-color": "^7.0.0" } }, + "jose": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.11.2.tgz", + "integrity": "sha512-njj0VL2TsIxCtgzhO+9RRobBvws4oYyCM8TpvoUQwl/MbIM3NFJRR9+e6x0sS5xXaP1t6OCBkaBME98OV9zU5A==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index df17cf47..ade0c3b5 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "debug": "~2.6.9", "dotenv": "^8.2.0", "express": "~4.16.1", + "express-oauth2-jwt-bearer": "^1.3.0", "faker": "^4.1.0", "helmet": "^3.23.1", "http-errors": "~1.6.3", diff --git a/server.js b/server.js index fd7133c7..0056a321 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,38 @@ require('dotenv').config(); - const app = require('./api/app.js'); +const { auth, requiredScopes } = require('express-oauth2-jwt-bearer'); + +// Authorization middleware. When used, the Access Token must +// exist and be verified against the Auth0 JSON Web Key Set. +const checkJwt = auth({ + audience: 'https://a.coderheroes.dev/', + issuerBaseURL: `https://dev-35n2stap.auth0.com/`, +}); + +// This route doesn't need authentication +app.get('/api/public', function (req, res) { + res.json({ + message: + "Hello from a public endpoint! You don't need to be authenticated to see this.", + }); +}); + +// This route needs authentication +app.get('/api/private', checkJwt, function (req, res) { + res.json({ + message: + 'Hello from a private endpoint! You need to be authenticated to see this.', + }); +}); + +const checkScopes = requiredScopes('read:messages'); + +app.get('/api/private-scoped', checkJwt, checkScopes, function (req, res) { + res.json({ + message: + 'Hello from a private endpoint! You need to be authenticated and have a scope of read:messages to see this.', + }); +}); const port = process.env.PORT || 8000; app.listen(port, () => console.log(`\n** Running on port ${port} **\n`)); From 5c2c404cb18fc0fc30626324eccc652581eefdbd Mon Sep 17 00:00:00 2001 From: jesswillcode Date: Tue, 10 Jan 2023 17:43:01 -0500 Subject: [PATCH 2/4] cleaning up routers after pulling in PR --- api/app.js | 2 +- api/calendarEvents/calendarEventsRouter.js | 34 ++++++++++------- api/children/childrenRouter.js | 26 +++++++++---- api/classroom/classroomRouter.js | 44 ++++++++++++---------- api/courses/coursesRouter.js | 35 ++++++++++------- api/dsService/dsRouter.js | 5 ++- api/inbox/inboxRouter.js | 11 +++--- api/instructor/instructorRouter.js | 21 +++++++---- api/newsfeed/newsfeedRouter.js | 12 +++--- api/parent/parentRouter.js | 9 +++-- api/profile/profileRouter.js | 5 ++- api/programs/programTypesRouter.js | 29 ++++++++------ api/user/userRouter.js | 4 +- 13 files changed, 141 insertions(+), 96 deletions(-) diff --git a/api/app.js b/api/app.js index 2ce94ebc..66c4504c 100644 --- a/api/app.js +++ b/api/app.js @@ -64,7 +64,7 @@ app.use('/', indexRouter); app.use(['/profile', '/profiles'], profileRouter); app.use(['/parent', '/parents'], parentRouter); app.use(['/instructor', '/instructors'], instructorRouter); -app.use(['/user'], userRouter); +app.use(['/user', '/users'], userRouter); app.use(['/conversation', '/conversations'], inboxRouter); app.use( ['/program-type', '/program-types', '/program', '/programs'], diff --git a/api/calendarEvents/calendarEventsRouter.js b/api/calendarEvents/calendarEventsRouter.js index 0e23d950..5056e7dd 100644 --- a/api/calendarEvents/calendarEventsRouter.js +++ b/api/calendarEvents/calendarEventsRouter.js @@ -1,5 +1,5 @@ const router = require('express').Router(); - +const authRequired = require('../middleware/authRequired'); const { checkCalendarEventExists, validateCalendarEvent, @@ -7,7 +7,7 @@ const { const CalendarEvents = require('./calendarEventsModel'); -router.get('/', (req, res, next) => { +router.get('/', authRequired, (req, res, next) => { CalendarEvents.getAllCalendarEvents() .then((events) => { res.status(200).json(events); @@ -15,7 +15,7 @@ router.get('/', (req, res, next) => { .catch(next); }); -router.get('/user', (req, res, next) => { +router.get('/user', authRequired, (req, res, next) => { CalendarEvents.getCalendarEventsByProfileId(req.profile.profile_id) .then((events) => { res.status(200).json({ @@ -26,11 +26,11 @@ router.get('/user', (req, res, next) => { .catch(next); }); -router.get('/:event_id', checkCalendarEventExists, (req, res) => { +router.get('/:event_id', authRequired, checkCalendarEventExists, (req, res) => { res.status(200).json(req.calendarEvent); }); -router.post('/', validateCalendarEvent, (req, res, next) => { +router.post('/', authRequired, validateCalendarEvent, (req, res, next) => { CalendarEvents.addCalendarEvent(req.validatedCalendarEvent) .then((newEvent) => { res.status(201).json({ @@ -43,6 +43,7 @@ router.post('/', validateCalendarEvent, (req, res, next) => { router.put( '/:event_id', + authRequired, checkCalendarEventExists, validateCalendarEvent, (req, res, next) => { @@ -60,14 +61,19 @@ router.put( } ); -router.delete('/:event_id', checkCalendarEventExists, (req, res, next) => { - CalendarEvents.delCalendarEventById(req.params.event_id) - .then( - res.json({ - message: 'Calendar Event sucessfully deleted', - }) - ) - .catch(next); -}); +router.delete( + '/:event_id', + authRequired, + checkCalendarEventExists, + (req, res, next) => { + CalendarEvents.delCalendarEventById(req.params.event_id) + .then( + res.json({ + message: 'Calendar Event sucessfully deleted', + }) + ) + .catch(next); + } +); module.exports = router; diff --git a/api/children/childrenRouter.js b/api/children/childrenRouter.js index ffada086..6596b6fe 100644 --- a/api/children/childrenRouter.js +++ b/api/children/childrenRouter.js @@ -1,6 +1,6 @@ const express = require('express'); const Children = require('./childrenModel'); - +const authRequired = require('../middleware/authRequired'); const { roleAuthenticationParent, } = require('../middleware/roleAuthentication'); @@ -13,7 +13,7 @@ const { const router = express.Router(); -router.get('/', function (req, res) { +router.get('/', authRequired, function (req, res) { Children.getChildren() .then((child) => { res.status(200).json(child); @@ -25,6 +25,7 @@ router.get('/', function (req, res) { router.post( '/', + authRequired, roleAuthenticationParent, checkChildObject, async function (req, res, next) { @@ -40,16 +41,22 @@ router.post( } ); -router.get('/:child_id', checkChildExist, async function (req, res, next) { - try { - res.status(200).json(req.child); - } catch (error) { - next(error); +router.get( + '/:child_id', + authRequired, + checkChildExist, + async function (req, res, next) { + try { + res.status(200).json(req.child); + } catch (error) { + next(error); + } } -}); +); router.put( '/:child_id', + authRequired, roleAuthenticationParent, checkChildExist, isChildParent, @@ -66,6 +73,7 @@ router.put( router.delete( '/:child_id', + authRequired, roleAuthenticationParent, checkChildExist, isChildParent, @@ -84,6 +92,7 @@ router.delete( // middleware for enrollments ready to implement checkChildExist2, checkIfCourseExist, checkChildAge, checkCourseSize router.get( '/:id/enrollments', + authRequired, checkChildExist, async function (req, res, next) { try { @@ -99,6 +108,7 @@ router.get( // middleware for enrollments ready to implement checkChildExist2, checkIfCourseExist, checkChildAge, checkCourseSize router.post( '/:id/enrollments', + authRequired, checkChildExist, isChildAlreadyEnrolled, async (req, res) => { diff --git a/api/classroom/classroomRouter.js b/api/classroom/classroomRouter.js index 1d964765..9b052d30 100644 --- a/api/classroom/classroomRouter.js +++ b/api/classroom/classroomRouter.js @@ -1,9 +1,9 @@ const express = require('express'); - +const authRequired = require('../middleware/authRequired'); const Classroom = require('./classroomModel'); const router = express.Router(); -router.get('/students/:course_id', function (req, res) { +router.get('/students/:course_id', authRequired, function (req, res) { const course_id = parseInt(req.params.course_id); Classroom.getStudentsByClassId(course_id) .then((students) => { @@ -14,7 +14,7 @@ router.get('/students/:course_id', function (req, res) { }); }); -router.get('/badges', function (req, res, next) { +router.get('/badges', authRequired, function (req, res, next) { Classroom.getBadges() .then((badges) => { res.status(200).json(badges); @@ -22,7 +22,7 @@ router.get('/badges', function (req, res, next) { .catch(next); }); -router.get('/badges/:child_id', function (req, res, next) { +router.get('/badges/:child_id', authRequired, function (req, res, next) { const child_id = parseInt(req.params.child_id); Classroom.getBadgesByChildId(child_id) .then((badges) => { @@ -31,7 +31,7 @@ router.get('/badges/:child_id', function (req, res, next) { .catch(next); }); -router.post('/assign', function (req, res, next) { +router.post('/assign', authRequired, function (req, res, next) { const child_id = req.body.child_id; const badge_id = req.body.badge_id; Classroom.assignBadgeByIds({ child_id, badge_id }) @@ -41,22 +41,26 @@ router.post('/assign', function (req, res, next) { .catch(next); }); -router.delete('/remove/:badge_id/:child_id', async function (req, res, next) { - const child_id = parseInt(req.params.child_id); - const badge_id = parseInt(req.params.badge_id); - const student_badge_id = await Classroom.getStudentBadgeId( - badge_id, - child_id - ); - try { - Classroom.removeBadge(student_badge_id[0].student_badge_id).then(() => { - res.status(200).json({ - message: 'Student badge removed', +router.delete( + '/remove/:badge_id/:child_id', + authRequired, + async function (req, res, next) { + const child_id = parseInt(req.params.child_id); + const badge_id = parseInt(req.params.badge_id); + const student_badge_id = await Classroom.getStudentBadgeId( + badge_id, + child_id + ); + try { + Classroom.removeBadge(student_badge_id[0].student_badge_id).then(() => { + res.status(200).json({ + message: 'Student badge removed', + }); }); - }); - } catch (err) { - next(err); + } catch (err) { + next(err); + } } -}); +); module.exports = router; diff --git a/api/courses/coursesRouter.js b/api/courses/coursesRouter.js index 2344607d..46c22712 100644 --- a/api/courses/coursesRouter.js +++ b/api/courses/coursesRouter.js @@ -1,5 +1,5 @@ const express = require('express'); - +const authRequired = require('../middleware/authRequired'); // const ownerAuthorization = require('../middleware/ownerAuthorization'); needs to be refactored const { roleAuthenticationInstructor, @@ -157,7 +157,7 @@ const { * $ref: '#/components/responses/UnauthorizedError' */ -router.get('/', function (req, res, next) { +router.get('/', authRequired, function (req, res, next) { Courses.getAllCourses() .then((scheduleList) => { res.status(200).json(scheduleList); @@ -225,11 +225,11 @@ router.get('/', function (req, res, next) { * description: 'Course Instance with id {course_id} does not exist' */ -router.get('/:course_id', checkCourseExists, (req, res) => { +router.get('/:course_id', authRequired, checkCourseExists, (req, res) => { res.status(200).json(req.course); }); -router.get('/students/:course_id', function (req, res, next) { +router.get('/students/:course_id', authRequired, function (req, res, next) { Courses.getStudentsById() .then((students) => { res.status(200).json(students); @@ -306,6 +306,7 @@ router.get('/students/:course_id', function (req, res, next) { router.post( '/', + authRequired, roleAuthenticationInstructor, validateCourseObject, checkInstructorExists, @@ -401,6 +402,7 @@ router.post( router.put( '/:course_id', + authRequired, validateCourseObject, checkInstructorExists, checkCourseExists, @@ -450,17 +452,22 @@ router.put( * example: Course instances with id:'${course_id}' was deleted */ -router.delete('/:course_id', checkCourseExists, (req, res, next) => { - const course_id = parseInt(req.params.course_id); - try { - Courses.removeCourse(course_id).then(() => { - res.status(200).json({ - message: `Course instance with id:'${course_id}' was deleted.`, +router.delete( + '/:course_id', + authRequired, + checkCourseExists, + (req, res, next) => { + const course_id = parseInt(req.params.course_id); + try { + Courses.removeCourse(course_id).then(() => { + res.status(200).json({ + message: `Course instance with id:'${course_id}' was deleted.`, + }); }); - }); - } catch (err) { - next(err); + } catch (err) { + next(err); + } } -}); +); module.exports = router; diff --git a/api/dsService/dsRouter.js b/api/dsService/dsRouter.js index 52acf5d7..0616f1dc 100644 --- a/api/dsService/dsRouter.js +++ b/api/dsService/dsRouter.js @@ -1,6 +1,7 @@ const express = require('express'); const router = express.Router(); const dsModel = require('./dsModel'); +const authRequired = require('../middleware/authRequired'); /** * @swagger @@ -59,7 +60,7 @@ const dsModel = require('./dsModel'); * 500: * description: 'Error making prediction' */ -router.get('/predict/:x1/:x2/:3', function (req, res) { +router.get('/predict/:x1/:x2/:3', authRequired, function (req, res) { const x1 = String(req.params.x1); const x2 = String(req.params.x2); const x3 = String(req.params.x3); @@ -102,7 +103,7 @@ router.get('/predict/:x1/:x2/:3', function (req, res) { * 500: * description: 'Error making prediction' */ -router.get('/viz/:state', function (req, res) { +router.get('/viz/:state', authRequired, function (req, res) { const state = String(req.params.state); dsModel diff --git a/api/inbox/inboxRouter.js b/api/inbox/inboxRouter.js index 64a029b5..11007a2a 100644 --- a/api/inbox/inboxRouter.js +++ b/api/inbox/inboxRouter.js @@ -1,8 +1,9 @@ const express = require('express'); const Inboxes = require('./inboxModel'); const router = express.Router(); +const authRequired = require('../middleware/authRequired'); -router.get('/', function (req, res) { +router.get('/', authRequired, function (req, res) { Inboxes.getConversations() .then((conversation) => { res.status(200).json(conversation); @@ -13,7 +14,7 @@ router.get('/', function (req, res) { }); }); -router.get('/:conversation_id', function (req, res) { +router.get('/:conversation_id', authRequired, function (req, res) { Inboxes.findByConversationId(req.params.conversation_id) .then((conversation) => { if (conversation.length) { @@ -44,7 +45,7 @@ router.post('/', async (req, res) => { }); }); -router.post('/messages', async (req, res) => { +router.post('/messages', authRequired, async (req, res) => { Inboxes.addMessage(req.body) .then((message) => { if (!req.body) { @@ -62,7 +63,7 @@ router.post('/messages', async (req, res) => { }); }); -router.put('/:messages_id', (req, res) => { +router.put('/:messages_id', authRequired, (req, res) => { if (!req.body.title) { res.status(200).json({ message: 'title is required' }); } else if (!req.body.message) { @@ -97,7 +98,7 @@ router.put('/:messages_id', (req, res) => { } }); -router.delete('/:conversation_id', (req, res) => { +router.delete('/:conversation_id', authRequired, (req, res) => { Inboxes.removeConversation(req.params.conversation_id) .then((conversation) => { if (conversation) { diff --git a/api/instructor/instructorRouter.js b/api/instructor/instructorRouter.js index ca47b6c0..85eb3451 100644 --- a/api/instructor/instructorRouter.js +++ b/api/instructor/instructorRouter.js @@ -1,5 +1,5 @@ const express = require('express'); - +const authRequired = require('../middleware/authRequired'); const Instructors = require('./instructorModel'); const router = express.Router(); // const Profiles = require('../profile/profileModel'); @@ -41,7 +41,7 @@ router.post('/register', (req, res) => { // res.send(err); // }); -router.get('/courses', getInstructorId, (req, res, next) => { +router.get('/courses', authRequired, getInstructorId, (req, res, next) => { Instructors.findInstructorCourses(req.instructor_id) .then((courses) => { if (courses) { @@ -53,13 +53,18 @@ router.get('/courses', getInstructorId, (req, res, next) => { .catch(next); }); -router.get('/:instructor_id', checkInstructorExist, (req, res) => { - if (req.instructor) { - res.status(200).json(req.instructor); - } else { - res.status(404).json({ error: 'Instructor not found.' }); +router.get( + '/:instructor_id', + authRequired, + checkInstructorExist, + (req, res) => { + if (req.instructor) { + res.status(200).json(req.instructor); + } else { + res.status(404).json({ error: 'Instructor not found.' }); + } } -}); +); router.use('*', errorhandler); //eslint-disable-next-line diff --git a/api/newsfeed/newsfeedRouter.js b/api/newsfeed/newsfeedRouter.js index 79923e78..865a6cee 100644 --- a/api/newsfeed/newsfeedRouter.js +++ b/api/newsfeed/newsfeedRouter.js @@ -1,9 +1,9 @@ const express = require('express'); - +const authRequired = require('../middleware/authRequired'); const Newsfeed = require('./newsfeedModel'); const router = express.Router(); -router.get('/', function (req, res) { +router.get('/', authRequired, function (req, res) { Newsfeed.getNewsfeed() .then((feed) => { res.status(200).json(feed); @@ -14,7 +14,7 @@ router.get('/', function (req, res) { }); }); -router.get('/:newsfeed_id', function (req, res) { +router.get('/:newsfeed_id', authRequired, function (req, res) { Newsfeed.findByNewsfeedId(req.params.newsfeed_id) .then((feed) => { if (!feed) { @@ -29,7 +29,7 @@ router.get('/:newsfeed_id', function (req, res) { }); }); -router.post('/', (req, res) => { +router.post('/', authRequired, (req, res) => { Newsfeed.addNewsfeed(req.body) .then((newFeed) => { if (!req.body) { @@ -52,7 +52,7 @@ router.post('/', (req, res) => { }); }); -router.put('/:newsfeed_id', (req, res) => { +router.put('/:newsfeed_id', authRequired, (req, res) => { Newsfeed.updateNewsfeed(req.params.newsfeed_id, req.body) .then((updatedFeed) => { if (updatedFeed) { @@ -67,7 +67,7 @@ router.put('/:newsfeed_id', (req, res) => { }); }); -router.delete('/:newsfeed_id', (req, res) => { +router.delete('/:newsfeed_id', authRequired, (req, res) => { Newsfeed.removeNewsfeed(req.params.newsfeed_id) .then((deletedFeed) => { if (!deletedFeed) { diff --git a/api/parent/parentRouter.js b/api/parent/parentRouter.js index 23039bd2..15c2e620 100644 --- a/api/parent/parentRouter.js +++ b/api/parent/parentRouter.js @@ -1,5 +1,5 @@ const express = require('express'); - +const authRequired = require('../middleware/authRequired'); const { roleAuthenticationParent, } = require('../middleware/roleAuthentication.js'); @@ -13,6 +13,7 @@ const router = express.Router(); router.post( '/', + authRequired, roleAuthenticationParent, checkChildObject, async function (req, res, next) { @@ -28,6 +29,7 @@ router.post( router.put( '/:child_id', + authRequired, roleAuthenticationParent, checkChildExist, async function (req, res, next) { @@ -43,6 +45,7 @@ router.put( router.delete( '/:child_id', + authRequired, roleAuthenticationParent, checkChildExist, async function (req, res, next) { @@ -56,7 +59,7 @@ router.delete( } ); -router.get('/:profile_id/children', function (req, res) { +router.get('/:profile_id/children', authRequired, function (req, res) { const { profile_id } = req.params; Parents.getParentChildren(profile_id) @@ -72,7 +75,7 @@ router.get('/:profile_id/children', function (req, res) { }); }); -router.get('/:profile_id/schedules', function (req, res) { +router.get('/:profile_id/schedules', authRequired, function (req, res) { const { profile_id } = req.params; Parents.getChildSchedules(profile_id) .then((schedules) => { diff --git a/api/profile/profileRouter.js b/api/profile/profileRouter.js index f98d0012..d7fb6b32 100644 --- a/api/profile/profileRouter.js +++ b/api/profile/profileRouter.js @@ -9,7 +9,7 @@ const { checkProfileExist, } = require('./profileMiddleware'); -router.get('/role/:role_id', checkRoleExist, function (req, res) { +router.get('/:role_id', authRequired, checkRoleExist, function (req, res) { const role_id = req.params.role_id; Profiles.findByRoleId(role_id) .then((roleList) => { @@ -23,6 +23,7 @@ router.get('/role/:role_id', checkRoleExist, function (req, res) { router.get( '/users/:profile_id', + authRequired, checkProfileExist, async function (req, res, next) { const profile_id = req.params.profile_id; @@ -193,7 +194,7 @@ router.get( * profile: * $ref: '#/components/schemas/Profile' */ -router.post('/', checkProfileObject, async (req, res) => { +router.post('/', authRequired, checkProfileObject, async (req, res) => { const profile = req.body; // TO-DO: Implement Auth0 - check DB if specific Auth0 ID already exists diff --git a/api/programs/programTypesRouter.js b/api/programs/programTypesRouter.js index e42afb99..49416478 100644 --- a/api/programs/programTypesRouter.js +++ b/api/programs/programTypesRouter.js @@ -1,6 +1,6 @@ const express = require('express'); const Programs = require('./programTypesModel'); - +const authRequired = require('../middleware/authRequired'); // const { // roleAuthentication, // roles, @@ -58,7 +58,7 @@ const { * $ref: '#/components/responses/UnauthorizedError' */ -router.get('/', async function (req, res, next) { +router.get('/', authRequired, async function (req, res, next) { try { const programs = await Programs.getAll(); res.status(200).json(programs); @@ -111,7 +111,7 @@ router.get('/', async function (req, res, next) { * description: 'Program with id {program_id} not found.' */ -router.get('/:id', checkProgramExists, async function (req, res) { +router.get('/:id', authRequired, checkProgramExists, async function (req, res) { res.status(200).json(req.programFromDB); }); @@ -151,6 +151,7 @@ router.get('/:id', checkProgramExists, async function (req, res) { router.post( '/', + authRequired, validateProgramObject, checkIfProgramIsUnique, async (req, res, next) => { @@ -212,6 +213,7 @@ router.post( router.put( '/:id', + authRequired, checkProgramExists, validateProgramObject, async (req, res, next) => { @@ -254,15 +256,20 @@ router.put( * example: Codersitters has been deleted successfully */ -router.delete('/:id', checkProgramExists, async (req, res, next) => { - const id = Number(req.params.id); - try { - const deletionMessage = await Programs.remove(id); - res.status(200).json(deletionMessage); - } catch (error) { - next(error); +router.delete( + '/:id', + authRequired, + checkProgramExists, + async (req, res, next) => { + const id = Number(req.params.id); + try { + const deletionMessage = await Programs.remove(id); + res.status(200).json(deletionMessage); + } catch (error) { + next(error); + } } -}); +); router.use('*', errorhandler); //eslint-disable-next-line diff --git a/api/user/userRouter.js b/api/user/userRouter.js index 483ebdd3..15a8ad82 100644 --- a/api/user/userRouter.js +++ b/api/user/userRouter.js @@ -44,7 +44,7 @@ router.get('/', authRequired, function (req, res) { }); }); -router.get('/schedules', function (req, res) { +router.get('/schedules', authRequired, function (req, res) { const { profile_id } = req.profile; User.getSchedule(profile_id) .then((schedule) => { @@ -56,7 +56,7 @@ router.get('/schedules', function (req, res) { }); }); -router.put('/', function (req, res) { +router.put('/', authRequired, function (req, res) { const { profile_id } = req.profile; User.updateUserData(profile_id, req.body) .then((user) => { From 6a360738a168295149aa0c9c771ecb8d1da8fafd Mon Sep 17 00:00:00 2001 From: jesswillcode Date: Tue, 10 Jan 2023 20:06:31 -0500 Subject: [PATCH 3/4] created auth0 middlewares and added auth0 into fake profile creater in seed --- api/middleware/auth0Middleware.js | 43 ++++++++++++++++++++++++++++ api/middleware/authRequired.js | 36 ++++++++++++++--------- api/middleware/ownerAuthorization.js | 20 ++++++------- api/profile/profileModel.js | 4 +-- api/profile/profileRouter.js | 27 ++++++++++------- data/seeds/001_profiles.js | 7 ++--- 6 files changed, 95 insertions(+), 42 deletions(-) diff --git a/api/middleware/auth0Middleware.js b/api/middleware/auth0Middleware.js index e69de29b..b7002c72 100644 --- a/api/middleware/auth0Middleware.js +++ b/api/middleware/auth0Middleware.js @@ -0,0 +1,43 @@ +const { expressjwt: jwt } = require('express-jwt'); +const jwksRsa = require('jwks-rsa'); +const createError = require('http-errors'); +const config = require('../../config/auth0'); + +// writing the config for expressJwt method to be invoked with product environment variables +const verifyJwt = jwt({ + secret: jwksRsa.expressJwtSecret({ + cache: true, + rateLimit: true, + jwksRequestsPerMinute: 5, + jwksUri: config.jwksUri, + }), + audience: config.audience, + issuer: config.issuer, + algorithms: ['RS256'], + requestProperty: 'auth0User', +}).unless({ path: ['/'] }); +//************ */ +//in the above line add all public endpoints (routes with no need for auth) as a string inside the path array [] <= +// **** IMPORTANT note: if your public endpoint has descendent end points (ex.: ./yourRouterEndPoint/:user_id) you need ot use regex as in the following example: +// ({ path: ['/', /^\/\/.*/] }); => example: ({ path: ['/', /^\/application\/.*/, /^\/roles\/.*/] }); +//************ */ + +//exporting the verifyjwt method as a middleware to be used in app.js server file against all routes except what is in the exception array in above method +const authRequired = (req, res, next) => { + verifyJwt(req, res, next); +}; + +//method to grab the current authenticated user from the req.auth0User and save it to req.body.user to be used globally in the server +const authProfile = async (req, res, next) => { + try { + const profile = await req.auth0User; + if (profile) { + req.body.profile = profile; + } + next(); + } catch (err) { + next(createError(401, err.message)); + } +}; + +module.exports = { authRequired, authProfile }; diff --git a/api/middleware/authRequired.js b/api/middleware/authRequired.js index 264fd399..67338d00 100644 --- a/api/middleware/authRequired.js +++ b/api/middleware/authRequired.js @@ -1,23 +1,31 @@ -// const createError = require('http-errors'); -// const Profiles = require('../profile/profileModel'); +const Profiles = require('../profile/profileModel'); /** - * TO-DO: Implement Auth0 - * If token verification fails - * catch(err) => next(createError(401, err.message)); - */ - -/** - * A simple middleware that asserts valid Okta idToken and sends 401 responses + * A simple middleware that asserts valid Auth0 idToken and sends 401 responses * if the token is not present or fails validation. If the token is valid its * contents are attached to req.profile */ const authRequired = async (req, res, next) => { - // TO-DO: Implement Auth0 -> assure authorized through Header Token + try { + // Verify that the token is valid + const profile = Profiles.findOrCreateProfile; + + if (profile) { + req.profile = profile; + } else { + next({ + status: 401, + message: 'Unable to process idToken', + }); + } - // const match = authHeader.match(/Bearer (.+)/); - // if (!match) throw new Error('Missing idToken'); - // req.profile = authorizedProfile; - next(); + // Proceed with request if token is valid + next(); + } catch (err) { + next({ + status: err.status || 500, + message: err.message || 'Internal Server Error', + }); + } }; module.exports = authRequired; diff --git a/api/middleware/ownerAuthorization.js b/api/middleware/ownerAuthorization.js index 6ecf662e..3f6ac283 100644 --- a/api/middleware/ownerAuthorization.js +++ b/api/middleware/ownerAuthorization.js @@ -1,16 +1,16 @@ // pass in the key parameter to the profile that is the owner of what's being affected -const ownerAuthorization = () => (req, res, next) => { +const ownerAuthorization = (key) => (req, res, next) => { // TO-DO: Implement Auth0 - check that the role_id matches the key passed - // if ( - // req.profile.profile_id === req[key].profile_id || - // (req.profile.role_id < 3 && req.profile.role_id < (req[key].role_id || 3)) - // ) - // next(); - // else - // res - // .status(401) - // .json({ message: 'You are not authorized to take this action' }); + if ( + req.profile.profile_id === req[key].profile_id || + (req.profile.role_id < 3 && req.profile.role_id < (req[key].role_id || 3)) + ) + next(); + else + res + .status(401) + .json({ message: 'You are not authorized to take this action' }); next(); }; diff --git a/api/profile/profileModel.js b/api/profile/profileModel.js index e184f57a..c6f5ac62 100644 --- a/api/profile/profileModel.js +++ b/api/profile/profileModel.js @@ -25,9 +25,7 @@ const remove = async (id) => { }; const findOrCreateProfile = async (profileObj) => { - const foundProfile = await findById(profileObj.okta_id).then( - (profile) => profile - ); + const foundProfile = await findById(profileObj.id).then((profile) => profile); if (foundProfile) { return foundProfile; } else { diff --git a/api/profile/profileRouter.js b/api/profile/profileRouter.js index d7fb6b32..faf0a6ca 100644 --- a/api/profile/profileRouter.js +++ b/api/profile/profileRouter.js @@ -9,17 +9,22 @@ const { checkProfileExist, } = require('./profileMiddleware'); -router.get('/:role_id', authRequired, checkRoleExist, function (req, res) { - const role_id = req.params.role_id; - Profiles.findByRoleId(role_id) - .then((roleList) => { - res.status(200).json(roleList); - }) - .catch((err) => { - console.log(err); - res.status(500).json({ message: err.message }); - }); -}); +router.get( + '/:role/:role_id', + authRequired, + checkRoleExist, + function (req, res) { + const role_id = req.params.role_id; + Profiles.findByRoleId(role_id) + .then((roleList) => { + res.status(200).json(roleList); + }) + .catch((err) => { + console.log(err); + res.status(500).json({ message: err.message }); + }); + } +); router.get( '/users/:profile_id', diff --git a/data/seeds/001_profiles.js b/data/seeds/001_profiles.js index 74ce7f57..6652399c 100644 --- a/data/seeds/001_profiles.js +++ b/data/seeds/001_profiles.js @@ -1,8 +1,7 @@ const faker = require('faker'); let profiles = [...new Array(20)].map((i, idx) => ({ - // TO-DO: Implement Auth0 ID - // okta_id: idx === 0 ? '00ulthapbErVUwVJy4x6' : faker.random.alphaNumeric(20), + auth0_id: idx === 0 ? '00ulthapbErVUwVJy4x6' : faker.random.alphaNumeric(20), avatarUrl: faker.image.avatar(), email: idx === 0 ? 'llama001@maildrop.cc"' : faker.internet.email(), name: @@ -13,9 +12,9 @@ let profiles = [...new Array(20)].map((i, idx) => ({ })); /* - Manually setting the `id` for each profile to the Okta provided ID. Adding + Manually setting the `id` for each profile to the Auth0 provided ID. Adding profiles was not in scope for this iteration, but adding profiles in the - future will require the okta-id to be set as the `id` for each profile. + future will require the auth0-id to be set as the `id` for each profile. */ // TO-DO: Implement dummy Auth0 IDs From 35d5ead95343fe1ae9c7afd3dc8e860453890420 Mon Sep 17 00:00:00 2001 From: jesswillcode Date: Tue, 10 Jan 2023 21:47:12 -0500 Subject: [PATCH 4/4] testing endpoints with auth0 and updating readME through POST /profile --- README.md | 6 +++--- api/middleware/authRequired.js | 1 + api/profile/profileMiddleware.js | 9 ++++++--- api/profile/profileRouter.js | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cd68f917..c05907cc 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ | Method | URL | Description | | -------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | [GET] | /profile/ | Returns an array of all existing profiles. | -| [GET] | /profile/:okta_id/ | Returns the profile object with the specified `okta_id`. | -| [GET] | /profiles/users/:profile_id (BUG: /profiles/users route does not exist; app.js only connects to /profiles/user) | Returns an array filled with event objects that contains information based on profile_id and role_id. | -| [GET] | /profile/role/:role_id (BUG: does not return any data) | Returns an array filled with event objects that contain information based on role_id for all profiles of a role_id type. | +| [GET] | /profile/:profile_id/ (BUG: does not complete request) | Returns the profile object with the specified `profile_id`. | +| [GET] | /profiles/users/:profile_id | Returns an array filled with event objects that contains information based on profile_id and role_id. | +| [GET] | /profile/role/:role_id | Returns an array filled with event objects that contain information based on role_id for all profiles of a role_id type. | | [POST] | /profile/ | Requires a name, password, and email. Registers a new user. | | [PUT] | /profile/ | Returns an event object with the specified `okta`. Updates specific profile. | | [DELETE] | /profile/:okta_id/ | Returns an event object with the specified `okta`. Deletes specific profile. | diff --git a/api/middleware/authRequired.js b/api/middleware/authRequired.js index 67338d00..07732b74 100644 --- a/api/middleware/authRequired.js +++ b/api/middleware/authRequired.js @@ -8,6 +8,7 @@ const authRequired = async (req, res, next) => { try { // Verify that the token is valid const profile = Profiles.findOrCreateProfile; + console.log("I'm in authRequired"); if (profile) { req.profile = profile; diff --git a/api/profile/profileMiddleware.js b/api/profile/profileMiddleware.js index a940165b..44d7f12a 100644 --- a/api/profile/profileMiddleware.js +++ b/api/profile/profileMiddleware.js @@ -2,9 +2,11 @@ const Profiles = require('./profileModel'); const checkProfileObject = (req, res, next) => { const { email, name, role_id, avatarUrl } = req.body; - if (!role_id) return next({ status: 400, message: 'role_id is required' }); - if (!email) return next({ status: 400, message: 'email is required' }); - if (!name) return next({ status: 400, message: 'name is required' }); + console.log(req.body); + console.log("I'm in the obj middleware"); + // if (!role_id) return next({ status: 400, message: 'role_id is required' }); + // if (!email) return next({ status: 400, message: 'email is required' }); + // if (!name) return next({ status: 400, message: 'name is required' }); if ( typeof role_id !== 'number' || typeof email !== 'string' || @@ -15,6 +17,7 @@ const checkProfileObject = (req, res, next) => { message: 'variables in the request body must all be of type string except role_id must be of type number', }); + console.log('I made it to the other side!'); if (email.length > 255 || name.length > 255) return next({ status: 400, diff --git a/api/profile/profileRouter.js b/api/profile/profileRouter.js index faf0a6ca..4a7f03c0 100644 --- a/api/profile/profileRouter.js +++ b/api/profile/profileRouter.js @@ -201,7 +201,7 @@ router.get( */ router.post('/', authRequired, checkProfileObject, async (req, res) => { const profile = req.body; - + console.log("I'm back to the router!"); // TO-DO: Implement Auth0 - check DB if specific Auth0 ID already exists // changed verification from findById(okta_id) to findBy(email) try {