mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-10-28 18:43:32 +00:00
380 lines
8.8 KiB
JavaScript
380 lines
8.8 KiB
JavaScript
const express = require("express");
|
|
const { body, validationResult } = require("express-validator");
|
|
const { PrismaClient } = require("@prisma/client");
|
|
const { authenticateToken } = require("../middleware/auth");
|
|
const { v4: uuidv4 } = require("uuid");
|
|
|
|
const router = express.Router();
|
|
const prisma = new PrismaClient();
|
|
|
|
// Helper function to get user permissions based on role
|
|
async function getUserPermissions(userRole) {
|
|
try {
|
|
const permissions = await prisma.role_permissions.findUnique({
|
|
where: { role: userRole },
|
|
});
|
|
|
|
// If no specific permissions found, return default admin permissions (for backward compatibility)
|
|
if (!permissions) {
|
|
console.warn(
|
|
`No permissions found for role: ${userRole}, defaulting to admin access`,
|
|
);
|
|
return {
|
|
can_view_dashboard: true,
|
|
can_view_hosts: true,
|
|
can_manage_hosts: true,
|
|
can_view_packages: true,
|
|
can_manage_packages: true,
|
|
can_view_users: true,
|
|
can_manage_users: true,
|
|
can_view_reports: true,
|
|
can_export_data: true,
|
|
can_manage_settings: true,
|
|
};
|
|
}
|
|
|
|
return permissions;
|
|
} catch (error) {
|
|
console.error("Error fetching user permissions:", error);
|
|
// Return admin permissions as fallback
|
|
return {
|
|
can_view_dashboard: true,
|
|
can_view_hosts: true,
|
|
can_manage_hosts: true,
|
|
can_view_packages: true,
|
|
can_manage_packages: true,
|
|
can_view_users: true,
|
|
can_manage_users: true,
|
|
can_view_reports: true,
|
|
can_export_data: true,
|
|
can_manage_settings: true,
|
|
};
|
|
}
|
|
}
|
|
|
|
// Helper function to create permission-based dashboard preferences for a new user
|
|
async function createDefaultDashboardPreferences(userId, userRole = "user") {
|
|
try {
|
|
// Get user's actual permissions
|
|
const permissions = await getUserPermissions(userRole);
|
|
|
|
// Define all possible dashboard cards with their required permissions
|
|
// Order aligned with preferred layout
|
|
const allCards = [
|
|
// Host-related cards
|
|
{ cardId: "totalHosts", requiredPermission: "can_view_hosts", order: 0 },
|
|
{
|
|
cardId: "hostsNeedingUpdates",
|
|
requiredPermission: "can_view_hosts",
|
|
order: 1,
|
|
},
|
|
|
|
// Package-related cards
|
|
{
|
|
cardId: "totalOutdatedPackages",
|
|
requiredPermission: "can_view_packages",
|
|
order: 2,
|
|
},
|
|
{
|
|
cardId: "securityUpdates",
|
|
requiredPermission: "can_view_packages",
|
|
order: 3,
|
|
},
|
|
|
|
// Host-related cards (continued)
|
|
{
|
|
cardId: "totalHostGroups",
|
|
requiredPermission: "can_view_hosts",
|
|
order: 4,
|
|
},
|
|
{
|
|
cardId: "upToDateHosts",
|
|
requiredPermission: "can_view_hosts",
|
|
order: 5,
|
|
},
|
|
|
|
// Repository-related cards
|
|
{ cardId: "totalRepos", requiredPermission: "can_view_hosts", order: 6 },
|
|
|
|
// User management cards (admin only)
|
|
{ cardId: "totalUsers", requiredPermission: "can_view_users", order: 7 },
|
|
|
|
// System/Report cards
|
|
{
|
|
cardId: "osDistribution",
|
|
requiredPermission: "can_view_reports",
|
|
order: 8,
|
|
},
|
|
{
|
|
cardId: "osDistributionBar",
|
|
requiredPermission: "can_view_reports",
|
|
order: 9,
|
|
},
|
|
{
|
|
cardId: "osDistributionDoughnut",
|
|
requiredPermission: "can_view_reports",
|
|
order: 10,
|
|
},
|
|
{
|
|
cardId: "recentCollection",
|
|
requiredPermission: "can_view_hosts",
|
|
order: 11,
|
|
},
|
|
{
|
|
cardId: "updateStatus",
|
|
requiredPermission: "can_view_reports",
|
|
order: 12,
|
|
},
|
|
{
|
|
cardId: "packagePriority",
|
|
requiredPermission: "can_view_packages",
|
|
order: 13,
|
|
},
|
|
{
|
|
cardId: "packageTrends",
|
|
requiredPermission: "can_view_packages",
|
|
order: 14,
|
|
},
|
|
{
|
|
cardId: "recentUsers",
|
|
requiredPermission: "can_view_users",
|
|
order: 15,
|
|
},
|
|
{
|
|
cardId: "quickStats",
|
|
requiredPermission: "can_view_dashboard",
|
|
order: 16,
|
|
},
|
|
];
|
|
|
|
// Filter cards based on user's permissions
|
|
const allowedCards = allCards.filter((card) => {
|
|
return permissions[card.requiredPermission] === true;
|
|
});
|
|
|
|
// Create preferences data
|
|
const preferencesData = allowedCards.map((card) => ({
|
|
id: uuidv4(),
|
|
user_id: userId,
|
|
card_id: card.cardId,
|
|
enabled: true,
|
|
order: card.order, // Preserve original order from allCards
|
|
created_at: new Date(),
|
|
updated_at: new Date(),
|
|
}));
|
|
|
|
await prisma.dashboard_preferences.createMany({
|
|
data: preferencesData,
|
|
});
|
|
|
|
console.log(
|
|
`Permission-based dashboard preferences created for user ${userId} with role ${userRole}: ${allowedCards.length} cards`,
|
|
);
|
|
} catch (error) {
|
|
console.error("Error creating default dashboard preferences:", error);
|
|
// Don't throw error - this shouldn't break user creation
|
|
}
|
|
}
|
|
|
|
// Get user's dashboard preferences
|
|
router.get("/", authenticateToken, async (req, res) => {
|
|
try {
|
|
const preferences = await prisma.dashboard_preferences.findMany({
|
|
where: { user_id: req.user.id },
|
|
orderBy: { order: "asc" },
|
|
});
|
|
|
|
res.json(preferences);
|
|
} catch (error) {
|
|
console.error("Dashboard preferences fetch error:", error);
|
|
res.status(500).json({ error: "Failed to fetch dashboard preferences" });
|
|
}
|
|
});
|
|
|
|
// Update dashboard preferences (bulk update)
|
|
router.put(
|
|
"/",
|
|
authenticateToken,
|
|
[
|
|
body("preferences").isArray().withMessage("Preferences must be an array"),
|
|
body("preferences.*.cardId").isString().withMessage("Card ID is required"),
|
|
body("preferences.*.enabled")
|
|
.isBoolean()
|
|
.withMessage("Enabled must be boolean"),
|
|
body("preferences.*.order").isInt().withMessage("Order must be integer"),
|
|
],
|
|
async (req, res) => {
|
|
try {
|
|
const errors = validationResult(req);
|
|
if (!errors.isEmpty()) {
|
|
return res.status(400).json({ errors: errors.array() });
|
|
}
|
|
|
|
const { preferences } = req.body;
|
|
const userId = req.user.id;
|
|
|
|
// Delete existing preferences for this user
|
|
await prisma.dashboard_preferences.deleteMany({
|
|
where: { user_id: userId },
|
|
});
|
|
|
|
// Create new preferences
|
|
const newPreferences = preferences.map((pref) => ({
|
|
id: require("uuid").v4(),
|
|
user_id: userId,
|
|
card_id: pref.cardId,
|
|
enabled: pref.enabled,
|
|
order: pref.order,
|
|
updated_at: new Date(),
|
|
}));
|
|
|
|
await prisma.dashboard_preferences.createMany({
|
|
data: newPreferences,
|
|
});
|
|
|
|
res.json({
|
|
message: "Dashboard preferences updated successfully",
|
|
preferences: newPreferences,
|
|
});
|
|
} catch (error) {
|
|
console.error("Dashboard preferences update error:", error);
|
|
res.status(500).json({ error: "Failed to update dashboard preferences" });
|
|
}
|
|
},
|
|
);
|
|
|
|
// Get default dashboard card configuration
|
|
router.get("/defaults", authenticateToken, async (_req, res) => {
|
|
try {
|
|
// This provides a comprehensive dashboard view for all new users
|
|
const defaultCards = [
|
|
{
|
|
cardId: "totalHosts",
|
|
title: "Total Hosts",
|
|
icon: "Server",
|
|
enabled: true,
|
|
order: 0,
|
|
},
|
|
{
|
|
cardId: "hostsNeedingUpdates",
|
|
title: "Needs Updating",
|
|
icon: "AlertTriangle",
|
|
enabled: true,
|
|
order: 1,
|
|
},
|
|
{
|
|
cardId: "totalOutdatedPackages",
|
|
title: "Outdated Packages",
|
|
icon: "Package",
|
|
enabled: true,
|
|
order: 2,
|
|
},
|
|
{
|
|
cardId: "securityUpdates",
|
|
title: "Security Updates",
|
|
icon: "Shield",
|
|
enabled: true,
|
|
order: 3,
|
|
},
|
|
{
|
|
cardId: "totalHostGroups",
|
|
title: "Host Groups",
|
|
icon: "Folder",
|
|
enabled: true,
|
|
order: 4,
|
|
},
|
|
{
|
|
cardId: "upToDateHosts",
|
|
title: "Up to date",
|
|
icon: "CheckCircle",
|
|
enabled: true,
|
|
order: 5,
|
|
},
|
|
{
|
|
cardId: "totalRepos",
|
|
title: "Repositories",
|
|
icon: "GitBranch",
|
|
enabled: true,
|
|
order: 6,
|
|
},
|
|
{
|
|
cardId: "totalUsers",
|
|
title: "Users",
|
|
icon: "Users",
|
|
enabled: true,
|
|
order: 7,
|
|
},
|
|
{
|
|
cardId: "osDistribution",
|
|
title: "OS Distribution",
|
|
icon: "BarChart3",
|
|
enabled: true,
|
|
order: 8,
|
|
},
|
|
{
|
|
cardId: "osDistributionBar",
|
|
title: "OS Distribution (Bar)",
|
|
icon: "BarChart3",
|
|
enabled: true,
|
|
order: 9,
|
|
},
|
|
{
|
|
cardId: "osDistributionDoughnut",
|
|
title: "OS Distribution (Doughnut)",
|
|
icon: "PieChart",
|
|
enabled: true,
|
|
order: 10,
|
|
},
|
|
{
|
|
cardId: "recentCollection",
|
|
title: "Recent Collection",
|
|
icon: "Server",
|
|
enabled: true,
|
|
order: 11,
|
|
},
|
|
{
|
|
cardId: "updateStatus",
|
|
title: "Update Status",
|
|
icon: "BarChart3",
|
|
enabled: true,
|
|
order: 12,
|
|
},
|
|
{
|
|
cardId: "packagePriority",
|
|
title: "Package Priority",
|
|
icon: "BarChart3",
|
|
enabled: true,
|
|
order: 13,
|
|
},
|
|
{
|
|
cardId: "packageTrends",
|
|
title: "Package Trends",
|
|
icon: "TrendingUp",
|
|
enabled: true,
|
|
order: 14,
|
|
},
|
|
{
|
|
cardId: "recentUsers",
|
|
title: "Recent Users Logged in",
|
|
icon: "Users",
|
|
enabled: true,
|
|
order: 15,
|
|
},
|
|
{
|
|
cardId: "quickStats",
|
|
title: "Quick Stats",
|
|
icon: "TrendingUp",
|
|
enabled: true,
|
|
order: 16,
|
|
},
|
|
];
|
|
|
|
res.json(defaultCards);
|
|
} catch (error) {
|
|
console.error("Default dashboard cards error:", error);
|
|
res.status(500).json({ error: "Failed to fetch default dashboard cards" });
|
|
}
|
|
});
|
|
|
|
module.exports = { router, createDefaultDashboardPreferences };
|