mirror of
https://github.com/DumbWareio/DumbDrop.git
synced 2025-11-02 13:03:31 +00:00
* feat: Add ALLOWED_IFRAME_ORIGINS configuration and update security headers (#47) - Introduced ALLOWED_IFRAME_ORIGINS environment variable to specify trusted origins for iframe embedding. - Updated security headers middleware to conditionally allow specified origins in Content Security Policy. - Enhanced documentation in README.md to explain the new configuration and its security implications. Fixes #35 * feat: Update .env.example and .gitignore for improved configuration management - Enhanced .env.example with detailed comments for environment variables, including upload settings, security options, and notification configurations. - Updated .gitignore to include additional editor and OS-specific files, ensuring a cleaner repository. - Modified package.json to add a predev script for Node.js version validation and adjusted the dev script for nodemon. - Improved server.js shutdown handling to prevent multiple shutdowns and ensure graceful exits. - Refactored config/index.js to log loaded environment variables and ensure the upload directory exists based on environment settings. - Cleaned up fileUtils.js by removing unused functions and improving logging for directory creation. This commit enhances clarity and maintainability of configuration settings and improves application shutdown behavior. * feat: Update Docker configuration and documentation for upload handling - Explicitly set the upload directory environment variable in docker-compose.yml to ensure clarity in file storage. - Simplified the Dockerfile by removing the creation of the local_uploads directory, as it is now managed by the host system. - Enhanced README.md to reflect changes in upload directory management and provide clearer instructions for users. - Removed outdated development configuration files to streamline the development setup. This commit improves the clarity and usability of the Docker setup for file uploads. * feat: Add Local Development Guide and update README for clarity - Introduced a comprehensive LOCAL_DEVELOPMENT.md file with setup instructions, testing guidelines, and troubleshooting tips for local development. - Updated README.md to include a link to the new Local Development Guide and revised sections for clarity regarding upload directory management. - Enhanced the Quick Start section to direct users to the dedicated local development documentation. This commit improves the onboarding experience for developers and provides clear instructions for local setup. * feat: Implement BASE_URL configuration for asset management and API requests - Added BASE_URL configuration to README.md, emphasizing the need for a trailing slash when deploying under a subpath. - Updated index.html and login.html to utilize BASE_URL for linking stylesheets, icons, and API requests, ensuring correct asset loading. - Enhanced app.js to replace placeholders with the actual BASE_URL during HTML rendering. - Implemented a validation check in config/index.js to ensure BASE_URL is a valid URL and ends with a trailing slash. This commit improves the flexibility of the application for different deployment scenarios and enhances asset management. Fixes #34, Fixes #39, Fixes #38 * Update app.js, borked some of the css n such * resolved BASE_URL breaking frontend * fix: Update BASE_URL handling and security headers - Ensured BASE_URL has a trailing slash in app.js to prevent asset loading issues. - Refactored index.html and login.html to remove leading slashes from API paths for correct concatenation with BASE_URL. - Enhanced security headers middleware to include 'connect-src' directive in Content Security Policy. This commit addresses issues with asset management and improves security configurations.
125 lines
4.0 KiB
JavaScript
125 lines
4.0 KiB
JavaScript
/**
|
|
* Server entry point that starts the HTTP server and manages connections.
|
|
* Handles graceful shutdown, connection tracking, and server initialization.
|
|
* Provides development mode directory listing functionality.
|
|
*/
|
|
|
|
const { app, initialize, config } = require('./app');
|
|
const logger = require('./utils/logger');
|
|
const fs = require('fs');
|
|
const { executeCleanup } = require('./utils/cleanup');
|
|
const { generatePWAManifest } = require('./scripts/pwa-manifest-generator')
|
|
|
|
// Track open connections
|
|
const connections = new Set();
|
|
|
|
/**
|
|
* Start the server and initialize the application
|
|
* @returns {Promise<http.Server>} The HTTP server instance
|
|
*/
|
|
async function startServer() {
|
|
try {
|
|
// Initialize the application
|
|
await initialize();
|
|
|
|
// Start the server
|
|
const server = app.listen(config.port, () => {
|
|
logger.info(`Server running at ${config.baseUrl}`);
|
|
logger.info(`Upload directory: ${config.uploadDisplayPath}`);
|
|
|
|
// List directory contents in development
|
|
if (config.nodeEnv === 'development') {
|
|
try {
|
|
const files = fs.readdirSync(config.uploadDir);
|
|
logger.info(`Current directory contents (${files.length} files):`);
|
|
files.forEach(file => {
|
|
logger.info(`- ${file}`);
|
|
});
|
|
} catch (err) {
|
|
logger.error(`Failed to list directory contents: ${err.message}`);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Dynamically generate PWA manifest into public folder
|
|
generatePWAManifest();
|
|
|
|
// Track new connections
|
|
server.on('connection', (connection) => {
|
|
connections.add(connection);
|
|
connection.on('close', () => {
|
|
connections.delete(connection);
|
|
});
|
|
});
|
|
|
|
// Shutdown handler function
|
|
let isShuttingDown = false; // Prevent multiple shutdowns
|
|
const shutdownHandler = async (signal) => {
|
|
if (isShuttingDown) return;
|
|
isShuttingDown = true;
|
|
logger.info(`${signal} received. Shutting down gracefully...`);
|
|
|
|
// Start a shorter force shutdown timer
|
|
const forceShutdownTimer = setTimeout(() => {
|
|
logger.error('Force shutdown initiated');
|
|
process.exit(1);
|
|
}, 3000); // 3 seconds maximum for total shutdown
|
|
|
|
try {
|
|
// 1. Stop accepting new connections immediately
|
|
server.unref();
|
|
|
|
// 2. Close all existing connections with a shorter timeout
|
|
const connectionClosePromises = Array.from(connections).map(conn => {
|
|
return new Promise(resolve => {
|
|
conn.end(() => {
|
|
connections.delete(conn);
|
|
resolve();
|
|
});
|
|
});
|
|
});
|
|
|
|
// Wait for connections to close with a timeout
|
|
await Promise.race([
|
|
Promise.all(connectionClosePromises),
|
|
new Promise(resolve => setTimeout(resolve, 1000)) // 1 second timeout for connections
|
|
]);
|
|
|
|
// 3. Close the server
|
|
await new Promise((resolve) => server.close(resolve));
|
|
logger.info('Server closed');
|
|
|
|
// 4. Run cleanup tasks with a shorter timeout
|
|
await executeCleanup(1000); // 1 second timeout for cleanup
|
|
|
|
// Clear the force shutdown timer since we completed gracefully
|
|
clearTimeout(forceShutdownTimer);
|
|
process.exitCode = 0;
|
|
process.exit(0); // Ensure immediate exit
|
|
} catch (error) {
|
|
logger.error(`Error during shutdown: ${error.message}`);
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
// Handle both SIGTERM and SIGINT
|
|
process.on('SIGTERM', () => shutdownHandler('SIGTERM'));
|
|
process.on('SIGINT', () => shutdownHandler('SIGINT'));
|
|
|
|
return server;
|
|
} catch (error) {
|
|
logger.error('Failed to start server:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Only start the server if this file is run directly
|
|
if (require.main === module) {
|
|
startServer().catch((error) => {
|
|
logger.error('Server failed to start:', error);
|
|
process.exitCode = 1;
|
|
throw error;
|
|
});
|
|
}
|
|
|
|
module.exports = { app, startServer };
|