fix: harden permissions system after code review

- Gate permissions in /app-config behind optionalAuth so unauthenticated
  requests don't receive admin configuration
- Fix trip_delete isMember parameter (was hardcoded false)
- Return skipped keys from savePermissions for admin visibility
- Add disabled prop to CustomSelect, use in BudgetPanel currency picker
- Fix CollabChat reaction handler returning false instead of void
- Pass canUploadFiles as prop to NoteFormModal instead of internal store read
- Make edit-only NoteFormModal props optional (onDeleteFile, note, tripId)
- Add missing trailing newlines to .gitignore and it.ts
This commit is contained in:
Gérnyi Márk
2026-03-31 23:33:27 +02:00
parent 1ff8546484
commit 23edfe3dfc
10 changed files with 35 additions and 24 deletions

View File

@@ -10,13 +10,13 @@ import fetch from 'node-fetch';
import { authenticator } from 'otplib';
import QRCode from 'qrcode';
import { db } from '../db/database';
import { authenticate, demoUploadBlock } from '../middleware/auth';
import { authenticate, optionalAuth, demoUploadBlock } from '../middleware/auth';
import { JWT_SECRET } from '../config';
import { encryptMfaSecret, decryptMfaSecret } from '../services/mfaCrypto';
import { getAllPermissions } from '../services/permissions';
import { randomBytes, createHash } from 'crypto';
import { revokeUserSessions } from '../mcp';
import { AuthRequest, User } from '../types';
import { AuthRequest, OptionalAuthRequest, User } from '../types';
import { writeAudit, getClientIp } from '../services/auditLog';
import { decrypt_api_key, maybe_encrypt_api_key } from '../services/apiKeyCrypto';
import { startTripReminders } from '../scheduler';
@@ -171,7 +171,7 @@ function generateToken(user: { id: number | bigint }) {
);
}
router.get('/app-config', (_req: Request, res: Response) => {
router.get('/app-config', optionalAuth, (req: Request, res: Response) => {
const userCount = (db.prepare('SELECT COUNT(*) as count FROM users').get() as { count: number }).count;
const setting = db.prepare("SELECT value FROM app_settings WHERE key = 'allow_registration'").get() as { value: string } | undefined;
const allowRegistration = userCount === 0 || (setting?.value ?? 'true') === 'true';
@@ -210,7 +210,7 @@ router.get('/app-config', (_req: Request, res: Response) => {
timezone: process.env.TZ || Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC',
notification_channel: notifChannel,
trip_reminders_enabled: tripRemindersEnabled,
permissions: getAllPermissions(),
permissions: (req as OptionalAuthRequest).user ? getAllPermissions() : undefined,
});
});