Merge pull request #3121 from web-engineer/fix/3120-data-leak

3120 remove URL's from data when they are supposed to be disabled
This commit is contained in:
Alexander Holliday
2026-01-15 14:24:47 -08:00
committed by GitHub
8 changed files with 33 additions and 28 deletions
+1
View File
@@ -56,6 +56,7 @@ const useSaveSettings = ({
setEmailPasswordHasBeenReset(false);
}
setSettingsData(settingsResponse.data.data);
createToast({ body: t("settingsSuccessSaved") });
} catch (error) {
createToast({ body: t("settingsFailedToSave") });
+13 -20
View File
@@ -75,11 +75,6 @@ const Settings = () => {
const handleChange = async (e) => {
const { name, value, checked } = e.target;
// Special case for showURL until handled properly in the backend
if (name === "showURL") {
dispatch(setShowURL(value));
return;
}
let newValue;
if (
name === "systemEmailIgnoreTLS" ||
@@ -90,6 +85,12 @@ const Settings = () => {
) {
newValue = checked;
}
// Ensure showURL is a proper boolean
if (name === "showURL") {
newValue = value === true || value === "true";
}
// Build next state early
const newSettingsData = {
...settingsData,
@@ -147,29 +148,22 @@ const Settings = () => {
return;
}
// Validate
const { error } = settingsValidation.validate(newSettingsData.settings, {
abortEarly: false,
});
if (!error || error.details.length === 0) {
setErrors({});
} else {
const newErrors = {};
error.details.forEach((err) => {
newErrors[err.path[0]] = err.message;
});
setErrors(newErrors);
}
setSettingsData(newSettingsData);
// Update Redux immediately for UI feedback
if (name === "showURL") {
dispatch(setShowURL(newValue));
}
};
const handleSave = () => {
// Validate
const { error } = settingsValidation.validate(settingsData.settings, {
abortEarly: false,
});
if (!error || error.details.length === 0) {
setErrors({});
saveSettings(settingsData?.settings);
} else {
const newErrors = {};
error.details.forEach((err) => {
@@ -178,7 +172,6 @@ const Settings = () => {
setErrors(newErrors);
}
saveSettings(settingsData?.settings);
};
return (
+1
View File
@@ -328,6 +328,7 @@ const settingsValidation = joi.object({
systemEmailIgnoreTLS: joi.boolean(),
systemEmailRequireTLS: joi.boolean(),
systemEmailRejectUnauthorized: joi.boolean(),
showURL: joi.boolean().optional(),
globalThresholds: joi
.object({
cpu: joi.number().min(1).max(100).allow("").optional(),
+1 -1
View File
@@ -129,7 +129,7 @@ export const initializeServices = async ({
// Create DB
const checkModule = new CheckModule({ logger, Monitor, User });
const inviteModule = new InviteModule({ InviteToken, crypto, stringService });
const statusPageModule = new StatusPageModule({ StatusPage, NormalizeData, stringService });
const statusPageModule = new StatusPageModule({ StatusPage, NormalizeData, stringService, AppSettings });
const userModule = new UserModule({ User, Team, GenerateAvatarImage, ParseBoolean, stringService });
const maintenanceWindowModule = new MaintenanceWindowModule({ MaintenanceWindow });
const notificationModule = new NotificationModule({ Notification, Monitor });
+4
View File
@@ -55,6 +55,10 @@ const AppSettingsSchema = mongoose.Schema(
type: Boolean,
default: true,
},
showURL: {
type: Boolean,
default: false,
},
singleton: {
type: Boolean,
required: true,
+11 -6
View File
@@ -1,4 +1,3 @@
// import StatusPage from "../../models/StatusPage.js";
// import { NormalizeData } from "../../../utils/dataUtils.js";
// import ServiceRegistry from "../../../service/system/serviceRegistry.js";
// import StringService from "../../../service/system/stringService.js";
@@ -6,10 +5,11 @@
const SERVICE_NAME = "statusPageModule";
class StatusPageModule {
constructor({ StatusPage, NormalizeData, stringService }) {
constructor({ StatusPage, NormalizeData, stringService, AppSettings }) {
this.StatusPage = StatusPage;
this.NormalizeData = NormalizeData;
this.stringService = stringService;
this.AppSettings = AppSettings;
}
createStatusPage = async ({ statusPageData, image, userId, teamId }) => {
@@ -260,11 +260,16 @@ class StatusPageModule {
const { statusPage, monitors } = statusPageQuery[0];
const appSettings = await this.AppSettings.findOne({ singleton: true }).lean();
const showURL = appSettings?.showURL === true;
const normalizedMonitors = monitors.map((monitor) => {
return {
...monitor,
checks: this.NormalizeData(monitor.checks, 10, 100),
};
const normalizedChecks = this.NormalizeData(monitor.checks, 10, 100);
if (!showURL) {
const { url, port, secret, notifications, ...rest } = monitor;
return { ...rest, checks: normalizedChecks };
}
return { ...monitor, checks: normalizedChecks };
});
return { statusPage, monitors: normalizedMonitors };
@@ -60,6 +60,7 @@ class SettingsService {
await this.AppSettings.create({});
settings = await this.AppSettings.findOne({ singleton: true }).select("-__v -_id -createdAt -updatedAt -singleton").lean();
}
return settings;
}
}
+1 -1
View File
@@ -413,7 +413,7 @@ const updateAppSettingsBodyValidation = joi.object({
pagespeedApiKey: joi.string().allow(""),
language: joi.string().allow(""),
timezone: joi.string().allow(""),
// showURL: joi.bool().required(),
showURL: joi.bool().optional(),
systemEmailHost: joi.string().allow(""),
systemEmailPort: joi.number().allow(""),
systemEmailAddress: joi.string().allow(""),