-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
159 lines (145 loc) · 6.37 KB
/
index.js
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
149
150
151
152
153
154
155
156
157
158
159
const express = require('express')
const cookieParser = require('cookie-parser')
const StormDB = require("stormdb")
const fetch = require('cross-fetch')
const { Server } = require("socket.io")
const { createServer } = require("http")
require('dotenv').config({ path: './.env' })
const app = express()
const port = process.env.PORT
const httpServer = createServer(app);
const io = new Server(httpServer,{
cors: {
origin: "*",
}
});
const engine = new StormDB.localFileEngine(process.env.DBPATH)
const db = new StormDB(engine)
db.default({ users: []}).save()
app.use(cookieParser())
app.use(express.json())
app.use(express.urlencoded({extended: false}))
var connectedusers = {}
function Authenticate(req, resp, callback, failcallback=(err)=>{res.send(JSON.stringify({"success":false,"error":"Token is invalid or has expired!"}))}){
fetch(`https://discord.com/api/v8/oauth2/@me`,{headers: {'Authorization':`Bearer ${req.headers.token}`}})
.then(res => {
if (res.status >= 400) {
const err = new Error("Bad response from server")
err.code = res.status
throw err
}
return res.json();
})
.then(res => {
if(res.application.id === process.env.DISCORD_APP_ID) {
var users = db.get("users").value()
var user = users.find(user => user.discordid == res.user.id)
if(user==undefined){
var newuser = {
discordid:res.user.id,
username:res.user.username,
}
console.log("User does not exist but the token is valid\nCreating user account...")
db.get("users").push(newuser).save()
var user = users.find(user => user.discordid == res.user.id)
callback(user,req,resp)
}else{
callback(user,req,resp)
}
}else{
failcallback(req,resp)
}
})
.catch(err => {failcallback(req,resp,err)})
}
app.post('/auth/gettoken', (req,res)=>{
var details = {
'client_id': process.env.DISCORD_APP_ID,
'client_secret': process.env.DISCORD_APP_SECRET,
'grant_type': 'authorization_code',
'code':req.body.code,
'redirect_uri':process.env.DISCORD_APP_REDIRECT_URI
}
var formBody = []
for (var property in details) {
var encodedKey = encodeURIComponent(property)
var encodedValue = encodeURIComponent(details[property])
formBody.push(encodedKey + "=" + encodedValue)
}
formBody = formBody.join("&")
fetch(`https://discord.com/api/v8/oauth2/token`,{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: formBody
}).then(resp => {
if (resp.status >= 400) {
const err = new Error("Bad response from server")
err.code = resp.status
throw err
}
return resp.json();
}
)
.then(resp => {
res.send(JSON.stringify({success: true, token: resp.access_token}))
}).catch(err => {
res.send(JSON.stringify({success: false, error: "Invalid OAuth 2.0 code"}))
})
})
io.on("connection", socket => {
console.log("\nUser "+socket.id+" trying to connect to websocket server...")
const token = socket.handshake.auth.token;
Authenticate({headers: {'token':token}},undefined,(userinfo)=>{
socket.emit("userinfo", userinfo)
console.log("User "+socket.id+" was authorized as "+userinfo.username+"("+userinfo.discordid+")")
connectedusers[socket.id] = userinfo
socket.on("joinrequest", joindata => {
console.log(`\nUser ${userinfo.username}(${socket.id}) is trying to join user ${joindata.userid}`)
var users = db.get("users").value()
var user = users.find(user => user.discordid == joindata.userid)
if(user==undefined){
console.log("User does not exist, sending rejection")
socket.emit("joinresponse",{accepted:false,error:"Invalid token"})
}else{
socketid = Object.keys(connectedusers)[Object.values(connectedusers).findIndex(fuser => fuser.discordid == joindata.userid)]
if(connectedusers[socketid].ongoingjoin || connectedusers[socket.id].ongoingjoin){
console.log("One of the users has an ongoing join request, sending rejection")
socket.emit("joinresponse",{accepted:false,error:"User is joining/being joined"})
}else{
console.log("User intent verified, sending decision prompt")
connectedusers[socketid].ongoingjoin = true
connectedusers[socket.id].ongoingjoin = true
joininguserid = userinfo.discordid
io.to(socketid).emit("requestjoinresponse",{...joindata,name:userinfo.username,userid:joininguserid})
}
}
})
socket.on("sendjoinresponse", joinresponse => {
console.log(`\nUser ${userinfo.username} is trying to respond to join request`)
socketid = Object.keys(connectedusers)[Object.values(connectedusers).findIndex(user => user.discordid == joinresponse.userid)]
if(connectedusers[socket.id].ongoingjoin && connectedusers[socketid].ongoingjoin){
console.log(`User intent verified, sending join response to ${socketid}\nUser will join: ${joinresponse.packet.accepted}`)
io.to(socketid).emit("joinresponse",{name:userinfo.username,userid:userinfo.discordid,...joinresponse.packet})
connectedusers[socketid].ongoingjoin = false
connectedusers[socket.id].ongoingjoin = false
}else{
console.log("Unauthorized join response from "+connectedusers[socket.id].username+" to "+connectedusers[socketid].username)
}
})
socket.on("disconnect", (reason) => {
console.log("\nUser "+socket.id+" disconnected because of "+reason)
delete connectedusers[socket.id]
})
},()=>{
console.log("User "+socket.id+" was not authorized and will be disconnected")
socket.disconnect(true)
})
});
app.get("/",(req,res) =>{
res.send(`<script src="/socket.io/socket.io.js"></script>`)
})
//setInterval(console.log,10000,connectedusers)
httpServer.listen(port)
console.log("Server listening on port "+port)