{"id":27363619,"url":"https://github.com/qamar2315/node-express-file-uploader","last_synced_at":"2026-04-12T17:55:17.623Z","repository":{"id":287622134,"uuid":"965299875","full_name":"Qamar2315/node-express-file-uploader","owner":"Qamar2315","description":"A simple Node.js and Express-based file upload server allowing users to upload files to categorized folders with a web interface.","archived":false,"fork":false,"pushed_at":"2025-04-12T22:05:52.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T22:25:16.105Z","etag":null,"topics":["backend","cors","expressjs","file-server","file-upload","javascript","layered-architecture","multer","nodejs","rest-api","web-application"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Qamar2315.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-12T21:13:02.000Z","updated_at":"2025-04-12T22:05:56.000Z","dependencies_parsed_at":"2025-04-12T22:25:20.028Z","dependency_job_id":"2ab9cc36-831b-423e-915d-f1f1ee9d8e28","html_url":"https://github.com/Qamar2315/node-express-file-uploader","commit_stats":null,"previous_names":["qamar2315/node-express-file-uploader"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qamar2315%2Fnode-express-file-uploader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qamar2315%2Fnode-express-file-uploader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qamar2315%2Fnode-express-file-uploader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qamar2315%2Fnode-express-file-uploader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Qamar2315","download_url":"https://codeload.github.com/Qamar2315/node-express-file-uploader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248663450,"owners_count":21141766,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","cors","expressjs","file-server","file-upload","javascript","layered-architecture","multer","nodejs","rest-api","web-application"],"created_at":"2025-04-13T04:31:24.419Z","updated_at":"2026-04-12T17:55:17.565Z","avatar_url":"https://github.com/Qamar2315.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Node.js Express File Uploader\n\nA robust and organized Node.js and Express-based file upload server allowing users to upload files to categorized folders via a user-friendly web interface. Built with a layered backend architecture for maintainability and scalability.\n\n## Features\n\n*   **File Uploads:** Supports uploading various file types (configurable).\n*   **Folder Management:**\n    *   Upload files to specific folders (pictures, videos, documents by default).\n    *   Dynamically create new folders via the API and web UI.\n    *   List available upload folders.\n*   **Web Interface:**\n    *   Clean UI for folder selection and creation.\n    *   Drag \u0026 drop file selection support.\n    *   File preview before uploading.\n    *   Real-time upload progress indication.\n    *   Display of recent upload history.\n*   **Backend API:** RESTful endpoints for interacting with folders and files.\n*   **Layered Architecture:** Backend structured into `config`, `routes`, `controllers`, `services`, and `middleware` for better separation of concerns.\n*   **Security:**\n    *   File type validation (MIME type checking).\n    *   Configurable file size limits.\n    *   Folder and file name sanitization.\n    *   Basic protection against directory traversal attacks.\n*   **Storage:** Uses the local filesystem for storing uploaded files.\n\n## Technology Stack\n\n*   **Backend:** Node.js, Express.js\n*   **Middleware:** Multer (for file uploads), CORS (for cross-origin requests)\n*   **Frontend:** HTML5, CSS3, Vanilla JavaScript (ES6+)\n*   **Storage:** Local Filesystem\n*   **Package Manager:** npm\n\n## Project Structure\n\n```\n/node-express-file-uploader\n├── src/                      # Backend source code\n│   ├── config/               # Configuration files (port, paths, limits etc.)\n│   │   └── index.js\n│   ├── controllers/          # Request/response handlers\n│   │   └── fileController.js\n│   ├── middleware/           # Custom Express middleware\n│   │   ├── errorHandler.js   # Global error handler\n│   │   └── uploadMiddleware.js # Multer configuration\n│   ├── routes/               # API route definitions\n│   │   ├── fileRoutes.js     # Routes for file/folder operations\n│   │   └── index.js          # Main API router\n│   ├── services/             # Business logic and external interactions\n│   │   └── fileSystemService.js # Filesystem operations\n│   └── app.js                # Express application setup and configuration\n├── public/                   # Static frontend files (served by Express)\n│   ├── index.html            # Main HTML page\n│   └── script.js             # Frontend JavaScript logic\n├── qamar_main_folder/        # Default root directory for uploads (created automatically)\n│   ├── pictures/             # Default subfolder\n│   ├── videos/               # Default subfolder\n│   └── documents/            # Default subfolder\n├── .gitignore                # Git ignore file\n├── package.json              # Project metadata and dependencies\n├── package-lock.json         # Exact dependency versions\n├── server.js                 # Main entry point to start the server\n└── README.md                 # This file\n```\n\n## Prerequisites\n\n*   [Node.js](https://nodejs.org/) (v14 or higher recommended)\n*   [npm](https://www.npmjs.com/) (usually comes with Node.js)\n*   [Git](https://git-scm.com/) (for cloning the repository)\n\n## Setup and Installation\n\n1.  **Clone the repository:**\n    ```bash\n    git clone https://github.com/Qamar2315/node-express-file-uploader\n    cd node-express-file-uploader\n    ```\n\n2.  **Install dependencies:**\n    ```bash\n    npm install\n    ```\n\n## Running the Application\n\n1.  **Start the server:**\n    ```bash\n    npm start\n    ```\n    This will run the `node server.js` script defined in `package.json`.\n\n2.  **(Optional) Start in development mode (requires nodemon):**\n    If you have `nodemon` installed (`npm install -g nodemon` or `npm install --save-dev nodemon`), you can use:\n    ```bash\n    npm run dev\n    ```\n    This will automatically restart the server when file changes are detected.\n\n3.  **Access the application:**\n    Open your web browser and navigate to: `http://localhost:3000` (or the port specified in the configuration).\n\n## API Endpoints\n\nThe following API endpoints are available under the `/api` prefix (e.g., `http://localhost:3000/api/folders`).\n\n### Folders\n\n*   **`GET /api/folders`**\n    *   **Description:** List all available upload folders.\n    *   **Response (Success - 200 OK):**\n        ```json\n        {\n          \"success\": true,\n          \"folders\": [\"pictures\", \"videos\", \"documents\", \"custom_folder1\"],\n          \"defaultFolders\": [\"pictures\", \"videos\", \"documents\"]\n        }\n        ```\n    *   **Response (Error - 500 Internal Server Error):**\n        ```json\n        {\n          \"success\": false,\n          \"message\": \"Failed to read directory contents.\"\n        }\n        ```\n\n*   **`POST /api/folders`**\n    *   **Description:** Create a new folder within the main upload directory.\n    *   **Request Body:**\n        ```json\n        {\n          \"folderName\": \"new_folder_name\"\n        }\n        ```\n    *   **Response (Success - 201 Created):**\n        ```json\n        {\n          \"success\": true,\n          \"message\": \"Folder 'new_folder_name' created successfully\",\n          \"folderName\": \"new_folder_name\", // The sanitized name\n          \"folderPath\": \"qamar_main_folder/new_folder_name\" // Relative path info\n        }\n        ```\n    *   **Response (Error - 400 Bad Request):** (e.g., missing name, invalid name, folder exists)\n        ```json\n        {\n          \"success\": false,\n          \"message\": \"Folder name is required.\" // Or other specific error\n        }\n        ```\n     *   **Response (Error - 500 Internal Server Error):** (e.g., filesystem permission issue)\n        ```json\n        {\n          \"success\": false,\n          \"message\": \"Failed to create folder on the server.\"\n        }\n        ```\n\n### Uploads\n\n*   **`POST /api/upload`**\n    *   **Description:** Upload one or more files to a specified folder. Uses `multipart/form-data`.\n    *   **Request:**\n        *   `Content-Type: multipart/form-data`\n        *   **Form Fields:**\n            *   `folder`: (String) The name of the target folder (e.g., \"pictures\", \"documents\"). If omitted or invalid, defaults usually to \"documents\".\n            *   `files`: (File) One or more files selected for upload. The key *must* be `files`.\n    *   **Response (Success - 200 OK):**\n        ```json\n        {\n          \"success\": true,\n          \"message\": \"1 file(s) uploaded successfully\", // Number might vary\n          \"uploadedFiles\": [\n            {\n              \"originalName\": \"My Vacation Photo.jpg\",\n              \"storedName\": \"My_Vacation_Photo-1678886400000-123456789.jpg\",\n              \"size\": 102400, // Size in bytes\n              \"mimetype\": \"image/jpeg\",\n              \"folder\": \"pictures\" // The folder it was actually saved in\n            }\n            // ... more files if multiple were uploaded\n          ]\n        }\n        ```\n    *   **Response (Error - 400 Bad Request):** (e.g., no files uploaded, file too large, invalid file type)\n        ```json\n        {\n          \"success\": false,\n          \"message\": \"No files were uploaded.\" // Or \"File is too large...\", \"File type not allowed...\"\n        }\n        ```\n     *   **Response (Error - 500 Internal Server Error):** (e.g., filesystem write error)\n            ```json\n            {\n            \"success\": false,\n            \"message\": \"An unexpected internal server error occurred.\"\n            }\n            ```\n\n## Configuration\n\nApplication settings are managed via environment variables. Create a `.env` file in the project root for local development. In production, set these variables directly on your server or hosting platform.\n\n**`.env` Example (for Development):**\n\n```dotenv\n# Server Configuration\nPORT=3000\nNODE_ENV=development\n\n# File Upload Configuration\nMAIN_FOLDER_NAME=qamar_main_folder\nMAX_FILES_PER_UPLOAD=100\nMAX_FILE_SIZE_MB=1024 # Size in Megabytes (1GB = 1024 MB)\n\n# CORS Configuration\nCORS_ORIGIN=*\n\n# Server Timeout (Optional, but good practice)\nSERVER_TIMEOUT_MINUTES=15\n```\n\n**Available Environment Variables:**\n\n| Variable               | Description                                                                  | Default (if not set) |\n| :--------------------- | :--------------------------------------------------------------------------- | :------------------- |\n| `PORT`                 | The port the server listens on.                                              | `3000`               |\n| `NODE_ENV`             | The runtime environment (e.g., `development`, `production`).                 | `development`        |\n| `MAIN_FOLDER_NAME`     | Name of the root directory for uploads.                                      | `qamar_main_folder`  |\n| `MAX_FILES_PER_UPLOAD` | Maximum number of files allowed in a single upload request.                  | `100`                |\n| `MAX_FILE_SIZE_MB`     | Maximum size allowed for a single file, specified in Megabytes (MB).         | `1024` (1GB)         |\n| `CORS_ORIGIN`          | Allowed origin(s) for CORS requests. Use `*` for development, specific domain for production. | `*`                  |\n| `SERVER_TIMEOUT_MINUTES`| Timeout for the HTTP server in minutes (for long uploads).                 | `15`                 |\n\n_(Note: `allowedMimeTypes` and `defaultFolders` are currently managed in `src/config/index.js`)_\n\n\n**How it Works:**\n\n1.  The `dotenv` package is loaded at the start of `src/config/index.js`.\n2.  It reads the `.env` file in your project root.\n3.  It adds the variables found in `.env` to the `process.env` object in Node.js.\n4.  The `src/config/index.js` file now reads these values from `process.env`, providing default fallbacks if a variable isn't defined.\n5.  Other parts of the application (like `server.js` and `fileRoutes.js`) import the configuration object from `src/config/index.js` to get the settings.\n\n\n## Security Considerations\n\n*   **File Types:** Only MIME types listed in `allowedMimeTypes` (config) are permitted. Ensure this list is appropriate for your use case.\n*   **File Size:** Uploads are limited by `maxFileSize` (config).\n*   **Sanitization:** Folder names and filenames are sanitized to remove potentially unsafe characters and prevent directory traversal (`../`).\n*   **CORS:** Cross-Origin Resource Sharing is enabled. Configure `corsOptions` strictly for production environments to only allow requests from your frontend's domain.\n*   **Authentication:** This project **does not** implement user authentication or authorization. Access to upload files and create folders is currently public. Implement appropriate security layers if deploying in a sensitive environment.\n*   **Rate Limiting:** Consider adding rate limiting middleware (e.g., `express-rate-limit`) to prevent abuse if the server is publicly accessible.\n\n## Future Enhancements\n\n*   **Authentication \u0026 Authorization:** Implement user accounts and permissions.\n*   **Database Integration:** Store file metadata (uploader, timestamp, description, etc.) in a database.\n*   **Cloud Storage:** Add support for uploading files to cloud providers like AWS S3 or Google Cloud Storage.\n*   **File Management:** Implement features for deleting files or listing files within folders.\n*   **Testing:** Add unit and integration tests.\n*   **Advanced Validation:** Implement more sophisticated file validation (e.g., magic number checks).\n*   **UI Improvements:** Enhance the frontend with features like thumbnail previews.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqamar2315%2Fnode-express-file-uploader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqamar2315%2Fnode-express-file-uploader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqamar2315%2Fnode-express-file-uploader/lists"}