diff --git a/.changeset/afraid-turkeys-swim.md b/.changeset/afraid-turkeys-swim.md new file mode 100644 index 00000000000..44f369f62db --- /dev/null +++ b/.changeset/afraid-turkeys-swim.md @@ -0,0 +1,7 @@ +--- +"@logto/core": patch +--- + +bug fix. Trigger the `Organization.Membership.Updated` webhook when a user accepts an invitation and join an organization. + +Added a new `Organization.Membership.Accepted` webhook event in the `PUT /api/organization-invitations/{id}/status` endpoint. This event will be triggered when the organization-invitation status is updated to `accepted`, and user is added to the organization. diff --git a/packages/core/src/routes/organization-invitation/index.ts b/packages/core/src/routes/organization-invitation/index.ts index c988850a783..083f6940269 100644 --- a/packages/core/src/routes/organization-invitation/index.ts +++ b/packages/core/src/routes/organization-invitation/index.ts @@ -145,7 +145,15 @@ export default function organizationInvitationRoutes { await assertOrganizationMembershipUpdated(organization.id); }); }); + + describe('organization membership update by accept organization invitation', () => { + const invitationApi = new OrganizationInvitationApiTest(); + + afterEach(async () => { + await invitationApi.cleanUp(); + }); + + it('should trigger `Organization.Membership.Updated` event when user accept organization invitation', async () => { + const organization = await organizationApi.create({ name: generateName() }); + const invitation = await invitationApi.create({ + organizationId: organization.id, + invitee: generateEmail(), + expiresAt: Date.now() + 1_000_000, + }); + expect(invitation.status).toBe('Pending'); + + const user = await userApi.create({ + primaryEmail: invitation.invitee, + }); + + const updated = await invitationApi.updateStatus( + invitation.id, + OrganizationInvitationStatus.Accepted, + user.id + ); + + expect(updated.status).toBe('Accepted'); + await assertOrganizationMembershipUpdated(organization.id); + }); + }); });