Merge branch 'main' into ENG-3041

This commit is contained in:
x032205
2025-07-03 19:55:32 -04:00
148 changed files with 3763 additions and 846 deletions
+13 -1
View File
@@ -10,6 +10,7 @@ import {
AdminGetUsersFilters,
AdminIntegrationsConfig,
OrganizationWithProjects,
TGetEnvOverrides,
TGetInvalidatingCacheStatus,
TGetServerRootKmsEncryptionDetails,
TServerConfig
@@ -31,7 +32,8 @@ export const adminQueryKeys = {
getAdminSlackConfig: () => ["admin-slack-config"] as const,
getServerEncryptionStrategies: () => ["server-encryption-strategies"] as const,
getInvalidateCache: () => ["admin-invalidate-cache"] as const,
getAdminIntegrationsConfig: () => ["admin-integrations-config"] as const
getAdminIntegrationsConfig: () => ["admin-integrations-config"] as const,
getEnvOverrides: () => ["env-overrides"] as const
};
export const fetchServerConfig = async () => {
@@ -163,3 +165,13 @@ export const useGetInvalidatingCacheStatus = (enabled = true) => {
refetchInterval: (data) => (data ? 3000 : false)
});
};
export const useGetEnvOverrides = () => {
return useQuery({
queryKey: adminQueryKeys.getEnvOverrides(),
queryFn: async () => {
const { data } = await apiRequest.get<TGetEnvOverrides>("/api/v1/admin/env-overrides");
return data;
}
});
};
+9
View File
@@ -48,6 +48,7 @@ export type TServerConfig = {
authConsentContent?: string;
pageFrameContent?: string;
invalidatingCache: boolean;
envOverrides?: Record<string, string>;
};
export type TUpdateServerConfigDTO = {
@@ -61,6 +62,7 @@ export type TUpdateServerConfigDTO = {
gitHubAppConnectionSlug?: string;
gitHubAppConnectionId?: string;
gitHubAppConnectionPrivateKey?: string;
envOverrides?: Record<string, string>;
} & Partial<TServerConfig>;
export type TCreateAdminUserDTO = {
@@ -138,3 +140,10 @@ export type TInvalidateCacheDTO = {
export type TGetInvalidatingCacheStatus = {
invalidating: boolean;
};
export interface TGetEnvOverrides {
[key: string]: {
name: string;
fields: { key: string; value: string; hasEnvEntry: boolean; description?: string }[];
};
}
@@ -28,5 +28,6 @@ export enum AppConnection {
Flyio = "flyio",
Gitlab = "gitlab",
Cloudflare = "cloudflare",
Bitbucket = "bitbucket"
Bitbucket = "bitbucket",
Zabbix = "zabbix"
}
@@ -134,6 +134,10 @@ export type TCloudflareConnectionOption = TAppConnectionOptionBase & {
export type TBitbucketConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Bitbucket;
}
export type TZabbixConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Zabbix;
};
export type TAppConnectionOption =
@@ -165,6 +169,7 @@ export type TAppConnectionOption =
| TGitlabConnectionOption
| TCloudflareConnectionOption
| TBitbucketConnectionOption;
| TZabbixConnectionOption;
export type TAppConnectionOptionMap = {
[AppConnection.AWS]: TAwsConnectionOption;
@@ -197,4 +202,5 @@ export type TAppConnectionOptionMap = {
[AppConnection.Gitlab]: TGitlabConnectionOption;
[AppConnection.Cloudflare]: TCloudflareConnectionOption;
[AppConnection.Bitbucket]: TBitbucketConnectionOption;
[AppConnection.Zabbix]: TZabbixConnectionOption;
};
@@ -30,6 +30,7 @@ import { TTeamCityConnection } from "./teamcity-connection";
import { TTerraformCloudConnection } from "./terraform-cloud-connection";
import { TVercelConnection } from "./vercel-connection";
import { TWindmillConnection } from "./windmill-connection";
import { TZabbixConnection } from "./zabbix-connection";
export * from "./1password-connection";
export * from "./auth0-connection";
@@ -61,6 +62,7 @@ export * from "./teamcity-connection";
export * from "./terraform-cloud-connection";
export * from "./vercel-connection";
export * from "./windmill-connection";
export * from "./zabbix-connection";
export type TAppConnection =
| TAwsConnection
@@ -92,7 +94,8 @@ export type TAppConnection =
| TFlyioConnection
| TGitLabConnection
| TCloudflareConnection
| TBitbucketConnection;
| TBitbucketConnection
| TZabbixConnection;
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
@@ -150,4 +153,5 @@ export type TAppConnectionMap = {
[AppConnection.Gitlab]: TGitLabConnection;
[AppConnection.Cloudflare]: TCloudflareConnection;
[AppConnection.Bitbucket]: TBitbucketConnection;
[AppConnection.Zabbix]: TZabbixConnection;
};
@@ -0,0 +1,14 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum ZabbixConnectionMethod {
ApiToken = "api-token"
}
export type TZabbixConnection = TRootAppConnection & { app: AppConnection.Zabbix } & {
method: ZabbixConnectionMethod.ApiToken;
credentials: {
apiToken: string;
instanceUrl: string;
};
};
@@ -0,0 +1,2 @@
export * from "./queries";
export * from "./types";
@@ -0,0 +1,36 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "../queries";
import { TZabbixHost } from "./types";
const zabbixConnectionKeys = {
all: [...appConnectionKeys.all, "zabbix"] as const,
listHosts: (connectionId: string) => [...zabbixConnectionKeys.all, "hosts", connectionId] as const
};
export const useZabbixConnectionListHosts = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TZabbixHost[],
unknown,
TZabbixHost[],
ReturnType<typeof zabbixConnectionKeys.listHosts>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: zabbixConnectionKeys.listHosts(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<TZabbixHost[]>(
`/api/v1/app-connections/zabbix/${connectionId}/hosts`
);
return data;
},
...options
});
};
@@ -0,0 +1,25 @@
export type TZabbixHost = {
host: string;
hostId: string;
};
export enum ZabbixSyncScope {
Host = "host",
Global = "global"
}
export enum ZabbixMacroType {
Text = 0,
Secret = 1
}
export const ZABBIX_SYNC_SCOPES = {
[ZabbixSyncScope.Host]: {
name: "Host",
description: "Sync secrets to a specific host in Zabbix."
},
[ZabbixSyncScope.Global]: {
name: "Global",
description: "Sync secrets to a global scope in Zabbix."
}
};
+2 -2
View File
@@ -30,8 +30,8 @@ export const useGetAuditLogs = (
params: {
...filters,
offset: pageParam,
startDate: filters?.startDate?.toISOString(),
endDate: filters?.endDate?.toISOString(),
startDate: filters.startDate.toISOString(),
endDate: filters.endDate.toISOString(),
...(filters.eventMetadata && Object.keys(filters.eventMetadata).length
? {
eventMetadata: Object.entries(filters.eventMetadata)
+2 -2
View File
@@ -14,8 +14,8 @@ export type TGetAuditLogsFilter = {
actor?: string; // user ID format
secretPath?: string;
secretKey?: string;
startDate?: Date;
endDate?: Date;
startDate: Date;
endDate: Date;
limit: number;
};
+2 -1
View File
@@ -20,7 +20,8 @@ export enum SecretSync {
Render = "render",
Flyio = "flyio",
GitLab = "gitlab",
CloudflarePages = "cloudflare-pages"
CloudflarePages = "cloudflare-pages",
Zabbix = "zabbix"
}
export enum SecretSyncStatus {
@@ -23,6 +23,7 @@ import { TTeamCitySync } from "./teamcity-sync";
import { TTerraformCloudSync } from "./terraform-cloud-sync";
import { TVercelSync } from "./vercel-sync";
import { TWindmillSync } from "./windmill-sync";
import { TZabbixSync } from "./zabbix-sync";
export type TSecretSyncOption = {
name: string;
@@ -53,7 +54,8 @@ export type TSecretSync =
| TRenderSync
| TFlyioSync
| TGitLabSync
| TCloudflarePagesSync;
| TCloudflarePagesSync
| TZabbixSync;
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };
@@ -0,0 +1,25 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { SecretSync } from "@app/hooks/api/secretSyncs";
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
import { ZabbixSyncScope } from "../../appConnections/zabbix";
export type TZabbixSync = TRootSecretSync & {
destination: SecretSync.Zabbix;
destinationConfig:
| {
scope: ZabbixSyncScope.Host;
hostId: string;
hostName: string;
macroType: number;
}
| {
scope: ZabbixSyncScope.Global;
macroType: number;
};
connection: {
app: AppConnection.Zabbix;
name: string;
id: string;
};
};
+1
View File
@@ -5,6 +5,7 @@ export { usePagination } from "./usePagination";
export { usePersistentState } from "./usePersistentState";
export { usePopUp } from "./usePopUp";
export { useResetPageHelper } from "./useResetPageHelper";
export * from "./useResizableHeaderHeight";
export { useSyntaxHighlight } from "./useSyntaxHighlight";
export { useTimedReset } from "./useTimedReset";
export { useToggle } from "./useToggle";
@@ -0,0 +1,71 @@
import { MouseEvent, useCallback, useEffect, useRef, useState } from "react";
type Params = {
minHeight: number;
maxHeight: number;
initialHeight: number;
};
export const useResizableHeaderHeight = ({ minHeight, maxHeight, initialHeight }: Params) => {
const [headerHeight, setHeaderHeight] = useState(initialHeight);
const [isResizing, setIsResizing] = useState(false);
const startY = useRef(0);
const startHeight = useRef(0);
const handleMouseDown = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
setIsResizing(true);
startY.current = e.clientY;
startHeight.current = headerHeight;
},
[headerHeight]
);
const handleMouseMove = useCallback(
(e: MouseEvent) => {
if (!isResizing) return;
const deltaY = e.clientY - startY.current;
const newHeight = Math.max(minHeight, Math.min(maxHeight, startHeight.current + deltaY));
setHeaderHeight(newHeight);
},
[isResizing]
);
const handleMouseUp = useCallback(() => {
setIsResizing(false);
}, []);
useEffect(() => {
if (isResizing) {
document.addEventListener(
"mousemove",
// @ts-expect-error native discrepancy
handleMouseMove
);
document.addEventListener("mouseup", handleMouseUp);
document.body.style.cursor = "ns-resize";
document.body.style.userSelect = "none";
}
return () => {
document.removeEventListener(
"mousemove",
// @ts-expect-error native discrepancy
handleMouseMove
);
document.removeEventListener("mouseup", handleMouseUp);
document.body.style.cursor = "";
document.body.style.userSelect = "";
};
}, [isResizing, handleMouseMove, handleMouseUp]);
return {
headerHeight,
handleMouseDown,
isResizing
};
};