From 148c8937906dd94f2effb1a059b41dec592cf548 Mon Sep 17 00:00:00 2001 From: Ambrose Chua Date: Tue, 16 Nov 2021 18:09:55 +0800 Subject: [PATCH] chore: Format code with prettier, bump dependencies --- .prettierignore | 1 + Dockerfile.env | 12 - assets/cmd.css | 6 +- assets/list.css | 26 +- assets/login.css | 25 +- assets/login.js | 85 ++-- assets/multi.js | 77 ++-- assets/navbar.css | 4 +- assets/shell.js | 101 ++--- assets/tooltip.js | 8 +- assets/upload.css | 8 +- assets/upload.js | 20 +- index.js | 986 +++++++++++++++++++++++++--------------------- package-lock.json | 330 +++++++++------- package.json | 15 +- 15 files changed, 922 insertions(+), 782 deletions(-) create mode 100644 .prettierignore delete mode 100644 Dockerfile.env diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..993c76d --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +views/**/*.handlebars diff --git a/Dockerfile.env b/Dockerfile.env deleted file mode 100644 index 3d7aef3..0000000 --- a/Dockerfile.env +++ /dev/null @@ -1,12 +0,0 @@ -FROM serverwentdown/env:alpine-node - -COPY . /usr/local/share/file-manager -RUN cd /usr/local/share/file-manager \ - && sudo npm install . - -USER ambrose - -ENV SHELL="zsh -l" -ENV NODE_ENV=production - -CMD ["node", "/usr/local/share/file-manager/index.js"] diff --git a/assets/cmd.css b/assets/cmd.css index 5f26890..6f59ce5 100644 --- a/assets/cmd.css +++ b/assets/cmd.css @@ -1,7 +1,7 @@ .cmd { - word-wrap: break-word; + word-wrap: break-word; } pre { - background-color: #eee; - min-height: 1.5em; + background-color: #eee; + min-height: 1.5em; } diff --git a/assets/list.css b/assets/list.css index d508986..0967b43 100644 --- a/assets/list.css +++ b/assets/list.css @@ -1,23 +1,23 @@ .name { - overflow: hidden; - word-wrap: break-word; + overflow: hidden; + word-wrap: break-word; } .badge-alignment { - margin-top: 0.25em; + margin-top: 0.25em; } .stretched-invisible-label { - display: block; + display: block; } .stretched-invisible-label > * { - position: relative; - z-index: 1; + position: relative; + z-index: 1; } .stretched-invisible-label::after { - content: ""; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 0; + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 0; } diff --git a/assets/login.css b/assets/login.css index 8d2cab9..2b1e0e1 100644 --- a/assets/login.css +++ b/assets/login.css @@ -1,22 +1,21 @@ .input-group-digits .form-control { - font-size: 2rem; - padding: 0.5rem 0; + font-size: 2rem; + padding: 0.5rem 0; - width: 2.75rem; - text-align: center; - font-weight: 300; + width: 2.75rem; + text-align: center; + font-weight: 300; } -.input-group-digits input[type=number] { - -moz-appearance: textfield; +.input-group-digits input[type="number"] { + -moz-appearance: textfield; } -.input-group-digits input[type=number]::-webkit-inner-spin-button, -.input-group-digits input[type=number]::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; +.input-group-digits input[type="number"]::-webkit-inner-spin-button, +.input-group-digits input[type="number"]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; } .login { - width: 19.2em; + width: 19.2em; } - diff --git a/assets/login.js b/assets/login.js index 1b04c7a..0ac9b7a 100644 --- a/assets/login.js +++ b/assets/login.js @@ -2,51 +2,52 @@ let $inputs = $(".input-group-digits"); $inputs.each((i, input) => { - let cleanup = () => { - $(input).find("input").each((i, ele) => { - let cleaned = $(ele).val().replace(/[^0-9]/, ""); - $(ele).val(cleaned); - }); - }; - let update = (e) => { - $digits = $(input).find("input"); + let cleanup = () => { + $(input) + .find("input") + .each((i, ele) => { + let cleaned = $(ele) + .val() + .replace(/[^0-9]/, ""); + $(ele).val(cleaned); + }); + }; + let update = (e) => { + $digits = $(input).find("input"); - // Cleanup - cleanup(); + // Cleanup + cleanup(); - // Shift characters - let excess = ""; - $digits.each((i, ele) => { - let now = excess + $(ele).val(); - $(ele).val(now.charAt(0)); - excess = now.substr(1); - }); + // Shift characters + let excess = ""; + $digits.each((i, ele) => { + let now = excess + $(ele).val(); + $(ele).val(now.charAt(0)); + excess = now.substr(1); + }); - // Move cursor to empty - $digits.each((i, ele) => { - if (!$(ele).val()) { - $(ele).focus(); - if (e.which == 8) { - $(ele).prev().focus().val(""); - } - return false; - } - }); + // Move cursor to empty + $digits.each((i, ele) => { + if (!$(ele).val()) { + $(ele).focus(); + if (e.which == 8) { + $(ele).prev().focus().val(""); + } + return false; + } + }); - // Submit if last digit is filled - if ($($digits[$digits.length - 1]).val()) { - let token = $.map( - $digits, - d => $(d).val() - ).join(""); - let $value = $(input).parent().find("#login-token-value"); - $value.val(token); - $value.closest("form").submit(); - } - }; + // Submit if last digit is filled + if ($($digits[$digits.length - 1]).val()) { + let token = $.map($digits, (d) => $(d).val()).join(""); + let $value = $(input).parent().find("#login-token-value"); + $value.val(token); + $value.closest("form").submit(); + } + }; - $digits = $(input).find("input"); - $digits.on("keyup", update); - $digits.on("change", update); - $digits.on("input", update); + $digits = $(input).find("input"); + $digits.on("keyup", update); + $digits.on("change", update); + $digits.on("input", update); }); diff --git a/assets/multi.js b/assets/multi.js index 71330d4..4cd13cc 100644 --- a/assets/multi.js +++ b/assets/multi.js @@ -1,51 +1,64 @@ /* jshint esversion: 6 */ function htmlEscape(text) { - const p = document.createElement('p'); - p.innerText = text; - return p.innerHTML; + const p = document.createElement("p"); + p.innerText = text; + return p.innerHTML; } let $select = $(".multi-select"); let setSelected = (files) => { - $(".multi-files-value").val(JSON.stringify(files.map(f => f.name))); - if (files.length == 0) { - $(".multi-files").html(`
  • No files selected
  • `); - return - } - $(".multi-files").html( - files.map(f => { - return ` + $(".multi-files-value").val(JSON.stringify(files.map((f) => f.name))); + if (files.length == 0) { + $(".multi-files").html( + `
  • No files selected
  • ` + ); + return; + } + $(".multi-files").html( + files + .map((f) => { + return `
  • ${htmlEscape(f.name)} - ${f.type == "directory" ? `` : `${filesize(f.size)}`} + ${ + f.type == "directory" + ? `` + : `${filesize( + f.size + )}` + }
  • `; - }).join("") - ); - const hasDirectory = files.reduce((a, f) => a || f.type == "directory", false); - const totalSize = files.map(f => f.size).reduce((a, b) => a + b); - if (hasDirectory) { - $(".multi-files-total").val(""); - } else { - $(".multi-files-total").val(filesize(totalSize)); - } + }) + .join("") + ); + const hasDirectory = files.reduce( + (a, f) => a || f.type == "directory", + false + ); + const totalSize = files.map((f) => f.size).reduce((a, b) => a + b); + if (hasDirectory) { + $(".multi-files-total").val(""); + } else { + $(".multi-files-total").val(filesize(totalSize)); + } }; const updateSelected = () => { - let $selected = $(".multi-select:checked"); - let files = []; - $selected.each((i, ele) => { - files.push({ - name: $(ele).data("select"), - type: $(ele).data("select-type"), - size: $(ele).data("select-size") - }); - }); + let $selected = $(".multi-select:checked"); + let files = []; + $selected.each((i, ele) => { + files.push({ + name: $(ele).data("select"), + type: $(ele).data("select-type"), + size: $(ele).data("select-size"), + }); + }); - setSelected(files); -} + setSelected(files); +}; $select.on("change", updateSelected); updateSelected(); diff --git a/assets/navbar.css b/assets/navbar.css index a17b84d..14ed39e 100644 --- a/assets/navbar.css +++ b/assets/navbar.css @@ -1,6 +1,6 @@ #navbar { - overflow-x: auto; + overflow-x: auto; } .nav-link { - white-space: nowrap; + white-space: nowrap; } diff --git a/assets/shell.js b/assets/shell.js index 9293e52..b411786 100644 --- a/assets/shell.js +++ b/assets/shell.js @@ -4,53 +4,62 @@ const $shell = $("#shell"); const $close = $("#shell-close"); if ($shell.length > 0) { + const ws = new WebSocket( + "ws" + + (window.location.protocol === "https:" ? "s" : "") + + "://" + + window.location.host + + "/websocket?path=" + + encodeURIComponent($shell.data("path")) + ); - const ws = new WebSocket("ws" + (window.location.protocol === "https:" ? "s" : "") + "://" + window.location.host + "/websocket?path=" + encodeURIComponent($shell.data("path"))); + const term = new Terminal(); + const attachAddon = new AttachAddon.AttachAddon(ws, { bidirectional: true }); + term.loadAddon(attachAddon); + const fitAddon = new FitAddon.FitAddon(); + term.loadAddon(fitAddon); + term.open($shell[0]); - const term = new Terminal(); - const attachAddon = new AttachAddon.AttachAddon(ws, { bidirectional: true }); - term.loadAddon(attachAddon); - const fitAddon = new FitAddon.FitAddon(); - term.loadAddon(fitAddon); - term.open($shell[0]); - - ws.addEventListener("open", () => { - - // resize - term.onResize(({ cols, rows }) => { - console.debug(cols, rows); - const buf = Uint16Array.of(0, cols, rows); - ws.send(buf); - }); - $(window).on("resize", () => { - fitAddon.fit(); - }); - fitAddon.fit(); - - // close - let closeTimeout = null; - $close.on("click", (e) => { - e.preventDefault(); - if (ws.readyState !== 1) { - window.location.pathname = window.location.pathname.replace("@shell", ""); - } else { - ws.close(); - } - }); - ws.addEventListener("close", () => { - term.write("\r\n\r\nclosing shell in 2 seconds..."); - closeTimeout = setTimeout(() => { - window.location.pathname = window.location.pathname.replace("@shell", ""); - }, 2000); - }); - term.onData(() => { - if (closeTimeout != null) { - clearTimeout(closeTimeout); - term.write("\r\nkeyboard input detected. timeout canceled"); - closeTimeout = null; - } - }); - - }); + ws.addEventListener("open", () => { + // resize + term.onResize(({ cols, rows }) => { + console.debug(cols, rows); + const buf = Uint16Array.of(0, cols, rows); + ws.send(buf); + }); + $(window).on("resize", () => { + fitAddon.fit(); + }); + fitAddon.fit(); + // close + let closeTimeout = null; + $close.on("click", (e) => { + e.preventDefault(); + if (ws.readyState !== 1) { + window.location.pathname = window.location.pathname.replace( + "@shell", + "" + ); + } else { + ws.close(); + } + }); + ws.addEventListener("close", () => { + term.write("\r\n\r\nclosing shell in 2 seconds..."); + closeTimeout = setTimeout(() => { + window.location.pathname = window.location.pathname.replace( + "@shell", + "" + ); + }, 2000); + }); + term.onData(() => { + if (closeTimeout != null) { + clearTimeout(closeTimeout); + term.write("\r\nkeyboard input detected. timeout canceled"); + closeTimeout = null; + } + }); + }); } diff --git a/assets/tooltip.js b/assets/tooltip.js index 579a680..ecc71db 100644 --- a/assets/tooltip.js +++ b/assets/tooltip.js @@ -1,7 +1,7 @@ /* jshint esversion: 6 */ -document.querySelectorAll("[title]").forEach(element => { - new bootstrap.Tooltip(element, { - delay: 500, - }); +document.querySelectorAll("[title]").forEach((element) => { + new bootstrap.Tooltip(element, { + delay: 500, + }); }); diff --git a/assets/upload.css b/assets/upload.css index 493985a..88d13e3 100644 --- a/assets/upload.css +++ b/assets/upload.css @@ -1,6 +1,6 @@ .custom-file-label { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - padding-right: 5.4em; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 5.4em; } diff --git a/assets/upload.js b/assets/upload.js index 5165d03..5e5f21c 100644 --- a/assets/upload.js +++ b/assets/upload.js @@ -1,22 +1,22 @@ /* jshint esversion: 6 */ const $form = $("form[action='@upload']"); -const $file = $("#upload-file"); +const $file = $("#upload-file"); $(".upload-unhide").fadeOut(); $file.on("change", () => { - const file = $file[0].files[0]; - const fnElement = $file.parent().find(".custom-file-label"); - fnElement.addClass("file-selected"); - fnElement.text(file.name); + const file = $file[0].files[0]; + const fnElement = $file.parent().find(".custom-file-label"); + fnElement.addClass("file-selected"); + fnElement.text(file.name); - $form.find("#upload-file-size").val(filesize(file.size)); - $form.find("[name=saveas]").val(file.name); - $(".upload-unhide").fadeIn(); + $form.find("#upload-file-size").val(filesize(file.size)); + $form.find("[name=saveas]").val(file.name); + $(".upload-unhide").fadeIn(); }); $form.on("submit", () => { - let putresource = $form.find("[name=saveas]").val(); - // TODO: do XHR to PUT at putresource + let putresource = $form.find("[name=saveas]").val(); + // TODO: do XHR to PUT at putresource }); diff --git a/index.js b/index.js index 0abc313..9aa0caa 100755 --- a/index.js +++ b/index.js @@ -5,7 +5,7 @@ "use strict"; const express = require("express"); -const hbs = require("express-handlebars"); +const { engine: hbs } = require("express-handlebars"); const bodyparser = require("body-parser"); const session = require("express-session"); const busboy = require("connect-busboy"); @@ -25,541 +25,615 @@ const filesize = require("filesize"); const octicons = require("octicons"); const handlebars = require("handlebars"); +const port = +process.env.PORT || 8080; + let app = express(); -let http = app.listen(process.env.PORT || 8080); +let http = app.listen(port); app.set("views", path.join(__dirname, "views")); -app.engine("handlebars", hbs({ - partialsDir: path.join(__dirname, "views", "partials"), - layoutsDir: path.join(__dirname, "views", "layouts"), - defaultLayout: "main", - helpers: { - either: function(a, b, options) { - if (a || b) { - return options.fn(this); - } - }, - filesize: filesize, - octicon: function(i, options) { - if (!octicons[i]) { - return new handlebars.SafeString(octicons.question.toSVG()); - } - return new handlebars.SafeString(octicons[i].toSVG()); - }, - eachpath: function (path, options) { - if (typeof path != "string") { - return ""; - } - let out = ""; - path = path.split("/"); - path.splice(path.length - 1, 1); - path.unshift(""); - path.forEach((folder, index) => { - out += options.fn({ - name: folder + "/", - path: "/" + path.slice(1, index + 1).join("/"), - current: index === path.length - 1 - }); - }); - return out; - }, - } -})); +app.engine( + "handlebars", + hbs({ + partialsDir: path.join(__dirname, "views", "partials"), + layoutsDir: path.join(__dirname, "views", "layouts"), + defaultLayout: "main", + helpers: { + either: function (a, b, options) { + if (a || b) { + return options.fn(this); + } + }, + filesize: filesize, + octicon: function (i, options) { + if (!octicons[i]) { + return new handlebars.SafeString(octicons.question.toSVG()); + } + return new handlebars.SafeString(octicons[i].toSVG()); + }, + eachpath: function (path, options) { + if (typeof path != "string") { + return ""; + } + let out = ""; + path = path.split("/"); + path.splice(path.length - 1, 1); + path.unshift(""); + path.forEach((folder, index) => { + out += options.fn({ + name: folder + "/", + path: "/" + path.slice(1, index + 1).join("/"), + current: index === path.length - 1, + }); + }); + return out; + }, + }, + }) +); app.set("view engine", "handlebars"); app.use("/@assets", express.static(path.join(__dirname, "assets"))); -app.use("/@assets/bootstrap", express.static(path.join(__dirname, "node_modules/bootstrap/dist"))); -app.use("/@assets/octicons", express.static(path.join(__dirname, "node_modules/octicons/build"))); -app.use("/@assets/jquery", express.static(path.join(__dirname, "node_modules/jquery/dist"))); -app.use("/@assets/filesize", express.static(path.join(__dirname, "node_modules/filesize/lib"))); -app.use("/@assets/xterm", express.static(path.join(__dirname, "node_modules/xterm"))); -app.use("/@assets/xterm-addon-attach", express.static(path.join(__dirname, "node_modules/xterm-addon-attach"))); -app.use("/@assets/xterm-addon-fit", express.static(path.join(__dirname, "node_modules/xterm-addon-fit"))); +app.use( + "/@assets/bootstrap", + express.static(path.join(__dirname, "node_modules/bootstrap/dist")) +); +app.use( + "/@assets/octicons", + express.static(path.join(__dirname, "node_modules/octicons/build")) +); +app.use( + "/@assets/jquery", + express.static(path.join(__dirname, "node_modules/jquery/dist")) +); +app.use( + "/@assets/filesize", + express.static(path.join(__dirname, "node_modules/filesize/lib")) +); +app.use( + "/@assets/xterm", + express.static(path.join(__dirname, "node_modules/xterm")) +); +app.use( + "/@assets/xterm-addon-attach", + express.static(path.join(__dirname, "node_modules/xterm-addon-attach")) +); +app.use( + "/@assets/xterm-addon-fit", + express.static(path.join(__dirname, "node_modules/xterm-addon-fit")) +); -app.use(session({ - secret: process.env.SESSION_KEY || "meowmeow" -})); +app.use( + session({ + secret: process.env.SESSION_KEY || "meowmeow", + }) +); app.use(flash()); app.use(busboy()); app.use(bodyparser.urlencoded()); // AUTH -const KEY = process.env.KEY ? base32.decode(process.env.KEY.replace(/ /g, "")) : null; +const KEY = process.env.KEY + ? base32.decode(process.env.KEY.replace(/ /g, "")) + : null; app.get("/@logout", (req, res) => { - if (KEY) { - req.session.login = false; - req.flash("success", "Signed out."); - res.redirect("/@login"); - return - } - req.flash("error", "You were never logged in..."); - res.redirect("back"); + if (KEY) { + req.session.login = false; + req.flash("success", "Signed out."); + res.redirect("/@login"); + return; + } + req.flash("error", "You were never logged in..."); + res.redirect("back"); }); app.get("/@login", (req, res) => { - res.render("login", flashify(req, {})); + res.render("login", flashify(req, {})); }); app.post("/@login", (req, res) => { - let pass = notp.totp.verify(req.body.token.replace(" ", ""), KEY); - if (pass) { - req.session.login = true; - res.redirect("/"); - return; - } - req.flash("error", "Bad token."); - res.redirect("/@login"); + let pass = notp.totp.verify(req.body.token.replace(" ", ""), KEY); + if (pass) { + req.session.login = true; + res.redirect("/"); + return; + } + req.flash("error", "Bad token."); + res.redirect("/@login"); }); app.use((req, res, next) => { - if (!KEY) { - return next(); - } - if (req.session.login === true) { - return next(); - } - req.flash("error", "Please sign in."); - res.redirect("/@login"); + if (!KEY) { + return next(); + } + if (req.session.login === true) { + return next(); + } + req.flash("error", "Please sign in."); + res.redirect("/@login"); }); function relative(...paths) { - return paths.reduce((a, b) => path.join(a, b), process.cwd()); + return paths.reduce((a, b) => path.join(a, b), process.cwd()); } function flashify(req, obj) { - let error = req.flash("error"); - if (error && error.length > 0) { - if (!obj.errors) { - obj.errors = []; - } - obj.errors.push(error); - } - let success = req.flash("success"); - if (success && success.length > 0) { - if (!obj.successes) { - obj.successes = []; - } - obj.successes.push(success); - } - obj.isloginenabled = !!KEY; - return obj; + let error = req.flash("error"); + if (error && error.length > 0) { + if (!obj.errors) { + obj.errors = []; + } + obj.errors.push(error); + } + let success = req.flash("success"); + if (success && success.length > 0) { + if (!obj.successes) { + obj.successes = []; + } + obj.successes.push(success); + } + obj.isloginenabled = !!KEY; + return obj; } app.all("/*", (req, res, next) => { - res.filename = req.params[0]; + res.filename = req.params[0]; - let fileExists = new Promise((resolve, reject) => { - // check if file exists - fs.stat(relative(res.filename), (err, stats) => { - if (err) { - return reject(err); - } - return resolve(stats); - }); - }); + let fileExists = new Promise((resolve, reject) => { + // check if file exists + fs.stat(relative(res.filename), (err, stats) => { + if (err) { + return reject(err); + } + return resolve(stats); + }); + }); - fileExists.then((stats) => { - res.stats = stats; - next(); - }).catch((err) => { - res.stats = { error: err }; - next(); - }); + fileExists + .then((stats) => { + res.stats = stats; + next(); + }) + .catch((err) => { + res.stats = { error: err }; + next(); + }); }); app.post("/*@upload", (req, res) => { - res.filename = req.params[0]; + res.filename = req.params[0]; - let buff = null; - let saveas = null; - req.busboy.on("file", (key, stream, filename) => { - if (key == "file") { - let buffs = []; - stream.on("data", (d) => { - buffs.push(d); - }); - stream.on("end", () => { - buff = Buffer.concat(buffs); - buffs = null; - }); - } - }); - req.busboy.on("field", (key, value) => { - if (key == "saveas") { - saveas = value; - } - }); - req.busboy.on("finish", () => { - if (!buff || !saveas) { - return res.status(400).end(); - } - let fileExists = new Promise((resolve, reject) => { - // check if file exists - fs.stat(relative(res.filename, saveas), (err, stats) => { - if (err) { - return reject(err); - } - return resolve(stats); - }); - }); + let buff = null; + let saveas = null; + req.busboy.on("file", (key, stream, filename) => { + if (key == "file") { + let buffs = []; + stream.on("data", (d) => { + buffs.push(d); + }); + stream.on("end", () => { + buff = Buffer.concat(buffs); + buffs = null; + }); + } + }); + req.busboy.on("field", (key, value) => { + if (key == "saveas") { + saveas = value; + } + }); + req.busboy.on("finish", () => { + if (!buff || !saveas) { + return res.status(400).end(); + } + let fileExists = new Promise((resolve, reject) => { + // check if file exists + fs.stat(relative(res.filename, saveas), (err, stats) => { + if (err) { + return reject(err); + } + return resolve(stats); + }); + }); - fileExists.then((stats) => { - console.warn("file exists, cannot overwrite"); - req.flash("error", "File exists, cannot overwrite. "); - res.redirect("back"); - }).catch((err) => { - const saveName = relative(res.filename, saveas); - console.log("saving file to " + saveName); - let save = fs.createWriteStream(saveName); - save.on("close", () => { - if (res.headersSent) { - return; - } - if (buff.length === 0) { - req.flash("success", "File saved. Warning: empty file."); - } - else { - buff = null; - req.flash("success", "File saved. "); - } - res.redirect("back"); - }); - save.on("error", (err) => { - console.warn(err); - req.flash("error", err.toString()); - res.redirect("back"); - }); - save.write(buff); - save.end(); - }); - }); - req.pipe(req.busboy); + fileExists + .then((stats) => { + console.warn("file exists, cannot overwrite"); + req.flash("error", "File exists, cannot overwrite. "); + res.redirect("back"); + }) + .catch((err) => { + const saveName = relative(res.filename, saveas); + console.log("saving file to " + saveName); + let save = fs.createWriteStream(saveName); + save.on("close", () => { + if (res.headersSent) { + return; + } + if (buff.length === 0) { + req.flash("success", "File saved. Warning: empty file."); + } else { + buff = null; + req.flash("success", "File saved. "); + } + res.redirect("back"); + }); + save.on("error", (err) => { + console.warn(err); + req.flash("error", err.toString()); + res.redirect("back"); + }); + save.write(buff); + save.end(); + }); + }); + req.pipe(req.busboy); }); app.post("/*@mkdir", (req, res) => { - res.filename = req.params[0]; + res.filename = req.params[0]; - let folder = req.body.folder; - if (!folder || folder.length < 1) { - return res.status(400).end(); - } + let folder = req.body.folder; + if (!folder || folder.length < 1) { + return res.status(400).end(); + } - let fileExists = new Promise((resolve, reject) => { - // Check if file exists - fs.stat(relative(res.filename, folder), (err, stats) => { - if (err) { - return reject(err); - } - return resolve(stats); - }); - }); + let fileExists = new Promise((resolve, reject) => { + // Check if file exists + fs.stat(relative(res.filename, folder), (err, stats) => { + if (err) { + return reject(err); + } + return resolve(stats); + }); + }); - fileExists.then((stats) => { - req.flash("error", "Folder exists, cannot overwrite. "); - res.redirect("back"); - }).catch((err) => { - fs.mkdir(relative(res.filename, folder), (err) => { - if (err) { - console.warn(err); - req.flash("error", err.toString()); - res.redirect("back"); - return; - } - req.flash("success", "Folder created. "); - res.redirect("back"); - }); - }); + fileExists + .then((stats) => { + req.flash("error", "Folder exists, cannot overwrite. "); + res.redirect("back"); + }) + .catch((err) => { + fs.mkdir(relative(res.filename, folder), (err) => { + if (err) { + console.warn(err); + req.flash("error", err.toString()); + res.redirect("back"); + return; + } + req.flash("success", "Folder created. "); + res.redirect("back"); + }); + }); }); app.post("/*@delete", (req, res) => { - res.filename = req.params[0]; + res.filename = req.params[0]; - let files = JSON.parse(req.body.files); - if (!files || !files.map) { - req.flash("error", "No files selected."); - res.redirect("back"); - return; // res.status(400).end(); - } + let files = JSON.parse(req.body.files); + if (!files || !files.map) { + req.flash("error", "No files selected."); + res.redirect("back"); + return; // res.status(400).end(); + } - let promises = files.map(f => { - return new Promise((resolve, reject) => { - fs.stat(relative(res.filename, f), (err, stats) => { - if (err) { - return reject(err); - } - resolve({ - name: f, - isdirectory: stats.isDirectory(), - isfile: stats.isFile() - }); - }); - }); - }); - Promise.all(promises).then((files) => { - let promises = files.map(f => { - return new Promise((resolve, reject) => { - let op = null; - if (f.isdirectory) { - op = (dir, cb) => rimraf(dir, { - glob: false - }, cb); - } - else if (f.isfile) { - op = fs.unlink; - } - if (op) { - op(relative(res.filename, f.name), (err) => { - if (err) { - return reject(err); - } - resolve(); - }); - } - }); - }); - Promise.all(promises).then(() => { - req.flash("success", "Files deleted. "); - res.redirect("back"); - }).catch((err) => { - console.warn(err); - req.flash("error", "Unable to delete some files: " + err); - res.redirect("back"); - }); - }).catch((err) => { - console.warn(err); - req.flash("error", err.toString()); - res.redirect("back"); - }); + let promises = files.map((f) => { + return new Promise((resolve, reject) => { + fs.stat(relative(res.filename, f), (err, stats) => { + if (err) { + return reject(err); + } + resolve({ + name: f, + isdirectory: stats.isDirectory(), + isfile: stats.isFile(), + }); + }); + }); + }); + Promise.all(promises) + .then((files) => { + let promises = files.map((f) => { + return new Promise((resolve, reject) => { + let op = null; + if (f.isdirectory) { + op = (dir, cb) => + rimraf( + dir, + { + glob: false, + }, + cb + ); + } else if (f.isfile) { + op = fs.unlink; + } + if (op) { + op(relative(res.filename, f.name), (err) => { + if (err) { + return reject(err); + } + resolve(); + }); + } + }); + }); + Promise.all(promises) + .then(() => { + req.flash("success", "Files deleted. "); + res.redirect("back"); + }) + .catch((err) => { + console.warn(err); + req.flash("error", "Unable to delete some files: " + err); + res.redirect("back"); + }); + }) + .catch((err) => { + console.warn(err); + req.flash("error", err.toString()); + res.redirect("back"); + }); }); app.get("/*@download", (req, res) => { - res.filename = req.params[0]; + res.filename = req.params[0]; - let files = null; - try { - files = JSON.parse(req.query.files); - } catch (e) {} - if (!files || !files.map) { - req.flash("error", "No files selected."); - res.redirect("back"); - return; // res.status(400).end(); - } + let files = null; + try { + files = JSON.parse(req.query.files); + } catch (e) {} + if (!files || !files.map) { + req.flash("error", "No files selected."); + res.redirect("back"); + return; // res.status(400).end(); + } - let promises = files.map(f => { - return new Promise((resolve, reject) => { - fs.stat(relative(res.filename, f), (err, stats) => { - if (err) { - return reject(err); - } - resolve({ - name: f, - isdirectory: stats.isDirectory(), - isfile: stats.isFile() - }); - }); - }); - }); - Promise.all(promises).then((files) => { - let zip = archiver("zip", {}); - zip.on("error", function(err) { - console.warn(err); - res.status(500).send({ - error: err.message - }); - }); + let promises = files.map((f) => { + return new Promise((resolve, reject) => { + fs.stat(relative(res.filename, f), (err, stats) => { + if (err) { + return reject(err); + } + resolve({ + name: f, + isdirectory: stats.isDirectory(), + isfile: stats.isFile(), + }); + }); + }); + }); + Promise.all(promises) + .then((files) => { + let zip = archiver("zip", {}); + zip.on("error", function (err) { + console.warn(err); + res.status(500).send({ + error: err.message, + }); + }); - files.filter(f => f.isfile).forEach((f) => { - zip.file(relative(res.filename, f.name), { name: f.name }); - }); - files.filter(f => f.isdirectory).forEach((f) => { - zip.directory(relative(res.filename, f.name), f.name); - }); + files + .filter((f) => f.isfile) + .forEach((f) => { + zip.file(relative(res.filename, f.name), { name: f.name }); + }); + files + .filter((f) => f.isdirectory) + .forEach((f) => { + zip.directory(relative(res.filename, f.name), f.name); + }); - res.attachment("Archive.zip"); - zip.pipe(res); + res.attachment("Archive.zip"); + zip.pipe(res); - zip.finalize(); - }).catch((err) => { - console.warn(err); - req.flash("error", err.toString()); - res.redirect("back"); - }); + zip.finalize(); + }) + .catch((err) => { + console.warn(err); + req.flash("error", err.toString()); + res.redirect("back"); + }); }); const shellable = process.env.SHELL != "false" && process.env.SHELL; const cmdable = process.env.CMD != "false" && process.env.CMD; if (shellable || cmdable) { - const shellArgs = process.env.SHELL.split(" "); - const exec = process.env.SHELL == "login" ? "/usr/bin/env" : shellArgs[0]; - const args = process.env.SHELL == "login" ? ["login"] : shellArgs.slice(1); + const shellArgs = process.env.SHELL.split(" "); + const exec = process.env.SHELL == "login" ? "/usr/bin/env" : shellArgs[0]; + const args = process.env.SHELL == "login" ? ["login"] : shellArgs.slice(1); - const child_process = require("child_process"); + const child_process = require("child_process"); - app.post("/*@cmd", (req, res) => { - res.filename = req.params[0]; + app.post("/*@cmd", (req, res) => { + res.filename = req.params[0]; - let cmd = req.body.cmd; - if (!cmd || cmd.length < 1) { - return res.status(400).end(); - } - console.log("running command " + cmd); + let cmd = req.body.cmd; + if (!cmd || cmd.length < 1) { + return res.status(400).end(); + } + console.log("running command " + cmd); - child_process.exec(cmd, { - cwd: relative(res.filename), - timeout: 60 * 1000, - }, (err, stdout, stderr) => { - if (err) { - console.log("command run failed: " + JSON.stringify(err)); - req.flash("error", "Command failed due to non-zero exit code"); - } - res.render("cmd", flashify(req, { - path: res.filename, - cmd: cmd, - stdout: stdout, - stderr: stderr, - })); - }); - }); + child_process.exec( + cmd, + { + cwd: relative(res.filename), + timeout: 60 * 1000, + }, + (err, stdout, stderr) => { + if (err) { + console.log("command run failed: " + JSON.stringify(err)); + req.flash("error", "Command failed due to non-zero exit code"); + } + res.render( + "cmd", + flashify(req, { + path: res.filename, + cmd: cmd, + stdout: stdout, + stderr: stderr, + }) + ); + } + ); + }); - const pty = require("node-pty"); - const WebSocket = require("ws"); + const pty = require("node-pty"); + const WebSocket = require("ws"); - app.get("/*@shell", (req, res) => { - res.filename = req.params[0]; + app.get("/*@shell", (req, res) => { + res.filename = req.params[0]; - res.render("shell", flashify(req, { - path: res.filename, - })); - }); + res.render( + "shell", + flashify(req, { + path: res.filename, + }) + ); + }); - const ws = new WebSocket.Server({ server: http }); - ws.on("connection", (socket, request) => { - const { path } = querystring.parse(request.url.split("?")[1]); - let cwd = relative(path); - let term = pty.spawn(exec, args, { - name: "xterm-256color", - cols: 80, - rows: 30, - cwd: cwd, - }); - console.log("pid " + term.pid + " shell " + process.env.SHELL + " started in " + cwd); + const ws = new WebSocket.Server({ server: http }); + ws.on("connection", (socket, request) => { + const { path } = querystring.parse(request.url.split("?")[1]); + let cwd = relative(path); + let term = pty.spawn(exec, args, { + name: "xterm-256color", + cols: 80, + rows: 30, + cwd: cwd, + }); + console.log( + "pid " + term.pid + " shell " + process.env.SHELL + " started in " + cwd + ); - term.on("data", (data) => { - socket.send(data, { binary: true }); - }); - term.on("exit", (code) => { - console.log("pid " + term.pid + " ended") - socket.close(); - }); - socket.on("message", (data) => { - // special messages should decode to Buffers - if (Buffer.isBuffer(data)) { - switch (data.readUInt16BE(0)) { - case 0: - term.resize(data.readUInt16BE(1), data.readUInt16BE(2)); - return; - } - } - term.write(data); - }); - socket.on("close", () => { - term.end(); - }); - }); + term.on("data", (data) => { + socket.send(data, { binary: true }); + }); + term.on("exit", (code) => { + console.log("pid " + term.pid + " ended"); + socket.close(); + }); + socket.on("message", (data) => { + // special messages should decode to Buffers + if (Buffer.isBuffer(data)) { + switch (data.readUInt16BE(0)) { + case 0: + term.resize(data.readUInt16BE(1), data.readUInt16BE(2)); + return; + } + } + term.write(data); + }); + socket.on("close", () => { + term.end(); + }); + }); } -const SMALL_IMAGE_MAX_SIZE = 750 * 1024; // 750 KB +const SMALL_IMAGE_MAX_SIZE = 750 * 1024; // 750 KB const EXT_IMAGES = [".jpg", ".jpeg", ".png", ".webp", ".svg", ".gif", ".tiff"]; function isimage(f) { - for (const ext of EXT_IMAGES) { - if (f.endsWith(ext)) { - return true; - } - } - return false; + for (const ext of EXT_IMAGES) { + if (f.endsWith(ext)) { + return true; + } + } + return false; } app.get("/*", (req, res) => { - if (res.stats.error) { - res.render("list", flashify(req, { - shellable: shellable, - cmdable: cmdable, - path: res.filename, - errors: [ - res.stats.error - ] - })); - } - else if (res.stats.isDirectory()) { - if (!req.url.endsWith("/")) { - return res.redirect(req.url + "/"); - } + if (res.stats.error) { + res.render( + "list", + flashify(req, { + shellable: shellable, + cmdable: cmdable, + path: res.filename, + errors: [res.stats.error], + }) + ); + } else if (res.stats.isDirectory()) { + if (!req.url.endsWith("/")) { + return res.redirect(req.url + "/"); + } - let readDir = new Promise((resolve, reject) => { - fs.readdir(relative(res.filename), (err, filenames) => { - if (err) { - return reject(err); - } - return resolve(filenames); - }); - }); + let readDir = new Promise((resolve, reject) => { + fs.readdir(relative(res.filename), (err, filenames) => { + if (err) { + return reject(err); + } + return resolve(filenames); + }); + }); - readDir.then((filenames) => { - const promises = filenames.map(f => new Promise((resolve, reject) => { - fs.stat(relative(res.filename, f), (err, stats) => { - if (err) { - console.warn(err); - return resolve({ - name: f, - error: err - }); - } - resolve({ - name: f, - isdirectory: stats.isDirectory(), - issmallimage: isimage(f) && stats.size < SMALL_IMAGE_MAX_SIZE, - size: stats.size - }); - }); - })); + readDir + .then((filenames) => { + const promises = filenames.map( + (f) => + new Promise((resolve, reject) => { + fs.stat(relative(res.filename, f), (err, stats) => { + if (err) { + console.warn(err); + return resolve({ + name: f, + error: err, + }); + } + resolve({ + name: f, + isdirectory: stats.isDirectory(), + issmallimage: isimage(f) && stats.size < SMALL_IMAGE_MAX_SIZE, + size: stats.size, + }); + }); + }) + ); - Promise.all(promises).then((files) => { - res.render("list", flashify(req, { - shellable: shellable, - cmdable: cmdable, - path: res.filename, - files: files, - })); - }).catch((err) => { - console.error(err); - res.render("list", flashify(req, { - shellable: shellable, - cmdable: cmdable, - path: res.filename, - errors: [ - err - ] - })); - }); - }).catch((err) => { - console.warn(err); - res.render("list", flashify(req, { - shellable: shellable, - cmdable: cmdable, - path: res.filename, - errors: [ - err - ] - })); - }); - } - else if (res.stats.isFile()) { - res.sendFile(relative(res.filename), { - headers: { - "Content-Security-Policy": "default-src 'self'; script-src 'none'; sandbox" - }, - dotfiles: "allow" - }); - } + Promise.all(promises) + .then((files) => { + res.render( + "list", + flashify(req, { + shellable: shellable, + cmdable: cmdable, + path: res.filename, + files: files, + }) + ); + }) + .catch((err) => { + console.error(err); + res.render( + "list", + flashify(req, { + shellable: shellable, + cmdable: cmdable, + path: res.filename, + errors: [err], + }) + ); + }); + }) + .catch((err) => { + console.warn(err); + res.render( + "list", + flashify(req, { + shellable: shellable, + cmdable: cmdable, + path: res.filename, + errors: [err], + }) + ); + }); + } else if (res.stats.isFile()) { + res.sendFile(relative(res.filename), { + headers: { + "Content-Security-Policy": + "default-src 'self'; script-src 'none'; sandbox", + }, + dotfiles: "allow", + }); + } }); +console.log(`Listening on port ${port}`); diff --git a/package-lock.json b/package-lock.json index 6dab7da..6bc5128 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "file-manager", - "version": "0.0.7a", + "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "file-manager", - "version": "0.0.7a", + "version": "0.1.0", "dependencies": { "archiver": "^5.3.0", "body-parser": "^1.19.0", @@ -14,9 +14,9 @@ "connect-busboy": "^0.0.2", "connect-flash": "^0.1.1", "express": "^4.17.1", - "express-handlebars": "^5.3.2", - "express-session": "^1.17.1", - "filesize": "^6.3.0", + "express-handlebars": "^6.0.1", + "express-session": "^1.17.2", + "filesize": "^8.0.6", "jquery": "^3.6.0", "node-pty": "^0.10.1", "notp": "^2.0.3", @@ -30,12 +30,15 @@ }, "bin": { "file-manager": "index.js" + }, + "devDependencies": { + "prettier": "^2.4.1" } }, "node_modules/@popperjs/core": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz", - "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz", + "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==", "peer": true, "funding": { "type": "opencollective", @@ -119,9 +122,9 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "node_modules/async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", + "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" }, "node_modules/balanced-match": { "version": "1.0.2", @@ -178,15 +181,15 @@ } }, "node_modules/bootstrap": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.0.tgz", - "integrity": "sha512-tmhPET9B9qCl8dCofvHeiIhi49iBt0EehmIsziZib65k1erBW1rHhj2s/2JsuQh5Pq+xz2E9bEbzp9B7xHG+VA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", + "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", "funding": { "type": "opencollective", "url": "https://opencollective.com/bootstrap" }, "peerDependencies": { - "@popperjs/core": "^2.9.2" + "@popperjs/core": "^2.10.2" } }, "node_modules/brace-expansion": { @@ -249,12 +252,12 @@ } }, "node_modules/compress-commons": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.0.tgz", - "integrity": "sha512-ofaaLqfraD1YRTkrRKPCrGJ1pFeDG/MVCkVVV2FNGeWquSlqw5wOrwOfPQ1xF2u+blpeWASie5EubHz+vsNIgA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "dependencies": { "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.1", + "crc32-stream": "^4.0.2", "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" }, @@ -319,9 +322,9 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/crc-32": { "version": "1.2.0", @@ -465,36 +468,44 @@ } }, "node_modules/express-handlebars": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-5.3.2.tgz", - "integrity": "sha512-iGR7HXP+x+SfJQo9m00ocqcr7hU8ZzcssTLE/4wBX+jsqcblO6sFJEbEAEFjiNze3XMz9Y26Zs1WN5Bb4zxivQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-6.0.1.tgz", + "integrity": "sha512-K3Lemki5jkD3sZwDhgBEBk+oAl1xg4nsMJAfpq1AUl5K187/mU1/xKVWt+4RZAHAxlyQFk4YBfX5+00AzLNfWg==", "dependencies": { - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", + "glob": "^7.2.0", + "graceful-fs": "^4.2.8", "handlebars": "^4.7.7" }, "engines": { - "node": ">=v10.24.1" + "node": ">=v12.22.7" } }, "node_modules/express-session": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz", - "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==", + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", "dependencies": { - "cookie": "0.4.0", + "cookie": "0.4.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", "parseurl": "~1.3.3", - "safe-buffer": "5.2.0", + "safe-buffer": "5.2.1", "uid-safe": "~2.1.5" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/express-session/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express-session/node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -504,14 +515,28 @@ } }, "node_modules/express-session/node_modules/safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/filesize": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.3.0.tgz", - "integrity": "sha512-ytx0ruGpDHKWVoiui6+BY/QMNngtDQ/pJaFwfBpQif0J63+E8DLdFyqS3NkKQn7vIruUEpoGD9JUJSg7Kp+I0g==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.6.tgz", + "integrity": "sha512-sHvRqTiwdmcuzqet7iVwsbwF6UrV3wIgDf2SHNdY1Hgl8PC45HZg/0xtdw6U2izIV4lccnrY9ftl6wZFNdjYMg==", "engines": { "node": ">= 0.4.0" } @@ -534,9 +559,9 @@ } }, "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { "node": ">= 0.6" } @@ -560,9 +585,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -579,9 +604,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "node_modules/handlebars": { "version": "4.7.7", @@ -686,9 +711,9 @@ "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" }, "node_modules/lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dependencies": { "readable-stream": "^2.0.5" }, @@ -776,19 +801,19 @@ } }, "node_modules/mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dependencies": { - "mime-db": "1.47.0" + "mime-db": "1.51.0" }, "engines": { "node": ">= 0.6" @@ -816,9 +841,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "node_modules/negotiator": { "version": "0.6.2", @@ -923,6 +948,18 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "node_modules/prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/printj": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", @@ -940,11 +977,11 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { @@ -1176,9 +1213,9 @@ } }, "node_modules/uglify-js": { - "version": "3.13.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz", - "integrity": "sha512-xtB8yEqIkn7zmOyS2zUNBsYCBRhDkvlNxMMY2smuJ/qA8NCHeQvKCF3i9Z4k8FJH4+PJvZRtMrPynfZ75+CSZw==", + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz", + "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -1238,9 +1275,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", "engines": { "node": ">=8.3.0" }, @@ -1258,9 +1295,9 @@ } }, "node_modules/xterm": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.11.0.tgz", - "integrity": "sha512-NeJH909WTO2vth/ZlC0gkP3AGzupbvVHVlmtrpBw56/sGFXaF9bNdKgqKa3tf8qbGvXMzL2JhCcHVklqFztIRw==" + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.15.0.tgz", + "integrity": "sha512-Ik1GoSq1yqKZQ2LF37RPS01kX9t4TP8gpamUYblD09yvWX5mEYuMK4CcqH6+plgiNEZduhTz/UrcaWs97gOlOw==" }, "node_modules/xterm-addon-attach": { "version": "0.6.0", @@ -1294,9 +1331,9 @@ }, "dependencies": { "@popperjs/core": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz", - "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz", + "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==", "peer": true }, "accepts": { @@ -1369,9 +1406,9 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", + "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" }, "balanced-match": { "version": "1.0.2", @@ -1411,9 +1448,9 @@ } }, "bootstrap": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.0.tgz", - "integrity": "sha512-tmhPET9B9qCl8dCofvHeiIhi49iBt0EehmIsziZib65k1erBW1rHhj2s/2JsuQh5Pq+xz2E9bEbzp9B7xHG+VA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", + "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", "requires": {} }, "brace-expansion": { @@ -1453,12 +1490,12 @@ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, "compress-commons": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.0.tgz", - "integrity": "sha512-ofaaLqfraD1YRTkrRKPCrGJ1pFeDG/MVCkVVV2FNGeWquSlqw5wOrwOfPQ1xF2u+blpeWASie5EubHz+vsNIgA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "requires": { "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.1", + "crc32-stream": "^4.0.2", "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" } @@ -1505,9 +1542,9 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "crc-32": { "version": "1.2.0", @@ -1624,46 +1661,51 @@ } }, "express-handlebars": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-5.3.2.tgz", - "integrity": "sha512-iGR7HXP+x+SfJQo9m00ocqcr7hU8ZzcssTLE/4wBX+jsqcblO6sFJEbEAEFjiNze3XMz9Y26Zs1WN5Bb4zxivQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-6.0.1.tgz", + "integrity": "sha512-K3Lemki5jkD3sZwDhgBEBk+oAl1xg4nsMJAfpq1AUl5K187/mU1/xKVWt+4RZAHAxlyQFk4YBfX5+00AzLNfWg==", "requires": { - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", + "glob": "^7.2.0", + "graceful-fs": "^4.2.8", "handlebars": "^4.7.7" } }, "express-session": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz", - "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==", + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", "requires": { - "cookie": "0.4.0", + "cookie": "0.4.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", "parseurl": "~1.3.3", - "safe-buffer": "5.2.0", + "safe-buffer": "5.2.1", "uid-safe": "~2.1.5" }, "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" } } }, "filesize": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.3.0.tgz", - "integrity": "sha512-ytx0ruGpDHKWVoiui6+BY/QMNngtDQ/pJaFwfBpQif0J63+E8DLdFyqS3NkKQn7vIruUEpoGD9JUJSg7Kp+I0g==" + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.6.tgz", + "integrity": "sha512-sHvRqTiwdmcuzqet7iVwsbwF6UrV3wIgDf2SHNdY1Hgl8PC45HZg/0xtdw6U2izIV4lccnrY9ftl6wZFNdjYMg==" }, "finalhandler": { "version": "1.1.2", @@ -1680,9 +1722,9 @@ } }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fresh": { "version": "0.5.2", @@ -1700,9 +1742,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1713,9 +1755,9 @@ } }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "handlebars": { "version": "4.7.7", @@ -1791,9 +1833,9 @@ "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" }, "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "requires": { "readable-stream": "^2.0.5" }, @@ -1868,16 +1910,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "requires": { - "mime-db": "1.47.0" + "mime-db": "1.51.0" } }, "minimatch": { @@ -1899,9 +1941,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "negotiator": { "version": "0.6.2", @@ -1980,6 +2022,12 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "dev": true + }, "printj": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", @@ -1991,11 +2039,11 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, @@ -2166,9 +2214,9 @@ } }, "uglify-js": { - "version": "3.13.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz", - "integrity": "sha512-xtB8yEqIkn7zmOyS2zUNBsYCBRhDkvlNxMMY2smuJ/qA8NCHeQvKCF3i9Z4k8FJH4+PJvZRtMrPynfZ75+CSZw==", + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz", + "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==", "optional": true }, "uid-safe": { @@ -2210,15 +2258,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", "requires": {} }, "xterm": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.11.0.tgz", - "integrity": "sha512-NeJH909WTO2vth/ZlC0gkP3AGzupbvVHVlmtrpBw56/sGFXaF9bNdKgqKa3tf8qbGvXMzL2JhCcHVklqFztIRw==" + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.15.0.tgz", + "integrity": "sha512-Ik1GoSq1yqKZQ2LF37RPS01kX9t4TP8gpamUYblD09yvWX5mEYuMK4CcqH6+plgiNEZduhTz/UrcaWs97gOlOw==" }, "xterm-addon-attach": { "version": "0.6.0", diff --git a/package.json b/package.json index efdfa26..3f3e992 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,12 @@ "name": "file-manager", "description": "A simple file manager", "version": "0.1.0", + "scripts": { + "format": "prettier --write .", + "start": "node index.js" + }, "bin": { - "file-manager": "./index.js" + "file-manager": "index.js" }, "dependencies": { "archiver": "^5.3.0", @@ -12,9 +16,9 @@ "connect-busboy": "^0.0.2", "connect-flash": "^0.1.1", "express": "^4.17.1", - "express-handlebars": "^5.3.2", - "express-session": "^1.17.1", - "filesize": "^6.3.0", + "express-handlebars": "^6.0.1", + "express-session": "^1.17.2", + "filesize": "^8.0.6", "jquery": "^3.6.0", "node-pty": "^0.10.1", "notp": "^2.0.3", @@ -25,5 +29,8 @@ "xterm": "^4.11.0", "xterm-addon-attach": "^0.6.0", "xterm-addon-fit": "^0.5.0" + }, + "devDependencies": { + "prettier": "^2.4.1" } }