Add new UnsavedUser type and update controllers
This commit is contained in:
parent
52916f11a8
commit
6bd4cb47c2
|
@ -9,9 +9,18 @@ import {
|
||||||
SearchUsersResponse,
|
SearchUsersResponse,
|
||||||
UpdateInviteRequest,
|
UpdateInviteRequest,
|
||||||
User,
|
User,
|
||||||
|
UserIdentifier,
|
||||||
|
UnsavedUser,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { BudiStore } from "../BudiStore"
|
import { BudiStore } from "../BudiStore"
|
||||||
|
|
||||||
|
interface UserInfo {
|
||||||
|
email: string
|
||||||
|
password: string
|
||||||
|
forceResetPassword?: boolean
|
||||||
|
role: keyof typeof Constants.BudibaseRoles
|
||||||
|
}
|
||||||
|
|
||||||
type UserState = SearchUsersResponse & SearchUsersRequest
|
type UserState = SearchUsersResponse & SearchUsersRequest
|
||||||
|
|
||||||
class UserStore extends BudiStore<UserState> {
|
class UserStore extends BudiStore<UserState> {
|
||||||
|
@ -116,9 +125,9 @@ class UserStore extends BudiStore<UserState> {
|
||||||
return await API.getUserCountByApp(appId)
|
return await API.getUserCountByApp(appId)
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(data: any) {
|
async create(data: { users: UserInfo[]; groups: any[] }) {
|
||||||
let mappedUsers: Omit<User, "tenantId">[] = data.users.map((user: any) => {
|
let mappedUsers: UnsavedUser[] = data.users.map((user: any) => {
|
||||||
const body: Omit<User, "tenantId"> = {
|
const body: UnsavedUser = {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
password: user.password,
|
password: user.password,
|
||||||
roles: {},
|
roles: {},
|
||||||
|
@ -128,17 +137,17 @@ class UserStore extends BudiStore<UserState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (user.role) {
|
switch (user.role) {
|
||||||
case "appUser":
|
case Constants.BudibaseRoles.AppUser:
|
||||||
body.builder = { global: false }
|
body.builder = { global: false }
|
||||||
body.admin = { global: false }
|
body.admin = { global: false }
|
||||||
break
|
break
|
||||||
case "developer":
|
case Constants.BudibaseRoles.Developer:
|
||||||
body.builder = { global: true }
|
body.builder = { global: true }
|
||||||
break
|
break
|
||||||
case "creator":
|
case Constants.BudibaseRoles.Creator:
|
||||||
body.builder = { creator: true, global: false }
|
body.builder = { creator: true, global: false }
|
||||||
break
|
break
|
||||||
case "admin":
|
case Constants.BudibaseRoles.Admin:
|
||||||
body.admin = { global: true }
|
body.admin = { global: true }
|
||||||
body.builder = { global: true }
|
body.builder = { global: true }
|
||||||
break
|
break
|
||||||
|
@ -157,12 +166,7 @@ class UserStore extends BudiStore<UserState> {
|
||||||
await API.deleteUser(id)
|
await API.deleteUser(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async bulkDelete(
|
async bulkDelete(users: UserIdentifier[]) {
|
||||||
users: Array<{
|
|
||||||
userId: string
|
|
||||||
email: string
|
|
||||||
}>
|
|
||||||
) {
|
|
||||||
return API.deleteUsers(users)
|
return API.deleteUsers(users)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,9 +203,8 @@ class UserStore extends BudiStore<UserState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foo = this.refreshUsage(this.create)
|
// Wrapper function to refresh quota usage after an operation,
|
||||||
bar = this.refreshUsage(this.save)
|
// persisting argument and return types
|
||||||
|
|
||||||
refreshUsage<T extends any[], U>(fn: (...args: T) => Promise<U>) {
|
refreshUsage<T extends any[], U>(fn: (...args: T) => Promise<U>) {
|
||||||
return async function (...args: T) {
|
return async function (...args: T) {
|
||||||
const response = await fn(...args)
|
const response = await fn(...args)
|
||||||
|
|
|
@ -21,11 +21,12 @@ import {
|
||||||
SaveUserResponse,
|
SaveUserResponse,
|
||||||
SearchUsersRequest,
|
SearchUsersRequest,
|
||||||
SearchUsersResponse,
|
SearchUsersResponse,
|
||||||
|
UnsavedUser,
|
||||||
UpdateInviteRequest,
|
UpdateInviteRequest,
|
||||||
UpdateInviteResponse,
|
UpdateInviteResponse,
|
||||||
UpdateSelfMetadataRequest,
|
UpdateSelfMetadataRequest,
|
||||||
UpdateSelfMetadataResponse,
|
UpdateSelfMetadataResponse,
|
||||||
User,
|
UserIdentifier,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { BaseAPIClient } from "./types"
|
import { BaseAPIClient } from "./types"
|
||||||
|
|
||||||
|
@ -38,14 +39,9 @@ export interface UserEndpoints {
|
||||||
createAdminUser: (
|
createAdminUser: (
|
||||||
user: CreateAdminUserRequest
|
user: CreateAdminUserRequest
|
||||||
) => Promise<CreateAdminUserResponse>
|
) => Promise<CreateAdminUserResponse>
|
||||||
saveUser: (user: User) => Promise<SaveUserResponse>
|
saveUser: (user: UnsavedUser) => Promise<SaveUserResponse>
|
||||||
deleteUser: (userId: string) => Promise<DeleteUserResponse>
|
deleteUser: (userId: string) => Promise<DeleteUserResponse>
|
||||||
deleteUsers: (
|
deleteUsers: (users: UserIdentifier[]) => Promise<BulkUserDeleted | undefined>
|
||||||
users: Array<{
|
|
||||||
userId: string
|
|
||||||
email: string
|
|
||||||
}>
|
|
||||||
) => Promise<BulkUserDeleted | undefined>
|
|
||||||
onboardUsers: (data: InviteUsersRequest) => Promise<InviteUsersResponse>
|
onboardUsers: (data: InviteUsersRequest) => Promise<InviteUsersResponse>
|
||||||
getUserInvite: (code: string) => Promise<CheckInviteResponse>
|
getUserInvite: (code: string) => Promise<CheckInviteResponse>
|
||||||
getUserInvites: () => Promise<GetUserInvitesResponse>
|
getUserInvites: () => Promise<GetUserInvitesResponse>
|
||||||
|
@ -60,7 +56,7 @@ export interface UserEndpoints {
|
||||||
getAccountHolder: () => Promise<LookupAccountHolderResponse>
|
getAccountHolder: () => Promise<LookupAccountHolderResponse>
|
||||||
searchUsers: (data: SearchUsersRequest) => Promise<SearchUsersResponse>
|
searchUsers: (data: SearchUsersRequest) => Promise<SearchUsersResponse>
|
||||||
createUsers: (
|
createUsers: (
|
||||||
users: Omit<User, "tenantId">[],
|
users: UnsavedUser[],
|
||||||
groups: any[]
|
groups: any[]
|
||||||
) => Promise<BulkUserCreated | undefined>
|
) => Promise<BulkUserCreated | undefined>
|
||||||
updateUserInvite: (
|
updateUserInvite: (
|
||||||
|
|
|
@ -22,6 +22,8 @@ export interface UserDetails {
|
||||||
password?: string
|
password?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UnsavedUser = Omit<User, "tenantId">
|
||||||
|
|
||||||
export interface BulkUserRequest {
|
export interface BulkUserRequest {
|
||||||
delete?: {
|
delete?: {
|
||||||
users: Array<{
|
users: Array<{
|
||||||
|
@ -31,7 +33,7 @@ export interface BulkUserRequest {
|
||||||
}
|
}
|
||||||
create?: {
|
create?: {
|
||||||
roles?: any[]
|
roles?: any[]
|
||||||
users: User[]
|
users: UnsavedUser[]
|
||||||
groups: any[]
|
groups: any[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import {
|
||||||
SaveUserResponse,
|
SaveUserResponse,
|
||||||
SearchUsersRequest,
|
SearchUsersRequest,
|
||||||
SearchUsersResponse,
|
SearchUsersResponse,
|
||||||
|
UnsavedUser,
|
||||||
UpdateInviteRequest,
|
UpdateInviteRequest,
|
||||||
UpdateInviteResponse,
|
UpdateInviteResponse,
|
||||||
User,
|
User,
|
||||||
|
@ -49,6 +50,7 @@ import {
|
||||||
tenancy,
|
tenancy,
|
||||||
db,
|
db,
|
||||||
locks,
|
locks,
|
||||||
|
context,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
import { checkAnyUserExists } from "../../../utilities/users"
|
import { checkAnyUserExists } from "../../../utilities/users"
|
||||||
import { isEmailConfigured } from "../../../utilities/email"
|
import { isEmailConfigured } from "../../../utilities/email"
|
||||||
|
@ -66,10 +68,11 @@ const generatePassword = (length: number) => {
|
||||||
.slice(0, length)
|
.slice(0, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const save = async (ctx: UserCtx<User, SaveUserResponse>) => {
|
export const save = async (ctx: UserCtx<UnsavedUser, SaveUserResponse>) => {
|
||||||
try {
|
try {
|
||||||
const currentUserId = ctx.user?._id
|
const currentUserId = ctx.user?._id
|
||||||
const requestUser = ctx.request.body
|
const tenantId = context.getTenantId()
|
||||||
|
const requestUser: User = { ...ctx.request.body, tenantId }
|
||||||
|
|
||||||
// Do not allow the account holder role to be changed
|
// Do not allow the account holder role to be changed
|
||||||
const accountMetadata = await users.getExistingAccounts([requestUser.email])
|
const accountMetadata = await users.getExistingAccounts([requestUser.email])
|
||||||
|
@ -149,7 +152,12 @@ export const bulkUpdate = async (
|
||||||
let created, deleted
|
let created, deleted
|
||||||
try {
|
try {
|
||||||
if (input.create) {
|
if (input.create) {
|
||||||
created = await bulkCreate(input.create.users, input.create.groups)
|
const tenantId = context.getTenantId()
|
||||||
|
const users: User[] = input.create.users.map(user => ({
|
||||||
|
...user,
|
||||||
|
tenantId,
|
||||||
|
}))
|
||||||
|
created = await bulkCreate(users, input.create.groups)
|
||||||
}
|
}
|
||||||
if (input.delete) {
|
if (input.delete) {
|
||||||
deleted = await bulkDelete(input.delete.users, currentUserId)
|
deleted = await bulkDelete(input.delete.users, currentUserId)
|
||||||
|
@ -441,7 +449,6 @@ export const checkInvite = async (ctx: UserCtx<void, CheckInviteResponse>) => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Error getting invite from code", e)
|
console.warn("Error getting invite from code", e)
|
||||||
ctx.throw(400, "There was a problem with the invite")
|
ctx.throw(400, "There was a problem with the invite")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
email: invite.email,
|
email: invite.email,
|
||||||
|
@ -472,7 +479,6 @@ export const updateInvite = async (
|
||||||
invite = await cache.invite.getCode(code)
|
invite = await cache.invite.getCode(code)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ctx.throw(400, "There was a problem with the invite")
|
ctx.throw(400, "There was a problem with the invite")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let updated = {
|
let updated = {
|
||||||
|
|
Loading…
Reference in New Issue