diff --git a/server/config.example.json b/server/config.example.json index a3356b7..946536b 100644 --- a/server/config.example.json +++ b/server/config.example.json @@ -5,7 +5,7 @@ "metrics": 9100 }, "session": { - "validity": 86400, + "validity": 86400000, "length": 64, "secret": "changeme" }, diff --git a/server/controller/ApiController.ts b/server/controller/ApiController.ts index bc6b4af..7caa5a7 100644 --- a/server/controller/ApiController.ts +++ b/server/controller/ApiController.ts @@ -5,6 +5,7 @@ import Controller from "./Controller"; // for Git server lookup let cachedVersion = ""; +let cachedClient = ""; let cacheExpiry = 0; export default class ApiController extends Controller { @@ -31,7 +32,7 @@ export default class ApiController extends Controller { } 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) { - const content = await response.text(); + const content = cachedClient = await response.text(); if (content.includes("@version")) { cachedVersion = content.split("@version")[1].split("\n")[0].trim().split(".").join(""); 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(); + } + } + } } \ No newline at end of file diff --git a/server/controller/Controller.ts b/server/controller/Controller.ts index 93e49e9..f83aa4d 100644 --- a/server/controller/Controller.ts +++ b/server/controller/Controller.ts @@ -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); controllerRequestHandler.bind(requestCtx)(req.method === "GET" ? req.query : req.body); } diff --git a/server/index.ts b/server/index.ts index c342037..7443753 100644 --- a/server/index.ts +++ b/server/index.ts @@ -120,6 +120,13 @@ fastify.register(FastifyStatic, { }); 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", { }); }); diff --git a/server/objects/Session.ts b/server/objects/Session.ts index 78fc482..7cb1acd 100644 --- a/server/objects/Session.ts +++ b/server/objects/Session.ts @@ -37,7 +37,7 @@ export default abstract class Session { validPeriod.setTime(validPeriod.getTime() + Config.session.validity); 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, { path: "/", diff --git a/server/objects/SessionUser.ts b/server/objects/SessionUser.ts index 1d39c43..8101024 100644 --- a/server/objects/SessionUser.ts +++ b/server/objects/SessionUser.ts @@ -4,12 +4,14 @@ export default class SessionUser { public readonly userId:number; public readonly username:string; public readonly userLevel:UserLevel; + public readonly apiKey:string; 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.username = username; this.userLevel = userLevel; + this.apiKey = apiKey; this.validityPeriod = validityPeriod; } } \ No newline at end of file diff --git a/server/views/404.ejs b/server/views/404.ejs index 8463cb0..7aaa283 100644 --- a/server/views/404.ejs +++ b/server/views/404.ejs @@ -1,3 +1,3 @@ -<%- include("base/header", { title: "404"}) %> +<%- include("base/header", { title: "404" }) %>

404!

<%- include("base/footer") %> \ No newline at end of file diff --git a/server/views/account/changeusername.ejs b/server/views/account/changeusername.ejs index 708c2d7..454c420 100644 --- a/server/views/account/changeusername.ejs +++ b/server/views/account/changeusername.ejs @@ -22,4 +22,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/badge.ejs b/server/views/admin/badge.ejs index ba575af..497a114 100644 --- a/server/views/admin/badge.ejs +++ b/server/views/admin/badge.ejs @@ -76,4 +76,4 @@ }); -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/badges.ejs b/server/views/admin/badges.ejs index d761cab..3983746 100644 --- a/server/views/admin/badges.ejs +++ b/server/views/admin/badges.ejs @@ -46,4 +46,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/index.ejs b/server/views/admin/index.ejs index cae32d2..9ca2bfe 100644 --- a/server/views/admin/index.ejs +++ b/server/views/admin/index.ejs @@ -53,4 +53,4 @@ Websocket Sessions -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/parties.ejs b/server/views/admin/parties.ejs index 6fa4336..1fbd44d 100644 --- a/server/views/admin/parties.ejs +++ b/server/views/admin/parties.ejs @@ -45,4 +45,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/party.ejs b/server/views/admin/party.ejs index 33c4236..51ea82f 100644 --- a/server/views/admin/party.ejs +++ b/server/views/admin/party.ejs @@ -40,4 +40,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/user.ejs b/server/views/admin/user.ejs index 9606178..13d981c 100644 --- a/server/views/admin/user.ejs +++ b/server/views/admin/user.ejs @@ -51,4 +51,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/userbadges.ejs b/server/views/admin/userbadges.ejs index c2f105a..e03d9d8 100644 --- a/server/views/admin/userbadges.ejs +++ b/server/views/admin/userbadges.ejs @@ -58,4 +58,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/users.ejs b/server/views/admin/users.ejs index ebd0857..cb459c6 100644 --- a/server/views/admin/users.ejs +++ b/server/views/admin/users.ejs @@ -45,4 +45,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/websessions.ejs b/server/views/admin/websessions.ejs index fa4560d..f01e3d5 100644 --- a/server/views/admin/websessions.ejs +++ b/server/views/admin/websessions.ejs @@ -42,4 +42,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/admin/wssessions.ejs b/server/views/admin/wssessions.ejs index e82f185..34cf42a 100644 --- a/server/views/admin/wssessions.ejs +++ b/server/views/admin/wssessions.ejs @@ -40,4 +40,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/base/footer.ejs b/server/views/base/footer.ejs index a716a9a..f2fc928 100644 --- a/server/views/base/footer.ejs +++ b/server/views/base/footer.ejs @@ -1,4 +1,33 @@ +<% if (typeof(apiKey) !== "undefined" && typeof(username) !== "undefined") { %> + + + +<% } else { %> + +<% } %> -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/party/createEdit.ejs b/server/views/party/createEdit.ejs index 6239e0d..2b81d69 100644 --- a/server/views/party/createEdit.ejs +++ b/server/views/party/createEdit.ejs @@ -29,4 +29,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file diff --git a/server/views/party/join.ejs b/server/views/party/join.ejs index 74296a7..66f045e 100644 --- a/server/views/party/join.ejs +++ b/server/views/party/join.ejs @@ -21,4 +21,4 @@ -<%- include("../base/footer") %> \ No newline at end of file +<%- include("../base/footer", { apiKey: session.apiKey, username: session.username }) %> \ No newline at end of file