import type { AuthenticatedRequest } from "../../../types/index.js"; import express, { type Request, type Response } from "express"; import { databaseLogger } from "../../utils/logger.js"; import { AuthManager } from "../../utils/auth-manager.js"; import { createCurrentCredentialSidebarPreferenceRepository } from "../repositories/factory.js"; import { defaultCredentialSidebarPreferences, sanitizeCredentialSidebarPreferences, } from "../../../types/credential-sidebar-preferences.js"; const router = express.Router(); const authManager = AuthManager.getInstance(); const authenticateJWT = authManager.createAuthMiddleware(); /** * @openapi * /credential-sidebar/preferences: * get: * summary: Get the credential sidebar preferences for the current user * description: Returns the current user's saved credential sidebar preferences (sort, filters, open folders, display settings). Unlike /host-sidebar/preferences, there is no legacy-column migration to perform here — credentials never had exploded preference columns on userPreferences — so a first-time GET simply returns the defaults without writing a row; a row is only created once the user actually changes something via PUT. * tags: * - Credential Sidebar * responses: * 200: * description: The current user's credential sidebar preferences. */ router.get("/", authenticateJWT, async (req: Request, res: Response) => { const userId = (req as AuthenticatedRequest).userId; try { const existing = await createCurrentCredentialSidebarPreferenceRepository().findByUserId( userId, ); if (existing) { const preferences = sanitizeCredentialSidebarPreferences( JSON.parse(existing.data), ); return res.json({ preferences }); } return res.json({ preferences: defaultCredentialSidebarPreferences() }); } catch (e) { databaseLogger.error("Failed to get credential sidebar preferences", e, { operation: "get_credential_sidebar_preferences", userId, }); return res .status(500) .json({ error: "Failed to get credential sidebar preferences" }); } }); /** * @openapi * /credential-sidebar/preferences: * put: * summary: Update the credential sidebar preferences for the current user * description: Persists the current user's credential sidebar preferences (sort, filters, open folders, display settings) as a single JSON document. * tags: * - Credential Sidebar * requestBody: * required: true * content: * application/json: * schema: * type: object * responses: * 200: * description: Preferences updated successfully. * 400: * description: Invalid preferences payload. */ router.put("/", authenticateJWT, async (req: Request, res: Response) => { const userId = (req as AuthenticatedRequest).userId; if (!req.body || typeof req.body !== "object") { return res.status(400).json({ error: "Invalid preferences payload" }); } try { const existing = await createCurrentCredentialSidebarPreferenceRepository().findByUserId( userId, ); const base = existing ? sanitizeCredentialSidebarPreferences(JSON.parse(existing.data)) : defaultCredentialSidebarPreferences(); const merged = sanitizeCredentialSidebarPreferences({ ...base, ...req.body, display: { ...base.display, ...(req.body.display ?? {}) }, sort: { ...base.sort, ...(req.body.sort ?? {}) }, filters: { ...base.filters, ...(req.body.filters ?? {}) }, }); await createCurrentCredentialSidebarPreferenceRepository().upsert( userId, JSON.stringify(merged), ); return res.json({ success: true, preferences: merged }); } catch (e) { databaseLogger.error("Failed to update credential sidebar preferences", e, { operation: "update_credential_sidebar_preferences", userId, }); return res .status(500) .json({ error: "Failed to update credential sidebar preferences" }); } }); export default router;