mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-15 20:25:23 +02:00
refactor: replace existing organization_role and audit_log tables with new definitions
- Deleted the old SQL files for organization_role and audit_log. - Introduced new SQL file defining organization_role and audit_log with updated foreign key constraints and indexes. - Updated metadata snapshots to reflect the new table structures and relationships. - Adjusted access control permissions for backup and notification operations to include update capabilities.
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
CREATE TABLE "organization_role" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"role" text NOT NULL,
|
||||
"permission" text NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "organization_role" ADD CONSTRAINT "organization_role_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "organizationRole_organizationId_idx" ON "organization_role" USING btree ("organization_id");--> statement-breakpoint
|
||||
CREATE INDEX "organizationRole_role_idx" ON "organization_role" USING btree ("role");
|
||||
31
apps/dokploy/drizzle/0149_rare_radioactive_man.sql
Normal file
31
apps/dokploy/drizzle/0149_rare_radioactive_man.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
CREATE TABLE "organization_role" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"role" text NOT NULL,
|
||||
"permission" text NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "audit_log" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text,
|
||||
"user_id" text,
|
||||
"user_email" text NOT NULL,
|
||||
"user_role" text NOT NULL,
|
||||
"action" text NOT NULL,
|
||||
"resource_type" text NOT NULL,
|
||||
"resource_id" text,
|
||||
"resource_name" text,
|
||||
"metadata" text,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "organization_role" ADD CONSTRAINT "organization_role_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "organizationRole_organizationId_idx" ON "organization_role" USING btree ("organization_id");--> statement-breakpoint
|
||||
CREATE INDEX "organizationRole_role_idx" ON "organization_role" USING btree ("role");--> statement-breakpoint
|
||||
CREATE INDEX "auditLog_organizationId_idx" ON "audit_log" USING btree ("organization_id");--> statement-breakpoint
|
||||
CREATE INDEX "auditLog_userId_idx" ON "audit_log" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "auditLog_createdAt_idx" ON "audit_log" USING btree ("created_at");
|
||||
@@ -1,19 +0,0 @@
|
||||
CREATE TABLE "audit_log" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"user_email" text NOT NULL,
|
||||
"user_role" text NOT NULL,
|
||||
"action" text NOT NULL,
|
||||
"resource_type" text NOT NULL,
|
||||
"resource_id" text,
|
||||
"resource_name" text,
|
||||
"metadata" text,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "auditLog_organizationId_idx" ON "audit_log" USING btree ("organization_id");--> statement-breakpoint
|
||||
CREATE INDEX "auditLog_userId_idx" ON "audit_log" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "auditLog_createdAt_idx" ON "audit_log" USING btree ("created_at");
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "5886356f-9277-465b-8ae1-54e2ba28cce4",
|
||||
"id": "e6eacbcd-0e09-4fa0-91be-730d3cc20d84",
|
||||
"prevId": "a293a443-ceaf-418e-8e34-ff46e183995f",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
@@ -917,6 +917,159 @@
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.audit_log": {
|
||||
"name": "audit_log",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"organization_id": {
|
||||
"name": "organization_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"user_email": {
|
||||
"name": "user_email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"user_role": {
|
||||
"name": "user_role",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"action": {
|
||||
"name": "action",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"resource_type": {
|
||||
"name": "resource_type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"resource_id": {
|
||||
"name": "resource_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"resource_name": {
|
||||
"name": "resource_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"metadata": {
|
||||
"name": "metadata",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"auditLog_organizationId_idx": {
|
||||
"name": "auditLog_organizationId_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "organization_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"auditLog_userId_idx": {
|
||||
"name": "auditLog_userId_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "user_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"auditLog_createdAt_idx": {
|
||||
"name": "auditLog_createdAt_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "created_at",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"audit_log_organization_id_organization_id_fk": {
|
||||
"name": "audit_log_organization_id_organization_id_fk",
|
||||
"tableFrom": "audit_log",
|
||||
"tableTo": "organization",
|
||||
"columnsFrom": [
|
||||
"organization_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"audit_log_user_id_user_id_fk": {
|
||||
"name": "audit_log_user_id_user_id_fk",
|
||||
"tableFrom": "audit_log",
|
||||
"tableTo": "user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.application": {
|
||||
"name": "application",
|
||||
"schema": "",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1048,15 +1048,8 @@
|
||||
{
|
||||
"idx": 149,
|
||||
"version": "7",
|
||||
"when": 1773184273215,
|
||||
"tag": "0149_clumsy_speedball",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 150,
|
||||
"version": "7",
|
||||
"when": 1773374115852,
|
||||
"tag": "0150_glorious_pyro",
|
||||
"when": 1773637297592,
|
||||
"tag": "0149_rare_radioactive_man",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -77,22 +77,21 @@ export const backupRouter = createTRPCRouter({
|
||||
.input(apiCreateBackup)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const newBackup = await createBackup(input);
|
||||
|
||||
const backup = await findBackupById(newBackup.backupId);
|
||||
|
||||
const serviceId =
|
||||
backup.postgresId ||
|
||||
backup.mysqlId ||
|
||||
backup.mariadbId ||
|
||||
backup.mongoId ||
|
||||
backup.composeId;
|
||||
input.postgresId ||
|
||||
input.mysqlId ||
|
||||
input.mariadbId ||
|
||||
input.mongoId ||
|
||||
input.composeId;
|
||||
if (serviceId) {
|
||||
await checkServicePermissionAndAccess(ctx, serviceId, {
|
||||
backup: ["create"],
|
||||
});
|
||||
}
|
||||
|
||||
const newBackup = await createBackup(input);
|
||||
const backup = await findBackupById(newBackup.backupId);
|
||||
|
||||
if (IS_CLOUD && backup.enabled) {
|
||||
const databaseType = backup.databaseType;
|
||||
let serverId = "";
|
||||
@@ -168,21 +167,22 @@ export const backupRouter = createTRPCRouter({
|
||||
.input(apiUpdateBackup)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
await updateBackupById(input.backupId, input);
|
||||
const backup = await findBackupById(input.backupId);
|
||||
|
||||
const existing = await findBackupById(input.backupId);
|
||||
const serviceId =
|
||||
backup.postgresId ||
|
||||
backup.mysqlId ||
|
||||
backup.mariadbId ||
|
||||
backup.mongoId ||
|
||||
backup.composeId;
|
||||
existing.postgresId ||
|
||||
existing.mysqlId ||
|
||||
existing.mariadbId ||
|
||||
existing.mongoId ||
|
||||
existing.composeId;
|
||||
if (serviceId) {
|
||||
await checkServicePermissionAndAccess(ctx, serviceId, {
|
||||
backup: ["create"],
|
||||
backup: ["update"],
|
||||
});
|
||||
}
|
||||
|
||||
await updateBackupById(input.backupId, input);
|
||||
const backup = await findBackupById(input.backupId);
|
||||
|
||||
if (IS_CLOUD) {
|
||||
if (backup.enabled) {
|
||||
await updateJob({
|
||||
|
||||
@@ -107,7 +107,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateSlack: withPermission("notification", "create")
|
||||
updateSlack: withPermission("notification", "update")
|
||||
.input(apiUpdateSlack)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -172,7 +172,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
updateTelegram: withPermission("notification", "create")
|
||||
updateTelegram: withPermission("notification", "update")
|
||||
.input(apiUpdateTelegram)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -238,7 +238,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
updateDiscord: withPermission("notification", "create")
|
||||
updateDiscord: withPermission("notification", "update")
|
||||
.input(apiUpdateDiscord)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -309,7 +309,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateEmail: withPermission("notification", "create")
|
||||
updateEmail: withPermission("notification", "update")
|
||||
.input(apiUpdateEmail)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -375,7 +375,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateResend: withPermission("notification", "create")
|
||||
updateResend: withPermission("notification", "update")
|
||||
.input(apiUpdateResend)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -561,7 +561,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateGotify: withPermission("notification", "create")
|
||||
updateGotify: withPermission("notification", "update")
|
||||
.input(apiUpdateGotify)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -626,7 +626,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateNtfy: withPermission("notification", "create")
|
||||
updateNtfy: withPermission("notification", "update")
|
||||
.input(apiUpdateNtfy)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -693,7 +693,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateCustom: withPermission("notification", "create")
|
||||
updateCustom: withPermission("notification", "update")
|
||||
.input(apiUpdateCustom)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -755,7 +755,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateLark: withPermission("notification", "create")
|
||||
updateLark: withPermission("notification", "update")
|
||||
.input(apiUpdateLark)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -821,7 +821,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updateTeams: withPermission("notification", "create")
|
||||
updateTeams: withPermission("notification", "update")
|
||||
.input(apiUpdateTeams)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
@@ -888,7 +888,7 @@ export const notificationRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
updatePushover: withPermission("notification", "create")
|
||||
updatePushover: withPermission("notification", "update")
|
||||
.input(apiUpdatePushover)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
|
||||
@@ -11,11 +11,9 @@ export const auditLog = pgTable(
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
.references(() => organization.id, { onDelete: "set null" }),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
.references(() => user.id, { onDelete: "set null" }),
|
||||
userEmail: text("user_email").notNull(),
|
||||
userRole: text("user_role").notNull(),
|
||||
action: text("action").notNull(),
|
||||
|
||||
@@ -38,12 +38,12 @@ export const statements = {
|
||||
server: ["read", "create", "delete"],
|
||||
registry: ["read", "create", "delete"],
|
||||
certificate: ["read", "create", "delete"],
|
||||
backup: ["read", "create", "delete", "restore"],
|
||||
backup: ["read", "create", "update", "delete", "restore"],
|
||||
volumeBackup: ["read", "create", "update", "delete", "restore"],
|
||||
schedule: ["read", "create", "update", "delete"],
|
||||
domain: ["read", "create", "delete"],
|
||||
destination: ["read", "create", "delete"],
|
||||
notification: ["read", "create", "delete"],
|
||||
notification: ["read", "create", "update", "delete"],
|
||||
logs: ["read"],
|
||||
monitoring: ["read"],
|
||||
auditLog: ["read"],
|
||||
@@ -101,12 +101,12 @@ export const ownerRole = ac.newRole({
|
||||
server: ["read", "create", "delete"],
|
||||
registry: ["read", "create", "delete"],
|
||||
certificate: ["read", "create", "delete"],
|
||||
backup: ["read", "create", "delete", "restore"],
|
||||
backup: ["read", "create", "update", "delete", "restore"],
|
||||
volumeBackup: ["read", "create", "update", "delete", "restore"],
|
||||
schedule: ["read", "create", "update", "delete"],
|
||||
domain: ["read", "create", "delete"],
|
||||
destination: ["read", "create", "delete"],
|
||||
notification: ["read", "create", "delete"],
|
||||
notification: ["read", "create", "update", "delete"],
|
||||
logs: ["read"],
|
||||
monitoring: ["read"],
|
||||
auditLog: ["read"],
|
||||
@@ -137,12 +137,12 @@ export const adminRole = ac.newRole({
|
||||
server: ["read", "create", "delete"],
|
||||
registry: ["read", "create", "delete"],
|
||||
certificate: ["read", "create", "delete"],
|
||||
backup: ["read", "create", "delete", "restore"],
|
||||
backup: ["read", "create", "update", "delete", "restore"],
|
||||
volumeBackup: ["read", "create", "update", "delete", "restore"],
|
||||
schedule: ["read", "create", "update", "delete"],
|
||||
domain: ["read", "create", "delete"],
|
||||
destination: ["read", "create", "delete"],
|
||||
notification: ["read", "create", "delete"],
|
||||
notification: ["read", "create", "update", "delete"],
|
||||
logs: ["read"],
|
||||
monitoring: ["read"],
|
||||
auditLog: ["read"],
|
||||
|
||||
Reference in New Issue
Block a user