diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index e4b7610..0ea7983 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1 @@
-github: [lllllllillllllillll]
-patreon: DweebUI
+patreon: DweebUI
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d192121..67312bf 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -15,6 +15,6 @@ updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
- interval: "daily"
+ interval: "weekly"
labels:
- "🤖 Dependencies"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..591aeb8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+database/database.sqlite
+test
+.dockerignore
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be791d7..60c6b83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,20 @@
-## v0.09 (dev)
+## v0.20 (dev) - The rewrite. Jumping all the way to v0.20.
+* Changed to ES6 imports.
+* Cleaned up file structure and code layout.
+* Updated DweebUI logo.
+* Visual tweaks to login and registration pages.
+* Added .gitignore and .dockerignore files.
+* Syslogs - View logs for sign-in and registration attempts. :new:
+* Docker socket now uses default connection.
+* Updated Users page displays 'inactive' if no sign-ins within 30 days.
+* Dashboard updates now triggered by Docker events.
+* Massive reduction in the amount of HTML, CSS, and JS on client side.
+* Container graphs are significantly more efficent and no longer use localStorage.
+* Made dark mode the default theme.
+* Created intervals to allow application to idle or scale bettery with more users.
+* Pages for images, volumes, and networks (non-functional at the moment). :new:
+
+## v0.09 (dev) dead. (It had so many problems that I essentially rewrote everything)
* Added authentication middleware to router.
* Added gzip compression.
* Added PM2.
diff --git a/Dockerfile b/Dockerfile
index f962484..604ee4c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,7 @@
-# syntax=docker/dockerfile:1
-
FROM node:21-alpine
ENV NODE_ENV=production
+ENV LOGGER=true
WORKDIR /app
diff --git a/README.md b/README.md
index a9b97f1..0b97ded 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,18 @@
# DweebUI
-DweebUI is a simple Docker web interface created using Javascript, Node.JS, and Express.
+DweebUI is a web interface for managing Docker, with a zero-config dashboard for your containers.
-Alpha v0.09 ( :fire: Experimental :fire: )
+Alpha v0.20 ( :fire: Experimental :fire: )
+
+:warning: DweebUI is a management interface and should not be directly exposed to the internet:warning:
+:warning: External access should be done through a VPN or secure SSH connection :warning:
[](https://github.com/lllllllillllllillll)
[](https://github.com/lllllllillllllillll)
[](https://hub.docker.com/repository/docker/lllllllillllllillll/dweebui)
[](https://github.com/lllllllillllllillll/DweebUI/blob/main/LICENSE)
+* This is a personal project that I started to get more familiar with Javascript and Node.js.
+* I probably should have waited a lot longer to share this :|
@@ -37,12 +42,11 @@ Docker Compose:
```
version: "3.9"
services:
-
dweebui:
container_name: dweebui
- image: lllllllillllllillll/dweebui:v0.09-dev
- # build:
- # context: .
+ # image: lllllllillllllillll/dweebui:v0.20
+ build:
+ context: .
environment:
NODE_ENV: production
PORT: 8000
@@ -52,21 +56,15 @@ services:
- 8000:8000
volumes:
- dweebui:/app
- - caddyfiles:/app/caddyfiles
- /var/run/docker.sock:/var/run/docker.sock
- #- ./custom-templates.json:/app/custom-templates.json
- #- ./composefiles:/app/composefiles
networks:
- - dweeb_network
-
+ - dweebui_net
volumes:
dweebui:
- caddyfiles:
-
networks:
- dweeb_network:
+ dweebui_net:
driver: bridge
```
@@ -77,14 +75,6 @@ Compose setup:
* You may need to use ```docker-compose up -d``` or execute the command as root with either ```sudo docker compose up -d``` or ```sudo docker-compose up -d```.
-Using setup.sh:
-```
-Extract DweebUI.zip and navigate to /DweebUI
-cd DweebUI
-chmod +x setup.sh
-sudo ./setup.sh
-```
-
## Credits
diff --git a/app.js b/app.js
index 658c4dd..69383a0 100644
--- a/app.js
+++ b/app.js
@@ -1,23 +1,43 @@
-// Express
-const express = require("express");
-const app = express();
-const session = require("express-session");
-const compression = require('compression');
-const helmet = require('helmet');
-const PORT = process.env.PORT || 8000;
+import express from 'express';
+import session from 'express-session';
+import compression from 'compression';
+import helmet from 'helmet';
+import Docker from 'dockerode';
+import cors from 'cors';
+import { Readable } from 'stream';
+import { instrument } from '@socket.io/admin-ui'
+import { router } from './router/index.js';
+import { createServer } from 'node:http';
+import { Server } from 'socket.io';
+import { sequelize, Container } from './database/models.js';
+import { currentLoad, mem, networkStats, fsSize, dockerContainerStats, dockerImages, networkInterfaces } from 'systeminformation';
+import { containerCard } from './components/containerCard.js';
-// Router
-const routes = require("./routes");
+export const app = express();
+const server = createServer(app);
+const port = process.env.PORT || 8000;
+export var docker = new Docker();
+let [cpu, ram, tx, rx, disk] = [0, 0, 0, 0, 0];
+let [hidden, clicked, dockerEvents] = ['', false, ''];
+let metricsInterval, cardsInterval, graphsInterval;
+let cardList = '';
+const statsArray = {};
-// Functions and variables
-const { serverStats, containerList, containerStats, containerAction, containerLogs, hiddenContainers, dockerImages, dockerVolumes, dockerNetworks } = require('./functions/system');
-let sentList, clicked;
-app.locals.site_list = '';
+// socket.io admin ui
+export const io = new Server(server, {
+ connectionStateRecovery: {},
+ cors: {
+ origin: ['http://localhost:8000', 'https://admin.socket.io'],
+ methods: ['GET', 'POST'],
+ credentials: true
+ }
+});
+instrument(io, {
+ auth: false,
+ readonly: true
+});
-const Containers = require('./database/ContainerModel');
-
-
-// Configure Session
+// Session middleware
const sessionMiddleware = session({
secret: "keyboard cat",
resave: false,
@@ -26,137 +46,280 @@ const sessionMiddleware = session({
secure:false, // Only set to true if you are using HTTPS.
httpOnly:false, // Only set to true if you are using HTTPS.
maxAge:3600000 * 8 // Session max age in milliseconds. 3600000 = 1 hour.
- }
-})
+ }
+});
+io.engine.use(sessionMiddleware);
-// Middleware
+// Express middleware
app.set('view engine', 'ejs');
app.use([
compression(),
+ cors(),
helmet({contentSecurityPolicy: false}),
express.static("public"),
express.json(),
express.urlencoded({ extended: true }),
sessionMiddleware,
- routes
+ router
]);
-// Start Express server
-const server = app.listen(PORT, async () => {
- console.log(`App listening on port ${PORT}`);
+// Initialize server
+server.listen(port, () => {
+ async function init() {
+ try {
+ await sequelize.authenticate();
+ console.log('[Connected to DB]');
+ } catch (error) {
+ console.log('[Could not connect to DB]', error);
+ }
+ try {
+ await sequelize.sync();
+ console.log('[Models Synced]');
+ hidden = await Container.findAll({ where: {visibility:false}});
+ containerCards();
+ } catch (error) {
+ console.log('[Could not Sync Models]', error);
+ }
+ console.log(`\nServer listening on http://localhost:${port}`);
+ }
+ init();
});
-// Start Socket.io
-const io = require('socket.io')(server);
-io.engine.use(sessionMiddleware);
+// Server metrics
+let serverMetrics = async () => {
+ currentLoad().then(data => {
+ cpu = Math.round(data.currentLoad);
+ });
+ mem().then(data => {
+ ram = Math.round((data.active / data.total) * 100);
+ });
+ networkStats().then(data => {
+ tx = data[0].tx_bytes / (1024 * 1024);
+ rx = data[0].rx_bytes / (1024 * 1024);
+ });
+ fsSize().then(data => {
+ disk = data[0].use;
+ });
+}
-io.on('connection', (socket) => {
+// List docker containers
+let containerCards = async () => {
+ let list = '';
+ const allContainers = await docker.listContainers({ all: true });
+ for (const container of allContainers) {
+ if (!hidden.includes(container.Names[0].slice(1))) {
- // Set user session
- const user_session = socket.request.session;
- console.log(`${user_session.user} connected from ${socket.handshake.headers.host} ${socket.handshake.address}`);
+ let imageVersion = container.Image.split('/');
+ let service = imageVersion[imageVersion.length - 1].split(':')[0];
+ let containerId = docker.getContainer(container.Id);
+ let containerInfo = await containerId.inspect();
+ let ports_list = [];
+ try {
+ for (const [key, value] of Object.entries(containerInfo.HostConfig.PortBindings)) {
+ let ports = {
+ check: 'checked',
+ external: value[0].HostPort,
+ internal: key.split('/')[0],
+ protocol: key.split('/')[1]
+ }
+ ports_list.push(ports);
+ }
+ } catch {}
- // Check if a list of containers or an install card needs to be sent
- if (sentList != null) { socket.emit('cards', sentList); }
- if((app.locals.install != '') && (app.locals.install != null)){ socket.emit('install', app.locals.install); }
+ let external_port = ports_list[0]?.external || 0;
+ let internal_port = ports_list[0]?.internal || 0;
-
- async function dockerStuff(){
- let i = await dockerImages();
- let v = await dockerVolumes();
- let n = await dockerNetworks();
-
- // console.log(i, v, n);
+ let container_info = {
+ name: container.Names[0].slice(1),
+ service: service,
+ id: container.Id,
+ state: container.State,
+ image: container.Image,
+ external_port: external_port,
+ internal_port: internal_port,
+ ports: ports_list,
+ link: 'localhost',
+ }
+ let card = containerCard(container_info);
+ list += card;
+ }
}
+ cardList = list;
+}
- dockerStuff();
+// Container metrics
+let containerStats = async () => {
+ const data = await docker.listContainers({ all: true });
+ for (const container of data) {
+ if (!hidden.includes(container.Names[0].slice(1))) {
+ const stats = await dockerContainerStats(container.Id);
+ const name = container.Names[0].slice(1);
- // Send server metrics
- let ServerStats = setInterval(async () => {
- socket.emit('metrics', await serverStats());
- }, 1000);
+ if (!statsArray[name]) {
+ statsArray[name] = {
+ cpuArray: Array(15).fill(0),
+ ramArray: Array(15).fill(0)
+ };
+ }
+ statsArray[name].cpuArray.push(Math.round(stats[0].cpuPercent));
+ statsArray[name].ramArray.push(Math.round(stats[0].memPercent));
- // Send list of containers
- let ContainerList = setInterval(async () => {
- let cardList = await containerList();
- if (sentList !== cardList) {
- sentList = cardList;
- app.locals.install = '';
- socket.emit('cards', cardList);
+ statsArray[name].cpuArray = statsArray[name].cpuArray.slice(-15);
+ statsArray[name].ramArray = statsArray[name].ramArray.slice(-15);
}
- }, 1000);
+ }
+}
- // Send container metrics
- let ContainerStats = setInterval(async () => {
- let stats = await containerStats();
- for (let i = 0; i < stats.length; i++) {
- socket.emit('containerStats', stats[i]);
- }
- }, 1000);
-
- // Container controls
- socket.on('clicked', (data) => {
- if (clicked == true) { return; } clicked = true;
- let buttonPress = {
- user: socket.request.session.user,
- role: socket.request.session.role,
- action: data.action,
- container: data.container,
- state: data.state
- }
- containerAction(buttonPress);
- clicked = false;
+// Store docker events
+docker.getEvents((err, stream) => {
+ if (err) throw err;
+ stream.on('data', (chunk) => {
+ dockerEvents += chunk.toString('utf8');
});
+});
-
- socket.on('hide', async (data) => {
- console.log(`Hide ${data.container}`);
+// Check for docker events
+setInterval( () => {
+ if (dockerEvents != '') {
+ getHidden();
+ containerCards();
+ dockerEvents = '';
+ }
+}, 1000);
- let containerExists = await Containers.findOne({ where: {name:data.container}});
+// Get hidden containers
+async function getHidden() {
+ hidden = await Container.findAll({ where: {visibility:false}});
+}
- if(!containerExists){
- const container = await Containers.create({
- name: data.container,
- visibility: false,
- });
- hiddenContainers();
- console.log(`[Created] Container ${data.container} hidden`)
-
- let containerData = await Containers.findOne({ where: {name:data.container}});
- console.log(containerData);
-
- } else {
- containerExists.update({ visibility: false });
- console.log(`[Updated] Container ${data.container} hidden`)
- hiddenContainers();
+// Socket.io
+io.on('connection', (socket) => {
+ let sessionData = socket.request.session;
+ let sent = '';
+ if (sessionData.user != undefined) {
+ console.log(`${sessionData.user} connected from ${socket.handshake.headers.host}`);
+
+ // Start intervals if not already started
+ if (!metricsInterval) {
+ metricsInterval = setInterval(serverMetrics, 1000);
+ console.log('Metrics interval started');
+ }
+ if (!cardsInterval) {
+ cardsInterval = setInterval(containerCards, 1000);
+ console.log('Cards interval started');
+ }
+ if (!graphsInterval) {
+ graphsInterval = setInterval(containerStats, 1000);
+ console.log('Graphs interval started');
}
- });
- socket.on('reset', (data) => {
- // set visibility to true for all containers
- Containers.update({ visibility: true }, { where: {} });
- console.log('All containers visible');
- hiddenContainers();
- });
+ setInterval(() => {
+ socket.emit('metrics', [cpu, ram, tx, rx, disk]);
+ if (sent != cardList) {
+ sent = cardList;
+ socket.emit('containers', cardList);
+ }
+ socket.emit('containerStats', statsArray);
+ }, 1000);
- // Container logs
- socket.on('logs', (data) => {
- containerLogs(data.container)
- .then(logs => {
- console.log(`Refreshed logs for ${data.container}`)
- socket.emit('logString', logs);
- })
- .catch(err => {
- console.error(err);
+
+
+ socket.on('clicked', (data) => {
+ if (clicked == true) { return; } clicked = true;
+ let { name, id, value } = data;
+ console.log(`${sessionData.user} clicked: ${id} ${value} ${name}`);
+
+
+ if (id == 'logs'){
+ function containerLogs (data) {
+ return new Promise((resolve, reject) => {
+ let logString = '';
+
+ var options = {
+ follow: false,
+ stdout: true,
+ stderr: false,
+ timestamps: false
+ };
+
+ var containerName = docker.getContainer(data);
+
+ containerName.logs(options, function (err, stream) {
+ if (err) {
+ reject(err);
+ return;
+ }
+
+ const readableStream = Readable.from(stream);
+
+ readableStream.on('data', function (chunk) {
+ logString += chunk.toString('utf8');
+ });
+
+ readableStream.on('end', function () {
+ resolve(logString);
+ });
+ });
+ });
+ };
+ containerLogs(name).then((data) => {
+ socket.emit('logs', data);
+ }).catch((err) => {
+ console.log(err);
+ });
+
+ }
+
+
+ if (id == 'start' || id == 'stop' || id == 'pause' || id == 'restart'){
+ var containerName = docker.getContainer(name);
+
+ if ((id == 'start') && (value == 'stopped')) {
+ containerName.start();
+ } else if ((id == 'start') && (value == 'paused')) {
+ containerName.unpause();
+ } else if ((id == 'stop') && (value != 'stopped')) {
+ containerName.stop();
+ } else if ((id == 'pause') && (value == 'running')) {
+ containerName.pause();
+ } else if ((id == 'pause') && (value == 'paused')) {
+ containerName.unpause();
+ } else if (id == 'restart') {
+ containerName.restart();
+ }
+ }
+ clicked = false;
});
- });
- // On disconnect
- socket.on('disconnect', () => {
- clearInterval(ServerStats);
- clearInterval(ContainerList);
- clearInterval(ContainerStats);
- });
+ socket.on('disconnect', () => {
+ console.log(`${sessionData.user} disconnected`);
+ socket.disconnect();
+ // clear intervals if no users are connected
+ if (io.engine.clientsCount == 0) {
+ clearInterval(metricsInterval);
+ clearInterval(cardsInterval);
+ clearInterval(graphsInterval);
+ metricsInterval = null;
+ cardsInterval = null;
+ graphsInterval = null;
+ console.log('All intervals cleared');
+ }
+ });
+ } else {
+ console.log('Missing session data');
+ }
+});
+
+
+
+
+
+
+
+
+// let link = '';
+// networkInterfaces().then(data => {
+// link = data[0].ip4;
+// });
-});
\ No newline at end of file
diff --git a/caddyfiles/Caddyfile b/caddyfiles/Caddyfile
deleted file mode 100644
index 7f8f696..0000000
--- a/caddyfiles/Caddyfile
+++ /dev/null
@@ -1 +0,0 @@
-import ./sites/*
\ No newline at end of file
diff --git a/components/appCard.js b/components/appCard.js
index c8b2e3b..cc7377b 100644
--- a/components/appCard.js
+++ b/components/appCard.js
@@ -1,4 +1,4 @@
-function appCard(data) {
+export const appCard = (data) => {
// make data.title lowercase
let app_name = data.name || data.title.toLowerCase();
@@ -227,11 +227,11 @@ function appCard(data) {
`;
-}
-
-module.exports = { appCard };
+}
\ No newline at end of file
diff --git a/components/containerCard.js b/components/containerCard.js
new file mode 100644
index 0000000..590c5cb
--- /dev/null
+++ b/components/containerCard.js
@@ -0,0 +1,118 @@
+// export for app.js
+export const containerCard = (data) => {
+
+ let { name, service, state, external_port, internal_port, ports, link } = data;
+ let wrapped = name;
+ let chart = name;
+
+ if (name.length > 13) {
+ wrapped = name.slice(0, 10) + '...';
+ }
+
+ //disable controls for a docker container depending on its name
+ let actions = "";
+ if (name.startsWith('dweebui')) {
+ actions = 'disabled=""';
+ }
+
+ if ( external_port == undefined ) { external_port = 0; }
+ if ( internal_port == undefined ) { internal_port = 0; }
+
+
+ let state_indicator = 'green';
+ if (state == 'exited') {
+ state = 'stopped';
+ state_indicator = 'red';
+ } else if (state == 'paused') {
+ state_indicator = 'orange';
+ }
+
+ let ports_data = [];
+ if (ports) {
+ ports_data = ports;
+ } else {
+ for (let i = 0; i < 12; i++) {
+
+ let port_check = "checked";
+ let external = i;
+ let internal = i;
+ let protocol = "tcp";
+
+ ports_data.push({
+ check: port_check,
+ external: external,
+ internal: internal,
+ protocol: protocol
+ });
+ }
+ }
+
+
+ return `
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`;
+}
\ No newline at end of file
diff --git a/components/dashCard.js b/components/dashCard.js
deleted file mode 100644
index 4be1edf..0000000
--- a/components/dashCard.js
+++ /dev/null
@@ -1,1110 +0,0 @@
-module.exports.dashCard = function dashCard(data) {
-
- let { name, service, id, state, image, external_port, internal_port, ports, volumes, environment_variables, labels, IPv4, style } = data;
-
- let margin, iconSize, fontSize = '';
-
- if (style == "Large") {
- iconSize = 'width="150px"'
- } else if ((style == "Compact") || (style == undefined)) {
- iconSize = 'width="100px"'
- margin = 'style="margin-bottom: 0;"'
- } else if (style == "Row") {
- iconSize = 'width="50px"'
- margin = 'style="margin-bottom: 0;"'
- }
-
-
- //disable controls for a docker container depending on its name
- let actions = "";
- if (name.startsWith('dweebui')) {
- actions = 'disabled=""';
- }
-
- if ( external_port == undefined ) { external_port = 0; }
- if ( internal_port == undefined ) { internal_port = 0; }
-
-
- let shortened_name = name;
- if (name.length > 13) {
- shortened_name = name.slice(0, 10) + '...';
- }
-
- let state_indicator = 'green';
- if (state == 'exited') {
- state = 'stopped';
- state_indicator = 'red';
- } else if (state == 'paused') {
- state_indicator = 'orange';
- }
-
-
- let app_name = name
- let modal = app_name.replaceAll(" ", "-");
- let form_id = app_name.replaceAll("-", "_");
-
- let restart_policy = 'unless-stopped';
-
- let ports_data = [];
- if (ports) {
- ports_data = ports;
- } else {
- for (let i = 0; i < 12; i++) {
-
- let port_check = "checked";
- let external = i;
- let internal = i;
- let protocol = "tcp";
-
- ports_data.push({
- check: port_check,
- external: external,
- internal: internal,
- protocol: protocol
- });
- }
- }
-
- let volumes_data = [];
- if (volumes) {
- volumes_data = volumes;
- } else {
- for (let i = 0; i < 12; i++) {
-
- let vol_check = "checked";
- let bind = i;
- let container = i;
- let readwrite = "rw";
-
- volumes_data.push({
- check: vol_check,
- bind: bind,
- container: container,
- readwrite: readwrite
- });
- }
- }
-
-
- let env_data = [];
- if (environment_variables) {
- env_data = environment_variables;
- } else {
- for (let i = 0; i < 12; i++) {
-
- let env_check = "checked";
- let env_name = i;
- let env_default = i;
-
- env_data.push({
- check: env_check,
- name: env_name,
- default: env_default
- });
- }
- }
-
-
- let label_data = [];
- if (labels) {
- label_data = labels;
- } else {
- for (let i = 0; i < 12; i++) {
-
- let label_check = "checked";
- let label_name = i;
- let label_default = i;
-
- label_data.push({
- check: label_check,
- name: label_name,
- value: label_default
- });
- }
- }
-
- return `
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Remove ${name}?
-
-
-
-
-
-
-
-
-
- `;
-}
\ No newline at end of file
diff --git a/components/siteCard.js b/components/siteCard.js
deleted file mode 100644
index a12960a..0000000
--- a/components/siteCard.js
+++ /dev/null
@@ -1,18 +0,0 @@
-function siteCard(type, domain, host, port, id) {
-
- let site = ``
- site += ` | `
- site += `${id} | `
- site += `${domain} | `
- site += `${type} | `
- site += `${host} | `
- site += `${port} | `
- site += ` Enabled | `
- site += ` Enabled | `
- site += ` Edit | `
- site += `
`
-
- return site;
-}
-
-module.exports = { siteCard };
\ No newline at end of file
diff --git a/controllers/account.js b/controllers/account.js
index c905474..4bf9195 100644
--- a/controllers/account.js
+++ b/controllers/account.js
@@ -1,22 +1,19 @@
-const User = require('../database/UserModel');
+import { User } from "../database/models.js";
+
+export const Account = async (req, res) => {
+
+
+ let user = await User.findOne({ where: { UUID: req.session.UUID }});
+
+ res.render("account", {
+ first_name: user.name,
+ last_name: user.name,
+ name: user.name,
+ id: user.id,
+ email: user.email,
+ role: user.role,
+ avatar: user.avatar,
+ });
+
-exports.Account = async function(req, res) {
- if (req.session.user) {
- // Get the user.
- let user = await User.findOne({ where: { UUID: req.session.UUID }});
- // Render the home page
- res.render("pages/account", {
- first_name: user.first_name,
- last_name: user.last_name,
- name: user.first_name + ' ' + user.last_name,
- id: user.id,
- email: user.email,
- role: user.role,
- avatar: user.avatar,
- isLoggedIn: true
- });
- } else {
- // Redirect to the login page
- res.redirect("/login");
- }
}
diff --git a/controllers/apps.js b/controllers/apps.js
index 498de7b..336246c 100644
--- a/controllers/apps.js
+++ b/controllers/apps.js
@@ -1,27 +1,23 @@
-const { appCard } = require('../components/appCard')
-const { dashCard } = require('../components/dashCard');
-const { install, uninstall } = require('../functions/package_manager');
+import { readFileSync } from 'fs';
+import { appCard } from '../components/appCard.js';
-const templates_json = require('../templates.json');
-let templates = templates_json.templates;
+let templatesJSON = readFileSync('./templates.json');
+let templates = JSON.parse(templatesJSON).templates;
-// sort templates alphabetically
templates = templates.sort((a, b) => {
if (a.name < b.name) {
return -1;
}
- });
-
-
-exports.Apps = async function(req, res) {
+});
+export const Apps = (req, res) => {
let page = Number(req.params.page) || 1;
- let list_start = (page - 1) * 28;
- let list_end = (page * 28);
- let last_page = Math.ceil(templates.length / 28);
+ 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);
+ let prev = '/apps/' + (page-1);
+ let next = '/apps/' + (page+1);
if (page == 1) {
prev = '/apps/' + (page);
}
@@ -36,12 +32,10 @@ exports.Apps = async function(req, res) {
apps_list += app_card;
}
- // Render the home page
- res.render("pages/apps", {
+ res.render("apps", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true,
list_start: list_start + 1,
list_end: list_end,
app_count: templates.length,
@@ -54,7 +48,7 @@ exports.Apps = async function(req, res) {
-exports.searchApps = async function(req, res) {
+export const searchApps = async (req, res) => {
let page = Number(req.query.page) || 1;
let list_start = (page - 1) * 28;
@@ -98,12 +92,10 @@ exports.searchApps = async function(req, res) {
apps_list += app_card;
}
- // Render the home page
- res.render("pages/apps", {
+ res.render("apps", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true,
list_start: list_start + 1,
list_end: list_end,
app_count: templates.length,
@@ -112,63 +104,4 @@ exports.searchApps = async function(req, res) {
apps_list: apps_list
});
-}
-
-
-
-
-
-
-
-
-
-exports.Install = async function (req, res) {
-
- if (req.session.role == "admin") {
-
- console.log(`Starting install for: ${req.body.name}`)
-
- install(req.body);
-
- let container_info = {
- name: req.body.name,
- service: req.body.service_name,
- state: 'installing',
- image: req.body.image,
- restart_policy: req.body.restart_policy
- }
-
- let installCard = dashCard(container_info);
-
- req.app.locals.install = installCard;
-
-
- // Redirect to the home page
- res.redirect("/");
- } else {
- // Redirect to the login page
- res.redirect("/login");
- }
-}
-
-
-
-exports.Uninstall = async function (req, res) {
-
- if (req.session.role == "admin") {
-
-
- if (req.body.confirm == 'Yes') {
-
- uninstall(req.body);
-
- }
-
-
- // Redirect to the home page
- res.redirect("/");
- } else {
- // Redirect to the login page
- res.redirect("/login");
- }
}
\ No newline at end of file
diff --git a/controllers/auth.js b/controllers/auth.js
deleted file mode 100644
index 6d28905..0000000
--- a/controllers/auth.js
+++ /dev/null
@@ -1,160 +0,0 @@
-const User = require('../database/UserModel');
-const bcrypt = require('bcrypt');
-
-
-exports.Login = function(req,res){
-
- // check whether we have a session
- if(req.session.user){
- // Redirect to log out.
- res.redirect("/logout");
- }else{
- // Render the login page.
- res.render("pages/login",{
- "error":"",
- "isLoggedIn": false
- });
- }
-}
-
-exports.processLogin = async function(req,res){
- // get the data.
- let email = req.body.email;
- let password = req.body.password;
- // check if we have data.
- if(email && password){
- // check if the user exists.
- let existingUser = await User.findOne({ where: {email:email}});
- if(existingUser){
- // compare the password.
- let match = await bcrypt.compare(password,existingUser.password);
- if(match){
-
- // set the session.
- req.session.user = existingUser.username;
- req.session.UUID = existingUser.UUID;
- req.session.role = existingUser.role;
- req.session.avatar = existingUser.avatar;
-
-
- // Redirect to the home page.
- res.redirect("/");
- }else{
- // return an error.
- res.render("pages/login",{
- "error":"Invalid password",
- isLoggedIn: false
- });
- }
- }else{
- // return an error.
- res.render("pages/login",{
- "error":"User with that email does not exist.",
- isLoggedIn:false
- });
- }
- }else{
- res.status(400);
- res.render("pages/login",{
- "error":"Please fill in all the fields.",
- isLoggedIn:false
- });
- }
-}
-
-
-exports.Logout = function(req,res){
- // clear the session.
- req.session.destroy();
- // Redirect to the login page.
- res.redirect("/login");
-}
-
-
-
-exports.Register = function(req,res){
- // Check whether we have a session
- if(req.session.user){
- // Redirect to log out.
- res.redirect("/logout");
- } else {
- // Render the signup page.
- res.render("pages/register",{
- "error":"",
- isLoggedIn:false
- });
- }
-}
-
-exports.processRegister = async function(req,res){
-
- // Get the data.
- let { first_name, last_name, username, email, password, avatar, tos, secret } = req.body;
- let role = "user";
-
- // Check the data.
- if((first_name && last_name && email && password && username && tos) && (secret == process.env.SECRET)){
-
- // Check if there is an existing user with that username.
- let existingUser = await User.findOne({ where: {username:username}});
-
- let adminUser = await User.findOne({ where: {role:"admin"}});
-
- if(!existingUser){
- // hash the password.
- let hashedPassword = bcrypt.hashSync(password,10);
-
- if(!adminUser){
- console.log('Creating admin User');
- role = "admin";
- }
-
- try {
- const user = await User.create({
- first_name: first_name,
- last_name: last_name,
- username: username,
- email: email,
- password: hashedPassword,
- role: role,
- group: 'all',
- avatar: `
`
- });
-
- let newUser = await User.findOne({ where: {email:email}});
-
- let match = await bcrypt.compare(password,newUser.password);
- if(match){
- console.log(`User session created for ${newUser.username}`)
- req.session.user = newUser.username;
- req.session.UUID = newUser.UUID;
- req.session.role = newUser.role;
- req.session.avatar = newUser.avatar;
- }
-
- // Redirect to the home page.
- res.redirect("/");
- }
- catch (err) {
- // return an error.
- res.render("pages/register",{
- "error":"Something went wrong when creating account.",
- isLoggedIn:false
- });
- }
-
- }else{
- // return an error.
- res.render("pages/register",{
- "error":"User with that username already exists.",
- isLoggedIn:false
- });
- }
- }else{
- // Redirect to the signup page.
- res.render("pages/register",{
- "error":"Please fill in all the fields and accept TOS.",
- isLoggedIn:false
- });
- }
-}
\ No newline at end of file
diff --git a/controllers/dashboard.js b/controllers/dashboard.js
index 5f9647c..6ba90d6 100644
--- a/controllers/dashboard.js
+++ b/controllers/dashboard.js
@@ -1,215 +1,24 @@
-const { readFileSync, writeFileSync, appendFileSync, readdirSync } = require('fs');
-const { execSync } = require("child_process");
-const { siteCard } = require('../components/siteCard');
-const { containerExec } = require('../functions/system')
+
+export const Dashboard = (req, res) => {
-exports.Dashboard = async function (req, res) {
-
- let caddy = 'd-none';
-
- if (process.env.Proxy_Manager == 'enabled') {
- caddy = '';
- }
-
- // Render the home page
- res.render("pages/dashboard", {
+ res.render("dashboard", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true,
- site_list: req.app.locals.site_list,
- caddy: caddy
});
}
+export const searchDashboard = (req, res) => {
+ console.log(req.params);
-exports.AddSite = async function (req, res) {
-
- let { domain, type, host, port } = req.body;
-
- if ( domain && type && host && port) {
-
-
- let { domain, type, host, port } = req.body;
-
- // build caddyfile
- let caddyfile = `${domain} {`
- caddyfile += `\n\t${type} ${host}:${port}`
- caddyfile += `\n\theader {`
- caddyfile += `\n\t\tStrict-Transport-Security "max-age=31536000; includeSubDomains; preload"`
- caddyfile += `\n\t}`
- caddyfile += `\n}`
-
-
- // save caddyfile
- writeFileSync(`./caddyfiles/sites/${domain}.Caddyfile`, caddyfile, function (err) { console.log(err) });
-
-
- // format caddyfile
- let format = {
- container: 'DweebProxy',
- command: `caddy fmt --overwrite /etc/caddy/sites/${domain}.Caddyfile`
- }
- await containerExec(format, function(err, data) {
- if (err) {
- console.error(err);
- return;
- }
- console.log(`Formatted ${domain}.Caddyfile`);
- });
-
- ///////////////// convert caddyfile to json
- let convert = {
- container: 'DweebProxy',
- command: `caddy adapt --config /etc/caddy/sites/${domain}.Caddyfile --pretty >> /etc/caddy/sites/${domain}.json`
- }
- await containerExec(convert, function(err, data) {
- if (err) {
- console.error(err);
- return;
- }
- console.log(`Converted ${domain}.Caddyfile to JSON`);
- });
-
- ////////////// reload caddy
- let reload = {
- container: 'DweebProxy',
- command: `caddy reload --config /etc/caddy/Caddyfile`
- }
- await containerExec(reload, function(err, data) {
- if (err) {
- console.error(err);
- return;
- }
- console.log(`Reloaded Caddy Config`);
- });
-
- let site = siteCard(type, domain, host, port, 0);
-
- req.app.locals.site_list += site;
-
-
- res.redirect("/");
- } else {
- // Redirect
- console.log('missing info')
- res.redirect("/");
- }
-}
-
-
-exports.RemoveSite = async function (req, res) {
-
- for (const [key, value] of Object.entries(req.body)) {
-
- execSync(`rm ./caddyfiles/sites/${value}.Caddyfile`, (err, stdout, stderr) => {
- if (err) { console.error(`error: ${err.message}`); return; }
- if (stderr) { console.error(`stderr: ${stderr}`); return; }
- console.log(`removed ${value}.Caddyfile`);
- });
-
- }
-
- let reload = {
- container: 'DweebProxy',
- command: `caddy reload --config /etc/caddy/Caddyfile`
- }
- await containerExec(reload);
-
-
- console.log('Removed Site(s)')
-
- res.redirect("/refreshsites");
-
-
-}
-
-
-exports.RefreshSites = async function (req, res) {
-
- let domain, type, host, port;
- let id = 1;
-
- // Clear site_list.ejs
- req.app.locals.site_list = "";
-
-
- // check if ./caddyfiles/sites contains any .json files, then delete them
- try {
- let files = readdirSync('./caddyfiles/sites/');
- files.forEach(file => {
- if (file.includes(".json")) {
- execSync(`rm ./caddyfiles/sites/${file}`, (err, stdout, stderr) => {
- if (err) { console.error(`error: ${err.message}`); return; }
- if (stderr) { console.error(`stderr: ${stderr}`); return; }
- console.log(`removed ${file}`);
- });
- }
- });
- } catch (error) { console.log("No .json files to delete") }
-
- // get list of Caddyfiles
- let sites = readdirSync('./caddyfiles/sites/');
-
-
- sites.forEach(site_name => {
- // convert the caddyfile of each site to json
- let convert = {
- container: 'DweebProxy',
- command: `caddy adapt --config ./caddyfiles/sites/${site_name} --pretty >> ./caddyfiles/sites/${site_name}.json`
- }
- containerExec(convert);
-
- try {
- // read the json file
- let site_file = readFileSync(`./caddyfiles/sites/${site_name}.json`, 'utf8');
- // fix whitespace and parse the json file
- site_file = site_file.replace(/ /g, " ");
- site_file = JSON.parse(site_file);
- } catch (error) { console.log("No .json file to read") }
-
-
- // get the domain, type, host, and port from the json file
- try { domain = site_file.apps.http.servers.srv0.routes[0].match[0].host[0] } catch (error) { console.log("No Domain") }
- try { type = site_file.apps.http.servers.srv0.routes[0].handle[0].routes[0].handle[1].handler } catch (error) { console.log("No Type") }
- try { host = site_file.apps.http.servers.srv0.routes[0].handle[0].routes[0].handle[1].upstreams[0].dial.split(":")[0] } catch (error) { console.log("Not Localhost") }
- try { port = site_file.apps.http.servers.srv0.routes[0].handle[0].routes[0].handle[1].upstreams[0].dial.split(":")[1] } catch (error) { console.log("No Port") }
-
- // build the site card
- let site = siteCard(type, domain, host, port, id);
-
- // append the site card to site_list
- req.app.locals.site_list += site;
-
- id++;
+ res.render("dashboard", {
+ name: req.session.user,
+ role: req.session.role,
+ avatar: req.session.avatar,
});
-
-
- res.redirect("/");
-
-}
-
-
-
-exports.DisableSite = async function (req, res) {
-
- console.log(req.body)
- console.log('Disable Site')
-
- res.redirect("/");
-
-}
-
-
-exports.EnableSite = async function (req, res) {
-
- console.log(req.body)
- console.log('Enable Site')
-
- res.redirect("/");
}
\ No newline at end of file
diff --git a/controllers/images.js b/controllers/images.js
index 78c282e..8b6c242 100644
--- a/controllers/images.js
+++ b/controllers/images.js
@@ -1,14 +1,18 @@
+import { docker } from '../app.js';
+export const Images = async function(req, res) {
-exports.Images = async function(req, res) {
+ const allImages = await docker.listImages({ all: true });
+
+ for (let i = 0; i < allImages.length; i++) {
+ console.log(`Image ${i}:`)
+ console.log(`repoTags: ${allImages[i].repoTags}`)
+ }
-
- // Render the home page
- res.render("pages/images", {
+ res.render("images", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true,
});
}
\ No newline at end of file
diff --git a/controllers/login.js b/controllers/login.js
new file mode 100644
index 0000000..c6eb8f8
--- /dev/null
+++ b/controllers/login.js
@@ -0,0 +1,72 @@
+import { User } from '../database/models.js';
+import { 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":"",
+ });
+ }
+}
+
+export const submitLogin = async function(req,res){
+
+ let { email, password } = req.body;
+
+ if(email && password){
+
+ let existingUser = await User.findOne({ where: {email:email}});
+ if(existingUser){
+
+ let match = await bcrypt.compare(password,existingUser.password);
+
+ if(match){
+
+ let currentDate = new Date();
+ let newLogin = currentDate.toLocaleString();
+ await User.update({lastLogin: newLogin}, {where: {UUID:existingUser.UUID}});
+
+ req.session.user = existingUser.username;
+ req.session.UUID = existingUser.UUID;
+ req.session.role = existingUser.role;
+ req.session.avatar = existingUser.avatar;
+
+ const syslog = await Syslog.create({
+ user: req.session.user,
+ email: email,
+ event: "Successful Login",
+ message: "User logged in successfully",
+ ip: req.socket.remoteAddress
+ });
+
+
+ res.redirect("/");
+ }else{
+
+ const syslog = await Syslog.create({
+ user: null,
+ email: email,
+ event: "Bad Login",
+ message: "Invalid password",
+ ip: req.socket.remoteAddress
+ });
+
+ res.render("login",{
+ "error":"Invalid password",
+ });
+ }
+ }else{
+ res.render("login",{
+ "error":"User with that email does not exist.",
+ });
+ }
+ }else{
+ res.status(400);
+ res.render("login",{
+ "error":"Please fill in all the fields.",
+ });
+ }
+}
\ No newline at end of file
diff --git a/controllers/networks.js b/controllers/networks.js
index af6f43c..3d64242 100644
--- a/controllers/networks.js
+++ b/controllers/networks.js
@@ -1,14 +1,13 @@
-const User = require('../database/UserModel');
+import { docker } from '../app.js';
-exports.Networks = async function(req, res) {
-
- // Render the home page
- res.render("pages/users", {
+export const Networks = async function(req, res) {
+
+
+ res.render("networks", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true,
});
}
\ No newline at end of file
diff --git a/controllers/register.js b/controllers/register.js
new file mode 100644
index 0000000..c350eb6
--- /dev/null
+++ b/controllers/register.js
@@ -0,0 +1,96 @@
+import { User, Syslog } from '../database/models.js';
+import bcrypt from 'bcrypt';
+
+let SECRET = process.env.SECRET || "MrWiskers"
+
+export const Register = function(req,res){
+ if(req.session.user){
+ res.redirect("/logout");
+ } else {
+ res.render("register",{
+ "error":"",
+ });
+ }
+}
+
+
+
+export const submitRegister = async function(req,res){
+
+ let { name, username, email, password, confirmPassword, avatar, tos, secret } = req.body;
+
+
+ if (secret != SECRET) {
+ const syslog = await Syslog.create({
+ user: username,
+ email: email,
+ event: "Failed Registration",
+ message: "Invalid secret",
+ ip: req.socket.remoteAddress
+ });
+ }
+
+ if((name && email && password && confirmPassword && username && tos) && (secret == SECRET) && (password == confirmPassword)){
+
+ async function userRole () {
+ let userCount = await User.count();
+ if(userCount == 0){
+ return "admin";
+ }else{
+ return "user";
+ }
+ }
+
+ let existingUser = await User.findOne({ where: {email:email}});
+ if(!existingUser){
+
+ try {
+ const user = await User.create({
+ name: name,
+ username: username,
+ email: email,
+ password: bcrypt.hashSync(password,10),
+ role: await userRole(),
+ group: 'all',
+ avatar: `
`
+ });
+
+ // make sure the user was created and get the UUID.
+ let newUser = await User.findOne({ where: {email:email}});
+ let match = await bcrypt.compare(password,newUser.password);
+
+ if(match){
+ req.session.user = newUser.username;
+ req.session.UUID = newUser.UUID;
+ req.session.role = newUser.role;
+ req.session.avatar = newUser.avatar;
+
+ const syslog = await Syslog.create({
+ user: req.session.user,
+ email: email,
+ event: "Successful Registration",
+ message: "User registered successfully",
+ ip: req.socket.remoteAddress
+ });
+
+ res.redirect("/");
+ }
+ } catch(err) {
+ res.render("register",{
+ "error":"Something went wrong when creating account.",
+ });
+ }
+
+ } else {
+ // return an error.
+ res.render("register",{
+ "error":"User with that email already exists.",
+ });
+ }
+ } else {
+ // Redirect to the signup page.
+ res.render("register",{
+ "error":"Please fill in all the fields and accept TOS.",
+ });
+ }
+}
\ No newline at end of file
diff --git a/controllers/settings.js b/controllers/settings.js
index 16a199a..a3196f6 100644
--- a/controllers/settings.js
+++ b/controllers/settings.js
@@ -1,14 +1,9 @@
-const User = require('../database/UserModel.js');
-const Server = require('../database/ServerModel.js');
-exports.Settings = async function(req, res) {
+export const Settings = (req, res) => {
- // Render the home page
- res.render("pages/settings", {
+ res.render("settings", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true
});
-
}
\ No newline at end of file
diff --git a/controllers/syslogs.js b/controllers/syslogs.js
new file mode 100644
index 0000000..aa2d94a
--- /dev/null
+++ b/controllers/syslogs.js
@@ -0,0 +1,36 @@
+import { Syslog } from '../database/models.js';
+
+export const Syslogs = async function(req, res) {
+
+ let logs = '';
+
+ const syslogs = await Syslog.findAll({
+ order: [
+ ['id', 'DESC']
+ ]
+ });
+
+ for (const log of syslogs) {
+ let date = (log.createdAt).toDateString();
+ let time = (log.createdAt).toLocaleTimeString();
+ let datetime = `${time} ${date}`;
+
+ logs += `
+ ${log.id} |
+ ${log.user} |
+ ${log.email} |
+ ${log.event} |
+ ${log.message} |
+ ${log.ip} |
+ ${datetime} |
+
`
+ }
+
+ res.render("syslogs", {
+ name: req.session.user || 'Dev',
+ role: req.session.role || 'Dev',
+ avatar: req.session.avatar || '
',
+ logs: logs
+ });
+
+}
\ No newline at end of file
diff --git a/controllers/users.js b/controllers/users.js
index 9ddae52..1968c47 100644
--- a/controllers/users.js
+++ b/controllers/users.js
@@ -1,6 +1,6 @@
-const User = require('../database/UserModel');
+import { User } from '../database/models.js';
-exports.Users = async function(req, res) {
+export const Users = async (req, res) => {
let user_list = `
@@ -12,36 +12,48 @@ exports.Users = async function(req, res) {
Email |
UUID |
Role |
+ Last Login |
Status |
Actions |
`
- let users = await User.findAll();
- users.forEach((account) => {
- full_name = account.first_name + ' ' + account.last_name;
- user_info = `
+ let allUsers = await User.findAll();
+ allUsers.forEach((account) => {
+
+ let active = 'Active'
+ let lastLogin = new Date(account.lastLogin);
+ let currentDate = new Date();
+ let days = Math.floor((currentDate - lastLogin) / (1000 * 60 * 60 * 24));
+
+ if (days > 30) {
+ active = 'Inactive';
+ }
+
+
+
+ let info = `
|
- ${user.id} |
+ ${account.id} |
${account.avatar} |
- ${full_name} |
+ ${account.name} |
${account.username} |
${account.email} |
${account.UUID} |
${account.role} |
- Active |
+ ${account.lastLogin} |
+ ${active} |
Edit |
`
- user_list += user_info;
+ user_list += info;
});
- // Render the home page
- res.render("pages/users", {
+
+ res.render("users", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true,
user_list: user_list
});
diff --git a/controllers/volumes.js b/controllers/volumes.js
index 66eec83..c3d9548 100644
--- a/controllers/volumes.js
+++ b/controllers/volumes.js
@@ -1,15 +1,9 @@
-const User = require('../database/UserModel');
+import { docker } from '../app.js';
-exports.Volumes = async function(req, res) {
-
-
-
- // Render the home page
- res.render("pages/volumes", {
+export const Volumes = (req, res) => {
+ res.render("volumes", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
- isLoggedIn: true,
});
-
}
\ No newline at end of file
diff --git a/database/ContainerModel.js b/database/ContainerModel.js
deleted file mode 100644
index 0613f4e..0000000
--- a/database/ContainerModel.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const { Sequelize, DataTypes } = require('sequelize');
-
-const sequelize = new Sequelize({
- dialect: 'sqlite',
- storage: './database/db.sqlite',
- logging: false
-});
-
-
-const Containers = sequelize.define('Containers', {
- // Model attributes are defined here
- id: {
- type: DataTypes.INTEGER,
- autoIncrement: true,
- primaryKey: true
- },
- name: {
- type: DataTypes.STRING,
- allowNull: false
- },
- visibility: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- size: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- group: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- start: {
- type: DataTypes.JSON
- // allowNull defaults to true
- },
- stop: {
- type: DataTypes.JSON
- // allowNull defaults to true
- },
- pause: {
- type: DataTypes.JSON
- // allowNull defaults to true
- },
- restart: {
- type: DataTypes.JSON
- // allowNull defaults to true
- },
- remove: {
- type: DataTypes.JSON
- // allowNull defaults to true
- },
- logs: {
- type: DataTypes.JSON
- // allowNull defaults to true
- },
- update: {
- type: DataTypes.JSON
- // allowNull defaults to true
- },
-
-});
-
-async function syncModel() {
- await sequelize.sync();
- console.log('Containers model synced');
-}
-
-syncModel();
-
-
-module.exports = Containers;
\ No newline at end of file
diff --git a/database/ServerModel.js b/database/ServerModel.js
deleted file mode 100644
index f02072a..0000000
--- a/database/ServerModel.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const { Sequelize, DataTypes } = require('sequelize');
-
-const sequelize = new Sequelize({
- dialect: 'sqlite',
- storage: './database/db.sqlite',
- logging: false
-});
-
-
-const Server = sequelize.define('Server', {
- // Model attributes are defined here
- timezone: {
- type: DataTypes.STRING,
- allowNull: false
- },
- hwa: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- media: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- pgid: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- puid: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- caddy: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
-});
-
-async function syncModel() {
- await sequelize.sync();
- console.log('Server model synced');
-}
-
-syncModel();
-
-
-module.exports = Server;
\ No newline at end of file
diff --git a/database/UserModel.js b/database/UserModel.js
deleted file mode 100644
index 01ac4f4..0000000
--- a/database/UserModel.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const { Sequelize, DataTypes } = require('sequelize');
-
-const sequelize = new Sequelize({
- dialect: 'sqlite',
- storage: './database/db.sqlite',
- logging: false
-});
-
-
-const User = sequelize.define('User', {
- // Model attributes are defined here
- id: {
- type: DataTypes.INTEGER,
- autoIncrement: true,
- primaryKey: true
- },
- first_name: {
- type: DataTypes.STRING,
- allowNull: false
- },
- last_name: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- username: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- email: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- password: {
- type: DataTypes.STRING,
- // allowNull: false
- },
- role: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- group: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- avatar: {
- type: DataTypes.STRING
- // allowNull defaults to true
- },
- UUID: {
- type: DataTypes.UUID,
- defaultValue: DataTypes.UUIDV4
- }
-});
-
-async function syncModel() {
- await sequelize.sync();
- console.log('User model synced');
-}
-
-syncModel();
-
-
-module.exports = User;
\ No newline at end of file
diff --git a/database/models.js b/database/models.js
new file mode 100644
index 0000000..43b4a68
--- /dev/null
+++ b/database/models.js
@@ -0,0 +1,162 @@
+import { Sequelize, DataTypes } from 'sequelize';
+
+// let SQLITE_PASS = process.env.SQLITE_PASS || 'some_long_elaborate_password';
+
+// export const sequelize = new Sequelize('dweebui', 'dweebui', SQLITE_PASS, {
+// dialect: 'sqlite',
+// dialectModulePath: '@journeyapps/sqlcipher',
+// storage: './database/database.sqlite',
+// logging: false,
+// });
+
+export const sequelize = new Sequelize({
+ dialect: 'sqlite',
+ storage: './database/database.sqlite',
+ logging: false,
+});
+
+export const User = sequelize.define('User', {
+ id: {
+ type: DataTypes.INTEGER,
+ autoIncrement: true,
+ primaryKey: true
+ },
+ name: {
+ type: DataTypes.STRING
+ },
+ username: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ email: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ password: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ role: {
+ type: DataTypes.STRING
+ },
+ group: {
+ type: DataTypes.STRING
+ },
+ avatar: {
+ type: DataTypes.STRING
+ },
+ lastLogin: {
+ type: DataTypes.STRING
+ },
+ UUID: {
+ type: DataTypes.UUID,
+ defaultValue: DataTypes.UUIDV4,
+ }
+});
+
+export const Container = sequelize.define('Container', {
+ id: {
+ type: DataTypes.INTEGER,
+ autoIncrement: true,
+ primaryKey: true
+ },
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ visibility: {
+ type: DataTypes.STRING
+ },
+ size: {
+ type: DataTypes.STRING
+ },
+ group: {
+ type: DataTypes.STRING
+ }
+});
+
+export const Permission = sequelize.define('Permission', {
+ id: {
+ type: DataTypes.INTEGER,
+ autoIncrement: true,
+ primaryKey: true
+ },
+ containerName: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ containerID: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ user: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ userID: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ install: {
+ type: DataTypes.STRING,
+ },
+ uninstall: {
+ type: DataTypes.STRING
+ },
+ edit: {
+ type: DataTypes.STRING
+ },
+ upgrade: {
+ type: DataTypes.STRING
+ },
+ start: {
+ type: DataTypes.STRING
+ },
+ stop: {
+ type: DataTypes.STRING
+ },
+ restart: {
+ type: DataTypes.STRING
+ },
+ pause: {
+ type: DataTypes.STRING
+ },
+ logs: {
+ type: DataTypes.STRING
+ },
+ hide: {
+ type: DataTypes.STRING
+ },
+ view: {
+ type: DataTypes.STRING
+ },
+ reset_view: {
+ type: DataTypes.STRING
+ },
+});
+
+
+export const Syslog = sequelize.define('Syslog', {
+ id: {
+ type: DataTypes.INTEGER,
+ autoIncrement: true,
+ primaryKey: true
+ },
+ user: {
+ type: DataTypes.STRING
+ },
+ email: {
+ type: DataTypes.STRING
+ },
+ event: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ message: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ ip : {
+ type: DataTypes.STRING
+ },
+});
\ No newline at end of file
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 8e05778..b046ab9 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -2,9 +2,9 @@ version: "3.9"
services:
dweebui:
container_name: dweebui
- image: lllllllillllllillll/dweebui:v0.09-dev
- # build:
- # context: .
+ # image: lllllllillllllillll/dweebui:v0.20
+ build:
+ context: .
environment:
NODE_ENV: production
PORT: 8000
@@ -14,17 +14,13 @@ services:
- 8000:8000
volumes:
- dweebui:/app
- - caddyfiles:/app/caddyfiles
- /var/run/docker.sock:/var/run/docker.sock
- #- ./custom-templates.json:/app/custom-templates.json
- #- ./composefiles:/app/composefiles
networks:
- - dweeb_network
+ - dweebui_net
volumes:
dweebui:
- caddyfiles:
networks:
- dweeb_network:
+ dweebui_net:
driver: bridge
diff --git a/functions/compose.js b/functions/compose.js
deleted file mode 100644
index 153f982..0000000
--- a/functions/compose.js
+++ /dev/null
@@ -1,205 +0,0 @@
-const { writeFileSync, mkdirSync, readFileSync } = require("fs");
-const yaml = require('js-yaml');
-
-const { exec, execSync } = require("child_process");
-
-const { docker } = require('./system');
-
-var DockerodeCompose = require('dockerode-compose');
-
-
-module.exports.install = async function (data) {
-
- console.log(`[Start of install function]`);
-
- let { service_name, name, image, command_check, command, net_mode, restart_policy } = data;
- let { port0, port1, port2, port3, port4, port5 } = data;
- let { volume0, volume1, volume2, volume3, volume4, volume5 } = data;
- let { env0, env1, env2, env3, env4, env5, env6, env7, env8, env9, env10, env11 } = data;
- let { label0, label1, label2, label3, label4, label5, label6, label7, label8, label9, label10, label11 } = data;
-
-
- if ((service_name.includes('caddy')) || (name.includes('caddy'))) {
- req.app.locals.caddy = 'enabled';
- }
-
- let docker_volumes = [];
-
- if (image.startsWith('https://')){
- mkdirSync(`./appdata/${name}`, { recursive: true });
- execSync(`curl -o ./appdata/${name}/${name}_stack.yml -L ${image}`);
- console.log(`Downloaded stackfile: ${image}`);
- let stackfile = yaml.load(readFileSync(`./appdata/${name}/${name}_stack.yml`, 'utf8'));
- let services = Object.keys(stackfile.services);
-
- for ( let i = 0; i < services.length; i++ ) {
- try {
- console.log(stackfile.services[Object.keys(stackfile.services)[i]].environment);
- } catch { console.log('no env') }
- }
-
- } else {
-
- let compose_file = `version: '3'`;
- compose_file += `\nservices:`
- compose_file += `\n ${service_name}:`
- compose_file += `\n container_name: ${name}`;
- compose_file += `\n image: ${image}`;
-
- // Command
- if (command_check == 'on') {
- compose_file += `\n command: ${command}`
- }
-
- // Network mode
- if (net_mode == 'host') {
- compose_file += `\n network_mode: 'host'`
- }
- else if (net_mode != 'host' && net_mode != 'docker') {
- compose_file += `\n network_mode: '${net_mode}'`
- }
-
- // Restart policy
- if (restart_policy != '') {
- compose_file += `\n restart: ${restart_policy}`
- }
-
- // Ports
- if ((port0 == 'on' || port1 == 'on' || port2 == 'on' || port3 == 'on' || port4 == 'on' || port5 == 'on') && (net_mode != 'host')) {
- compose_file += `\n ports:`
-
- for (let i = 0; i < 6; i++) {
- if (data[`port${i}`] == 'on') {
- compose_file += `\n - ${data[`port_${i}_external`]}:${data[`port_${i}_internal`]}/${data[`port_${i}_protocol`]}`
- }
- }
- }
-
- // Volumes
- if (volume0 == 'on' || volume1 == 'on' || volume2 == 'on' || volume3 == 'on' || volume4 == 'on' || volume5 == 'on') {
- compose_file += `\n volumes:`
-
- for (let i = 0; i < 6; i++) {
-
- // if volume is on and neither bind or container is empty, it's a bind mount (ex /mnt/user/appdata/config:/config )
- if ((data[`volume${i}`] == 'on') && (data[`volume_${i}_bind`] != '') && (data[`volume_${i}_container`] != '')) {
- compose_file += `\n - ${data[`volume_${i}_bind`]}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}`
- }
-
- // if bind is empty create a docker volume (ex container_name_config:/config) convert any '/' in container name to '_'
- else if ((data[`volume${i}`] == 'on') && (data[`volume_${i}_bind`] == '') && (data[`volume_${i}_container`] != '')) {
- let volume_name = data[`volume_${i}_container`].replace(/\//g, '_');
- compose_file += `\n - ${name}_${volume_name}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}`
- docker_volumes.push(`${name}_${volume_name}`);
- }
- }
- }
-
- // Environment variables
- if (env0 == 'on' || env1 == 'on' || env2 == 'on' || env3 == 'on' || env4 == 'on' || env5 == 'on' || env6 == 'on' || env7 == 'on' || env8 == 'on' || env9 == 'on' || env10 == 'on' || env11 == 'on') {
- compose_file += `\n environment:`
- }
- for (let i = 0; i < 12; i++) {
- if (data[`env${i}`] == 'on') {
- compose_file += `\n - ${data[`env_${i}_name`]}=${data[`env_${i}_default`]}`
-
- }
- }
-
- // Add labels
- if (label0 == 'on' || label1 == 'on' || label2 == 'on' || label3 == 'on' || label4 == 'on' || label5 == 'on' || label6 == 'on' || label7 == 'on' || label8 == 'on' || label9 == 'on' || label10 == 'on' || label11 == 'on') {
- compose_file += `\n labels:`
- }
- for (let i = 0; i < 12; i++) {
- if (data[`label${i}`] == 'on') {
- compose_file += `\n - ${data[`label_${i}_name`]}=${data[`label_${i}_value`]}`
- }
- }
-
- // Add privileged mode
-
- if (data.privileged == 'on') {
- compose_file += `\n privileged: true`
- }
-
-
- // Add hardware acceleration to the docker-compose file if one of the environment variables has the label DRINODE
- if (env0 == 'on' || env1 == 'on' || env2 == 'on' || env3 == 'on' || env4 == 'on' || env5 == 'on' || env6 == 'on' || env7 == 'on' || env8 == 'on' || env9 == 'on' || env10 == 'on' || env11 == 'on') {
- for (let i = 0; i < 12; i++) {
- if (data[`env${i}`] == 'on') {
- if (data[`env_${i}_name`] == 'DRINODE') {
- compose_file += `\n deploy:`
- compose_file += `\n resources:`
- compose_file += `\n reservations:`
- compose_file += `\n devices:`
- compose_file += `\n - driver: nvidia`
- compose_file += `\n count: 1`
- compose_file += `\n capabilities: [gpu]`
- }
- }
- }
- }
-
-
- // add any docker volumes to the docker-compose file
- if ( docker_volumes.length > 0 ) {
- compose_file += `\n`
- compose_file += `\nvolumes:`
-
- // check docker_volumes for duplicates and remove them completely
- docker_volumes = docker_volumes.filter((item, index) => docker_volumes.indexOf(item) === index)
-
- for (let i = 0; i < docker_volumes.length; i++) {
- if ( docker_volumes[i] != '') {
- compose_file += `\n ${docker_volumes[i]}:`
- }
- }
- }
-
- try {
- mkdirSync(`./appdata/${name}`, { recursive: true });
- writeFileSync(`./appdata/${name}/docker-compose.yml`, compose_file, function (err) { console.log(err) });
-
- } catch { console.log('error creating directory or compose file') }
-
- try {
- var compose = new DockerodeCompose(docker, `./appdata/${name}/docker-compose.yml`, `${name}`);
-
- (async () => {
- await compose.pull();
- await compose.up();
- })();
-
- } catch { console.log('error running compose file')}
-
- }
-
-
-}
-
-
-
-module.exports.uninstall = async function (data) {
-
-
- if (data.confirm == 'Yes') {
-
-
- var containerName = docker.getContainer(`${data.service_name}`);
-
- try {
- containerName.stop(function (err, data) {
- if (data) {
- containerName.remove(function (err, data) {
- });
- }
- });
- } catch {
- containerName.remove(function (err, data) {
- });
- }
-
- }
-
-
-}
\ No newline at end of file
diff --git a/functions/package_manager.js b/functions/package_manager.js
deleted file mode 100644
index 9f5065a..0000000
--- a/functions/package_manager.js
+++ /dev/null
@@ -1,194 +0,0 @@
-const { writeFileSync, mkdirSync, readFileSync } = require("fs");
-const yaml = require('js-yaml');
-
-const { execSync } = require("child_process");
-
-const { docker } = require('./system');
-
-var DockerodeCompose = require('dockerode-compose');
-
-
-module.exports.install = async function (data) {
-
- console.log(`[Start of install function]`);
-
- let { service_name, name, image, command_check, command, net_mode, restart_policy } = data;
- let { port0, port1, port2, port3, port4, port5 } = data;
- let { volume0, volume1, volume2, volume3, volume4, volume5 } = data;
- let { env0, env1, env2, env3, env4, env5, env6, env7, env8, env9, env10, env11 } = data;
- let { label0, label1, label2, label3, label4, label5, label6, label7, label8, label9, label10, label11 } = data;
-
- let docker_volumes = [];
-
- if (image.startsWith('https://')){
- mkdirSync(`./appdata/${name}`, { recursive: true });
- execSync(`curl -o ./appdata/${name}/${name}_stack.yml -L ${image}`);
- console.log(`Downloaded stackfile: ${image}`);
- let stackfile = yaml.load(readFileSync(`./appdata/${name}/${name}_stack.yml`, 'utf8'));
- let services = Object.keys(stackfile.services);
-
- for ( let i = 0; i < services.length; i++ ) {
- try {
- console.log(stackfile.services[Object.keys(stackfile.services)[i]].environment);
- } catch { console.log('no env') }
- }
-
- } else {
-
- let compose_file = `version: '3'`;
- compose_file += `\nservices:`
- compose_file += `\n ${service_name}:`
- compose_file += `\n container_name: ${name}`;
- compose_file += `\n image: ${image}`;
-
- // Command
- if (command_check == 'on') {
- compose_file += `\n command: ${command}`
- }
-
- // Network mode
- if (net_mode == 'host') {
- compose_file += `\n network_mode: 'host'`
- }
- else if (net_mode != 'host' && net_mode != 'docker') {
- compose_file += `\n network_mode: '${net_mode}'`
- }
-
- // Restart policy
- if (restart_policy != '') {
- compose_file += `\n restart: ${restart_policy}`
- }
-
- // Ports
- if ((port0 == 'on' || port1 == 'on' || port2 == 'on' || port3 == 'on' || port4 == 'on' || port5 == 'on') && (net_mode != 'host')) {
- compose_file += `\n ports:`
-
- for (let i = 0; i < 6; i++) {
- if (data[`port${i}`] == 'on') {
- compose_file += `\n - ${data[`port_${i}_external`]}:${data[`port_${i}_internal`]}/${data[`port_${i}_protocol`]}`
- }
- }
- }
-
- // Volumes
- if (volume0 == 'on' || volume1 == 'on' || volume2 == 'on' || volume3 == 'on' || volume4 == 'on' || volume5 == 'on') {
- compose_file += `\n volumes:`
-
- for (let i = 0; i < 6; i++) {
-
- // if volume is on and neither bind or container is empty, it's a bind mount (ex /mnt/user/appdata/config:/config )
- if ((data[`volume${i}`] == 'on') && (data[`volume_${i}_bind`] != '') && (data[`volume_${i}_container`] != '')) {
- compose_file += `\n - ${data[`volume_${i}_bind`]}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}`
- }
-
- // if bind is empty create a docker volume (ex container_name_config:/config) convert any '/' in container name to '_'
- else if ((data[`volume${i}`] == 'on') && (data[`volume_${i}_bind`] == '') && (data[`volume_${i}_container`] != '')) {
- let volume_name = data[`volume_${i}_container`].replace(/\//g, '_');
- compose_file += `\n - ${name}_${volume_name}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}`
- docker_volumes.push(`${name}_${volume_name}`);
- }
- }
- }
-
- // Environment variables
- if (env0 == 'on' || env1 == 'on' || env2 == 'on' || env3 == 'on' || env4 == 'on' || env5 == 'on' || env6 == 'on' || env7 == 'on' || env8 == 'on' || env9 == 'on' || env10 == 'on' || env11 == 'on') {
- compose_file += `\n environment:`
- }
- for (let i = 0; i < 12; i++) {
- if (data[`env${i}`] == 'on') {
- compose_file += `\n - ${data[`env_${i}_name`]}=${data[`env_${i}_default`]}`
-
- }
- }
-
- // Add labels
- if (label0 == 'on' || label1 == 'on' || label2 == 'on' || label3 == 'on' || label4 == 'on' || label5 == 'on' || label6 == 'on' || label7 == 'on' || label8 == 'on' || label9 == 'on' || label10 == 'on' || label11 == 'on') {
- compose_file += `\n labels:`
- }
- for (let i = 0; i < 12; i++) {
- if (data[`label${i}`] == 'on') {
- compose_file += `\n - ${data[`label_${i}_name`]}=${data[`label_${i}_value`]}`
- }
- }
-
- // Add privileged mode
-
- if (data.privileged == 'on') {
- compose_file += `\n privileged: true`
- }
-
-
- // Add hardware acceleration to the docker-compose file if one of the environment variables has the label DRINODE
- if (env0 == 'on' || env1 == 'on' || env2 == 'on' || env3 == 'on' || env4 == 'on' || env5 == 'on' || env6 == 'on' || env7 == 'on' || env8 == 'on' || env9 == 'on' || env10 == 'on' || env11 == 'on') {
- for (let i = 0; i < 12; i++) {
- if (data[`env${i}`] == 'on') {
- if (data[`env_${i}_name`] == 'DRINODE') {
- compose_file += `\n deploy:`
- compose_file += `\n resources:`
- compose_file += `\n reservations:`
- compose_file += `\n devices:`
- compose_file += `\n - driver: nvidia`
- compose_file += `\n count: 1`
- compose_file += `\n capabilities: [gpu]`
- }
- }
- }
- }
-
-
- // add any docker volumes to the docker-compose file
- if ( docker_volumes.length > 0 ) {
- compose_file += `\n`
- compose_file += `\nvolumes:`
-
- // check docker_volumes for duplicates and remove them completely
- docker_volumes = docker_volumes.filter((item, index) => docker_volumes.indexOf(item) === index)
-
- for (let i = 0; i < docker_volumes.length; i++) {
- if ( docker_volumes[i] != '') {
- compose_file += `\n ${docker_volumes[i]}:`
- }
- }
- }
-
- try {
- mkdirSync(`./appdata/${name}`, { recursive: true });
- writeFileSync(`./appdata/${name}/docker-compose.yml`, compose_file, function (err) { console.log(err) });
-
- } catch { console.log('error creating directory or compose file') }
-
- try {
- var compose = new DockerodeCompose(docker, `./appdata/${name}/docker-compose.yml`, `${name}`);
-
- (async () => {
- await compose.pull();
- await compose.up();
- })();
-
- } catch { console.log('error running compose file')}
-
- }
-
-
-}
-
-
-
-module.exports.uninstall = async function (data) {
- if (data.confirm == 'Yes') {
- console.log(`Uninstalling ${data.service_name}: ${data}`);
- var containerName = docker.getContainer(`${data.service_name}`);
- try {
- await containerName.stop();
- console.log(`Stopped ${data.service_name} container`);
- } catch {
- console.log(`Error stopping ${data.service_name} container`);
- }
- try {
- await containerName.remove();
- console.log(`Removed ${data.service_name} container`);
- } catch {
- console.log(`Error removing ${data.service_name} container`);
- }
- }
-}
\ No newline at end of file
diff --git a/functions/system.js b/functions/system.js
deleted file mode 100644
index a3a1df6..0000000
--- a/functions/system.js
+++ /dev/null
@@ -1,382 +0,0 @@
-const { currentLoad, mem, networkStats, fsSize, dockerContainerStats, dockerImages, networkInterfaces, dockerInfo } = require('systeminformation');
-var Docker = require('dockerode');
-var docker = new Docker({ socketPath: '/var/run/docker.sock' });
-const { dashCard } = require('../components/dashCard');
-const { Readable } = require('stream');
-
-const Containers = require('../database/ContainerModel');
-
-// export docker
-module.exports.docker = docker;
-
-
-let IPv4 = '';
-networkInterfaces().then(data => {
- IPv4 = data[0].ip4;
-});
-
-let hidden = '';
-module.exports.hiddenContainers = async function () {
- hidden = await Containers.findAll({ where: {visibility:false}});
- hidden = hidden.map(a => a.name);
-}
-
-module.exports.serverStats = async function () {
- const cpuUsage = await currentLoad();
- const ramUsage = await mem();
- const netUsage = await networkStats();
- const diskUsage = await fsSize();
-
- const info = {
- cpu: Math.round(cpuUsage.currentLoad),
- ram: Math.round((ramUsage.active / ramUsage.total) * 100),
- tx: netUsage[0].tx_bytes,
- rx: netUsage[0].rx_bytes,
- disk: diskUsage[0].use,
- };
-
- return info;
-}
-
-
-
-module.exports.containerList = async function () {
- let card_list = '';
-
- const data = await docker.listContainers({ all: true });
- for (const container of data) {
-
-
- if (!hidden.includes(container.Names[0].slice(1))) {
-
- let imageVersion = container.Image.split('/');
- let service = imageVersion[imageVersion.length - 1].split(':')[0];
-
- let containerId = docker.getContainer(container.Id);
- let containerInfo = await containerId.inspect();
-
- // Get ports //////////////////////////
- let ports_list = [];
- try {
- for (const [key, value] of Object.entries(containerInfo.HostConfig.PortBindings)) {
- let ports = {
- check : 'checked',
- external: value[0].HostPort,
- internal: key.split('/')[0],
- protocol: key.split('/')[1]
- }
- ports_list.push(ports);
- }
- } catch {
- // console.log('no ports')
- }
-
- for (let i = 0; i < 12; i++) {
- if (ports_list[i] == undefined) {
- let ports = {
- check : '',
- external: '',
- internal: '',
- protocol: ''
- }
- ports_list[i] = ports;
- }
- } /////////////////////////////////////
-
-
- // Get volumes ////////////////////////
- let volumes_list = [];
- try { for (const [key, value] of Object.entries(containerInfo.HostConfig.Binds)) {
- let volumes = {
- check : 'checked',
- bind: value.split(':')[0],
- container: value.split(':')[1],
- readwrite: value.split(':')[2]
- }
- volumes_list.push(volumes);
- }} catch {
- // console.log('no volumes')
- }
- for (let i = 0; i < 12; i++) {
- if (volumes_list[i] == undefined) {
- let volumes = {
- check : '',
- bind: '',
- container: '',
- readwrite: ''
- }
- volumes_list[i] = volumes;
- }
- } /////////////////////////////////////
-
-
- // Get environment variables.
- let environment_variables = [];
- try { for (const [key, value] of Object.entries(containerInfo.Config.Env)) {
- let env = {
- check : 'checked',
- name: value.split('=')[0],
- default: value.split('=')[1]
- }
- environment_variables.push(env);
- }} catch { console.log('no env') }
- for (let i = 0; i < 12; i++) {
- if (environment_variables[i] == undefined) {
- let env = {
- check : '',
- name: '',
- default: ''
- }
- environment_variables[i] = env;
- }
- }
-
- // Get labels.
- let labels = [];
- for (const [key, value] of Object.entries(containerInfo.Config.Labels)) {
- let label = {
- check : 'checked',
- name: key,
- value: value
- }
- labels.push(label);
- }
- for (let i = 0; i < 12; i++) {
- if (labels[i] == undefined) {
- let label = {
- check : '',
- name: '',
- value: ''
- }
- labels[i] = label;
- }
- }
-
-
- let container_info = {
- name: container.Names[0].slice(1),
- service: service,
- id: container.Id,
- state: container.State,
- image: container.Image,
- external_port: ports_list[0].external || 0,
- internal_port: ports_list[0].internal || 0,
- ports: ports_list,
- volumes: volumes_list,
- environment_variables: environment_variables,
- labels: labels,
- IPv4: IPv4,
- style: "Compact"
- }
-
- let dockerCard = dashCard(container_info);
-
- card_list += dockerCard;
- }
-
- }
-
- return card_list;
-}
-
-
-
-
-
-
-
-module.exports.containerStats = async function () {
-
- let container_stats = [];
- const data = await docker.listContainers({ all: true });
-
- for (const container of data) {
-
- if (!hidden.includes(container.Names[0].slice(1))) {
- const stats = await dockerContainerStats(container.Id);
-
- let container_stat = {
- name: container.Names[0].slice(1),
- cpu: Math.round(stats[0].cpuPercent),
- ram: Math.round(stats[0].memPercent)
- }
-
- //push stats to an array
- container_stats.push(container_stat);
- }
- }
- return container_stats;
-}
-
-
-
-
-
-
-module.exports.containerAction = async function (data) {
-
- let { user, role, action, container, state } = data;
-
- console.log(`${user} wants to: ${action} ${container}`);
-
- if (role == 'admin') {
- var containerName = docker.getContainer(container);
-
- if ((action == 'start') && (state == 'stopped')) {
- containerName.start();
- } else if ((action == 'start') && (state == 'paused')) {
- containerName.unpause();
- } else if ((action == 'stop') && (state != 'stopped')) {
- containerName.stop();
- } else if ((action == 'pause') && (state == 'running')) {
- containerName.pause();
- } else if ((action == 'pause') && (state == 'paused')) {
- containerName.unpause();
- } else if (action == 'restart') {
- containerName.restart();
- }
- } else {
- console.log('User is not an admin');
- }
-}
-
-
-
-module.exports.containerExec = async function (data) {
-
- let { container, command } = data;
-
- var containerName = docker.getContainer(container);
-
- var options = {
- Cmd: ['/bin/sh', '-c', command],
- AttachStdout: true,
- AttachStderr: true,
- Tty: true
- };
-
- containerName.exec(options, function (err, exec) {
- if (err) return;
-
- exec.start(function (err, stream) {
- if (err) return;
-
- containerName.modem.demuxStream(stream, process.stdout, process.stderr);
-
- exec.inspect(function (err, data) {
- if (err) return;
-
-
- });
- });
- });
-
-}
-
-
-
-
-
-
-
-
-
-
-module.exports.containerLogs = function (data) {
- return new Promise((resolve, reject) => {
- let logString = '';
-
- var options = {
- follow: false,
- stdout: true,
- stderr: false,
- timestamps: false
- };
-
- var containerName = docker.getContainer(data);
-
- containerName.logs(options, function (err, stream) {
- if (err) {
- reject(err);
- return;
- }
-
- const readableStream = Readable.from(stream);
-
- readableStream.on('data', function (chunk) {
- logString += chunk.toString('utf8');
- });
-
- readableStream.on('end', function () {
- resolve(logString);
- });
- });
- });
-};
-
-
-
-module.exports.dockerImages = async function () {
-
- // get the names, tags, status, created date, and size of all images
-
- const data1 = await dockerImages({ all: true });
-
- const data2 = await docker.listImages({ all: true });
-
- // for ( i = 0; i < data.length; i++) {
- // console.log(`Image ${i}:`)
- // console.log(`repoTags: ${data[i].repoTags}`)
- // }
-
- // console.log(data1);
-
- console.log(data2);
-
-}
-
-
-module.exports.dockerVolumes = async function () {
- let volume_list = '';
-
- const data = await docker.listVolumes();
-
- return data;
-
- // for (const volume of data.Volumes) {
-
- // let volume_info = {
- // name: volume.Name,
- // style: "Compact"
- // }
-
- // let dockerCard = dashCard(volume_info);
-
- // volume_list += dockerCard;
- // }
-
- // return volume_list;
-}
-
-
-module.exports.dockerNetworks = async function () {
- let network_list = '';
-
- const data = await docker.listNetworks();
-
- return data;
-
- // for (const network of data) {
-
- // let network_info = {
- // name: network.Name,
- // style: "Compact"
- // }
-
- // let dockerCard = dashCard(network_info);
-
- // network_list += dockerCard;
- // }
-
- // return network_list;
-}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index f99496f..228d68c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,20 +9,540 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
- "bcrypt": "^5.1.0",
- "child_process": "^1.0.2",
+ "@babel/register": "^7.23.7",
+ "@journeyapps/sqlcipher": "^5.3.1",
+ "@socket.io/admin-ui": "^0.5.1",
+ "bcrypt": "^5.1.1",
+ "chai": "^5.0.0",
"compression": "^1.7.4",
- "dockerode": "^4.0.0",
- "dockerode-compose": "^1.4.0",
+ "cors": "^2.8.5",
+ "dockerode": "^4.0.1",
"ejs": "^3.1.9",
"express": "^4.18.2",
"express-session": "^1.17.3",
"helmet": "^7.1.0",
- "js-yaml": "^4.1.0",
+ "mocha": "^10.2.0",
"sequelize": "^6.35.2",
- "socket.io": "^4.6.1",
+ "sinon": "^17.0.1",
+ "socket.io": "^4.7.2",
"sqlite3": "^5.1.6",
- "systeminformation": "^5.21.20"
+ "stream": "^0.0.2",
+ "supertest": "^6.3.3",
+ "systeminformation": "^5.21.22"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "peer": true,
+ "dependencies": {
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "peer": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "peer": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "peer": true
+ },
+ "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "peer": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
+ "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.23.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
+ "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
+ "peer": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.23.7",
+ "@babel/parser": "^7.23.6",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.7",
+ "@babel/types": "^7.23.6",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
+ "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.23.6",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+ "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.23.5",
+ "@babel/helper-validator-option": "^7.23.5",
+ "browserslist": "^4.22.2",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "peer": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "peer": true
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "peer": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+ "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+ "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+ "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+ "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+ "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.23.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz",
+ "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.7",
+ "@babel/types": "^7.23.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "peer": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "peer": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "peer": true
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "peer": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
+ "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
+ "peer": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/register": {
+ "version": "7.23.7",
+ "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.23.7.tgz",
+ "integrity": "sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==",
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "find-cache-dir": "^2.0.0",
+ "make-dir": "^2.1.0",
+ "pirates": "^4.0.6",
+ "source-map-support": "^0.5.16"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/register/node_modules/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@babel/register/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.23.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
+ "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.6",
+ "@babel/types": "^7.23.6",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
+ "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.23.4",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
"node_modules/@balena/dockerignore": {
@@ -36,6 +556,64 @@
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
"optional": true
},
+ "node_modules/@journeyapps/sqlcipher": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@journeyapps/sqlcipher/-/sqlcipher-5.3.1.tgz",
+ "integrity": "sha512-d1mncvE1f9+A/P3HJLwjSAgY6/IDAf2TPLGRgTLQN4hRO7J0QdqEC6CRUvPFJXcsGHn9JkEHQnPpzFXh81ocLA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@mapbox/node-pre-gyp": "^1.0.0",
+ "node-addon-api": "^3.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "peer": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.20",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
+ "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
"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",
@@ -79,6 +657,58 @@
"node": ">=10"
}
},
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
+ "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "11.2.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
+ "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.0"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
+ "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
+ "dependencies": {
+ "@sinonjs/commons": "^2.0.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
+ "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/text-encoding": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz",
+ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ=="
+ },
+ "node_modules/@socket.io/admin-ui": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/@socket.io/admin-ui/-/admin-ui-0.5.1.tgz",
+ "integrity": "sha512-1dlGL2FGm6T+uL1e6iDvbo2eCINwvW7iVbjIblwh5kPPRM1SP8lmZrbFZf4QNJ/cqQ+JLcx49eXGM9WAB4TK7w==",
+ "dependencies": {
+ "@types/bcryptjs": "^2.4.2",
+ "bcryptjs": "^2.4.3",
+ "debug": "~4.3.1"
+ },
+ "peerDependencies": {
+ "socket.io": ">=3.1.0"
+ }
+ },
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
@@ -93,6 +723,11 @@
"node": ">= 6"
}
},
+ "node_modules/@types/bcryptjs": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz",
+ "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ=="
+ },
"node_modules/@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
@@ -120,9 +755,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.10.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz",
- "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==",
+ "version": "20.10.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
+ "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -185,6 +820,14 @@
"node": ">=8"
}
},
+ "node_modules/ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -207,6 +850,18 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
@@ -234,6 +889,11 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
+ },
"node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
@@ -242,11 +902,24 @@
"safer-buffer": "~2.1.0"
}
},
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/async": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -300,6 +973,32 @@
"tweetnacl": "^0.14.3"
}
},
+ "node_modules/bcrypt/node_modules/node-addon-api": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
+ "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
+ },
+ "node_modules/bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "dependencies": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -333,6 +1032,14 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
+ "node_modules/body-parser/node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/body-parser/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -355,6 +1062,54 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
+ },
+ "node_modules/browserslist": {
+ "version": "4.22.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
+ "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "peer": true,
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001565",
+ "electron-to-chromium": "^1.4.601",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
@@ -378,6 +1133,11 @@
"ieee754": "^1.1.13"
}
},
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "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",
@@ -388,9 +1148,9 @@
}
},
"node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
"engines": {
"node": ">= 0.8"
}
@@ -437,6 +1197,52 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001574",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz",
+ "integrity": "sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "peer": true
+ },
+ "node_modules/chai": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.0.0.tgz",
+ "integrity": "sha512-HO5p0oEKd5M6HEcwOkNAThAE3j960vIZvVcc0t2tI06Dd0ATu69cEnMB2wOhC5/ZyQ6m67w3ePjU/HzXsSsdBA==",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.0.0",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.0.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -452,10 +1258,39 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/child_process": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
- "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g=="
+ "node_modules/check-error": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.0.0.tgz",
+ "integrity": "sha512-tjLAOBHKVxtPoHe/SA7kNOMvhCRdCJ3vETdeY0RuAc9popf+hyaSV6ZEg9hr4cpWF7jmo/JSWEnLDrnijS9Tog==",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
},
"node_modules/chownr": {
"version": "2.0.0",
@@ -474,6 +1309,29 @@
"node": ">=6"
}
},
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -498,6 +1356,30 @@
"color-support": "bin.js"
}
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
+ },
+ "node_modules/component-emitter": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
+ "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -526,14 +1408,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/compression/node_modules/bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/compression/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -547,11 +1421,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/compression/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -573,6 +1442,25 @@
"node": ">= 0.6"
}
},
+ "node_modules/content-disposition/node_modules/safe-buffer": {
+ "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/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
@@ -581,6 +1469,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "peer": true
+ },
"node_modules/cookie": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
@@ -594,6 +1488,11 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
+ "node_modules/cookiejar": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="
+ },
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
@@ -636,6 +1535,47 @@
}
}
},
+ "node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.1.tgz",
+ "integrity": "sha512-nwQCf6ne2gez3o1MxWifqkciwt0zhl0LO1/UwVu4uMBuPmflWM4oQ70XMqHqnBJA+nhzncaqL9HVL6KkHJ28lw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
"node_modules/define-data-property": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
@@ -649,6 +1589,14 @@
"node": ">= 0.4"
}
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
@@ -679,59 +1627,50 @@
"node": ">=8"
}
},
+ "node_modules/dezalgo": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
+ "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+ "dependencies": {
+ "asap": "^2.0.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/diff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/docker-modem": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.1.tgz",
- "integrity": "sha512-vqrE/nrweCyzmCpVpdFRC41qS+tfTF+IoUKlTZr52O82urbUqdfyJBGWMvT01pYUprWepLr8IkyVTEWJKRTQSg==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.3.tgz",
+ "integrity": "sha512-89zhop5YVhcPEt5FpUFGr3cDyceGhq/F9J+ZndQ4KfqNvfbJpPMfgeixFgUj5OjCYAboElqODxY5Z1EBsSa6sg==",
"dependencies": {
"debug": "^4.1.1",
"readable-stream": "^3.5.0",
"split-ca": "^1.0.1",
- "ssh2": "^1.11.0"
+ "ssh2": "^1.15.0"
},
"engines": {
"node": ">= 8.0"
}
},
"node_modules/dockerode": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-4.0.0.tgz",
- "integrity": "sha512-3LF7/3MPz5+9RsUo91rD0MCcx0yxjC9bnbtgtVjOLKyKxlZSJ7/Kk3OPAgARlwlWHqXwAGYhmkAHYx7IwD0tJQ==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-4.0.2.tgz",
+ "integrity": "sha512-9wM1BVpVMFr2Pw3eJNXrYYt6DT9k0xMcsSCjtPvyQ+xa1iPg/Mo3T/gUcwI0B2cczqCeCYRPF8yFYDwtFXT0+w==",
"dependencies": {
"@balena/dockerignore": "^1.0.2",
- "docker-modem": "^5.0.0",
+ "docker-modem": "^5.0.3",
"tar-fs": "~2.0.1"
},
"engines": {
"node": ">= 8.0"
}
},
- "node_modules/dockerode-compose": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/dockerode-compose/-/dockerode-compose-1.4.0.tgz",
- "integrity": "sha512-6x5ZlK06H+cgoTR4ffucqN5kWVvxNvxwTLcHQUZcegCJBEDGrdzXMOEGDMsxbHwiLtLo2dNwG0eZK7B2RfEWSw==",
- "dependencies": {
- "dockerode": "^4.0.0",
- "js-yaml": "^4.0.0",
- "tar-fs": "^2.1.1"
- }
- },
- "node_modules/dockerode-compose/node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
- },
- "node_modules/dockerode-compose/node_modules/tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
- "dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
- }
- },
"node_modules/dottie": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz",
@@ -756,6 +1695,20 @@
"node": ">=0.10.0"
}
},
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.623",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz",
+ "integrity": "sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A==",
+ "peer": true
+ },
+ "node_modules/emitter-component": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz",
+ "integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -849,11 +1802,30 @@
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
"optional": true
},
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
},
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@@ -862,6 +1834,14 @@
"node": ">= 0.6"
}
},
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
@@ -942,6 +1922,25 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/express-session/node_modules/safe-buffer": {
+ "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/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -955,6 +1954,35 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/express/node_modules/safe-buffer": {
+ "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/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
+ },
+ "node_modules/file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
+ },
"node_modules/filelist": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -982,6 +2010,17 @@
"node": ">=10"
}
},
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
@@ -1012,6 +2051,89 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/find-cache-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+ "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^2.0.0",
+ "pkg-dir": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/formidable": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
+ "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
+ "dependencies": {
+ "dezalgo": "^1.0.4",
+ "hexoid": "^1.0.0",
+ "once": "^1.4.0",
+ "qs": "^6.11.0"
+ },
+ "funding": {
+ "url": "https://ko-fi.com/tunnckoCore/commissions"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -1049,6 +2171,19 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -1076,6 +2211,31 @@
"node": ">=10"
}
},
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-func-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
+ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/get-intrinsic": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
@@ -1090,6 +2250,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
+ },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -1109,6 +2274,26 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
@@ -1183,6 +2368,14 @@
"node": ">= 0.4"
}
},
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
"node_modules/helmet": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz",
@@ -1191,6 +2384,14 @@
"node": ">=16.0.0"
}
},
+ "node_modules/hexoid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
+ "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
@@ -1323,6 +2524,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
"node_modules/ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
@@ -1337,6 +2543,25 @@
"node": ">= 0.10"
}
},
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -1345,18 +2570,80 @@
"node": ">=8"
}
},
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-lambda": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
"integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
"optional": true
},
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
+ },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"optional": true
},
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/jake": {
"version": "10.8.7",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz",
@@ -1374,6 +2661,12 @@
"node": ">=10"
}
},
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "peer": true
+ },
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -1385,11 +2678,90 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "peer": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "peer": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/just-extend": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
+ "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg=="
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/loupe": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.0.2.tgz",
+ "integrity": "sha512-Tzlkbynv7dtqxTROe54Il+J4e/zG2iehtJGZUYpTv8WzlkW9qyEcE83UhGJCeuF3SCfzHuM5VWhBi47phV3+AQ==",
+ "dependencies": {
+ "get-func-name": "^2.0.1"
+ }
+ },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -1501,6 +2873,17 @@
"node": ">= 0.6"
}
},
+ "node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -1512,6 +2895,14 @@
"node": "*"
}
},
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
@@ -1616,18 +3007,136 @@
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
+ "node_modules/mocha": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
+ "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
+ "dependencies": {
+ "ansi-colors": "4.1.1",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.5.3",
+ "debug": "4.3.4",
+ "diff": "5.0.0",
+ "escape-string-regexp": "4.0.0",
+ "find-up": "5.0.0",
+ "glob": "7.2.0",
+ "he": "1.2.0",
+ "js-yaml": "4.1.0",
+ "log-symbols": "4.1.0",
+ "minimatch": "5.0.1",
+ "ms": "2.1.3",
+ "nanoid": "3.3.3",
+ "serialize-javascript": "6.0.0",
+ "strip-json-comments": "3.1.1",
+ "supports-color": "8.1.1",
+ "workerpool": "6.2.1",
+ "yargs": "16.2.0",
+ "yargs-parser": "20.2.4",
+ "yargs-unparser": "2.0.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mochajs"
+ }
+ },
+ "node_modules/mocha/node_modules/glob": {
+ "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",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/mocha/node_modules/glob/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mocha/node_modules/minimatch": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
+ "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mocha/node_modules/minimatch/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/mocha/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/mocha/node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/moment": {
- "version": "2.29.4",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
- "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": {
"node": "*"
}
},
"node_modules/moment-timezone": {
- "version": "0.5.43",
- "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz",
- "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==",
+ "version": "0.5.44",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.44.tgz",
+ "integrity": "sha512-nv3YpzI/8lkQn0U6RkLd+f0W/zy/JnoR5/EyPz/dNkPTBjA2jNLCVxaiQ8QpeLymhSZvX0wCL5s27NQWdOPwAw==",
"dependencies": {
"moment": "^2.29.4"
},
@@ -1646,6 +3155,22 @@
"integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==",
"optional": true
},
+ "node_modules/nanoid": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
+ "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+ },
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -1654,10 +3179,65 @@
"node": ">= 0.6"
}
},
+ "node_modules/nise": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz",
+ "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==",
+ "dependencies": {
+ "@sinonjs/commons": "^2.0.0",
+ "@sinonjs/fake-timers": "^10.0.2",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "node_modules/nise/node_modules/@sinonjs/commons": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
+ "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/nise/node_modules/@sinonjs/fake-timers": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
+ "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.0"
+ }
+ },
+ "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
+ "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/nise/node_modules/path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "dependencies": {
+ "isarray": "0.0.1"
+ }
+ },
+ "node_modules/node-abi": {
+ "version": "3.54.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz",
+ "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/node-addon-api": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
- "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
+ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A=="
},
"node_modules/node-fetch": {
"version": "2.7.0",
@@ -1749,6 +3329,12 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "peer": true
+ },
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
@@ -1763,6 +3349,14 @@
"node": ">=6"
}
},
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/npmlog": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
@@ -1817,6 +3411,34 @@
"wrappy": "1"
}
},
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/p-map": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
@@ -1832,6 +3454,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -1840,6 +3470,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -1853,11 +3491,144 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
+ "node_modules/pathval": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
+ "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
"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=="
},
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "peer": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dependencies": {
+ "find-up": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dependencies": {
+ "locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dependencies": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dependencies": {
+ "p-limit": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^3.3.0",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^4.0.0",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@@ -1920,6 +3691,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -1942,6 +3721,28 @@
"node": ">= 0.8"
}
},
+ "node_modules/raw-body/node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -1955,6 +3756,25 @@
"node": ">= 6"
}
},
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
@@ -1984,23 +3804,9 @@
}
},
"node_modules/safe-buffer": {
- "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"
- }
- ]
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/safer-buffer": {
"version": "2.1.2",
@@ -2131,6 +3937,14 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
"node_modules/serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
@@ -2169,6 +3983,17 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dependencies": {
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -2187,6 +4012,74 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "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/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/sinon": {
+ "version": "17.0.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz",
+ "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.0",
+ "@sinonjs/fake-timers": "^11.2.2",
+ "@sinonjs/samsam": "^8.0.0",
+ "diff": "^5.1.0",
+ "nise": "^5.1.5",
+ "supports-color": "^7.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sinon"
+ }
+ },
+ "node_modules/sinon/node_modules/diff": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+ "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
@@ -2198,9 +4091,9 @@
}
},
"node_modules/socket.io": {
- "version": "4.7.2",
- "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz",
- "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==",
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.3.tgz",
+ "integrity": "sha512-SE+UIQXBQE+GPG2oszWMlsEmWtHVqw/h1VrYJGK5/MC7CH5p58N448HwIrtREcvR4jfdOJAY4ieQfxMr55qbbw==",
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
@@ -2262,19 +4155,37 @@
"node": ">= 10"
}
},
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
"node_modules/split-ca": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz",
"integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ=="
},
"node_modules/sqlite3": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz",
- "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==",
+ "version": "5.1.7",
+ "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz",
+ "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==",
"hasInstallScript": true,
"dependencies": {
- "@mapbox/node-pre-gyp": "^1.0.0",
- "node-addon-api": "^4.2.0",
+ "bindings": "^1.5.0",
+ "node-addon-api": "^7.0.0",
+ "prebuild-install": "^7.1.1",
"tar": "^6.1.11"
},
"optionalDependencies": {
@@ -2290,14 +4201,14 @@
}
},
"node_modules/sqlite3/node_modules/node-addon-api": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
- "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz",
+ "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA=="
},
"node_modules/ssh2": {
- "version": "1.14.0",
- "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.14.0.tgz",
- "integrity": "sha512-AqzD1UCqit8tbOKoj6ztDDi1ffJZ2rV2SwlgrVVrHPkV5vWqGJOVp5pmtj18PunkPJAuKQsnInyKV+/Nb2bUnA==",
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.15.0.tgz",
+ "integrity": "sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==",
"hasInstallScript": true,
"dependencies": {
"asn1": "^0.2.6",
@@ -2307,8 +4218,8 @@
"node": ">=10.16.0"
},
"optionalDependencies": {
- "cpu-features": "~0.0.8",
- "nan": "^2.17.0"
+ "cpu-features": "~0.0.9",
+ "nan": "^2.18.0"
}
},
"node_modules/ssri": {
@@ -2331,6 +4242,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/stream": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz",
+ "integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==",
+ "dependencies": {
+ "emitter-component": "^1.1.1"
+ }
+ },
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -2339,6 +4258,25 @@
"safe-buffer": "~5.2.0"
}
},
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "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/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -2363,6 +4301,57 @@
"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",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/superagent": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz",
+ "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==",
+ "dependencies": {
+ "component-emitter": "^1.3.0",
+ "cookiejar": "^2.1.4",
+ "debug": "^4.3.4",
+ "fast-safe-stringify": "^2.1.1",
+ "form-data": "^4.0.0",
+ "formidable": "^2.1.2",
+ "methods": "^1.1.2",
+ "mime": "2.6.0",
+ "qs": "^6.11.0",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">=6.4.0 <13 || >=14"
+ }
+ },
+ "node_modules/superagent/node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/supertest": {
+ "version": "6.3.3",
+ "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz",
+ "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==",
+ "dependencies": {
+ "methods": "^1.1.2",
+ "superagent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">=6.4.0"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -2375,9 +4364,9 @@
}
},
"node_modules/systeminformation": {
- "version": "5.21.20",
- "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.20.tgz",
- "integrity": "sha512-AyS1fNc+MDoAJtFknFbbo587H8h6yejJwM+H9rVusnOToIEkiMehMyD5JM7o3j55Cto20MawIZrcgNMgd4BfOQ==",
+ "version": "5.21.22",
+ "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.22.tgz",
+ "integrity": "sha512-gNHloAJSyS+sKWkwvmvozZ1eHrdVTEsynWMTY6lvLGBB70gflkBQFw8drXXr1oEXY84+Vr9tOOrN8xHZLJSycA==",
"os": [
"darwin",
"linux",
@@ -2454,6 +4443,26 @@
"node": ">=8"
}
},
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -2472,11 +4481,30 @@
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
},
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -2531,6 +4559,36 @@
"node": ">= 0.8"
}
},
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "peer": true,
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -2613,6 +4671,27 @@
"@types/node": "*"
}
},
+ "node_modules/workerpool": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
+ "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw=="
+ },
+ "node_modules/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/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -2638,10 +4717,68 @@
}
}
},
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
}
}
}
diff --git a/package.json b/package.json
index 8bd93e6..cf9f02d 100644
--- a/package.json
+++ b/package.json
@@ -1,25 +1,35 @@
{
"name": "dweebui",
"version": "1.0.0",
+ "description": "A web UI for Docker",
"main": "app.js",
+ "type": "module",
+ "scripts": {
+ "test": "mocha --require @babel/register --exit"
+ },
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
- "bcrypt": "^5.1.0",
- "child_process": "^1.0.2",
+ "@babel/register": "^7.23.7",
+ "@journeyapps/sqlcipher": "^5.3.1",
+ "@socket.io/admin-ui": "^0.5.1",
+ "bcrypt": "^5.1.1",
+ "chai": "^5.0.0",
"compression": "^1.7.4",
- "dockerode": "^4.0.0",
- "dockerode-compose": "^1.4.0",
+ "cors": "^2.8.5",
+ "dockerode": "^4.0.1",
"ejs": "^3.1.9",
"express": "^4.18.2",
"express-session": "^1.17.3",
"helmet": "^7.1.0",
- "js-yaml": "^4.1.0",
+ "mocha": "^10.2.0",
"sequelize": "^6.35.2",
- "socket.io": "^4.6.1",
+ "sinon": "^17.0.1",
+ "socket.io": "^4.7.2",
"sqlite3": "^5.1.6",
- "systeminformation": "^5.21.20"
- },
- "description": ""
+ "stream": "^0.0.2",
+ "supertest": "^6.3.3",
+ "systeminformation": "^5.21.22"
+ }
}
diff --git a/public/css/meters.css b/public/css/meters.css
index 6f97f47..89ded5b 100644
--- a/public/css/meters.css
+++ b/public/css/meters.css
@@ -2,7 +2,7 @@
.meter {
box-sizing: content-box;
- height: 15px; /* Can be anything */
+ height: 15px;
margin-left: auto;
margin-right: auto;
position: relative;
diff --git a/public/css/tabler.min.css b/public/css/tabler.min.css
index 5c288bd..3c0f155 100644
--- a/public/css/tabler.min.css
+++ b/public/css/tabler.min.css
@@ -11462,47 +11462,38 @@ fieldset:disabled .btn {
}
.column-gap-0 {
- -moz-column-gap: 0 !important;
column-gap: 0 !important
}
.column-gap-1 {
- -moz-column-gap: .25rem !important;
column-gap: .25rem !important
}
.column-gap-2 {
- -moz-column-gap: .5rem !important;
column-gap: .5rem !important
}
.column-gap-3 {
- -moz-column-gap: 1rem !important;
column-gap: 1rem !important
}
.column-gap-4 {
- -moz-column-gap: 1.5rem !important;
column-gap: 1.5rem !important
}
.column-gap-5 {
- -moz-column-gap: 2rem !important;
column-gap: 2rem !important
}
.column-gap-6 {
- -moz-column-gap: 3rem !important;
column-gap: 3rem !important
}
.column-gap-7 {
- -moz-column-gap: 5rem !important;
column-gap: 5rem !important
}
.column-gap-8 {
- -moz-column-gap: 8rem !important;
column-gap: 8rem !important
}
@@ -12910,17 +12901,14 @@ fieldset:disabled .btn {
}
.columns-2 {
- -moz-columns: 2 !important;
columns: 2 !important
}
.columns-3 {
- -moz-columns: 3 !important;
columns: 3 !important
}
.columns-4 {
- -moz-columns: 4 !important;
columns: 4 !important
}
@@ -13821,47 +13809,38 @@ fieldset:disabled .btn {
}
.column-gap-sm-0 {
- -moz-column-gap: 0 !important;
column-gap: 0 !important
}
.column-gap-sm-1 {
- -moz-column-gap: .25rem !important;
column-gap: .25rem !important
}
.column-gap-sm-2 {
- -moz-column-gap: .5rem !important;
column-gap: .5rem !important
}
.column-gap-sm-3 {
- -moz-column-gap: 1rem !important;
column-gap: 1rem !important
}
.column-gap-sm-4 {
- -moz-column-gap: 1.5rem !important;
column-gap: 1.5rem !important
}
.column-gap-sm-5 {
- -moz-column-gap: 2rem !important;
column-gap: 2rem !important
}
.column-gap-sm-6 {
- -moz-column-gap: 3rem !important;
column-gap: 3rem !important
}
.column-gap-sm-7 {
- -moz-column-gap: 5rem !important;
column-gap: 5rem !important
}
.column-gap-sm-8 {
- -moz-column-gap: 8rem !important;
column-gap: 8rem !important
}
@@ -13878,17 +13857,14 @@ fieldset:disabled .btn {
}
.columns-sm-2 {
- -moz-columns: 2 !important;
columns: 2 !important
}
.columns-sm-3 {
- -moz-columns: 3 !important;
columns: 3 !important
}
.columns-sm-4 {
- -moz-columns: 4 !important;
columns: 4 !important
}
}
@@ -14790,47 +14766,38 @@ fieldset:disabled .btn {
}
.column-gap-md-0 {
- -moz-column-gap: 0 !important;
column-gap: 0 !important
}
.column-gap-md-1 {
- -moz-column-gap: .25rem !important;
column-gap: .25rem !important
}
.column-gap-md-2 {
- -moz-column-gap: .5rem !important;
column-gap: .5rem !important
}
.column-gap-md-3 {
- -moz-column-gap: 1rem !important;
column-gap: 1rem !important
}
.column-gap-md-4 {
- -moz-column-gap: 1.5rem !important;
column-gap: 1.5rem !important
}
.column-gap-md-5 {
- -moz-column-gap: 2rem !important;
column-gap: 2rem !important
}
.column-gap-md-6 {
- -moz-column-gap: 3rem !important;
column-gap: 3rem !important
}
.column-gap-md-7 {
- -moz-column-gap: 5rem !important;
column-gap: 5rem !important
}
.column-gap-md-8 {
- -moz-column-gap: 8rem !important;
column-gap: 8rem !important
}
@@ -14847,17 +14814,14 @@ fieldset:disabled .btn {
}
.columns-md-2 {
- -moz-columns: 2 !important;
columns: 2 !important
}
.columns-md-3 {
- -moz-columns: 3 !important;
columns: 3 !important
}
.columns-md-4 {
- -moz-columns: 4 !important;
columns: 4 !important
}
}
@@ -15759,47 +15723,38 @@ fieldset:disabled .btn {
}
.column-gap-lg-0 {
- -moz-column-gap: 0 !important;
column-gap: 0 !important
}
.column-gap-lg-1 {
- -moz-column-gap: .25rem !important;
column-gap: .25rem !important
}
.column-gap-lg-2 {
- -moz-column-gap: .5rem !important;
column-gap: .5rem !important
}
.column-gap-lg-3 {
- -moz-column-gap: 1rem !important;
column-gap: 1rem !important
}
.column-gap-lg-4 {
- -moz-column-gap: 1.5rem !important;
column-gap: 1.5rem !important
}
.column-gap-lg-5 {
- -moz-column-gap: 2rem !important;
column-gap: 2rem !important
}
.column-gap-lg-6 {
- -moz-column-gap: 3rem !important;
column-gap: 3rem !important
}
.column-gap-lg-7 {
- -moz-column-gap: 5rem !important;
column-gap: 5rem !important
}
.column-gap-lg-8 {
- -moz-column-gap: 8rem !important;
column-gap: 8rem !important
}
@@ -15816,17 +15771,14 @@ fieldset:disabled .btn {
}
.columns-lg-2 {
- -moz-columns: 2 !important;
columns: 2 !important
}
.columns-lg-3 {
- -moz-columns: 3 !important;
columns: 3 !important
}
.columns-lg-4 {
- -moz-columns: 4 !important;
columns: 4 !important
}
}
@@ -16728,47 +16680,38 @@ fieldset:disabled .btn {
}
.column-gap-xl-0 {
- -moz-column-gap: 0 !important;
column-gap: 0 !important
}
.column-gap-xl-1 {
- -moz-column-gap: .25rem !important;
column-gap: .25rem !important
}
.column-gap-xl-2 {
- -moz-column-gap: .5rem !important;
column-gap: .5rem !important
}
.column-gap-xl-3 {
- -moz-column-gap: 1rem !important;
column-gap: 1rem !important
}
.column-gap-xl-4 {
- -moz-column-gap: 1.5rem !important;
column-gap: 1.5rem !important
}
.column-gap-xl-5 {
- -moz-column-gap: 2rem !important;
column-gap: 2rem !important
}
.column-gap-xl-6 {
- -moz-column-gap: 3rem !important;
column-gap: 3rem !important
}
.column-gap-xl-7 {
- -moz-column-gap: 5rem !important;
column-gap: 5rem !important
}
.column-gap-xl-8 {
- -moz-column-gap: 8rem !important;
column-gap: 8rem !important
}
@@ -16785,17 +16728,14 @@ fieldset:disabled .btn {
}
.columns-xl-2 {
- -moz-columns: 2 !important;
columns: 2 !important
}
.columns-xl-3 {
- -moz-columns: 3 !important;
columns: 3 !important
}
.columns-xl-4 {
- -moz-columns: 4 !important;
columns: 4 !important
}
}
@@ -17697,47 +17637,38 @@ fieldset:disabled .btn {
}
.column-gap-xxl-0 {
- -moz-column-gap: 0 !important;
column-gap: 0 !important
}
.column-gap-xxl-1 {
- -moz-column-gap: .25rem !important;
column-gap: .25rem !important
}
.column-gap-xxl-2 {
- -moz-column-gap: .5rem !important;
column-gap: .5rem !important
}
.column-gap-xxl-3 {
- -moz-column-gap: 1rem !important;
column-gap: 1rem !important
}
.column-gap-xxl-4 {
- -moz-column-gap: 1.5rem !important;
column-gap: 1.5rem !important
}
.column-gap-xxl-5 {
- -moz-column-gap: 2rem !important;
column-gap: 2rem !important
}
.column-gap-xxl-6 {
- -moz-column-gap: 3rem !important;
column-gap: 3rem !important
}
.column-gap-xxl-7 {
- -moz-column-gap: 5rem !important;
column-gap: 5rem !important
}
.column-gap-xxl-8 {
- -moz-column-gap: 8rem !important;
column-gap: 8rem !important
}
@@ -17754,17 +17685,14 @@ fieldset:disabled .btn {
}
.columns-xxl-2 {
- -moz-columns: 2 !important;
columns: 2 !important
}
.columns-xxl-3 {
- -moz-columns: 3 !important;
columns: 3 !important
}
.columns-xxl-4 {
- -moz-columns: 4 !important;
columns: 4 !important
}
}
diff --git a/public/fonts/Inter-Black.woff2 b/public/fonts/Inter-Black.woff2
new file mode 100644
index 0000000..18b35db
Binary files /dev/null and b/public/fonts/Inter-Black.woff2 differ
diff --git a/public/fonts/Inter-BlackItalic.woff2 b/public/fonts/Inter-BlackItalic.woff2
new file mode 100644
index 0000000..02c9d8e
Binary files /dev/null and b/public/fonts/Inter-BlackItalic.woff2 differ
diff --git a/public/fonts/Inter-Bold.woff2 b/public/fonts/Inter-Bold.woff2
new file mode 100644
index 0000000..0f1b157
Binary files /dev/null and b/public/fonts/Inter-Bold.woff2 differ
diff --git a/public/fonts/Inter-BoldItalic.woff2 b/public/fonts/Inter-BoldItalic.woff2
new file mode 100644
index 0000000..bc50f24
Binary files /dev/null and b/public/fonts/Inter-BoldItalic.woff2 differ
diff --git a/public/fonts/Inter-ExtraBold.woff2 b/public/fonts/Inter-ExtraBold.woff2
new file mode 100644
index 0000000..b113368
Binary files /dev/null and b/public/fonts/Inter-ExtraBold.woff2 differ
diff --git a/public/fonts/Inter-ExtraBoldItalic.woff2 b/public/fonts/Inter-ExtraBoldItalic.woff2
new file mode 100644
index 0000000..a5b76ca
Binary files /dev/null and b/public/fonts/Inter-ExtraBoldItalic.woff2 differ
diff --git a/public/fonts/Inter-ExtraLight.woff2 b/public/fonts/Inter-ExtraLight.woff2
new file mode 100644
index 0000000..1d77ae8
Binary files /dev/null and b/public/fonts/Inter-ExtraLight.woff2 differ
diff --git a/public/fonts/Inter-ExtraLightItalic.woff2 b/public/fonts/Inter-ExtraLightItalic.woff2
new file mode 100644
index 0000000..8c68492
Binary files /dev/null and b/public/fonts/Inter-ExtraLightItalic.woff2 differ
diff --git a/public/fonts/Inter-Italic.woff2 b/public/fonts/Inter-Italic.woff2
new file mode 100644
index 0000000..4c24ce2
Binary files /dev/null and b/public/fonts/Inter-Italic.woff2 differ
diff --git a/public/fonts/Inter-Light.woff2 b/public/fonts/Inter-Light.woff2
new file mode 100644
index 0000000..dbe6143
Binary files /dev/null and b/public/fonts/Inter-Light.woff2 differ
diff --git a/public/fonts/Inter-LightItalic.woff2 b/public/fonts/Inter-LightItalic.woff2
new file mode 100644
index 0000000..a40d042
Binary files /dev/null and b/public/fonts/Inter-LightItalic.woff2 differ
diff --git a/public/fonts/Inter-Medium.woff2 b/public/fonts/Inter-Medium.woff2
new file mode 100644
index 0000000..0fd2ee7
Binary files /dev/null and b/public/fonts/Inter-Medium.woff2 differ
diff --git a/public/fonts/Inter-MediumItalic.woff2 b/public/fonts/Inter-MediumItalic.woff2
new file mode 100644
index 0000000..9676715
Binary files /dev/null and b/public/fonts/Inter-MediumItalic.woff2 differ
diff --git a/public/fonts/Inter-Regular.woff2 b/public/fonts/Inter-Regular.woff2
new file mode 100644
index 0000000..b8699af
Binary files /dev/null and b/public/fonts/Inter-Regular.woff2 differ
diff --git a/public/fonts/Inter-SemiBold.woff2 b/public/fonts/Inter-SemiBold.woff2
new file mode 100644
index 0000000..95c48b1
Binary files /dev/null and b/public/fonts/Inter-SemiBold.woff2 differ
diff --git a/public/fonts/Inter-SemiBoldItalic.woff2 b/public/fonts/Inter-SemiBoldItalic.woff2
new file mode 100644
index 0000000..ddfe19e
Binary files /dev/null and b/public/fonts/Inter-SemiBoldItalic.woff2 differ
diff --git a/public/fonts/Inter-Thin.woff2 b/public/fonts/Inter-Thin.woff2
new file mode 100644
index 0000000..0790960
Binary files /dev/null and b/public/fonts/Inter-Thin.woff2 differ
diff --git a/public/fonts/Inter-ThinItalic.woff2 b/public/fonts/Inter-ThinItalic.woff2
new file mode 100644
index 0000000..a7bf213
Binary files /dev/null and b/public/fonts/Inter-ThinItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-Black.woff2 b/public/fonts/InterDisplay-Black.woff2
new file mode 100644
index 0000000..8138123
Binary files /dev/null and b/public/fonts/InterDisplay-Black.woff2 differ
diff --git a/public/fonts/InterDisplay-BlackItalic.woff2 b/public/fonts/InterDisplay-BlackItalic.woff2
new file mode 100644
index 0000000..735ba21
Binary files /dev/null and b/public/fonts/InterDisplay-BlackItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-Bold.woff2 b/public/fonts/InterDisplay-Bold.woff2
new file mode 100644
index 0000000..11c6719
Binary files /dev/null and b/public/fonts/InterDisplay-Bold.woff2 differ
diff --git a/public/fonts/InterDisplay-BoldItalic.woff2 b/public/fonts/InterDisplay-BoldItalic.woff2
new file mode 100644
index 0000000..5b6a1fb
Binary files /dev/null and b/public/fonts/InterDisplay-BoldItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-ExtraBold.woff2 b/public/fonts/InterDisplay-ExtraBold.woff2
new file mode 100644
index 0000000..9058e98
Binary files /dev/null and b/public/fonts/InterDisplay-ExtraBold.woff2 differ
diff --git a/public/fonts/InterDisplay-ExtraBoldItalic.woff2 b/public/fonts/InterDisplay-ExtraBoldItalic.woff2
new file mode 100644
index 0000000..4cd61c0
Binary files /dev/null and b/public/fonts/InterDisplay-ExtraBoldItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-ExtraLight.woff2 b/public/fonts/InterDisplay-ExtraLight.woff2
new file mode 100644
index 0000000..8621b29
Binary files /dev/null and b/public/fonts/InterDisplay-ExtraLight.woff2 differ
diff --git a/public/fonts/InterDisplay-ExtraLightItalic.woff2 b/public/fonts/InterDisplay-ExtraLightItalic.woff2
new file mode 100644
index 0000000..689c8d9
Binary files /dev/null and b/public/fonts/InterDisplay-ExtraLightItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-Italic.woff2 b/public/fonts/InterDisplay-Italic.woff2
new file mode 100644
index 0000000..11f20bc
Binary files /dev/null and b/public/fonts/InterDisplay-Italic.woff2 differ
diff --git a/public/fonts/InterDisplay-Light.woff2 b/public/fonts/InterDisplay-Light.woff2
new file mode 100644
index 0000000..446301c
Binary files /dev/null and b/public/fonts/InterDisplay-Light.woff2 differ
diff --git a/public/fonts/InterDisplay-LightItalic.woff2 b/public/fonts/InterDisplay-LightItalic.woff2
new file mode 100644
index 0000000..f688196
Binary files /dev/null and b/public/fonts/InterDisplay-LightItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-Medium.woff2 b/public/fonts/InterDisplay-Medium.woff2
new file mode 100644
index 0000000..29160b2
Binary files /dev/null and b/public/fonts/InterDisplay-Medium.woff2 differ
diff --git a/public/fonts/InterDisplay-MediumItalic.woff2 b/public/fonts/InterDisplay-MediumItalic.woff2
new file mode 100644
index 0000000..ef1bcbe
Binary files /dev/null and b/public/fonts/InterDisplay-MediumItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-Regular.woff2 b/public/fonts/InterDisplay-Regular.woff2
new file mode 100644
index 0000000..a6c04f6
Binary files /dev/null and b/public/fonts/InterDisplay-Regular.woff2 differ
diff --git a/public/fonts/InterDisplay-SemiBold.woff2 b/public/fonts/InterDisplay-SemiBold.woff2
new file mode 100644
index 0000000..2b4db23
Binary files /dev/null and b/public/fonts/InterDisplay-SemiBold.woff2 differ
diff --git a/public/fonts/InterDisplay-SemiBoldItalic.woff2 b/public/fonts/InterDisplay-SemiBoldItalic.woff2
new file mode 100644
index 0000000..59091db
Binary files /dev/null and b/public/fonts/InterDisplay-SemiBoldItalic.woff2 differ
diff --git a/public/fonts/InterDisplay-Thin.woff2 b/public/fonts/InterDisplay-Thin.woff2
new file mode 100644
index 0000000..dc0b948
Binary files /dev/null and b/public/fonts/InterDisplay-Thin.woff2 differ
diff --git a/public/fonts/InterDisplay-ThinItalic.woff2 b/public/fonts/InterDisplay-ThinItalic.woff2
new file mode 100644
index 0000000..96439c0
Binary files /dev/null and b/public/fonts/InterDisplay-ThinItalic.woff2 differ
diff --git a/public/fonts/InterVariable-Italic.woff2 b/public/fonts/InterVariable-Italic.woff2
new file mode 100644
index 0000000..f22ec25
Binary files /dev/null and b/public/fonts/InterVariable-Italic.woff2 differ
diff --git a/public/fonts/InterVariable.woff2 b/public/fonts/InterVariable.woff2
new file mode 100644
index 0000000..22a12b0
Binary files /dev/null and b/public/fonts/InterVariable.woff2 differ
diff --git a/public/fonts/inter.css b/public/fonts/inter.css
new file mode 100644
index 0000000..ff5b47d
--- /dev/null
+++ b/public/fonts/inter.css
@@ -0,0 +1,59 @@
+/* Variable fonts usage:
+:root { font-family: "Inter", sans-serif; }
+@supports (font-variation-settings: normal) {
+ :root { font-family: "InterVariable", sans-serif; font-optical-sizing: auto; }
+} */
+@font-face {
+ font-family: InterVariable;
+ font-style: normal;
+ font-weight: 100 900;
+ font-display: swap;
+ src: url('InterVariable.woff2?v=4.0') format('woff2');
+}
+@font-face {
+ font-family: InterVariable;
+ font-style: italic;
+ font-weight: 100 900;
+ font-display: swap;
+ src: url('InterVariable-Italic.woff2?v=4.0') format('woff2');
+}
+/* legacy name "Inter var" (Oct 2023) */
+@font-face { font-family:'Inter var'; font-style:normal; font-weight:100 900; font-display:swap; src: url('InterVariable.woff2?v=4.0') format('woff2'); }
+@font-face { font-family:'Inter var'; font-style:italic; font-weight:100 900; font-display:swap; src: url('InterVariable-Italic.woff2?v=4.0') format('woff2'); }
+/* static fonts */
+@font-face { font-family:Inter; font-style:normal; font-weight:100; font-display:swap; src:url("Inter-Thin.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:100; font-display:swap; src:url("Inter-ThinItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:200; font-display:swap; src:url("Inter-ExtraLight.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:200; font-display:swap; src:url("Inter-ExtraLightItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:300; font-display:swap; src:url("Inter-Light.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:300; font-display:swap; src:url("Inter-LightItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:400; font-display:swap; src:url("Inter-Regular.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:400; font-display:swap; src:url("Inter-Italic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:500; font-display:swap; src:url("Inter-Medium.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:500; font-display:swap; src:url("Inter-MediumItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:600; font-display:swap; src:url("Inter-SemiBold.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:600; font-display:swap; src:url("Inter-SemiBoldItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:700; font-display:swap; src:url("Inter-Bold.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:700; font-display:swap; src:url("Inter-BoldItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:800; font-display:swap; src:url("Inter-ExtraBold.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:800; font-display:swap; src:url("Inter-ExtraBoldItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:normal; font-weight:900; font-display:swap; src:url("Inter-Black.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:Inter; font-style:italic; font-weight:900; font-display:swap; src:url("Inter-BlackItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:100; font-display:swap; src:url("InterDisplay-Thin.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:100; font-display:swap; src:url("InterDisplay-ThinItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:200; font-display:swap; src:url("InterDisplay-ExtraLight.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:200; font-display:swap; src:url("InterDisplay-ExtraLightItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:300; font-display:swap; src:url("InterDisplay-Light.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:300; font-display:swap; src:url("InterDisplay-LightItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:400; font-display:swap; src:url("InterDisplay-Regular.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:400; font-display:swap; src:url("InterDisplay-Italic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:500; font-display:swap; src:url("InterDisplay-Medium.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:500; font-display:swap; src:url("InterDisplay-MediumItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:600; font-display:swap; src:url("InterDisplay-SemiBold.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:600; font-display:swap; src:url("InterDisplay-SemiBoldItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:700; font-display:swap; src:url("InterDisplay-Bold.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:700; font-display:swap; src:url("InterDisplay-BoldItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:800; font-display:swap; src:url("InterDisplay-ExtraBold.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:800; font-display:swap; src:url("InterDisplay-ExtraBoldItalic.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:normal; font-weight:900; font-display:swap; src:url("InterDisplay-Black.woff2?v=4.0") format("woff2"); }
+@font-face { font-family:InterDisplay; font-style:italic; font-weight:900; font-display:swap; src:url("InterDisplay-BlackItalic.woff2?v=4.0") format("woff2"); }
\ No newline at end of file
diff --git a/public/static/avatars/burns.jpg b/public/img/avatars/burns.jpg
similarity index 100%
rename from public/static/avatars/burns.jpg
rename to public/img/avatars/burns.jpg
diff --git a/public/img/avatars/duffman.png b/public/img/avatars/duffman.png
new file mode 100644
index 0000000..6b29787
Binary files /dev/null and b/public/img/avatars/duffman.png differ
diff --git a/public/static/avatars/frank.jpg b/public/img/avatars/frank.jpg
similarity index 100%
rename from public/static/avatars/frank.jpg
rename to public/img/avatars/frank.jpg
diff --git a/public/static/avatars/moe.jpg b/public/img/avatars/moe.jpg
similarity index 100%
rename from public/static/avatars/moe.jpg
rename to public/img/avatars/moe.jpg
diff --git a/public/img/avatars/moleman.png b/public/img/avatars/moleman.png
new file mode 100644
index 0000000..ed0a8ab
Binary files /dev/null and b/public/img/avatars/moleman.png differ
diff --git a/public/static/avatars/poochie.jpg b/public/img/avatars/poochie.jpg
similarity index 100%
rename from public/static/avatars/poochie.jpg
rename to public/img/avatars/poochie.jpg
diff --git a/public/static/avatars/rus.jpg b/public/img/avatars/rus.jpg
similarity index 100%
rename from public/static/avatars/rus.jpg
rename to public/img/avatars/rus.jpg
diff --git a/public/static/avatars/skinner.jpg b/public/img/avatars/skinner.jpg
similarity index 100%
rename from public/static/avatars/skinner.jpg
rename to public/img/avatars/skinner.jpg
diff --git a/public/js/demo-theme.js b/public/js/demo-theme.js
index aea1ac9..749ccd6 100644
--- a/public/js/demo-theme.js
+++ b/public/js/demo-theme.js
@@ -12,7 +12,7 @@
})((function () { 'use strict';
var themeStorageKey = "tablerTheme";
- var defaultTheme = "light";
+ var defaultTheme = "dark";
var selectedTheme;
var params = new Proxy(new URLSearchParams(window.location.search), {
get: function get(searchParams, prop) {
diff --git a/public/js/main.js b/public/js/main.js
index a91ae29..246d739 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -1,16 +1,6 @@
-// SOCKET IO
-const socket = io({
- auth: {
- token: "abc"
- }
-});
+socket.on('connect', () => { console.log('connected'); });
-// ON CONNECT EVENT
-socket.on('connect', () => {
- console.log('Connected');
-});
-
-// SELECT METRICS ELEMENTS
+// Server metrics
const cpuText = document.getElementById('cpu-text');
const cpuBar = document.getElementById('cpu-bar');
const ramText = document.getElementById('ram-text');
@@ -20,19 +10,22 @@ const netBar = document.getElementById('net-bar');
const diskText = document.getElementById('disk-text');
const diskBar = document.getElementById('disk-bar');
+// Container cards
const dockerCards = document.getElementById('cards');
+// Container logs
const logViewer = document.getElementById('logView');
-//Update usage bars
+// Server metrics
socket.on('metrics', (data) => {
-
- let {cpu, ram, tx, rx, disk} = data;
+ let [cpu, ram, tx, rx, disk] = data;
cpuText.innerHTML = `CPU ${cpu} %`;
+ if (cpu < 7 ) { cpu = 7; }
cpuBar.innerHTML = ``;
ramText.innerHTML = `RAM ${ram} %`;
+ if (ram < 7 ) { ram = 7; }
ramBar.innerHTML = ``;
tx = Math.round(tx / 1024 / 1024);
@@ -42,165 +35,117 @@ socket.on('metrics', (data) => {
netBar.innerHTML = ``;
diskText.innerHTML = `DISK ${disk} %`;
+ if (disk < 7 ) { disk = 7; }
diskBar.innerHTML = ``;
});
-function drawCharts(name, cpu_array, ram_array) {
- var elements = document.querySelectorAll(`${name}`);
-
- Array.from(elements).forEach(function(element) {
- if (window.ApexCharts) {
- new ApexCharts(element, {
- chart: {
- type: "line",
- fontFamily: 'inherit',
- height: 40.0,
- sparkline: {
- enabled: true
- },
- animations: {
- enabled: false
- }
- },
- fill: {
- opacity: 1
- },
- stroke: {
- width: [2, 1],
- dashArray: [0, 3],
- lineCap: "round",
- curve: "smooth"
- },
- series: [{
- name: "CPU",
- data: cpu_array
- }, {
- name: "RAM",
- data: ram_array
- }],
- tooltip: {
- theme: 'dark'
- },
- grid: {
- strokeDashArray: 4
- },
- xaxis: {
- labels: {
- padding: 0
- },
- tooltip: {
- enabled: false
- },
- type: 'datetime'
- },
- yaxis: {
- labels: {
- padding: 4
- }
- },
- labels: [
- '2020-06-20', '2020-06-21', '2020-06-22', '2020-06-23', '2020-06-24', '2020-06-25', '2020-06-26', '2020-06-27', '2020-06-28', '2020-06-29', '2020-06-30', '2020-07-01', '2020-07-02', '2020-07-03', '2020-07-04', '2020-07-05', '2020-07-06', '2020-07-07', '2020-07-08', '2020-07-09', '2020-07-10', '2020-07-11', '2020-07-12', '2020-07-13', '2020-07-14', '2020-07-15', '2020-07-16', '2020-07-17', '2020-07-18', '2020-07-19'
- ],
- colors: [tabler.getColor("primary"), tabler.getColor("gray-600")],
- legend: {
- show: false
- }
- }).render();
- }
- });
-}
-
-// container button actions
-function buttonAction(button) {
- socket.emit('clicked', {container: button.name, state: button.id, action: button.value});
-}
-
-
-function hideContainer(button) {
- socket.emit('hide', {container: button.name});
-}
-
-function resetView() {
- socket.emit('reset');
-}
-
-let containerLogs;
-
-function viewLogs(button) {
-
- if (button.name != 'refresh') {
- containerLogs = button.name;
- }
-
-
- socket.emit('logs', {container: containerLogs});
-}
-
-socket.on('logString', (data) => {
- logViewer.innerHTML = `${data}
`;
+// Container cards
+socket.on('containers', (data) => {
+ let deleteMeElements = document.querySelectorAll('.deleteme');
+ deleteMeElements.forEach((element) => {
+ element.parentNode.removeChild(element);
+ });
+ dockerCards.insertAdjacentHTML("afterend", data);
});
+function drawCharts(name, cpuArray, ramArray) {
+ let element = document.querySelector(`${name}`);
-socket.on('cards', (data) => {
-
- console.log('cards deleted');
- let deleteMeElements = document.querySelectorAll('.deleteme');
- deleteMeElements.forEach((element) => {
- element.parentNode.removeChild(element);
- });
-
- dockerCards.insertAdjacentHTML("afterend", data);
-
- // check localStorage for items ending with _cpu and redraw the charts
- for (let i = 0; i < localStorage.length; i++) {
- if (localStorage.key(i).endsWith('_cpu')) {
- let name = localStorage.key(i).split('_')[0];
- let cpu_array = JSON.parse(localStorage.getItem(`${name}_cpu`));
- let ram_array = JSON.parse(localStorage.getItem(`${name}_ram`));
- drawCharts(`#${name}_chart`, cpu_array, ram_array);
+ let chart = new ApexCharts(element, {
+ chart: {
+ type: "line",
+ height: 40.0,
+ sparkline: {
+ enabled: true
+ },
+ animations: {
+ enabled: false
+ }
+ },
+ fill: {
+ opacity: 1
+ },
+ stroke: {
+ width: [2, 1],
+ dashArray: [0, 3],
+ lineCap: "round",
+ curve: "smooth"
+ },
+ series: [{
+ name: "CPU",
+ data: cpuArray
+ }, {
+ name: "RAM",
+ data: ramArray
+ }],
+ tooltip: {
+ enabled: false
+ },
+ grid: {
+ strokeDashArray: 4
+ },
+ xaxis: {
+ labels: {
+ padding: 0
+ },
+ tooltip: {
+ enabled: false
+ }
+ },
+ yaxis: {
+ labels: {
+ padding: 4
+ }
+ },
+ colors: [tabler.getColor("primary"), tabler.getColor("gray-600")],
+ legend: {
+ show: false
}
- }
-
-
-});
+ })
+ chart.render();
+}
+
+// Buttons functions
+function clicked(button) {
+ socket.emit('clicked', {name: button.name, id: button.id, value: button.value});
+}
socket.on('containerStats', (data) => {
-
- let {name, cpu, ram} = data;
-
- console.log(`drawing chart for ${name}`)
-
- var cpu_array = JSON.parse(localStorage.getItem(`${name}_cpu`));
- var ram_array = JSON.parse(localStorage.getItem(`${name}_ram`));
-
- if (cpu_array == null) { cpu_array = Array(30).fill(0); }
- if (ram_array == null) { ram_array = Array(30).fill(0); }
-
- cpu_array.push(cpu);
- ram_array.push(ram);
+ let containerStats = data;
- cpu_array = cpu_array.slice(-30);
- ram_array = ram_array.slice(-30);
+ for (const [name, statsArray] of Object.entries(containerStats)) {
- localStorage.setItem(`${name}_cpu`, JSON.stringify(cpu_array));
- localStorage.setItem(`${name}_ram`, JSON.stringify(ram_array));
+ let cpuArray = statsArray.cpuArray;
+ let ramArray = statsArray.ramArray;
- // replace the old chart with the new one
- let chart = document.getElementById(`${name}_chart`);
- if (chart) {
- let newChart = document.createElement('div');
- newChart.id = `${name}_chart`;
- chart.parentNode.replaceChild(newChart, chart);
- drawCharts(`#${name}_chart`, cpu_array, ram_array);
- } else {
- console.log(`Chart element with id ${name}_chart not found in the DOM`);
+ let chart = document.getElementById(`${name}_chart`);
+ if (chart) {
+ chart.innerHTML = '';
+ drawCharts(`#${name}_chart`, cpuArray, ramArray);
+ } else {
+ console.log(`Chart element with id ${name}_chart not found in the DOM`);
+ }
}
+
});
-socket.on('install', (data) => {
-
- console.log('added install card');
- dockerCards.insertAdjacentHTML("afterend", data);
+
+
+// socket.on('install', (data) => {
+// dockerCards.insertAdjacentHTML("afterend", data);
+// });
+
+// let containerLogs;
+
+// function viewLogs(button) {
+// if (button.name != 'refresh') {
+// containerLogs = button.name;
+// }
+// socket.emit('logs', {container: containerLogs});
+// }
+
+socket.on('logs', (data) => {
+ logViewer.innerHTML = `${data}
`;
});
diff --git a/public/static/logo-dark.svg b/public/static/logo-dark.svg
new file mode 100644
index 0000000..02d81dc
--- /dev/null
+++ b/public/static/logo-dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/static/logo-sm-black.svg b/public/static/logo-sm-black.svg
new file mode 100644
index 0000000..4664975
--- /dev/null
+++ b/public/static/logo-sm-black.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/static/logo-sm-white.svg b/public/static/logo-sm-white.svg
new file mode 100644
index 0000000..0a44230
--- /dev/null
+++ b/public/static/logo-sm-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/static/logo-small-white.svg b/public/static/logo-small-white.svg
deleted file mode 100644
index 4d436ef..0000000
--- a/public/static/logo-small-white.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/public/static/logo-small.svg b/public/static/logo-small.svg
deleted file mode 100644
index 4b14f51..0000000
--- a/public/static/logo-small.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/static/logo-white.svg b/public/static/logo-white.svg
deleted file mode 100644
index 3d6af9a..0000000
--- a/public/static/logo-white.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/public/static/logo.svg b/public/static/logo.svg
index 5d395f4..6dfb8a9 100644
--- a/public/static/logo.svg
+++ b/public/static/logo.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/router/index.js b/router/index.js
new file mode 100644
index 0000000..c00fbaf
--- /dev/null
+++ b/router/index.js
@@ -0,0 +1,60 @@
+import express from "express";
+import { io } from "../app.js";
+
+import { Login, submitLogin } from "../controllers/login.js";
+import { Register, submitRegister } from "../controllers/register.js";
+import { Dashboard, searchDashboard } from "../controllers/dashboard.js";
+import { Apps } from "../controllers/apps.js";
+import { Users } from "../controllers/users.js";
+import { Images } from "../controllers/images.js";
+import { Account } from "../controllers/account.js";
+import { Settings } from "../controllers/settings.js";
+import { Networks } from "../controllers/networks.js";
+import { Volumes } from "../controllers/volumes.js";
+import { Syslogs } from "../controllers/syslogs.js";
+
+export const router = express.Router();
+
+const auth = (req, res, next) => {
+ if (req.session.role == "admin") {
+ next();
+ } else {
+ res.redirect("/login");
+ }
+};
+
+
+router.get("/login", Login);
+router.post("/login", submitLogin);
+
+router.get("/register", Register);
+router.post("/register", submitRegister);
+
+router.get("/", auth, Dashboard);
+router.post("/", auth, searchDashboard);
+router.post("/:search", auth, searchDashboard);
+
+router.get("/apps", auth, Apps);
+router.get("/apps/:page", auth, Apps);
+
+router.get("/users", auth, Users);
+
+router.get("/images", auth, Images);
+
+router.get("/networks", auth, Networks);
+
+router.get("/volumes", auth, Volumes);
+
+router.get("/syslogs", auth, Syslogs);
+
+router.get("/account", Account);
+
+router.get("/settings", auth, Settings);
+
+router.get("/logout", (req, res) => {
+ const sessionId = req.session.id;
+ req.session.destroy(() => {
+ io.to(sessionId).disconnectSockets();
+ res.redirect("/login");
+ });
+});
\ No newline at end of file
diff --git a/routes/index.js b/routes/index.js
deleted file mode 100644
index 79d8411..0000000
--- a/routes/index.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const express = require("express");
-const router = express.Router();
-
-const { Dashboard, AddSite, RemoveSite, RefreshSites, DisableSite, EnableSite } = require("../controllers/dashboard");
-const { Login, processLogin, Logout, Register, processRegister } = require("../controllers/auth");
-const { Apps, searchApps, Install, Uninstall } = require("../controllers/apps");
-
-const { Images } = require("../controllers/images");
-const { Volumes } = require("../controllers/volumes");
-const { Networks } = require("../controllers/networks");
-
-const { Users } = require("../controllers/users");
-const { Account } = require("../controllers/account");
-const { Settings } = require("../controllers/settings");
-
-// Authentication middleware
-const authenticate = (req, res, next) => {
- if (req.session && req.session.role == "admin") {
- console.log(`User ${req.session.user} [${req.session.role}] accessed ${req.originalUrl}`)
- next();
- } else {
- console.log('Not admin')
- res.redirect("/login");
- }
-};
-
-// Dashboard
-router.get("/", authenticate, Dashboard);
-router.post("/addsite", authenticate, AddSite);
-router.post("/removesite", authenticate, RemoveSite);
-router.get("/refreshsites", authenticate, RefreshSites);
-router.post("/disablesite", authenticate, DisableSite);
-router.post("/enablesite", authenticate, EnableSite);
-
-router.get("/images", authenticate, Images);
-
-// Auth
-router.get("/login", Login);
-router.post("/login", processLogin);
-router.get("/register", Register);
-router.post("/register", processRegister);
-router.get("/logout", Logout);
-
-// Apps page
-router.get("/apps", authenticate, Apps);
-router.get("/apps/:page", authenticate, Apps);
-router.get("/apps/:template/:page", authenticate, Apps);
-router.post("/apps", authenticate, searchApps);
-
-// Settings page
-router.get("/settings", authenticate, Settings);
-router.get("/account", authenticate, Account);
-
-router.post("/install", authenticate, Install);
-router.post("/uninstall", authenticate, Uninstall);
-
-router.get("/users", authenticate, Users);
-
-module.exports = router;
\ No newline at end of file
diff --git a/screenshots/account.png b/screenshots/account.png
deleted file mode 100644
index 0f2d996..0000000
Binary files a/screenshots/account.png and /dev/null differ
diff --git a/screenshots/apps.png b/screenshots/apps.png
deleted file mode 100644
index ce86c91..0000000
Binary files a/screenshots/apps.png and /dev/null differ
diff --git a/screenshots/dashboard.png b/screenshots/dashboard.png
deleted file mode 100644
index 16d8450..0000000
Binary files a/screenshots/dashboard.png and /dev/null differ
diff --git a/screenshots/logs.png b/screenshots/logs.png
deleted file mode 100644
index 0a9cff3..0000000
Binary files a/screenshots/logs.png and /dev/null differ
diff --git a/screenshots/register.png b/screenshots/register.png
deleted file mode 100644
index a72e51a..0000000
Binary files a/screenshots/register.png and /dev/null differ
diff --git a/setup.sh b/setup.sh
deleted file mode 100644
index 7264ca7..0000000
--- a/setup.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/bash
-
-# To demo DweebUI, run this script on a fresh Debian 12.2 install. This script will open port 443/tcp for Reverse Proxy and 22/tcp for SSH.
-
-# Manual Install:
-# cd DweebUI
-# chmod +x setup.sh
-# sudo ./setup.sh
-
-# Install dependencies
-apt-get install -y curl unzip ufw gnupg ca-certificates lsb-release gpg
-
-# Enable firewall
-ufw allow ssh && ufw --force enable
-
-# Opens port 443/tcp for Reverse Proxy
-ufw allow https
-
-# Install Docker
-install -m 0755 -d /etc/apt/keyrings
-curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
-chmod a+r /etc/apt/keyrings/docker.gpg
-
-echo \
- "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
- "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
- sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
-sudo apt-get update -y
-sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
-
-# Create docker network
-docker network create -d bridge AppBridge
-
-# Create a redis docker container with persistent storage and a password
-docker run -d --name DweebCache --restart unless-stopped -v /home/docker/redis:/data -p 6379:6379 redis redis-server --requirepass "somesupersecretpassword"
-
-
-# Install redis
-# curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
-# echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
-# apt-get update -y
-# apt-get install -y redis
-# systemctl enable --now redis-server
-
-# Install nodejs
-mkdir -p /etc/apt/keyrings
-curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
-NODE_MAJOR=20
-echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
-sudo apt-get update
-sudo apt-get install nodejs -y
-
-npm i
-
-# Prep for caddy
-mkdir -p /home/docker/caddy/sites
-echo "import sites/*" > /home/docker/caddy/Caddyfile.tmp
-mv /home/docker/caddy/Caddyfile.tmp /home/docker/caddy/Caddyfile
-
-
-# Install pm2 and start DweebUI
-npm install pm2 -g
-pm2 start app.js --name "dweebui"
-pm2 log
-
-
-# Creates a 'docker-compose' alias, since the command changed to 'docker compose' in Debian 11.
-echo '#!/bin/sh
-docker compose "$@"' > /usr/local/bin/docker-compose
-chmod +x /usr/local/bin/docker-compose
diff --git a/views/pages/account.ejs b/views/account.ejs
similarity index 85%
rename from views/pages/account.ejs
rename to views/account.ejs
index 4274200..2831f17 100644
--- a/views/pages/account.ejs
+++ b/views/account.ejs
@@ -4,25 +4,25 @@
- Settings - Tabler - Premium and Open Source dashboard template with responsive and high quality UI.
+ DweebUI - Account
-
-
+
+
+ @import url('fonts/inter.css');
+ :root {
+ --tblr-font-sans-serif: 'Inter Var', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
+ }
+ body {
+ font-feature-settings: "cv03", "cv04", "cv11";
+ }
+
-
+
- <%- include('../partials/navbar.ejs') %>
+ <%- include('navbar.ejs') %>
- <%- include('../partials/footer.ejs') %>
+ <%- include('footer.ejs') %>
-
-
+
+