-
Notifications
You must be signed in to change notification settings - Fork 7
/
server.js
139 lines (128 loc) · 3.63 KB
/
server.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
const { promisify } = require("util");
const randomBytes = promisify(require("crypto").randomBytes);
const path = require("path");
const express = require("express");
const axios = require("axios");
const localtunnel = require("localtunnel");
const app = express();
const port = 8080;
let computer;
let hasPremium = false;
function updateComputerTimeout(comp, timeout) {
const headers = {
Authorization: `Bearer ${comp.admin_token}`,
};
const computerBaseUrl = comp.embed_url.split("?")[0];
return axios.post(`${computerBaseUrl}/timeout`, timeout, { headers });
}
function listen(webhookUrl, bearer) {
app.use(express.json());
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "/index.html"));
});
app.post("/upgrade", async (req, res) => {
hasPremium = true;
if (computer) {
try {
await updateComputerTimeout(computer, {
offline: 30, // 30 seconds
inactive: 60, // 60 seconds
absolute: 60 * 60 * 2, // null // set the value to "null" to eliminate the timeout
});
} catch (e) {
console.error("updateComputerTimeout failed:", e);
}
}
console.log("Upgraded to premium");
res.sendStatus(200);
});
app.post("/cancel", async (req, res) => {
hasPremium = false;
if (computer) {
try {
await updateComputerTimeout(computer, {
offline: 10, // 10 seconds
inactive: 30, // 30 seconds
absolute: 60, // 60 seconds
reset: false,
});
} catch (e) {
console.error("updateComputerTimeout failed:", e);
}
}
console.log("Cancelled premium");
res.sendStatus(200);
});
app.get("/computer", async (req, res) => {
if (computer) {
res.send(computer);
return;
}
const settings = {
ublock: true,
// Timeout values are in seconds
// In this example, we pick low values so you can quickly see the timeouts in action
timeout: {
offline: 10, // 10 seconds
inactive: 30, // 30 seconds
absolute: 60, // 60 seconds
warning: 15, // 15 seconds
webhook: {
url: webhookUrl,
bearer,
},
},
};
const headers = {
Authorization: `Bearer ${process.env.HB_API_KEY}`,
};
const resp = await axios.post(
"https://engine.hyperbeam.com/v0/vm",
settings,
{ headers }
);
computer = resp.data;
res.send({
hasPremium,
computer,
});
});
app.post("/webhook", async (req, res) => {
const { session_id, type } = req.body;
const incomingBearer = req.get("Authorization").slice(7); // Slice off "Bearer " prefix
if (bearer !== incomingBearer) {
console.log(`Incorrect incoming bearer token, token=${incomingBearer}`);
res.sendStatus(401);
return;
}
console.log(
`Hyperbeam computer with session_id=${session_id} timed out, timeout type=${type}`
);
computer = undefined;
res.sendStatus(200);
});
app.listen(port, () => {
console.log(`Server started at http://localhost:${port.toString()}`);
});
}
async function main() {
let bearerBytes;
try {
bearerBytes = await randomBytes(32);
} catch (e) {
console.error(
"crypto failed to generate 32 random bytes for webhook token:",
e
);
return;
}
try {
const tunnel = await localtunnel({ port });
const bearer = Buffer.from(bearerBytes).toString("base64");
console.log(`Receiving webhook messages from ${tunnel.url}`);
listen(`${tunnel.url}/webhook`, bearer);
} catch (e) {
console.error(`localtunnel failed to expose port ${port.toString()}:`, e);
}
}
main();