resolve scoping issue by fetching proxy summary

This commit is contained in:
Alex Holliday committed 2026-08-25 11:13:12 -07:00
1 parent b2dca7b62f
commit 3f62c8ec6a
7 files changed
+43 -19

No files matched your search

+1 -4
View File
@@ -484,10 +484,7 @@ const CreateMonitorPage = () => {
})),
[t]
);
const globalProxyName =
appSettings?.settings?.globalProxyEnabled === true
? proxies?.find((proxy) => proxy.id === appSettings?.settings?.globalProxyId)?.name
: undefined;
const globalProxyName = appSettings?.globalProxy?.name;
const proxyModeOptions = useMemo(
() =>
+4 -9
View File
@@ -45,12 +45,7 @@ import { FormSwitchField } from "@/Components/inputs/forms/FormSwitchField";
import { FormNumberField } from "@/Components/inputs/forms/FormNumberField";
import { FormSelectField } from "@/Components/inputs/forms/FormSelectField";
import type { ProxyResponse } from "@/Types/Proxy";
interface SettingsResponse {
settings: any;
pagespeedKeySet: boolean;
emailPasswordSet: boolean;
}
import type { AppSettingsResponse } from "@/Types/Settings";
export const SettingsPage = () => {
const theme = useTheme();
@@ -66,9 +61,9 @@ export const SettingsPage = () => {
const { post: importMonitors, loading: isImportingMonitors } = usePost();
// Fetch settings data from API
const { data: fetchedSettings } = useGet<SettingsResponse>("/settings");
const { data: fetchedSettings } = useGet<AppSettingsResponse>("/settings");
// Get proxies
const { data: proxies } = useGet<ProxyResponse[]>("/proxies/team");
const { data: proxies } = useGet<ProxyResponse[]>("/proxies");
const proxyOptions = useMemo(
() =>
(proxies ?? []).map((proxy) => ({
@@ -79,7 +74,7 @@ export const SettingsPage = () => {
);
// Form submission
const { patch, loading: isSaving } = usePatch<SettingsFormData, SettingsResponse>();
const { patch, loading: isSaving } = usePatch<SettingsFormData, AppSettingsResponse>();
// Local state for API key reset
const [isApiKeySet, setIsApiKeySet] = useState(
+6
View File
@@ -33,5 +33,11 @@ export interface Settings {
export interface AppSettingsResponse {
pagespeedKeySet: boolean;
emailPasswordSet: boolean;
globalProxy: {
id: string;
name: string;
host: string;
port: number;
} | null;
settings: Settings;
}
@@ -5,6 +5,7 @@ import { sendTestEmailBodyValidation } from "@/api/validation/notificationValida
import { AppError } from "@/utils/AppError.js";
import { ISettingsService } from "@/domain/app-settings/app-settings.service.js";
import { IEmailService } from "@/service/emailService.js";
import { IProxiesService } from "@/domain/proxies/proxy.service.js";
import { Settings } from "@/domain/app-settings/app-settings.type.js";
export interface ISettingsController {
@@ -16,18 +17,23 @@ export interface ISettingsController {
class SettingsController implements ISettingsController {
private settingsService: ISettingsService;
private emailService: IEmailService;
constructor(settingsService: ISettingsService, emailService: IEmailService) {
private proxiesService: IProxiesService;
constructor(settingsService: ISettingsService, emailService: IEmailService, proxiesService: IProxiesService) {
this.settingsService = settingsService;
this.emailService = emailService;
this.proxiesService = proxiesService;
}
buildAppSettings = (dbSettings: Settings) => {
buildAppSettings = async (dbSettings: Settings) => {
const sanitizedSettings: Record<string, unknown> = { ...dbSettings };
delete sanitizedSettings.version;
delete sanitizedSettings.jwtSecret;
const globalProxy =
dbSettings.globalProxyEnabled && dbSettings.globalProxyId ? await this.proxiesService.getProxySummary(dbSettings.globalProxyId) : null;
const returnSettings: Record<string, unknown | null> = {
pagespeedKeySet: false,
emailPasswordSet: false,
globalProxy,
settings: null,
};
@@ -46,7 +52,7 @@ class SettingsController implements ISettingsController {
getAppSettings = catchAsync(async (req: Request, res: Response) => {
const dbSettings = await this.settingsService.getDBSettings();
const returnSettings = this.buildAppSettings(dbSettings);
const returnSettings = await this.buildAppSettings(dbSettings);
return res.status(200).json({
success: true,
msg: "App settings fetched successfully",
@@ -57,8 +63,15 @@ class SettingsController implements ISettingsController {
updateAppSettings = catchAsync(async (req: Request, res: Response) => {
const validatedBody = updateAppSettingsBodyValidation.parse(req.body);
if (validatedBody.globalProxyId) {
const proxy = await this.proxiesService.getProxySummary(validatedBody.globalProxyId);
if (!proxy) {
throw new AppError({ message: "Referenced proxy does not exist", status: 422 });
}
}
const updatedSettings = await this.settingsService.updateDbSettings(validatedBody);
const returnSettings = this.buildAppSettings(updatedSettings);
const returnSettings = await this.buildAppSettings(updatedSettings);
return res.status(200).json({
success: true,
msg: "App settings updated successfully",
+1 -1
View File
@@ -36,7 +36,7 @@ export const initializeControllers = (apiServices: ApiServices): InitializedCont
return {
authController: new AuthController(apiServices.userService),
monitorController: new MonitorController(apiServices.monitorService, apiServices.notificationsService),
settingsController: new SettingsController(apiServices.settingsService, apiServices.emailService),
settingsController: new SettingsController(apiServices.settingsService, apiServices.emailService, apiServices.proxiesService),
checkController: new CheckController(apiServices.checkService),
geoCheckController: new GeoCheckController(apiServices.geoChecksService),
inviteController: new InviteController(apiServices.inviteService),
+12 -1
View File
@@ -1,4 +1,4 @@
import { Proxy, ProxyResponse } from "@/domain/proxies/proxy.type.js";
import { Proxy, ProxyResponse, ProxySummary } from "@/domain/proxies/proxy.type.js";
import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js";
import { IProxiesRepository } from "@/domain/proxies/proxy.repository.interface.js";
import { AppError } from "@/utils/AppError.js";
@@ -8,6 +8,7 @@ export interface IProxiesService {
createProxy(proxy: Partial<Proxy>, teamId: string): Promise<ProxyResponse>;
getProxy(proxyId: string, teamId: string): Promise<ProxyResponse>;
getProxies(): Promise<ProxyResponse[]>;
getProxySummary(proxyId: string): Promise<ProxySummary | null>;
getProxiesByTeamId(teamId: string): Promise<ProxyResponse[]>;
updateProxy(proxyId: string, teamId: string, patch: Partial<Proxy> & { clearPassword?: boolean; clearUsername?: boolean }): Promise<ProxyResponse>;
deleteProxy(proxyId: string, teamId: string): Promise<ProxyResponse>;
@@ -47,6 +48,16 @@ export class ProxiesService implements IProxiesService {
});
return clean;
};
getProxySummary = async (proxyId: string): Promise<ProxySummary | null> => {
const proxy = await this.proxiesRepository.findByIdOrNull(proxyId);
if (!proxy) {
return null;
}
const { id, name, host, port } = proxy;
return { id, name, host, port };
};
getProxiesByTeamId = async (teamId: string): Promise<ProxyResponse[]> => {
const raw = await this.proxiesRepository.findByTeamId(teamId);
const clean = raw.map((r) => {
+2
View File
@@ -15,3 +15,5 @@ export interface Proxy {
}
export type ProxyResponse = Omit<Proxy, "password"> & { hasPassword: boolean };
export type ProxySummary = Pick<Proxy, "id" | "name" | "host" | "port">;