diff --git a/packages/backend-core/src/errors/errors.ts b/packages/backend-core/src/errors/errors.ts index 54ca8456ab..4e1f1abbb5 100644 --- a/packages/backend-core/src/errors/errors.ts +++ b/packages/backend-core/src/errors/errors.ts @@ -97,3 +97,11 @@ export class InvalidAPIKeyError extends BudibaseError { ) } } + +// USERS + +export class EmailUnavailableError extends Error { + constructor(email: string) { + super(`Email already in use: '${email}'`) + } +} diff --git a/packages/server/src/api/routes/tests/automation.spec.js b/packages/server/src/api/routes/tests/automation.spec.js index 2eae5e2a61..47daa8975b 100644 --- a/packages/server/src/api/routes/tests/automation.spec.js +++ b/packages/server/src/api/routes/tests/automation.spec.js @@ -19,11 +19,14 @@ describe("/automations", () => { afterAll(setup.afterAll) - // For some reason this cannot be a beforeAll or the test "tests the automation successfully" fail - beforeEach(async () => { + beforeAll(async () => { await config.init() }) + beforeEach(() => { + events.automation.deleted.mockClear() + }) + describe("get definitions", () => { it("returns a list of definitions for actions", async () => { const res = await request diff --git a/packages/worker/src/api/routes/global/tests/scim.spec.ts b/packages/worker/src/api/routes/global/tests/scim.spec.ts index 6c411a640d..e76e6b6cda 100644 --- a/packages/worker/src/api/routes/global/tests/scim.spec.ts +++ b/packages/worker/src/api/routes/global/tests/scim.spec.ts @@ -318,6 +318,15 @@ describe("scim", () => { await postScimUser({ body }, { expect: 500 }) }) }) + + it("creating an existing user name returns a conflict", async () => { + const body = structures.scim.createUserRequest() + + await postScimUser({ body }) + + const res = await postScimUser({ body }, { expect: 409 }) + expect((res as any).message).toBe("Email already in use") + }) }) describe("GET /api/global/scim/v2/users/:id", () => { diff --git a/packages/worker/src/api/routes/global/tests/users.spec.ts b/packages/worker/src/api/routes/global/tests/users.spec.ts index d1afa0191e..52d77cbae6 100644 --- a/packages/worker/src/api/routes/global/tests/users.spec.ts +++ b/packages/worker/src/api/routes/global/tests/users.spec.ts @@ -48,7 +48,7 @@ describe("/api/global/users", () => { 400 ) - expect(res.body.message).toBe("Unavailable") + expect(res.body.message).toBe(`Unavailable`) expect(sendMailMock).toHaveBeenCalledTimes(0) expect(code).toBeUndefined() expect(events.user.invited).toBeCalledTimes(0) @@ -225,7 +225,9 @@ describe("/api/global/users", () => { const response = await config.api.users.saveUser(user, 400) - expect(response.body.message).toBe(`Unavailable`) + expect(response.body.message).toBe( + `Email already in use: '${user.email}'` + ) expect(events.user.created).toBeCalledTimes(0) }) @@ -237,7 +239,9 @@ describe("/api/global/users", () => { delete user._id const response = await config.api.users.saveUser(user, 400) - expect(response.body.message).toBe(`Unavailable`) + expect(response.body.message).toBe( + `Email already in use: '${user.email}'` + ) expect(events.user.created).toBeCalledTimes(0) }) }) @@ -249,7 +253,9 @@ describe("/api/global/users", () => { const response = await config.api.users.saveUser(user, 400) - expect(response.body.message).toBe(`Unavailable`) + expect(response.body.message).toBe( + `Email already in use: '${user.email}'` + ) expect(events.user.created).toBeCalledTimes(0) }) diff --git a/packages/worker/src/sdk/users/users.ts b/packages/worker/src/sdk/users/users.ts index f05c6b98d2..2150654ae9 100644 --- a/packages/worker/src/sdk/users/users.ts +++ b/packages/worker/src/sdk/users/users.ts @@ -16,6 +16,7 @@ import { ViewName, env as coreEnv, context, + EmailUnavailableError, } from "@budibase/backend-core" import { AccountMetadata, @@ -158,7 +159,7 @@ const validateUniqueUser = async (email: string, tenantId: string) => { if (env.MULTI_TENANCY) { const tenantUser = await getPlatformUser(email) if (tenantUser != null && tenantUser.tenantId !== tenantId) { - throw `Unavailable` + throw new EmailUnavailableError(email) } } @@ -166,7 +167,7 @@ const validateUniqueUser = async (email: string, tenantId: string) => { if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { const account = await accounts.getAccount(email) if (account && account.verified && account.tenantId !== tenantId) { - throw `Unavailable` + throw new EmailUnavailableError(email) } } } @@ -235,7 +236,7 @@ export const save = async ( // no id was specified - load from email instead dbUser = await usersCore.getGlobalUserByEmail(email) if (dbUser && dbUser._id !== _id) { - throw `Unavailable` + throw new EmailUnavailableError(email) } }