Merge pull request #4761 from specklesystems/iain/duplicate-workspace-join-request
fix(server/workspaces): gracefully handle duplicate workspace join requests
This commit is contained in:
@@ -23,7 +23,11 @@ const tables = {
|
||||
export const createWorkspaceJoinRequestFactory =
|
||||
({ db }: { db: Knex }): CreateWorkspaceJoinRequest =>
|
||||
async ({ workspaceJoinRequest }) => {
|
||||
const res = await tables.workspaceJoinRequests(db).insert(workspaceJoinRequest, '*')
|
||||
const res = await tables
|
||||
.workspaceJoinRequests(db)
|
||||
.insert(workspaceJoinRequest, '*')
|
||||
.onConflict()
|
||||
.ignore()
|
||||
return res[0]
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export const requestToJoinWorkspaceFactory =
|
||||
throw new WorkspaceProtectedError()
|
||||
}
|
||||
|
||||
await createWorkspaceJoinRequest({
|
||||
const joinRequest = await createWorkspaceJoinRequest({
|
||||
workspaceJoinRequest: {
|
||||
userId,
|
||||
workspaceId,
|
||||
@@ -92,6 +92,11 @@ export const requestToJoinWorkspaceFactory =
|
||||
}
|
||||
})
|
||||
|
||||
if (!joinRequest || joinRequest.status !== 'pending') {
|
||||
// The request was already created, so don't send the email again
|
||||
return true
|
||||
}
|
||||
|
||||
await sendWorkspaceJoinRequestReceivedEmail({
|
||||
workspace,
|
||||
requester
|
||||
|
||||
@@ -233,6 +233,95 @@ const { FF_WORKSPACES_MODULE_ENABLED } = getFeatureFlags()
|
||||
)
|
||||
expect(sendWorkspaceJoinRequestReceivedEmailCalls[0].requester).to.equal(user)
|
||||
})
|
||||
it('duplicate request is idempotent', async () => {
|
||||
const createWorkspaceJoinRequest = createWorkspaceJoinRequestFactory({ db })
|
||||
|
||||
const sendWorkspaceJoinRequestReceivedEmailCalls: Parameters<SendWorkspaceJoinRequestReceivedEmail>[number][] =
|
||||
[]
|
||||
const sendWorkspaceJoinRequestReceivedEmail = async (
|
||||
args: Parameters<SendWorkspaceJoinRequestReceivedEmail>[number]
|
||||
) => sendWorkspaceJoinRequestReceivedEmailCalls.push(args)
|
||||
|
||||
const user: BasicTestUser = {
|
||||
id: '',
|
||||
name: 'John Speckle',
|
||||
email: `${createRandomString()}@example.org`,
|
||||
role: Roles.Server.Admin,
|
||||
verified: true
|
||||
}
|
||||
|
||||
await createTestUser(user)
|
||||
|
||||
const workspace: BasicTestWorkspace = {
|
||||
id: '',
|
||||
slug: '',
|
||||
ownerId: '',
|
||||
name: cryptoRandomString({ length: 6 }),
|
||||
description: cryptoRandomString({ length: 12 }),
|
||||
discoverabilityEnabled: true
|
||||
}
|
||||
await createTestWorkspace(workspace, user, { domain: 'example.org' })
|
||||
const domain = {
|
||||
id: cryptoRandomString({ length: 10 }),
|
||||
workspaceId: workspace.id,
|
||||
domain: 'example.org',
|
||||
verified: true,
|
||||
createdAt: new Date(),
|
||||
createdByUserId: user.id,
|
||||
updatedAt: new Date()
|
||||
}
|
||||
|
||||
const requestToJoinWorkspace = await requestToJoinWorkspaceFactory({
|
||||
createWorkspaceJoinRequest,
|
||||
sendWorkspaceJoinRequestReceivedEmail:
|
||||
sendWorkspaceJoinRequestReceivedEmail as unknown as SendWorkspaceJoinRequestReceivedEmail,
|
||||
getUserById: async () => user as unknown as UserWithOptionalRole,
|
||||
getWorkspaceWithDomains: async () =>
|
||||
({
|
||||
...workspace,
|
||||
domains: [domain]
|
||||
} as unknown as WorkspaceWithDomains),
|
||||
getUserEmails: async () =>
|
||||
[{ email: user.email, verified: true }] as unknown as UserEmail[]
|
||||
})
|
||||
|
||||
expect(
|
||||
await requestToJoinWorkspace({ workspaceId: workspace.id, userId: user.id })
|
||||
).to.equal(true)
|
||||
|
||||
expect(
|
||||
(await db<WorkspaceJoinRequest>(WorkspaceJoinRequests.name)
|
||||
.where({
|
||||
workspaceId: workspace.id,
|
||||
userId: user.id
|
||||
})
|
||||
.select('status')
|
||||
.first())!.status
|
||||
).to.equal('pending')
|
||||
|
||||
expect(sendWorkspaceJoinRequestReceivedEmailCalls).to.have.length(1)
|
||||
expect(sendWorkspaceJoinRequestReceivedEmailCalls[0].workspace.id).to.equal(
|
||||
workspace.id
|
||||
)
|
||||
expect(sendWorkspaceJoinRequestReceivedEmailCalls[0].requester).to.equal(user)
|
||||
|
||||
// attempt to join again
|
||||
expect(
|
||||
await requestToJoinWorkspace({ workspaceId: workspace.id, userId: user.id })
|
||||
).to.equal(true)
|
||||
|
||||
expect(
|
||||
(await db<WorkspaceJoinRequest>(WorkspaceJoinRequests.name)
|
||||
.where({
|
||||
workspaceId: workspace.id,
|
||||
userId: user.id
|
||||
})
|
||||
.select('status')
|
||||
.first())!.status
|
||||
).to.equal('pending')
|
||||
|
||||
expect(sendWorkspaceJoinRequestReceivedEmailCalls).to.have.length(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('approveWorkspaceJoinRequestFactory, returns a function that ', () => {
|
||||
|
||||
Reference in New Issue
Block a user