mirror of
https://github.com/dokploy/dokploy.git
synced 2026-06-13 19:09:49 +00:00
feat: implement audit logs and custom role management components
- Added new components for displaying and managing audit logs, including a data table and filters for user actions. - Introduced a custom roles management interface, allowing users to create and modify roles with specific permissions. - Updated permission checks to ensure proper access control for audit logs and custom roles. - Refactored existing components to integrate new functionality and improve user experience.
This commit is contained in:
@@ -88,16 +88,28 @@ describe("enterprise resources for static roles", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("member gets true for all enterprise resources", async () => {
|
||||
it("member gets true for service-level enterprise resources", async () => {
|
||||
memberToReturn = mockMemberData("member");
|
||||
const perms = await resolvePermissions(ctx);
|
||||
|
||||
for (const resource of enterpriseOnlyResources) {
|
||||
const actions = statements[resource as keyof typeof statements];
|
||||
for (const action of actions) {
|
||||
expect((perms as any)[resource][action]).toBe(true);
|
||||
}
|
||||
}
|
||||
expect(perms.deployment.read).toBe(true);
|
||||
expect(perms.deployment.create).toBe(true);
|
||||
expect(perms.domain.read).toBe(true);
|
||||
expect(perms.backup.read).toBe(true);
|
||||
expect(perms.logs.read).toBe(true);
|
||||
expect(perms.monitoring.read).toBe(true);
|
||||
});
|
||||
|
||||
it("member gets false for org-level enterprise resources", async () => {
|
||||
memberToReturn = mockMemberData("member");
|
||||
const perms = await resolvePermissions(ctx);
|
||||
|
||||
expect(perms.server.read).toBe(false);
|
||||
expect(perms.registry.read).toBe(false);
|
||||
expect(perms.certificate.read).toBe(false);
|
||||
expect(perms.destination.read).toBe(false);
|
||||
expect(perms.notification.read).toBe(false);
|
||||
expect(perms.auditLog.read).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||
import type { GetServerSidePropsContext } from "next";
|
||||
import type { ReactElement } from "react";
|
||||
import superjson from "superjson";
|
||||
import { ShowAuditLogs } from "@/components/dashboard/settings/audit-logs/show-audit-logs";
|
||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||
import { ShowAuditLogs } from "@/components/proprietary/audit-logs/show-audit-logs";
|
||||
import { appRouter } from "@/server/api/root";
|
||||
|
||||
const Page = () => {
|
||||
|
||||
@@ -3,10 +3,10 @@ import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||
import type { GetServerSidePropsContext } from "next";
|
||||
import type { ReactElement } from "react";
|
||||
import superjson from "superjson";
|
||||
import { ManageCustomRoles } from "@/components/dashboard/settings/users/manage-custom-roles";
|
||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||
import { ManageCustomRoles } from "@/components/proprietary/roles/manage-custom-roles";
|
||||
import { ShowInvitations } from "@/components/dashboard/settings/users/show-invitations";
|
||||
import { ShowUsers } from "@/components/dashboard/settings/users/show-users";
|
||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||
import { appRouter } from "@/server/api/root";
|
||||
import { api } from "@/utils/api";
|
||||
|
||||
|
||||
@@ -168,21 +168,23 @@ export const memberRole = ac.newRole({
|
||||
gitProviders: [],
|
||||
traefikFiles: [],
|
||||
api: [],
|
||||
volume: [],
|
||||
deployment: [],
|
||||
envVars: [],
|
||||
projectEnvVars: [],
|
||||
environmentEnvVars: [],
|
||||
// Service-level enterprise resources — member can do everything within services they have access to
|
||||
volume: ["read", "create", "delete"],
|
||||
deployment: ["read", "create", "cancel"],
|
||||
envVars: ["read", "write"],
|
||||
projectEnvVars: ["read", "write"],
|
||||
environmentEnvVars: ["read", "write"],
|
||||
backup: ["read", "create", "update", "delete", "restore"],
|
||||
volumeBackup: ["read", "create", "update", "delete", "restore"],
|
||||
schedule: ["read", "create", "update", "delete"],
|
||||
domain: ["read", "create", "delete"],
|
||||
logs: ["read"],
|
||||
monitoring: ["read"],
|
||||
// Org-level enterprise resources — member cannot manage these
|
||||
server: [],
|
||||
registry: [],
|
||||
certificate: [],
|
||||
backup: [],
|
||||
volumeBackup: [],
|
||||
schedule: [],
|
||||
domain: [],
|
||||
destination: [],
|
||||
notification: [],
|
||||
logs: [],
|
||||
monitoring: [],
|
||||
auditLog: [],
|
||||
});
|
||||
|
||||
@@ -182,13 +182,14 @@ export const resolvePermissions = async (
|
||||
const legacyOverrides =
|
||||
memberRecord.role === "member" ? getLegacyOverrides(memberRecord) : {};
|
||||
|
||||
const isStaticRole = memberRecord.role in staticRoles;
|
||||
const isPrivilegedRole =
|
||||
memberRecord.role === "owner" || memberRecord.role === "admin";
|
||||
const result = {} as ResolvedPermissions;
|
||||
|
||||
for (const [resource, actions] of Object.entries(statements)) {
|
||||
const resourcePerms = {} as Record<string, boolean>;
|
||||
for (const action of actions) {
|
||||
if (isStaticRole && enterpriseOnlyResources.has(resource)) {
|
||||
if (isPrivilegedRole && enterpriseOnlyResources.has(resource)) {
|
||||
resourcePerms[action] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user