mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 15:40:47 +00:00
MVP preliminary idea for initial sync behavior
This commit is contained in:
@@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { organizationKeys } from "../organization/queries";
|
||||
import { User } from "../users/types";
|
||||
import { adminQueryKeys } from "./queries";
|
||||
import { TCreateAdminUserDTO, TServerConfig } from "./types";
|
||||
@@ -9,7 +10,11 @@ import { TCreateAdminUserDTO, TServerConfig } from "./types";
|
||||
export const useCreateAdminUser = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{ user: User; token: string }, {}, TCreateAdminUserDTO>({
|
||||
return useMutation<
|
||||
{ user: User; token: string; organization: { id: string } },
|
||||
{},
|
||||
TCreateAdminUserDTO
|
||||
>({
|
||||
mutationFn: async (opt) => {
|
||||
const { data } = await apiRequest.post("/api/v1/admin/signup", opt);
|
||||
return data;
|
||||
@@ -34,6 +39,7 @@ export const useUpdateServerConfig = () => {
|
||||
onSuccess: (data) => {
|
||||
queryClient.setQueryData(adminQueryKeys.serverConfig(), data);
|
||||
queryClient.invalidateQueries(adminQueryKeys.serverConfig());
|
||||
queryClient.invalidateQueries(organizationKeys.getUserOrganizations);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export type TServerConfig = {
|
||||
initialized: boolean;
|
||||
allowSignUp: boolean;
|
||||
allowedSignUpDomain?: string | null;
|
||||
isMigrationModeOn?: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ export * from "./integrations";
|
||||
export * from "./keys";
|
||||
export * from "./organization";
|
||||
export * from "./roles";
|
||||
export * from "./scim";
|
||||
export * from "./secretApproval";
|
||||
export * from "./secretApprovalRequest";
|
||||
export * from "./secretFolders";
|
||||
|
||||
@@ -61,6 +61,7 @@ export const useCreateIntegration = () => {
|
||||
metadata?: {
|
||||
secretPrefix?: string;
|
||||
secretSuffix?: string;
|
||||
syncBehavior?: string;
|
||||
}
|
||||
}) => {
|
||||
const { data: { integration } } = await apiRequest.post("/api/v1/integration", {
|
||||
|
||||
@@ -33,9 +33,22 @@ export type TIntegration = {
|
||||
__v: number;
|
||||
metadata?: {
|
||||
secretSuffix?: string;
|
||||
syncBehavior?: IntegrationSyncBehavior;
|
||||
scope: string;
|
||||
org: string;
|
||||
project: string;
|
||||
environment: string;
|
||||
};
|
||||
};
|
||||
|
||||
export enum IntegrationSyncBehavior {
|
||||
OVERWRITE_TARGET = "overwrite-target",
|
||||
PREFER_TARGET = "prefer-target",
|
||||
PREFER_SOURCE = "prefer-source"
|
||||
}
|
||||
|
||||
export const syncBehaviors = [
|
||||
{ label: "Overwrite target", value: IntegrationSyncBehavior.OVERWRITE_TARGET },
|
||||
{ label: "Prefer target", value: IntegrationSyncBehavior.PREFER_TARGET },
|
||||
{ label: "Prefer source", value: IntegrationSyncBehavior.PREFER_SOURCE }
|
||||
];
|
||||
@@ -8,9 +8,9 @@ const encKeyKeys = {
|
||||
getUserWorkspaceKey: (workspaceID: string) => ["workspace-key-pair", { workspaceID }] as const
|
||||
};
|
||||
|
||||
export const fetchUserWsKey = async (workspaceID: string) => {
|
||||
export const fetchUserWsKey = async (projectId: string) => {
|
||||
const { data } = await apiRequest.get<UserWsKeyPair>(
|
||||
`/api/v2/workspace/${workspaceID}/encrypted-key`
|
||||
`/api/v2/workspace/${projectId}/encrypted-key`
|
||||
);
|
||||
|
||||
return data;
|
||||
|
||||
@@ -71,12 +71,14 @@ export const useUpdateOrg = () => {
|
||||
mutationFn: ({
|
||||
name,
|
||||
authEnforced,
|
||||
scimEnabled,
|
||||
slug,
|
||||
orgId
|
||||
}) => {
|
||||
return apiRequest.patch(`/api/v1/organization/${orgId}`, {
|
||||
name,
|
||||
authEnforced,
|
||||
scimEnabled,
|
||||
slug
|
||||
});
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ export type Organization = {
|
||||
createAt: string;
|
||||
updatedAt: string;
|
||||
authEnforced: boolean;
|
||||
scimEnabled: boolean;
|
||||
slug: string;
|
||||
};
|
||||
|
||||
@@ -11,6 +12,7 @@ export type UpdateOrgDTO = {
|
||||
orgId: string;
|
||||
name?: string;
|
||||
authEnforced?: boolean;
|
||||
scimEnabled?: boolean;
|
||||
slug?: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export {
|
||||
useCreateScimToken,
|
||||
useDeleteScimToken
|
||||
} from "./mutations";
|
||||
export { useGetScimTokens } from "./queries";
|
||||
@@ -0,0 +1,45 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { scimKeys } from "./queries";
|
||||
import {
|
||||
CreateScimTokenDTO,
|
||||
CreateScimTokenRes,
|
||||
DeleteScimTokenDTO
|
||||
} from "./types";
|
||||
|
||||
export const useCreateScimToken = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<CreateScimTokenRes, {}, CreateScimTokenDTO>({
|
||||
mutationFn: async ({
|
||||
organizationId,
|
||||
description,
|
||||
ttlDays
|
||||
}) => {
|
||||
const { data } = await apiRequest.post("/api/v1/scim/scim-tokens", {
|
||||
organizationId,
|
||||
description,
|
||||
ttlDays
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { organizationId }) => {
|
||||
queryClient.invalidateQueries(scimKeys.getScimTokens(organizationId));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteScimToken = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<CreateScimTokenRes, {}, DeleteScimTokenDTO>({
|
||||
mutationFn: async ({ scimTokenId }) => {
|
||||
const { data } = await apiRequest.delete(`/api/v1/scim/scim-tokens/${scimTokenId}`);
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { organizationId }) => {
|
||||
queryClient.invalidateQueries(scimKeys.getScimTokens(organizationId));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { ScimTokenData } from "./types";
|
||||
|
||||
export const scimKeys = {
|
||||
getScimTokens: (orgId: string) => [{ orgId }, "organization-scim-token"] as const,
|
||||
};
|
||||
|
||||
export const useGetScimTokens = (organizationId: string) => {
|
||||
return useQuery({
|
||||
queryKey: scimKeys.getScimTokens(organizationId),
|
||||
queryFn: async () => {
|
||||
if (organizationId === "") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { data: { scimTokens } } = await apiRequest.get<{ scimTokens: ScimTokenData[] }>(`/api/v1/scim/scim-tokens?organizationId=${organizationId}`);
|
||||
|
||||
return scimTokens;
|
||||
},
|
||||
enabled: true
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
export type ScimTokenData = {
|
||||
id: string;
|
||||
ttlDays: number;
|
||||
description: string;
|
||||
tokenSuffix: string;
|
||||
orgId: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type CreateScimTokenDTO = {
|
||||
organizationId: string;
|
||||
description?: string;
|
||||
ttlDays?: number;
|
||||
}
|
||||
|
||||
export type DeleteScimTokenDTO = {
|
||||
organizationId: string;
|
||||
scimTokenId: string;
|
||||
}
|
||||
|
||||
export type CreateScimTokenRes = {
|
||||
scimToken: string;
|
||||
}
|
||||
@@ -2,7 +2,6 @@ export type ServerStatus = {
|
||||
date: string;
|
||||
message: string;
|
||||
emailConfigured: boolean;
|
||||
inviteOnlySignup: boolean;
|
||||
secretScanningConfigured: boolean
|
||||
redisConfigured: boolean
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
import { organizationKeys } from "@app/hooks/api/organization/queries";
|
||||
|
||||
const ssoConfigKeys = {
|
||||
getSSOConfig: (orgId: string) => [{ orgId }, "organization-saml-sso"] as const
|
||||
@@ -82,8 +83,12 @@ export const useUpdateSSOConfig = () => {
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess(_, dto) {
|
||||
queryClient.invalidateQueries(ssoConfigKeys.getSSOConfig(dto.organizationId));
|
||||
onSuccess(_, { organizationId, isActive }) {
|
||||
if (isActive === false) {
|
||||
queryClient.invalidateQueries(organizationKeys.getUserOrganizations);
|
||||
}
|
||||
|
||||
queryClient.invalidateQueries(ssoConfigKeys.getSSOConfig(organizationId));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ export type SubscriptionPlan = {
|
||||
workspacesUsed: number;
|
||||
environmentLimit: number;
|
||||
samlSSO: boolean;
|
||||
scim: boolean;
|
||||
status:
|
||||
| "incomplete"
|
||||
| "incomplete_expired"
|
||||
|
||||
@@ -22,7 +22,7 @@ export * from "./secrets/types";
|
||||
export type { CreateServiceTokenDTO, ServiceToken } from "./serviceTokens/types";
|
||||
export type { SubscriptionPlan } from "./subscriptions/types";
|
||||
export type { WsTag } from "./tags/types";
|
||||
export type { AddUserToWsDTO, OrgUser, TWorkspaceUser, User, UserEnc } from "./users/types";
|
||||
export type { AddUserToWsDTOE2EE, OrgUser, TWorkspaceUser, User, UserEnc } from "./users/types";
|
||||
export type { TWebhook } from "./webhooks/types";
|
||||
export type {
|
||||
CreateEnvironmentDTO,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { useAddUserToWs } from "./mutation";
|
||||
export { useAddUserToWsE2EE, useAddUserToWsNonE2EE } from "./mutation";
|
||||
export {
|
||||
fetchOrgUsers,
|
||||
useAddUserToOrg,
|
||||
|
||||
@@ -7,12 +7,12 @@ import {
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { workspaceKeys } from "../workspace/queries";
|
||||
import { AddUserToWsDTO } from "./types";
|
||||
import { AddUserToWsDTOE2EE, AddUserToWsDTONonE2EE } from "./types";
|
||||
|
||||
export const useAddUserToWs = () => {
|
||||
export const useAddUserToWsE2EE = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{}, {}, AddUserToWsDTO>({
|
||||
return useMutation<{}, {}, AddUserToWsDTOE2EE>({
|
||||
mutationFn: async ({ workspaceId, members, decryptKey, userPrivateKey }) => {
|
||||
// assymmetrically decrypt symmetric key with local private key
|
||||
const key = decryptAssymmetric({
|
||||
@@ -45,3 +45,19 @@ export const useAddUserToWs = () => {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useAddUserToWsNonE2EE = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{}, {}, AddUserToWsDTONonE2EE>({
|
||||
mutationFn: async ({ projectId, emails }) => {
|
||||
const { data } = await apiRequest.post(`/api/v2/workspace/${projectId}/memberships`, {
|
||||
emails
|
||||
});
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { projectId }) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getWorkspaceUsers(projectId));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -63,7 +63,7 @@ export type TProjectMembership = {
|
||||
|
||||
export type TWorkspaceUser = OrgUser;
|
||||
|
||||
export type AddUserToWsDTO = {
|
||||
export type AddUserToWsDTOE2EE = {
|
||||
workspaceId: string;
|
||||
decryptKey: UserWsKeyPair;
|
||||
userPrivateKey: string;
|
||||
@@ -73,6 +73,11 @@ export type AddUserToWsDTO = {
|
||||
}[];
|
||||
};
|
||||
|
||||
export type AddUserToWsDTONonE2EE = {
|
||||
projectId: string;
|
||||
emails: string[];
|
||||
};
|
||||
|
||||
export type UpdateOrgUserRoleDTO = {
|
||||
organizationId: string;
|
||||
membershipId: string;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
export {
|
||||
useAddIdentityToWorkspace,
|
||||
useAddUserToWorkspace,
|
||||
useCreateWorkspace,
|
||||
useCreateWsEnvironment,
|
||||
useDeleteIdentityFromWorkspace,
|
||||
useDeleteUserFromWorkspace,
|
||||
useDeleteWorkspace,
|
||||
useDeleteWsEnvironment,
|
||||
useGetUpgradeProjectStatus,
|
||||
useGetUserWorkspaceMemberships,
|
||||
useGetUserWorkspaces,
|
||||
useGetWorkspaceAuthorizations,
|
||||
@@ -21,5 +21,6 @@ export {
|
||||
useToggleAutoCapitalization,
|
||||
useUpdateIdentityWorkspaceRole,
|
||||
useUpdateUserWorkspaceRole,
|
||||
useUpdateWsEnvironment
|
||||
useUpdateWsEnvironment,
|
||||
useUpgradeProject
|
||||
} from "./queries";
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
DeleteWorkspaceDTO,
|
||||
NameWorkspaceSecretsDTO,
|
||||
RenameWorkspaceDTO,
|
||||
TGetUpgradeProjectStatusDTO,
|
||||
ToggleAutoCapitalizationDTO,
|
||||
UpdateEnvironmentDTO,
|
||||
Workspace
|
||||
@@ -24,6 +25,7 @@ export const workspaceKeys = {
|
||||
getWorkspaceSecrets: (workspaceId: string) => [{ workspaceId }, "workspace-secrets"] as const,
|
||||
getWorkspaceIndexStatus: (workspaceId: string) =>
|
||||
[{ workspaceId }, "workspace-index-status"] as const,
|
||||
getProjectUpgradeStatus: (workspaceId: string) => [{ workspaceId }, "workspace-upgrade-status"],
|
||||
getWorkspaceMemberships: (orgId: string) => [{ orgId }, "workspace-memberships"],
|
||||
getWorkspaceAuthorization: (workspaceId: string) => [{ workspaceId }, "workspace-authorizations"],
|
||||
getWorkspaceIntegrations: (workspaceId: string) => [{ workspaceId }, "workspace-integrations"],
|
||||
@@ -51,6 +53,14 @@ const fetchWorkspaceIndexStatus = async (workspaceId: string) => {
|
||||
return data;
|
||||
};
|
||||
|
||||
const fetchProjectUpgradeStatus = async (projectId: string) => {
|
||||
const { data } = await apiRequest.get<{ status: string }>(
|
||||
`/api/v2/workspace/${projectId}/upgrade/status`
|
||||
);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchWorkspaceSecrets = async (workspaceId: string) => {
|
||||
const {
|
||||
data: { secrets }
|
||||
@@ -61,6 +71,36 @@ export const fetchWorkspaceSecrets = async (workspaceId: string) => {
|
||||
return secrets;
|
||||
};
|
||||
|
||||
export const useUpgradeProject = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{}, {}, { projectId: string; privateKey: string }>({
|
||||
mutationFn: ({ projectId, privateKey }) => {
|
||||
return apiRequest.post(`/api/v2/workspace/${projectId}/upgrade`, {
|
||||
userPrivateKey: privateKey
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetUpgradeProjectStatus = ({
|
||||
projectId,
|
||||
onSuccess,
|
||||
enabled,
|
||||
refetchInterval
|
||||
}: TGetUpgradeProjectStatusDTO) => {
|
||||
return useQuery({
|
||||
queryKey: workspaceKeys.getProjectUpgradeStatus(projectId),
|
||||
queryFn: () => fetchProjectUpgradeStatus(projectId),
|
||||
enabled,
|
||||
onSuccess,
|
||||
refetchInterval
|
||||
});
|
||||
};
|
||||
|
||||
const fetchUserWorkspaces = async () => {
|
||||
const { data } = await apiRequest.get<{ workspaces: Workspace[] }>("/api/v1/workspace");
|
||||
return data.workspaces;
|
||||
@@ -158,19 +198,19 @@ export const useGetWorkspaceIntegrations = (workspaceId: string) =>
|
||||
|
||||
export const createWorkspace = ({
|
||||
organizationId,
|
||||
workspaceName
|
||||
}: CreateWorkspaceDTO): Promise<{ data: { workspace: Workspace } }> => {
|
||||
return apiRequest.post("/api/v1/workspace", { workspaceName, organizationId });
|
||||
projectName
|
||||
}: CreateWorkspaceDTO): Promise<{ data: { project: Workspace } }> => {
|
||||
return apiRequest.post("/api/v2/workspace", { projectName, organizationId });
|
||||
};
|
||||
|
||||
export const useCreateWorkspace = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{ data: { workspace: Workspace } }, {}, CreateWorkspaceDTO>({
|
||||
mutationFn: async ({ organizationId, workspaceName }) =>
|
||||
return useMutation<{ data: { project: Workspace } }, {}, CreateWorkspaceDTO>({
|
||||
mutationFn: async ({ organizationId, projectName }) =>
|
||||
createWorkspace({
|
||||
organizationId,
|
||||
workspaceName
|
||||
projectName
|
||||
}),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
|
||||
@@ -279,40 +319,16 @@ export const useGetWorkspaceUsers = (workspaceId: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useAddUserToWorkspace = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ email, workspaceId }: { email: string; workspaceId: string }) => {
|
||||
const {
|
||||
data: { invitee, latestKey }
|
||||
} = await apiRequest.post(`/api/v1/workspace/${workspaceId}/invite-signup`, { email });
|
||||
|
||||
return {
|
||||
invitee,
|
||||
latestKey
|
||||
};
|
||||
},
|
||||
onSuccess: (_, dto) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getWorkspaceUsers(dto.workspaceId));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteUserFromWorkspace = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({
|
||||
membershipId,
|
||||
workspaceId
|
||||
}: {
|
||||
workspaceId: string;
|
||||
membershipId: string;
|
||||
}) => {
|
||||
mutationFn: async ({ emails, workspaceId }: { workspaceId: string; emails: string[] }) => {
|
||||
const {
|
||||
data: { deletedMembership }
|
||||
} = await apiRequest.delete(`/api/v1/workspace/${workspaceId}/memberships/${membershipId}`);
|
||||
} = await apiRequest.delete(`/api/v2/workspace/${workspaceId}/memberships`, {
|
||||
data: { emails }
|
||||
});
|
||||
return deletedMembership;
|
||||
},
|
||||
onSuccess: (_, { workspaceId }) => {
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
export enum ProjectVersion {
|
||||
V1 = 1,
|
||||
V2 = 2
|
||||
}
|
||||
|
||||
export type Workspace = {
|
||||
__v: number;
|
||||
id: string;
|
||||
name: string;
|
||||
orgId: string;
|
||||
version: ProjectVersion;
|
||||
upgradeStatus: string | null;
|
||||
autoCapitalization: boolean;
|
||||
environments: WorkspaceEnv[];
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type WorkspaceEnv = {
|
||||
@@ -23,9 +31,16 @@ export type NameWorkspaceSecretsDTO = {
|
||||
}[];
|
||||
};
|
||||
|
||||
export type TGetUpgradeProjectStatusDTO = {
|
||||
projectId: string;
|
||||
onSuccess?: (data?: { status: string }) => void;
|
||||
enabled?: boolean;
|
||||
refetchInterval?: number;
|
||||
};
|
||||
|
||||
// mutation dto
|
||||
export type CreateWorkspaceDTO = {
|
||||
workspaceName: string;
|
||||
projectName: string;
|
||||
organizationId: string;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user