MCPcopy
hub / github.com/simstudioai/sim / acceptInvitation

Function acceptInvitation

apps/sim/lib/invitations/core.ts:266–577  ·  view source on GitHub ↗
(
  input: AcceptInvitationInput
)

Source from the content-addressed store, hash-verified

264}
265
266export async function acceptInvitation(
267 input: AcceptInvitationInput
268): Promise<AcceptInvitationResult> {
269 const inv = await getInvitationById(input.invitationId)
270
271 if (!inv) {
272 return { success: false, kind: 'not-found' }
273 }
274
275 if (input.token && inv.token !== input.token) {
276 return { success: false, kind: 'invalid-token' }
277 }
278
279 if (inv.status !== 'pending') {
280 return { success: false, kind: 'already-processed' }
281 }
282
283 if (isInvitationExpired(inv)) {
284 await db
285 .update(invitation)
286 .set({ status: 'expired', updatedAt: new Date() })
287 .where(and(eq(invitation.id, inv.id), eq(invitation.status, 'pending')))
288 return { success: false, kind: 'expired' }
289 }
290
291 if (normalizeEmail(input.userEmail) !== normalizeEmail(inv.email)) {
292 return { success: false, kind: 'email-mismatch' }
293 }
294
295 let membershipAlreadyExists = false
296 let acceptedMembershipIntent = inv.membershipIntent
297 let shouldJoinOrganization = inv.membershipIntent !== 'external'
298
299 const primaryGrant = inv.grants[0]
300 let billingOwnerUserId = inv.inviterId
301 let workspaceOrganizationId = inv.organizationId
302 if (primaryGrant) {
303 const grantWorkspace = await getWorkspaceWithOwner(primaryGrant.workspaceId)
304 if (grantWorkspace) {
305 billingOwnerUserId = grantWorkspace.billedAccountUserId
306 workspaceOrganizationId = grantWorkspace.organizationId ?? inv.organizationId
307 }
308 }
309
310 const existingMembership = await getUserOrganization(input.userId)
311 const inviteeAlreadyInDifferentOrg =
312 !!existingMembership &&
313 (workspaceOrganizationId ? existingMembership.organizationId !== workspaceOrganizationId : true)
314
315 if (shouldJoinOrganization && inviteeAlreadyInDifferentOrg) {
316 if (await downgradeOrRejectCrossOrgInvite(inv)) {
317 acceptedMembershipIntent = 'external'
318 shouldJoinOrganization = false
319 } else {
320 return { success: false, kind: 'already-in-organization' }
321 }
322 }
323

Callers 2

core.test.tsFile · 0.90
route.tsFile · 0.90

Calls 15

normalizeEmailFunction · 0.90
getWorkspaceWithOwnerFunction · 0.90
getUserOrganizationFunction · 0.90
ensureUserInOrganizationFunction · 0.90
recordAuditFunction · 0.90
captureServerEventFunction · 0.90
acquireOrgMembershipLockFunction · 0.90
generateIdFunction · 0.90

Tested by

no test coverage detected