From 3adfbb57bda7a66941d648e40c0947ad1f953bbf Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Sat, 4 Oct 2025 13:06:17 +0000 Subject: [PATCH] Preserve Cloudinary configuration on settings update Modify Cloudinary configuration endpoint to allow partial updates and preserve existing API keys and secrets when not explicitly provided, and clear input fields on successful save. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ae4037a0-2a6f-4530-9bac-79b543286bda Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/397bca8c-984f-43ff-841a-10897aeb8140/ae4037a0-2a6f-4530-9bac-79b543286bda/sEXz3DF --- client/src/pages/settings.tsx | 20 +++++++++++++++----- server/routes.ts | 27 ++++++++++++++++++++------- shared/schema.ts | 7 +++++++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/client/src/pages/settings.tsx b/client/src/pages/settings.tsx index 0a13a7e..b9aa3c4 100644 --- a/client/src/pages/settings.tsx +++ b/client/src/pages/settings.tsx @@ -55,18 +55,28 @@ export default function Settings() { const hasExistingConfig = !!openrouterConfig; const saveCloudinaryMutation = useMutation({ - mutationFn: () => - apiRequest('POST', '/api/cloudinary/config', { + mutationFn: () => { + const payload: any = { cloudName, - apiKey, - apiSecret, - }), + }; + + // N'inclure apiKey et apiSecret que s'ils ne sont pas vides + if (apiKey && apiKey.trim() !== "") { + payload.apiKey = apiKey; + } + if (apiSecret && apiSecret.trim() !== "") { + payload.apiSecret = apiSecret; + } + + return apiRequest('POST', '/api/cloudinary/config', payload); + }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['/api/cloudinary/config'] }); toast({ title: "Configuration sauvegardée", description: "Vos paramètres Cloudinary ont été enregistrés", }); + setApiKey(""); // Clear the API key after saving setApiSecret(""); // Clear the secret after saving }, onError: () => { diff --git a/server/routes.ts b/server/routes.ts index 22afc99..4075ff7 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -8,7 +8,7 @@ import passport from "./auth"; import { z } from "zod"; import { openRouterService } from "./services/openrouter"; import { cloudinaryService } from "./services/cloudinary"; -import { insertPostSchema, insertScheduledPostSchema, insertSocialPageSchema, insertAiGenerationSchema, insertCloudinaryConfigSchema, insertOpenrouterConfigSchema, updateOpenrouterConfigSchema, insertUserSchema, postMedia } from "@shared/schema"; +import { insertPostSchema, insertScheduledPostSchema, insertSocialPageSchema, insertAiGenerationSchema, insertCloudinaryConfigSchema, updateCloudinaryConfigSchema, insertOpenrouterConfigSchema, updateOpenrouterConfigSchema, insertUserSchema, postMedia } from "@shared/schema"; import type { User, InsertUser } from "@shared/schema"; const upload = multer({ storage: multer.memoryStorage() }); @@ -618,18 +618,31 @@ export async function registerRoutes(app: Express): Promise { const user = req.user as User; const userId = user.id; - const configData = insertCloudinaryConfigSchema.parse({ - ...req.body, - userId, - }); - // Check if config already exists const existingConfig = await storage.getCloudinaryConfig(userId); let config; if (existingConfig) { - config = await storage.updateCloudinaryConfig(userId, configData); + // Pour les mises à jour, utiliser le schéma qui rend les secrets optionnels + const updateData = updateCloudinaryConfigSchema.parse({ + ...req.body, + userId, + }); + + // Si apiKey/apiSecret ne sont pas fournis, garder les anciens + const finalData = { + ...updateData, + apiKey: updateData.apiKey || existingConfig.apiKey, + apiSecret: updateData.apiSecret || existingConfig.apiSecret, + }; + + config = await storage.updateCloudinaryConfig(userId, finalData); } else { + // Pour les créations, exiger tous les champs + const configData = insertCloudinaryConfigSchema.parse({ + ...req.body, + userId, + }); config = await storage.createCloudinaryConfig(configData); } diff --git a/shared/schema.ts b/shared/schema.ts index c50590b..c2ea279 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -230,6 +230,11 @@ export const updateOpenrouterConfigSchema = insertOpenrouterConfigSchema.partial apiKey: true, }); +export const updateCloudinaryConfigSchema = insertCloudinaryConfigSchema.partial({ + apiKey: true, + apiSecret: true, +}); + // Types export type User = typeof users.$inferSelect; export type InsertUser = z.infer; @@ -251,8 +256,10 @@ export type InsertAiGeneration = z.infer; export type CloudinaryConfig = typeof cloudinaryConfig.$inferSelect; export type InsertCloudinaryConfig = z.infer; +export type UpdateCloudinaryConfig = z.infer; export type OpenrouterConfig = typeof openrouterConfig.$inferSelect; export type InsertOpenrouterConfig = z.infer; +export type UpdateOpenrouterConfig = z.infer; export type PostMedia = typeof postMedia.$inferSelect;