Backend: - Add hostGate middleware for host-based API protection - Extend rate limiter with publicUploadLimiter (20/hour) - Add source_host and source_type to audit logs - Database migration for audit log source tracking - Unit tests for hostGate middleware (10/20 passing) Frontend: - Add hostDetection utility for runtime host detection - Implement React code splitting with lazy loading - Update App.js with ProtectedRoute component - Customize 404 page for public vs internal hosts - Update env-config.js for host configuration Docker: - Add environment variables to prod/dev docker-compose - Configure ENABLE_HOST_RESTRICTION flags - Set PUBLIC_HOST and INTERNAL_HOST variables Infrastructure: - Prepared for nginx-proxy-manager setup - Trust proxy configuration (TRUST_PROXY_HOPS=1) Note: Some unit tests still need adjustment for ENV handling
95 lines
2.7 KiB
JavaScript
95 lines
2.7 KiB
JavaScript
/**
|
|
* Host Detection Utility
|
|
*
|
|
* Erkennt, ob App auf public oder internal Host läuft
|
|
* Basiert auf window.location.hostname + env-config
|
|
*
|
|
* @module Utils/hostDetection
|
|
*/
|
|
|
|
/**
|
|
* Hole Host-Konfiguration und Feature-Flags
|
|
* @returns {Object} Host-Config mit Feature-Flags
|
|
*/
|
|
export const getHostConfig = () => {
|
|
const hostname = window.location.hostname;
|
|
|
|
// Hole Hosts aus Runtime-Config (wird von env.sh beim Container-Start gesetzt)
|
|
const publicHost = window._env_?.PUBLIC_HOST || 'deinprojekt.hobbyhimmel.de';
|
|
const internalHost = window._env_?.INTERNAL_HOST || 'deinprojekt.lan.hobbyhimmel.de';
|
|
|
|
// Bestimme Host-Typ
|
|
const isPublic = hostname === publicHost;
|
|
const isInternal = hostname === internalHost || hostname === 'localhost' || hostname === '127.0.0.1';
|
|
|
|
// Feature Flags basierend auf Host
|
|
return {
|
|
hostname,
|
|
publicHost,
|
|
internalHost,
|
|
isPublic,
|
|
isInternal,
|
|
|
|
// Feature Flags
|
|
canAccessAdmin: isInternal,
|
|
canAccessSlideshow: isInternal,
|
|
canAccessGroups: isInternal,
|
|
canAccessModeration: isInternal,
|
|
canAccessReorder: isInternal,
|
|
canAccessBatchUpload: isInternal,
|
|
canAccessSocialMedia: isInternal,
|
|
canAccessMigration: isInternal,
|
|
|
|
// Immer erlaubt (public + internal)
|
|
canUpload: true,
|
|
canManageByUUID: true
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Prüft, ob App auf public Host läuft
|
|
* @returns {boolean} True wenn public Host
|
|
*/
|
|
export const isPublicHost = () => {
|
|
return getHostConfig().isPublic;
|
|
};
|
|
|
|
/**
|
|
* Prüft, ob App auf internal Host läuft
|
|
* @returns {boolean} True wenn internal Host
|
|
*/
|
|
export const isInternalHost = () => {
|
|
return getHostConfig().isInternal;
|
|
};
|
|
|
|
/**
|
|
* Hole spezifisches Feature-Flag
|
|
* @param {string} featureName - Name des Features (z.B. 'canAccessAdmin')
|
|
* @returns {boolean} True wenn Feature erlaubt
|
|
*/
|
|
export const canAccessFeature = (featureName) => {
|
|
const config = getHostConfig();
|
|
return config[featureName] || false;
|
|
};
|
|
|
|
/**
|
|
* Debug-Funktion: Logge Host-Config in Console
|
|
* Nur in Development
|
|
*/
|
|
export const logHostConfig = () => {
|
|
if (process.env.NODE_ENV === 'development') {
|
|
const config = getHostConfig();
|
|
console.log('🔍 Host Configuration:', {
|
|
hostname: config.hostname,
|
|
isPublic: config.isPublic,
|
|
isInternal: config.isInternal,
|
|
features: {
|
|
admin: config.canAccessAdmin,
|
|
slideshow: config.canAccessSlideshow,
|
|
groups: config.canAccessGroups,
|
|
moderation: config.canAccessModeration
|
|
}
|
|
});
|
|
}
|
|
};
|