diff --git a/apps/dokploy/__test__/permissions/check-permission.test.ts b/apps/dokploy/__test__/permissions/check-permission.test.ts index 21d81d5f8..7f14e2d0e 100644 --- a/apps/dokploy/__test__/permissions/check-permission.test.ts +++ b/apps/dokploy/__test__/permissions/check-permission.test.ts @@ -1,6 +1,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -const mockMemberData = (role: string, overrides: Record = {}) => ({ +const mockMemberData = ( + role: string, + overrides: Record = {}, +) => ({ id: "member-1", role, userId: "user-1", @@ -22,7 +25,8 @@ const mockMemberData = (role: string, overrides: Record = {}) = user: { id: "user-1", email: "test@test.com" }, }); -let memberToReturn: ReturnType = mockMemberData("member"); +let memberToReturn: ReturnType = + mockMemberData("member"); vi.mock("@dokploy/server/db", () => ({ db: { @@ -57,23 +61,33 @@ beforeEach(() => { describe("static roles bypass enterprise resources", () => { it("owner bypasses deployment.read", async () => { memberToReturn = mockMemberData("owner"); - await expect(checkPermission(ctx, { deployment: ["read"] })).resolves.toBeUndefined(); + await expect( + checkPermission(ctx, { deployment: ["read"] }), + ).resolves.toBeUndefined(); }); it("admin bypasses backup.create", async () => { memberToReturn = mockMemberData("admin"); - await expect(checkPermission(ctx, { backup: ["create"] })).resolves.toBeUndefined(); + await expect( + checkPermission(ctx, { backup: ["create"] }), + ).resolves.toBeUndefined(); }); it("member bypasses schedule.delete", async () => { memberToReturn = mockMemberData("member"); - await expect(checkPermission(ctx, { schedule: ["delete"] })).resolves.toBeUndefined(); + await expect( + checkPermission(ctx, { schedule: ["delete"] }), + ).resolves.toBeUndefined(); }); it("member bypasses multiple enterprise permissions at once", async () => { memberToReturn = mockMemberData("member"); await expect( - checkPermission(ctx, { deployment: ["read"], backup: ["create"], domain: ["delete"] }), + checkPermission(ctx, { + deployment: ["read"], + backup: ["create"], + domain: ["delete"], + }), ).resolves.toBeUndefined(); }); }); @@ -81,34 +95,46 @@ describe("static roles bypass enterprise resources", () => { describe("static roles validate free-tier resources", () => { it("owner passes project.create", async () => { memberToReturn = mockMemberData("owner"); - await expect(checkPermission(ctx, { project: ["create"] })).resolves.toBeUndefined(); + await expect( + checkPermission(ctx, { project: ["create"] }), + ).resolves.toBeUndefined(); }); it("member fails project.create (no legacy override)", async () => { memberToReturn = mockMemberData("member"); - await expect(checkPermission(ctx, { project: ["create"] })).rejects.toThrow(); + await expect( + checkPermission(ctx, { project: ["create"] }), + ).rejects.toThrow(); }); it("member passes service.read", async () => { memberToReturn = mockMemberData("member"); - await expect(checkPermission(ctx, { service: ["read"] })).resolves.toBeUndefined(); + await expect( + checkPermission(ctx, { service: ["read"] }), + ).resolves.toBeUndefined(); }); it("member fails service.create", async () => { memberToReturn = mockMemberData("member"); - await expect(checkPermission(ctx, { service: ["create"] })).rejects.toThrow(); + await expect( + checkPermission(ctx, { service: ["create"] }), + ).rejects.toThrow(); }); }); describe("legacy boolean overrides for member", () => { it("member passes project.create with canCreateProjects=true", async () => { memberToReturn = mockMemberData("member", { canCreateProjects: true }); - await expect(checkPermission(ctx, { project: ["create"] })).resolves.toBeUndefined(); + await expect( + checkPermission(ctx, { project: ["create"] }), + ).resolves.toBeUndefined(); }); it("member passes docker.read with canAccessToDocker=true", async () => { memberToReturn = mockMemberData("member", { canAccessToDocker: true }); - await expect(checkPermission(ctx, { docker: ["read"] })).resolves.toBeUndefined(); + await expect( + checkPermission(ctx, { docker: ["read"] }), + ).resolves.toBeUndefined(); }); it("member fails docker.read with canAccessToDocker=false", async () => { diff --git a/apps/dokploy/__test__/permissions/enterprise-only-resources.test.ts b/apps/dokploy/__test__/permissions/enterprise-only-resources.test.ts index 1db1eb2f6..9568b12af 100644 --- a/apps/dokploy/__test__/permissions/enterprise-only-resources.test.ts +++ b/apps/dokploy/__test__/permissions/enterprise-only-resources.test.ts @@ -1,5 +1,8 @@ import { describe, it, expect } from "vitest"; -import { enterpriseOnlyResources, statements } from "@dokploy/server/lib/access-control"; +import { + enterpriseOnlyResources, + statements, +} from "@dokploy/server/lib/access-control"; const FREE_TIER_RESOURCES = [ "organization", diff --git a/apps/dokploy/__test__/permissions/resolve-permissions.test.ts b/apps/dokploy/__test__/permissions/resolve-permissions.test.ts index 5c1d52268..8ea6b9596 100644 --- a/apps/dokploy/__test__/permissions/resolve-permissions.test.ts +++ b/apps/dokploy/__test__/permissions/resolve-permissions.test.ts @@ -1,6 +1,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -const mockMemberData = (role: string, overrides: Record = {}) => ({ +const mockMemberData = ( + role: string, + overrides: Record = {}, +) => ({ id: "member-1", role, userId: "user-1", @@ -22,7 +25,8 @@ const mockMemberData = (role: string, overrides: Record = {}) = user: { id: "user-1", email: "test@test.com" }, }); -let memberToReturn: ReturnType = mockMemberData("member"); +let memberToReturn: ReturnType = + mockMemberData("member"); vi.mock("@dokploy/server/db", () => ({ db: { @@ -43,8 +47,12 @@ vi.mock("@dokploy/server/services/proprietary/license-key", () => ({ hasValidLicense: vi.fn(() => Promise.resolve(false)), })); -const { resolvePermissions } = await import("@dokploy/server/services/permission"); -const { enterpriseOnlyResources, statements } = await import("@dokploy/server/lib/access-control"); +const { resolvePermissions } = await import( + "@dokploy/server/services/permission" +); +const { enterpriseOnlyResources, statements } = await import( + "@dokploy/server/lib/access-control" +); const ctx = { user: { id: "user-1" }, diff --git a/apps/dokploy/__test__/permissions/service-access.test.ts b/apps/dokploy/__test__/permissions/service-access.test.ts index 7a1e20bc0..b3786807d 100644 --- a/apps/dokploy/__test__/permissions/service-access.test.ts +++ b/apps/dokploy/__test__/permissions/service-access.test.ts @@ -26,7 +26,8 @@ const mockMemberData = ( user: { id: "user-1", email: "test@test.com" }, }); -let memberToReturn: ReturnType = mockMemberData("member"); +let memberToReturn: ReturnType = + mockMemberData("member"); vi.mock("@dokploy/server/db", () => ({ db: { @@ -64,35 +65,45 @@ describe("checkServicePermissionAndAccess", () => { it("owner bypasses accessedServices check", async () => { memberToReturn = mockMemberData("owner", []); await expect( - checkServicePermissionAndAccess(ctx, "service-123", { deployment: ["read"] }), + checkServicePermissionAndAccess(ctx, "service-123", { + deployment: ["read"], + }), ).resolves.toBeUndefined(); }); it("admin bypasses accessedServices check", async () => { memberToReturn = mockMemberData("admin", []); await expect( - checkServicePermissionAndAccess(ctx, "service-123", { backup: ["create"] }), + checkServicePermissionAndAccess(ctx, "service-123", { + backup: ["create"], + }), ).resolves.toBeUndefined(); }); it("member with access to service passes", async () => { memberToReturn = mockMemberData("member", ["service-123"]); await expect( - checkServicePermissionAndAccess(ctx, "service-123", { deployment: ["read"] }), + checkServicePermissionAndAccess(ctx, "service-123", { + deployment: ["read"], + }), ).resolves.toBeUndefined(); }); it("member WITHOUT access to service fails", async () => { memberToReturn = mockMemberData("member", ["other-service"]); await expect( - checkServicePermissionAndAccess(ctx, "service-123", { deployment: ["read"] }), + checkServicePermissionAndAccess(ctx, "service-123", { + deployment: ["read"], + }), ).rejects.toThrow("You don't have access to this service"); }); it("member with empty accessedServices fails", async () => { memberToReturn = mockMemberData("member", []); await expect( - checkServicePermissionAndAccess(ctx, "service-123", { domain: ["delete"] }), + checkServicePermissionAndAccess(ctx, "service-123", { + domain: ["delete"], + }), ).rejects.toThrow("You don't have access to this service"); }); }); @@ -100,7 +111,9 @@ describe("checkServicePermissionAndAccess", () => { describe("checkServiceAccess", () => { it("member with service access passes read check", async () => { memberToReturn = mockMemberData("member", ["app-1"]); - await expect(checkServiceAccess(ctx, "app-1", "read")).resolves.toBeUndefined(); + await expect( + checkServiceAccess(ctx, "app-1", "read"), + ).resolves.toBeUndefined(); }); it("member without service access fails read check", async () => { @@ -112,6 +125,8 @@ describe("checkServiceAccess", () => { it("owner bypasses all access checks", async () => { memberToReturn = mockMemberData("owner", [], []); - await expect(checkServiceAccess(ctx, "project-1", "create")).resolves.toBeUndefined(); + await expect( + checkServiceAccess(ctx, "project-1", "create"), + ).resolves.toBeUndefined(); }); }); diff --git a/packages/server/auth-schema2.ts b/packages/server/auth-schema2.ts index 6eec45f53..9c163c820 100644 --- a/packages/server/auth-schema2.ts +++ b/packages/server/auth-schema2.ts @@ -1,299 +1,299 @@ import { relations } from "drizzle-orm"; import { - pgTable, - text, - timestamp, - boolean, - integer, - index, - uniqueIndex, + pgTable, + text, + timestamp, + boolean, + integer, + index, + uniqueIndex, } from "drizzle-orm/pg-core"; export const user = pgTable("user", { - id: text("id").primaryKey(), - firstName: text("first_name").notNull(), - email: text("email").notNull().unique(), - emailVerified: boolean("email_verified").default(false).notNull(), - image: text("image"), - createdAt: timestamp("created_at").defaultNow().notNull(), - updatedAt: timestamp("updated_at") - .defaultNow() - .$onUpdate(() => /* @__PURE__ */ new Date()) - .notNull(), - twoFactorEnabled: boolean("two_factor_enabled").default(false), - role: text("role"), - ownerId: text("owner_id"), - allowImpersonation: boolean("allow_impersonation").default(false), - lastName: text("last_name").default(""), - enableEnterpriseFeatures: boolean("enable_enterprise_features"), - isValidEnterpriseLicense: boolean("is_valid_enterprise_license"), + id: text("id").primaryKey(), + firstName: text("first_name").notNull(), + email: text("email").notNull().unique(), + emailVerified: boolean("email_verified").default(false).notNull(), + image: text("image"), + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at") + .defaultNow() + .$onUpdate(() => /* @__PURE__ */ new Date()) + .notNull(), + twoFactorEnabled: boolean("two_factor_enabled").default(false), + role: text("role"), + ownerId: text("owner_id"), + allowImpersonation: boolean("allow_impersonation").default(false), + lastName: text("last_name").default(""), + enableEnterpriseFeatures: boolean("enable_enterprise_features"), + isValidEnterpriseLicense: boolean("is_valid_enterprise_license"), }); export const session = pgTable( - "session", - { - id: text("id").primaryKey(), - expiresAt: timestamp("expires_at").notNull(), - token: text("token").notNull().unique(), - createdAt: timestamp("created_at").defaultNow().notNull(), - updatedAt: timestamp("updated_at") - .$onUpdate(() => /* @__PURE__ */ new Date()) - .notNull(), - ipAddress: text("ip_address"), - userAgent: text("user_agent"), - userId: text("user_id") - .notNull() - .references(() => user.id, { onDelete: "cascade" }), - activeOrganizationId: text("active_organization_id"), - }, - (table) => [index("session_userId_idx").on(table.userId)], + "session", + { + id: text("id").primaryKey(), + expiresAt: timestamp("expires_at").notNull(), + token: text("token").notNull().unique(), + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at") + .$onUpdate(() => /* @__PURE__ */ new Date()) + .notNull(), + ipAddress: text("ip_address"), + userAgent: text("user_agent"), + userId: text("user_id") + .notNull() + .references(() => user.id, { onDelete: "cascade" }), + activeOrganizationId: text("active_organization_id"), + }, + (table) => [index("session_userId_idx").on(table.userId)], ); export const account = pgTable( - "account", - { - id: text("id").primaryKey(), - accountId: text("account_id").notNull(), - providerId: text("provider_id").notNull(), - userId: text("user_id") - .notNull() - .references(() => user.id, { onDelete: "cascade" }), - accessToken: text("access_token"), - refreshToken: text("refresh_token"), - idToken: text("id_token"), - accessTokenExpiresAt: timestamp("access_token_expires_at"), - refreshTokenExpiresAt: timestamp("refresh_token_expires_at"), - scope: text("scope"), - password: text("password"), - createdAt: timestamp("created_at").defaultNow().notNull(), - updatedAt: timestamp("updated_at") - .$onUpdate(() => /* @__PURE__ */ new Date()) - .notNull(), - }, - (table) => [index("account_userId_idx").on(table.userId)], + "account", + { + id: text("id").primaryKey(), + accountId: text("account_id").notNull(), + providerId: text("provider_id").notNull(), + userId: text("user_id") + .notNull() + .references(() => user.id, { onDelete: "cascade" }), + accessToken: text("access_token"), + refreshToken: text("refresh_token"), + idToken: text("id_token"), + accessTokenExpiresAt: timestamp("access_token_expires_at"), + refreshTokenExpiresAt: timestamp("refresh_token_expires_at"), + scope: text("scope"), + password: text("password"), + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at") + .$onUpdate(() => /* @__PURE__ */ new Date()) + .notNull(), + }, + (table) => [index("account_userId_idx").on(table.userId)], ); export const verification = pgTable( - "verification", - { - id: text("id").primaryKey(), - identifier: text("identifier").notNull(), - value: text("value").notNull(), - expiresAt: timestamp("expires_at").notNull(), - createdAt: timestamp("created_at").defaultNow().notNull(), - updatedAt: timestamp("updated_at") - .defaultNow() - .$onUpdate(() => /* @__PURE__ */ new Date()) - .notNull(), - }, - (table) => [index("verification_identifier_idx").on(table.identifier)], + "verification", + { + id: text("id").primaryKey(), + identifier: text("identifier").notNull(), + value: text("value").notNull(), + expiresAt: timestamp("expires_at").notNull(), + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at") + .defaultNow() + .$onUpdate(() => /* @__PURE__ */ new Date()) + .notNull(), + }, + (table) => [index("verification_identifier_idx").on(table.identifier)], ); export const apikey = pgTable( - "apikey", - { - id: text("id").primaryKey(), - configId: text("config_id").default("default").notNull(), - name: text("name"), - start: text("start"), - referenceId: text("reference_id").notNull(), - prefix: text("prefix"), - key: text("key").notNull(), - refillInterval: integer("refill_interval"), - refillAmount: integer("refill_amount"), - lastRefillAt: timestamp("last_refill_at"), - enabled: boolean("enabled").default(true), - rateLimitEnabled: boolean("rate_limit_enabled").default(true), - rateLimitTimeWindow: integer("rate_limit_time_window").default(86400000), - rateLimitMax: integer("rate_limit_max").default(10), - requestCount: integer("request_count").default(0), - remaining: integer("remaining"), - lastRequest: timestamp("last_request"), - expiresAt: timestamp("expires_at"), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), - permissions: text("permissions"), - metadata: text("metadata"), - }, - (table) => [ - index("apikey_configId_idx").on(table.configId), - index("apikey_referenceId_idx").on(table.referenceId), - index("apikey_key_idx").on(table.key), - ], + "apikey", + { + id: text("id").primaryKey(), + configId: text("config_id").default("default").notNull(), + name: text("name"), + start: text("start"), + referenceId: text("reference_id").notNull(), + prefix: text("prefix"), + key: text("key").notNull(), + refillInterval: integer("refill_interval"), + refillAmount: integer("refill_amount"), + lastRefillAt: timestamp("last_refill_at"), + enabled: boolean("enabled").default(true), + rateLimitEnabled: boolean("rate_limit_enabled").default(true), + rateLimitTimeWindow: integer("rate_limit_time_window").default(86400000), + rateLimitMax: integer("rate_limit_max").default(10), + requestCount: integer("request_count").default(0), + remaining: integer("remaining"), + lastRequest: timestamp("last_request"), + expiresAt: timestamp("expires_at"), + createdAt: timestamp("created_at").notNull(), + updatedAt: timestamp("updated_at").notNull(), + permissions: text("permissions"), + metadata: text("metadata"), + }, + (table) => [ + index("apikey_configId_idx").on(table.configId), + index("apikey_referenceId_idx").on(table.referenceId), + index("apikey_key_idx").on(table.key), + ], ); export const ssoProvider = pgTable("sso_provider", { - id: text("id").primaryKey(), - issuer: text("issuer").notNull(), - oidcConfig: text("oidc_config"), - samlConfig: text("saml_config"), - userId: text("user_id").references(() => user.id, { onDelete: "cascade" }), - providerId: text("provider_id").notNull().unique(), - organizationId: text("organization_id"), - domain: text("domain").notNull(), + id: text("id").primaryKey(), + issuer: text("issuer").notNull(), + oidcConfig: text("oidc_config"), + samlConfig: text("saml_config"), + userId: text("user_id").references(() => user.id, { onDelete: "cascade" }), + providerId: text("provider_id").notNull().unique(), + organizationId: text("organization_id"), + domain: text("domain").notNull(), }); export const twoFactor = pgTable( - "two_factor", - { - id: text("id").primaryKey(), - secret: text("secret").notNull(), - backupCodes: text("backup_codes").notNull(), - userId: text("user_id") - .notNull() - .references(() => user.id, { onDelete: "cascade" }), - }, - (table) => [ - index("twoFactor_secret_idx").on(table.secret), - index("twoFactor_userId_idx").on(table.userId), - ], + "two_factor", + { + id: text("id").primaryKey(), + secret: text("secret").notNull(), + backupCodes: text("backup_codes").notNull(), + userId: text("user_id") + .notNull() + .references(() => user.id, { onDelete: "cascade" }), + }, + (table) => [ + index("twoFactor_secret_idx").on(table.secret), + index("twoFactor_userId_idx").on(table.userId), + ], ); export const organization = pgTable( - "organization", - { - id: text("id").primaryKey(), - name: text("name").notNull(), - slug: text("slug").notNull().unique(), - logo: text("logo"), - createdAt: timestamp("created_at").notNull(), - metadata: text("metadata"), - }, - (table) => [uniqueIndex("organization_slug_uidx").on(table.slug)], + "organization", + { + id: text("id").primaryKey(), + name: text("name").notNull(), + slug: text("slug").notNull().unique(), + logo: text("logo"), + createdAt: timestamp("created_at").notNull(), + metadata: text("metadata"), + }, + (table) => [uniqueIndex("organization_slug_uidx").on(table.slug)], ); export const organizationRole = pgTable( - "organization_role", - { - id: text("id").primaryKey(), - organizationId: text("organization_id") - .notNull() - .references(() => organization.id, { onDelete: "cascade" }), - role: text("role").notNull(), - permission: text("permission").notNull(), - createdAt: timestamp("created_at").defaultNow().notNull(), - updatedAt: timestamp("updated_at").$onUpdate( - () => /* @__PURE__ */ new Date(), - ), - }, - (table) => [ - index("organizationRole_organizationId_idx").on(table.organizationId), - index("organizationRole_role_idx").on(table.role), - ], + "organization_role", + { + id: text("id").primaryKey(), + organizationId: text("organization_id") + .notNull() + .references(() => organization.id, { onDelete: "cascade" }), + role: text("role").notNull(), + permission: text("permission").notNull(), + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at").$onUpdate( + () => /* @__PURE__ */ new Date(), + ), + }, + (table) => [ + index("organizationRole_organizationId_idx").on(table.organizationId), + index("organizationRole_role_idx").on(table.role), + ], ); export const member = pgTable( - "member", - { - id: text("id").primaryKey(), - organizationId: text("organization_id") - .notNull() - .references(() => organization.id, { onDelete: "cascade" }), - userId: text("user_id") - .notNull() - .references(() => user.id, { onDelete: "cascade" }), - role: text("role").default("member").notNull(), - createdAt: timestamp("created_at").notNull(), - }, - (table) => [ - index("member_organizationId_idx").on(table.organizationId), - index("member_userId_idx").on(table.userId), - ], + "member", + { + id: text("id").primaryKey(), + organizationId: text("organization_id") + .notNull() + .references(() => organization.id, { onDelete: "cascade" }), + userId: text("user_id") + .notNull() + .references(() => user.id, { onDelete: "cascade" }), + role: text("role").default("member").notNull(), + createdAt: timestamp("created_at").notNull(), + }, + (table) => [ + index("member_organizationId_idx").on(table.organizationId), + index("member_userId_idx").on(table.userId), + ], ); export const invitation = pgTable( - "invitation", - { - id: text("id").primaryKey(), - organizationId: text("organization_id") - .notNull() - .references(() => organization.id, { onDelete: "cascade" }), - email: text("email").notNull(), - role: text("role"), - status: text("status").default("pending").notNull(), - expiresAt: timestamp("expires_at").notNull(), - createdAt: timestamp("created_at").defaultNow().notNull(), - inviterId: text("inviter_id") - .notNull() - .references(() => user.id, { onDelete: "cascade" }), - }, - (table) => [ - index("invitation_organizationId_idx").on(table.organizationId), - index("invitation_email_idx").on(table.email), - ], + "invitation", + { + id: text("id").primaryKey(), + organizationId: text("organization_id") + .notNull() + .references(() => organization.id, { onDelete: "cascade" }), + email: text("email").notNull(), + role: text("role"), + status: text("status").default("pending").notNull(), + expiresAt: timestamp("expires_at").notNull(), + createdAt: timestamp("created_at").defaultNow().notNull(), + inviterId: text("inviter_id") + .notNull() + .references(() => user.id, { onDelete: "cascade" }), + }, + (table) => [ + index("invitation_organizationId_idx").on(table.organizationId), + index("invitation_email_idx").on(table.email), + ], ); export const userRelations = relations(user, ({ many }) => ({ - sessions: many(session), - accounts: many(account), - ssoProviders: many(ssoProvider), - twoFactors: many(twoFactor), - members: many(member), - invitations: many(invitation), + sessions: many(session), + accounts: many(account), + ssoProviders: many(ssoProvider), + twoFactors: many(twoFactor), + members: many(member), + invitations: many(invitation), })); export const sessionRelations = relations(session, ({ one }) => ({ - user: one(user, { - fields: [session.userId], - references: [user.id], - }), + user: one(user, { + fields: [session.userId], + references: [user.id], + }), })); export const accountRelations = relations(account, ({ one }) => ({ - user: one(user, { - fields: [account.userId], - references: [user.id], - }), + user: one(user, { + fields: [account.userId], + references: [user.id], + }), })); export const ssoProviderRelations = relations(ssoProvider, ({ one }) => ({ - user: one(user, { - fields: [ssoProvider.userId], - references: [user.id], - }), + user: one(user, { + fields: [ssoProvider.userId], + references: [user.id], + }), })); export const twoFactorRelations = relations(twoFactor, ({ one }) => ({ - user: one(user, { - fields: [twoFactor.userId], - references: [user.id], - }), + user: one(user, { + fields: [twoFactor.userId], + references: [user.id], + }), })); export const organizationRelations = relations(organization, ({ many }) => ({ - organizationRoles: many(organizationRole), - members: many(member), - invitations: many(invitation), + organizationRoles: many(organizationRole), + members: many(member), + invitations: many(invitation), })); export const organizationRoleRelations = relations( - organizationRole, - ({ one }) => ({ - organization: one(organization, { - fields: [organizationRole.organizationId], - references: [organization.id], - }), - }), + organizationRole, + ({ one }) => ({ + organization: one(organization, { + fields: [organizationRole.organizationId], + references: [organization.id], + }), + }), ); export const memberRelations = relations(member, ({ one }) => ({ - organization: one(organization, { - fields: [member.organizationId], - references: [organization.id], - }), - user: one(user, { - fields: [member.userId], - references: [user.id], - }), + organization: one(organization, { + fields: [member.organizationId], + references: [organization.id], + }), + user: one(user, { + fields: [member.userId], + references: [user.id], + }), })); export const invitationRelations = relations(invitation, ({ one }) => ({ - organization: one(organization, { - fields: [invitation.organizationId], - references: [organization.id], - }), - user: one(user, { - fields: [invitation.inviterId], - references: [user.id], - }), + organization: one(organization, { + fields: [invitation.organizationId], + references: [organization.id], + }), + user: one(user, { + fields: [invitation.inviterId], + references: [user.id], + }), })); diff --git a/packages/server/src/db/schema/account.ts b/packages/server/src/db/schema/account.ts index 7bdbf0741..5d8bfb99d 100644 --- a/packages/server/src/db/schema/account.ts +++ b/packages/server/src/db/schema/account.ts @@ -125,7 +125,9 @@ export const member = pgTable("member", { userId: text("user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), - role: text("role").notNull().$type<"owner" | "member" | "admin" | (string & {})>(), + role: text("role") + .notNull() + .$type<"owner" | "member" | "admin" | (string & {})>(), createdAt: timestamp("created_at").notNull(), teamId: text("team_id"), isDefault: boolean("is_default").notNull().default(false), diff --git a/packages/server/src/services/permission.ts b/packages/server/src/services/permission.ts index 2c6854ff1..4a4800495 100644 --- a/packages/server/src/services/permission.ts +++ b/packages/server/src/services/permission.ts @@ -265,10 +265,7 @@ export const checkServiceAccess = async ( await checkPermission(ctx, { service: [action] }); - if ( - memberRecord.role !== "owner" && - memberRecord.role !== "admin" - ) { + if (memberRecord.role !== "owner" && memberRecord.role !== "admin") { if (action === "create") { if (!memberRecord.accessedProjects.includes(serviceId)) { throw new TRPCError({ @@ -352,10 +349,7 @@ export const checkEnvironmentDeletionPermission = async ( } }; -export const addNewProject = async ( - ctx: PermissionCtx, - projectId: string, -) => { +export const addNewProject = async (ctx: PermissionCtx, projectId: string) => { const userId = ctx.user.id; const organizationId = ctx.session.activeOrganizationId; const memberRecord = await findMemberByUserId(userId, organizationId); @@ -395,10 +389,7 @@ export const addNewEnvironment = async ( ); }; -export const addNewService = async ( - ctx: PermissionCtx, - serviceId: string, -) => { +export const addNewService = async (ctx: PermissionCtx, serviceId: string) => { const userId = ctx.user.id; const organizationId = ctx.session.activeOrganizationId; const memberRecord = await findMemberByUserId(userId, organizationId); diff --git a/packages/server/src/services/proprietary/audit-log.ts b/packages/server/src/services/proprietary/audit-log.ts index 66526b8ee..157e75c9b 100644 --- a/packages/server/src/services/proprietary/audit-log.ts +++ b/packages/server/src/services/proprietary/audit-log.ts @@ -74,7 +74,8 @@ export const getAuditLogs = async (input: GetAuditLogsInput) => { if (userId) conditions.push(eq(auditLog.userId, userId)); if (userEmail) conditions.push(ilike(auditLog.userEmail, `%${userEmail}%`)); - if (resourceName) conditions.push(ilike(auditLog.resourceName, `%${resourceName}%`)); + if (resourceName) + conditions.push(ilike(auditLog.resourceName, `%${resourceName}%`)); if (action) conditions.push(eq(auditLog.action, action)); if (resourceType) conditions.push(eq(auditLog.resourceType, resourceType)); if (from) conditions.push(gte(auditLog.createdAt, from));