mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-10 08:55:44 +00:00
Fixed permissions issues
Created default user role modified server.js to check if roles of admin/user is present modified server.js to check dashboard cards set up default dashboard cards to show
This commit is contained in:
@@ -8,7 +8,9 @@ const FirstTimeAdminSetup = () => {
|
||||
username: '',
|
||||
email: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
confirmPassword: '',
|
||||
firstName: '',
|
||||
lastName: ''
|
||||
})
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
@@ -25,6 +27,14 @@ const FirstTimeAdminSetup = () => {
|
||||
}
|
||||
|
||||
const validateForm = () => {
|
||||
if (!formData.firstName.trim()) {
|
||||
setError('First name is required')
|
||||
return false
|
||||
}
|
||||
if (!formData.lastName.trim()) {
|
||||
setError('Last name is required')
|
||||
return false
|
||||
}
|
||||
if (!formData.username.trim()) {
|
||||
setError('Username is required')
|
||||
return false
|
||||
@@ -69,7 +79,9 @@ const FirstTimeAdminSetup = () => {
|
||||
body: JSON.stringify({
|
||||
username: formData.username.trim(),
|
||||
email: formData.email.trim(),
|
||||
password: formData.password
|
||||
password: formData.password,
|
||||
firstName: formData.firstName.trim(),
|
||||
lastName: formData.lastName.trim()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -145,6 +157,41 @@ const FirstTimeAdminSetup = () => {
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label htmlFor="firstName" className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-2">
|
||||
First Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="firstName"
|
||||
name="firstName"
|
||||
value={formData.firstName}
|
||||
onChange={handleInputChange}
|
||||
className="input w-full"
|
||||
placeholder="Enter your first name"
|
||||
required
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="lastName" className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-2">
|
||||
Last Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="lastName"
|
||||
name="lastName"
|
||||
value={formData.lastName}
|
||||
onChange={handleInputChange}
|
||||
className="input w-full"
|
||||
placeholder="Enter your last name"
|
||||
required
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="username" className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-2">
|
||||
Username
|
||||
|
||||
@@ -47,7 +47,7 @@ const Layout = ({ children }) => {
|
||||
const [userMenuOpen, setUserMenuOpen] = useState(false)
|
||||
const [githubStars, setGithubStars] = useState(null)
|
||||
const location = useLocation()
|
||||
const { user, logout, canViewHosts, canManageHosts, canViewPackages, canViewUsers, canManageUsers, canManageSettings } = useAuth()
|
||||
const { user, logout, canViewDashboard, canViewHosts, canManageHosts, canViewPackages, canViewUsers, canManageUsers, canViewReports, canExportData, canManageSettings } = useAuth()
|
||||
const { updateAvailable } = useUpdateNotification()
|
||||
const userMenuRef = useRef(null)
|
||||
|
||||
@@ -66,44 +66,103 @@ const Layout = ({ children }) => {
|
||||
staleTime: 300000, // Consider data stale after 5 minutes
|
||||
})
|
||||
|
||||
const navigation = [
|
||||
{ name: 'Dashboard', href: '/', icon: Home },
|
||||
{
|
||||
section: 'Inventory',
|
||||
items: [
|
||||
...(canViewHosts() ? [{ name: 'Hosts', href: '/hosts', icon: Server }] : []),
|
||||
...(canViewPackages() ? [{ name: 'Packages', href: '/packages', icon: Package }] : []),
|
||||
...(canViewHosts() ? [{ name: 'Repos', href: '/repositories', icon: GitBranch }] : []),
|
||||
{ name: 'Services', href: '/services', icon: Activity, comingSoon: true },
|
||||
{ name: 'Docker', href: '/docker', icon: Container, comingSoon: true },
|
||||
{ name: 'Reporting', href: '/reporting', icon: BarChart3, comingSoon: true },
|
||||
]
|
||||
},
|
||||
...(canViewUsers() || canManageUsers() ? [{
|
||||
section: 'PatchMon Users',
|
||||
items: [
|
||||
...(canViewUsers() ? [{ name: 'Users', href: '/users', icon: Users }] : []),
|
||||
...(canManageSettings() ? [{ name: 'Permissions', href: '/permissions', icon: Shield }] : []),
|
||||
]
|
||||
}] : []),
|
||||
{
|
||||
section: 'Settings',
|
||||
items: [
|
||||
...(canManageHosts() ? [{
|
||||
// Build navigation based on permissions
|
||||
const buildNavigation = () => {
|
||||
const nav = []
|
||||
|
||||
// Dashboard - only show if user can view dashboard
|
||||
if (canViewDashboard()) {
|
||||
nav.push({ name: 'Dashboard', href: '/', icon: Home })
|
||||
}
|
||||
|
||||
// Inventory section - only show if user has any inventory permissions
|
||||
if (canViewHosts() || canViewPackages() || canViewReports()) {
|
||||
const inventoryItems = []
|
||||
|
||||
if (canViewHosts()) {
|
||||
inventoryItems.push({ name: 'Hosts', href: '/hosts', icon: Server })
|
||||
inventoryItems.push({ name: 'Repos', href: '/repositories', icon: GitBranch })
|
||||
}
|
||||
|
||||
if (canViewPackages()) {
|
||||
inventoryItems.push({ name: 'Packages', href: '/packages', icon: Package })
|
||||
}
|
||||
|
||||
if (canViewReports()) {
|
||||
inventoryItems.push(
|
||||
{ name: 'Services', href: '/services', icon: Activity, comingSoon: true },
|
||||
{ name: 'Docker', href: '/docker', icon: Container, comingSoon: true },
|
||||
{ name: 'Reporting', href: '/reporting', icon: BarChart3, comingSoon: true }
|
||||
)
|
||||
}
|
||||
|
||||
if (inventoryItems.length > 0) {
|
||||
nav.push({
|
||||
section: 'Inventory',
|
||||
items: inventoryItems
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// PatchMon Users section - only show if user can view/manage users
|
||||
if (canViewUsers() || canManageUsers()) {
|
||||
const userItems = []
|
||||
|
||||
if (canViewUsers()) {
|
||||
userItems.push({ name: 'Users', href: '/users', icon: Users })
|
||||
}
|
||||
|
||||
if (canManageSettings()) {
|
||||
userItems.push({ name: 'Permissions', href: '/permissions', icon: Shield })
|
||||
}
|
||||
|
||||
if (userItems.length > 0) {
|
||||
nav.push({
|
||||
section: 'PatchMon Users',
|
||||
items: userItems
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Settings section - only show if user has any settings permissions
|
||||
if (canManageSettings() || canViewReports() || canExportData()) {
|
||||
const settingsItems = []
|
||||
|
||||
if (canManageSettings()) {
|
||||
settingsItems.push({
|
||||
name: 'PatchMon Options',
|
||||
href: '/options',
|
||||
icon: Settings
|
||||
}] : []),
|
||||
{ name: 'Audit Log', href: '/audit-log', icon: FileText, comingSoon: true },
|
||||
...(canManageSettings() ? [{
|
||||
})
|
||||
settingsItems.push({
|
||||
name: 'Server Config',
|
||||
href: '/settings',
|
||||
icon: Wrench,
|
||||
showUpgradeIcon: updateAvailable
|
||||
}] : []),
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
if (canViewReports() || canExportData()) {
|
||||
settingsItems.push({
|
||||
name: 'Audit Log',
|
||||
href: '/audit-log',
|
||||
icon: FileText,
|
||||
comingSoon: true
|
||||
})
|
||||
}
|
||||
|
||||
if (settingsItems.length > 0) {
|
||||
nav.push({
|
||||
section: 'Settings',
|
||||
items: settingsItems
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
return nav
|
||||
}
|
||||
|
||||
const navigation = buildNavigation()
|
||||
|
||||
const isActive = (path) => location.pathname === path
|
||||
|
||||
@@ -221,6 +280,15 @@ const Layout = ({ children }) => {
|
||||
</div>
|
||||
</div>
|
||||
<nav className="mt-8 flex-1 space-y-6 px-2">
|
||||
{/* Show message for users with very limited permissions */}
|
||||
{navigation.length === 0 && (
|
||||
<div className="px-2 py-4 text-center">
|
||||
<div className="text-sm text-secondary-500 dark:text-secondary-400">
|
||||
<p className="mb-2">Limited access</p>
|
||||
<p className="text-xs">Contact your administrator for additional permissions</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{navigation.map((item, index) => {
|
||||
if (item.name) {
|
||||
// Single item (Dashboard)
|
||||
@@ -346,6 +414,15 @@ const Layout = ({ children }) => {
|
||||
</div>
|
||||
<nav className="flex flex-1 flex-col">
|
||||
<ul className="flex flex-1 flex-col gap-y-6">
|
||||
{/* Show message for users with very limited permissions */}
|
||||
{navigation.length === 0 && (
|
||||
<li className="px-2 py-4 text-center">
|
||||
<div className="text-sm text-secondary-500 dark:text-secondary-400">
|
||||
<p className="mb-2">Limited access</p>
|
||||
<p className="text-xs">Contact your administrator for additional permissions</p>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
{navigation.map((item, index) => {
|
||||
if (item.name) {
|
||||
// Single item (Dashboard)
|
||||
|
||||
Reference in New Issue
Block a user