Wired most of the frontend to support ghost users

This commit is contained in:
Daniel Hougaard
2024-02-06 03:17:33 +04:00
parent fe21ba0e54
commit ccc409e9cd
9 changed files with 80 additions and 52 deletions

View File

@@ -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,

View File

@@ -1,4 +1,4 @@
export { useAddUserToWs } from "./mutation";
export { useAddUserToWsE2EE, useAddUserToWsNonE2EE } from "./mutation";
export {
fetchOrgUsers,
useAddUserToOrg,

View File

@@ -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/v3/projects/${projectId}/memberships`, {
emails
});
return data;
},
onSuccess: (_, { projectId }) => {
queryClient.invalidateQueries(workspaceKeys.getWorkspaceUsers(projectId));
}
});
};

View File

@@ -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;

View File

@@ -158,21 +158,19 @@ export const useGetWorkspaceIntegrations = (workspaceId: string) =>
export const createWorkspace = ({
organizationId,
projectName,
inviteAllOrgMembers
}: CreateWorkspaceDTO): Promise<{ data: { workspace: Workspace } }> => {
return apiRequest.post("/api/v3/projects", { projectName, inviteAllOrgMembers, organizationId });
projectName
}: CreateWorkspaceDTO): Promise<{ data: { project: Workspace } }> => {
return apiRequest.post("/api/v3/projects", { projectName, organizationId });
};
export const useCreateWorkspace = () => {
const queryClient = useQueryClient();
return useMutation<{ data: { workspace: Workspace } }, {}, CreateWorkspaceDTO>({
mutationFn: async ({ organizationId, projectName, inviteAllOrgMembers }) =>
return useMutation<{ data: { project: Workspace } }, {}, CreateWorkspaceDTO>({
mutationFn: async ({ organizationId, projectName }) =>
createWorkspace({
organizationId,
projectName,
inviteAllOrgMembers
projectName
}),
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
@@ -287,11 +285,13 @@ export const useAddUserToWorkspace = () => {
return useMutation({
mutationFn: async ({ email, workspaceId }: { email: string; workspaceId: string }) => {
const {
data: { invitee, latestKey }
} = await apiRequest.post(`/api/v1/workspace/${workspaceId}/invite-signup`, { email });
data: { invitees, latestKey }
} = await apiRequest.post(`/api/v1/workspace/${workspaceId}/invite-signup`, {
emails: [email]
});
return {
invitee,
invitees,
latestKey
};
},

View File

@@ -3,6 +3,7 @@ export type Workspace = {
id: string;
name: string;
orgId: string;
e2ee: boolean;
autoCapitalization: boolean;
environments: WorkspaceEnv[];
};
@@ -26,7 +27,6 @@ export type NameWorkspaceSecretsDTO = {
// mutation dto
export type CreateWorkspaceDTO = {
projectName: string;
inviteAllOrgMembers: boolean;
organizationId: string;
};

View File

@@ -62,7 +62,7 @@ import {
import { usePopUp } from "@app/hooks";
import {
fetchOrgUsers,
useAddUserToWs,
useAddUserToWsE2EE,
useCreateWorkspace,
useGetOrgTrialUrl,
useGetSecretApprovalRequestCount,
@@ -130,7 +130,7 @@ export const AppLayout = ({ children }: LayoutProps) => {
const createWs = useCreateWorkspace();
const uploadWsKey = useUploadWsKey();
const addWsUser = useAddUserToWs();
const addWsUser = useAddUserToWsE2EE();
const infisicalPlatformVersion = process.env.NEXT_PUBLIC_INFISICAL_PLATFORM_VERSION;
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
@@ -224,11 +224,11 @@ export const AppLayout = ({ children }: LayoutProps) => {
try {
const {
data: {
workspace: { id: newWorkspaceId }
project: { id: newWorkspaceId }
}
} = await createWs.mutateAsync({
organizationId: currentOrg?.id,
workspaceName: name
projectName: name
});
const randomBytes = crypto.randomBytes(16).toString("hex");

View File

@@ -53,7 +53,7 @@ import {
// fetchOrgUsers,
// useAddUserToWs,
useCreateWorkspace,
useRegisterUserAction,
useRegisterUserAction
} from "@app/hooks/api";
// import { fetchUserWsKey } from "@app/hooks/api/keys/queries";
import { useFetchServerStatus } from "@app/hooks/api/serverDetails";
@@ -471,7 +471,7 @@ const OrganizationPage = withPermission(
const currentOrg = String(router.query.id);
const orgWorkspaces = workspaces?.filter((workspace) => workspace.orgId === currentOrg) || [];
const { createNotification } = useNotificationContext();
// const addWsUser = useAddUserToWs();
// const addWsUser = useAddUserToWs();
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
"addNewWs",
@@ -501,35 +501,32 @@ const OrganizationPage = withPermission(
try {
const {
data: {
workspace: { id: newWorkspaceId }
project: { id: newWorkspaceId }
}
} = await createWs.mutateAsync({
organizationId: currentOrg,
inviteAllOrgMembers: addMembers,
projectName: name
});
/*
if (addMembers) {
// not using hooks because need at this point only
const orgUsers = await fetchOrgUsers(currentOrg);
const decryptKey = await fetchUserWsKey(newWorkspaceId);
await addWsUser.mutateAsync({
workspaceId: newWorkspaceId,
decryptKey,
userPrivateKey: PRIVATE_KEY,
members: orgUsers
.filter(
({ status, user: orgUser }) => status === "accepted" && user.email !== orgUser.email
)
.map(({ user: orgUser, id: orgMembershipId }) => ({
userPublicKey: orgUser.publicKey,
orgMembershipId
}))
});
// const orgUsers = await fetchOrgUsers(currentOrg);
// const decryptKey = await fetchUserWsKey(newWorkspaceId);
// await addWsUser.mutateAsync({
// workspaceId: newWorkspaceId,
// decryptKey,
// userPrivateKey: PRIVATE_KEY,
// members: orgUsers
// .filter(
// ({ status, user: orgUser }) => status === "accepted" && user.email !== orgUser.email
// )
// .map(({ user: orgUser, id: orgMembershipId }) => ({
// userPublicKey: orgUser.publicKey,
// orgMembershipId
// }))
// });
}
*/
createNotification({ text: "Workspace created", type: "success" });
handlePopUpClose("addNewWs");
router.push(`/project/${newWorkspaceId}/secrets/overview`);

View File

@@ -44,7 +44,8 @@ import {
} from "@app/context";
import { usePopUp } from "@app/hooks";
import {
useAddUserToWs,
useAddUserToWsE2EE,
useAddUserToWsNonE2EE,
useDeleteUserFromWorkspace,
useGetOrgUsers,
useGetProjectRoles,
@@ -95,12 +96,14 @@ export const MemberListTab = () => {
formState: { isSubmitting }
} = useForm<TAddMemberForm>({ resolver: zodResolver(addMemberFormSchema) });
const { mutateAsync: addUserToWorkspace } = useAddUserToWs();
const { mutateAsync: addUserToWorkspace } = useAddUserToWsE2EE();
const { mutateAsync: addUserToWorkspaceNonE2EE } = useAddUserToWsNonE2EE();
const { mutateAsync: uploadWsKey } = useUploadWsKey();
const { mutateAsync: removeUserFromWorkspace } = useDeleteUserFromWorkspace();
const { mutateAsync: updateUserWorkspaceRole } = useUpdateUserWorkspaceRole();
const onAddMember = async ({ orgMembershipId }: TAddMemberForm) => {
if (!currentWorkspace) return;
if (!currentOrg?.id) return;
// TODO(akhilmhdh): Move to memory storage
const userPrivateKey = localStorage.getItem("PRIVATE_KEY");
@@ -114,12 +117,19 @@ export const MemberListTab = () => {
if (!orgUser) return;
try {
await addUserToWorkspace({
workspaceId,
userPrivateKey,
decryptKey: wsKey,
members: [{ orgMembershipId, userPublicKey: orgUser.user.publicKey }]
});
if (currentWorkspace.e2ee) {
await addUserToWorkspace({
workspaceId,
userPrivateKey,
decryptKey: wsKey,
members: [{ orgMembershipId, userPublicKey: orgUser.user.publicKey }]
});
} else {
await addUserToWorkspaceNonE2EE({
projectId: workspaceId,
emails: [orgUser.user.email]
});
}
createNotification({
text: "Successfully added user to the project",
type: "success"