mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-04 14:03:17 +00:00
fix(backend): lint errors
This commit is contained in:
@@ -58,9 +58,13 @@ async function checkDatabaseConnection(prisma) {
|
|||||||
// Wait for database to be available with retry logic
|
// Wait for database to be available with retry logic
|
||||||
async function waitForDatabase(prisma, options = {}) {
|
async function waitForDatabase(prisma, options = {}) {
|
||||||
const maxAttempts =
|
const maxAttempts =
|
||||||
options.maxAttempts || parseInt(process.env.PM_DB_CONN_MAX_ATTEMPTS) || 30;
|
options.maxAttempts ||
|
||||||
|
parseInt(process.env.PM_DB_CONN_MAX_ATTEMPTS, 10) ||
|
||||||
|
30;
|
||||||
const waitInterval =
|
const waitInterval =
|
||||||
options.waitInterval || parseInt(process.env.PM_DB_CONN_WAIT_INTERVAL) || 2;
|
options.waitInterval ||
|
||||||
|
parseInt(process.env.PM_DB_CONN_WAIT_INTERVAL, 10) ||
|
||||||
|
2;
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`Waiting for database connection (max ${maxAttempts} attempts, ${waitInterval}s interval)...`,
|
`Waiting for database connection (max ${maxAttempts} attempts, ${waitInterval}s interval)...`,
|
||||||
@@ -75,7 +79,7 @@ async function waitForDatabase(prisma, options = {}) {
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
// checkDatabaseConnection already logs the error
|
// checkDatabaseConnection already logs the error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ const prisma = new PrismaClient();
|
|||||||
// Middleware to verify JWT token
|
// Middleware to verify JWT token
|
||||||
const authenticateToken = async (req, res, next) => {
|
const authenticateToken = async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const authHeader = req.headers["authorization"];
|
const authHeader = req.headers.authorization;
|
||||||
const token = authHeader && authHeader.split(" ")[1]; // Bearer TOKEN
|
const token = authHeader?.split(" ")[1]; // Bearer TOKEN
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return res.status(401).json({ error: "Access token required" });
|
return res.status(401).json({ error: "Access token required" });
|
||||||
@@ -70,10 +70,10 @@ const requireAdmin = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Middleware to check if user is authenticated (optional)
|
// Middleware to check if user is authenticated (optional)
|
||||||
const optionalAuth = async (req, res, next) => {
|
const optionalAuth = async (req, _res, next) => {
|
||||||
try {
|
try {
|
||||||
const authHeader = req.headers["authorization"];
|
const authHeader = req.headers.authorization;
|
||||||
const token = authHeader && authHeader.split(" ")[1];
|
const token = authHeader?.split(" ")[1];
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
const decoded = jwt.verify(
|
const decoded = jwt.verify(
|
||||||
@@ -94,12 +94,12 @@ const optionalAuth = async (req, res, next) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user && user.is_active) {
|
if (user?.is_active) {
|
||||||
req.user = user;
|
req.user = user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Continue without authentication for optional auth
|
// Continue without authentication for optional auth
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const bcrypt = require("bcryptjs");
|
|||||||
const jwt = require("jsonwebtoken");
|
const jwt = require("jsonwebtoken");
|
||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const { body, validationResult } = require("express-validator");
|
const { body, validationResult } = require("express-validator");
|
||||||
const { authenticateToken, requireAdmin } = require("../middleware/auth");
|
const { authenticateToken, _requireAdmin } = require("../middleware/auth");
|
||||||
const {
|
const {
|
||||||
requireViewUsers,
|
requireViewUsers,
|
||||||
requireManageUsers,
|
requireManageUsers,
|
||||||
@@ -17,7 +17,7 @@ const router = express.Router();
|
|||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
// Check if any admin users exist (for first-time setup)
|
// Check if any admin users exist (for first-time setup)
|
||||||
router.get("/check-admin-users", async (req, res) => {
|
router.get("/check-admin-users", async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const adminCount = await prisma.users.count({
|
const adminCount = await prisma.users.count({
|
||||||
where: { role: "admin" },
|
where: { role: "admin" },
|
||||||
@@ -143,7 +143,7 @@ router.get(
|
|||||||
"/admin/users",
|
"/admin/users",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireViewUsers,
|
requireViewUsers,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const users = await prisma.users.findMany({
|
const users = await prisma.users.findMany({
|
||||||
select: {
|
select: {
|
||||||
@@ -527,7 +527,7 @@ router.post(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Check if signup is enabled (public endpoint)
|
// Check if signup is enabled (public endpoint)
|
||||||
router.get("/signup-enabled", async (req, res) => {
|
router.get("/signup-enabled", async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const settings = await prisma.settings.findFirst();
|
const settings = await prisma.settings.findFirst();
|
||||||
res.json({ signupEnabled: settings?.signup_enabled || false });
|
res.json({ signupEnabled: settings?.signup_enabled || false });
|
||||||
@@ -990,7 +990,7 @@ router.put(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Logout (client-side token removal)
|
// Logout (client-side token removal)
|
||||||
router.post("/logout", authenticateToken, async (req, res) => {
|
router.post("/logout", authenticateToken, async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
res.json({
|
res.json({
|
||||||
message: "Logout successful",
|
message: "Logout successful",
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ router.put(
|
|||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createdPreferences = await prisma.dashboard_preferences.createMany({
|
await prisma.dashboard_preferences.createMany({
|
||||||
data: newPreferences,
|
data: newPreferences,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ router.put(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Get default dashboard card configuration
|
// Get default dashboard card configuration
|
||||||
router.get("/defaults", authenticateToken, async (req, res) => {
|
router.get("/defaults", authenticateToken, async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
// This provides a comprehensive dashboard view for all new users
|
// This provides a comprehensive dashboard view for all new users
|
||||||
const defaultCards = [
|
const defaultCards = [
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ router.get(
|
|||||||
"/stats",
|
"/stats",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireViewDashboard,
|
requireViewDashboard,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ router.get(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Get hosts with their update status
|
// Get hosts with their update status
|
||||||
router.get("/hosts", authenticateToken, requireViewHosts, async (req, res) => {
|
router.get("/hosts", authenticateToken, requireViewHosts, async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const hosts = await prisma.hosts.findMany({
|
const hosts = await prisma.hosts.findMany({
|
||||||
// Show all hosts regardless of status
|
// Show all hosts regardless of status
|
||||||
@@ -269,7 +269,7 @@ router.get(
|
|||||||
"/packages",
|
"/packages",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireViewPackages,
|
requireViewPackages,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const packages = await prisma.packages.findMany({
|
const packages = await prisma.packages.findMany({
|
||||||
where: {
|
where: {
|
||||||
@@ -397,7 +397,7 @@ router.get(
|
|||||||
"/recent-users",
|
"/recent-users",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireViewUsers,
|
requireViewUsers,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const users = await prisma.users.findMany({
|
const users = await prisma.users.findMany({
|
||||||
where: {
|
where: {
|
||||||
@@ -430,7 +430,7 @@ router.get(
|
|||||||
"/recent-collection",
|
"/recent-collection",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireViewHosts,
|
requireViewHosts,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const hosts = await prisma.hosts.findMany({
|
const hosts = await prisma.hosts.findMany({
|
||||||
select: {
|
select: {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
const { body, validationResult } = require("express-validator");
|
const { body, validationResult } = require("express-validator");
|
||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const { randomUUID } = require("crypto");
|
const { randomUUID } = require("node:crypto");
|
||||||
const { authenticateToken } = require("../middleware/auth");
|
const { authenticateToken } = require("../middleware/auth");
|
||||||
const { requireManageHosts } = require("../middleware/permissions");
|
const { requireManageHosts } = require("../middleware/permissions");
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ const router = express.Router();
|
|||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
// Get all host groups
|
// Get all host groups
|
||||||
router.get("/", authenticateToken, async (req, res) => {
|
router.get("/", authenticateToken, async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const hostGroups = await prisma.host_groups.findMany({
|
const hostGroups = await prisma.host_groups.findMany({
|
||||||
include: {
|
include: {
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ const express = require("express");
|
|||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const { body, validationResult } = require("express-validator");
|
const { body, validationResult } = require("express-validator");
|
||||||
const { v4: uuidv4 } = require("uuid");
|
const { v4: uuidv4 } = require("uuid");
|
||||||
const bcrypt = require("bcryptjs");
|
const crypto = require("node:crypto");
|
||||||
const crypto = require("crypto");
|
const path = require("node:path");
|
||||||
const path = require("path");
|
const fs = require("node:fs");
|
||||||
const fs = require("fs");
|
const { authenticateToken, _requireAdmin } = require("../middleware/auth");
|
||||||
const { authenticateToken, requireAdmin } = require("../middleware/auth");
|
|
||||||
const {
|
const {
|
||||||
requireManageHosts,
|
requireManageHosts,
|
||||||
requireManageSettings,
|
requireManageSettings,
|
||||||
@@ -48,7 +47,7 @@ router.get("/agent/download", async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use script content from database if available, otherwise fallback to file
|
// Use script content from database if available, otherwise fallback to file
|
||||||
if (agentVersion && agentVersion.script_content) {
|
if (agentVersion?.script_content) {
|
||||||
// Convert Windows line endings to Unix line endings
|
// Convert Windows line endings to Unix line endings
|
||||||
const scriptContent = agentVersion.script_content
|
const scriptContent = agentVersion.script_content
|
||||||
.replace(/\r\n/g, "\n")
|
.replace(/\r\n/g, "\n")
|
||||||
@@ -88,7 +87,7 @@ router.get("/agent/download", async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Version check endpoint for agents
|
// Version check endpoint for agents
|
||||||
router.get("/agent/version", async (req, res) => {
|
router.get("/agent/version", async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const currentVersion = await prisma.agent_versions.findFirst({
|
const currentVersion = await prisma.agent_versions.findFirst({
|
||||||
where: { is_current: true },
|
where: { is_current: true },
|
||||||
@@ -235,7 +234,7 @@ router.post(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Legacy register endpoint (deprecated - returns error message)
|
// Legacy register endpoint (deprecated - returns error message)
|
||||||
router.post("/register", async (req, res) => {
|
router.post("/register", async (_req, res) => {
|
||||||
res.status(400).json({
|
res.status(400).json({
|
||||||
error:
|
error:
|
||||||
"Host registration has been disabled. Please contact your administrator to add this host to PatchMon.",
|
"Host registration has been disabled. Please contact your administrator to add this host to PatchMon.",
|
||||||
@@ -517,7 +516,7 @@ router.post(
|
|||||||
try {
|
try {
|
||||||
const settings = await prisma.settings.findFirst();
|
const settings = await prisma.settings.findFirst();
|
||||||
// Check both global auto-update setting AND host-specific auto-update setting
|
// Check both global auto-update setting AND host-specific auto-update setting
|
||||||
if (settings && settings.auto_update && host.auto_update) {
|
if (settings?.auto_update && host.auto_update) {
|
||||||
// Get current agent version from the request
|
// Get current agent version from the request
|
||||||
const currentAgentVersion = req.body.agentVersion;
|
const currentAgentVersion = req.body.agentVersion;
|
||||||
|
|
||||||
@@ -863,7 +862,7 @@ router.get(
|
|||||||
"/admin/list",
|
"/admin/list",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireManageHosts,
|
requireManageHosts,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const hosts = await prisma.hosts.findMany({
|
const hosts = await prisma.hosts.findMany({
|
||||||
select: {
|
select: {
|
||||||
@@ -1089,10 +1088,10 @@ router.patch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Serve the installation script
|
// Serve the installation script
|
||||||
router.get("/install", async (req, res) => {
|
router.get("/install", async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const fs = require("fs");
|
const fs = require("node:fs");
|
||||||
const path = require("path");
|
const path = require("node:path");
|
||||||
|
|
||||||
const scriptPath = path.join(
|
const scriptPath = path.join(
|
||||||
__dirname,
|
__dirname,
|
||||||
@@ -1144,7 +1143,7 @@ router.get(
|
|||||||
"/agent/versions",
|
"/agent/versions",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireManageSettings,
|
requireManageSettings,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const versions = await prisma.agent_versions.findMany({
|
const versions = await prisma.agent_versions.findMany({
|
||||||
orderBy: { created_at: "desc" },
|
orderBy: { created_at: "desc" },
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const { body, validationResult } = require("express-validator");
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
@@ -17,8 +16,8 @@ router.get("/", async (req, res) => {
|
|||||||
isSecurityUpdate = "",
|
isSecurityUpdate = "",
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
const skip = (parseInt(page) - 1) * parseInt(limit);
|
const skip = (parseInt(page, 10) - 1) * parseInt(limit, 10);
|
||||||
const take = parseInt(limit);
|
const take = parseInt(limit, 10);
|
||||||
|
|
||||||
// Build where clause
|
// Build where clause
|
||||||
const where = {
|
const where = {
|
||||||
@@ -139,10 +138,10 @@ router.get("/", async (req, res) => {
|
|||||||
res.json({
|
res.json({
|
||||||
packages: packagesWithStats,
|
packages: packagesWithStats,
|
||||||
pagination: {
|
pagination: {
|
||||||
page: parseInt(page),
|
page: parseInt(page, 10),
|
||||||
limit: parseInt(limit),
|
limit: parseInt(limit, 10),
|
||||||
total: totalCount,
|
total: totalCount,
|
||||||
pages: Math.ceil(totalCount / parseInt(limit)),
|
pages: Math.ceil(totalCount / parseInt(limit, 10)),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const { authenticateToken, requireAdmin } = require("../middleware/auth");
|
const { authenticateToken } = require("../middleware/auth");
|
||||||
const {
|
const {
|
||||||
requireManageSettings,
|
requireManageSettings,
|
||||||
requireManageUsers,
|
requireManageUsers,
|
||||||
@@ -14,7 +14,7 @@ router.get(
|
|||||||
"/roles",
|
"/roles",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireManageUsers,
|
requireManageUsers,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const permissions = await prisma.role_permissions.findMany({
|
const permissions = await prisma.role_permissions.findMany({
|
||||||
orderBy: {
|
orderBy: {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const router = express.Router();
|
|||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
// Get all repositories with host count
|
// Get all repositories with host count
|
||||||
router.get("/", authenticateToken, requireViewHosts, async (req, res) => {
|
router.get("/", authenticateToken, requireViewHosts, async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const repositories = await prisma.repositories.findMany({
|
const repositories = await prisma.repositories.findMany({
|
||||||
include: {
|
include: {
|
||||||
@@ -251,7 +251,7 @@ router.get(
|
|||||||
"/stats/summary",
|
"/stats/summary",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireViewHosts,
|
requireViewHosts,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const stats = await prisma.repositories.aggregate({
|
const stats = await prisma.repositories.aggregate({
|
||||||
_count: true,
|
_count: true,
|
||||||
@@ -294,7 +294,7 @@ router.delete(
|
|||||||
"/cleanup/orphaned",
|
"/cleanup/orphaned",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireManageHosts,
|
requireManageHosts,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
console.log("Cleaning up orphaned repositories...");
|
console.log("Cleaning up orphaned repositories...");
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ async function triggerCrontabUpdates() {
|
|||||||
|
|
||||||
// We'll use the existing ping endpoint but add a special parameter
|
// We'll use the existing ping endpoint but add a special parameter
|
||||||
// The agent will detect this and run update-crontab command
|
// The agent will detect this and run update-crontab command
|
||||||
const http = require("http");
|
const http = require("node:http");
|
||||||
const https = require("https");
|
const https = require("node:https");
|
||||||
|
|
||||||
const url = new URL(`${serverUrl}/api/v1/hosts/ping`);
|
const url = new URL(`${serverUrl}/api/v1/hosts/ping`);
|
||||||
const isHttps = url.protocol === "https:";
|
const isHttps = url.protocol === "https:";
|
||||||
@@ -106,7 +106,7 @@ async function triggerCrontabUpdates() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get current settings
|
// Get current settings
|
||||||
router.get("/", authenticateToken, requireManageSettings, async (req, res) => {
|
router.get("/", authenticateToken, requireManageSettings, async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const settings = await getSettings();
|
const settings = await getSettings();
|
||||||
console.log("Returning settings:", settings);
|
console.log("Returning settings:", settings);
|
||||||
@@ -228,7 +228,7 @@ router.put(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Get server URL for public use (used by installation scripts)
|
// Get server URL for public use (used by installation scripts)
|
||||||
router.get("/server-url", async (req, res) => {
|
router.get("/server-url", async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const settings = await getSettings();
|
const settings = await getSettings();
|
||||||
const serverUrl = settings.server_url;
|
const serverUrl = settings.server_url;
|
||||||
@@ -240,7 +240,7 @@ router.get("/server-url", async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get update interval policy for agents (public endpoint)
|
// Get update interval policy for agents (public endpoint)
|
||||||
router.get("/update-interval", async (req, res) => {
|
router.get("/update-interval", async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const settings = await getSettings();
|
const settings = await getSettings();
|
||||||
res.json({
|
res.json({
|
||||||
@@ -254,7 +254,7 @@ router.get("/update-interval", async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get auto-update policy for agents (public endpoint)
|
// Get auto-update policy for agents (public endpoint)
|
||||||
router.get("/auto-update", async (req, res) => {
|
router.get("/auto-update", async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
const settings = await getSettings();
|
const settings = await getSettings();
|
||||||
res.json({
|
res.json({
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ router.post(
|
|||||||
return res.status(400).json({ errors: errors.array() });
|
return res.status(400).json({ errors: errors.array() });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { password } = req.body;
|
const { password: _password } = req.body;
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
|
|
||||||
// Verify password
|
// Verify password
|
||||||
@@ -165,12 +165,12 @@ router.post(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: In a real implementation, you would verify the password hash here
|
// FIXME: In a real implementation, you would verify the password hash here
|
||||||
// For now, we'll skip password verification for simplicity
|
// For now, we'll skip password verification for simplicity
|
||||||
|
|
||||||
// Disable TFA
|
// Disable TFA
|
||||||
await prisma.users.update({
|
await prisma.users.update({
|
||||||
where: { id: id },
|
where: { id: userId },
|
||||||
data: {
|
data: {
|
||||||
tfa_enabled: false,
|
tfa_enabled: false,
|
||||||
tfa_secret: null,
|
tfa_secret: null,
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ const express = require("express");
|
|||||||
const { authenticateToken } = require("../middleware/auth");
|
const { authenticateToken } = require("../middleware/auth");
|
||||||
const { requireManageSettings } = require("../middleware/permissions");
|
const { requireManageSettings } = require("../middleware/permissions");
|
||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const { exec } = require("child_process");
|
const { exec } = require("node:child_process");
|
||||||
const { promisify } = require("util");
|
const { promisify } = require("node:util");
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
@@ -11,14 +11,14 @@ const execAsync = promisify(exec);
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// Get current version info
|
// Get current version info
|
||||||
router.get("/current", authenticateToken, async (req, res) => {
|
router.get("/current", authenticateToken, async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
// Read version from package.json dynamically
|
// Read version from package.json dynamically
|
||||||
let currentVersion = "1.2.6"; // fallback
|
let currentVersion = "1.2.6"; // fallback
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const packageJson = require("../../package.json");
|
const packageJson = require("../../package.json");
|
||||||
if (packageJson && packageJson.version) {
|
if (packageJson?.version) {
|
||||||
currentVersion = packageJson.version;
|
currentVersion = packageJson.version;
|
||||||
}
|
}
|
||||||
} catch (packageError) {
|
} catch (packageError) {
|
||||||
@@ -78,8 +78,8 @@ router.post(
|
|||||||
|
|
||||||
// Check if SSH key file exists and is readable
|
// Check if SSH key file exists and is readable
|
||||||
try {
|
try {
|
||||||
require("fs").accessSync(sshKeyPath);
|
require("node:fs").accessSync(sshKeyPath);
|
||||||
} catch (e) {
|
} catch {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: "SSH key file not found or not accessible",
|
error: "SSH key file not found or not accessible",
|
||||||
details: `Cannot access: ${sshKeyPath}`,
|
details: `Cannot access: ${sshKeyPath}`,
|
||||||
@@ -165,7 +165,7 @@ router.get(
|
|||||||
"/check-updates",
|
"/check-updates",
|
||||||
authenticateToken,
|
authenticateToken,
|
||||||
requireManageSettings,
|
requireManageSettings,
|
||||||
async (req, res) => {
|
async (_req, res) => {
|
||||||
try {
|
try {
|
||||||
// Get cached update information from settings
|
// Get cached update information from settings
|
||||||
const settings = await prisma.settings.findFirst();
|
const settings = await prisma.settings.findFirst();
|
||||||
@@ -201,22 +201,4 @@ router.get(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Simple version comparison function
|
|
||||||
function compareVersions(version1, version2) {
|
|
||||||
const v1Parts = version1.split(".").map(Number);
|
|
||||||
const v2Parts = version2.split(".").map(Number);
|
|
||||||
|
|
||||||
const maxLength = Math.max(v1Parts.length, v2Parts.length);
|
|
||||||
|
|
||||||
for (let i = 0; i < maxLength; i++) {
|
|
||||||
const v1Part = v1Parts[i] || 0;
|
|
||||||
const v2Part = v2Parts[i] || 0;
|
|
||||||
|
|
||||||
if (v1Part > v2Part) return 1;
|
|
||||||
if (v1Part < v2Part) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ const permissionsRoutes = require("./routes/permissionsRoutes");
|
|||||||
const settingsRoutes = require("./routes/settingsRoutes");
|
const settingsRoutes = require("./routes/settingsRoutes");
|
||||||
const {
|
const {
|
||||||
router: dashboardPreferencesRoutes,
|
router: dashboardPreferencesRoutes,
|
||||||
createDefaultDashboardPreferences,
|
|
||||||
} = require("./routes/dashboardPreferencesRoutes");
|
} = require("./routes/dashboardPreferencesRoutes");
|
||||||
const repositoryRoutes = require("./routes/repositoryRoutes");
|
const repositoryRoutes = require("./routes/repositoryRoutes");
|
||||||
const versionRoutes = require("./routes/versionRoutes");
|
const versionRoutes = require("./routes/versionRoutes");
|
||||||
@@ -63,9 +62,9 @@ async function checkAndImportAgentVersion() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fs = require("fs");
|
const fs = require("node:fs");
|
||||||
const path = require("path");
|
const path = require("node:path");
|
||||||
const crypto = require("crypto");
|
const crypto = require("node:crypto");
|
||||||
|
|
||||||
// Read and validate agent script
|
// Read and validate agent script
|
||||||
const agentScriptPath = path.join(
|
const agentScriptPath = path.join(
|
||||||
@@ -239,7 +238,7 @@ async function checkAndCreateRolePermissions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const crypto = require("crypto");
|
const crypto = require("node:crypto");
|
||||||
|
|
||||||
// Define default roles and permissions
|
// Define default roles and permissions
|
||||||
const defaultRoles = [
|
const defaultRoles = [
|
||||||
@@ -437,12 +436,12 @@ app.disable("x-powered-by");
|
|||||||
|
|
||||||
// Rate limiting with monitoring
|
// Rate limiting with monitoring
|
||||||
const limiter = rateLimit({
|
const limiter = rateLimit({
|
||||||
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000,
|
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS, 10) || 15 * 60 * 1000,
|
||||||
max: parseInt(process.env.RATE_LIMIT_MAX) || 100,
|
max: parseInt(process.env.RATE_LIMIT_MAX, 10) || 100,
|
||||||
message: {
|
message: {
|
||||||
error: "Too many requests from this IP, please try again later.",
|
error: "Too many requests from this IP, please try again later.",
|
||||||
retryAfter: Math.ceil(
|
retryAfter: Math.ceil(
|
||||||
(parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000) / 1000,
|
(parseInt(process.env.RATE_LIMIT_WINDOW_MS, 10) || 15 * 60 * 1000) / 1000,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
@@ -523,7 +522,7 @@ if (process.env.ENABLE_LOGGING === "true") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Health check endpoint
|
// Health check endpoint
|
||||||
app.get("/health", (req, res) => {
|
app.get("/health", (_req, res) => {
|
||||||
res.json({ status: "ok", timestamp: new Date().toISOString() });
|
res.json({ status: "ok", timestamp: new Date().toISOString() });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -532,12 +531,13 @@ const apiVersion = process.env.API_VERSION || "v1";
|
|||||||
|
|
||||||
// Per-route rate limits with monitoring
|
// Per-route rate limits with monitoring
|
||||||
const authLimiter = rateLimit({
|
const authLimiter = rateLimit({
|
||||||
windowMs: parseInt(process.env.AUTH_RATE_LIMIT_WINDOW_MS) || 10 * 60 * 1000,
|
windowMs:
|
||||||
max: parseInt(process.env.AUTH_RATE_LIMIT_MAX) || 20,
|
parseInt(process.env.AUTH_RATE_LIMIT_WINDOW_MS, 10) || 10 * 60 * 1000,
|
||||||
|
max: parseInt(process.env.AUTH_RATE_LIMIT_MAX, 10) || 20,
|
||||||
message: {
|
message: {
|
||||||
error: "Too many authentication requests, please try again later.",
|
error: "Too many authentication requests, please try again later.",
|
||||||
retryAfter: Math.ceil(
|
retryAfter: Math.ceil(
|
||||||
(parseInt(process.env.AUTH_RATE_LIMIT_WINDOW_MS) || 10 * 60 * 1000) /
|
(parseInt(process.env.AUTH_RATE_LIMIT_WINDOW_MS, 10) || 10 * 60 * 1000) /
|
||||||
1000,
|
1000,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -546,12 +546,13 @@ const authLimiter = rateLimit({
|
|||||||
skipSuccessfulRequests: true,
|
skipSuccessfulRequests: true,
|
||||||
});
|
});
|
||||||
const agentLimiter = rateLimit({
|
const agentLimiter = rateLimit({
|
||||||
windowMs: parseInt(process.env.AGENT_RATE_LIMIT_WINDOW_MS) || 60 * 1000,
|
windowMs: parseInt(process.env.AGENT_RATE_LIMIT_WINDOW_MS, 10) || 60 * 1000,
|
||||||
max: parseInt(process.env.AGENT_RATE_LIMIT_MAX) || 120,
|
max: parseInt(process.env.AGENT_RATE_LIMIT_MAX, 10) || 120,
|
||||||
message: {
|
message: {
|
||||||
error: "Too many agent requests, please try again later.",
|
error: "Too many agent requests, please try again later.",
|
||||||
retryAfter: Math.ceil(
|
retryAfter: Math.ceil(
|
||||||
(parseInt(process.env.AGENT_RATE_LIMIT_WINDOW_MS) || 60 * 1000) / 1000,
|
(parseInt(process.env.AGENT_RATE_LIMIT_WINDOW_MS, 10) || 60 * 1000) /
|
||||||
|
1000,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
@@ -572,7 +573,7 @@ app.use(`/api/${apiVersion}/version`, versionRoutes);
|
|||||||
app.use(`/api/${apiVersion}/tfa`, tfaRoutes);
|
app.use(`/api/${apiVersion}/tfa`, tfaRoutes);
|
||||||
|
|
||||||
// Error handling middleware
|
// Error handling middleware
|
||||||
app.use((err, req, res, next) => {
|
app.use((err, _req, res, _next) => {
|
||||||
if (process.env.ENABLE_LOGGING === "true") {
|
if (process.env.ENABLE_LOGGING === "true") {
|
||||||
logger.error(err.stack);
|
logger.error(err.stack);
|
||||||
}
|
}
|
||||||
@@ -583,7 +584,7 @@ app.use((err, req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 404 handler
|
// 404 handler
|
||||||
app.use("*", (req, res) => {
|
app.use("*", (_req, res) => {
|
||||||
res.status(404).json({ error: "Route not found" });
|
res.status(404).json({ error: "Route not found" });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const { PrismaClient } = require("@prisma/client");
|
const { PrismaClient } = require("@prisma/client");
|
||||||
const { exec } = require("child_process");
|
const { exec } = require("node:child_process");
|
||||||
const { promisify } = require("util");
|
const { promisify } = require("node:util");
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
@@ -112,7 +112,7 @@ class UpdateScheduler {
|
|||||||
let currentVersion = "1.2.6"; // fallback
|
let currentVersion = "1.2.6"; // fallback
|
||||||
try {
|
try {
|
||||||
const packageJson = require("../../package.json");
|
const packageJson = require("../../package.json");
|
||||||
if (packageJson && packageJson.version) {
|
if (packageJson?.version) {
|
||||||
currentVersion = packageJson.version;
|
currentVersion = packageJson.version;
|
||||||
}
|
}
|
||||||
} catch (packageError) {
|
} catch (packageError) {
|
||||||
@@ -179,10 +179,10 @@ class UpdateScheduler {
|
|||||||
|
|
||||||
for (const path of possibleKeyPaths) {
|
for (const path of possibleKeyPaths) {
|
||||||
try {
|
try {
|
||||||
require("fs").accessSync(path);
|
require("node:fs").accessSync(path);
|
||||||
sshKeyPath = path;
|
sshKeyPath = path;
|
||||||
break;
|
break;
|
||||||
} catch (e) {
|
} catch {
|
||||||
// Key not found at this path, try next
|
// Key not found at this path, try next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ class UpdateScheduler {
|
|||||||
let currentVersion = "1.2.6"; // fallback
|
let currentVersion = "1.2.6"; // fallback
|
||||||
try {
|
try {
|
||||||
const packageJson = require("../../package.json");
|
const packageJson = require("../../package.json");
|
||||||
if (packageJson && packageJson.version) {
|
if (packageJson?.version) {
|
||||||
currentVersion = packageJson.version;
|
currentVersion = packageJson.version;
|
||||||
}
|
}
|
||||||
} catch (packageError) {
|
} catch (packageError) {
|
||||||
|
|||||||
Reference in New Issue
Block a user