fix(server): consolidate allowed_file_types onto AllowedFileTypesService

This commit is contained in:
jubnl
2026-08-16 09:49:46 +02:00
parent c75d431e4c
commit b72645272b
10 changed files with 45 additions and 20 deletions
+2
View File
@@ -23,6 +23,7 @@ import { StorageModule } from '../storage/storage.module';
import { StorageService } from '../storage/storage.service';
import { buildStorageUploadOptions } from '../storage/storage-upload.factory';
import { AVATAR_FILE_FILTER, MAX_AVATAR_SIZE } from './auth.controller';
import { AllowedFileTypesModule } from '../files/allowed-file-types.module';
/**
* Auth module — public flows (login/register/reset/mfa-verify/logout) and the
@@ -60,6 +61,7 @@ import { AVATAR_FILE_FILTER, MAX_AVATAR_SIZE } from './auth.controller';
}),
}),
StorageModule,
AllowedFileTypesModule,
EphemeralTokenModule, RateLimitModule, AuditModule, PermissionsModule, TripMembershipModule, MailerModule, AppConfigModule, TokensModule, BudgetModule],
controllers: [AuthPublicController, AuthController, PasskeyController],
providers: [AuthService, UserProfileService, RegistrationInvitesService, PasskeyService, UserCleanupService, WebauthnConfigService, AuthMcp],
+7 -1
View File
@@ -30,6 +30,7 @@ import { TripMembershipService } from '../trip-membership/trip-membership.servic
import { WebauthnConfigService } from './webauthn-config.service';
import { setAuthCookie, clearAuthCookie } from '../common/cookie';
import { MailerService } from '../notifications/mailer/mailer.service';
import { AllowedFileTypesService } from '../files/allowed-file-types.service';
import { getAppUrl } from '../../app-config';
import {
ADMIN_SETTINGS_KEYS,
@@ -127,6 +128,7 @@ export class AuthService {
private readonly userCleanup: UserCleanupService,
private readonly mailer: MailerService,
private readonly tokens: EphemeralTokenService,
private readonly allowedFileTypes: AllowedFileTypesService,
) {}
// Cookie
@@ -290,7 +292,11 @@ export class AuthService {
oidc_configured: oidcConfigured,
oidc_display_name: oidcConfigured ? (oidcDisplayName || 'SSO') : undefined,
require_mfa: requireMfaRow?.value === 'true',
allowed_file_types: this.db.get<{ value: string }>("SELECT value FROM app_settings WHERE key = 'allowed_file_types'")?.value || 'jpg,jpeg,png,gif,webp,heic,pdf,doc,docx,xls,xlsx,txt,csv',
// The canonical live-read: same query + DEFAULT_ALLOWED_EXTENSIONS
// fallback the upload filters use, so the client's picker and the
// server's acceptance can never drift (the historical inline copy here
// dropped pkpass, pkpasses, md and markdown).
allowed_file_types: this.allowedFileTypes.get(),
// Whether the configuration belongs to whoever operates this install
// rather than to its admin. The client uses it to stop offering settings
// the server would refuse anyway — it is an honesty flag for the UI, never
+3 -10
View File
@@ -45,9 +45,9 @@ export interface FileLink {
* DatabaseService's canAccessTrip (the legacy verifyTripAccess re-export was a
* plain wrapper over the same helper); the file_* permissions, path-resolution
* guard, download-token auth and WebSocket broadcasts are unchanged. The
* load-time constants live in files.constants.ts; the one out-of-DI consumer
* path (module-scope multer configs) reaches getAllowedExtensions through
* files.bridge.ts.
* load-time constants live in files.constants.ts; the admin allowed-types
* live-read is AllowedFileTypesService (the single query owner since the
* storage slice-2 consolidation).
*
* Two deliberate post-migration fixes over the legacy behavior: createFileLink
* no longer swallows insert errors, and updateFile coerces an empty-string
@@ -74,13 +74,6 @@ export class FilesService {
this.realtime.broadcast(tripId, event, payload, socketId);
}
getAllowedExtensions(): string {
try {
const row = this.db.get<{ value: string }>("SELECT value FROM app_settings WHERE key = 'allowed_file_types'");
return row?.value || DEFAULT_ALLOWED_EXTENSIONS;
} catch { return DEFAULT_ALLOWED_EXTENSIONS; }
}
// ---------------------------------------------------------------------------
// Token-based download auth & safe path resolution (used by the unguarded
// download route)