mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-04 14:03:17 +00:00
fix: conflate frontend_url and server_url
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "settings" DROP COLUMN "frontend_url";
|
||||
@@ -157,7 +157,6 @@ model settings {
|
||||
server_protocol String @default("http")
|
||||
server_host String @default("localhost")
|
||||
server_port Int @default(3001)
|
||||
frontend_url String @default("http://localhost:3000")
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime
|
||||
update_interval Int @default(60)
|
||||
|
||||
@@ -107,7 +107,6 @@ router.get('/', authenticateToken, requireManageSettings, async (req, res) => {
|
||||
server_protocol: 'http',
|
||||
server_host: 'localhost',
|
||||
server_port: 3001,
|
||||
frontend_url: 'http://localhost:3000',
|
||||
update_interval: 60,
|
||||
auto_update: false,
|
||||
signup_enabled: false,
|
||||
@@ -128,7 +127,6 @@ router.put('/', authenticateToken, requireManageSettings, [
|
||||
body('serverProtocol').isIn(['http', 'https']).withMessage('Protocol must be http or https'),
|
||||
body('serverHost').isLength({ min: 1 }).withMessage('Server host is required'),
|
||||
body('serverPort').isInt({ min: 1, max: 65535 }).withMessage('Port must be between 1 and 65535'),
|
||||
body('frontendUrl').isLength({ min: 1 }).withMessage('Frontend URL is required'),
|
||||
body('updateInterval').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('signupEnabled').isBoolean().withMessage('Signup enabled must be a boolean'),
|
||||
@@ -151,7 +149,7 @@ router.put('/', authenticateToken, requireManageSettings, [
|
||||
return res.status(400).json({ errors: errors.array() });
|
||||
}
|
||||
|
||||
const { serverProtocol, serverHost, serverPort, frontendUrl, updateInterval, autoUpdate, signupEnabled, githubRepoUrl, repositoryType, sshKeyPath } = req.body;
|
||||
const { serverProtocol, serverHost, serverPort, updateInterval, autoUpdate, signupEnabled, githubRepoUrl, repositoryType, sshKeyPath } = req.body;
|
||||
|
||||
// Construct server URL from components
|
||||
const serverUrl = `${serverProtocol}://${serverHost}:${serverPort}`;
|
||||
@@ -171,7 +169,6 @@ router.put('/', authenticateToken, requireManageSettings, [
|
||||
server_protocol: serverProtocol,
|
||||
server_host: serverHost,
|
||||
server_port: serverPort,
|
||||
frontend_url: frontendUrl,
|
||||
update_interval: updateInterval || 60,
|
||||
auto_update: autoUpdate || false,
|
||||
signup_enabled: signupEnabled || false,
|
||||
@@ -181,7 +178,6 @@ router.put('/', authenticateToken, requireManageSettings, [
|
||||
updated_at: new Date()
|
||||
}
|
||||
});
|
||||
|
||||
// If update interval changed, trigger crontab updates on all hosts with auto-update enabled
|
||||
if (oldUpdateInterval !== (updateInterval || 60)) {
|
||||
console.log(`Update interval changed from ${oldUpdateInterval} to ${updateInterval || 60} minutes. Triggering crontab updates...`);
|
||||
@@ -196,7 +192,6 @@ router.put('/', authenticateToken, requireManageSettings, [
|
||||
server_protocol: serverProtocol,
|
||||
server_host: serverHost,
|
||||
server_port: serverPort,
|
||||
frontend_url: frontendUrl,
|
||||
update_interval: updateInterval || 60,
|
||||
auto_update: autoUpdate || false,
|
||||
signup_enabled: signupEnabled || false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { Save, Server, Globe, Shield, AlertCircle, CheckCircle, Code, Plus, Trash2, Star, Download, X, Settings as SettingsIcon, Clock } from 'lucide-react';
|
||||
import { Save, Server, Shield, AlertCircle, CheckCircle, Code, Plus, Trash2, Star, Download, X, Settings as SettingsIcon, Clock } from 'lucide-react';
|
||||
import { settingsAPI, agentVersionAPI, versionAPI } from '../utils/api';
|
||||
import { useUpdateNotification } from '../contexts/UpdateNotificationContext';
|
||||
import UpgradeNotificationIcon from '../components/UpgradeNotificationIcon';
|
||||
@@ -10,7 +10,6 @@ const Settings = () => {
|
||||
serverProtocol: 'http',
|
||||
serverHost: 'localhost',
|
||||
serverPort: 3001,
|
||||
frontendUrl: 'http://localhost:3000',
|
||||
updateInterval: 60,
|
||||
autoUpdate: false,
|
||||
signupEnabled: false,
|
||||
@@ -31,7 +30,6 @@ const Settings = () => {
|
||||
// Tab configuration
|
||||
const tabs = [
|
||||
{ id: 'server', name: 'Server Configuration', icon: Server },
|
||||
{ id: 'frontend', name: 'Frontend Configuration', icon: Globe },
|
||||
{ id: 'agent', name: 'Agent Management', icon: SettingsIcon },
|
||||
{ id: 'version', name: 'Server Version', icon: Code, showUpgradeIcon: updateAvailable }
|
||||
];
|
||||
@@ -77,7 +75,6 @@ const Settings = () => {
|
||||
serverProtocol: settings.server_protocol || 'http',
|
||||
serverHost: settings.server_host || 'localhost',
|
||||
serverPort: settings.server_port || 3001,
|
||||
frontendUrl: settings.frontend_url || 'http://localhost:3000',
|
||||
updateInterval: settings.update_interval || 60,
|
||||
autoUpdate: settings.auto_update || false,
|
||||
signupEnabled: settings.signup_enabled === true ? true : false, // Explicit boolean conversion
|
||||
@@ -284,12 +281,6 @@ const Settings = () => {
|
||||
newErrors.serverPort = 'Port must be between 1 and 65535';
|
||||
}
|
||||
|
||||
try {
|
||||
new URL(formData.frontendUrl);
|
||||
} catch {
|
||||
newErrors.frontendUrl = 'Frontend URL must be a valid URL';
|
||||
}
|
||||
|
||||
if (!formData.updateInterval || formData.updateInterval < 5 || formData.updateInterval > 1440) {
|
||||
newErrors.updateInterval = 'Update interval must be between 5 and 1440 minutes';
|
||||
}
|
||||
@@ -627,74 +618,6 @@ const Settings = () => {
|
||||
</form>
|
||||
)}
|
||||
|
||||
{/* Frontend Configuration Tab */}
|
||||
{activeTab === 'frontend' && (
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div className="flex items-center mb-6">
|
||||
<Globe className="h-6 w-6 text-primary-600 mr-3" />
|
||||
<h2 className="text-xl font-semibold text-secondary-900 dark:text-white">Frontend Configuration</h2>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-secondary-700 dark:text-secondary-200 mb-2">
|
||||
Frontend URL *
|
||||
</label>
|
||||
<input
|
||||
type="url"
|
||||
value={formData.frontendUrl}
|
||||
onChange={(e) => handleInputChange('frontendUrl', e.target.value)}
|
||||
className={`w-full border rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white ${
|
||||
errors.frontendUrl ? 'border-red-300 dark:border-red-500' : 'border-secondary-300 dark:border-secondary-600'
|
||||
}`}
|
||||
placeholder="https://patchmon.example.com"
|
||||
/>
|
||||
{errors.frontendUrl && (
|
||||
<p className="mt-1 text-sm text-red-600 dark:text-red-400">{errors.frontendUrl}</p>
|
||||
)}
|
||||
<p className="mt-1 text-sm text-secondary-500 dark:text-secondary-400">
|
||||
The URL where users will access the PatchMon web interface.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Save Button */}
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleSave}
|
||||
disabled={!isDirty || updateSettingsMutation.isPending}
|
||||
className={`inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white ${
|
||||
!isDirty || updateSettingsMutation.isPending
|
||||
? 'bg-secondary-400 cursor-not-allowed'
|
||||
: 'bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500'
|
||||
}`}
|
||||
>
|
||||
{updateSettingsMutation.isPending ? (
|
||||
<>
|
||||
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
|
||||
Saving...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Save className="h-4 w-4 mr-2" />
|
||||
Save Settings
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{updateSettingsMutation.isSuccess && (
|
||||
<div className="bg-green-50 dark:bg-green-900 border border-green-200 dark:border-green-700 rounded-md p-4">
|
||||
<div className="flex">
|
||||
<CheckCircle className="h-5 w-5 text-green-400 dark:text-green-300" />
|
||||
<div className="ml-3">
|
||||
<p className="text-sm text-green-700 dark:text-green-300">Settings saved successfully!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
|
||||
{/* Agent Management Tab */}
|
||||
{activeTab === 'agent' && (
|
||||
<div className="space-y-6">
|
||||
|
||||
Reference in New Issue
Block a user