diff --git a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte
index 87309f9b29..8f7b24f1b6 100644
--- a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte
+++ b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte
@@ -275,7 +275,7 @@
diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte b/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte
index e86943c106..165d94e0b5 100644
--- a/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte
+++ b/packages/builder/src/pages/builder/portal/manage/users/_components/AddUserModal.svelte
@@ -47,7 +47,11 @@
function validateInput(email, index) {
if (email) {
const res = emailValidator(email)
- userData[index].error = res === true ? null : res
+ if (res === true) {
+ delete userData[index].error
+ } else {
+ userData[index].error = res
+ }
} else {
userData[index].error = "Please enter an email address"
}
@@ -89,7 +93,7 @@
inputType="email"
bind:inputValue={input.email}
bind:dropdownValue={input.role}
- options={Constants.BbRoles}
+ options={Constants.BudibaseRoleOptions}
error={input.error}
on:blur={() => validateInput(input.email, index)}
/>
diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/RoleTableRenderer.svelte b/packages/builder/src/pages/builder/portal/manage/users/_components/RoleTableRenderer.svelte
index 0a2daf7580..fe7acee6c4 100644
--- a/packages/builder/src/pages/builder/portal/manage/users/_components/RoleTableRenderer.svelte
+++ b/packages/builder/src/pages/builder/portal/manage/users/_components/RoleTableRenderer.svelte
@@ -10,7 +10,9 @@
admin: "Full access",
}
- $: role = Constants.BbRoles.find(x => x.value === users.getUserRole(row))
+ $: role = Constants.BudibaseRoleOptions.find(
+ x => x.value === users.getUserRole(row)
+ )
$: value = role?.label || "Not available"
$: tooltip = TooltipMap[role?.value] || ""
diff --git a/packages/builder/src/pages/builder/portal/manage/users/index.svelte b/packages/builder/src/pages/builder/portal/manage/users/index.svelte
index a33ef55c61..73cf5e26fa 100644
--- a/packages/builder/src/pages/builder/portal/manage/users/index.svelte
+++ b/packages/builder/src/pages/builder/portal/manage/users/index.svelte
@@ -26,6 +26,7 @@
import ImportUsersModal from "./_components/ImportUsersModal.svelte"
import { createPaginationStore } from "helpers/pagination"
import { get } from "svelte/store"
+ import { Constants } from "@budibase/frontend-core"
let enrichedUsers = []
let createUserModal,
@@ -85,13 +86,13 @@
}
async function createUserFlow() {
- let emails = userData?.users?.map(x => x.email) || []
+ const payload = userData?.users?.map(user => ({
+ email: user.email,
+ builder: user.role === Constants.BudibaseRoles.Developer,
+ admin: user.role === Constants.BudibaseRoles.Admin,
+ }))
try {
- const res = await users.invite({
- emails: emails,
- builder: false,
- admin: false,
- })
+ const res = await users.invite(payload)
notifications.success(res.message)
inviteConfirmationModal.show()
} catch (error) {
diff --git a/packages/builder/src/stores/portal/users.js b/packages/builder/src/stores/portal/users.js
index 490d1bc9f6..7fc3704e98 100644
--- a/packages/builder/src/stores/portal/users.js
+++ b/packages/builder/src/stores/portal/users.js
@@ -26,12 +26,8 @@ export function createUsersStore() {
return await API.getUsers()
}
- async function invite({ emails, builder, admin }) {
- return API.inviteUsers({
- emails,
- builder,
- admin,
- })
+ async function invite(payload) {
+ return API.inviteUsers(payload)
}
async function acceptInvite(inviteCode, password) {
return API.acceptInvite({
diff --git a/packages/frontend-core/src/api/user.js b/packages/frontend-core/src/api/user.js
index 17223a80e6..56f0537b97 100644
--- a/packages/frontend-core/src/api/user.js
+++ b/packages/frontend-core/src/api/user.js
@@ -141,20 +141,18 @@ export const buildUserEndpoints = API => ({
/**
* Invites multiple users to the current tenant.
- * @param email An array of email addresses
- * @param builder whether the user should be a global builder
- * @param admin whether the user should be a global admin
+ * @param users An array of users to invite
*/
- inviteUsers: async ({ emails, builder, admin }) => {
+ inviteUsers: async users => {
return await API.post({
url: "/api/global/users/inviteMultiple",
- body: {
- emails,
+ body: users.map(user => ({
+ email: user.email,
userInfo: {
- admin: admin ? { global: true } : undefined,
- builder: builder ? { global: true } : undefined,
+ admin: user.admin ? { global: true } : undefined,
+ builder: user.admin || user.builder ? { global: true } : undefined,
},
- },
+ })),
})
},
diff --git a/packages/frontend-core/src/constants.js b/packages/frontend-core/src/constants.js
index 77765f8d6e..4ad4f0fef8 100644
--- a/packages/frontend-core/src/constants.js
+++ b/packages/frontend-core/src/constants.js
@@ -60,25 +60,31 @@ export const TableNames = {
USERS: "ta_users",
}
-export const BbRoles = [
- { label: "App User", value: "appUser" },
- { label: "Developer", value: "developer" },
- { label: "Admin", value: "admin" },
+export const BudibaseRoles = {
+ AppUser: "appUser",
+ Developer: "developer",
+ Admin: "admin",
+}
+
+export const BudibaseRoleOptions = [
+ { label: "App User", value: BudibaseRoles.AppUser },
+ { label: "Developer", value: BudibaseRoles.Developer },
+ { label: "Admin", value: BudibaseRoles.Admin },
]
export const BuilderRoleDescriptions = [
{
- value: "appUser",
+ value: BudibaseRoles.AppUser,
icon: "User",
label: "App user - Only has access to published apps",
},
{
- value: "developer",
+ value: BudibaseRoles.Developer,
icon: "Hammer",
label: "Developer - Access to the app builder",
},
{
- value: "admin",
+ value: BudibaseRoles.Admin,
icon: "Draw",
label: "Admin - Full access",
},
diff --git a/packages/worker/src/api/controllers/global/users.ts b/packages/worker/src/api/controllers/global/users.ts
index 30bf78efc6..f5e551130e 100644
--- a/packages/worker/src/api/controllers/global/users.ts
+++ b/packages/worker/src/api/controllers/global/users.ts
@@ -214,13 +214,13 @@ export const invite = async (ctx: any) => {
}
export const inviteMultiple = async (ctx: any) => {
- let { emails, userInfo } = ctx.request.body
+ let users = ctx.request.body
let existing = false
let existingEmail
- for (let email of emails) {
- if (await usersCore.getGlobalUserByEmail(email)) {
+ for (let user of users) {
+ if (await usersCore.getGlobalUserByEmail(user.email)) {
existing = true
- existingEmail = email
+ existingEmail = user.email
break
}
}
@@ -228,17 +228,19 @@ export const inviteMultiple = async (ctx: any) => {
if (existing) {
ctx.throw(400, `${existingEmail} already exists`)
}
- if (!userInfo) {
- userInfo = {}
- }
- userInfo.tenantId = tenancy.getTenantId()
- const opts: any = {
- subject: "{{ company }} platform invitation",
- info: userInfo,
- }
- for (let i = 0; i < emails.length; i++) {
- await sendEmail(emails[i], EmailTemplatePurpose.INVITATION, opts)
+ for (let i = 0; i < users.length; i++) {
+ let userInfo = users[i].userInfo
+ if (!userInfo) {
+ userInfo = {}
+ }
+ userInfo.tenantId = tenancy.getTenantId()
+ const opts: any = {
+ subject: "{{ company }} platform invitation",
+ info: userInfo,
+ }
+ console.log(userInfo)
+ await sendEmail(users[i].email, EmailTemplatePurpose.INVITATION, opts)
}
ctx.body = {
diff --git a/packages/worker/src/api/routes/global/users.js b/packages/worker/src/api/routes/global/users.js
index e62e996443..7e8aee1b9e 100644
--- a/packages/worker/src/api/routes/global/users.js
+++ b/packages/worker/src/api/routes/global/users.js
@@ -32,10 +32,12 @@ function buildInviteValidation() {
function buildInviteMultipleValidation() {
// prettier-ignore
- return joiValidator.body(Joi.object({
- emails: Joi.array().required(),
- userInfo: Joi.object().optional(),
- }).required())
+ return joiValidator.body(Joi.array().required().items(
+ Joi.object({
+ email: Joi.string(),
+ userInfo: Joi.object().optional(),
+ })
+ ))
}
function buildInviteAcceptValidation() {