diff --git a/frontend/src/components/DashboardSettingsModal.jsx b/frontend/src/components/DashboardSettingsModal.jsx index 4299b56..982109c 100644 --- a/frontend/src/components/DashboardSettingsModal.jsx +++ b/frontend/src/components/DashboardSettingsModal.jsx @@ -36,7 +36,9 @@ const SortableCardItem = ({ card, onToggle }) => { transform, transition, isDragging, - } = useSortable({ id: card.cardId }); + } = useSortable({ + id: card.cardId, + }); const style = { transform: CSS.Transform.toString(transform), diff --git a/frontend/src/pages/HostGroups.jsx b/frontend/src/pages/HostGroups.jsx index 7be8bc7..6d4577e 100644 --- a/frontend/src/pages/HostGroups.jsx +++ b/frontend/src/pages/HostGroups.jsx @@ -496,8 +496,9 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {

Warning: This group contains{" "} - {group._count.hosts} host{group._count.hosts !== 1 ? "s" : ""}. - You must move or remove these hosts before deleting the group. + {group._count.hosts} host + {group._count.hosts !== 1 ? "s" : ""}. You must move or remove + these hosts before deleting the group.

)} diff --git a/frontend/src/pages/Hosts.jsx b/frontend/src/pages/Hosts.jsx index a2f2c8c..905e395 100644 --- a/frontend/src/pages/Hosts.jsx +++ b/frontend/src/pages/Hosts.jsx @@ -292,7 +292,9 @@ const Hosts = () => { newSearchParams.delete("action"); navigate( `/hosts${newSearchParams.toString() ? `?${newSearchParams.toString()}` : ""}`, - { replace: true }, + { + replace: true, + }, ); } @@ -306,7 +308,9 @@ const Hosts = () => { newSearchParams.delete("selected"); navigate( `/hosts${newSearchParams.toString() ? `?${newSearchParams.toString()}` : ""}`, - { replace: true }, + { + replace: true, + }, ); } }, [searchParams, navigate]); diff --git a/frontend/src/pages/Options.jsx b/frontend/src/pages/Options.jsx index 1c623f7..e623b61 100644 --- a/frontend/src/pages/Options.jsx +++ b/frontend/src/pages/Options.jsx @@ -583,8 +583,9 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {

Warning: This group contains{" "} - {group._count.hosts} host{group._count.hosts !== 1 ? "s" : ""}. - You must move or remove these hosts before deleting the group. + {group._count.hosts} host + {group._count.hosts !== 1 ? "s" : ""}. You must move or remove + these hosts before deleting the group.

)} diff --git a/package.json b/package.json index bf2d8ad..ff76059 100644 --- a/package.json +++ b/package.json @@ -1,47 +1,47 @@ { - "name": "patchmon", - "version": "1.2.6", - "description": "Linux Patch Monitoring System", - "private": true, - "workspaces": [ - "backend", - "frontend" - ], - "scripts": { - "install:all": "npm install && npm run install:backend && npm run install:frontend", - "install:backend": "cd backend && npm install", - "install:frontend": "cd frontend && npm install", - "dev:backend": "cd backend && npm run dev", - "dev:frontend": "cd frontend && npm run dev", - "dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"", - "build:backend": "cd backend && npm run build", - "build:frontend": "cd frontend && npm run build", - "build": "npm run build:backend && npm run build:frontend", - "format": "npx @biomejs/biome format --write .", - "format:check": "npx @biomejs/biome format .", - "lint": "npx @biomejs/biome check .", - "lint:fix": "npx @biomejs/biome check --write ." - }, - "devDependencies": { - "@biomejs/biome": "2.2.4", - "@commitlint/cli": "^20.0.0", - "@commitlint/config-conventional": "^20.0.0", - "concurrently": "^8.2.2", - "husky": "^9.1.6", - "lint-staged": "^15.2.10", - "markdownlint-cli": "^0.41.0", - "prettier": "^3.3.3", - "prettier-plugin-tailwindcss": "^0.6.8" - }, - "engines": { - "node": ">=18.0.0" - }, - "lint-staged": { - "*.{js,jsx,ts,tsx,json}": [ - "npx @biomejs/biome check --write" - ], - "*.{md,yml,yaml,css,scss}": [ - "npx @biomejs/biome format --write" - ] - } + "name": "patchmon", + "version": "1.2.6", + "description": "Linux Patch Monitoring System", + "private": true, + "workspaces": [ + "backend", + "frontend" + ], + "scripts": { + "install:all": "npm install && npm run install:backend && npm run install:frontend", + "install:backend": "cd backend && npm install", + "install:frontend": "cd frontend && npm install", + "dev:backend": "cd backend && npm run dev", + "dev:frontend": "cd frontend && npm run dev", + "dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"", + "build:backend": "cd backend && npm run build", + "build:frontend": "cd frontend && npm run build", + "build": "npm run build:backend && npm run build:frontend", + "format": "npx @biomejs/biome format --write .", + "format:check": "npx @biomejs/biome format .", + "lint": "npx @biomejs/biome check .", + "lint:fix": "npx @biomejs/biome check --write ." + }, + "devDependencies": { + "@biomejs/biome": "2.2.4", + "@commitlint/cli": "^20.0.0", + "@commitlint/config-conventional": "^20.0.0", + "concurrently": "^8.2.2", + "husky": "^9.1.6", + "lint-staged": "^15.2.10", + "markdownlint-cli": "^0.41.0", + "prettier": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.8" + }, + "engines": { + "node": ">=18.0.0" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx,json}": [ + "npx @biomejs/biome check --write" + ], + "*.{md,yml,yaml,css,scss}": [ + "npx @biomejs/biome format --write" + ] + } } diff --git a/setup-admin-user.js b/setup-admin-user.js index 6e46690..59381d1 100644 --- a/setup-admin-user.js +++ b/setup-admin-user.js @@ -1,111 +1,123 @@ -const { PrismaClient } = require('@prisma/client'); -const bcrypt = require('bcryptjs'); -const readline = require('readline'); +const { PrismaClient } = require("@prisma/client"); +const bcrypt = require("bcryptjs"); +const readline = require("node:readline"); const prisma = new PrismaClient(); const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout + input: process.stdin, + output: process.stdout, }); -const question = (query) => new Promise((resolve) => rl.question(query, resolve)); +const question = (query) => + new Promise((resolve) => rl.question(query, resolve)); async function setupAdminUser() { - try { - console.log('šŸ” Setting up PatchMon Admin User'); - console.log('=====================================\n'); + try { + console.log("šŸ” Setting up PatchMon Admin User"); + console.log("=====================================\n"); - // Check if any users exist - const existingUsers = await prisma.users.count(); - if (existingUsers > 0) { - console.log('āš ļø Users already exist in the database.'); - const overwrite = await question('Do you want to create another admin user? (y/N): '); - if (overwrite.toLowerCase() !== 'y' && overwrite.toLowerCase() !== 'yes') { - console.log('āŒ Setup cancelled.'); - return; - } - } + // Check if any users exist + const existingUsers = await prisma.users.count(); + if (existingUsers > 0) { + console.log("āš ļø Users already exist in the database."); + const overwrite = await question( + "Do you want to create another admin user? (y/N): ", + ); + if ( + overwrite.toLowerCase() !== "y" && + overwrite.toLowerCase() !== "yes" + ) { + console.log("āŒ Setup cancelled."); + return; + } + } - // Get user input - const username = await question('Enter admin username: '); - if (!username.trim()) { - console.log('āŒ Username is required.'); - return; - } + // Get user input + const username = await question("Enter admin username: "); + if (!username.trim()) { + console.log("āŒ Username is required."); + return; + } - const email = await question('Enter admin email: '); - if (!email.trim()) { - console.log('āŒ Email is required.'); - return; - } + const email = await question("Enter admin email: "); + if (!email.trim()) { + console.log("āŒ Email is required."); + return; + } - const password = await question('Enter admin password (min 6 characters): '); - if (password.length < 6) { - console.log('āŒ Password must be at least 6 characters.'); - return; - } + const password = await question( + "Enter admin password (min 6 characters): ", + ); + if (password.length < 6) { + console.log("āŒ Password must be at least 6 characters."); + return; + } - // Check if username or email already exists - const existingUser = await prisma.users.findFirst({ - where: { - OR: [ - { username: username.trim() }, - { email: email.trim() } - ] - } - }); + // Check if username or email already exists + const existingUser = await prisma.users.findFirst({ + where: { + OR: [{ username: username.trim() }, { email: email.trim() }], + }, + }); - if (existingUser) { - console.log('āŒ Username or email already exists.'); - return; - } + if (existingUser) { + console.log("āŒ Username or email already exists."); + return; + } - // Hash password - console.log('\nšŸ”„ Creating admin user...'); - const passwordHash = await bcrypt.hash(password, 12); + // Hash password + console.log("\nšŸ”„ Creating admin user..."); + const passwordHash = await bcrypt.hash(password, 12); - // Create admin user - const user = await prisma.users.create({ - data: { - id: require('crypto').randomUUID(), - username: username.trim(), - email: email.trim(), - password_hash: passwordHash, - role: 'admin', - is_active: true, - created_at: new Date(), - updated_at: new Date() - }, - select: { - id: true, - username: true, - email: true, - role: true, - created_at: true - } - }); + // Create admin user + const user = await prisma.users.create({ + data: { + id: require("node:crypto").randomUUID(), + username: username.trim(), + email: email.trim(), + password_hash: passwordHash, + role: "admin", + is_active: true, + created_at: new Date(), + updated_at: new Date(), + }, + select: { + id: true, + username: true, + email: true, + role: true, + created_at: true, + }, + }); - console.log('āœ… Admin user created successfully!'); - console.log('\nšŸ“‹ User Details:'); - console.log(` Username: ${user.username}`); - console.log(` Email: ${user.email}`); - console.log(` Role: ${user.role}`); - console.log(` Created: ${user.created_at.toISOString()}`); + console.log("āœ… Admin user created successfully!"); + console.log("\nšŸ“‹ User Details:"); + console.log(` Username: ${user.username}`); + console.log(` Email: ${user.email}`); + console.log(` Role: ${user.role}`); + console.log(` Created: ${user.created_at.toISOString()}`); - console.log('\nšŸŽ‰ Setup complete!'); - console.log('\nNext steps:'); - console.log('1. The backend server is already running as a systemd service'); - console.log('2. The frontend is already built and served by Nginx'); - console.log('3. Visit https://' + process.env.FQDN + ' and login with your credentials'); - console.log('4. Use the management script: ./manage.sh {status|restart|logs|update|backup|credentials|reset-admin}'); - - } catch (error) { - console.error('āŒ Error setting up admin user:', error); - } finally { - rl.close(); - await prisma.$disconnect(); - } + console.log("\nšŸŽ‰ Setup complete!"); + console.log("\nNext steps:"); + console.log( + "1. The backend server is already running as a systemd service", + ); + console.log("2. The frontend is already built and served by Nginx"); + console.log( + "3. Visit https://" + + process.env.FQDN + + " and login with your credentials", + ); + console.log( + "4. Use the management script: ./manage.sh {status|restart|logs|update|backup|credentials|reset-admin}", + ); + } catch (error) { + console.error("āŒ Error setting up admin user:", error); + } finally { + rl.close(); + await prisma.$disconnect(); + } } // Run the setup