-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
148 lines (123 loc) · 5.08 KB
/
index.js
File metadata and controls
148 lines (123 loc) · 5.08 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(async()=>{
"use strict";
// Dependencies
const client = await require("./modules/mongodb.js")
const { rateLimit } = require("express-rate-limit")
const simpleAES256 = require("simple-aes-256")
const cookieParser = require("cookie-parser")
const compression = require("compression")
const { parse } = require("smol-toml")
const express = require("express")
const hashJS = require("hash.js")
const helmet = require("helmet")
const cryptr = require("cryptr")
const path = require("path")
const fs = require("fs")
// Variables
const settings = parse(fs.readFileSync(path.join(__dirname, "settings.toml"), "utf8"))
const web = express()
const port = process.env.PORT || 8080
const limiter = rateLimit({
windowMs: 10 * 60 * 1000, // 10 Minutes
limit: 300,
standardHeaders: "draft-8",
legacyHeaders: false,
ipv6Subnet: 56
})
const db = client.db(settings.database.databaseName)
const pads = db.collection(settings.database.collectionName)
const cT = new cryptr(settings.security.cookieMasterKey, { encoding: "hex", pbkdf2Iterations: settings.security.cookiePBKDF2Iterations, saltLength: settings.security.saltLength })
// Functions
const SHA512 = (string)=>{return hashJS.sha512().update(string).digest("hex")}
const setCookie = (res, data)=>{
res.cookie("d", data, {
maxAge: 30 * 60 * 1000, // 30 Minutes
httpOnly: true,
secure: process.env.NODE_ENV === "production"
})
}
const dS = async(session)=>{
try{
const sessionData = JSON.parse(cT.decrypt(session.d))
return sessionData
}catch{return false}
}
// Configurations
//* Express
web.use(limiter)
web.use(helmet({ contentSecurityPolicy: false }))
web.set("trust proxy", 1)
web.use(cookieParser())
web.use(compression({ level: 1 }))
web.use(express.json({ limit: "15mb" }))
// Main
web.use((req, res, next)=>{
if(req.path.match(".html")) return res.redirect(req.path.replace(".html", ""))
next()
})
web.get("/note", async(req, res, next)=>{
if(!(await dS(req.cookies))) return res.redirect("/")
next()
})
web.use(express.static(path.join(__dirname, "public"), { extensions: ["html"] }))
web.get("/api/cc", async(req, res)=>{
res.clearCookie("d")
res.redirect("/")
})
web.post("/api/open-pad", async(req, res)=>{
var { primaryKey, code, password, location } = req.body
if(!primaryKey || !code || !password || !location) return res.send("0")
primaryKey = primaryKey.slice(0, 500); code = code.slice(0, 500); password = password.slice(0, 500); location = location.slice(0, 500);
const realPassword = `${primaryKey}${code}${password}`
primaryKey = SHA512(primaryKey); code = SHA512(code); password = SHA512(password); location = `${SHA512(location)}${settings.security.garbageKey}`
location = `${primaryKey}${code}${location}`
const data = await pads.findOne({ location: location })
if(!data) await pads.insertOne({ location: location, content: "" })
const cookieData = {
location: location,
password: realPassword
}
setCookie(res, cT.encrypt(JSON.stringify(cookieData)))
res.send("success")
})
web.post("/api/save-pad", async(req, res)=>{
if(!(await dS(req.cookies))) return res.send("failed")
const { content } = req.body
var cookieData = await dS(req.cookies)
const data = await pads.findOne({ location: cookieData.location })
if(content.length > 100000) return res.send("0") // Max of content that can be stored is 100k characters.
if(data){
await pads.updateOne({ location: cookieData.location }, {
$set: {
content: simpleAES256.encrypt(cookieData.password, content).toString("hex")
}
})
}else{
return res.redirect("/")
}
res.send("success")
})
web.get("/api/nuke-pad", async(req, res)=>{
if(!(await dS(req.cookies))) return res.redirect("/")
var cookieData = await dS(req.cookies)
const data = await pads.findOne({ location: cookieData.location })
if(data) await pads.deleteOne({ location: cookieData.location })
res.clearCookie("d").redirect("/")
})
web.get("/api/view-pad", async(req, res)=>{
if(!(await dS(req.cookies))) return res.send("failed")
var cookieData = await dS(req.cookies)
const data = await pads.findOne({ location: cookieData.location })
if(data){
if(data.content){
res.send(simpleAES256.decrypt(cookieData.password, Buffer.from(data.content, "hex")))
}else{
res.send("This pad is empty.")
}
}else{
return res.redirect("/")
}
})
web.use("/{*any}", (req, res)=>res.redirect("/"))
web.listen(settings.web.port, ()=>console.log(`Server is running. Port: ${port}`))
})()