Skip to content

Commit db403c8

Browse files
authored
fixed UI and added multi files uploading (#8)
* added auto delete * fixed UI and added multi files uploading * fixed some issues
1 parent c156a2a commit db403c8

File tree

12 files changed

+1210
-2557
lines changed

12 files changed

+1210
-2557
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
.env
1+
.env
2+
node_modules
3+
pnpm-lock.yaml
4+
package-lock.json
5+
m.js

README.md

Lines changed: 184 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1+
# MegaCDN
12

2-
# MegaCDN
3-
A lightweight and serverless CDN utilizing MEGA for file storage and delivery.
3+
A lightweight and serverless CDN utilizing MEGA for file storage and delivery.
44

5-
## Installation
5+
## Features
6+
7+
- File upload and delivery via MEGA storage
8+
- Multiple account support (load balancing)
9+
- Multiple Files and folder Upload Support
10+
- Cool and Professional UI
11+
- **Optional upload-protection** using `Authorization` Header
12+
- **Optional auto-deletion** with configurable time periods
13+
- Supports both `MongoDB` and `Json`
14+
- Serverless deployment ready
15+
16+
## Installation
17+
18+
### Clone the Repository
619

7-
### Clone the Repository
820
```sh
921
git clone https://github.com/IRON-M4N/MegaCDN.git
1022
cd MegaCDN
@@ -14,149 +26,238 @@ npm install
1426
## Deployments
1527

1628
#### Deploy To Heroku
17-
1. *If You Don't Have a Heroku Account, [Create An Account](https://signup.heroku.com).*
18-
2. *Now Deploy To Heroku.* <br>
19-
[![Heroku](https://img.shields.io/badge/Heroku-000000?style=for-the-badge&logo=heroku&logoColor=white)](https://heroku.com/deploy?template=https://github.com/IRON-M4N/MegaCDN)
29+
30+
1. _If You Don't Have a Heroku Account, [Create An Account](https://signup.heroku.com)._
31+
2. _Now Deploy To Heroku._ <br>
32+
[![Heroku](https://img.shields.io/badge/Heroku-000000?style=for-the-badge&logo=heroku&logoColor=white)](https://heroku.com/deploy?template=https://github.com/IRON-M4N/MegaCDN)
2033

2134
#### Deploy on Vercel
22-
1. *[Create Vercel Account](https://vercel.com/signup) If You Don't Have.*
23-
2. *Deploy on Vercel.* <br>
24-
[![Vercel](https://img.shields.io/badge/Vercel-000000?style=for-the-badge&logo=vercel&logoColor=white)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FIRON-M4N%2FMegaCDN&env=MEGA_ACCOUNT,PORT&envDescription=provide%20multiple%20accounts%20in%20this%20format%20email%3Apass%3Bemail%3Apass%0Afor%20port%20use%203000%20or%20any)
35+
36+
1. _[Create Vercel Account](https://vercel.com/signup) If You Don't Have._
37+
2. _Deploy on Vercel._ <br>
38+
[![Vercel](https://img.shields.io/badge/Vercel-000000?style=for-the-badge&logo=vercel&logoColor=white)](<https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FIRON-M4N%2FMegaCDN&env=MEGA_ACCOUNT,PORT,TEMP,MAX_REQUESTS,RATE_LIMIT,AUTO_DELETE,DELETE_TIME,MONGODB_URI,AUTHORIZATION,AUTH_TOKEN,MAX_FILE_SIZE,MAX_FILES,CACHE_TTL&envDescription=Required%20env%20variables%3A%0A-%20MEGA_ACCOUNT%3A%20email%3Apass%3Bemail%3Apass%0A-%20PORT%3A%203000%0A%0AOptional%20env%20variables%3A%0A-%20TEMP%3A%20memory%20or%20file%0A-%20AUTO_DELETE%3A%20true%2Ffalse%0A-%20AUTH_TOKEN%3A%20Your%20Bearer%20Token%20(if%20AUTHORIZATION%3Dtrue)%0A-%20MAX_FILE_SIZE%3A%20In%20MB%0A-%20CACHE_TTL%3A%20In%20seconds>)
2539

2640
#### Deploy To Railway
27-
1. *If You Don't Have Railway Account, [Create First](https://railway.com).*
28-
2. *Now Deploy The Repo.* <br>
29-
[![Railway](https://img.shields.io/badge/Railway-000000?style=for-the-badge&logo=railway&logoColor=white)](https://railway.com/new)
41+
42+
1. _If You Don't Have Railway Account, [Create First](https://railway.com)._
43+
2. _Now Deploy The Repo._ <br>
44+
[![Railway](https://img.shields.io/badge/Railway-000000?style=for-the-badge&logo=railway&logoColor=white)](https://railway.com/new)
3045

3146
#### Deploy on Render
32-
1. *[Create Render Account](https://dashboard.render.com/register) If You Don't Have Any.*
33-
2. *Deploy Now.* <br>
34-
[![Render](https://img.shields.io/badge/Render-000000?style=for-the-badge&logo=render&logoColor=white)](https://render.com/deploy?repo=https://github.com/IRON-M4N/MegaCDN)
47+
48+
1. _[Create Render Account](https://dashboard.render.com/register) If You Don't Have Any._
49+
2. _Deploy Now._ <br>
50+
[![Render](https://img.shields.io/badge/Render-000000?style=for-the-badge&logo=render&logoColor=white)](https://render.com/deploy?repo=https://github.com/IRON-M4N/MegaCDN)
3551

3652
#### Deploy on Koyeb
37-
1. *[Create Account](https://app.koyeb.com/auth/signup) If You Don't Have.*
38-
2. *Now Deploy.* <br>
39-
[![Koyeb](https://img.shields.io/badge/Koyeb-000000?style=for-the-badge&logo=koyeb&logoColor=white)](https://app.koyeb.com/deploy?type=git&repository=github.com/IRON-M4N/MegaCDN&name=MegaCDN&builder=buildpack&env[MEGA_ACCOUNT]=email:pass&env[PORT]=3000&env[TEMP]=memory )
4053

41-
## Configuration
54+
1. _[Create Account](https://app.koyeb.com/auth/signup) If You Don't Have._
55+
2. _Now Deploy._ <br>
56+
[![Koyeb](https://img.shields.io/badge/Koyeb-000000?style=for-the-badge&logo=koyeb&logoColor=white)](https://app.koyeb.com/deploy?type=git&repository=github.com/IRON-M4N/MegaCDN&name=MegaCDN&builder=buildpack&env[MEGA_ACCOUNT]=email:pass;email:pass&env[PORT]=3000&env[TEMP]=memory&env[MAX_REQUESTS]=100&env[RATE_LIMIT]=1%20minute&env[AUTO_DELETE]=false&env[DELETE_TIME]=1440&env[MONGODB_URI]=null&env[AUTHORIZATION]=false&env[AUTH_TOKEN]=YOUR_BEARER_TOKEN&env[MAX_FILE_SIZE]=100&env[MAX_FILES]=10&env[CACHE_TTL]=3600)
57+
58+
## Configuration
4259

43-
Modify `config.js` or use environment variables. Example `.env` file:
60+
Modify `config.js` or use environment variables. Example `.env` file:
4461

4562
```
46-
MEGA_ACCOUNT=email:pass;email:pass
47-
TEMP=memory
63+
PORT=3000 # Port to run the app
64+
MEGA_ACCOUNT=email:pass;email:pass # Multiple accounts for load balancing
65+
TEMP=memory # Upload storage option
66+
AUTO_DELETE=true # Enable/disable auto-deletion
67+
DELETE_TIME=1440 # Minutes until deletion (default: 1 day)
68+
MONGODB_URI=null # Optional MongoDB connection string
69+
AUTHORIZATION=true # Enable/disable secure uploading
70+
AUTH_TOKEN=YOUR_BEARER_TOKEN # Bearer token for authentication
71+
MAX_FILES=10 # Maximum files per upload
72+
MAX_FILE_SIZE=50 # Maximum file size in MB
73+
CACHE_TTL=3600 # Cache duration in seconds
74+
MAX_REQUESTS=100 # Max upload requests in specific time
75+
RATE_LIMIT=1 minute # 100 req per minute
4876
```
4977

50-
## Running the Server
78+
## Starting the Server
79+
80+
Using PM2 for process management:
5181

52-
Using PM2 for process management:
5382
```sh
5483
npm start
55-
```
56-
To stop or restart:
84+
```
85+
86+
To stop or restart:
87+
5788
```sh
58-
npm stop
59-
npm restart
89+
npm stop
90+
npm restart
6091
```
6192

62-
## Uploading Files
93+
## Uploading Files
6394

64-
Send a POST request to /upload with a multipart form containing a file.
95+
Send a POST request to /upload with a multipart form containing a file.
6596

6697
<details>
6798
<summary>Curl - Single Mode</summary>
6899

69-
``` sh
70-
curl -X POST -F "[email protected]" -F "mode=single" http://yourdomain.com/upload
71-
```
100+
```sh
101+
# Single file without Authorization
102+
curl -X POST -F "[email protected]" -F "mode=single" http://yourdomain.com/upload
103+
104+
# Multiple Files With Authorizatoin
105+
curl -X POST -H "Authorization: Bearer YOUR_BEARER_TOKEN" -F "[email protected]" -F "[email protected]" -F "mode=single" http://yourdomain.com/upload
106+
```
107+
72108
</details>
73109

74110
<details>
75111
<summary>Curl - Dual Mode</summary>
76112

77-
```sh
78-
curl -X POST -F "[email protected]" -F "mode=dual" -F "[email protected]" http://yourdomain.com/upload
79-
```
113+
```sh
114+
# Single file without Authorization
115+
curl -X POST -F "[email protected]" -F "mode=dual" -F "[email protected]" http://yourdomain.com/upload
116+
117+
# Multiple Files With Authorizatoin
118+
curl -X POST -H "Authorization: Bearer YOUR_BEARER_TOKEN" -F "[email protected]" -F "[email protected]" -F "[email protected]" -F "mode=dual" -F "[email protected]" http://yourdomain.com/upload
119+
```
120+
80121
</details>
81122

82123
<details>
83124
<summary>Node.js - Single Mode</summary>
84125

85-
```js
86-
const fs = require("fs");
87-
const axios = require("axios");
88-
const FormData = require("form-data");
126+
```js
127+
// Single file without Authorization
128+
const fs = require("fs");
129+
const axios = require("axios");
130+
const FormData = require("form-data");
131+
132+
async function uploadSingle() {
133+
const form = new FormData();
134+
form.append("file", fs.createReadStream("image.jpg"));
135+
form.append("mode", "single");
136+
137+
const res = await axios.post("http://yourdomain.com/upload", form, {
138+
headers: form.getHeaders(),
139+
});
89140

90-
async function uploadSingle() {
91-
const form = new FormData();
92-
form.append("file", fs.createReadStream("image.jpg"));
93-
form.append("mode", "single");
141+
console.log(res.data);
142+
}
143+
144+
uploadSingle();
145+
146+
// Multiple Files with Authorization
147+
async function uploadMultiple() {
148+
const form = new FormData();
94149

95-
const res = await axios.post("http://yourdomain.com/upload", form, {
96-
headers: form.getHeaders(),
97-
});
150+
form.append("file", fs.createReadStream("image1.jpg"));
151+
form.append("file", fs.createReadStream("image2.png"));
98152

99-
console.log(res.data);
153+
form.append("mode", "single");
154+
155+
const headers = {
156+
...form.getHeaders(),
157+
Authorization: "Bearer YOUR_BEARER_TOKEN",
158+
};
159+
160+
try {
161+
const res = await axios.post("http://yourdomain.com/upload", form, { headers });
162+
console.log("Upload successful:", res.data);
163+
} catch (error) {
164+
console.error("Upload failed:", error.response?.data || error.message);
100165
}
166+
}
167+
168+
uploadMultiple();
169+
```
101170
102-
uploadSingle();
103-
```
104171
</details>
105172
106173
<details>
107174
<summary>Node.js - Dual Mode</summary>
108175
109-
```js
110-
const fs = require("fs");
111-
const axios = require("axios");
112-
const FormData = require("form-data");
176+
```js
177+
// Single file without Authorization
178+
const fs = require("fs");
179+
const axios = require("axios");
180+
const FormData = require("form-data");
181+
182+
async function uploadDual() {
183+
const form = new FormData();
184+
form.append("file", fs.createReadStream("image.jpg"));
185+
form.append("mode", "dual");
186+
form.append("email", "[email protected]");
187+
188+
const res = await axios.post("http://yourdomain.com/upload", form, {
189+
headers: form.getHeaders(),
190+
});
191+
192+
console.log(res.data);
193+
}
194+
195+
uploadDual();
196+
197+
// Multiple Files with Authorization
198+
async function uploadMultiple() {
199+
const form = new FormData();
113200

114-
async function uploadDual() {
115-
const form = new FormData();
116-
form.append("file", fs.createReadStream("image.jpg"));
117-
form.append("mode", "dual");
118-
form.append("email", "[email protected]");
201+
form.append("file", fs.createReadStream("image1.jpg"));
202+
form.append("file", fs.createReadStream("image2.png"));
119203

120-
const res = await axios.post("http://yourdomain.com/upload", form, {
121-
headers: form.getHeaders(),
122-
});
204+
form.append("mode", "dual");
205+
form.append("email", "[email protected]");
123206

124-
console.log(res.data);
207+
const headers = {
208+
...form.getHeaders(),
209+
Authorization: "Bearer YOUR_BEARER_TOKEN",
210+
};
211+
212+
try {
213+
const res = await axios.post("http://yourdomain.com/upload", form, { headers });
214+
console.log("Upload successful:", res.data);
215+
} catch (error) {
216+
console.error("Upload failed:", error.response?.data || error.message);
125217
}
218+
}
219+
220+
uploadMultiple();
221+
```
126222
127-
uploadDual();
128-
```
129223
</details>
130224
131-
### **Parameters Explained:**
132-
| Parameter | Description |
133-
|------------|-------------|
134-
| `file` | The file to upload. |
135-
| `mode` | Upload mode: `single` (default) or `dual` (requires `email`). |
136-
| `email` | (Optional) Required if `mode=dual`, specifies which account to use. |
225+
### **Parameters Explained:**
226+
227+
| Parameter | Description |
228+
| --------- | ------------------------------------------------------------------- |
229+
| `file` | The file to upload. |
230+
| `mode` | Upload mode: `single` (default) or `dual` (requires `email`). |
231+
| `email` | (Optional) Required if `mode=dual`, specifies which account to use. |
232+
233+
### Response Example
137234
138-
### Response Example
139235
```json
140236
{
141237
"success": true,
142238
"files": [
143239
{
144-
"url": "https://yourdomain.com/media/blahblahblah",
145-
"size": 6969
240+
"url": "https://your_domain.com/media/your_file",
241+
"name": "your_file.png",
242+
"size": 51470,
243+
"formattedSize": "50.26 KB",
244+
"expires": "86400 sec",
245+
"formattedExpires": "1 day"
146246
}
147247
]
148248
}
149-
```
249+
```
250+
251+
## To-Do
150252
151-
## To-Do
253+
- [ ] Add custom file name
152254
- [ ] Proper logging (error and alerts)
153-
- [ ] Fix webpage
154255
155-
## Contributing
156-
1. Fork the repository
157-
2. Create a new branch (`feature-web`)
158-
3. Commit your changes
159-
4. Open a pull request
256+
## Contributing
160257
258+
1. Fork the repository
259+
2. Create a new branch (`feature-web`)
260+
3. Commit your changes
261+
4. Open a pull request
161262
162263
© [IRON-M4N](https://github.com/IRON-M4N)

0 commit comments

Comments
 (0)