import env from "../../environment" import { events, accounts, tenancy } from "@budibase/backend-core" import { User, UserRoles, CloudAccount } from "@budibase/types" export const handleDeleteEvents = async (user: any) => { await events.user.deleted(user) if (isBuilder(user)) { await events.user.permissionBuilderRemoved(user) } if (isAdmin(user)) { await events.user.permissionAdminRemoved(user) } } const assignAppRoleEvents = async ( user: User, roles: UserRoles, existingRoles: UserRoles ) => { for (const [appId, role] of Object.entries(roles)) { // app role in existing is not same as new if (!existingRoles || existingRoles[appId] !== role) { await events.role.assigned(user, role) } } } const unassignAppRoleEvents = async ( user: User, roles: UserRoles, existingRoles: UserRoles ) => { if (!existingRoles) { return } for (const [appId, role] of Object.entries(existingRoles)) { // app role in new is not same as existing if (!roles || roles[appId] !== role) { await events.role.unassigned(user, role) } } } const handleAppRoleEvents = async (user: any, existingUser: any) => { const roles = user.roles const existingRoles = existingUser?.roles await assignAppRoleEvents(user, roles, existingRoles) await unassignAppRoleEvents(user, roles, existingRoles) } export const handleSaveEvents = async (user: any, existingUser: any) => { const tenantId = tenancy.getTenantId() let tenantAccount: CloudAccount | undefined if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { tenantAccount = await accounts.getAccountByTenantId(tenantId) } await events.identification.identifyUser(user, tenantAccount) if (existingUser) { await events.user.updated(user) if (isRemovingBuilder(user, existingUser)) { await events.user.permissionBuilderRemoved(user) } if (isRemovingAdmin(user, existingUser)) { await events.user.permissionAdminRemoved(user) } if ( !existingUser.forceResetPassword && user.forceResetPassword && user.password ) { await events.user.passwordForceReset(user) } } else { await events.user.created(user) } if (isAddingBuilder(user, existingUser)) { await events.user.permissionBuilderAssigned(user) } if (isAddingAdmin(user, existingUser)) { await events.user.permissionAdminAssigned(user) } await handleAppRoleEvents(user, existingUser) } const isBuilder = (user: any) => user.builder && user.builder.global const isAdmin = (user: any) => user.admin && user.admin.global export const isAddingBuilder = (user: any, existingUser: any) => { return isAddingPermission(user, existingUser, isBuilder) } export const isRemovingBuilder = (user: any, existingUser: any) => { return isRemovingPermission(user, existingUser, isBuilder) } const isAddingAdmin = (user: any, existingUser: any) => { return isAddingPermission(user, existingUser, isAdmin) } const isRemovingAdmin = (user: any, existingUser: any) => { return isRemovingPermission(user, existingUser, isAdmin) } /** * Check if a permission is being added to a new or existing user. */ const isAddingPermission = ( user: any, existingUser: any, hasPermission: any ) => { // new user doesn't have the permission if (!hasPermission(user)) { return false } // existing user has the permission if (existingUser && hasPermission(existingUser)) { return false } // permission is being added return true } /** * Check if a permission is being removed from an existing user. */ const isRemovingPermission = ( user: any, existingUser: any, hasPermission: any ) => { // new user has the permission if (hasPermission(user)) { return false } // no existing user or existing user doesn't have the permission if (!existingUser) { return false } // existing user doesn't have the permission if (!hasPermission(existingUser)) { return false } // permission is being removed return true }