diff --git a/CHANGELOG.md b/CHANGELOG.md
index 08b435b..c46bb04 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,9 +7,13 @@
* Container cards display pending actions (starting, stopping, pausing, restarting).
* Dynamically generated avatars.
* Updated database models.
-* Persistent Database.
-* Install cards displayed on dashboard.
+* Multi-user permission system.
+* Refactored dashboard to support multiple users.
+* New alert banner for installs and file uploads.
* Updated docker compose to include HTTPS Env.
+* Updated Apps page to view or upload compose files.
+* Improved app search.
+* Updated dependencies.
## v0.40 (Feb 26th 2024) - HTMX rewrite
* Pages rewritten to use HTMX.
diff --git a/docker-compose.yaml b/compose.yaml
similarity index 78%
rename from docker-compose.yaml
rename to compose.yaml
index 48a0d67..ad83d09 100644
--- a/docker-compose.yaml
+++ b/compose.yaml
@@ -1,28 +1,28 @@
-version: "3.9"
-services:
- dweebui:
- container_name: dweebui
- image: lllllllillllllillll/dweebui:v0.50
- environment:
- PORT: 8000
- SECRET: MrWiskers
- HTTPS: false
- restart: unless-stopped
- ports:
- - 8000:8000
- volumes:
- - dweebui:/app/database/
- # Docker socket
- - /var/run/docker.sock:/var/run/docker.sock
- # Podman socket
- #- /run/podman/podman.sock:/var/run/docker.sock
-
- networks:
- - dweebui_net
-
-volumes:
- dweebui:
-
-networks:
- dweebui_net:
+version: "3.9"
+services:
+ dweebui:
+ container_name: dweebui
+ image: lllllllillllllillll/dweebui:v0.60-dev
+ environment:
+ PORT: 8000
+ SECRET: MrWiskers
+ HTTPS: false
+ restart: unless-stopped
+ ports:
+ - 8000:8000
+ volumes:
+ - dweebui:/app
+ # Docker socket
+ - /var/run/docker.sock:/var/run/docker.sock
+ # Podman socket
+ #- /run/podman/podman.sock:/var/run/docker.sock
+
+ networks:
+ - dweebui_net
+
+volumes:
+ dweebui:
+
+networks:
+ dweebui_net:
driver: bridge
\ No newline at end of file
diff --git a/controllers/apps.js b/controllers/apps.js
index f29b917..0863211 100644
--- a/controllers/apps.js
+++ b/controllers/apps.js
@@ -1,5 +1,7 @@
-import { readFileSync, readdirSync, renameSync, mkdirSync, unlinkSync } from 'fs';
+import { readFileSync, readdirSync, renameSync, mkdirSync, unlinkSync, read } from 'fs';
+import { parse } from 'yaml';
import multer from 'multer';
+import AdmZip from 'adm-zip';
const upload = multer({storage: multer.diskStorage({
destination: function (req, file, cb) { cb(null, 'templates/tmp/') },
@@ -7,55 +9,85 @@ const upload = multer({storage: multer.diskStorage({
})});
let alert = '';
+let templates_global = '';
-export const Apps = (req, res) => {
+export const Apps = async (req, res) => {
let page = Number(req.params.page) || 1;
let template_param = req.params.template || 'default';
- let template_file = readFileSync(`./templates/json/${template_param}.json`);
-
- let templates = JSON.parse(template_file).templates;
-
- templates = templates.sort((a, b) => {
- if (a.name < b.name) { return -1; }
- });
-
-
-
- let list_start = (page-1)*28;
- let list_end = (page*28);
- let last_page = Math.ceil(templates.length/28);
- let prev = '/apps/' + (page-1);
- let next = '/apps/' + (page+1);
- if (page == 1) { prev = '/apps/' + (page); }
- if (page == last_page) { next = '/apps/' + (page); }
-
let apps_list = '';
- for (let i = list_start; i < list_end && i < templates.length; i++) {
+ let app_count = '';
+
+ let list_start = (page - 1) * 28;
+ let list_end = (page * 28);
+ let last_page = '';
+
+ let prev = '/apps/' + (page - 1) + '/' + template_param;
+ let next = '/apps/' + (page + 1) + '/' + template_param;
+ if (page == 1) { prev = '/apps/' + (page) + '/' + template_param; }
+ if (page == last_page) { next = '/apps/' + (page) + '/' + template_param;}
+
+
+ if (template_param == 'compose') {
+ let compose_files = readdirSync('templates/compose/');
+
+ app_count = compose_files.length;
+ last_page = Math.ceil(compose_files.length/28);
+
+ compose_files.forEach(file => {
+ let compose = readFileSync(`templates/compose/${file}/compose.yaml`, 'utf8');
+ let compose_data = parse(compose);
+ let service_name = Object.keys(compose_data.services)
+ let container = compose_data.services[service_name].container_name;
+ let image = compose_data.services[service_name].image;
+
let appCard = readFileSync('./views/partials/appCard.html', 'utf8');
- let name = templates[i].name || templates[i].title.toLowerCase();
- let desc = templates[i].description.slice(0, 60) + "...";
- let description = templates[i].description.replaceAll(". ", ".\n") || "no description available";
- let note = templates[i].note ? templates[i].note.replaceAll(". ", ".\n") : "no notes available";
- let image = templates[i].image;
- let logo = templates[i].logo;
- let categories = '';
- // set data.catagories to 'other' if data.catagories is empty or undefined
- if (templates[i].categories == null || templates[i].categories == undefined || templates[i].categories == '') {
- templates[i].categories = ['Other'];
- }
- // loop through the categories and add the badge to the card
- for (let j = 0; j < templates[i].categories.length; j++) {
- categories += CatagoryColor(templates[i].categories[j]);
- }
- appCard = appCard.replace(/AppName/g, name);
- appCard = appCard.replace(/AppShortName/g, name);
- appCard = appCard.replace(/AppDesc/g, desc);
- appCard = appCard.replace(/AppLogo/g, logo);
- appCard = appCard.replace(/AppCategories/g, categories);
+ appCard = appCard.replace(/AppName/g, service_name);
+ appCard = appCard.replace(/AppShortName/g, service_name);
+ appCard = appCard.replace(/AppDesc/g, 'Compose File');
+ appCard = appCard.replace(/AppLogo/g, `https://raw.githubusercontent.com/lllllllillllllillll/DweebUI-Icons/main/${service_name}.png`);
+ appCard = appCard.replace(/AppCategories/g, 'Compose ');
apps_list += appCard;
- }
+ });
+ } else {
+
+ let template_file = readFileSync(`./templates/json/default.json`);
+ let templates = JSON.parse(template_file).templates;
+ templates = templates.sort((a, b) => { if (a.name < b.name) { return -1; } });
+ app_count = templates.length;
+
+ templates_global = templates;
+
+ apps_list = '';
+ for (let i = list_start; i < list_end && i < templates.length; i++) {
+ let appCard = readFileSync('./views/partials/appCard.html', 'utf8');
+ let name = templates[i].name || templates[i].title.toLowerCase();
+ let desc = templates[i].description.slice(0, 60) + "...";
+ let description = templates[i].description.replaceAll(". ", ".\n") || "no description available";
+ let note = templates[i].note ? templates[i].note.replaceAll(". ", ".\n") : "no notes available";
+ let image = templates[i].image;
+ let logo = templates[i].logo;
+ let categories = '';
+ // set data.catagories to 'other' if data.catagories is empty or undefined
+ if (templates[i].categories == null || templates[i].categories == undefined || templates[i].categories == '') {
+ templates[i].categories = ['Other'];
+ }
+ // loop through the categories and add the badge to the card
+ for (let j = 0; j < templates[i].categories.length; j++) {
+ categories += CatagoryColor(templates[i].categories[j]);
+ }
+ appCard = appCard.replace(/AppName/g, name);
+ appCard = appCard.replace(/AppShortName/g, name);
+ appCard = appCard.replace(/AppDesc/g, desc);
+ appCard = appCard.replace(/AppLogo/g, logo);
+ appCard = appCard.replace(/AppCategories/g, categories);
+ apps_list += appCard;
+ }
+ }
+
+
+
res.render("apps", {
@@ -64,7 +96,7 @@ export const Apps = (req, res) => {
avatar: req.session.user.charAt(0).toUpperCase(),
list_start: list_start + 1,
list_end: list_end,
- app_count: templates.length,
+ app_count: app_count,
prev: prev,
next: next,
apps_list: apps_list,
@@ -212,7 +244,7 @@ function CatagoryColor(category) {
export const InstallModal = async (req, res) => {
let input = req.header('hx-trigger-name');
- let result = templates.find(t => t.name == input);
+ let result = templates_global.find(t => t.name == input);
let name = result.name || result.title.toLowerCase();
let short_name = name.slice(0, 25) + "...";
@@ -416,12 +448,8 @@ export const Upload = (req, res) => {
alert = `
-
-
- Template(s) Uploaded!
-
+
+
Template(s) Uploaded!
`;
@@ -429,16 +457,29 @@ export const Upload = (req, res) => {
let files = readdirSync('templates/tmp/');
for (let i = 0; i < files.length; i++) {
- if (files[i].endsWith('.json')) {
+ if (files[i].endsWith('.zip')) {
+ let zip = new AdmZip(`templates/tmp/${files[i]}`);
+ zip.extractAllTo('templates/compose', true);
+ unlinkSync(`templates/tmp/${files[i]}`);
+ } else if (files[i].endsWith('.json')) {
renameSync(`templates/tmp/${files[i]}`, `templates/json/${files[i]}`);
- } else if (files[i].endsWith('.yml') || files[i].endsWith('.yaml')) {
- mkdirSync(`templates/compose/${files[i].slice(0, -4)}`);
- renameSync(`templates/tmp/${files[i]}`, `templates/compose/${files[i].slice(0, -4)}/${files[i]}`);
+ } else if (files[i].endsWith('.yml')) {
+ let compose = readFileSync(`templates/tmp/${files[i]}`, 'utf8');
+ let compose_data = parse(compose);
+ let service_name = Object.keys(compose_data.services)
+ mkdirSync(`templates/compose/${service_name}`);
+ renameSync(`templates/tmp/${files[i]}`, `templates/compose/${service_name}/compose.yaml`);
+ } else if (files[i].endsWith('.yaml')) {
+ let compose = readFileSync(`templates/tmp/${files[i]}`, 'utf8');
+ let compose_data = parse(compose);
+ let service_name = Object.keys(compose_data.services)
+ mkdirSync(`templates/compose/${service_name}`);
+ renameSync(`templates/tmp/${files[i]}`, `templates/compose/${service_name}/compose.yaml`);
} else {
+ console.log('Unsupported file type');
unlinkSync(`templates/tmp/${files[i]}`);
}
- }
-
+ }
res.redirect('/apps');
});
};
\ No newline at end of file
diff --git a/controllers/dashboard.js b/controllers/dashboard.js
index 5c00bd8..e4dbd86 100644
--- a/controllers/dashboard.js
+++ b/controllers/dashboard.js
@@ -12,6 +12,7 @@ let [ cardList, newCards, stats ] = [ '', '', {}];
// The page
export const Dashboard = (req, res) => {
+
let name = req.session.user;
let role = req.session.role;
alert = req.session.alert;
@@ -338,15 +339,15 @@ export const Stats = async (req, res) => {
export async function addAlert (session, type, message) {
session.alert = `
-
- Loading...
-
-
- ${message}
-
+
+ Loading...
+
+
+ ${message}
+
-
`;
+ `;
}
export const UpdatePermissions = async (req, res) => {
diff --git a/controllers/login.js b/controllers/login.js
index 69c619c..35d40c8 100644
--- a/controllers/login.js
+++ b/controllers/login.js
@@ -2,31 +2,22 @@ import { User, Syslog } from '../database/models.js';
import bcrypt from 'bcrypt';
-
export const Login = function(req,res){
- if(req.session.user){
- res.redirect("/logout");
- }else{
- res.render("login",{
- "error":"",
- });
- }
+ if (req.session.user) { res.redirect("/logout"); }
+ else { res.render("login",{ "error":"", }); }
}
export const submitLogin = async function(req,res){
-
let { email, password } = req.body;
email = email.toLowerCase();
- if(email && password){
-
+ if (email && password) {
let existingUser = await User.findOne({ where: {email:email}});
- if(existingUser){
+ if (existingUser) {
let match = await bcrypt.compare(password,existingUser.password);
- if(match){
-
+ if (match) {
let currentDate = new Date();
let newLogin = currentDate.toLocaleString();
await User.update({lastLogin: newLogin}, {where: {UUID:existingUser.UUID}});
@@ -43,8 +34,9 @@ export const submitLogin = async function(req,res){
message: "User logged in successfully",
ip: req.socket.remoteAddress
});
+
res.redirect("/dashboard");
- }else{
+ } else {
const syslog = await Syslog.create({
user: null,
@@ -58,12 +50,12 @@ export const submitLogin = async function(req,res){
"error":"Invalid password",
});
}
- }else{
+ } else {
res.render("login",{
"error":"User with that email does not exist.",
});
}
- }else{
+ } else {
res.status(400);
res.render("login",{
"error":"Please fill in all the fields.",
diff --git a/package-lock.json b/package-lock.json
index e59556e..0ff4231 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,18 +9,19 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
+ "adm-zip": "^0.5.12",
"bcrypt": "^5.1.1",
"dockerode": "^4.0.2",
"dockerode-compose": "^1.4.0",
"ejs": "^3.1.10",
"express": "^4.19.2",
"express-session": "^1.18.0",
- "js-yaml": "^4.1.0",
"memorystore": "^1.6.7",
"multer": "^1.4.5-lts.1",
"sequelize": "^6.37.3",
"sqlite3": "^5.1.7",
- "systeminformation": "^5.22.7"
+ "systeminformation": "^5.22.7",
+ "yaml": "^2.4.2"
}
},
"node_modules/@balena/dockerignore": {
@@ -34,6 +35,68 @@
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
"optional": true
},
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
@@ -77,6 +140,27 @@
"node": ">=10"
}
},
+ "node_modules/@npmcli/move-file/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "optional": true,
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -100,9 +184,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.11.20",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
- "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
+ "version": "20.12.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.10.tgz",
+ "integrity": "sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -129,6 +213,14 @@
"node": ">= 0.6"
}
},
+ "node_modules/adm-zip": {
+ "version": "0.5.12",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.12.tgz",
+ "integrity": "sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ==",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -368,15 +460,6 @@
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
- "node_modules/buildcheck": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz",
- "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==",
- "optional": true,
- "engines": {
- "node": ">=10.0.0"
- }
- },
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -425,6 +508,26 @@
"node": ">= 10"
}
},
+ "node_modules/cacache/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "optional": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/cacache/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -437,6 +540,18 @@
"node": ">=10"
}
},
+ "node_modules/cacache/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "optional": true,
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/cacache/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -605,18 +720,17 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
- "node_modules/cpu-features": {
- "version": "0.0.9",
- "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.9.tgz",
- "integrity": "sha512-AKjgn2rP2yJyfbepsmLfiYcmtNn/2eUvocUyM/09yB0YDiz39HteK/5/T4Onf0pmdYDMgkBoGvRLvEguzyL7wQ==",
- "hasInstallScript": true,
- "optional": true,
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dependencies": {
- "buildcheck": "~0.0.6",
- "nan": "^2.17.0"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
},
"engines": {
- "node": ">=10.0.0"
+ "node": ">= 8"
}
},
"node_modules/debug": {
@@ -696,9 +810,9 @@
}
},
"node_modules/detect-libc": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
- "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"engines": {
"node": ">=8"
}
@@ -761,6 +875,11 @@
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz",
"integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA=="
},
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
+ },
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -1029,6 +1148,32 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/foreground-child": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+ "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/foreground-child/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -1117,24 +1262,56 @@
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
},
"node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "version": "10.3.12",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
+ "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.6",
+ "minimatch": "^9.0.1",
+ "minipass": "^7.0.4",
+ "path-scurry": "^1.10.2"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": "*"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob/node_modules/minipass": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz",
+ "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
@@ -1389,13 +1566,29 @@
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "optional": true
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ },
+ "node_modules/jackspeak": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
+ "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
},
"node_modules/jake": {
- "version": "10.8.7",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz",
- "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==",
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz",
+ "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==",
"dependencies": {
"async": "^3.2.3",
"chalk": "^4.0.2",
@@ -1699,14 +1892,14 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
"bin": {
"mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
}
},
"node_modules/mkdirp-classic": {
@@ -1755,23 +1948,6 @@
"node": ">= 6.0.0"
}
},
- "node_modules/multer/node_modules/mkdirp": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
- "dependencies": {
- "minimist": "^1.2.6"
- },
- "bin": {
- "mkdirp": "bin/cmd.js"
- }
- },
- "node_modules/nan": {
- "version": "2.18.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz",
- "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==",
- "optional": true
- },
"node_modules/napi-build-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
@@ -1786,9 +1962,9 @@
}
},
"node_modules/node-abi": {
- "version": "3.55.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.55.0.tgz",
- "integrity": "sha512-uPEjtyh2tFEvWYt4Jw7McOD5FPcHkcxm/tHZc5PWaDB3JYq0rGFUbgaAK+CT5pYpQddBfsZVWI08OwoRfdfbcQ==",
+ "version": "3.62.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.62.0.tgz",
+ "integrity": "sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==",
"dependencies": {
"semver": "^7.3.5"
},
@@ -1876,6 +2052,26 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
+ "node_modules/node-gyp/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "optional": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/node-gyp/node_modules/npmlog": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
@@ -1990,20 +2186,59 @@
"node": ">=0.10.0"
}
},
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
+ "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+ "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/path-scurry/node_modules/minipass": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz",
+ "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"node_modules/pg-connection-string": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
- "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA=="
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz",
+ "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA=="
},
"node_modules/prebuild-install": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
- "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz",
+ "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==",
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
@@ -2174,6 +2409,25 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -2378,6 +2632,25 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
@@ -2454,9 +2727,9 @@
}
},
"node_modules/socks": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz",
- "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==",
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
+ "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
"optional": true,
"dependencies": {
"ip-address": "^9.0.5",
@@ -2589,6 +2862,20 @@
"node": ">=8"
}
},
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -2600,6 +2887,18 @@
"node": ">=8"
}
},
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
@@ -2620,9 +2919,9 @@
}
},
"node_modules/systeminformation": {
- "version": "5.22.7",
- "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.7.tgz",
- "integrity": "sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A==",
+ "version": "5.22.8",
+ "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.8.tgz",
+ "integrity": "sha512-F1iWQ+PSfOzvLMGh2UXASaWLDq5o+1h1db13Kddl6ojcQ47rsJhpMtRrmBXfTA5QJgutC4KV67YRmXLuroIxrA==",
"os": [
"darwin",
"linux",
@@ -2645,9 +2944,9 @@
}
},
"node_modules/tar": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
- "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -2699,6 +2998,17 @@
"node": ">=8"
}
},
+ "node_modules/tar/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/tar/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -2852,7 +3162,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "optional": true,
"dependencies": {
"isexe": "^2.0.0"
},
@@ -2879,6 +3188,96 @@
"@types/node": "*"
}
},
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -2896,6 +3295,17 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
+ },
+ "node_modules/yaml": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
+ "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
}
}
}
diff --git a/package.json b/package.json
index 3af5255..29b4237 100644
--- a/package.json
+++ b/package.json
@@ -12,17 +12,18 @@
"author": "",
"license": "ISC",
"dependencies": {
+ "adm-zip": "^0.5.12",
"bcrypt": "^5.1.1",
"dockerode": "^4.0.2",
"dockerode-compose": "^1.4.0",
"ejs": "^3.1.10",
"express": "^4.19.2",
"express-session": "^1.18.0",
- "js-yaml": "^4.1.0",
"memorystore": "^1.6.7",
"multer": "^1.4.5-lts.1",
"sequelize": "^6.37.3",
"sqlite3": "^5.1.7",
- "systeminformation": "^5.22.7"
+ "systeminformation": "^5.22.7",
+ "yaml": "^2.4.2"
}
}
diff --git a/public/img/add to zip.jpg b/public/img/add to zip.jpg
new file mode 100644
index 0000000..6d88098
Binary files /dev/null and b/public/img/add to zip.jpg differ
diff --git a/server.js b/server.js
index 6a4b966..46cbac1 100644
--- a/server.js
+++ b/server.js
@@ -9,8 +9,7 @@ export const docker = new Docker();
const app = express();
const MemoryStore = memorystore(session);
-const port = process.env.PORT || 8000;
-const connection = process.env.HTTPS || false;
+const PORT = process.env.PORT || 8000;
// Session middleware
const sessionMiddleware = session({
@@ -19,9 +18,9 @@ const sessionMiddleware = session({
resave: false,
saveUninitialized: false,
cookie:{
- secure: connection,
- httpOnly: connection,
- maxAge:3600000 * 8 // Session max age in milliseconds. 3600000 = 1 hour.
+ secure: false,
+ httpOnly: false,
+ maxAge: 3600000 * 8 // Session max age in milliseconds. 3600000 = 1 hour.
}
});
@@ -36,7 +35,7 @@ app.use([
]);
// Initialize server
-app.listen(port, async () => {
+app.listen(PORT, async () => {
async function init() {// I made sure the console.logs and emojis lined up
try { await sequelize.authenticate().then(
() => { console.log('DB Connection: ✔️') }); }
@@ -45,6 +44,6 @@ app.listen(port, async () => {
() => { console.log('Synced Models: ✔️') }); }
catch { console.log('Synced Models: ❌'); } }
await init().then(() => {
- console.log(`Listening on http://localhost:${port}`);
+ console.log(`Listening on http://localhost:${PORT}`);
});
});
\ No newline at end of file
diff --git a/views/apps.html b/views/apps.html
index 5acee02..c60fa77 100644
--- a/views/apps.html
+++ b/views/apps.html
@@ -79,10 +79,10 @@
-
+
diff --git a/views/modals/import.html b/views/modals/import.html
index d1fca78..744e8cf 100644
--- a/views/modals/import.html
+++ b/views/modals/import.html
@@ -3,9 +3,10 @@
Import Template(s)
-
Template(s) can be *.json, *.yml, or *.yaml
+
Template(s) can be *.json, *.yml, or *.yaml.
+
Multiple compose files can be imported from a zip file.
+