style: fmt

This commit is contained in:
tigattack
2025-09-25 08:59:28 +01:00
parent 469107c149
commit 35eb9303b1
6 changed files with 162 additions and 142 deletions

View File

@@ -36,7 +36,9 @@ const SortableCardItem = ({ card, onToggle }) => {
transform, transform,
transition, transition,
isDragging, isDragging,
} = useSortable({ id: card.cardId }); } = useSortable({
id: card.cardId,
});
const style = { const style = {
transform: CSS.Transform.toString(transform), transform: CSS.Transform.toString(transform),

View File

@@ -496,8 +496,9 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {
<div className="mt-3 p-3 bg-warning-50 border border-warning-200 rounded-md"> <div className="mt-3 p-3 bg-warning-50 border border-warning-200 rounded-md">
<p className="text-sm text-warning-800"> <p className="text-sm text-warning-800">
<strong>Warning:</strong> This group contains{" "} <strong>Warning:</strong> This group contains{" "}
{group._count.hosts} host{group._count.hosts !== 1 ? "s" : ""}. {group._count.hosts} host
You must move or remove these hosts before deleting the group. {group._count.hosts !== 1 ? "s" : ""}. You must move or remove
these hosts before deleting the group.
</p> </p>
</div> </div>
)} )}

View File

@@ -292,7 +292,9 @@ const Hosts = () => {
newSearchParams.delete("action"); newSearchParams.delete("action");
navigate( navigate(
`/hosts${newSearchParams.toString() ? `?${newSearchParams.toString()}` : ""}`, `/hosts${newSearchParams.toString() ? `?${newSearchParams.toString()}` : ""}`,
{ replace: true }, {
replace: true,
},
); );
} }
@@ -306,7 +308,9 @@ const Hosts = () => {
newSearchParams.delete("selected"); newSearchParams.delete("selected");
navigate( navigate(
`/hosts${newSearchParams.toString() ? `?${newSearchParams.toString()}` : ""}`, `/hosts${newSearchParams.toString() ? `?${newSearchParams.toString()}` : ""}`,
{ replace: true }, {
replace: true,
},
); );
} }
}, [searchParams, navigate]); }, [searchParams, navigate]);

View File

@@ -583,8 +583,9 @@ const DeleteHostGroupModal = ({ group, onClose, onConfirm, isLoading }) => {
<div className="mt-3 p-3 bg-warning-50 border border-warning-200 rounded-md"> <div className="mt-3 p-3 bg-warning-50 border border-warning-200 rounded-md">
<p className="text-sm text-warning-800"> <p className="text-sm text-warning-800">
<strong>Warning:</strong> This group contains{" "} <strong>Warning:</strong> This group contains{" "}
{group._count.hosts} host{group._count.hosts !== 1 ? "s" : ""}. {group._count.hosts} host
You must move or remove these hosts before deleting the group. {group._count.hosts !== 1 ? "s" : ""}. You must move or remove
these hosts before deleting the group.
</p> </p>
</div> </div>
)} )}

View File

@@ -1,47 +1,47 @@
{ {
"name": "patchmon", "name": "patchmon",
"version": "1.2.6", "version": "1.2.6",
"description": "Linux Patch Monitoring System", "description": "Linux Patch Monitoring System",
"private": true, "private": true,
"workspaces": [ "workspaces": [
"backend", "backend",
"frontend" "frontend"
], ],
"scripts": { "scripts": {
"install:all": "npm install && npm run install:backend && npm run install:frontend", "install:all": "npm install && npm run install:backend && npm run install:frontend",
"install:backend": "cd backend && npm install", "install:backend": "cd backend && npm install",
"install:frontend": "cd frontend && npm install", "install:frontend": "cd frontend && npm install",
"dev:backend": "cd backend && npm run dev", "dev:backend": "cd backend && npm run dev",
"dev:frontend": "cd frontend && npm run dev", "dev:frontend": "cd frontend && npm run dev",
"dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"", "dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"",
"build:backend": "cd backend && npm run build", "build:backend": "cd backend && npm run build",
"build:frontend": "cd frontend && npm run build", "build:frontend": "cd frontend && npm run build",
"build": "npm run build:backend && npm run build:frontend", "build": "npm run build:backend && npm run build:frontend",
"format": "npx @biomejs/biome format --write .", "format": "npx @biomejs/biome format --write .",
"format:check": "npx @biomejs/biome format .", "format:check": "npx @biomejs/biome format .",
"lint": "npx @biomejs/biome check .", "lint": "npx @biomejs/biome check .",
"lint:fix": "npx @biomejs/biome check --write ." "lint:fix": "npx @biomejs/biome check --write ."
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.2.4", "@biomejs/biome": "2.2.4",
"@commitlint/cli": "^20.0.0", "@commitlint/cli": "^20.0.0",
"@commitlint/config-conventional": "^20.0.0", "@commitlint/config-conventional": "^20.0.0",
"concurrently": "^8.2.2", "concurrently": "^8.2.2",
"husky": "^9.1.6", "husky": "^9.1.6",
"lint-staged": "^15.2.10", "lint-staged": "^15.2.10",
"markdownlint-cli": "^0.41.0", "markdownlint-cli": "^0.41.0",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.8" "prettier-plugin-tailwindcss": "^0.6.8"
}, },
"engines": { "engines": {
"node": ">=18.0.0" "node": ">=18.0.0"
}, },
"lint-staged": { "lint-staged": {
"*.{js,jsx,ts,tsx,json}": [ "*.{js,jsx,ts,tsx,json}": [
"npx @biomejs/biome check --write" "npx @biomejs/biome check --write"
], ],
"*.{md,yml,yaml,css,scss}": [ "*.{md,yml,yaml,css,scss}": [
"npx @biomejs/biome format --write" "npx @biomejs/biome format --write"
] ]
} }
} }

