fix(tool-config): merge partial updates instead of replacing, mask bot_app_password

This commit is contained in:
Matthias Hochmeister
2026-04-17 09:30:13 +02:00
parent 7532a19326
commit 510b44e48c
2 changed files with 15 additions and 2 deletions

View File

@@ -10,7 +10,7 @@ const TOOL_SETTINGS_KEYS: Record<string, string> = {
nextcloud: 'tool_config_nextcloud',
};
const MASKED_FIELDS = ['tokenSecret', 'apiToken'];
const MASKED_FIELDS = ['tokenSecret', 'apiToken', 'bot_app_password'];
function maskValue(value: string): string {
if (!value || value.length <= 4) return '****';
@@ -98,7 +98,16 @@ class ToolConfigController {
try {
const userId = req.user!.id;
await settingsService.set(settingsKey, req.body, userId);
const existing = await settingsService.get(settingsKey);
const current = existing?.value && typeof existing.value === 'object' ? existing.value as Record<string, unknown> : {};
const incoming: Record<string, unknown> = { ...req.body };
for (const key of Object.keys(incoming)) {
if (typeof incoming[key] === 'string' && /^\*+/.test(incoming[key] as string)) {
delete incoming[key];
}
}
const merged = { ...current, ...incoming };
await settingsService.set(settingsKey, merged, userId);
toolConfigService.clearCache();
res.status(200).json({ success: true, message: 'Konfiguration gespeichert' });
} catch (error) {

View File

@@ -14,6 +14,8 @@ export interface VikunjaConfig {
export interface NextcloudConfig {
url: string;
bot_username?: string;
bot_app_password?: string;
}
interface CacheEntry<T> {
@@ -72,6 +74,8 @@ async function getNextcloudConfig(): Promise<NextcloudConfig> {
const db = await getDbConfig('tool_config_nextcloud');
const config: NextcloudConfig = {
url: db.url || environment.nextcloudUrl,
bot_username: db.bot_username || undefined,
bot_app_password: db.bot_app_password || undefined,
};
nextcloudCache = { data: config, expiresAt: Date.now() + CACHE_TTL_MS };