Merge branch 'heads/main' into daniel/srp-removal-round-2

This commit is contained in:
Daniel Hougaard
2025-08-05 22:17:01 +04:00
446 changed files with 13524 additions and 3367 deletions
+19
View File
@@ -68,6 +68,25 @@ export const useAdminDeleteUser = () => {
});
};
export const useAdminBulkDeleteUsers = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (userIds: string[]) => {
await apiRequest.delete("/api/v1/admin/user-management/users", {
data: { userIds }
});
return {};
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: [adminStandaloneKeys.getUsers]
});
queryClient.invalidateQueries({ queryKey: adminStandaloneKeys.getOrganizations });
}
});
};
export const useAdminDeleteOrganizationMembership = () => {
const queryClient = useQueryClient();
return useMutation<object, object, { organizationId: string; membershipId: string }>({
+1
View File
@@ -35,6 +35,7 @@ export type TServerConfig = {
initialized: boolean;
allowSignUp: boolean;
allowedSignUpDomain?: string | null;
disableAuditLogStorage: boolean;
isMigrationModeOn?: boolean;
trustSamlEmails: boolean;
trustLdapEmails: boolean;
@@ -3,14 +3,16 @@ import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "../queries";
import { TCloudflarePagesProject, TCloudflareWorkersScript } from "./types";
import { TCloudflarePagesProject, TCloudflareWorkersScript, TCloudflareZone } from "./types";
const cloudflareConnectionKeys = {
all: [...appConnectionKeys.all, "cloudflare"] as const,
listPagesProjects: (connectionId: string) =>
[...cloudflareConnectionKeys.all, "pages-projects", connectionId] as const,
listWorkersScripts: (connectionId: string) =>
[...cloudflareConnectionKeys.all, "workers-scripts", connectionId] as const
[...cloudflareConnectionKeys.all, "workers-scripts", connectionId] as const,
listZones: (connectionId: string) =>
[...cloudflareConnectionKeys.all, "zones", connectionId] as const
};
export const useCloudflareConnectionListPagesProjects = (
@@ -62,3 +64,28 @@ export const useCloudflareConnectionListWorkersScripts = (
...options
});
};
export const useCloudflareConnectionListZones = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TCloudflareZone[],
unknown,
TCloudflareZone[],
ReturnType<typeof cloudflareConnectionKeys.listZones>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: cloudflareConnectionKeys.listZones(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<TCloudflareZone[]>(
`/api/v1/app-connections/cloudflare/${connectionId}/cloudflare-zones`
);
return data;
},
...options
});
};
@@ -6,3 +6,8 @@ export type TCloudflarePagesProject = {
export type TCloudflareWorkersScript = {
id: string;
};
export type TCloudflareZone = {
id: string;
name: string;
};
@@ -26,7 +26,7 @@ export enum AppConnection {
Heroku = "heroku",
Render = "render",
Flyio = "flyio",
Gitlab = "gitlab",
GitLab = "gitlab",
Cloudflare = "cloudflare",
Bitbucket = "bitbucket",
Zabbix = "zabbix",
@@ -34,5 +34,6 @@ export enum AppConnection {
Checkly = "checkly",
Supabase = "supabase",
DigitalOcean = "digital-ocean",
Netlify = "netlify",
Okta = "okta"
}
@@ -13,7 +13,7 @@ const gitlabConnectionKeys = {
[...gitlabConnectionKeys.all, "groups", connectionId] as const
};
export const useGitlabConnectionListProjects = (
export const useGitLabConnectionListProjects = (
connectionId: string,
options?: Omit<
UseQueryOptions<
@@ -38,7 +38,7 @@ export const useGitlabConnectionListProjects = (
});
};
export const useGitlabConnectionListGroups = (
export const useGitLabConnectionListGroups = (
connectionId: string,
options?: Omit<
UseQueryOptions<
@@ -0,0 +1,2 @@
export * from "./queries";
export * from "./types";
@@ -0,0 +1,65 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "@app/hooks/api/appConnections";
import { TNetlifyAccount, TNetlifySite } from "./types";
const netlifyConnectionKeys = {
all: [...appConnectionKeys.all, "netlify"] as const,
listAccounts: (connectionId: string) =>
[...netlifyConnectionKeys.all, "accounts", connectionId] as const,
listSites: (connectionId: string, accountId: string) =>
[...netlifyConnectionKeys.all, "sites", connectionId, accountId] as const
};
export const useNetlifyConnectionListAccounts = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TNetlifyAccount[],
unknown,
TNetlifyAccount[],
ReturnType<typeof netlifyConnectionKeys.listAccounts>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: netlifyConnectionKeys.listAccounts(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<{ accounts: TNetlifyAccount[] }>(
`/api/v1/app-connections/netlify/${connectionId}/accounts`
);
return data.accounts;
},
...options
});
};
export const useNetlifyConnectionListSites = (
connectionId: string,
accountId: string,
options?: Omit<
UseQueryOptions<
TNetlifySite[],
unknown,
TNetlifySite[],
ReturnType<typeof netlifyConnectionKeys.listSites>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: netlifyConnectionKeys.listSites(connectionId, accountId),
queryFn: async () => {
const { data } = await apiRequest.get<{ sites: TNetlifySite[] }>(
`/api/v1/app-connections/netlify/${connectionId}/accounts/${accountId}/sites`
);
return data.sites;
},
...options
});
};
@@ -0,0 +1,9 @@
export type TNetlifyAccount = {
id: string;
name: string;
};
export type TNetlifySite = {
id: string;
name: string;
};
@@ -124,7 +124,7 @@ export type TFlyioConnectionOption = TAppConnectionOptionBase & {
};
export type TGitlabConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Gitlab;
app: AppConnection.GitLab;
oauthClientId?: string;
};
@@ -156,6 +156,10 @@ export type TDigitalOceanConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.DigitalOcean;
};
export type TNetlifyConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Netlify;
};
export type TOktaConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Okta;
};
@@ -193,6 +197,7 @@ export type TAppConnectionOption =
| TRailwayConnectionOption
| TChecklyConnectionOption
| TDigitalOceanConnectionOption
| TNetlifyConnectionOption
| TOktaConnectionOption;
export type TAppConnectionOptionMap = {
@@ -223,7 +228,7 @@ export type TAppConnectionOptionMap = {
[AppConnection.Heroku]: THerokuConnectionOption;
[AppConnection.Render]: TRenderConnectionOption;
[AppConnection.Flyio]: TFlyioConnectionOption;
[AppConnection.Gitlab]: TGitlabConnectionOption;
[AppConnection.GitLab]: TGitlabConnectionOption;
[AppConnection.Cloudflare]: TCloudflareConnectionOption;
[AppConnection.Bitbucket]: TBitbucketConnectionOption;
[AppConnection.Zabbix]: TZabbixConnectionOption;
@@ -231,5 +236,6 @@ export type TAppConnectionOptionMap = {
[AppConnection.Checkly]: TChecklyConnectionOption;
[AppConnection.Supabase]: TSupabaseConnectionOption;
[AppConnection.DigitalOcean]: TDigitalOceanConnectionOption;
[AppConnection.Netlify]: TNetlifyConnectionOption;
[AppConnection.Okta]: TOktaConnectionOption;
};
@@ -2,15 +2,26 @@ import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum AzureAppConfigurationConnectionMethod {
OAuth = "oauth"
OAuth = "oauth",
ClientSecret = "client-secret"
}
export type TAzureAppConfigurationConnection = TRootAppConnection & {
app: AppConnection.AzureAppConfiguration;
} & {
method: AzureAppConfigurationConnectionMethod.OAuth;
credentials: {
code: string;
tenantId?: string;
};
};
} & (
| {
method: AzureAppConfigurationConnectionMethod.OAuth;
credentials: {
code: string;
tenantId?: string;
};
}
| {
method: AzureAppConfigurationConnectionMethod.ClientSecret;
credentials: {
clientId: string;
clientSecret: string;
tenantId: string;
};
}
);
@@ -3,7 +3,8 @@ import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-con
export enum AzureDevOpsConnectionMethod {
OAuth = "oauth",
AccessToken = "access-token"
AccessToken = "access-token",
ClientSecret = "client-secret"
}
export type TAzureDevOpsConnection = TRootAppConnection & {
@@ -24,4 +25,13 @@ export type TAzureDevOpsConnection = TRootAppConnection & {
orgName: string;
};
}
| {
method: AzureDevOpsConnectionMethod.ClientSecret;
credentials: {
clientSecret: string;
tenantId: string;
clientId: string;
orgName: string;
};
}
);
@@ -2,13 +2,24 @@ import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum AzureKeyVaultConnectionMethod {
OAuth = "oauth"
OAuth = "oauth",
ClientSecret = "client-secret"
}
export type TAzureKeyVaultConnection = TRootAppConnection & { app: AppConnection.AzureKeyVault } & {
method: AzureKeyVaultConnectionMethod.OAuth;
credentials: {
code: string;
tenantId?: string;
};
};
export type TAzureKeyVaultConnection = TRootAppConnection & { app: AppConnection.AzureKeyVault } & (
| {
method: AzureKeyVaultConnectionMethod.OAuth;
credentials: {
code: string;
tenantId?: string;
};
}
| {
method: AzureKeyVaultConnectionMethod.ClientSecret;
credentials: {
clientId: string;
clientSecret: string;
tenantId: string;
};
}
);
@@ -11,6 +11,7 @@ export type TGitHubConnection = TRootAppConnection & { app: AppConnection.GitHub
method: GitHubConnectionMethod.OAuth;
credentials: {
code: string;
instanceType?: "cloud" | "server";
host?: string;
};
}
@@ -19,6 +20,7 @@ export type TGitHubConnection = TRootAppConnection & { app: AppConnection.GitHub
credentials: {
code: string;
installationId: string;
instanceType?: "cloud" | "server";
host?: string;
};
}
@@ -8,7 +8,7 @@ export enum GitLabConnectionMethod {
OAuth = "oauth"
}
export type TGitLabConnection = TRootAppConnection & { app: AppConnection.Gitlab } & (
export type TGitLabConnection = TRootAppConnection & { app: AppConnection.GitLab } & (
| {
method: GitLabConnectionMethod.AccessToken;
credentials: {
@@ -24,6 +24,7 @@ import { THumanitecConnection } from "./humanitec-connection";
import { TLdapConnection } from "./ldap-connection";
import { TMsSqlConnection } from "./mssql-connection";
import { TMySqlConnection } from "./mysql-connection";
import { TNetlifyConnection } from "./netlify-connection";
import { TOCIConnection } from "./oci-connection";
import { TOktaConnection } from "./okta-connection";
import { TOracleDBConnection } from "./oracledb-connection";
@@ -109,6 +110,7 @@ export type TAppConnection =
| TChecklyConnection
| TSupabaseConnection
| TDigitalOceanConnection
| TNetlifyConnection
| TOktaConnection;
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
@@ -173,7 +175,7 @@ export type TAppConnectionMap = {
[AppConnection.Heroku]: THerokuConnection;
[AppConnection.Render]: TRenderConnection;
[AppConnection.Flyio]: TFlyioConnection;
[AppConnection.Gitlab]: TGitLabConnection;
[AppConnection.GitLab]: TGitLabConnection;
[AppConnection.Cloudflare]: TCloudflareConnection;
[AppConnection.Bitbucket]: TBitbucketConnection;
[AppConnection.Zabbix]: TZabbixConnection;
@@ -181,5 +183,6 @@ export type TAppConnectionMap = {
[AppConnection.Checkly]: TChecklyConnection;
[AppConnection.Supabase]: TSupabaseConnection;
[AppConnection.DigitalOcean]: TDigitalOceanConnection;
[AppConnection.Netlify]: TNetlifyConnection;
[AppConnection.Okta]: TOktaConnection;
};
@@ -0,0 +1,14 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum NetlifyConnectionMethod {
AccessToken = "access-token"
}
export type TNetlifyConnection = TRootAppConnection & {
app: AppConnection.Netlify;
method: NetlifyConnectionMethod.AccessToken;
credentials: {
accessToken: string;
};
};
+12 -1
View File
@@ -1,6 +1,7 @@
import { AppConnection } from "../appConnections/enums";
import { SshCaStatus } from "../sshCa";
import { SshCertTemplateStatus } from "../sshCertificateTemplates";
import { CaStatus, InternalCaType } from "./enums";
import { AcmeDnsProvider, CaStatus, InternalCaType } from "./enums";
export const caTypeToNameMap: { [K in InternalCaType]: string } = {
[InternalCaType.ROOT]: "Root",
@@ -13,6 +14,16 @@ export const caStatusToNameMap: { [K in CaStatus]: string } = {
[CaStatus.PENDING_CERTIFICATE]: "Pending Certificate"
};
export const ACME_DNS_PROVIDER_NAME_MAP: Record<AcmeDnsProvider, string> = {
[AcmeDnsProvider.ROUTE53]: "Route53",
[AcmeDnsProvider.Cloudflare]: "Cloudflare"
};
export const ACME_DNS_PROVIDER_APP_CONNECTION_MAP: Record<AcmeDnsProvider, AppConnection> = {
[AcmeDnsProvider.ROUTE53]: AppConnection.AWS,
[AcmeDnsProvider.Cloudflare]: AppConnection.Cloudflare
};
export const getCaStatusBadgeVariant = (status: CaStatus | SshCaStatus | SshCertTemplateStatus) => {
switch (status) {
case CaStatus.ACTIVE:
+2 -1
View File
@@ -19,5 +19,6 @@ export enum CaRenewalType {
}
export enum AcmeDnsProvider {
ROUTE53 = "route53"
ROUTE53 = "route53",
Cloudflare = "cloudflare"
}
+1 -1
View File
@@ -11,7 +11,7 @@ export type TAcmeCertificateAuthority = {
configuration: {
dnsAppConnectionId: string;
dnsProviderConfig: {
provider: AcmeDnsProvider.ROUTE53;
provider: AcmeDnsProvider;
hostedZoneId: string;
};
directoryUrl: string;
@@ -1385,6 +1385,7 @@ export const useAddIdentityLdapAuth = () => {
return useMutation<IdentityLdapAuth, object, AddIdentityLdapAuthDTO>({
mutationFn: async ({
identityId,
templateId,
url,
bindDN,
bindPass,
@@ -1400,6 +1401,7 @@ export const useAddIdentityLdapAuth = () => {
const { data } = await apiRequest.post<{ identityLdapAuth: IdentityLdapAuth }>(
`/api/v1/auth/ldap-auth/identities/${identityId}`,
{
templateId,
url,
bindDN,
bindPass,
@@ -1432,6 +1434,7 @@ export const useUpdateIdentityLdapAuth = () => {
return useMutation<IdentityLdapAuth, object, UpdateIdentityLdapAuthDTO>({
mutationFn: async ({
identityId,
templateId,
url,
bindDN,
bindPass,
@@ -1447,6 +1450,7 @@ export const useUpdateIdentityLdapAuth = () => {
const { data } = await apiRequest.patch<{ identityLdapAuth: IdentityLdapAuth }>(
`/api/v1/auth/ldap-auth/identities/${identityId}`,
{
templateId,
url,
bindDN,
bindPass,
+11 -8
View File
@@ -567,10 +567,11 @@ export type IdentityTokenAuth = {
export type AddIdentityLdapAuthDTO = {
organizationId: string;
identityId: string;
url: string;
bindDN: string;
bindPass: string;
searchBase: string;
templateId?: string;
url?: string;
bindDN?: string;
bindPass?: string;
searchBase?: string;
searchFilter: string;
ldapCaCertificate?: string;
allowedFields?: {
@@ -588,6 +589,7 @@ export type AddIdentityLdapAuthDTO = {
export type UpdateIdentityLdapAuthDTO = {
identityId: string;
organizationId: string;
templateId?: string;
url?: string;
bindDN?: string;
bindPass?: string;
@@ -612,10 +614,11 @@ export type DeleteIdentityLdapAuthDTO = {
};
export type IdentityLdapAuth = {
url: string;
bindDN: string;
bindPass: string;
searchBase: string;
url?: string;
bindDN?: string;
templateId?: string;
bindPass?: string;
searchBase?: string;
searchFilter: string;
ldapCaCertificate?: string;
allowedFields?: {
@@ -0,0 +1,3 @@
export * from "./mutations";
export * from "./queries";
export * from "./types";
@@ -0,0 +1,97 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { identityAuthTemplatesKeys } from "./queries";
import {
CreateIdentityAuthTemplateDTO,
DeleteIdentityAuthTemplateDTO,
IdentityAuthTemplate,
MachineAuthTemplateUsage,
UnlinkTemplateUsageDTO,
UpdateIdentityAuthTemplateDTO
} from "./types";
export const useCreateIdentityAuthTemplate = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (dto: CreateIdentityAuthTemplateDTO) => {
const { data } = await apiRequest.post<{ template: IdentityAuthTemplate }>(
"/api/v1/identity-templates",
dto
);
return data.template;
},
onSuccess: (_, { organizationId }) => {
queryClient.invalidateQueries({
queryKey: identityAuthTemplatesKeys.getTemplates({ organizationId })
});
}
});
};
export const useUpdateIdentityAuthTemplate = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (dto: UpdateIdentityAuthTemplateDTO) => {
const { data } = await apiRequest.patch<{ template: IdentityAuthTemplate }>(
`/api/v1/identity-templates/${dto.templateId}`,
dto
);
return data.template;
},
onSuccess: (_, { organizationId, templateId }) => {
queryClient.invalidateQueries({
queryKey: identityAuthTemplatesKeys.getTemplates({ organizationId })
});
queryClient.invalidateQueries({
queryKey: identityAuthTemplatesKeys.getTemplate(templateId)
});
}
});
};
export const useDeleteIdentityAuthTemplate = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (dto: DeleteIdentityAuthTemplateDTO) => {
await apiRequest.delete(`/api/v1/identity-templates/${dto.templateId}`, {
params: { organizationId: dto.organizationId }
});
},
onSuccess: (_, { organizationId, templateId }) => {
queryClient.invalidateQueries({
queryKey: identityAuthTemplatesKeys.getTemplates({ organizationId })
});
queryClient.removeQueries({
queryKey: identityAuthTemplatesKeys.getTemplate(templateId)
});
}
});
};
export const useUnlinkTemplateUsage = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (dto: UnlinkTemplateUsageDTO) => {
const { data } = await apiRequest.post<MachineAuthTemplateUsage[]>(
`/api/v1/identity-templates/${dto.templateId}/delete-usage`,
{ identityIds: dto.identityIds },
{ params: { organizationId: dto.organizationId } }
);
return data;
},
onSuccess: (_, { templateId, organizationId }) => {
queryClient.invalidateQueries({
queryKey: identityAuthTemplatesKeys.getTemplateUsages(templateId)
});
queryClient.invalidateQueries({
queryKey: identityAuthTemplatesKeys.getTemplates({ organizationId })
});
}
});
};
@@ -0,0 +1,89 @@
import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import {
GetIdentityAuthTemplatesDTO,
GetTemplateUsagesDTO,
IdentityAuthTemplate,
MachineAuthTemplateUsage,
MachineIdentityAuthMethod
} from "./types";
export const identityAuthTemplatesKeys = {
all: ["identity-auth-templates"] as const,
getTemplates: (dto: GetIdentityAuthTemplatesDTO) =>
[...identityAuthTemplatesKeys.all, "list", dto] as const,
getTemplate: (templateId: string) =>
[...identityAuthTemplatesKeys.all, "single", templateId] as const,
getAvailableTemplates: (authMethod: MachineIdentityAuthMethod) =>
[...identityAuthTemplatesKeys.all, "available", authMethod] as const,
getTemplateUsages: (templateId: string) =>
[...identityAuthTemplatesKeys.all, "usages", templateId] as const
};
export const useGetIdentityAuthTemplates = (dto: GetIdentityAuthTemplatesDTO) => {
return useQuery({
queryKey: identityAuthTemplatesKeys.getTemplates(dto),
queryFn: async () => {
const { data } = await apiRequest.get<{
templates: IdentityAuthTemplate[];
totalCount: number;
}>("/api/v1/identity-templates/search", {
params: {
organizationId: dto.organizationId,
limit: dto.limit || 50,
offset: dto.offset || 0,
...(dto.search && { search: dto.search })
}
});
return data;
},
enabled: Boolean(dto.organizationId)
});
};
export const useGetIdentityAuthTemplate = (templateId: string, organizationId: string) => {
return useQuery({
queryKey: identityAuthTemplatesKeys.getTemplate(templateId),
queryFn: async () => {
const { data } = await apiRequest.get<IdentityAuthTemplate>(
`/api/v1/identity-templates/${templateId}`,
{
params: { organizationId }
}
);
return data;
},
enabled: Boolean(templateId) && Boolean(organizationId)
});
};
export const useGetAvailableTemplates = (authMethod: MachineIdentityAuthMethod) => {
return useQuery({
queryKey: identityAuthTemplatesKeys.getAvailableTemplates(authMethod),
queryFn: async () => {
const { data } = await apiRequest.get<IdentityAuthTemplate[]>("/api/v1/identity-templates", {
params: { authMethod }
});
return data;
},
enabled: Boolean(authMethod)
});
};
export const useGetTemplateUsages = (dto: GetTemplateUsagesDTO) => {
return useQuery({
queryKey: identityAuthTemplatesKeys.getTemplateUsages(dto.templateId),
queryFn: async () => {
const { data } = await apiRequest.get<MachineAuthTemplateUsage[]>(
`/api/v1/identity-templates/${dto.templateId}/usage`,
{
params: { organizationId: dto.organizationId }
}
);
return data;
},
enabled: Boolean(dto.templateId) && Boolean(dto.organizationId)
});
};
@@ -0,0 +1,78 @@
export enum MachineIdentityAuthMethod {
LDAP = "ldap"
}
export interface LdapTemplateFields {
url: string;
bindDN: string;
bindPass: string;
searchBase: string;
ldapCaCertificate?: string;
}
export interface IdentityAuthTemplate {
id: string;
name: string;
authMethod: MachineIdentityAuthMethod;
organizationId: string;
templateFields: LdapTemplateFields;
createdAt: string;
updatedAt: string;
}
export interface CreateIdentityAuthTemplateDTO {
organizationId: string;
name: string;
authMethod: MachineIdentityAuthMethod;
templateFields: LdapTemplateFields;
}
export interface UpdateIdentityAuthTemplateDTO {
templateId: string;
organizationId: string;
name?: string;
templateFields?: Partial<LdapTemplateFields>;
}
export interface DeleteIdentityAuthTemplateDTO {
templateId: string;
organizationId: string;
}
export interface GetIdentityAuthTemplatesDTO {
organizationId: string;
limit?: number;
offset?: number;
search?: string;
}
export interface MachineAuthTemplateUsage {
identityId: string;
identityName: string;
}
export interface GetTemplateUsagesDTO {
templateId: string;
organizationId: string;
}
export interface UnlinkTemplateUsageDTO {
templateId: string;
identityIds: string[];
organizationId: string;
}
export const TEMPLATE_ERROR_MESSAGES = {
UNLINK_SUCCESS: "Successfully unlinked template usages",
UNLINK_FAILED: "Failed to unlink template usages",
SINGLE_UNLINK_SUCCESS: "Successfully unlinked template usage",
SINGLE_UNLINK_FAILED: "Failed to unlink template usage"
} as const;
export const TEMPLATE_UI_LABELS = {
VIEW_USAGES: "View Usages",
EDIT_TEMPLATE: "Edit Template",
DELETE_TEMPLATE: "Delete Template",
UNLINK: "Unlink",
UNSELECT_ALL: "Unselect All"
} as const;
+1
View File
@@ -15,6 +15,7 @@ export * from "./gateways";
export * from "./githubOrgSyncConfig";
export * from "./groups";
export * from "./identities";
export * from "./identityAuthTemplates";
export * from "./identityProjectAdditionalPrivilege";
export * from "./incidentContacts";
export * from "./integrationAuth";
+3 -2
View File
@@ -12,14 +12,15 @@ export const useCreateReminder = (secretId: string) => {
const queryClient = useQueryClient();
return useMutation<Reminder, object, CreateReminderDTO>({
mutationFn: async ({ message, repeatDays, nextReminderDate, recipients }) => {
mutationFn: async ({ message, repeatDays, nextReminderDate, recipients, fromDate }) => {
const { data } = await apiRequest.post<{ reminder: Reminder }>(
`/api/v1/reminders/secrets/${secretId}`,
{
message,
repeatDays,
nextReminderDate,
recipients
recipients,
fromDate
}
);
return data.reminder;
@@ -2,6 +2,7 @@ export type CreateReminderDTO = {
message?: string | null;
repeatDays?: number | null;
nextReminderDate?: Date | null;
fromDate?: Date | null;
secretId: string;
recipients?: string[];
};
@@ -1,6 +1,7 @@
export enum SecretScanningDataSource {
GitHub = "github",
Bitbucket = "bitbucket"
Bitbucket = "bitbucket",
GitLab = "gitlab"
}
export enum SecretScanningScanStatus {
@@ -0,0 +1,31 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { SecretScanningDataSource } from "../enums";
import { TSecretScanningDataSourceBase } from "./shared";
export enum GitLabDataSourceScope {
Project = "project",
Group = "group"
}
export type TGitLabDataSource = TSecretScanningDataSourceBase & {
type: SecretScanningDataSource.GitLab;
config:
| {
groupId: number;
groupName?: string;
includeProjects: string[];
scope: GitLabDataSourceScope.Group;
}
| {
projectName?: string;
projectId: number;
scope: GitLabDataSourceScope.Project;
};
};
export type TGitLabDataSourceOption = {
name: string;
type: SecretScanningDataSource.GitLab;
connection: AppConnection.GitLab;
};
@@ -1,3 +1,7 @@
import {
TGitLabDataSource,
TGitLabDataSourceOption
} from "@app/hooks/api/secretScanningV2/types/gitlab-data-source";
import { DiscriminativePick } from "@app/types";
import {
@@ -11,7 +15,10 @@ import {
import { TBitbucketDataSource, TBitbucketDataSourceOption } from "./bitbucket-data-source";
import { TGitHubDataSource, TGitHubDataSourceOption } from "./github-data-source";
export type TSecretScanningDataSource = TGitHubDataSource | TBitbucketDataSource;
export type TSecretScanningDataSource =
| TGitHubDataSource
| TBitbucketDataSource
| TGitLabDataSource;
export type TSecretScanningDataSourceWithDetails = TSecretScanningDataSource & {
lastScannedAt: string | null;
@@ -24,7 +31,10 @@ export type TListSecretScanningDataSources = {
dataSources: TSecretScanningDataSourceWithDetails[];
};
export type TSecretScanningDataSourceOption = TGitHubDataSourceOption | TBitbucketDataSourceOption;
export type TSecretScanningDataSourceOption =
| TGitHubDataSourceOption
| TBitbucketDataSourceOption
| TGitLabDataSourceOption;
export type TListSecretScanningDataSourceOptions = {
dataSourceOptions: TSecretScanningDataSourceOption[];
@@ -27,6 +27,7 @@ export enum SecretSync {
Railway = "railway",
Checkly = "checkly",
DigitalOceanAppPlatform = "digital-ocean-app-platform",
Netlify = "netlify",
Bitbucket = "bitbucket"
}
@@ -29,7 +29,7 @@ export type TGitLabSync = TRootSecretSync & {
shouldHideSecrets?: boolean;
};
connection: {
app: AppConnection.Gitlab;
app: AppConnection.GitLab;
name: string;
id: string;
};
@@ -21,6 +21,7 @@ import { TGitLabSync } from "./gitlab-sync";
import { THCVaultSync } from "./hc-vault-sync";
import { THerokuSync } from "./heroku-sync";
import { THumanitecSync } from "./humanitec-sync";
import { TNetlifySync } from "./netlify-sync";
import { TOCIVaultSync } from "./oci-vault-sync";
import { TRailwaySync } from "./railway-sync";
import { TRenderSync } from "./render-sync";
@@ -67,6 +68,7 @@ export type TSecretSync =
| TChecklySync
| TSupabaseSync
| TDigitalOceanAppPlatformSync
| TNetlifySync
| TBitbucketSync;
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };
@@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-empty-object-type */
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 TNetlifySync = TRootSecretSync & {
destination: SecretSync.Netlify;
destinationConfig: {
accountId: string;
accountName: string;
siteId?: string;
siteName?: string;
context?: string;
};
connection: {
app: AppConnection.Netlify;
name: string;
id: string;
};
};
@@ -5,4 +5,5 @@ export type ServerStatus = {
secretScanningConfigured: boolean;
redisConfigured: boolean;
samlDefaultOrgSlug: string;
auditLogStorageDisabled: boolean;
};
@@ -53,4 +53,5 @@ export type SubscriptionPlan = {
secretScanning: boolean;
enterpriseSecretSyncs: boolean;
enterpriseAppConnections: boolean;
machineIdentityAuthTemplates: boolean;
};
+21 -3
View File
@@ -17,7 +17,8 @@ import {
APIKeyData,
AuthMethod,
CreateAPIKeyRes,
DeletOrgMembershipDTO,
DeleteOrgMembershipBatchDTO,
DeleteOrgMembershipDTO,
OrgUser,
RenameUserDTO,
TokenVersion,
@@ -243,7 +244,7 @@ export const useGetOrgMembershipProjectMemberships = (
export const useDeleteOrgMembership = () => {
const queryClient = useQueryClient();
return useMutation<object, object, DeletOrgMembershipDTO>({
return useMutation<object, object, DeleteOrgMembershipDTO>({
mutationFn: ({ membershipId, orgId }) => {
return apiRequest.delete(`/api/v2/organizations/${orgId}/memberships/${membershipId}`);
},
@@ -253,10 +254,27 @@ export const useDeleteOrgMembership = () => {
});
};
export const useDeleteOrgMembershipBatch = () => {
const queryClient = useQueryClient();
return useMutation<object, object, DeleteOrgMembershipBatchDTO>({
mutationFn: ({ membershipIds, orgId }) => {
return apiRequest.delete(`/api/v2/organizations/${orgId}/memberships`, {
data: {
membershipIds
}
});
},
onSuccess: (_, { orgId }) => {
queryClient.invalidateQueries({ queryKey: userKeys.getOrgUsers(orgId) });
}
});
};
export const useDeactivateOrgMembership = () => {
const queryClient = useQueryClient();
return useMutation<object, object, DeletOrgMembershipDTO>({
return useMutation<object, object, DeleteOrgMembershipDTO>({
mutationFn: ({ membershipId, orgId }) => {
return apiRequest.post(
`/api/v2/organizations/${orgId}/memberships/${membershipId}/deactivate`
+6 -1
View File
@@ -143,11 +143,16 @@ export type UpdateOrgMembershipDTO = {
metadata?: { key: string; value: string }[];
};
export type DeletOrgMembershipDTO = {
export type DeleteOrgMembershipDTO = {
membershipId: string;
orgId: string;
};
export type DeleteOrgMembershipBatchDTO = {
membershipIds: string[];
orgId: string;
};
export type AddUserToOrgDTO = {
inviteeEmails: string[];
organizationRoleSlug: string;