View File

@@ -1,111 +1,123 @@
const { PrismaClient } = require('@prisma/client'); const { PrismaClient } = require("@prisma/client");
const bcrypt = require('bcryptjs'); const bcrypt = require("bcryptjs");
const readline = require('readline'); const readline = require("node:readline");
const prisma = new PrismaClient(); const prisma = new PrismaClient();
const rl = readline.createInterface({ const rl = readline.createInterface({
input: process.stdin, input: process.stdin,
output: process.stdout 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() { async function setupAdminUser() {
try { try {
console.log('🔐 Setting up PatchMon Admin User'); console.log("🔐 Setting up PatchMon Admin User");
console.log('=====================================\n'); console.log("=====================================\n");
// Check if any users exist // Check if any users exist
const existingUsers = await prisma.users.count(); const existingUsers = await prisma.users.count();
if (existingUsers > 0) { if (existingUsers > 0) {
console.log('⚠️ Users already exist in the database.'); console.log("⚠️ Users already exist in the database.");
const overwrite = await question('Do you want to create another admin user? (y/N): '); const overwrite = await question(
if (overwrite.toLowerCase() !== 'y' && overwrite.toLowerCase() !== 'yes') { "Do you want to create another admin user? (y/N): ",
console.log('❌ Setup cancelled.'); );
return; if (
} overwrite.toLowerCase() !== "y" &&
} overwrite.toLowerCase() !== "yes"
) {
console.log("❌ Setup cancelled.");
return;
}
}
// Get user input // Get user input
const username = await question('Enter admin username: '); const username = await question("Enter admin username: ");
if (!username.trim()) { if (!username.trim()) {
console.log('❌ Username is required.'); console.log("❌ Username is required.");
return; return;
} }
const email = await question('Enter admin email: '); const email = await question("Enter admin email: ");
if (!email.trim()) { if (!email.trim()) {
console.log('❌ Email is required.'); console.log("❌ Email is required.");
return; return;
} }
const password = await question('Enter admin password (min 6 characters): '); const password = await question(
if (password.length < 6) { "Enter admin password (min 6 characters): ",
console.log('❌ Password must be at least 6 characters.'); );
return; if (password.length < 6) {
} console.log("❌ Password must be at least 6 characters.");
return;
}
// Check if username or email already exists // Check if username or email already exists
const existingUser = await prisma.users.findFirst({ const existingUser = await prisma.users.findFirst({
where: { where: {
OR: [ OR: [{ username: username.trim() }, { email: email.trim() }],
{ username: username.trim() }, },
{ email: email.trim() } });
]
}
});
if (existingUser) { if (existingUser) {
console.log('❌ Username or email already exists.'); console.log("❌ Username or email already exists.");
return; return;
} }
// Hash password // Hash password
console.log('\n🔄 Creating admin user...'); console.log("\n🔄 Creating admin user...");
const passwordHash = await bcrypt.hash(password, 12); const passwordHash = await bcrypt.hash(password, 12);
// Create admin user // Create admin user
const user = await prisma.users.create({ const user = await prisma.users.create({
data: { data: {
id: require('crypto').randomUUID(), id: require("node:crypto").randomUUID(),
username: username.trim(), username: username.trim(),
email: email.trim(), email: email.trim(),
password_hash: passwordHash, password_hash: passwordHash,
role: 'admin', role: "admin",
is_active: true, is_active: true,
created_at: new Date(), created_at: new Date(),
updated_at: new Date() updated_at: new Date(),
}, },
select: { select: {
id: true, id: true,
username: true, username: true,
email: true, email: true,
role: true, role: true,
created_at: true created_at: true,
} },
}); });
console.log('✅ Admin user created successfully!'); console.log("✅ Admin user created successfully!");
console.log('\n📋 User Details:'); console.log("\n📋 User Details:");
console.log(` Username: ${user.username}`); console.log(` Username: ${user.username}`);
console.log(` Email: ${user.email}`); console.log(` Email: ${user.email}`);
console.log(` Role: ${user.role}`); console.log(` Role: ${user.role}`);
console.log(` Created: ${user.created_at.toISOString()}`); console.log(` Created: ${user.created_at.toISOString()}`);
console.log('\n🎉 Setup complete!'); console.log("\n🎉 Setup complete!");
console.log('\nNext steps:'); console.log("\nNext steps:");
console.log('1. The backend server is already running as a systemd service'); console.log(
console.log('2. The frontend is already built and served by Nginx'); "1. The backend server is already running as a systemd service",
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}'); console.log("2. The frontend is already built and served by Nginx");
console.log(
} catch (error) { "3. Visit https://" +
console.error('❌ Error setting up admin user:', error); process.env.FQDN +
} finally { " and login with your credentials",
rl.close(); );
await prisma.$disconnect(); 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 // Run the setup