add multiprobe to the multiprobe site :)
This commit is contained in:
parent
0787dfda47
commit
1b99440d70
22 changed files with 83 additions and 19 deletions
|
@ -5,7 +5,7 @@
|
||||||
"metrics": 9100
|
"metrics": 9100
|
||||||
},
|
},
|
||||||
"session": {
|
"session": {
|
||||||
"validity": 86400,
|
"validity": 86400000,
|
||||||
"length": 64,
|
"length": 64,
|
||||||
"secret": "changeme"
|
"secret": "changeme"
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@ import Controller from "./Controller";
|
||||||
|
|
||||||
// for Git server lookup
|
// for Git server lookup
|
||||||
let cachedVersion = "";
|
let cachedVersion = "";
|
||||||
|
let cachedClient = "";
|
||||||
let cacheExpiry = 0;
|
let cacheExpiry = 0;
|
||||||
|
|
||||||
export default class ApiController extends Controller {
|
export default class ApiController extends Controller {
|
||||||
|
@ -31,7 +32,7 @@ export default class ApiController extends Controller {
|
||||||
} else {
|
} else {
|
||||||
const response = await fetch(`http://${Config.githost}/tgpholly/t00-multiuser/raw/branch/master/client/Terminal-00-Multiuser.user.js?${Date.now()}`);
|
const response = await fetch(`http://${Config.githost}/tgpholly/t00-multiuser/raw/branch/master/client/Terminal-00-Multiuser.user.js?${Date.now()}`);
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
const content = await response.text();
|
const content = cachedClient = await response.text();
|
||||||
if (content.includes("@version")) {
|
if (content.includes("@version")) {
|
||||||
cachedVersion = content.split("@version")[1].split("\n")[0].trim().split(".").join("");
|
cachedVersion = content.split("@version")[1].split("\n")[0].trim().split(".").join("");
|
||||||
cacheExpiry = Date.now() + 30000;
|
cacheExpiry = Date.now() + 30000;
|
||||||
|
@ -44,4 +45,18 @@ export default class ApiController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async LatestClient_Get() {
|
||||||
|
if (Date.now() < cacheExpiry) {
|
||||||
|
this.ok(cachedClient);
|
||||||
|
} else {
|
||||||
|
const response = await fetch(`http://${Config.githost}/tgpholly/t00-multiuser/raw/branch/master/client/Terminal-00-Multiuser.user.js?${Date.now()}`);
|
||||||
|
if (response.status === 200) {
|
||||||
|
cachedClient = await response.text();
|
||||||
|
return this.ok(cachedClient);
|
||||||
|
} else {
|
||||||
|
return this.badRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -66,6 +66,17 @@ export default abstract class Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.header("X-Powered-By", "MultiProbe");
|
||||||
|
if (controllerName !== "api") {
|
||||||
|
res.header("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
|
||||||
|
res.header("X-XSS-Protection", "1; mode=block");
|
||||||
|
res.header("Permissions-Policy", "microphone=(), geolocation=(), magnetometer=(), camera=(), payment=(), usb=(), accelerometer=(), gyroscope=()");
|
||||||
|
res.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
||||||
|
res.header("Content-Security-Policy", "block-all-mixed-content;frame-ancestors 'self'");
|
||||||
|
res.header("X-Frame-Options", "SAMEORIGIN");
|
||||||
|
res.header("X-Content-Type-Options", "nosniff");
|
||||||
|
}
|
||||||
|
|
||||||
const requestCtx = new RequestCtx(req, res, controllerName, methodName, session);
|
const requestCtx = new RequestCtx(req, res, controllerName, methodName, session);
|
||||||
controllerRequestHandler.bind(requestCtx)(req.method === "GET" ? req.query : req.body);
|
controllerRequestHandler.bind(requestCtx)(req.method === "GET" ? req.query : req.body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,13 @@ fastify.register(FastifyStatic, {
|
||||||
});
|
});
|
||||||
|
|
||||||
fastify.setNotFoundHandler(async (req, res) => {
|
fastify.setNotFoundHandler(async (req, res) => {
|
||||||
|
res.header("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
|
||||||
|
res.header("X-XSS-Protection", "1; mode=block");
|
||||||
|
res.header("Permissions-Policy", "microphone=(), geolocation=(), magnetometer=(), camera=(), payment=(), usb=(), accelerometer=(), gyroscope=()");
|
||||||
|
res.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
||||||
|
res.header("Content-Security-Policy", "block-all-mixed-content;frame-ancestors 'self'");
|
||||||
|
res.header("X-Frame-Options", "SAMEORIGIN");
|
||||||
|
res.header("X-Content-Type-Options", "nosniff");
|
||||||
return res.status(404).view("views/404.ejs", { });
|
return res.status(404).view("views/404.ejs", { });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ export default abstract class Session {
|
||||||
validPeriod.setTime(validPeriod.getTime() + Config.session.validity);
|
validPeriod.setTime(validPeriod.getTime() + Config.session.validity);
|
||||||
const key = randomBytes(Config.session.length).toString("hex");
|
const key = randomBytes(Config.session.length).toString("hex");
|
||||||
|
|
||||||
Session.Sessions.set(key, new SessionUser(user.Id, user.Username, user.UserLevel, validPeriod));
|
Session.Sessions.set(key, new SessionUser(user.Id, user.Username, user.UserLevel, user.APIKey, validPeriod));
|
||||||
|
|
||||||
res.setCookie("MP_SESSION", key, {
|
res.setCookie("MP_SESSION", key, {
|
||||||
path: "/",
|
path: "/",
|
||||||
|
|
|
@ -4,12 +4,14 @@ export default class SessionUser {
|
||||||
public readonly userId:number;
|
public readonly userId:number;
|
||||||
public readonly username:string;
|
public readonly username:string;
|
||||||
public readonly userLevel:UserLevel;
|
public readonly userLevel:UserLevel;
|
||||||
|
public readonly apiKey:string;
|
||||||
public readonly validityPeriod:Date;
|
public readonly validityPeriod:Date;
|
||||||
|
|
||||||
constructor(userId:number, username:string, userLevel:UserLevel, validityPeriod:Date) {
|
constructor(userId:number, username:string, userLevel:UserLevel, apiKey:string, validityPeriod:Date) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.userLevel = userLevel;
|
this.userLevel = userLevel;
|
||||||
|
this.apiKey = apiKey;
|
||||||
this.validityPeriod = validityPeriod;
|
this.validityPeriod = validityPeriod;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
<%- include("base/header", { title: "404"}) %>
|
<%- include("base/header", { title: "404" }) %>
|
||||||
<h1 class="text-center" style="font-size:10rem">404!</h1>
|
<h1 class="text-center" style="font-size:10rem">404!</h1>
|
||||||
<%- include("base/footer") %>
|
<%- include("base/footer") %>
|
|
@ -22,4 +22,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -76,4 +76,4 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -46,4 +46,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -53,4 +53,4 @@
|
||||||
<a class="btn btn-primary btn-lg me-2 mb-3" href="/admin/wssessions">Websocket Sessions</a>
|
<a class="btn btn-primary btn-lg me-2 mb-3" href="/admin/wssessions">Websocket Sessions</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -45,4 +45,4 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -40,4 +40,4 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -51,4 +51,4 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -58,4 +58,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -45,4 +45,4 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -42,4 +42,4 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -40,4 +40,4 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -1,4 +1,33 @@
|
||||||
</div>
|
</div>
|
||||||
|
<% if (typeof(apiKey) !== "undefined" && typeof(username) !== "undefined") { %>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
cursor: unset!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html mp_button, html mp_container, html mp_party {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html mp_cursor mp_container {
|
||||||
|
display: unset!important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
localStorage["t00mp_username"] = `<%= username %>`;
|
||||||
|
localStorage.mpconnectonload = "true";
|
||||||
|
localStorage.mpshowfirsttime = "false";
|
||||||
|
localStorage.mpapikey = `<%= apiKey %>`;
|
||||||
|
</script>
|
||||||
|
<script src="/api/latestclient?<%= Date.now() %>"></script>
|
||||||
|
<% } else { %>
|
||||||
|
<script>
|
||||||
|
localStorage["t00mp_username"] = "";
|
||||||
|
localStorage.mpconnectonload = "true";
|
||||||
|
localStorage.mpshowfirsttime = "false";
|
||||||
|
localStorage.mpapikey = "";
|
||||||
|
</script>
|
||||||
|
<% } %>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cookieconsent/3.1.1/cookieconsent.min.js" integrity="sha512-yXXqOFjdjHNH1GND+1EO0jbvvebABpzGKD66djnUfiKlYME5HGMUJHoCaeE4D5PTG2YsSJf6dwqyUUvQvS0vaA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/cookieconsent/3.1.1/cookieconsent.min.js" integrity="sha512-yXXqOFjdjHNH1GND+1EO0jbvvebABpzGKD66djnUfiKlYME5HGMUJHoCaeE4D5PTG2YsSJf6dwqyUUvQvS0vaA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script>
|
<script>
|
||||||
(() => {
|
(() => {
|
||||||
|
|
|
@ -87,4 +87,4 @@
|
||||||
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
|
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
|
||||||
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl, { html: true }));
|
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl, { html: true }));
|
||||||
</script>
|
</script>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -29,4 +29,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
|
@ -21,4 +21,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%- include("../base/footer") %>
|
<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %>
|
Loading…
Reference in a new issue