fix(server): accept invite condition (#9124)

This commit is contained in:
darkskygit
2024-12-12 10:01:13 +00:00
parent e100d252b2
commit 56c573ebf3
4 changed files with 32 additions and 4 deletions

View File

@@ -323,16 +323,23 @@ export class PermissionService {
}); });
if (data) { if (data) {
const toBeOwner = permission === Permission.Owner;
if (data.accepted && data.status === WorkspaceMemberStatus.Accepted) { if (data.accepted && data.status === WorkspaceMemberStatus.Accepted) {
const [p] = await this.prisma.$transaction( const [p] = await this.prisma.$transaction(
[ [
this.prisma.workspaceUserPermission.update({ this.prisma.workspaceUserPermission.update({
where: { workspaceId_userId: { workspaceId: ws, userId: user } }, where: {
workspaceId_userId: { workspaceId: ws, userId: user },
// only update permission:
// 1. if the new permission is owner and original permission is admin
// 2. if the original permission is not owner
type: toBeOwner ? Permission.Admin : { not: Permission.Owner },
},
data: { type: permission }, data: { type: permission },
}), }),
// If the new permission is owner, we need to revoke old owner // If the new permission is owner, we need to revoke old owner
permission === Permission.Owner toBeOwner
? this.prisma.workspaceUserPermission.updateMany({ ? this.prisma.workspaceUserPermission.updateMany({
where: { where: {
workspaceId: ws, workspaceId: ws,

View File

@@ -15,6 +15,7 @@ import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
import type { FileUpload } from '../../../fundamentals'; import type { FileUpload } from '../../../fundamentals';
import { import {
AlreadyInSpace,
Cache, Cache,
CantChangeSpaceOwner, CantChangeSpaceOwner,
DocNotFound, DocNotFound,
@@ -528,6 +529,14 @@ export class WorkspaceResolver {
} }
if (user) { if (user) {
const status = await this.permissions.getWorkspaceMemberStatus(
workspaceId,
user.id
);
if (status === WorkspaceMemberStatus.Accepted) {
throw new AlreadyInSpace({ spaceId: workspaceId });
}
// invite link // invite link
const invite = await this.cache.get<{ inviteId: string }>( const invite = await this.cache.get<{ inviteId: string }>(
`workspace:inviteLink:${workspaceId}` `workspace:inviteLink:${workspaceId}`

View File

@@ -120,6 +120,9 @@ const init = async (app: INestApplication, memberLimit = 10) => {
await acceptInviteById(app, ws.id, inviteId, false, member.token.token); await acceptInviteById(app, ws.id, inviteId, false, member.token.token);
return member; return member;
}, },
async (token: string) => {
await acceptInviteById(app, ws.id, inviteId, false, token);
},
] as const; ] as const;
}; };
@@ -259,7 +262,7 @@ test('should be able to leave workspace', async t => {
test('should be able to invite by link', async t => { test('should be able to invite by link', async t => {
const { app, permissions, quotaManager } = t.context; const { app, permissions, quotaManager } = t.context;
const { createInviteLink, owner, ws } = await init(app, 4); const { createInviteLink, owner, ws } = await init(app, 4);
const [inviteId, invite] = await createInviteLink(); const [inviteId, invite, acceptInvite] = await createInviteLink();
{ {
// check invite link // check invite link
@@ -311,5 +314,14 @@ test('should be able to invite by link', async t => {
WorkspaceMemberStatus.UnderReview, WorkspaceMemberStatus.UnderReview,
'should not change status' 'should not change status'
); );
{
const message = `You have already joined in Space ${ws.id}.`;
await t.throwsAsync(
acceptInvite(owner.token.token),
{ message },
'should throw error if member already in workspace'
);
}
} }
}); });

View File

@@ -7,7 +7,7 @@
"en": 100, "en": 100,
"es-AR": 13, "es-AR": 13,
"es-CL": 14, "es-CL": 14,
"es": 13, "es": 12,
"fr": 61, "fr": 61,
"hi": 2, "hi": 2,
"it-IT": 1, "it-IT": 1,