(
userId: User['id'],
inviteToken: string,
authentication: InvitationAuthenticationContext = {}
)
| 613 | if (policy.status === 'misconfigured') { |
| 614 | throw new Error('Organization SSO policy is misconfigured'); |
| 615 | } |
| 616 | |
| 617 | let authenticationRequirement: 'default' | 'workos' = 'default'; |
| 618 | let ssoSourceOrganizationId: string | null = null; |
| 619 | const emailDomain = getLowerDomainFromEmail(email); |
| 620 | if (policy.status === 'required' && emailDomain === policy.domain) { |
| 621 | if (policy.source === 'self') { |
| 622 | throw new Error('User must join this organization through SSO'); |
| 623 | } |
| 624 | authenticationRequirement = 'workos'; |
| 625 | ssoSourceOrganizationId = policy.sourceOrganizationId; |
| 626 | } |
| 627 | |
| 628 | const existingInvitation = await tx |
| 629 | .select() |
| 630 | .from(organization_invitations) |
| 631 | .where( |
| 632 | and( |
| 633 | eq(organization_invitations.organization_id, organizationId), |
| 634 | eq(organization_invitations.email, email), |
| 635 | isNull(organization_invitations.accepted_at), |
| 636 | gt(organization_invitations.expires_at, sql`NOW()`) |
| 637 | ) |
| 638 | ) |
| 639 | .limit(1); |
| 640 | |
| 641 | if (existingInvitation.length > 0) { |
| 642 | throw new Error('User already has a pending invitation'); |
| 643 | } |
| 644 | |
| 645 | const existingMember = await tx |
| 646 | .select() |
| 647 | .from(organization_memberships) |
| 648 | .innerJoin(kilocode_users, eq(kilocode_users.id, organization_memberships.kilo_user_id)) |
| 649 | .where( |
| 650 | and( |
| 651 | eq(organization_memberships.organization_id, organizationId), |
| 652 | eq(kilocode_users.google_user_email, email) |
| 653 | ) |
| 654 | ) |
| 655 | .limit(1); |
| 656 | |
| 657 | if (existingMember.length > 0) { |
| 658 | throw new Error('User is already a member of this organization'); |
| 659 | } |
| 660 | |
| 661 | const [invitation] = await tx |
| 662 | .insert(organization_invitations) |
| 663 | .values({ |
| 664 | organization_id: organizationId, |
| 665 | email, |
| 666 | role, |
| 667 | invited_by: invitingUserId, |
| 668 | token: randomUUID(), |
| 669 | expires_at: sql`NOW() + INTERVAL '7 days'`, |
| 670 | authentication_requirement: authenticationRequirement, |
| 671 | sso_source_organization_id: ssoSourceOrganizationId, |
| 672 | }) |
no test coverage detected