diff options
Diffstat (limited to '')
-rw-r--r-- | src/index.ts | 16 | ||||
-rw-r--r-- | src/public/js/form.js | 9 | ||||
-rw-r--r-- | src/routes/api.ts (renamed from src/routes/pendulum.ts) | 8 | ||||
-rw-r--r-- | src/routes/middleware/saml.ts | 13 |
4 files changed, 35 insertions, 11 deletions
diff --git a/src/index.ts b/src/index.ts index 117f0f1..c4b346a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,12 @@ import rateLimit from 'express-rate-limit'; import helmet from 'helmet'; import path from 'path'; import { env } from 'process'; -import api from './routes/pendulum'; +import api from './routes/api.js'; +import saml from './routes/middleware/saml.js'; +import { dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); const app = express(); @@ -21,7 +26,7 @@ const csrf = csurf({ cookie: true }); // Rate limiting const rateLimiter = rateLimit({ windowMs: 1 * 60 * 1000, // 1 minute - max: 40, // Limit each IP to 40 requests per `window` (here, per 1 minutes) + max: 40, // Limit each IP to 40 requests per `window` (here, per 1 minute) standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers legacyHeaders: false, // Disable the `X-RateLimit-*` headers }); @@ -33,7 +38,7 @@ app.use('/api/v1/', api); /* RENDERING */ app.set('view engine', 'ejs'); // Add ejs as view engine -app.set('views', path.join(__dirname, 'views/pages')); // Set views directory (where the ejs lies) +app.set('views', path.join(__dirname, 'views/pages')); // Set views directory (where the ejs is) app.use('/public', express.static(path.join(__dirname, 'public'))); // Set static directory (where the static CSS/JS/images lie) /* ROUTING */ @@ -41,9 +46,12 @@ app.use('/public', express.static(path.join(__dirname, 'public'))); // Set stati app.get('/', csrf, (req: Request, res: Response) => { res.render('index', { csrfToken: req.csrfToken() }); }); -app.get('/about', csrf, (req: Request, res: Response) => { +app.get('/about', csrf, saml, (req: Request, res: Response) => { res.render('about'); }); +app.all('/login', csrf, (req: Request, res: Response) => { + res.redirect('/api/v1/login'); +}); // Start the server const port = env.PORT || 2000; diff --git a/src/public/js/form.js b/src/public/js/form.js index 1e9eaca..9823dcf 100644 --- a/src/public/js/form.js +++ b/src/public/js/form.js @@ -15,7 +15,7 @@ document.getElementById('upload').onsubmit = function () { document.getElementById('download-link').innerText = ''; // Make AJAX request let xhr = new XMLHttpRequest(); - xhr.open('POST', '/api/v1/upload'); + xhr.open('POST', '/api/v1/pendulum/upload'); let formData = new FormData(this); xhr.send(formData); xhr.onreadystatechange = function () { @@ -43,7 +43,7 @@ document.getElementById('upload').onsubmit = function () { // function actuate(file) { let xhr = new XMLHttpRequest(); - xhr.open('POST', '/api/v1/actuate'); + xhr.open('POST', '/api/v1/pendulum/actuate'); let data = { file: file.file, }; @@ -72,7 +72,10 @@ function createDownload(response) { const tempName = response.filename; const downloadName = response.name.split('.')[0]; const downloadLink = document.createElement('a'); - downloadLink.setAttribute('href', `/api/v1/download/?filename=${tempName}`); + downloadLink.setAttribute( + 'href', + `/api/v1/pendulum/download/?filename=${tempName}` + ); downloadLink.setAttribute('download', `${downloadName}.csv`); downloadLink.innerText = 'Download CSV of results here.'; document.getElementById('download-link').appendChild(downloadLink); diff --git a/src/routes/pendulum.ts b/src/routes/api.ts index 66ad594..6cb804c 100644 --- a/src/routes/pendulum.ts +++ b/src/routes/api.ts @@ -222,13 +222,13 @@ api /** * Verify that the file exists and is a regular file so it can be sent to the user - * @param file The path to the file - * @param res The Express response object, used if the file is not accessible - * @returns `true` if the file exists and is a regular file,`false` otherwise + * @param {string} file The path to the file + * @param {Response} res The Express response object, used if the file is not accessible + * @returns {Promise<boolean>} `true` if the file exists and is a regular file,`false` otherwise * * `AFTER THIS POINT, THE API HAS ALREADY SENT A RESPONSE, SO THE FUNCTION THAT CALLED IT SHOULD NOT RETURN ANOTHER RESPONSE ` */ -async function verifyFile(file: string, res: Response) { +async function verifyFile(file: string, res: Response): Promise<boolean> { // Make sure the file being requested to run exists try { await access(file); diff --git a/src/routes/middleware/saml.ts b/src/routes/middleware/saml.ts new file mode 100644 index 0000000..ad9d50d --- /dev/null +++ b/src/routes/middleware/saml.ts @@ -0,0 +1,13 @@ +import BasicAuthenticator from 'umn-shib-nodejs'; +import { Request, Response, NextFunction } from 'express'; + +const saml = function (req: Request, res: Response, next: NextFunction): void { + const authenticator = new BasicAuthenticator(req, res); + if (!authenticator.hasSession()) { + authenticator.redirectToLogin(); + next(); + } + next(); +}; + +export default saml; |