1
0
Fork 0
mirror of synced 2024-06-30 20:10:54 +12:00

Reject inviting the same user twice.

This commit is contained in:
Sam Rose 2023-11-09 11:15:44 +00:00
parent 3f69b17c94
commit a6a75b533c
No known key found for this signature in database
4 changed files with 21 additions and 8 deletions

View file

@ -349,14 +349,12 @@ export const checkInvite = async (ctx: any) => {
} }
export const getUserInvites = async (ctx: any) => { export const getUserInvites = async (ctx: any) => {
let invites
try { try {
// Restricted to the currently authenticated tenant // Restricted to the currently authenticated tenant
invites = await getInviteCodes() ctx.body = await getInviteCodes()
} catch (e) { } catch (e) {
ctx.throw(400, "There was a problem fetching invites") ctx.throw(400, "There was a problem fetching invites")
} }
ctx.body = invites
} }
export const updateInvite = async (ctx: any) => { export const updateInvite = async (ctx: any) => {

View file

@ -59,6 +59,8 @@ describe("/api/global/users", () => {
const email = structures.users.newEmail() const email = structures.users.newEmail()
await config.api.users.sendUserInvite(sendMailMock, email) await config.api.users.sendUserInvite(sendMailMock, email)
jest.clearAllMocks()
const { code, res } = await config.api.users.sendUserInvite( const { code, res } = await config.api.users.sendUserInvite(
sendMailMock, sendMailMock,
email, email,

View file

@ -1,5 +1,9 @@
import { events, tenancy, users as usersCore } from "@budibase/backend-core" import { events, tenancy, users as usersCore } from "@budibase/backend-core"
import { InviteUsersRequest, InviteUsersResponse } from "@budibase/types" import {
InviteUserRequest,
InviteUsersRequest,
InviteUsersResponse,
} from "@budibase/types"
import { sendEmail } from "../../utilities/email" import { sendEmail } from "../../utilities/email"
import { EmailTemplatePurpose } from "../../constants" import { EmailTemplatePurpose } from "../../constants"
import { getInviteCodes } from "../..//utilities/redis" import { getInviteCodes } from "../..//utilities/redis"
@ -15,12 +19,17 @@ export async function invite(
const matchedEmails = await usersCore.searchExistingEmails( const matchedEmails = await usersCore.searchExistingEmails(
users.map(u => u.email) users.map(u => u.email)
) )
const existingInvites = await getInviteCodes() const invitedEmails = (await getInviteCodes()).map(invite => invite.email)
const newUsers = [] const newUsers: InviteUserRequest[] = []
// separate duplicates from new users // separate duplicates from new users
for (let user of users) { for (let user of users) {
if (matchedEmails.includes(user.email)) { if (
matchedEmails.includes(user.email) ||
invitedEmails.includes(user.email)
) {
// This "Unavailable" is load bearing. The tests and frontend both check for it
// specifically
response.unsuccessful.push({ email: user.email, reason: "Unavailable" }) response.unsuccessful.push({ email: user.email, reason: "Unavailable" })
} else { } else {
newUsers.push(user) newUsers.push(user)

View file

@ -66,7 +66,11 @@ async function writeCode(db: RedisDBName, value: Invite | PasswordReset) {
return code return code
} }
async function updateCode(db: RedisDBName, code: string, value: any) { async function updateCode(
db: RedisDBName,
code: string,
value: Invite | PasswordReset
) {
const client = getClient(db) const client = getClient(db)
await client.store(code, value, getExpirySecondsForDB(db)) await client.store(code, value, getExpirySecondsForDB(db))
} }