Merge branch '1.23.X'

# Conflicts:
#	package-lock.json
#	server/database.js
#	server/server.js
#	server/util-server.js
This commit is contained in:
Louis Lam
2023-10-09 21:28:01 +08:00
12 changed files with 100 additions and 33 deletions

View File

@@ -85,6 +85,7 @@ class Database {
"patch-monitor-oauth-cc.sql": true,
"patch-add-timeout-monitor.sql": true,
"patch-add-gamedig-given-port.sql": true, // The last file so far converted to a knex migration file
"patch-notification-config.sql": true,
};
/**

View File

@@ -56,7 +56,7 @@ class Monitor extends BeanModel {
obj.tags = await this.getTags();
}
if (certExpiry && this.type === "http" && this.getURLProtocol() === "https:") {
if (certExpiry && (this.type === "http" || this.type === "keyword" || this.type === "json-query") && this.getURLProtocol() === "https:") {
const { certExpiryDaysRemaining, validCert } = await this.getCertExpiry(this.id);
obj.certExpiryDaysRemaining = certExpiryDaysRemaining;
obj.validCert = validCert;

View File

@@ -1,6 +1,8 @@
const { BeanModel } = require("redbean-node/dist/bean-model");
const passwordHash = require("../password-hash");
const { R } = require("redbean-node");
const jwt = require("jsonwebtoken");
const { shake256, SHAKE256_LENGTH } = require("../util-server");
class User extends BeanModel {
/**
@@ -27,6 +29,19 @@ class User extends BeanModel {
this.password = newPassword;
}
/**
* Create a new JWT for a user
* @param {User} user
* @param {string} jwtSecret
* @return {string}
*/
static createJWT(user, jwtSecret) {
return jwt.sign({
username: user.username,
h: shake256(user.password, SHAKE256_LENGTH),
}, jwtSecret);
}
}
module.exports = User;

View File

@@ -1,5 +1,12 @@
let express = require("express");
const { allowDevAllOrigin, allowAllOrigin, percentageToColor, filterAndJoin, sendHttpError } = require("../util-server");
const {
setting,
allowDevAllOrigin,
allowAllOrigin,
percentageToColor,
filterAndJoin,
sendHttpError,
} = require("../util-server");
const { R } = require("redbean-node");
const apicache = require("../modules/apicache");
const Monitor = require("../model/monitor");
@@ -23,10 +30,14 @@ router.get("/api/entry-page", async (request, response) => {
allowDevAllOrigin(response);
let result = { };
let hostname = request.hostname;
if ((await setting("trustProxy")) && request.headers["x-forwarded-host"]) {
hostname = request.headers["x-forwarded-host"];
}
if (request.hostname in StatusPage.domainMappingList) {
if (hostname in StatusPage.domainMappingList) {
result.type = "statusPageMatchedDomain";
result.statusPageSlug = StatusPage.domainMappingList[request.hostname];
result.statusPageSlug = StatusPage.domainMappingList[hostname];
} else {
result.type = "entryPage";
result.entryPage = server.entryPage;

View File

@@ -78,9 +78,10 @@ const app = server.app;
log.info("server", "Importing this project modules");
log.debug("server", "Importing Monitor");
const Monitor = require("./model/monitor");
const User = require("./model/user");
log.debug("server", "Importing Settings");
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, FBSD, doubleCheckPassword, startE2eTests,
allowDevAllOrigin
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword, startE2eTests, shake256, SHAKE256_LENGTH, allowDevAllOrigin,
} = require("./util-server");
log.debug("server", "Importing Notification");
@@ -326,6 +327,11 @@ let needSetup = false;
decoded.username,
]);
// Check if the password changed
if (decoded.h !== shake256(user.password, SHAKE256_LENGTH)) {
throw new Error("The token is invalid due to password change or old token");
}
if (user) {
log.debug("auth", "afterLogin");
afterLogin(socket, user);
@@ -347,9 +353,10 @@ let needSetup = false;
});
}
} catch (error) {
log.error("auth", `Invalid token. IP=${clientIP}`);
if (error.message) {
log.error("auth", error.message, `IP=${clientIP}`);
}
callback({
ok: false,
msg: "authInvalidToken",
@@ -389,9 +396,7 @@ let needSetup = false;
callback({
ok: true,
token: jwt.sign({
username: data.username,
}, server.jwtSecret),
token: User.createJWT(user, server.jwtSecret),
});
}
@@ -419,9 +424,7 @@ let needSetup = false;
callback({
ok: true,
token: jwt.sign({
username: data.username,
}, server.jwtSecret),
token: User.createJWT(user, server.jwtSecret),
});
} else {

View File

@@ -36,6 +36,7 @@ const rl = readline.createInterface({ input: process.stdin,
// SASLOptions used in JSDoc
// eslint-disable-next-line no-unused-vars
const { Kafka, SASLOptions } = require("kafkajs");
const crypto = require("crypto");
const isWindows = process.platform === /^win/.test(process.platform);
/**
@@ -290,22 +291,22 @@ exports.kafkaProducerAsync = function (brokers, topic, message, options = {}, sa
producer.connect().then(
() => {
try {
producer.send({
topic: topic,
messages: [{
value: message,
}],
});
connectedToKafka = true;
clearTimeout(timeoutID);
producer.send({
topic: topic,
messages: [{
value: message,
}],
}).then((_) => {
resolve("Message sent successfully");
} catch (e) {
}).catch((e) => {
connectedToKafka = true;
producer.disconnect();
clearTimeout(timeoutID);
reject(new Error("Error sending message: " + e.message));
}
}).finally(() => {
connectedToKafka = true;
clearTimeout(timeoutID);
});
}
).catch(
(e) => {
@@ -317,8 +318,10 @@ exports.kafkaProducerAsync = function (brokers, topic, message, options = {}, sa
);
producer.on("producer.network.request_timeout", (_) => {
clearTimeout(timeoutID);
reject(new Error("producer.network.request_timeout"));
if (!connectedToKafka) {
clearTimeout(timeoutID);
reject(new Error("producer.network.request_timeout"));
}
});
producer.on("producer.disconnect", (_) => {
@@ -1060,6 +1063,23 @@ module.exports.grpcQuery = async (options) => {
});
};
module.exports.SHAKE256_LENGTH = 16;
/**
*
* @param {string} data
* @param {number} len
* @return {string}
*/
module.exports.shake256 = (data, len) => {
if (!data) {
return "";
}
return crypto.createHash("shake256", { outputLength: len })
.update(data)
.digest("hex");
};
module.exports.prompt = (query) => new Promise((resolve) => rl.question(query, resolve));
// For unit test, export functions