Skip to content

Commit a4e9c6e

Browse files
committed
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.
1 parent 72fb85f commit a4e9c6e

File tree

9 files changed

+38
-23
lines changed

9 files changed

+38
-23
lines changed

apps/dokploy/__test__/permissions/resolve-permissions.test.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,28 @@ describe("enterprise resources for static roles", () => {
8888
}
8989
});
9090

91-
it("member gets true for all enterprise resources", async () => {
91+
it("member gets true for service-level enterprise resources", async () => {
9292
memberToReturn = mockMemberData("member");
9393
const perms = await resolvePermissions(ctx);
9494

95-
for (const resource of enterpriseOnlyResources) {
96-
const actions = statements[resource as keyof typeof statements];
97-
for (const action of actions) {
98-
expect((perms as any)[resource][action]).toBe(true);
99-
}
100-
}
95+
expect(perms.deployment.read).toBe(true);
96+
expect(perms.deployment.create).toBe(true);
97+
expect(perms.domain.read).toBe(true);
98+
expect(perms.backup.read).toBe(true);
99+
expect(perms.logs.read).toBe(true);
100+
expect(perms.monitoring.read).toBe(true);
101+
});
102+
103+
it("member gets false for org-level enterprise resources", async () => {
104+
memberToReturn = mockMemberData("member");
105+
const perms = await resolvePermissions(ctx);
106+
107+
expect(perms.server.read).toBe(false);
108+
expect(perms.registry.read).toBe(false);
109+
expect(perms.certificate.read).toBe(false);
110+
expect(perms.destination.read).toBe(false);
111+
expect(perms.notification.read).toBe(false);
112+
expect(perms.auditLog.read).toBe(false);
101113
});
102114
});
103115

apps/dokploy/components/dashboard/settings/audit-logs/columns.tsx renamed to apps/dokploy/components/proprietary/audit-logs/columns.tsx

File renamed without changes.

apps/dokploy/components/dashboard/settings/audit-logs/data-table.tsx renamed to apps/dokploy/components/proprietary/audit-logs/data-table.tsx

File renamed without changes.

apps/dokploy/components/dashboard/settings/audit-logs/show-audit-logs.tsx renamed to apps/dokploy/components/proprietary/audit-logs/show-audit-logs.tsx

File renamed without changes.

apps/dokploy/components/dashboard/settings/users/manage-custom-roles.tsx renamed to apps/dokploy/components/proprietary/roles/manage-custom-roles.tsx

File renamed without changes.

apps/dokploy/pages/dashboard/settings/audit-logs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { createServerSideHelpers } from "@trpc/react-query/server";
33
import type { GetServerSidePropsContext } from "next";
44
import type { ReactElement } from "react";
55
import superjson from "superjson";
6-
import { ShowAuditLogs } from "@/components/dashboard/settings/audit-logs/show-audit-logs";
76
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
7+
import { ShowAuditLogs } from "@/components/proprietary/audit-logs/show-audit-logs";
88
import { appRouter } from "@/server/api/root";
99

1010
const Page = () => {

apps/dokploy/pages/dashboard/settings/users.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { createServerSideHelpers } from "@trpc/react-query/server";
33
import type { GetServerSidePropsContext } from "next";
44
import type { ReactElement } from "react";
55
import superjson from "superjson";
6-
import { ManageCustomRoles } from "@/components/dashboard/settings/users/manage-custom-roles";
6+
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
7+
import { ManageCustomRoles } from "@/components/proprietary/roles/manage-custom-roles";
78
import { ShowInvitations } from "@/components/dashboard/settings/users/show-invitations";
89
import { ShowUsers } from "@/components/dashboard/settings/users/show-users";
9-
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
1010
import { appRouter } from "@/server/api/root";
1111
import { api } from "@/utils/api";
1212

packages/server/src/lib/access-control.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -168,21 +168,23 @@ export const memberRole = ac.newRole({
168168
gitProviders: [],
169169
traefikFiles: [],
170170
api: [],
171-
volume: [],
172-
deployment: [],
173-
envVars: [],
174-
projectEnvVars: [],
175-
environmentEnvVars: [],
171+
// Service-level enterprise resources — member can do everything within services they have access to
172+
volume: ["read", "create", "delete"],
173+
deployment: ["read", "create", "cancel"],
174+
envVars: ["read", "write"],
175+
projectEnvVars: ["read", "write"],
176+
environmentEnvVars: ["read", "write"],
177+
backup: ["read", "create", "update", "delete", "restore"],
178+
volumeBackup: ["read", "create", "update", "delete", "restore"],
179+
schedule: ["read", "create", "update", "delete"],
180+
domain: ["read", "create", "delete"],
181+
logs: ["read"],
182+
monitoring: ["read"],
183+
// Org-level enterprise resources — member cannot manage these
176184
server: [],
177185
registry: [],
178186
certificate: [],
179-
backup: [],
180-
volumeBackup: [],
181-
schedule: [],
182-
domain: [],
183187
destination: [],
184188
notification: [],
185-
logs: [],
186-
monitoring: [],
187189
auditLog: [],
188190
});

packages/server/src/services/permission.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,14 @@ export const resolvePermissions = async (
182182
const legacyOverrides =
183183
memberRecord.role === "member" ? getLegacyOverrides(memberRecord) : {};
184184

185-
const isStaticRole = memberRecord.role in staticRoles;
185+
const isPrivilegedRole =
186+
memberRecord.role === "owner" || memberRecord.role === "admin";
186187
const result = {} as ResolvedPermissions;
187188

188189
for (const [resource, actions] of Object.entries(statements)) {
189190
const resourcePerms = {} as Record<string, boolean>;
190191
for (const action of actions) {
191-
if (isStaticRole && enterpriseOnlyResources.has(resource)) {
192+
if (isPrivilegedRole && enterpriseOnlyResources.has(resource)) {
192193
resourcePerms[action] = true;
193194
continue;
194195
}

0 commit comments

Comments
 (0)