diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f701eb..be791d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ ## v0.09 (dev) * Added authentication middleware to router. * Added gzip compression. -* Added PM2 to dockerfile. +* Added PM2. +* Added Helmet. +* Fixed missing session data. +* Reduced sqlite queries. ## v0.08 (Dec 15th 2023) * Updates to compose file and instructions from [steveiliop56](https://github.com/steveiliop56) diff --git a/README.md b/README.md index af30b5c..a9b97f1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # DweebUI DweebUI is a simple Docker web interface created using Javascript, Node.JS, and Express. -v0.09 +Alpha v0.09 ( :fire: Experimental :fire: ) [![GitHub Stars](https://img.shields.io/github/stars/lllllllillllllillll/DweebUI)](https://github.com/lllllllillllllillll) [![GitHub Activity](https://img.shields.io/github/commit-activity/y/lllllllillllllillll/DweebUI)](https://github.com/lllllllillllllillll) @@ -18,13 +18,13 @@ v0.09 * [x] Dashboard provides server metrics, container metrics, and container controls, on a single page. * [x] View container logs. * [ ] Update containers (planned). -* [ ] Manage your Docker networks, images, and volumes (planned). +* [ ] Manage your Docker networks, images, and volumes (in development). * [x] Light/Dark Mode. * [x] Easy to install app templates. * [x] Multi-User built-in. -* [ ] User pages (planned). +* [ ] Permissions system (in development). * [x] Support for Windows, Linux, and MacOS. -* [ ] Docker compose support (planned). +* [ ] Docker compose import (in development). * [x] Templates.json maintains compatability with Portainer, allowing you to use the template without needing to use DweebUI. * [x] Automatically persists data in docker volumes if bind mount isn't used. * [ ] Preset variables (planned). diff --git a/app.js b/app.js index 6de2dcf..fe24fde 100644 --- a/app.js +++ b/app.js @@ -3,6 +3,7 @@ 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; // Router @@ -13,7 +14,7 @@ const { serverStats, containerList, containerStats, containerAction, containerLo let sentList, clicked; app.locals.site_list = ''; -const Containers = require('./database/ContainerSettings'); +const Containers = require('./database/ContainerModel'); // Configure Session @@ -32,6 +33,7 @@ const sessionMiddleware = session({ app.set('view engine', 'ejs'); app.use([ compression(), + helmet(), express.static("public"), express.json(), express.urlencoded({ extended: true }), @@ -111,14 +113,18 @@ io.on('connection', (socket) => { console.log(`Hide ${data.container}`); let containerExists = await Containers.findOne({ where: {name:data.container}}); - + if(!containerExists){ const container = await Containers.create({ name: data.container, - visibility: false - }); - hiddenContainers(); + 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`) diff --git a/components/dashCard.js b/components/dashCard.js index 2afbc14..4be1edf 100644 --- a/components/dashCard.js +++ b/components/dashCard.js @@ -166,6 +166,7 @@ module.exports.dashCard = function dashCard(data) { diff --git a/controllers/images.js b/controllers/images.js index 06da594..78c282e 100644 --- a/controllers/images.js +++ b/controllers/images.js @@ -1,48 +1,14 @@ -const User = require('../database/UserModel'); + exports.Images = async function(req, res) { - let user_list = ` - - - ID - Avatar - Name - Username - Email - UUID - Role - Status - Actions - ` - - let users = await User.findAll(); - users.forEach((account) => { - full_name = account.first_name + ' ' + account.last_name; - user_info = ` - - - ${user.id} - ${account.avatar} - ${full_name} - ${account.username} - ${account.email} - ${account.UUID} - ${account.role} - Active - Edit - ` - - user_list += user_info; - }); - + // Render the home page res.render("pages/images", { name: req.session.user, role: req.session.role, avatar: req.session.avatar, isLoggedIn: true, - user_list: user_list }); } \ No newline at end of file diff --git a/controllers/networks.js b/controllers/networks.js index f336929..af6f43c 100644 --- a/controllers/networks.js +++ b/controllers/networks.js @@ -2,47 +2,13 @@ const User = require('../database/UserModel'); exports.Networks = async function(req, res) { - let user_list = ` - - - ID - Avatar - Name - Username - Email - UUID - Role - Status - Actions - ` - - let users = await User.findAll(); - users.forEach((account) => { - full_name = account.first_name + ' ' + account.last_name; - user_info = ` - - - ${user.id} - ${account.avatar} - ${full_name} - ${account.username} - ${account.email} - ${account.UUID} - ${account.role} - Active - Edit - ` - - user_list += user_info; - }); - + // Render the home page res.render("pages/users", { name: req.session.user, role: req.session.role, avatar: req.session.avatar, isLoggedIn: true, - user_list: user_list }); } \ No newline at end of file diff --git a/controllers/settings.js b/controllers/settings.js index c990ea4..16a199a 100644 --- a/controllers/settings.js +++ b/controllers/settings.js @@ -1,5 +1,5 @@ const User = require('../database/UserModel.js'); -const Server = require('../database/ServerSettings.js'); +const Server = require('../database/ServerModel.js'); exports.Settings = async function(req, res) { diff --git a/controllers/volumes.js b/controllers/volumes.js index 24ffc17..66eec83 100644 --- a/controllers/volumes.js +++ b/controllers/volumes.js @@ -3,39 +3,6 @@ const User = require('../database/UserModel'); exports.Volumes = async function(req, res) { - let user_list = ` - - - ID - Avatar - Name - Username - Email - UUID - Role - Status - Actions - ` - - let users = await User.findAll(); - users.forEach((account) => { - full_name = account.first_name + ' ' + account.last_name; - user_info = ` - - - ${user.id} - ${account.avatar} - ${full_name} - ${account.username} - ${account.email} - ${account.UUID} - ${account.role} - Active - Edit - ` - - user_list += user_info; - }); // Render the home page res.render("pages/volumes", { @@ -43,7 +10,6 @@ exports.Volumes = async function(req, res) { role: req.session.role, avatar: req.session.avatar, isLoggedIn: true, - user_list: user_list }); } \ No newline at end of file diff --git a/database/ContainerSettings.js b/database/ContainerModel.js similarity index 60% rename from database/ContainerSettings.js rename to database/ContainerModel.js index 14e4491..0613f4e 100644 --- a/database/ContainerSettings.js +++ b/database/ContainerModel.js @@ -30,10 +30,35 @@ const Containers = sequelize.define('Containers', { type: DataTypes.STRING // allowNull defaults to true }, - permissions: { - type: DataTypes.STRING + 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() { diff --git a/database/ServerSettings.js b/database/ServerModel.js similarity index 87% rename from database/ServerSettings.js rename to database/ServerModel.js index 39cdda9..f02072a 100644 --- a/database/ServerSettings.js +++ b/database/ServerModel.js @@ -1,42 +1,46 @@ -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 - } -}); - -async function syncModel() { - await sequelize.sync(); - console.log('Server model synced'); -} - -syncModel(); - - +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/docker-compose.yaml b/docker-compose.yaml index 8e05778..7784b01 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.09-dev + build: + context: . environment: NODE_ENV: production PORT: 8000 diff --git a/functions/system.js b/functions/system.js index cc2b24d..a3a1df6 100644 --- a/functions/system.js +++ b/functions/system.js @@ -1,10 +1,10 @@ -const { currentLoad, mem, networkStats, fsSize, dockerContainerStats, dockerImages, networkInterfaces } = require('systeminformation'); +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/ContainerSettings'); +const Containers = require('../database/ContainerModel'); // export docker module.exports.docker = docker; @@ -317,15 +317,21 @@ module.exports.containerLogs = function (data) { module.exports.dockerImages = async function () { - - const data = await dockerImages({ all: true }); - for ( i = 0; i < data.length; i++) { - console.log(`Image ${i}:`) - console.log(`repoTags: ${data[i].repoTags}`) - // console.log(`repoDigest: ${data[i].repoDigests}`) - } + // 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); } diff --git a/package-lock.json b/package-lock.json index 77fc3b7..f99496f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "ejs": "^3.1.9", "express": "^4.18.2", "express-session": "^1.17.3", + "helmet": "^7.1.0", "js-yaml": "^4.1.0", "sequelize": "^6.35.2", "socket.io": "^4.6.1", @@ -1182,6 +1183,14 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", diff --git a/package.json b/package.json index 65741c8..8bd93e6 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "ejs": "^3.1.9", "express": "^4.18.2", "express-session": "^1.17.3", + "helmet": "^7.1.0", "js-yaml": "^4.1.0", "sequelize": "^6.35.2", "socket.io": "^4.6.1", diff --git a/views/pages/networks.ejs b/views/pages/networks.ejs index 57cdb45..471fc3f 100644 --- a/views/pages/networks.ejs +++ b/views/pages/networks.ejs @@ -48,7 +48,6 @@ - <%- user_list %>
diff --git a/views/pages/volumes.ejs b/views/pages/volumes.ejs index 298965d..5aa9a32 100644 --- a/views/pages/volumes.ejs +++ b/views/pages/volumes.ejs @@ -48,7 +48,7 @@ - <%- user_list %> +