fix(server): auto-accept pending invitations by link (#11409)

close CLOUD-192
This commit is contained in:
fengmk2
2025-04-02 13:24:03 +00:00
parent fde97dcf78
commit c8392d0cbe
2 changed files with 62 additions and 1 deletions

View File

@@ -402,3 +402,55 @@ e2e('should get invite link info with status', async t => {
t.truthy(getInviteInfo3, 'failed to get invite info');
t.is(getInviteInfo3.status, WorkspaceMemberStatus.UnderReview);
});
e2e(
'should accept invitation by link directly if status is pending',
async t => {
const owner = await app.create(Mockers.User);
const member = await app.create(Mockers.User);
const workspace = await app.create(Mockers.Workspace, {
owner: { id: owner.id },
});
await app.login(owner);
// create a pending invitation
const invite = await app.gql({
query: inviteByEmailMutation,
variables: {
email: member.email,
workspaceId: workspace.id,
},
});
t.truthy(invite, 'failed to create invitation');
const { createInviteLink } = await app.gql({
query: createInviteLinkMutation,
variables: {
workspaceId: workspace.id,
expireTime: WorkspaceInviteLinkExpireTime.OneDay,
},
});
t.truthy(createInviteLink, 'failed to create invite link');
const link = createInviteLink.link;
const inviteLinkId = link.split('/').pop()!;
// member accept invitation by link
await app.login(member);
await app.gql({
query: acceptInviteByInviteIdMutation,
variables: {
inviteId: inviteLinkId,
workspaceId: workspace.id,
},
});
const { getInviteInfo } = await app.gql({
query: getInviteInfoQuery,
variables: {
inviteId: invite.invite,
},
});
t.is(getInviteInfo.status, WorkspaceMemberStatus.Accepted);
}
);

View File

@@ -628,9 +628,13 @@ export class WorkspaceResolver {
}
}
await this.acceptInviteByInviteId(inviteId);
return true;
}
private async acceptInviteByInviteId(inviteId: string) {
await this.models.workspaceUser.accept(inviteId);
await this.workspaceService.sendInvitationAcceptedNotification(inviteId);
return true;
}
private async acceptInviteByLink(user: CurrentUser, workspaceId: string) {
@@ -642,6 +646,11 @@ export class WorkspaceResolver {
WorkspaceRole.Collaborator,
WorkspaceMemberStatus.UnderReview
);
// if status is pending, should accept the invite directly
if (role.status === WorkspaceMemberStatus.Pending) {
await this.acceptInviteByInviteId(role.id);
return;
}
await this.workspaceService.sendReviewRequestNotification(role.id);
return;
}