Merge remote-tracking branch 'origin/main' into feat/gitlabSecretSync

This commit is contained in:
carlosmonastyrski
2025-06-24 22:42:28 -03:00
213 changed files with 8222 additions and 1633 deletions
@@ -65,11 +65,11 @@ const fetchApprovalPolicies = async ({ projectSlug }: TGetAccessApprovalRequests
const fetchApprovalRequests = async ({
projectSlug,
envSlug,
authorProjectMembershipId
authorUserId
}: TGetAccessApprovalRequestsDTO) => {
const { data } = await apiRequest.get<{ requests: TAccessApprovalRequest[] }>(
"/api/v1/access-approvals/requests",
{ params: { projectSlug, envSlug, authorProjectMembershipId } }
{ params: { projectSlug, envSlug, authorUserId } }
);
return data.requests.map((request) => ({
@@ -109,12 +109,12 @@ export const useGetAccessRequestsCount = ({
export const useGetAccessApprovalPolicies = ({
projectSlug,
envSlug,
authorProjectMembershipId,
authorUserId,
options = {}
}: TGetAccessApprovalRequestsDTO & TReactQueryOptions) =>
useQuery({
queryKey: accessApprovalKeys.getAccessApprovalPolicies(projectSlug),
queryFn: () => fetchApprovalPolicies({ projectSlug, envSlug, authorProjectMembershipId }),
queryFn: () => fetchApprovalPolicies({ projectSlug, envSlug, authorUserId }),
...options,
enabled: Boolean(projectSlug) && (options?.enabled ?? true)
});
@@ -122,16 +122,13 @@ export const useGetAccessApprovalPolicies = ({
export const useGetAccessApprovalRequests = ({
projectSlug,
envSlug,
authorProjectMembershipId,
authorUserId,
options = {}
}: TGetAccessApprovalRequestsDTO & TReactQueryOptions) =>
useQuery({
queryKey: accessApprovalKeys.getAccessApprovalRequests(
projectSlug,
envSlug,
authorProjectMembershipId
),
queryFn: () => fetchApprovalRequests({ projectSlug, envSlug, authorProjectMembershipId }),
queryKey: accessApprovalKeys.getAccessApprovalRequests(projectSlug, envSlug, authorUserId),
queryFn: () => fetchApprovalRequests({ projectSlug, envSlug, authorUserId }),
...options,
enabled: Boolean(projectSlug) && (options?.enabled ?? true)
enabled: Boolean(projectSlug) && (options?.enabled ?? true),
placeholderData: (previousData) => previousData
});
@@ -35,7 +35,7 @@ export type Approver = {
id: string;
type: ApproverType;
sequence?: number;
approvals?: number;
approvalsRequired?: number;
};
export type Bypasser = {
@@ -148,7 +148,7 @@ export type TCreateAccessRequestDTO = {
export type TGetAccessApprovalRequestsDTO = {
projectSlug: string;
envSlug?: string;
authorProjectMembershipId?: string;
authorUserId?: string;
};
export type TGetAccessPolicyApprovalCountDTO = {
+12
View File
@@ -56,6 +56,11 @@ export type TUpdateServerConfigDTO = {
microsoftTeamsAppId?: string;
microsoftTeamsClientSecret?: string;
microsoftTeamsBotId?: string;
gitHubAppConnectionClientId?: string;
gitHubAppConnectionClientSecret?: string;
gitHubAppConnectionSlug?: string;
gitHubAppConnectionId?: string;
gitHubAppConnectionPrivateKey?: string;
} & Partial<TServerConfig>;
export type TCreateAdminUserDTO = {
@@ -100,6 +105,13 @@ export type AdminIntegrationsConfig = {
clientSecret: string;
botId: string;
};
gitHubAppConnection: {
clientId: string;
clientSecret: string;
appSlug: string;
appId: string;
privateKey: string;
};
};
export type TGetServerRootKmsEncryptionDetails = {
@@ -0,0 +1,2 @@
export * from "./queries";
export * from "./types";
@@ -0,0 +1,37 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "../queries";
import { TCloudflareProject } from "./types";
const cloudflareConnectionKeys = {
all: [...appConnectionKeys.all, "cloudflare"] as const,
listPagesProjects: (connectionId: string) =>
[...cloudflareConnectionKeys.all, "pages-projects", connectionId] as const
};
export const useCloudflareConnectionListPagesProjects = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TCloudflareProject[],
unknown,
TCloudflareProject[],
ReturnType<typeof cloudflareConnectionKeys.listPagesProjects>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: cloudflareConnectionKeys.listPagesProjects(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<TCloudflareProject[]>(
`/api/v1/app-connections/cloudflare/${connectionId}/cloudflare-pages-projects`
);
return data;
},
...options
});
};
@@ -0,0 +1,4 @@
export type TCloudflareProject = {
id: string;
name: string;
};
@@ -26,5 +26,6 @@ export enum AppConnection {
Heroku = "heroku",
Render = "render",
Flyio = "flyio",
Gitlab = "gitlab"
Gitlab = "gitlab",
Cloudflare = "cloudflare"
}
@@ -128,6 +128,10 @@ export type TGitlabConnectionOption = TAppConnectionOptionBase & {
oauthClientId?: string;
};
export type TCloudflareConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Cloudflare;
};
export type TAppConnectionOption =
| TAwsConnectionOption
| TGitHubConnectionOption
@@ -154,7 +158,8 @@ export type TAppConnectionOption =
| THerokuConnectionOption
| TRenderConnectionOption
| TFlyioConnectionOption
| TGitlabConnectionOption;
| TGitlabConnectionOption
| TCloudflareConnectionOption;
export type TAppConnectionOptionMap = {
[AppConnection.AWS]: TAwsConnectionOption;
@@ -185,4 +190,5 @@ export type TAppConnectionOptionMap = {
[AppConnection.Render]: TRenderConnectionOption;
[AppConnection.Flyio]: TFlyioConnectionOption;
[AppConnection.Gitlab]: TGitlabConnectionOption;
[AppConnection.Cloudflare]: TCloudflareConnectionOption;
};
@@ -0,0 +1,14 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum CloudflareConnectionMethod {
ApiToken = "api-token"
}
export type TCloudflareConnection = TRootAppConnection & { app: AppConnection.Cloudflare } & {
method: CloudflareConnectionMethod.ApiToken;
credentials: {
apiToken: string;
accountId: string;
};
};
@@ -8,6 +8,7 @@ import { TAzureClientSecretsConnection } from "./azure-client-secrets-connection
import { TAzureDevOpsConnection } from "./azure-devops-connection";
import { TAzureKeyVaultConnection } from "./azure-key-vault-connection";
import { TCamundaConnection } from "./camunda-connection";
import { TCloudflareConnection } from "./cloudflare-connection";
import { TDatabricksConnection } from "./databricks-connection";
import { TFlyioConnection } from "./flyio-connection";
import { TGcpConnection } from "./gcp-connection";
@@ -37,6 +38,7 @@ export * from "./azure-client-secrets-connection";
export * from "./azure-devops-connection";
export * from "./azure-key-vault-connection";
export * from "./camunda-connection";
export * from "./cloudflare-connection";
export * from "./databricks-connection";
export * from "./flyio-connection";
export * from "./gcp-connection";
@@ -86,7 +88,8 @@ export type TAppConnection =
| THerokuConnection
| TRenderConnection
| TFlyioConnection
| TGitlabConnection;
| TGitlabConnection
| TCloudflareConnection;
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
@@ -142,4 +145,5 @@ export type TAppConnectionMap = {
[AppConnection.Render]: TRenderConnection;
[AppConnection.Flyio]: TFlyioConnection;
[AppConnection.Gitlab]: TGitlabConnection;
[AppConnection.Cloudflare]: TCloudflareConnection;
};
-1
View File
@@ -73,7 +73,6 @@ export const selectOrganization = async (data: {
}) => {
const { data: res } = await apiRequest.post<{
token: string;
refreshToken: string;
isMfaEnabled: boolean;
mfaMethod?: MfaMethod;
}>("/api/v3/auth/select-organization", data);
+15 -2
View File
@@ -12,9 +12,10 @@ export type TDynamicSecret = {
defaultTTL: string;
status?: DynamicSecretStatus;
statusDetails?: string;
maxTTL: string;
maxTTL?: string;
usernameTemplate?: string | null;
metadata?: { key: string; value: string }[];
tags?: { key: string; value: string }[];
};
export enum DynamicSecretProviders {
@@ -35,7 +36,8 @@ export enum DynamicSecretProviders {
SapAse = "sap-ase",
Kubernetes = "kubernetes",
Vertica = "vertica",
GcpIam = "gcp-iam"
GcpIam = "gcp-iam",
Github = "github"
}
export enum KubernetesDynamicSecretCredentialType {
@@ -89,6 +91,7 @@ export type TDynamicSecretProvider =
}
| {
type: DynamicSecretProviders.AwsIam;
tags?: { key: string; value: string }[];
inputs:
| {
method: DynamicSecretAwsIamAuth.AccessKey;
@@ -333,6 +336,14 @@ export type TDynamicSecretProvider =
inputs: {
serviceAccountEmail: string;
};
}
| {
type: DynamicSecretProviders.Github;
inputs: {
appId: number;
installationId: number;
privateKey: string;
};
};
export type TCreateDynamicSecretDTO = {
@@ -345,6 +356,7 @@ export type TCreateDynamicSecretDTO = {
name: string;
metadata?: { key: string; value: string }[];
usernameTemplate?: string;
tags?: { key: string; value: string }[];
};
export type TUpdateDynamicSecretDTO = {
@@ -359,6 +371,7 @@ export type TUpdateDynamicSecretDTO = {
maxTTL?: string | null;
inputs?: unknown;
usernameTemplate?: string | null;
tags?: { key: string; value: string }[];
};
};
@@ -1,5 +1,5 @@
/* eslint-disable no-param-reassign */
import { useInfiniteQuery, useQuery, UseQueryOptions } from "@tanstack/react-query";
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import {
decryptAssymmetric,
@@ -25,10 +25,11 @@ export const secretApprovalRequestKeys = {
status,
committer,
offset,
limit
limit,
search
}: TGetSecretApprovalRequestList) =>
[
{ workspaceId, environment, status, committer, offset, limit },
{ workspaceId, environment, status, committer, offset, limit, search },
"secret-approval-requests"
] as const,
detail: ({ id }: Omit<TGetSecretApprovalRequestDetails, "decryptKey">) =>
@@ -118,23 +119,25 @@ const fetchSecretApprovalRequestList = async ({
committer,
status = "open",
limit = 20,
offset
offset = 0,
search = ""
}: TGetSecretApprovalRequestList) => {
const { data } = await apiRequest.get<{ approvals: TSecretApprovalRequest[] }>(
"/api/v1/secret-approval-requests",
{
params: {
workspaceId,
environment,
committer,
status,
limit,
offset
}
const { data } = await apiRequest.get<{
approvals: TSecretApprovalRequest[];
totalCount: number;
}>("/api/v1/secret-approval-requests", {
params: {
workspaceId,
environment,
committer,
status,
limit,
offset,
search
}
);
});
return data.approvals;
return data;
};
export const useGetSecretApprovalRequests = ({
@@ -143,31 +146,32 @@ export const useGetSecretApprovalRequests = ({
options = {},
status,
limit = 20,
offset = 0,
search,
committer
}: TGetSecretApprovalRequestList & TReactQueryOptions) =>
useInfiniteQuery({
initialPageParam: 0,
useQuery({
queryKey: secretApprovalRequestKeys.list({
workspaceId,
environment,
committer,
status
status,
limit,
search,
offset
}),
queryFn: ({ pageParam }) =>
queryFn: () =>
fetchSecretApprovalRequestList({
workspaceId,
environment,
status,
committer,
limit,
offset: pageParam
offset,
search
}),
enabled: Boolean(workspaceId) && (options?.enabled ?? true),
getNextPageParam: (lastPage, pages) => {
if (lastPage.length && lastPage.length < limit) return undefined;
return lastPage?.length !== 0 ? pages.length * limit : undefined;
}
placeholderData: (previousData) => previousData
});
const fetchSecretApprovalRequestDetails = async ({
@@ -113,6 +113,7 @@ export type TGetSecretApprovalRequestList = {
committer?: string;
limit?: number;
offset?: number;
search?: string;
};
export type TGetSecretApprovalRequestCount = {
+2 -1
View File
@@ -19,7 +19,8 @@ export enum SecretSync {
Heroku = "heroku",
Render = "render",
Flyio = "flyio",
GitLab = "gitlab"
GitLab = "gitlab",
CloudflarePages = "cloudflare-pages"
}
export enum SecretSyncStatus {
@@ -0,0 +1,16 @@
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";
export type TCloudflarePagesSync = TRootSecretSync & {
destination: SecretSync.CloudflarePages;
destinationConfig: {
projectName: string;
environment: string;
};
connection: {
app: AppConnection.Cloudflare;
name: string;
id: string;
};
};
@@ -9,6 +9,7 @@ import { TAzureAppConfigurationSync } from "./azure-app-configuration-sync";
import { TAzureDevOpsSync } from "./azure-devops-sync";
import { TAzureKeyVaultSync } from "./azure-key-vault-sync";
import { TCamundaSync } from "./camunda-sync";
import { TCloudflarePagesSync } from "./cloudflare-pages-sync";
import { TDatabricksSync } from "./databricks-sync";
import { TFlyioSync } from "./flyio-sync";
import { TGcpSync } from "./gcp-sync";
@@ -51,7 +52,8 @@ export type TSecretSync =
| THerokuSync
| TRenderSync
| TFlyioSync
| TGitlabSync;
| TGitlabSync
| TCloudflarePagesSync;
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };