plsgivemeachane commited on
Commit
9787a3e
·
1 Parent(s): 502e2f5
Files changed (4) hide show
  1. index.js +489 -308
  2. prisma/bruh.txt +22 -0
  3. prisma/schema.prisma +3 -2
  4. uploads/Waterxtest.zip +0 -3
index.js CHANGED
@@ -1,205 +1,267 @@
1
- const express = require('express')
2
- const bodyParser = require('body-parser');
3
- const { sha } = require("sha256quanvn")
4
- const { PrismaClient } = require('@prisma/client')
5
- const multer = require('multer');
6
- const fs = require('fs');
7
- const path = require('path');
8
- const streamToBlob = require('stream-to-blob')
9
- const statusMonitor = require('express-status-monitor')({
10
- path: '/bee3hivestatuspagethatnoonewillrememberthisurl',
11
- title: "Bee3Hive API Status"
12
- });
13
- const cors = require("cors")
14
- const prisma = new PrismaClient()
15
- const app = express()
16
- const http = require('http');
17
- const server = http.createServer(app);
18
- const { type } = require('os');
19
- const io = require("socket.io")(server, {
20
- maxHttpBufferSize: 1e8,
21
- rejectUnauthorized: false,
22
- cors: {
23
- origin: "*",
24
- methods: ["GET", "POST"],
25
- }
26
  });
