mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-02 04:53:40 +00:00
Relaid out settings page and configured agent and other communication to use curl flags which can be configured to ignore ssl cert if self-hosted.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
-- Fix dashboard preferences unique constraint
|
||||
-- This migration fixes the unique constraint on dashboard_preferences table
|
||||
|
||||
-- Drop existing indexes if they exist
|
||||
DROP INDEX IF EXISTS "dashboard_preferences_card_id_key";
|
||||
DROP INDEX IF EXISTS "dashboard_preferences_user_id_card_id_key";
|
||||
DROP INDEX IF EXISTS "dashboard_preferences_user_id_key";
|
||||
|
||||
-- Add the correct unique constraint
|
||||
ALTER TABLE "dashboard_preferences" ADD CONSTRAINT "dashboard_preferences_user_id_card_id_key" UNIQUE ("user_id", "card_id");
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Add ignore_ssl_self_signed column to settings table
|
||||
-- This allows users to configure whether curl commands should ignore SSL certificate validation
|
||||
|
||||
ALTER TABLE "settings" ADD COLUMN "ignore_ssl_self_signed" BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -7,7 +7,6 @@ datasource db {
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
|
||||
model dashboard_preferences {
|
||||
id String @id
|
||||
user_id String
|
||||
@@ -157,6 +156,7 @@ model settings {
|
||||
update_available Boolean @default(false)
|
||||
signup_enabled Boolean @default(false)
|
||||
default_user_role String @default("user")
|
||||
ignore_ssl_self_signed Boolean @default(false)
|
||||
}
|
||||
|
||||
model update_history {
|
||||
@@ -175,8 +175,6 @@ model users {
|
||||
username String @unique
|
||||
email String @unique
|
||||
password_hash String
|
||||
first_name String?
|
||||
last_name String?
|
||||
role String @default("admin")
|
||||
is_active Boolean @default(true)
|
||||
last_login DateTime?
|
||||
@@ -185,5 +183,7 @@ model users {
|
||||
tfa_backup_codes String?
|
||||
tfa_enabled Boolean @default(false)
|
||||
tfa_secret String?
|
||||
first_name String?
|
||||
last_name String?
|
||||
dashboard_preferences dashboard_preferences[]
|
||||
}
|
||||
|
||||
@@ -45,11 +45,26 @@ router.get("/agent/download", async (req, res) => {
|
||||
}
|
||||
|
||||
// Read file and convert line endings
|
||||
const scriptContent = fs
|
||||
let scriptContent = fs
|
||||
.readFileSync(agentPath, "utf8")
|
||||
.replace(/\r\n/g, "\n")
|
||||
.replace(/\r/g, "\n");
|
||||
|
||||
// Determine curl flags dynamically from settings for consistency
|
||||
let curlFlags = "-s";
|
||||
try {
|
||||
const settings = await prisma.settings.findFirst();
|
||||
if (settings && settings.ignore_ssl_self_signed === true) {
|
||||
curlFlags = "-sk";
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
// Inject the curl flags into the script
|
||||
scriptContent = scriptContent.replace(
|
||||
'CURL_FLAGS=""',
|
||||
`CURL_FLAGS="${curlFlags}"`,
|
||||
);
|
||||
|
||||
res.setHeader("Content-Type", "application/x-shellscript");
|
||||
res.setHeader(
|
||||
"Content-Disposition",
|
||||
@@ -1101,11 +1116,21 @@ router.get("/install", async (req, res) => {
|
||||
);
|
||||
}
|
||||
|
||||
// Inject the API credentials and server URL into the script as environment variables
|
||||
// Determine curl flags dynamically from settings (ignore self-signed)
|
||||
let curlFlags = "-s";
|
||||
try {
|
||||
const settings = await prisma.settings.findFirst();
|
||||
if (settings && settings.ignore_ssl_self_signed === true) {
|
||||
curlFlags = "-sk";
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
// Inject the API credentials, server URL, and curl flags into the script
|
||||
const envVars = `#!/bin/bash
|
||||
export PATCHMON_URL="${serverUrl}"
|
||||
export API_ID="${host.api_id}"
|
||||
export API_KEY="${host.api_key}"
|
||||
export CURL_FLAGS="${curlFlags}"
|
||||
|
||||
`;
|
||||
|
||||
@@ -1141,7 +1166,24 @@ router.get("/remove", async (_req, res) => {
|
||||
}
|
||||
|
||||
// Read the script content
|
||||
const script = fs.readFileSync(scriptPath, "utf8");
|
||||
let script = fs.readFileSync(scriptPath, "utf8");
|
||||
|
||||
// Convert line endings
|
||||
script = script.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
||||
|
||||
// Determine curl flags dynamically from settings for consistency
|
||||
let curlFlags = "-s";
|
||||
try {
|
||||
const settings = await prisma.settings.findFirst();
|
||||
if (settings && settings.ignore_ssl_self_signed === true) {
|
||||
curlFlags = "-sk";
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
// Prepend environment for CURL_FLAGS so script can use it if needed
|
||||
const envPrefix = `#!/bin/bash\nexport CURL_FLAGS="${curlFlags}"\n\n`;
|
||||
script = script.replace(/^#!/, "#");
|
||||
script = envPrefix + script;
|
||||
|
||||
// Set appropriate headers for script download
|
||||
res.setHeader("Content-Type", "text/plain");
|
||||
|
||||
@@ -165,19 +165,31 @@ router.put(
|
||||
requireManageSettings,
|
||||
[
|
||||
body("serverProtocol")
|
||||
.optional()
|
||||
.isIn(["http", "https"])
|
||||
.withMessage("Protocol must be http or https"),
|
||||
body("serverHost")
|
||||
.optional()
|
||||
.isLength({ min: 1 })
|
||||
.withMessage("Server host is required"),
|
||||
body("serverPort")
|
||||
.optional()
|
||||
.isInt({ min: 1, max: 65535 })
|
||||
.withMessage("Port must be between 1 and 65535"),
|
||||
body("updateInterval")
|
||||
.optional()
|
||||
.isInt({ min: 5, max: 1440 })
|
||||
.withMessage("Update interval must be between 5 and 1440 minutes"),
|
||||
body("autoUpdate").isBoolean().withMessage("Auto update must be a boolean"),
|
||||
body("autoUpdate")
|
||||
.optional()
|
||||
.isBoolean()
|
||||
.withMessage("Auto update must be a boolean"),
|
||||
body("ignoreSslSelfSigned")
|
||||
.optional()
|
||||
.isBoolean()
|
||||
.withMessage("Ignore SSL self-signed must be a boolean"),
|
||||
body("signupEnabled")
|
||||
.optional()
|
||||
.isBoolean()
|
||||
.withMessage("Signup enabled must be a boolean"),
|
||||
body("defaultUserRole")
|
||||
@@ -218,6 +230,7 @@ router.put(
|
||||
serverPort,
|
||||
updateInterval,
|
||||
autoUpdate,
|
||||
ignoreSslSelfSigned,
|
||||
signupEnabled,
|
||||
defaultUserRole,
|
||||
githubRepoUrl,
|
||||
@@ -229,32 +242,43 @@ router.put(
|
||||
const currentSettings = await getSettings();
|
||||
const oldUpdateInterval = currentSettings.update_interval;
|
||||
|
||||
// Update settings using the service
|
||||
const normalizedInterval = normalizeUpdateInterval(updateInterval || 60);
|
||||
// Build update object with only provided fields
|
||||
const updateData = {};
|
||||
|
||||
const updatedSettings = await updateSettings(currentSettings.id, {
|
||||
server_protocol: serverProtocol,
|
||||
server_host: serverHost,
|
||||
server_port: serverPort,
|
||||
update_interval: normalizedInterval,
|
||||
auto_update: autoUpdate || false,
|
||||
signup_enabled: signupEnabled || false,
|
||||
default_user_role:
|
||||
defaultUserRole || process.env.DEFAULT_USER_ROLE || "user",
|
||||
github_repo_url:
|
||||
githubRepoUrl !== undefined
|
||||
? githubRepoUrl
|
||||
: "git@github.com:9technologygroup/patchmon.net.git",
|
||||
repository_type: repositoryType || "public",
|
||||
ssh_key_path: sshKeyPath || null,
|
||||
});
|
||||
if (serverProtocol !== undefined)
|
||||
updateData.server_protocol = serverProtocol;
|
||||
if (serverHost !== undefined) updateData.server_host = serverHost;
|
||||
if (serverPort !== undefined) updateData.server_port = serverPort;
|
||||
if (updateInterval !== undefined) {
|
||||
updateData.update_interval = normalizeUpdateInterval(updateInterval);
|
||||
}
|
||||
if (autoUpdate !== undefined) updateData.auto_update = autoUpdate;
|
||||
if (ignoreSslSelfSigned !== undefined)
|
||||
updateData.ignore_ssl_self_signed = ignoreSslSelfSigned;
|
||||
if (signupEnabled !== undefined)
|
||||
updateData.signup_enabled = signupEnabled;
|
||||
if (defaultUserRole !== undefined)
|
||||
updateData.default_user_role = defaultUserRole;
|
||||
if (githubRepoUrl !== undefined)
|
||||
updateData.github_repo_url = githubRepoUrl;
|
||||
if (repositoryType !== undefined)
|
||||
updateData.repository_type = repositoryType;
|
||||
if (sshKeyPath !== undefined) updateData.ssh_key_path = sshKeyPath;
|
||||
|
||||
const updatedSettings = await updateSettings(
|
||||
currentSettings.id,
|
||||
updateData,
|
||||
);
|
||||
|
||||
console.log("Settings updated successfully:", updatedSettings);
|
||||
|
||||
// If update interval changed, trigger crontab updates on all hosts with auto-update enabled
|
||||
if (oldUpdateInterval !== normalizedInterval) {
|
||||
if (
|
||||
updateInterval !== undefined &&
|
||||
oldUpdateInterval !== updateData.update_interval
|
||||
) {
|
||||
console.log(
|
||||
`Update interval changed from ${oldUpdateInterval} to ${normalizedInterval} minutes. Triggering crontab updates...`,
|
||||
`Update interval changed from ${oldUpdateInterval} to ${updateData.update_interval} minutes. Triggering crontab updates...`,
|
||||
);
|
||||
await triggerCrontabUpdates();
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ async function createSettingsFromEnvironment() {
|
||||
update_interval: 60,
|
||||
auto_update: false,
|
||||
signup_enabled: false,
|
||||
ignore_ssl_self_signed: false,
|
||||
updated_at: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user