mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 10:28:00 +00:00
fix: invite to sub-org
This commit is contained in:
@@ -188,16 +188,29 @@ export const membershipUserServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (existingMemberships.length === users.length) return { memberships: [] };
|
if (existingMemberships.length === users.length) return { memberships: [] };
|
||||||
|
const orgDetails = await orgDAL.findById(dto.permission.orgId);
|
||||||
|
const isSubOrganization = Boolean(orgDetails.rootOrgId);
|
||||||
|
|
||||||
const newMembershipUsers = users.filter((user) => !existingMemberships?.find((el) => el.actorUserId === user.id));
|
const newMembershipUsers = users.filter((user) => !existingMemberships?.find((el) => el.actorUserId === user.id));
|
||||||
await factory.onCreateMembershipUserGuard(dto, newMembershipUsers);
|
await factory.onCreateMembershipUserGuard(dto, newMembershipUsers);
|
||||||
const newMemberships = newMembershipUsers.map((user) => ({
|
const newMemberships = newMembershipUsers.map((user) => {
|
||||||
scope: scopeData.scope,
|
let status: OrgMembershipStatus | undefined;
|
||||||
...scopeDatabaseFields,
|
if (scopeData.scope === AccessScope.Organization) {
|
||||||
actorUserId: user.id,
|
if (isSubOrganization) {
|
||||||
status: scopeData.scope === AccessScope.Organization ? OrgMembershipStatus.Invited : undefined,
|
status = OrgMembershipStatus.Accepted;
|
||||||
inviteEmail: scopeData.scope === AccessScope.Organization ? user.email : undefined
|
} else {
|
||||||
}));
|
status = OrgMembershipStatus.Invited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
scope: scopeData.scope,
|
||||||
|
...scopeDatabaseFields,
|
||||||
|
actorUserId: user.id,
|
||||||
|
status,
|
||||||
|
inviteEmail: status === OrgMembershipStatus.Invited ? user.email : undefined
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role));
|
const customInputRoles = data.roles.filter((el) => factory.isCustomRole(el.role));
|
||||||
const hasCustomRole = customInputRoles.length > 0;
|
const hasCustomRole = customInputRoles.length > 0;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { AccessScope, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, OrganizationActionScope, OrgMembershipStatus } from "@app/db/schemas";
|
||||||
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
@@ -122,16 +122,33 @@ export const newOrgMembershipUserFactory = ({
|
|||||||
const signUpTokens: { email: string; link: string }[] = [];
|
const signUpTokens: { email: string; link: string }[] = [];
|
||||||
const orgDetails = await orgDAL.findById(dto.permission.orgId);
|
const orgDetails = await orgDAL.findById(dto.permission.orgId);
|
||||||
if (orgDetails.rootOrgId) {
|
if (orgDetails.rootOrgId) {
|
||||||
const emails = newUsers.map((el) => el.email).filter(Boolean);
|
// checking if the users have accepted the invitation in the root organization to send the email
|
||||||
await smtpService.sendMail({
|
const orgMembershipAccepted = await membershipUserDAL.find({
|
||||||
template: SmtpTemplates.SubOrgInvite,
|
scope: AccessScope.Organization,
|
||||||
subjectLine: "Infisical sub-organization invitation",
|
scopeOrgId: orgDetails.rootOrgId,
|
||||||
recipients: emails as string[],
|
status: OrgMembershipStatus.Accepted,
|
||||||
substitutions: {
|
$in: {
|
||||||
subOrganizationName: orgDetails.slug,
|
actorUserId: newUsers.map((el) => el.id)
|
||||||
callback_url: `${appCfg.SITE_URL}/organizations/${dto.permission.orgId}/projects`
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const orgMembershipAcceptedUserIds = orgMembershipAccepted.map((el) => el.actorUserId as string);
|
||||||
|
|
||||||
|
const emails = newUsers
|
||||||
|
.filter((el) => Boolean(el?.email) && orgMembershipAcceptedUserIds.includes(el.id))
|
||||||
|
.map((el) => el?.email as string);
|
||||||
|
|
||||||
|
if (emails.length) {
|
||||||
|
await smtpService.sendMail({
|
||||||
|
template: SmtpTemplates.SubOrgInvite,
|
||||||
|
subjectLine: "Infisical sub-organization invitation",
|
||||||
|
recipients: emails,
|
||||||
|
substitutions: {
|
||||||
|
subOrganizationName: orgDetails.slug,
|
||||||
|
callback_url: `${appCfg.SITE_URL}/organizations/${dto.permission.orgId}/projects`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await Promise.allSettled(
|
await Promise.allSettled(
|
||||||
newUsers.map(async (el) => {
|
newUsers.map(async (el) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user