From d39bba9fb1735fef4b2153b3e1967f286e7dcffd Mon Sep 17 00:00:00 2001 From: Chris Vanderloo Date: Tue, 16 Apr 2019 00:10:18 -0400 Subject: [PATCH] Upgraded cookie-parser, added cookie support for authentication --- api.js | 554 ++++++++++++++++++++++++---------------------- index.js | 24 +- package-lock.json | 117 ++++++---- package.json | 2 +- routes/sis.js | 55 +++-- routes/yacs.js | 2 +- 6 files changed, 397 insertions(+), 357 deletions(-) diff --git a/api.js b/api.js index 98c2174..38af4f3 100644 --- a/api.js +++ b/api.js @@ -1,301 +1,315 @@ -var request = require("request"); -// use a single request object in order to hold cookies in session -request = request.defaults({ - jar: true, - agentOptions: { - rejectUnauthorized: false - } -}); - const sources = require('./sources.json'); const $ = require('cheerio'); - +var request = require("request"); var moment = require('moment'); +const j = request.jar() -module.exports = { - sis: { - fetch: (url, next) => { - request.get("http://sis.rpi.edu/" + url, (err,res,body) => { - if (err) next(err); - else next(null, body); - }); - }, - login: (user, pass, next) => { - // gets the URL first to initialize the cookie - request.get(sources.sis.login, () =>{ - // sends post request, replies with it - request({ - uri: sources.sis.login, - method: "POST", - qs: { - "sid": user, - "PIN": pass +module.exports = (sessid) => { + // generates new request object each time + + function r() { + return request.defaults({ + jar: j, + agentOptions: { + rejectUnauthorized: false, + }, + headers: { + 'Cookie': 'SESSID=' + sessid + } + }); + } + + return { + sis: { + fetch: (url, next) => { + request.get("http://sis.rpi.edu/" + url, (err,res,body) => { + if (err) next(err); + else next(null, body); + }); + }, + login: (user, pass, next) => { + // gets the URL first to initialize the cookie + request = request.defaults({ + jar: true, + agentOptions: { + rejectUnauthorized: false } + }); + request.get(sources.sis.login, () => { + // sends post request, replies with it + request({ + uri: sources.sis.login, + method: "POST", + qs: { + "sid": user, + "PIN": pass + } + }, (err, res, body) => { + if (!err && res.statusCode == 200) { + var msg = $('meta',body).attr('content'); + try { + next(null, res.headers['set-cookie'], msg.slice( + msg.indexOf('Welcome,+')+9, + msg.indexOf('+to+the+Rensselaer')-1 + )); + } + catch (err) { + next("Problem communicating with SIS"); + } + } else { + next(err); + } + }); + }); + }, + logout: (next) => { + // gets URL first + r()({ + uri: sources.sis.logout, + method: "GET" }, (err, res, body) => { if (!err && res.statusCode == 200) { - var msg = $('meta',body).attr('content'); - try { - next(null, res.headers['set-cookie'], msg.slice( - msg.indexOf('Welcome,+')+9, - msg.indexOf('+to+the+Rensselaer')-1 - )); - } - catch (err) { - next("Problem communicating with SIS"); - } - } else { - next(err); - } + next(null); + } else { + next(err); + } }); - }); - }, - logout: (next) => { - // gets URL first - request({ - uri: sources.sis.logout, - method: "GET" - }, (err, res, body) => { - if (!err && res.statusCode == 200) { - next(null); - } else { - next(err); - } - }); - }, - get_student_menu: (next) => { - request({ - uri: sources.sis.get_student_menu, - method: "GET", - }, (err, res, body) => { - if (!err && res.statusCode == 200) { - next(null, body); - } else { - next(err); - } - }); - }, - get_current_term: (next) => { - request.get(sources.sis.schedule.current_week, (err, res, html) => { - if (!err) { - //success! - var reply = $('input[name="termDir"]', html).attr('value'); - next(null, reply); - } - else next(err); - }); - }, - get_next_term: (next) => { - request.get(sources.sis.classes, (err, res, html) => { - if (!err) { - //success! - next(null, $('option', '#term_id', html).attr('value')); - } - else next(err); - }); - }, - get_address: (next) => { - request.get(sources.sis.address, (err, res, html) => { - try { - if (!err) { - var data = { - address: '', - city: '', - zip: '', - zip_short: '' - } - var raw = $('table.datadisplaytable > tbody > tr:nth-child(3) > td:nth-child(2)', html) - .html() - .replace(/\n/g,'') - .split('
'); - var cityzip = raw[1].split('    '); - data.address = raw[0]; - data.city = cityzip[0].split(', ')[0]; - data.state = cityzip[0].split(', ')[1]; - data.zip = cityzip[1]; - data.zip_short = cityzip[1].split('-')[0]; - next(null, data); + }, + get_student_menu: (next) => { + r()({ + uri: sources.sis.get_student_menu, + method: "GET", + }, (err, res, body) => { + if (!err && res.statusCode == 200) { + next(null, body); + } else { + next(err); } - else next(err) - } - catch (err) { - next(err); - } - }) - }, - get_registration_status: (term, next) => { - request.post(sources.sis.registration + '?term_in=' + term, (err, res, html) => { - if (err) next(err); - else { - var obj = {}; + }); + }, + get_current_term: (next) => { + r().get(sources.sis.schedule.current_week, (err, res, html) => { + if (!err) { + //success! + var reply = $('input[name="termDir"]', html).attr('value'); + next(null, reply); + } + else next(err); + }); + }, + get_next_term: (next) => { + r().get(sources.sis.classes, (err, res, html) => { + if (!err) { + //success! + next(null, $('option', '#term_id', html).attr('value')); + } + else next(err); + }); + }, + get_address: (next) => { + r().get(sources.sis.address, (err, res, html) => { try { - var arr = $('div.pagebodydiv > table:nth-child(2) > tbody > tr:nth-child(2)', html).html().split('\n'); + if (!err) { + var data = { + address: '', + city: '', + zip: '', + zip_short: '' + } + var raw = $('table.datadisplaytable > tbody > tr:nth-child(3) > td:nth-child(2)', html) + .html() + .replace(/\n/g,'') + .split('
'); + var cityzip = raw[1].split('    '); + data.address = raw[0]; + data.city = cityzip[0].split(', ')[0]; + data.state = cityzip[0].split(', ')[1]; + data.zip = cityzip[1]; + data.zip_short = cityzip[1].split('-')[0]; + next(null, data); + } + else next(err) } catch (err) { next(err); - return; } - var start = moment($('td', arr[1]).text() + " " + $('td', arr[2]).text(), "MMM D, YYYY hh:mm a"); - var end = moment($('td', arr[3]).text() + " " + $('td', arr[4]).text(), "MMM D, YYYY hh:mm a"); - obj["start_date"] = start.format("MMMM Do"); - obj["start_time"] = start.format("h:mm A"); - obj["end_date"] = end.format("MMMM Do"); - obj["end_time"] = end.format("h:mm A"); - obj["start_passed"] = start.isBefore(); - obj["end_passed"] = end.isBefore(); - next(null, obj); - } - }); - }, - get_schedule: (next) => { - request(sources.sis.schedule.current_week, (err, res, html) => { - if (err) next(err); - else { - var schedule_date = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']; - // ordered by day of the week - var obj = { - 'start': '', - 'end': '', - 'today': [], - 'clinfo': [[],[],[],[],[]] - }; - $('div.pagebodydiv > table.datadisplaytable > tbody tr', html).each((i, row) => { - $('td', row).each((j, td) => { - var classinfo = $('a', td).html(); - if (classinfo) { - var m_f = 'h:mm a'; - var clinfo = classinfo.split('
'); - var start_time = moment(clinfo[2].split('-')[0], m_f); - var end_time = moment(clinfo[2].split('-')[1], m_f); + }) + }, + get_registration_status: (term, next) => { + r().post(sources.sis.registration + '?term_in=' + term, (err, res, html) => { + if (err) next(err); + else { + var obj = {}; + try { + var arr = $('div.pagebodydiv > table:nth-child(2) > tbody > tr:nth-child(2)', html).html().split('\n'); + } + catch (err) { + next(err); + return; + } + var start = moment($('td', arr[1]).text() + " " + $('td', arr[2]).text(), "MMM D, YYYY hh:mm a"); + var end = moment($('td', arr[3]).text() + " " + $('td', arr[4]).text(), "MMM D, YYYY hh:mm a"); + obj["start_date"] = start.format("MMMM Do"); + obj["start_time"] = start.format("h:mm A"); + obj["end_date"] = end.format("MMMM Do"); + obj["end_time"] = end.format("h:mm A"); + obj["start_passed"] = start.isBefore(); + obj["end_passed"] = end.isBefore(); + next(null, obj); + } + }); + }, + get_schedule: (next) => { + r()(sources.sis.schedule.current_week, (err, res, html) => { + if (err) next(err); + else { + var schedule_date = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']; + // ordered by day of the week + var obj = { + 'start': '', + 'end': '', + 'today': [], + 'clinfo': [[],[],[],[],[]] + }; + $('div.pagebodydiv > table.datadisplaytable > tbody tr', html).each((i, row) => { + $('td', row).each((j, td) => { + var classinfo = $('a', td).html(); + if (classinfo) { + var m_f = 'h:mm a'; + var clinfo = classinfo.split('
'); + var start_time = moment(clinfo[2].split('-')[0], m_f); + var end_time = moment(clinfo[2].split('-')[1], m_f); - if (obj.start==='') obj.start = start_time.format(m_f); - else if (moment(obj.start, m_f).isAfter(start_time)) obj.start = start_time.format(m_f); + if (obj.start==='') obj.start = start_time.format(m_f); + else if (moment(obj.start, m_f).isAfter(start_time)) obj.start = start_time.format(m_f); - if (obj.end==='') obj.end = end_time.format(m_f); - else if (moment(obj.end, m_f).isBefore(end_time)) obj.end = end_time.format(m_f); + if (obj.end==='') obj.end = end_time.format(m_f); + else if (moment(obj.end, m_f).isBefore(end_time)) obj.end = end_time.format(m_f); - var classinfo = { - "name": clinfo[0], - "CRN": clinfo[1].split(' ')[0], - "start_time": start_time.format(m_f), - "end_time": end_time.format(m_f), - "location": clinfo[3] - } + var classinfo = { + "name": clinfo[0], + "CRN": clinfo[1].split(' ')[0], + "start_time": start_time.format(m_f), + "end_time": end_time.format(m_f), + "location": clinfo[3] + } - obj.clinfo[j].push(classinfo); - if (moment().day()-1 == j) - obj.today.push(classinfo); - } + obj.clinfo[j].push(classinfo); + if (moment().day()-1 == j) + obj.today.push(classinfo); + } + }); }); - }); - next(null, JSON.stringify(obj)); - } - }); - }, - get_class_info: (crn, term, next) => { - request(sources.sis.schedule.class_info + crn + "&term_in=" + term, (err, res, html) => { - if (err) next(err); - else { - var obj = {}; - var split_info = $('div.pagebodydiv > table > caption', html).html() - if (!split_info) next("No split object"); - else { - split_info=split_info.split(' - '); - obj["name"] = split_info[0]; - obj["id"] = split_info[1]; - obj["section"] = split_info[2]; - obj["instructor"] = $('body > div.pagebodydiv > table:nth-child(3) > tbody > tr:nth-child(4) > td', html).text() - obj["instructor_email"] = $('body > div.pagebodydiv > table:nth-child(3) > tbody > tr:nth-child(4) > td > a', html).attr('href') - next(null, obj); + next(null, JSON.stringify(obj)); } - } - }); - }, - get_student_info: (next) => { - request.post() - }, - get_grades: (next) => { - request.get(sources.sis.grades_term, (err, res, html) => { - var requests = []; - var grades_obj = {}; - var total = $('#term_id > option', html).length; - if (total==0) next("No results"); - $('#term_id > option', html).each((index, option)=> { - var term_in = $(option).attr('value'); - requests.push(request.post(sources.sis.grades + '?term_in=' + term_in, (err, res, html) => { - if (err) next(err); + }); + }, + get_class_info: (crn, term, next) => { + r()(sources.sis.schedule.class_info + crn + "&term_in=" + term, (err, res, html) => { + if (err) next(err); + else { + var obj = {}; + var split_info = $('div.pagebodydiv > table > caption', html).html() + if (!split_info) next("No split object"); else { - var obj = []; - var param; - $('div.pagebodydiv > table:nth-child(4) > tbody > tr', html).each((j, row)=>{ - // skip 0th row, it only has headings for each thing - if (j==0) return; - // creates a variable that holds all the data for a row - var course_data = { - 'CRN': '', - 'SUBJ': '', - 'COURSE': '', - 'SECTION': '', - 'TITLE': '', - 'CAMPUS': '', - 'GRADE': '', - 'ATTEMPTED': '', - 'EARNED': '', - 'GPA_HRS': '', - 'POINTS': '' - }; + split_info=split_info.split(' - '); + obj["name"] = split_info[0]; + obj["id"] = split_info[1]; + obj["section"] = split_info[2]; + obj["instructor"] = $('body > div.pagebodydiv > table:nth-child(3) > tbody > tr:nth-child(4) > td', html).text() + obj["instructor_email"] = $('body > div.pagebodydiv > table:nth-child(3) > tbody > tr:nth-child(4) > td > a', html).attr('href') + next(null, obj); + } + } + }); + }, + get_student_info: (next) => { + r().post() + }, + get_grades: (next) => { + r().get(sources.sis.grades_term, (err, res, html) => { + var requests = []; + var grades_obj = {}; + var total = $('#term_id > option', html).length; + if (total==0) next("No results"); + $('#term_id > option', html).each((index, option)=> { + var term_in = $(option).attr('value'); + requests.push(request.post(sources.sis.grades + '?term_in=' + term_in, (err, res, html) => { + if (err) next(err); + else { + var obj = []; + var param; + $('div.pagebodydiv > table:nth-child(4) > tbody > tr', html).each((j, row)=>{ + // skip 0th row, it only has headings for each thing + if (j==0) return; + // creates a variable that holds all the data for a row + var course_data = { + 'CRN': '', + 'SUBJ': '', + 'COURSE': '', + 'SECTION': '', + 'TITLE': '', + 'CAMPUS': '', + 'GRADE': '', + 'ATTEMPTED': '', + 'EARNED': '', + 'GPA_HRS': '', + 'POINTS': '' + }; - // goes through each column in the rows - $( "td", row ).each(function( index ) { - // scrapes the text from the column - var txt = $(this).text().trim(); - var i=0; - // inputs the text into the course_data - for (var prop in course_data) { - if (index==i) - course_data[prop] = txt; - i+=1; - } - }); + // goes through each column in the rows + $( "td", row ).each(function( index ) { + // scrapes the text from the column + var txt = $(this).text().trim(); + var i=0; + // inputs the text into the course_data + for (var prop in course_data) { + if (index==i) + course_data[prop] = txt; + i+=1; + } + }); - // inputs course_data object into obj for returning - obj.push(course_data); - }); - grades_obj[term_in] = obj; - var size = Object.keys(grades_obj).length; - if (size==total) - next(null, grades_obj) - } - })); + // inputs course_data object into obj for returning + obj.push(course_data); + }); + grades_obj[term_in] = obj; + var size = Object.keys(grades_obj).length; + if (size==total) + next(null, grades_obj) + } + })); + }); }); - }); + }, + get_holds_bool: (next) => { + r().get(sources.sis.holds, (err, res, html) => { + if (err) next(err); + else { + if ($('div.pagebodydiv > table.datadisplaytable > tbody > tr:nth-child(2)', html).html()!=null) + next(null, true); + else next(null, false); + } + }) + } }, - get_holds_bool: (next) => { - request.get(sources.sis.holds, (err, res, html) => { - if (err) next(err); - else { - if ($('div.pagebodydiv > table.datadisplaytable > tbody > tr:nth-child(2)', html).html()!=null) - next(null, true); - else next(null, false); - } - }) - } - }, - yacs: { - departments: (next) => { - request.get(sources.yacs.departments, (err, res, body) => { - if (!err) next(null, body); - else next(err); - }); - }, - courses: (dep_id, next) => { - request.get(sources.yacs.courses + dep_id + "&show_periods=true&show_sections=true&", (err, res, body) => { - if (!err) next(null, body); - else next(err); - }); + yacs: { + departments: (next) => { + r().get(sources.yacs.departments, (err, res, body) => { + if (!err) next(null, body); + else next(err); + }); + }, + courses: (dep_id, next) => { + r().get(sources.yacs.courses + dep_id + "&show_periods=true&show_sections=true&", (err, res, body) => { + if (!err) next(null, body); + else next(err); + }); + } } - } + } } diff --git a/index.js b/index.js index 452fb9a..9b3469c 100644 --- a/index.js +++ b/index.js @@ -1,38 +1,30 @@ const express = require("express"); const path = require('path'); -const api = require('./api.js'); const cron = require('node-cron'); const runUpdate = require('./update_data.js'); const https = require('https'); const fs = require('fs'); +var cookieParser = require('cookie-parser'); var app = express(); +app.use(cookieParser()); app.listen(8080, () => { console.log("Listening on port 8080"); }); -// certs - -var rootCas = require('ssl-root-cas/latest').create(); -require('https').globalAgent.options.ca = rootCas; - -var secureContext = require('tls').createSecureContext({ - ca: rootCas -}); - -// YACS -require('./routes/yacs.js')(app, api.yacs, runUpdate); - -// SIS -require('./routes/sis.js')(app, api.sis); - // handshake app.get("/verify_status", (req, res) => { console.log("Client handshake"); res.send({ status: 'active' }); }); +// YACS +require('./routes/yacs.js')(app, runUpdate); + +// SIS +require('./routes/sis.js')(app); + // SERVER cron.schedule('0 0 * * *', () => { diff --git a/package-lock.json b/package-lock.json index 4f11c02..3932465 100644 --- a/package-lock.json +++ b/package-lock.json @@ -490,9 +490,9 @@ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, "cookie-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", - "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz", + "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==", "requires": { "cookie": "0.3.1", "cookie-signature": "1.0.6" @@ -1012,9 +1012,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "optional": true, "requires": { "nan": "^2.9.2", @@ -1028,7 +1028,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1036,7 +1037,7 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "optional": true, "requires": { @@ -1046,32 +1047,37 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1087,7 +1093,7 @@ } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "optional": true }, @@ -1130,7 +1136,7 @@ } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "optional": true, "requires": { @@ -1148,11 +1154,11 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -1174,7 +1180,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1184,6 +1191,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1196,24 +1204,27 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, + "optional": true, "requires": { - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "optional": true, "requires": { @@ -1223,6 +1234,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1233,7 +1245,7 @@ "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.2.4", "bundled": true, "optional": true, "requires": { @@ -1243,17 +1255,17 @@ } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.10.3", "bundled": true, "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", - "needle": "^2.2.0", + "needle": "^2.2.1", "nopt": "^4.0.1", "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4" @@ -1269,12 +1281,12 @@ } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.5", "bundled": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.2.0", "bundled": true, "optional": true, "requires": { @@ -1295,7 +1307,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1305,6 +1318,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1339,11 +1353,11 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -1371,16 +1385,17 @@ } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", - "bundled": true + "version": "5.1.2", + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -1393,7 +1408,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.6.0", "bundled": true, "optional": true }, @@ -1410,6 +1425,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1427,6 +1443,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1437,16 +1454,16 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "optional": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } }, @@ -1456,20 +1473,22 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { - "version": "3.0.2", - "bundled": true + "version": "3.0.3", + "bundled": true, + "optional": true } } }, @@ -2114,9 +2133,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", "optional": true }, "nanomatch": { diff --git a/package.json b/package.json index dd48a74..00c7f20 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "license": "ISC", "dependencies": { "cheerio": "^1.0.0-rc.2", - "cookie-parser": "^1.4.3", + "cookie-parser": "^1.4.4", "express": "^4.16.4", "moment": "^2.24.0", "node-cron": "^2.0.3", diff --git a/routes/sis.js b/routes/sis.js index cf2680f..2295154 100644 --- a/routes/sis.js +++ b/routes/sis.js @@ -1,15 +1,19 @@ -module.exports = function(app, api, auth) { +module.exports = function(app, auth) { + var api = require('../api.js')(null).sis; - app.get("/fetch", (req,res) => { - api.fetch(req.query.url, (err,body) => { - if (err) res.status(500).send(err); - else res.send(body); - }) - }); + function isAuthenticated(req, res, next) { + var cookie = req.cookies.SESSID; + console.log(cookie) + req.api = require('../api.js')(cookie).sis; + + if (req.cookies.SESSID) + return next(); + res.status(403).send('No SESSID token sent.'); + } // The login route has a lot going on; this takes a few key bits of information from SIS at once - app.post("/login", (req,res) => + app.post("/login", (req,res) => { api.login(req.query.user, req.query.pass, (err, cookie, name) => { if (!err) { if (cookie[0].startsWith("SESSID=;")) res.status(403).send("No SESSID returned"); @@ -18,7 +22,7 @@ module.exports = function(app, api, auth) { reply.sessid = cookie[0].replace("SESSID=", ""); reply.name = name; reply.term = term; - res.send(JSON.stringify(reply)); + res.cookie('SESSID', reply.sessid).send(JSON.stringify(reply)); }); } else { @@ -26,10 +30,21 @@ module.exports = function(app, api, auth) { res.status(500).send(err); } }) - ); + }); + + app.use(isAuthenticated); + + // IMPORTANT: ALL ROUTES BELOW THIS ARE PROTECTED + + app.get("/fetch", (req,res) => { + req.api.fetch(req.query.url, (err,body) => { + if (err) res.status(500).send(err); + else res.send(body); + }) + }); - app.get("/schedule", (req,res) => { - api.get_schedule((err, body) => { + app.get("/schedule", isAuthenticated, (req,res) => { + req.api.get_schedule((err, body) => { if (!err) res.send(body); else { @@ -40,8 +55,8 @@ module.exports = function(app, api, auth) { }); app.get("/class_info", (req,res) => { - api.get_current_term((err, term) => { - api.get_class_info(req.query.crn, term, (err, body) => { + req.api.get_current_term((err, term) => { + req.api.get_class_info(req.query.crn, term, (err, body) => { if (!err) res.send(body); else { @@ -54,7 +69,7 @@ module.exports = function(app, api, auth) { // Logout route app.get("/logout", (req,res) =>{ - api.logout( (err) => { + req.api.logout( (err) => { if (!err) res.send("SUCCESS"); else { @@ -66,7 +81,7 @@ module.exports = function(app, api, auth) { //Student Menu Route - just for testing app.get("/get_student_menu", (req, res) => { - api.get_student_menu((err, html) => { + req.api.get_student_menu((err, html) => { if (!err) res.send(html); else { @@ -76,7 +91,7 @@ module.exports = function(app, api, auth) { }) app.get("/address", (req, res) => { - api.get_address((err, data) => { + req.api.get_address((err, data) => { if (!err) res.send(data) else { @@ -88,7 +103,7 @@ module.exports = function(app, api, auth) { app.get("/feed/registration", (req, res) => { var term = req.query.term; if (!term) res.status(400).send("Requires term param"); - else api.get_registration_status(term, (err, data) => { + else req.api.get_registration_status(term, (err, data) => { if (err) res.status(500).send(err); else @@ -101,7 +116,7 @@ module.exports = function(app, api, auth) { }); app.get("/grades", (req, res) => { - api.get_grades((err, data) => { + req.api.get_grades((err, data) => { if (err) res.status(500).send(err); else { @@ -111,7 +126,7 @@ module.exports = function(app, api, auth) { }); app.get("/exists_hold", (req, res) => { - api.get_holds_bool((err, hold_exists) => { + req.api.get_holds_bool((err, hold_exists) => { if (err) res.status(500).send(err); else res.send(hold_exists); }); diff --git a/routes/yacs.js b/routes/yacs.js index 605a833..71a610e 100644 --- a/routes/yacs.js +++ b/routes/yacs.js @@ -1,4 +1,4 @@ -module.exports = (app, api, update) => { +module.exports = (app, update) => { app.get("/api/update", (req,res) => { update(); -- 2.51.2