mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-20 15:35:23 +00:00
fix(permissions): mask apiKey on ai.one, add audit logging, remove dead endpoint
This commit is contained in:
@@ -15,6 +15,8 @@ import {
|
||||
getAiSettingById,
|
||||
getAiSettingsByOrganizationId,
|
||||
getCustomAiProviders,
|
||||
maskAiApiKey,
|
||||
mergeAiApiKey,
|
||||
saveAiSettings,
|
||||
saveCustomAiProviders,
|
||||
suggestVariants,
|
||||
@@ -41,16 +43,18 @@ import {
|
||||
withAnyPermission,
|
||||
withPermission,
|
||||
} from "@/server/api/trpc";
|
||||
import { audit } from "@/server/api/utils/audit";
|
||||
import { generatePassword } from "@/templates/utils";
|
||||
|
||||
export const aiRouter = createTRPCRouter({
|
||||
one: withAnyPermission("ai", ["read", "update"])
|
||||
.input(z.object({ aiId: z.string() }))
|
||||
.query(async ({ input, ctx }) => {
|
||||
return await getAiSettingById(
|
||||
const setting = await getAiSettingById(
|
||||
input.aiId,
|
||||
ctx.session.activeOrganizationId,
|
||||
);
|
||||
return maskAiApiKey(setting);
|
||||
}),
|
||||
|
||||
getModels: withAnyPermission("ai", ["read", "create", "update"])
|
||||
@@ -184,13 +188,39 @@ export const aiRouter = createTRPCRouter({
|
||||
create: withPermission("ai", "create")
|
||||
.input(apiCreateAi)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
return await saveAiSettings(ctx.session.activeOrganizationId, input);
|
||||
const result = await saveAiSettings(
|
||||
ctx.session.activeOrganizationId,
|
||||
input,
|
||||
);
|
||||
await audit(ctx, {
|
||||
action: "create",
|
||||
resourceType: "ai",
|
||||
resourceName: input.name,
|
||||
});
|
||||
return result;
|
||||
}),
|
||||
|
||||
update: withPermission("ai", "update")
|
||||
.input(apiUpdateAi)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
return await saveAiSettings(ctx.session.activeOrganizationId, input);
|
||||
if (input.apiKey) {
|
||||
const existing = await getAiSettingById(
|
||||
input.aiId,
|
||||
ctx.session.activeOrganizationId,
|
||||
);
|
||||
input.apiKey = mergeAiApiKey(input.apiKey, existing.apiKey);
|
||||
}
|
||||
const result = await saveAiSettings(
|
||||
ctx.session.activeOrganizationId,
|
||||
input,
|
||||
);
|
||||
await audit(ctx, {
|
||||
action: "update",
|
||||
resourceType: "ai",
|
||||
resourceId: input.aiId,
|
||||
resourceName: input.name,
|
||||
});
|
||||
return result;
|
||||
}),
|
||||
|
||||
getAll: withAnyPermission("ai", ["read", "create", "update", "delete"]).query(
|
||||
@@ -202,22 +232,21 @@ export const aiRouter = createTRPCRouter({
|
||||
},
|
||||
),
|
||||
|
||||
get: withPermission("ai", "read")
|
||||
.input(z.object({ aiId: z.string() }))
|
||||
.query(async ({ input, ctx }) => {
|
||||
return await getAiSettingById(
|
||||
input.aiId,
|
||||
ctx.session.activeOrganizationId,
|
||||
);
|
||||
}),
|
||||
|
||||
delete: withPermission("ai", "delete")
|
||||
.input(z.object({ aiId: z.string() }))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
return await deleteAiSettings(
|
||||
const setting = await getAiSettingById(
|
||||
input.aiId,
|
||||
ctx.session.activeOrganizationId,
|
||||
);
|
||||
await deleteAiSettings(input.aiId, ctx.session.activeOrganizationId);
|
||||
await audit(ctx, {
|
||||
action: "delete",
|
||||
resourceType: "ai",
|
||||
resourceId: input.aiId,
|
||||
resourceName: setting.name,
|
||||
});
|
||||
return true;
|
||||
}),
|
||||
|
||||
getCustomProviders: withAnyPermission("ai", [
|
||||
|
||||
@@ -95,4 +95,5 @@ export type AuditResourceType =
|
||||
| "network"
|
||||
| "vaultProvider"
|
||||
| "dnsProvider"
|
||||
| "telemetryProvider";
|
||||
| "telemetryProvider"
|
||||
| "ai";
|
||||
|
||||
@@ -10,6 +10,16 @@ import { IS_CLOUD } from "../constants";
|
||||
import { findServerById } from "./server";
|
||||
import { getWebServerSettings } from "./web-server-settings";
|
||||
|
||||
export const AI_SECRET_MASK = "********";
|
||||
|
||||
export const maskAiApiKey = <T extends { apiKey: string }>(settings: T): T => ({
|
||||
...settings,
|
||||
apiKey: AI_SECRET_MASK,
|
||||
});
|
||||
|
||||
export const mergeAiApiKey = (incoming: string, existing: string): string =>
|
||||
incoming === AI_SECRET_MASK ? existing : incoming;
|
||||
|
||||
interface SuggestionItem {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user