Skip to content

Commit

Permalink
fix(core): trigger webhook in organization invitation flow
Browse files Browse the repository at this point in the history
should trigger the Organization.Membership.Updated webhook event when a organization invitation is accepted.
  • Loading branch information
simeng-li committed Feb 7, 2025
1 parent 52f2489 commit 07a768d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
7 changes: 7 additions & 0 deletions .changeset/afraid-turkeys-swim.md
Original file line number Diff line number Diff line change
@@ -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.
10 changes: 9 additions & 1 deletion packages/core/src/routes/organization-invitation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,15 @@ export default function organizationInvitationRoutes<T extends ManagementApiRout
})
);

ctx.body = await organizationInvitations.updateStatus(id, status, acceptedUserId);
const result = await organizationInvitations.updateStatus(id, status, acceptedUserId);

const { organizationId } = result;
ctx.appendDataHookContext('Organization.Membership.Updated', {
organizationId,
});

ctx.body = result;

Check warning on line 156 in packages/core/src/routes/organization-invitation/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/routes/organization-invitation/index.ts#L148-L156

Added lines #L148 - L156 were not covered by tests
return next();
}
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { SignInIdentifier, hookEvents, userInfoSelectFields } from '@logto/schemas';
import {
OrganizationInvitationStatus,
SignInIdentifier,
hookEvents,
userInfoSelectFields,
} from '@logto/schemas';
import { pick } from '@silverhand/essentials';

import { deleteUser } from '#src/api/admin-user.js';
Expand All @@ -10,7 +15,7 @@ import { SsoConnectorApi } from '#src/api/sso-connector.js';
import { setEmailConnector, setSmsConnector } from '#src/helpers/connector.js';
import { WebHookApiTest } from '#src/helpers/hook.js';
import { registerWithEmail } from '#src/helpers/interactions.js';
import { OrganizationApiTest } from '#src/helpers/organization.js';
import { OrganizationApiTest, OrganizationInvitationApiTest } from '#src/helpers/organization.js';
import { enableAllVerificationCodeSignInMethods } from '#src/helpers/sign-in-experience.js';
import { registerNewUserWithSso } from '#src/helpers/single-sign-on.js';
import { UserApiTest } from '#src/helpers/user.js';
Expand Down Expand Up @@ -169,4 +174,35 @@ describe('manual data hook tests', () => {
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);
});
});
});

0 comments on commit 07a768d

Please sign in to comment.