27
-
28
- const SALT = process.env.PRIVATE_KEY
29
-
30
- const queueFileUpload = {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  const info = (message) => {
33
- console.log(`<${new Date()}> [INFO] - ${message}`)
34
- }
35
  const warn = (message) => {
36
- console.log(`<${new Date()}> [INFO] - ${message}`)
37
- }
38
 
39
  //* Sussy bigint thing
40
  BigInt.prototype["toJSON"] = function () {
41
  return this.toString();
42
- };
43
 
44
  //* Safe Base64 Encode
45
  const safeb64 = (str) => {
46
- return btoa(str).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
 
49
  const generateJWT = async (id) => {
50
  const header = {
51
- "alg": "SHA256QUANVN",
52
- "typ": "JWT"
53
- }
54
 
55
  const payload = {
56
  id: id,
57
- exp: Date.now() + (3600000 * 24) // 1 days
58
- }
59
 
60
  await prisma.users.update({
61
  where: {
62
- id: payload.id
63
  },
64
  data: {
65
- last_login: new Date()
66
- }
67
- })
68
 
69
- const token = safeb64(JSON.stringify(header)) + "." + safeb64(JSON.stringify(payload));
 
70
 
71
  const sig = sha(token + "." + SALT);
72
 
73
- info("Generated new token for user: " + id)
74
  // console.log("New Token generated: " + token + "." + sig)
75
 
76
- return token + "." + safeb64(sig)
77
- }
78
 
79
  const generateFileID = () => {
80
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
81
- let fileID = '';
 
82
  for (let i = 0; i < 6; i++) {
83
  fileID += characters.charAt(Math.floor(Math.random() * characters.length));
84
  }
85
  return fileID;
 
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  }
88
 
 
 
 
89
  // Configure Multer storage
90
  const storage = multer.diskStorage({
91
  destination: (req, file, cb) => {
92
- cb(null, 'uploads/');
93
  },
94
  filename: (req, file, cb) => {
95
  // cb(null, generateFileID() + '-' + Date.now());
96
- cb(null, file.originalname);
97
- }
98
  });
99
 
100
- if(!fs.existsSync('uploads')) {
101
- fs.mkdirSync('uploads');
102
  }
103
 
104
  // Set file size limit to 10GB
105
  const upload = multer({
106
  storage: storage,
107
- limits: { fileSize: 10 * 1024 * 1024 * 1024 } // 10GB
108
  });
109
 
110
  // console.log(file)
111
 
112
- const current_connections = []
113
 
114
- io.on('connection', (socket) => {
115
- info('A IPFS Services connected id=' + socket.id);
116
 
117
- socket.on("availible", () => {
118
- info("Services id=" + socket.id + " availible")
119
- current_connections.push(socket.id)
120
- })
121
-
122
- socket.emit("health_check");
123
 
124
- const interval = setInterval(() => {
125
- //* Health check
126
- info("Send health_check")
127
- socket.emit("health_check");
128
- }, 60000)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
- socket.on("health", (data) => {
131
- info("Services id=" + socket.id + " " + data.healthy + " availible=" + data.availible + " ping=" + Math.abs(Date.now() - (data.now)) + "ms") //* Check if services is healthy
132
- })
 
 
 
 
 
 
133
 
134
- socket.on("unavailible", () => {
135
- info("Services id=" + socket.id + " unavailible")
136
- for(let i = 0; i < current_connections.length; i++) {
137
- if(current_connections[i] === socket.id) {
138
- current_connections.splice(i, 1);
139
- break;
140
- }
141
- }
142
- })
 
 
 
 
 
 
 
143
 
144
- socket.on("delete", async (data) => {
145
- info("File Successfully uploaded, writing record")
146
- console.log(data) //* The data is comsumed by the IPFS services
 
147
 
148
- try {
149
- await prisma.storage.create({
150
- data: {
151
- handle: data.handle,
152
- username: data.username,
153
- CID: data.ipfs[0].Hash,
154
- dir: data.directory
155
- }
156
- })
157
- } catch (e) {
158
- warn("Creating record fail")
159
- }
160
 
161
- //* Remove the initial file
162
- fs.unlinkSync("uploads/" + data.relative_path)
163
- info(`File ${data.relative_path} deleted`)
164
  })
 
165
 
166
- socket.on('disconnect', () => {
167
- info('A IPFS Services disconnected');
168
- clearInterval(interval)
169
- //* Removing services when disconnected (died)
170
- for(let i = 0; i < current_connections.length; i++) {
171
- if(current_connections[i] === socket.id) {
172
- current_connections.splice(i, 1);
173
- break;
174
- }
175
- }
176
- });
177
- });
178
-
179
-
180
- app.use(cors({
181
- origin: "*"
182
- }))
183
-
184
- app.use(bodyParser.json());
185
 
186
  app.use(statusMonitor);
187
 
188
- app.use('/upload_queue' ,express.static("uploads"))
189
 
190
- app.get('/bee3hivestatuspagethatnoonewillrememberthisurl', statusMonitor.pageRoute)
 
 
 
191
 
192
  app.post("/auth/email/register", async (req, res) => {
193
  let { username, email, password } = req.body;
194
 
195
- if(!username || !email || !password) {
196
- info("Missing required fields registration")
197
- res.sendStatus(400)
198
  return;
199
  }
200
 
201
- if(username.length < 6) {
202
- info("Username: " + username + " is too short!")
203
  res.sendStatus(400);
204
  return;
205
  }
@@ -210,112 +272,118 @@ app.post("/auth/email/register", async (req, res) => {
210
 
211
  // console.log(username, email, password)
212
 
213
- if(["admin", "administrator", "root", "user", "anonymous", "guest"].includes(username)) {
214
- warn("Username not allowed: " + username)
215
- res.sendStatus(401)
 
 
 
 
216
  return;
217
  }
218
 
219
  const record = await prisma.users.findUnique({
220
  where: {
221
- email: email
222
- }
223
- })
224
 
225
- if(record) {
226
- info("User already exists: " + username)
227
- res.status(400).send({ error: "Username already exists" })
228
  return;
229
  }
230
 
231
  try {
232
-
233
- info("Creating user: " + email + " username: " + username + " password: " + sha(password) + " " + new Date())
 
 
 
 
 
 
 
 
234
 
235
  const created = await prisma.users.create({
236
  data: {
237
  username: username,
238
  email: email,
239
  password_hash: sha(password),
240
- last_login: new Date()
241
- }
242
- })
243
-
244
- await createRepo({
245
- repo: getRepo(username),
246
- credentials: credentials,
247
- private: true
248
- })
249
 
250
- info("User created: " + email + " username: " + username)
251
- res.send({ token: await generateJWT(created.id) })
 
 
 
 
 
252
  return;
253
- } catch(e) {
254
- warn("Error on creating users")
255
- console.log(e)
256
- res.sendStatus(500)
257
- return
258
  }
259
- })
260
 
261
  app.post("/auth/email/login", async (req, res) => {
262
- const { email, password } = req.body
263
 
264
- if(!email || !password) {
265
- info("Missing required fields login")
266
- res.sendStatus(400)
267
- return
268
  }
269
 
270
  const record = await prisma.users.findUnique({
271
  where: {
272
- email: email
273
- }
274
- })
275
 
276
- if(!record) {
277
- info("User not found: " + email)
278
- res.sendStatus(401)
279
- return
280
  }
281
 
282
- if(record.password_hash != sha(password)) {
283
- warn("Wrong password attempt: " + email)
284
- res.sendStatus(401)
285
  return;
286
  }
287
 
288
- info("User logged in: " + email)
289
- res.send({ token: await generateJWT(record.id) })
290
- })
291
 
292
  app.use(async (req, res, next) => {
293
- if(!req.headers.authorization) {
294
- info("Authorization header not found")
295
- res.sendStatus(401)
296
  return;
297
  }
298
 
299
  let token;
300
  try {
301
  token = req.headers.authorization.slice(7); // Bearer token
302
- } catch(e) {
303
- warn("Parsing token fail")
304
- console.log(e)
305
  return;
306
  }
307
 
308
- if(!token) {
309
- info("Token not found")
310
- res.sendStatus(401)
311
  return;
312
  }
313
 
314
- const [tokenHeader, tokenPayload, tokenSig] = token.split(".")
315
 
316
- if(!tokenHeader || !tokenPayload || !tokenSig) {
317
- info("Invalid token")
318
- res.sendStatus(401)
319
  return;
320
  }
321
 
@@ -330,63 +398,63 @@ app.use(async (req, res, next) => {
330
 
331
  // console.log(header, payload, token_sig, sig)
332
 
333
- if(sig !== token_sig) {
334
- warn("Invalid signature")
335
- res.sendStatus(401)
336
  return;
337
  }
338
 
339
- if(Date.now() > payload.exp) {
340
- info("Token expired")
341
- res.sendStatus(401)
342
  return;
343
  }
344
 
345
  const record = await prisma.users.findUnique({
346
  where: {
347
- id: payload.id
348
- }
349
- })
350
 
351
- if(!record) {
352
- warn("Record not found")
353
- res.sendStatus(500) // How?
354
  return;
355
  }
356
 
357
- info("Authorized: " + record.id)
358
 
359
- req.user = record
360
- next()
361
  return;
362
  } catch (e) {
363
- console.log(e)
364
- res.sendStatus(401)
365
  return;
366
  }
367
- })
368
 
369
  app.post("/auth/me", async (req, res) => {
370
- if(!Array.isArray(queueFileUpload[req.user.username])) {
371
- queueFileUpload[req.user.username] = []
372
  }
373
  // User already authorize
374
- res.send(req.user)
375
- })
376
 
377
  app.post("/auth/delete", async (req, res) => {
378
  // User already authorize
379
  const { password } = req.body;
380
 
381
- if(!password) {
382
- info("Missing password when deleting user")
383
- res.sendStatus(400)
384
  return;
385
  }
386
 
387
  // Check password
388
- if(sha(password) != req.user.password_hash) {
389
- res.sendStatus(401)
390
  return;
391
  }
392
 
@@ -394,125 +462,238 @@ app.post("/auth/delete", async (req, res) => {
394
  try {
395
  await prisma.users.delete({
396
  where: {
397
- id: req.user.id
398
- }
399
- })
400
  res.sendStatus(200);
401
  return;
402
  } catch (e) {
403
- warn("Error on deleting user")
404
  console.log(e);
405
  res.sendStatus(500);
406
  return;
407
  }
408
- })
409
-
410
- app.post('/file/upload', upload.single('file'), async (req, res) => {
411
- const upload_path = req.file.path;
412
-
413
- const file_path = req.body.filePath;
414
- const full_file_path = req.user.username + (file_path ? ("/" + file_path) : "");
415
 
 
 
416
  try {
 
 
 
417
 
418
- if(current_connections.length == 0) {
419
- res.sendStatus(500);
420
- return
421
- }
422
  // Upload the file to another backend
423
- const random_client = Math.floor(Math.random() * current_connections.length);
424
- const client = current_connections[random_client];
425
 
426
- io.to(client).emit("fetch", {
427
- filename: req.file.filename,
 
 
 
 
 
 
 
428
  directory: full_file_path,
429
  username: req.user.username,
430
- fileURI: req.file.filename //* Prod: with timeframe
431
- })
 
 
432
 
433
- // Remove the file after upload
434
- info("File uploaded queued successfully: " + full_file_path)
435
- res.send('File uploaded queued.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  } catch (error) {
437
  // Fail to upload
438
- warn("File upload failed")
439
- console.log(error)
440
- res.status(500).send('File upload failed.');
441
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  })
443
 
444
- // app.get("/file/status", async (req, res) => {
445
- // res.send(queueFileUpload[req.user.username])
446
- // })
447
-
448
- // app.get("/file/list", async (req, res) => {
449
- // const filePath = req.query.filePath;
450
- // const recursive = req.query.recursive == "true";
451
- // const files = []
452
-
453
- // try{
454
- // for await (const fileInfo of listFiles({
455
- // repo: getRepo(req.user.username),
456
- // credentials: credentials,
457
- // path: (filePath ? (filePath + "/") : ""),
458
- // recursive: recursive
459
- // })) {
460
- // files.push(fileInfo)
461
- // }
462
- // } catch (e) {
463
- // info("No file found")
464
- // console.log(e)
465
- // }
466
 
467
- // res.send(files)
468
- // })
469
 
470
- // app.post("/file/delete", async (req, res) => {
471
- // const filePath = req.body.filePath;
 
 
 
472
 
473
- // const fileInfo = await fileExists({
474
- // repo: getRepo(req.user.username),
475
- // credentials: credentials,
476
- // path: (filePath ? (filePath + "/") : "")
477
- // });
478
 
479
- // if(!fileInfo) {
480
- // warn("File not found: " + (filePath ? (filePath + "/") : ""))
481
- // res.status(404).send("File not found.");
482
- // return;
483
- // }
484
-
485
- // await deleteFile({
486
- // repo: getRepo(req.user.username),
487
- // credentials: credentials,
488
- // path: (filePath ? (filePath + "/") : "")
489
- // })
490
-
491
- // info("File deleted: " + (filePath ? (filePath + "/") : ""))
492
- // res.send("File deleted successfully.");
493
- // })
494
-
495
- // app.post("/file/getdownloadurl", async (req, res) => {
496
- // const path = req.body.path;
497
-
498
- // try {
499
- // const downloadURL = await fileDownloadInfo({
500
- // repo: getRepo(req.user.username),
501
- // credentials: credentials,
502
- // path: path,
503
- // // raw: true
504
- // })
505
-
506
- // if(!downloadURL) {
507
- // res.status(404).send("File not found")
508
- // return;
509
- // }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
 
511
- // res.send(downloadURL)
512
- // } catch(e) {
513
- // console.log(e);
514
- // res.sendStatus(500)
515
- // }
516
- // })
 
 
517
 
518
- server.listen(7860, () => info('Server started on port 7860'))
 
1
+ const express = require("express");
2
+ const bodyParser = require("body-parser");
3
+ const { sha } = require("sha256quanvn");
4
+ const { PrismaClient } = require("@prisma/client");
5
+ const multer = require("multer");
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+ const streamToBlob = require("stream-to-blob");
9
+ const statusMonitor = require("express-status-monitor")({
10
+ path: "/bee3hivestatuspagethatnoonewillrememberthisurl",
11
+ title: "Bee3Hive API Status",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  });
13
+ const cors = require("cors");
14
+ const { resolveSoa } = require("dns");
15
+ const prisma = new PrismaClient();
16
+ const app = express();
17
+ // const http = require("http");
18
+ // const server = http.createServer(app);
19
+ // const { type } = require("os");
20
+ // const io = require("socket.io")(server, {
21
+ // maxHttpBufferSize: 1e8,
22
+ // rejectUnauthorized: false,
23
+ // cors: {
24
+ // origin: "*",
25
+ // methods: ["GET", "POST"],
26
+ // },
27
+ // });
28
+
29
+ const SALT = process.env.PRIVATE_KEY;
30
+
31
+ const services = ["http://localhost:7861"];
32
+ const queueFileUpload = {};
33
 
34
  const info = (message) => {
35
+ console.log(`<${new Date()}> [INFO] - ${message}`);
36
+ };
37
  const warn = (message) => {
38
+ console.log(`<${new Date()}> [INFO] - ${message}`);
39
+ };
40
 
41
  //* Sussy bigint thing
42
  BigInt.prototype["toJSON"] = function () {
43
  return this.toString();
44
+ };
45
 
46
  //* Safe Base64 Encode
47
  const safeb64 = (str) => {
48
+ return btoa(str).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
49
+ };
50
+
51
+
52
+ /**
53
+ * Returns a new array with all duplicates removed.
54
+ *
55
+ * @param {Array} a - The array to remove duplicates from.
56
+ * @return {Array} - A new array with all duplicates removed.
57
+ */
58
+ function uniq(a) {
59
+ var seen = {};
60
+ return a.filter(function(item) {
61
+ return seen.hasOwnProperty(item) ? false : (seen[item] = true);
62
+ });
63
  }
64
 
65
+
66
  const generateJWT = async (id) => {
67
  const header = {
68
+ alg: "SHA256QUANVN",
69
+ typ: "JWT",
70
+ };
71
 
72
  const payload = {
73
  id: id,
74
+ exp: Date.now() + 3600000 * 24, // 1 days
75
+ };
76
 
77
  await prisma.users.update({
78
  where: {
79
+ id: payload.id,
80
  },
81
  data: {
82
+ last_login: new Date(),
83
+ },
84
+ });
85
 
86
+ const token =
87
+ safeb64(JSON.stringify(header)) + "." + safeb64(JSON.stringify(payload));
88
 
89
  const sig = sha(token + "." + SALT);
90
 
91
+ info("Generated new token for user: " + id);
92
  // console.log("New Token generated: " + token + "." + sig)
93
 
94
+ return token + "." + safeb64(sig);
95
+ };
96
 
97
  const generateFileID = () => {
98
+ const characters =
99
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
100
+ let fileID = "";
101
  for (let i = 0; i < 6; i++) {
102
  fileID += characters.charAt(Math.floor(Math.random() * characters.length));
103
  }
104
  return fileID;
105
+ };
106
 
107
+ async function checkServer() {
108
+ // info("Checking servers...");
109
+ for(var i = services.length - 1; i >= 0; i--) {
110
+ try {
111
+ const resp = await fetch(services[i] + "/availible");
112
+ if(!resp.ok) {
113
+ // This server is ded but can try again later lol
114
+ warn("Server " + services[i] + " fail to ping");
115
+ continue;
116
+ }
117
+
118
+ const data = await resp.text();
119
+ // info(data)
120
+ if(data != "\"Ok!\"") {
121
+ //This server is full
122
+ warn("Server " + services[i] + " is full");
123
+ services.splice(i, 1);
124
+ }
125
+ } catch(e) {
126
+ // This server is ded but can try again later lol
127
+ warn("Server " + services[i] + " fail to fetch");
128
+ // services.splice(i, 1);
129
+ }
130
+ }
131
  }
132
 
133
+ setInterval(checkServer, 60 * 1000)
134
+ checkServer()
135
+
136
  // Configure Multer storage
137
  const storage = multer.diskStorage({
138
  destination: (req, file, cb) => {
139
+ cb(null, "uploads/");
140
  },
141
  filename: (req, file, cb) => {
142
  // cb(null, generateFileID() + '-' + Date.now());
143
+ cb(null, generateFileID() + "-" + file.originalname);
144
+ },
145
  });
146
 
147
+ if (!fs.existsSync("uploads")) {
148
+ fs.mkdirSync("uploads");
149
  }
150
 
151
  // Set file size limit to 10GB
152
  const upload = multer({
153
  storage: storage,
154
+ limits: { fileSize: 10 * 1024 * 1024 * 1024 }, // 10GB
155
  });
156
 
157
  // console.log(file)
158
 
159
+ const current_connections = [];
160
 
161
+ // io.on("connection", (socket) => {
162
+ // info("A IPFS Services connected id=" + socket.id);
163
 
164
+ // socket.on("availible", () => {
165
+ // info("Services id=" + socket.id + " availible");
166
+ // current_connections.push(socket.id);
167
+ // });
 
 
168
 
169
+ // socket.emit("health_check");
170
+
171
+ // const interval = setInterval(() => {
172
+ // //* Health check
173
+ // info("Send health_check");
174
+ // socket.emit("health_check");
175
+ // }, 60000);
176
+
177
+ // socket.on("health", (data) => {
178
+ // info(
179
+ // "Services id=" +
180
+ // socket.id +
181
+ // " " +
182
+ // data.healthy +
183
+ // " availible=" +
184
+ // data.availible +
185
+ // " ping=" +
186
+ // Math.abs(Date.now() - data.now) +
187
+ // "ms"
188
+ // ); //* Check if services is healthy
189
+ // });
190
 
191
+ // socket.on("unavailible", () => {
192
+ // info("Services id=" + socket.id + " unavailible");
193
+ // for (let i = 0; i < current_connections.length; i++) {
194
+ // if (current_connections[i] === socket.id) {
195
+ // current_connections.splice(i, 1);
196
+ // break;
197
+ // }
198
+ // }
199
+ // });
200
 
201
+ // socket.on("delete", async (data) => {
202
+ // info("File Successfully uploaded, writing record");
203
+ // console.log(data); //* The data is comsumed by the IPFS services
204
+
205
+ // try {
206
+ // await prisma.storage.create({
207
+ // data: {
208
+ // handle: data.handle,
209
+ // username: data.username,
210
+ // CID: data.ipfs[0].Hash,
211
+ // dir: data.directory,
212
+ // },
213
+ // });
214
+ // } catch (e) {
215
+ // warn("Creating record fail");
216
+ // }
217
 
218
+ // //* Remove the initial file
219
+ // fs.unlinkSync("uploads/" + data.relative_path);
220
+ // info(`File ${data.relative_path} deleted`);
221
+ // });
222
 
223
+ // socket.on("disconnect", () => {
224
+ // info("A IPFS Services disconnected");
225
+ // clearInterval(interval);
226
+ // //* Removing services when disconnected (died)
227
+ // for (let i = 0; i < current_connections.length; i++) {
228
+ // if (current_connections[i] === socket.id) {
229
+ // current_connections.splice(i, 1);
230
+ // break;
231
+ // }
232
+ // }
233
+ // });
234
+ // });
235
 
236
+ app.use(
237
+ cors({
238
+ origin: "*",
239
  })
240
+ );
241
 
242
+ app.use(bodyParser.json()); //utilizes the body-parser package
243
+ app.use(bodyParser.urlencoded({extended: true}));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
  app.use(statusMonitor);
246
 
247
+ app.use("/upload_queue", express.static("uploads"));
248
 
249
+ app.get(
250
+ "/bee3hivestatuspagethatnoonewillrememberthisurl",
251
+ statusMonitor.pageRoute
252
+ );
253
 
254
  app.post("/auth/email/register", async (req, res) => {
255
  let { username, email, password } = req.body;
256
 
257
+ if (!username || !email || !password) {
258
+ info("Missing required fields registration");
259
+ res.sendStatus(400);
260
  return;
261
  }
262
 
263
+ if (username.length < 6) {
264
+ info("Username: " + username + " is too short!");
265
  res.sendStatus(400);
266
  return;
267
  }
 
272
 
273
  // console.log(username, email, password)
274
 
275
+ if (
276
+ ["admin", "administrator", "root", "user", "anonymous", "guest"].includes(
277
+ username
278
+ )
279
+ ) {
280
+ warn("Username not allowed: " + username);
281
+ res.sendStatus(401);
282
  return;
283
  }
284
 
285
  const record = await prisma.users.findUnique({
286
  where: {
287
+ email: email,
288
+ },
289
+ });
290
 
291
+ if (record) {
292
+ info("User already exists: " + username);
293
+ res.status(400).send({ error: "Username already exists" });
294
  return;
295
  }
296
 
297
  try {
298
+ info(
299
+ "Creating user: " +
300
+ email +
301
+ " username: " +
302
+ username +
303
+ " password: " +
304
+ sha(password) +
305
+ " " +
306
+ new Date()
307
+ );
308
 
309
  const created = await prisma.users.create({
310
  data: {
311
  username: username,
312
  email: email,
313
  password_hash: sha(password),
314
+ last_login: new Date(),
315
+ },
316
+ });
 
 
 
 
 
 
317
 
318
+ info("User created: " + email + " username: " + username);
319
+ res.send({ token: await generateJWT(created.id) });
320
+ return;
321
+ } catch (e) {
322
+ warn("Error on creating users");
323
+ console.log(e);
324
+ res.sendStatus(500);
325
  return;
 
 
 
 
 
326
  }
327
+ });
328
 
329
  app.post("/auth/email/login", async (req, res) => {
330
+ const { email, password } = req.body;
331
 
332
+ if (!email || !password) {
333
+ info("Missing required fields login");
334
+ res.sendStatus(400);
335
+ return;
336
  }
337
 
338
  const record = await prisma.users.findUnique({
339
  where: {
340
+ email: email,
341
+ },
342
+ });
343
 
344
+ if (!record) {
345
+ info("User not found: " + email);
346
+ res.sendStatus(401);
347
+ return;
348
  }
349
 
350
+ if (record.password_hash != sha(password)) {
351
+ warn("Wrong password attempt: " + email);
352
+ res.sendStatus(401);
353
  return;
354
  }
355
 
356
+ info("User logged in: " + email);
357
+ res.send({ token: await generateJWT(record.id) });
358
+ });
359
 
360
  app.use(async (req, res, next) => {
361
+ if (!req.headers.authorization) {
362
+ info("Authorization header not found");
363
+ res.sendStatus(401);
364
  return;
365
  }
366
 
367
  let token;
368
  try {
369
  token = req.headers.authorization.slice(7); // Bearer token
370
+ } catch (e) {
371
+ warn("Parsing token fail");
372
+ console.log(e);
373
  return;
374
  }
375
 
376
+ if (!token) {
377
+ info("Token not found");
378
+ res.sendStatus(401);
379
  return;
380
  }
381
 
382
+ const [tokenHeader, tokenPayload, tokenSig] = token.split(".");
383
 
384
+ if (!tokenHeader || !tokenPayload || !tokenSig) {
385
+ info("Invalid token");
386
+ res.sendStatus(401);
387
  return;
388
  }
389
 
 
398
 
399
  // console.log(header, payload, token_sig, sig)
400
 
401
+ if (sig !== token_sig) {
402
+ warn("Invalid signature");
403
+ res.sendStatus(401);
404
  return;
405
  }
406
 
407
+ if (Date.now() > payload.exp) {
408
+ warn("Token expired");
409
+ res.sendStatus(401);
410
  return;
411
  }
412
 
413
  const record = await prisma.users.findUnique({
414
  where: {
415
+ id: payload.id,
416
+ },
417
+ });
418
 
419
+ if (!record) {
420
+ warn("Record not found");
421
+ res.sendStatus(500); // How?
422
  return;
423
  }
424
 
425
+ info("Authorized: " + record.id);
426
 
427
+ req.user = record;
428
+ next();
429
  return;
430
  } catch (e) {
431
+ console.log(e);
432
+ res.sendStatus(401);
433
  return;
434
  }
435
+ });
436
 
437
  app.post("/auth/me", async (req, res) => {
438
+ if (!Array.isArray(queueFileUpload[req.user.username])) {
439
+ queueFileUpload[req.user.username] = [];
440
  }
441
  // User already authorize
442
+ res.send(req.user);
443
+ });
444
 
445
  app.post("/auth/delete", async (req, res) => {
446
  // User already authorize
447
  const { password } = req.body;
448
 
449
+ if (!password) {
450
+ info("Missing password when deleting user");
451
+ res.sendStatus(400);
452
  return;
453
  }
454
 
455
  // Check password
456
+ if (sha(password) != req.user.password_hash) {
457
+ res.sendStatus(401);
458
  return;
459
  }
460
 
 
462
  try {
463
  await prisma.users.delete({
464
  where: {
465
+ id: req.user.id,
466
+ },
467
+ });
468
  res.sendStatus(200);
469
  return;
470
  } catch (e) {
471
+ warn("Error on deleting user");
472
  console.log(e);
473
  res.sendStatus(500);
474
  return;
475
  }
476
+ });
 
 
 
 
 
 
477
 
478
+ app.post("/file/upload", upload.single("file"), async (req, res) => {
479
+
480
  try {
481
+ const upload_path = req.file.path;
482
+ const file_path = req.body.filePath;
483
+ const full_file_path = req.user.username + (file_path ? "/" + file_path : "");
484
 
 
 
 
 
485
  // Upload the file to another backend
 
 
486
 
487
+ if(services.length == 0) {
488
+ res.status(500).send("Service unavailable");
489
+ return;
490
+ }
491
+
492
+ const server = services[Math.floor(Math.random() * services.length)];
493
+
494
+ const body = {
495
+ filename: file_path,
496
  directory: full_file_path,
497
  username: req.user.username,
498
+ fileURI: req.file.filename,
499
+ }
500
+
501
+ // console.log(body)
502
 
503
+ // Upload the file
504
+ try {
505
+ info("Uploading file to " + server);
506
+ const resp = await fetch(server + "/fetch", {
507
+ method: "POST",
508
+ headers: {
509
+ "Content-Type": "application/json",
510
+ },
511
+ body: JSON.stringify(body),
512
+ });
513
+
514
+ if(!resp.ok) {
515
+ warn(await resp.text());
516
+ res.sendStatus(500);
517
+ return;
518
+ }
519
+
520
+ const json = await resp.json();
521
+ console.log(json)
522
+
523
+ if(await prisma.storage.findUnique({ where: { dir: full_file_path } })) {
524
+ // File already exists and same content
525
+ warn("File already exists. No override: " + full_file_path);
526
+ res.sendStatus(200);
527
+ return;
528
+ }
529
+
530
+ if(await prisma.storage.findUnique({ where: { dir: full_file_path } })) {
531
+ warn("File already exists. Override: " + full_file_path);
532
+ await prisma.storage.update({
533
+ where:{
534
+ dir: full_file_path
535
+ },
536
+
537
+ data: {
538
+ handle: server,
539
+ username: req.user.username,
540
+ CID: json[0].Hash,
541
+ size: +json[0].Size,
542
+ dir: full_file_path,
543
+ }
544
+ })
545
+ } else {
546
+ info("Adding record: " + full_file_path);
547
+ //* Add record
548
+ await prisma.storage.create({
549
+ data: {
550
+ handle: server,
551
+ username: req.user.username,
552
+ CID: json[0].Hash,
553
+ size: +json[0].Size,
554
+ dir: full_file_path,
555
+ }
556
+ })
557
+ }
558
+ } catch (e) {
559
+ warn("Error on uploading file");
560
+ console.log(e);
561
+ res.sendStatus(500);
562
+ fs.unlinkSync(upload_path);
563
+ return;
564
+ }
565
+
566
+ fs.unlinkSync(upload_path);
567
+
568
+ info("File uploaded successfully: " + full_file_path);
569
+ res.send("File uploaded successfully.");
570
  } catch (error) {
571
  // Fail to upload
572
+ warn("File upload failed");
573
+ console.log(error);
574
+ res.status(500).send("File upload failed.");
575
  }
576
+ });
577
+
578
+ app.get("/file/list", async (req, res) => {
579
+ const filePath = req.query.filePath;
580
+ const recursive = req.query.recursive == "true";
581
+ const files = []
582
+
583
+ const setsDirectory = []
584
+
585
+ try{
586
+ const record = await prisma.storage.findMany({
587
+ where: {
588
+ username: req.user.username,
589
+ }
590
+ })
591
+
592
+ for (const r of record) {
593
+ const path = r.dir ? r.dir.split("/") : [];
594
+ // remove first element too
595
+ if(path.length > 1) {
596
+ path.shift();
597
+ path.pop();
598
+ } else {
599
+ path = [];
600
+ }
601
+ // console.log(path)
602
+ let dir = "";
603
+ for (const p of path) {
604
+ dir += p;
605
+ setsDirectory.push({
606
+ type:"directory",
607
+ dir
608
+ });
609
+ }
610
+
611
+ r.type = "file";
612
+
613
+ files.push(r)
614
+ }
615
+ } catch (e) {
616
+ info("No file found")
617
+ console.log(e)
618
+ }
619
+ res.send(files.concat(uniq(setsDirectory)));
620
  })
621
 
622
+ app.post("/file/delete", async (req, res) => {
623
+ const filePath = req.body.filePath;
624
+ const full_file_path = req.user.username + (filePath ? "/" + filePath : "");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
 
 
 
626
 
627
+ const record = await prisma.storage.findUnique({
628
+ where: {
629
+ dir: full_file_path,
630
+ }
631
+ })
632
 
633
+ if(!record) {
634
+ warn("File not found: " + (full_file_path ? (full_file_path + "/") : ""))
635
+ res.status(404).send("File not found.");
636
+ return;
637
+ }
638
 
639
+ try {
640
+ // Tell the server to unpin the file
641
+ const resp = await fetch(record.handle + "/delete", {
642
+ method: "POST",
643
+ headers: {
644
+ "Content-Type": "application/json",
645
+ },
646
+ body: JSON.stringify({
647
+ CID: record.CID
648
+ }),
649
+ })
650
+
651
+ if(!resp.ok) {
652
+ throw "Respone not ok";
653
+ }
654
+
655
+ console.log(await resp.json())
656
+
657
+ await prisma.storage.delete({
658
+ where: {
659
+ CID: record.CID
660
+ }
661
+ })
662
+ } catch (e) {
663
+ console.log(e);
664
+ res.sendStatus(500);
665
+ return;
666
+ }
667
+
668
+ info("File deleted: " + (filePath ? (filePath + "/") : ""))
669
+ res.send("File deleted successfully.");
670
+ })
671
+
672
+ app.post("/file/getdownloadurl", async (req, res) => {
673
+ const filePath = req.body.filePath;
674
+ const full_file_path = req.user.username + (filePath ? "/" + filePath : "");
675
+
676
+
677
+ info("Get download url: " + full_file_path)
678
+
679
+ const record = await prisma.storage.findUnique({
680
+ where: {
681
+ dir: full_file_path
682
+ }
683
+ })
684
+
685
+ if(!record) {
686
+ res.status(404).send("File not found")
687
+ return;
688
+ }
689
 
690
+ try {
691
+ const IPFS_GATEWAY = "https://ipfs.io/ipfs/";
692
+ res.send(IPFS_GATEWAY + record.CID);
693
+ } catch(e) {
694
+ console.log(e);
695
+ res.sendStatus(500)
696
+ }
697
+ })
698
 
699
+ app.listen(7860, () => info("Server started on port 7860"));
prisma/bruh.txt ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
2
+ /// This model contains row level security and requires additional setup for migrations. Visit https://pris.ly/d/row-level-security for more info.
3
+ model Users {
4
+ id BigInt @id @default(autoincrement())
5
+ created_at DateTime @default(now()) @db.Timestamptz(6)
6
+ username String @unique
7
+ password_hash String
8
+ email String? @unique
9
+ phone String?
10
+ last_login DateTime? @db.Time(6)
11
+ }
12
+
13
+ /// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
14
+ /// This model contains row level security and requires additional setup for migrations. Visit https://pris.ly/d/row-level-security for more info.
15
+ model Storage {
16
+ id BigInt @id @default(autoincrement())
17
+ created_at DateTime @default(now()) @db.Timestamptz(6)
18
+ CID String @unique @default("CID")
19
+ username String
20
+ handle String
21
+ dir String? @default("/")
22
+ }
prisma/schema.prisma CHANGED
@@ -27,5 +27,6 @@ model Storage {
27
  CID String @unique @default("CID")
28
  username String
29
  handle String
30
- dir String? @default("/")
31
- }
 
 
27
  CID String @unique @default("CID")
28
  username String
29
  handle String
30
+ dir String? @default("/") @unique
31
+ size Int @default(0)
32
+ }
uploads/Waterxtest.zip DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:9db1781ab02687e4da0e3918b77d311a17869ab4a882a42e761ed7b6d67eed9c
3
- size 84280