From e9cc00f8947d3aea0f802a8b8d7f2e406c3fcb1f Mon Sep 17 00:00:00 2001 From: Matt Strapp Date: Fri, 11 Feb 2022 11:30:40 -0600 Subject: Finish upload API endpoint Signed-off-by: Matt Strapp --- src/index.ts | 4 ++-- src/public/js/form.js | 21 +++++++++++---------- src/routes/api.ts | 25 ++++++++++++------------- src/views/pages/about.ejs | 5 ++--- src/views/pages/index.ejs | 2 +- src/views/partials/head.ejs | 6 +++--- 6 files changed, 31 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/index.ts b/src/index.ts index bd2c7d5..1bf018f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,7 @@ const app = express(); // Rate limiting const rateLimiter = rateLimit({ windowMs: 1 * 60 * 1000, // 1 minute - max: 40, // Limit each IP to 100 requests per `window` (here, per 15 minutes) + max: 40, // Limit each IP to 40 requests per `window` (here, per 1 minutes) standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers legacyHeaders: false, // Disable the `X-RateLimit-*` headers }); @@ -30,7 +30,7 @@ const csrf = csurf({ cookie: true }); app.use(helmet()); // The API -app.use('/api', api); +app.use('/api/v1/', api); /* RENDERING */ diff --git a/src/public/js/form.js b/src/public/js/form.js index cfa80fd..7085422 100644 --- a/src/public/js/form.js +++ b/src/public/js/form.js @@ -1,17 +1,18 @@ +// File submit AJAX request document.getElementById('upload').onsubmit = function () { - var data = new FormData(document.getElementById('upload')); - var xhr = new XMLHttpRequest(); - xhr.open('POST', '/api/upload'); - xhr.send(data); + let xhr = new XMLHttpRequest(); + xhr.open('POST', '/api/v1/upload'); + let formData = new FormData(this); + xhr.send(formData); xhr.onreadystatechange = function () { - if (xhr.readyState == 4 && xhr.status == 200) { - var response = JSON.parse(xhr.responseText); - if (response.success) { - document.getElementById('success').style.display = 'block'; + if (xhr.readyState === 4) { + let response = JSON.parse(xhr.responseText); + if (xhr.status === 200) { + console.log(response); } else { - document.getElementById('error').style.display = 'block'; + console.log(response.error); } } }; return false; -}; +}; \ No newline at end of file diff --git a/src/routes/api.ts b/src/routes/api.ts index 4612c16..e360709 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -4,22 +4,21 @@ import cookieParser from 'cookie-parser'; import fileUpload, { UploadedFile } from 'express-fileupload'; import slowDown from 'express-slow-down'; +const api = express.Router(); + +// For file uploads +api.use(fileUpload()); // Slow down everything to prevent DoS attacks const speedLimiter = slowDown({ - windowMs: 5 * 60 * 1000, // 15 minutes - delayAfter: 50, // allow 100 requests per 5 minutes, then... + windowMs: 5 * 60 * 1000, // 5 minutes + delayAfter: 50, // allow 50 requests per 5 minutes, then... delayMs: 500 // begin adding 500ms of delay per request above 100: // request # 101 is delayed by 500ms // request # 102 is delayed by 1000ms // request # 103 is delayed by 1500ms // etc. }); - - -const api = express.Router(); - -api.use(fileUpload()); api.use(speedLimiter); // CSRF protection @@ -27,14 +26,14 @@ api.use(cookieParser()); const csrf = csurf({ cookie: true }); api.post('/upload', csrf, (req: Request, res: Response) => { + // Check if there is a file if (!req.files || Object.keys(req.files).length === 0) - return res.status(400).json({ err: 'ENOENT' }); - // Kludge to prevent a compiler error - const file: UploadedFile = req.files.file as UploadedFile; - console.log(file.mimetype); + return res.status(400).json({ error: 'No file uploaded' }); + const file: UploadedFile = req.files.file as UploadedFile; // Kludge to prevent a compiler error + // Check if the file is a python file if (file.mimetype !== 'text/x-python') - return res.status(400).json({ err: 'EINVAL' }); - res.status(200).json({ err: null }); + return res.status(400).json({ error: 'Not a Python file' }); + res.status(200).json({ file: file.name }); }); export default api; \ No newline at end of file diff --git a/src/views/pages/about.ejs b/src/views/pages/about.ejs index 022354c..2feede5 100644 --- a/src/views/pages/about.ejs +++ b/src/views/pages/about.ejs @@ -4,12 +4,12 @@ <%- include('../partials/head.ejs') %> + About the Remotely Accessible Inverted Pendulum <%- include('../partials/nav.ejs') %> - About the Remotely Accessible Inverted Pendulum
Pendulum logo

Remotely Accessible Inverted Pendulum

@@ -28,8 +28,7 @@

Background

- Our teams developed an inverted pendulum system that could be accessed over a computer network for use by students. The inverted pendulum is a common controls problem used in academia. This problem teaches students concepts of control loops, data filtering, - and machine learning, and web development. + Our teams developed an inverted pendulum system that could be accessed over a computer network for use by students. The inverted pendulum is a common controls problem used in academia. This problem teaches students concepts of control loops, data filtering, and machine learning.


What is an Inverted Pendulum?

diff --git a/src/views/pages/index.ejs b/src/views/pages/index.ejs index 0e6fe15..8b5f044 100644 --- a/src/views/pages/index.ejs +++ b/src/views/pages/index.ejs @@ -11,7 +11,7 @@ <%- include('../partials/nav.ejs') %>
-

Please upload a Python file (.py file extension) onto the Inverted Pendulum.

+

Please upload a Python file (.py file extension) to run on the Inverted Pendulum.



diff --git a/src/views/partials/head.ejs b/src/views/partials/head.ejs index 320f0e6..4a9d76a 100644 --- a/src/views/partials/head.ejs +++ b/src/views/partials/head.ejs @@ -1,6 +1,6 @@ - + - - \ No newline at end of file + + \ No newline at end of file -- cgit v1.2.3