Fix users invited by email not being able to take priveleged roles

This commit is contained in:
Andrew Kingston 2022-08-03 15:16:26 +01:00
parent 60565abfbf
commit 6701c25fc9
9 changed files with 61 additions and 50 deletions

View File

@ -275,7 +275,7 @@
<Label size="L">Role</Label> <Label size="L">Role</Label>
<Select <Select
value={globalRole} value={globalRole}
options={Constants.BbRoles} options={Constants.BudibaseRoleOptions}
on:change={updateUserRole} on:change={updateUserRole}
/> />
</div> </div>

View File

@ -47,7 +47,11 @@
function validateInput(email, index) { function validateInput(email, index) {
if (email) { if (email) {
const res = emailValidator(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 { } else {
userData[index].error = "Please enter an email address" userData[index].error = "Please enter an email address"
} }
@ -89,7 +93,7 @@
inputType="email" inputType="email"
bind:inputValue={input.email} bind:inputValue={input.email}
bind:dropdownValue={input.role} bind:dropdownValue={input.role}
options={Constants.BbRoles} options={Constants.BudibaseRoleOptions}
error={input.error} error={input.error}
on:blur={() => validateInput(input.email, index)} on:blur={() => validateInput(input.email, index)}
/> />

View File

@ -10,7 +10,9 @@
admin: "Full access", 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" $: value = role?.label || "Not available"
$: tooltip = TooltipMap[role?.value] || "" $: tooltip = TooltipMap[role?.value] || ""
</script> </script>

View File

@ -26,6 +26,7 @@
import ImportUsersModal from "./_components/ImportUsersModal.svelte" import ImportUsersModal from "./_components/ImportUsersModal.svelte"
import { createPaginationStore } from "helpers/pagination" import { createPaginationStore } from "helpers/pagination"
import { get } from "svelte/store" import { get } from "svelte/store"
import { Constants } from "@budibase/frontend-core"
let enrichedUsers = [] let enrichedUsers = []
let createUserModal, let createUserModal,
@ -85,13 +86,13 @@
} }
async function createUserFlow() { 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 { try {
const res = await users.invite({ const res = await users.invite(payload)
emails: emails,
builder: false,
admin: false,
})
notifications.success(res.message) notifications.success(res.message)
inviteConfirmationModal.show() inviteConfirmationModal.show()
} catch (error) { } catch (error) {

View File

@ -26,12 +26,8 @@ export function createUsersStore() {
return await API.getUsers() return await API.getUsers()
} }
async function invite({ emails, builder, admin }) { async function invite(payload) {
return API.inviteUsers({ return API.inviteUsers(payload)
emails,
builder,
admin,
})
} }
async function acceptInvite(inviteCode, password) { async function acceptInvite(inviteCode, password) {
return API.acceptInvite({ return API.acceptInvite({

View File

@ -141,20 +141,18 @@ export const buildUserEndpoints = API => ({
/** /**
* Invites multiple users to the current tenant. * Invites multiple users to the current tenant.
* @param email An array of email addresses * @param users An array of users to invite
* @param builder whether the user should be a global builder
* @param admin whether the user should be a global admin
*/ */
inviteUsers: async ({ emails, builder, admin }) => { inviteUsers: async users => {
return await API.post({ return await API.post({
url: "/api/global/users/inviteMultiple", url: "/api/global/users/inviteMultiple",
body: { body: users.map(user => ({
emails, email: user.email,
userInfo: { userInfo: {
admin: admin ? { global: true } : undefined, admin: user.admin ? { global: true } : undefined,
builder: builder ? { global: true } : undefined, builder: user.admin || user.builder ? { global: true } : undefined,
}, },
}, })),
}) })
}, },

View File

@ -60,25 +60,31 @@ export const TableNames = {
USERS: "ta_users", USERS: "ta_users",
} }
export const BbRoles = [ export const BudibaseRoles = {
{ label: "App User", value: "appUser" }, AppUser: "appUser",
{ label: "Developer", value: "developer" }, Developer: "developer",
{ label: "Admin", value: "admin" }, Admin: "admin",
}
export const BudibaseRoleOptions = [
{ label: "App User", value: BudibaseRoles.AppUser },
{ label: "Developer", value: BudibaseRoles.Developer },
{ label: "Admin", value: BudibaseRoles.Admin },
] ]
export const BuilderRoleDescriptions = [ export const BuilderRoleDescriptions = [
{ {
value: "appUser", value: BudibaseRoles.AppUser,
icon: "User", icon: "User",
label: "App user - Only has access to published apps", label: "App user - Only has access to published apps",
}, },
{ {
value: "developer", value: BudibaseRoles.Developer,
icon: "Hammer", icon: "Hammer",
label: "Developer - Access to the app builder", label: "Developer - Access to the app builder",
}, },
{ {
value: "admin", value: BudibaseRoles.Admin,
icon: "Draw", icon: "Draw",
label: "Admin - Full access", label: "Admin - Full access",
}, },

View File

@ -214,13 +214,13 @@ export const invite = async (ctx: any) => {
} }
export const inviteMultiple = async (ctx: any) => { export const inviteMultiple = async (ctx: any) => {
let { emails, userInfo } = ctx.request.body let users = ctx.request.body
let existing = false let existing = false
let existingEmail let existingEmail
for (let email of emails) { for (let user of users) {
if (await usersCore.getGlobalUserByEmail(email)) { if (await usersCore.getGlobalUserByEmail(user.email)) {
existing = true existing = true
existingEmail = email existingEmail = user.email
break break
} }
} }
@ -228,17 +228,19 @@ export const inviteMultiple = async (ctx: any) => {
if (existing) { if (existing) {
ctx.throw(400, `${existingEmail} already exists`) 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++) { for (let i = 0; i < users.length; i++) {
await sendEmail(emails[i], EmailTemplatePurpose.INVITATION, opts) 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 = { ctx.body = {

View File

@ -32,10 +32,12 @@ function buildInviteValidation() {
function buildInviteMultipleValidation() { function buildInviteMultipleValidation() {
// prettier-ignore // prettier-ignore
return joiValidator.body(Joi.object({ return joiValidator.body(Joi.array().required().items(
emails: Joi.array().required(), Joi.object({
userInfo: Joi.object().optional(), email: Joi.string(),
}).required()) userInfo: Joi.object().optional(),
})
))
} }
function buildInviteAcceptValidation() { function buildInviteAcceptValidation() {