From 2e3dcc50ae77a2e88b3b91c3041f20f560d6555d Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Fri, 6 Sep 2024 10:35:35 +0400 Subject: [PATCH 01/13] API doc --- backend/src/lib/api-docs/constants.ts | 4 +++- backend/src/server/routes/v2/project-membership-router.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index b08c70d93..7d998f8ea 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -447,7 +447,9 @@ export const PROJECT_USERS = { INVITE_MEMBER: { projectId: "The ID of the project to invite the member to.", emails: "A list of organization member emails to invite to the project.", - usernames: "A list of usernames to invite to the project." + usernames: "A list of usernames to invite to the project.", + roleSlugs: + "A list of role slugs to assign to the newly created project membership. If nothing is provided, it will default to the Member role." }, REMOVE_MEMBER: { projectId: "The ID of the project to remove the member from.", diff --git a/backend/src/server/routes/v2/project-membership-router.ts b/backend/src/server/routes/v2/project-membership-router.ts index 6ab574d64..4aa03f33c 100644 --- a/backend/src/server/routes/v2/project-membership-router.ts +++ b/backend/src/server/routes/v2/project-membership-router.ts @@ -26,7 +26,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider }), body: z.object({ emails: z.string().email().array().default([]).describe(PROJECT_USERS.INVITE_MEMBER.emails), - usernames: z.string().array().default([]).describe(PROJECT_USERS.INVITE_MEMBER.usernames) + usernames: z.string().array().default([]).describe(PROJECT_USERS.INVITE_MEMBER.usernames), + roleSlugs: z.string().array().optional().describe(PROJECT_USERS.INVITE_MEMBER.roleSlugs) }), response: { 200: z.object({ From ceab951bcad5bbda59d797a186517e44b3cd8e64 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Fri, 6 Sep 2024 10:39:27 +0400 Subject: [PATCH 02/13] feat: remove project role from workspace user encryption computation --- backend/src/services/project/project-fns.ts | 3 +-- backend/src/services/project/project-queue.ts | 3 +-- backend/src/services/project/project-service.ts | 5 ++--- backend/src/services/project/project-types.ts | 3 +-- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/backend/src/services/project/project-fns.ts b/backend/src/services/project/project-fns.ts index cb836d932..d6b01c33b 100644 --- a/backend/src/services/project/project-fns.ts +++ b/backend/src/services/project/project-fns.ts @@ -16,7 +16,7 @@ export const assignWorkspaceKeysToMembers = ({ members, decryptKey, userPrivateK privateKey: userPrivateKey }); - const newWsMembers = members.map(({ orgMembershipId, userPublicKey, projectMembershipRole }) => { + const newWsMembers = members.map(({ orgMembershipId, userPublicKey }) => { const { ciphertext: inviteeCipherText, nonce: inviteeNonce } = encryptAsymmetric( plaintextProjectKey, userPublicKey, @@ -25,7 +25,6 @@ export const assignWorkspaceKeysToMembers = ({ members, decryptKey, userPrivateK return { orgMembershipId, - projectRole: projectMembershipRole, workspaceEncryptedKey: inviteeCipherText, workspaceEncryptedNonce: inviteeNonce }; diff --git a/backend/src/services/project/project-queue.ts b/backend/src/services/project/project-queue.ts index 8f1e3fc3f..d59bde6c1 100644 --- a/backend/src/services/project/project-queue.ts +++ b/backend/src/services/project/project-queue.ts @@ -300,8 +300,7 @@ export const projectQueueFactory = ({ members: [ { userPublicKey: user.publicKey, - orgMembershipId: orgMembership.id, - projectMembershipRole: ProjectMembershipRole.Admin + orgMembershipId: orgMembership.id } ] }); diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts index f51c561d7..31ab297b8 100644 --- a/backend/src/services/project/project-service.ts +++ b/backend/src/services/project/project-service.ts @@ -277,8 +277,7 @@ export const projectServiceFactory = ({ members: [ { userPublicKey: user.publicKey, - orgMembershipId: orgMembership.id, - projectMembershipRole: ProjectMembershipRole.Admin + orgMembershipId: orgMembership.id } ] }); @@ -292,7 +291,7 @@ export const projectServiceFactory = ({ tx ); await projectUserMembershipRoleDAL.create( - { projectMembershipId: userProjectMembership.id, role: projectAdmin.projectRole }, + { projectMembershipId: userProjectMembership.id, role: ProjectMembershipRole.Admin }, tx ); diff --git a/backend/src/services/project/project-types.ts b/backend/src/services/project/project-types.ts index fbbd32d2b..3bfdae709 100644 --- a/backend/src/services/project/project-types.ts +++ b/backend/src/services/project/project-types.ts @@ -1,4 +1,4 @@ -import { ProjectMembershipRole, TProjectKeys } from "@app/db/schemas"; +import { TProjectKeys } from "@app/db/schemas"; import { TProjectPermission } from "@app/lib/types"; import { ActorAuthMethod, ActorType } from "../auth/auth-type"; @@ -88,7 +88,6 @@ export type AddUserToWsDTO = { userPrivateKey: string; members: { orgMembershipId: string; - projectMembershipRole: ProjectMembershipRole; userPublicKey: string; }[]; }; From 1581aa088d6351bea991cd185fbe71e00eb8b727 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Fri, 6 Sep 2024 10:39:41 +0400 Subject: [PATCH 03/13] Update org-admin-service.ts --- backend/src/services/org-admin/org-admin-service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/services/org-admin/org-admin-service.ts b/backend/src/services/org-admin/org-admin-service.ts index 4759db309..4ee192c88 100644 --- a/backend/src/services/org-admin/org-admin-service.ts +++ b/backend/src/services/org-admin/org-admin-service.ts @@ -153,7 +153,6 @@ export const orgAdminServiceFactory = ({ members: [ { orgMembershipId: membership.id, - projectMembershipRole: ProjectMembershipRole.Admin, userPublicKey: userEncryptionKey.publicKey } ] From 93ba29e57fc7b285d9cdf3a81d3583bc302aee65 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Fri, 6 Sep 2024 10:40:23 +0400 Subject: [PATCH 04/13] Feat: Invite multiple users to project with multiple roles --- .../project-membership-fns.ts | 44 +++- .../project-membership-service.ts | 2 +- .../project-membership-types.ts | 1 + frontend/src/hooks/api/users/mutation.tsx | 5 +- frontend/src/hooks/api/users/types.ts | 1 + .../MembersTab/components/AddMemberModal.tsx | 247 +++++++++++++++--- 6 files changed, 252 insertions(+), 48 deletions(-) diff --git a/backend/src/services/project-membership/project-membership-fns.ts b/backend/src/services/project-membership/project-membership-fns.ts index 98acd6eec..baa62628c 100644 --- a/backend/src/services/project-membership/project-membership-fns.ts +++ b/backend/src/services/project-membership/project-membership-fns.ts @@ -12,6 +12,8 @@ import { TProjectDALFactory } from "../project/project-dal"; import { assignWorkspaceKeysToMembers } from "../project/project-fns"; import { TProjectBotDALFactory } from "../project-bot/project-bot-dal"; import { TProjectKeyDALFactory } from "../project-key/project-key-dal"; +import { TProjectRoleDALFactory } from "../project-role/project-role-dal"; +import { getPredefinedRoles } from "../project-role/project-role-fns"; import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service"; import { TProjectMembershipDALFactory } from "./project-membership-dal"; import { TProjectUserMembershipRoleDALFactory } from "./project-user-membership-role-dal"; @@ -24,6 +26,7 @@ type TAddMembersToProjectArg = { projectBotDAL: Pick; userGroupMembershipDAL: Pick; projectUserMembershipRoleDAL: Pick; + projectRoleDAL: Pick; smtpService: Pick; }; @@ -31,7 +34,7 @@ type AddMembersToNonE2EEProjectDTO = { emails: string[]; usernames: string[]; projectId: string; - projectMembershipRole: ProjectMembershipRole; + projectMembershipRoles: string[]; sendEmails?: boolean; }; @@ -48,11 +51,12 @@ export const addMembersToProject = ({ projectBotDAL, userGroupMembershipDAL, projectUserMembershipRoleDAL, + projectRoleDAL, smtpService }: TAddMembersToProjectArg) => { // Can create multiple memberships for a singular project, based on user email / username const addMembersToNonE2EEProject = async ( - { emails, usernames, projectId, projectMembershipRole, sendEmails }: AddMembersToNonE2EEProjectDTO, + { emails, usernames, projectId, projectMembershipRoles, sendEmails }: AddMembersToNonE2EEProjectDTO, options: AddMembersToNonE2EEProjectOptions = { throwOnProjectNotFound: true } ) => { const processTransaction = async (tx: Knex) => { @@ -119,7 +123,6 @@ export const addMembersToProject = ({ userPrivateKey: botPrivateKey, members: orgMembers.map((membership) => ({ orgMembershipId: membership.id, - projectMembershipRole, userPublicKey: membership.user.publicKey })) }); @@ -136,10 +139,37 @@ export const addMembersToProject = ({ })), tx ); - await projectUserMembershipRoleDAL.insertMany( - projectMemberships.map(({ id }) => ({ projectMembershipId: id, role: projectMembershipRole })), - tx - ); + + const defaultRoles = getPredefinedRoles(projectId).map((i) => i.slug) as string[]; + for await (const projectMembershipRole of projectMembershipRoles) { + // Custom role + if (!defaultRoles.includes(projectMembershipRole)) { + const role = await projectRoleDAL.findOne({ + projectId, + slug: projectMembershipRole + }); + + if (!role) { + throw new BadRequestError({ message: `Custom role "${projectMembershipRole}" not found` }); + } + + await projectUserMembershipRoleDAL.insertMany( + projectMemberships.map(({ id }) => ({ + projectMembershipId: id, + role: ProjectMembershipRole.Custom, + customRoleId: role.id + })), + tx + ); + } + // Predefined role + else { + await projectUserMembershipRoleDAL.insertMany( + projectMemberships.map(({ id }) => ({ projectMembershipId: id, role: projectMembershipRole })), + tx + ); + } + } members.push(...projectMemberships); diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index 49a86f31b..e2ed4647d 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -42,7 +42,7 @@ type TProjectMembershipServiceFactoryDep = { projectUserMembershipRoleDAL: Pick; userDAL: Pick; userGroupMembershipDAL: TUserGroupMembershipDALFactory; - projectRoleDAL: Pick; + projectRoleDAL: Pick; orgDAL: Pick; projectDAL: Pick; projectKeyDAL: Pick; diff --git a/backend/src/services/project-membership/project-membership-types.ts b/backend/src/services/project-membership/project-membership-types.ts index 21efaf691..c50ee4c1b 100644 --- a/backend/src/services/project-membership/project-membership-types.ts +++ b/backend/src/services/project-membership/project-membership-types.ts @@ -53,4 +53,5 @@ export type TAddUsersToWorkspaceNonE2EEDTO = { sendEmails?: boolean; emails: string[]; usernames: string[]; + roleSlugs?: string[]; } & TProjectPermission; diff --git a/frontend/src/hooks/api/users/mutation.tsx b/frontend/src/hooks/api/users/mutation.tsx index eb9bb8007..9ee16415d 100644 --- a/frontend/src/hooks/api/users/mutation.tsx +++ b/frontend/src/hooks/api/users/mutation.tsx @@ -51,9 +51,10 @@ export const useAddUserToWsNonE2EE = () => { const queryClient = useQueryClient(); return useMutation<{}, {}, AddUserToWsDTONonE2EE>({ - mutationFn: async ({ projectId, usernames }) => { + mutationFn: async ({ projectId, usernames, roleSlugs }) => { const { data } = await apiRequest.post(`/api/v2/workspace/${projectId}/memberships`, { - usernames + usernames, + roleSlugs }); return data; }, diff --git a/frontend/src/hooks/api/users/types.ts b/frontend/src/hooks/api/users/types.ts index 6c538811b..048dd3d63 100644 --- a/frontend/src/hooks/api/users/types.ts +++ b/frontend/src/hooks/api/users/types.ts @@ -133,6 +133,7 @@ export type AddUserToWsDTOE2EE = { export type AddUserToWsDTONonE2EE = { projectId: string; usernames: string[]; + roleSlugs?: string[]; orgId: string; }; diff --git a/frontend/src/views/Project/MembersPage/components/MembersTab/components/AddMemberModal.tsx b/frontend/src/views/Project/MembersPage/components/MembersTab/components/AddMemberModal.tsx index 6db92861e..fbf174756 100644 --- a/frontend/src/views/Project/MembersPage/components/MembersTab/components/AddMemberModal.tsx +++ b/frontend/src/views/Project/MembersPage/components/MembersTab/components/AddMemberModal.tsx @@ -2,24 +2,38 @@ import { useMemo } from "react"; import { Controller, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import Link from "next/link"; +import { faCheckCircle, faChevronDown } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; +import { twMerge } from "tailwind-merge"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, Modal, ModalContent, Select, SelectItem } from "@app/components/v2"; +import { + Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + FormControl, + Modal, + ModalContent +} from "@app/components/v2"; import { useOrganization, useWorkspace } from "@app/context"; import { - useAddUserToWsE2EE, useAddUserToWsNonE2EE, useGetOrgUsers, + useGetProjectRoles, useGetUserWsKey, useGetWorkspaceUsers } from "@app/hooks/api"; +import { ProjectMembershipRole } from "@app/hooks/api/roles/types"; import { ProjectVersion } from "@app/hooks/api/workspace/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; const addMemberFormSchema = z.object({ - orgMembershipId: z.string().trim() + orgMembershipIds: z.array(z.string().trim()).min(1), + projectRoleSlugs: z.array(z.string().trim().min(1)).min(1) }); type TAddMemberForm = z.infer; @@ -41,17 +55,22 @@ export const AddMemberModal = ({ popUp, handlePopUpToggle }: Props) => { const { data: members } = useGetWorkspaceUsers(workspaceId); const { data: orgUsers } = useGetOrgUsers(orgId); - const { mutateAsync: addUserToWorkspace } = useAddUserToWsE2EE(); const { mutateAsync: addUserToWorkspaceNonE2EE } = useAddUserToWsNonE2EE(); + const { data: roles } = useGetProjectRoles(currentWorkspace?.slug || ""); + const { control, handleSubmit, reset, + watch, formState: { isSubmitting } - } = useForm({ resolver: zodResolver(addMemberFormSchema) }); + } = useForm({ + resolver: zodResolver(addMemberFormSchema), + defaultValues: { orgMembershipIds: [], projectRoleSlugs: [ProjectMembershipRole.Member] } + }); - const onAddMember = async ({ orgMembershipId }: TAddMemberForm) => { + const onAddMember = async ({ orgMembershipIds, projectRoleSlugs }: TAddMemberForm) => { if (!currentWorkspace) return; if (!currentOrg?.id) return; // TODO(akhilmhdh): Move to memory storage @@ -62,22 +81,23 @@ export const AddMemberModal = ({ popUp, handlePopUpToggle }: Props) => { }); return; } - const orgUser = (orgUsers || []).find(({ id }) => id === orgMembershipId); - if (!orgUser) return; + const selectedMembers = orgMembershipIds.map((orgMembershipId) => + orgUsers?.find((orgUser) => orgUser.id === orgMembershipId) + ); + + if (!selectedMembers) return; try { - // TODO: update if (currentWorkspace.version === ProjectVersion.V1) { - await addUserToWorkspace({ - workspaceId, - userPrivateKey, - decryptKey: wsKey, - members: [{ orgMembershipId, userPublicKey: orgUser.user.publicKey }] + createNotification({ + type: "error", + text: "Please upgrade your project to invite new members to the project." }); } else { await addUserToWorkspaceNonE2EE({ projectId: workspaceId, - usernames: [orgUser.user.username], + usernames: [...selectedMembers.map((member) => member?.user.username!)], + roleSlugs: projectRoleSlugs, orgId }); } @@ -104,6 +124,11 @@ export const AddMemberModal = ({ popUp, handlePopUpToggle }: Props) => { return (orgUsers || []).filter(({ user: u }) => !wsUserUsernames.has(u.username)); }, [orgUsers, members]); + const selectedOrgMembershipIds = watch("orgMembershipIds"); + const selectedRoleSlugs = watch("projectRoleSlugs"); + + console.log(selectedOrgMembershipIds); + return ( { > {filteredOrgUsers.length ? (
- ( - - - - )} - /> +
+
+ ( + + + + {filteredOrgUsers && filteredOrgUsers.length > 0 ? ( +
+ {/* eslint-disable-next-line no-nested-ternary */} + {selectedOrgMembershipIds.length === 1 + ? filteredOrgUsers.find( + (orgUser) => orgUser.id === selectedOrgMembershipIds[0] + )?.user.username + : selectedOrgMembershipIds.length === 0 + ? "No users selected" + : `${selectedOrgMembershipIds.length} users selected`} + +
+ ) : ( +
+ No users found +
+ )} +
+ + {filteredOrgUsers && filteredOrgUsers.length > 0 ? ( + filteredOrgUsers.map((member) => { + const isSelected = selectedOrgMembershipIds.includes(member.id); + + return ( + + filteredOrgUsers.length > 1 && event.preventDefault() + } + onClick={() => { + if (selectedOrgMembershipIds.includes(String(member.id))) { + field.onChange( + selectedOrgMembershipIds.filter( + (membershipId: string) => + membershipId !== String(member.id) + ) + ); + } else { + field.onChange([ + ...selectedOrgMembershipIds, + String(member.id) + ]); + } + }} + key={`membership-id-${member.id}`} + icon={ + isSelected ? ( + + ) : ( +
+ ) + } + iconPos="left" + className="w-[28.4rem] text-sm" + > + {member.user.username} + + ); + }) + ) : ( +
+ )} + + + + )} + /> +
+ +
+ ( + + + + {roles && roles.length > 0 ? ( +
+ {/* eslint-disable-next-line no-nested-ternary */} + {selectedRoleSlugs.length === 1 + ? roles.find((role) => role.slug === selectedRoleSlugs[0])?.name + : selectedRoleSlugs.length === 0 + ? "Select at least one role" + : `${selectedRoleSlugs.length} roles selected`} + +
+ ) : ( +
+ No roles found +
+ )} +
+ + {roles && roles.length > 0 ? ( + roles.map((role) => { + const isSelected = selectedRoleSlugs.includes(role.slug); + + return ( + roles.length > 1 && event.preventDefault()} + onClick={() => { + if (selectedRoleSlugs.includes(String(role.slug))) { + field.onChange( + selectedRoleSlugs.filter( + (roleSlug: string) => roleSlug !== String(role.slug) + ) + ); + } else { + field.onChange([...selectedRoleSlugs, role.slug]); + } + }} + key={`role-slug-${role.slug}`} + icon={ + isSelected ? ( + + ) : ( +
+ ) + } + iconPos="left" + className="w-[28.4rem] text-sm" + > + {role.name} + + ); + }) + ) : ( +
+ )} + + + + )} + /> +
+
+
From 626262461a6ebc979eb3cc0ea49c4a8a69096751 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Fri, 6 Sep 2024 14:01:28 +0400 Subject: [PATCH 05/13] feat: assign roles when inviting members to project --- backend/src/server/routes/index.ts | 2 ++ backend/src/services/auth/auth-signup-service.ts | 3 +++ backend/src/services/org/org-service.ts | 2 ++ 3 files changed, 7 insertions(+) diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index af0aa3d8a..9c211e3ad 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -499,6 +499,7 @@ export const registerRoutes = async ( tokenService, projectUserAdditionalPrivilegeDAL, projectUserMembershipRoleDAL, + projectRoleDAL, projectDAL, projectMembershipDAL, orgMembershipDAL, @@ -517,6 +518,7 @@ export const registerRoutes = async ( userGroupMembershipDAL, projectKeyDAL, projectDAL, + projectRoleDAL, projectBotDAL, groupProjectDAL, projectMembershipDAL, diff --git a/backend/src/services/auth/auth-signup-service.ts b/backend/src/services/auth/auth-signup-service.ts index 11c4bc61e..d29bf6aff 100644 --- a/backend/src/services/auth/auth-signup-service.ts +++ b/backend/src/services/auth/auth-signup-service.ts @@ -22,6 +22,7 @@ import { TOrgDALFactory } from "../org/org-dal"; import { TOrgServiceFactory } from "../org/org-service"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal"; +import { TProjectRoleDALFactory } from "../project-role/project-role-dal"; import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service"; import { TUserDALFactory } from "../user/user-dal"; import { UserEncryption } from "../user/user-types"; @@ -52,6 +53,7 @@ type TAuthSignupDep = { licenseService: Pick; projectMembershipDAL: Pick; projectUserMembershipRoleDAL: Pick; + projectRoleDAL: Pick; }; export type TAuthSignupFactory = ReturnType; @@ -66,6 +68,7 @@ export const authSignupServiceFactory = ({ tokenService, smtpService, orgService, + projectRoleDAL, orgDAL, licenseService }: TAuthSignupDep) => { diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 9dad7086e..09ee3b58e 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -92,6 +92,7 @@ type TOrgServiceFactoryDep = { projectRoleDAL: Pick; userGroupMembershipDAL: Pick; projectBotDAL: Pick; + projectRoleDAL: Pick; projectUserMembershipRoleDAL: Pick; }; @@ -114,6 +115,7 @@ export const orgServiceFactory = ({ tokenService, orgBotDAL, licenseService, + projectRoleDAL, samlConfigDAL, userGroupMembershipDAL, projectBotDAL, From d2a54234f4c2466f657a24351a144e957d6f13ee Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Mon, 9 Sep 2024 10:18:53 +0400 Subject: [PATCH 06/13] Rebase with Akhi --- .../src/services/auth/auth-signup-service.ts | 3 -- backend/src/services/org/org-service.ts | 4 +-- .../src/components/signup/TeamInviteStep.tsx | 2 +- .../MembersTab/components/AddMemberModal.tsx | 29 +++++++------------ 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/backend/src/services/auth/auth-signup-service.ts b/backend/src/services/auth/auth-signup-service.ts index d29bf6aff..11c4bc61e 100644 --- a/backend/src/services/auth/auth-signup-service.ts +++ b/backend/src/services/auth/auth-signup-service.ts @@ -22,7 +22,6 @@ import { TOrgDALFactory } from "../org/org-dal"; import { TOrgServiceFactory } from "../org/org-service"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal"; -import { TProjectRoleDALFactory } from "../project-role/project-role-dal"; import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service"; import { TUserDALFactory } from "../user/user-dal"; import { UserEncryption } from "../user/user-types"; @@ -53,7 +52,6 @@ type TAuthSignupDep = { licenseService: Pick; projectMembershipDAL: Pick; projectUserMembershipRoleDAL: Pick; - projectRoleDAL: Pick; }; export type TAuthSignupFactory = ReturnType; @@ -68,7 +66,6 @@ export const authSignupServiceFactory = ({ tokenService, smtpService, orgService, - projectRoleDAL, orgDAL, licenseService }: TAuthSignupDep) => { diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 09ee3b58e..5b4efb992 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -92,7 +92,6 @@ type TOrgServiceFactoryDep = { projectRoleDAL: Pick; userGroupMembershipDAL: Pick; projectBotDAL: Pick; - projectRoleDAL: Pick; projectUserMembershipRoleDAL: Pick; }; @@ -119,8 +118,7 @@ export const orgServiceFactory = ({ samlConfigDAL, userGroupMembershipDAL, projectBotDAL, - projectUserMembershipRoleDAL, - projectRoleDAL + projectUserMembershipRoleDAL }: TOrgServiceFactoryDep) => { /* * Get organization details by the organization id diff --git a/frontend/src/components/signup/TeamInviteStep.tsx b/frontend/src/components/signup/TeamInviteStep.tsx index 934935a42..60276d217 100644 --- a/frontend/src/components/signup/TeamInviteStep.tsx +++ b/frontend/src/components/signup/TeamInviteStep.tsx @@ -60,7 +60,7 @@ export default function TeamInviteStep(): JSX.Element { placeholder="email@example.com, email2@example.com..." />
-
+