1
0
Fork 0
mirror of synced 2024-06-02 18:44:54 +12:00
budibase/packages/backend-core/src/tenancy/tenancy.ts

147 lines
3.8 KiB
TypeScript
Raw Normal View History

import { doWithDB } from "../db"
2022-09-08 10:21:14 +12:00
import { queryPlatformView } from "../db/views"
2022-09-03 03:07:30 +12:00
import { StaticDatabases, ViewName } from "../db/constants"
import { getGlobalDBName } from "../db/tenancy"
import {
getTenantId,
DEFAULT_TENANT_ID,
isMultiTenant,
getTenantIDFromAppID,
} from "../context"
import env from "../environment"
import { PlatformUser } from "@budibase/types"
const TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants
const PLATFORM_INFO_DB = StaticDatabases.PLATFORM_INFO.name
export const addTenantToUrl = (url: string) => {
const tenantId = getTenantId()
if (isMultiTenant()) {
const char = url.indexOf("?") === -1 ? "?" : "&"
url += `${char}tenantId=${tenantId}`
}
return url
}
export const doesTenantExist = async (tenantId: string) => {
return doWithDB(PLATFORM_INFO_DB, async (db: any) => {
let tenants
try {
tenants = await db.get(TENANT_DOC)
} catch (err) {
// if theres an error the doc doesn't exist, no tenants exist
return false
}
return (
tenants &&
Array.isArray(tenants.tenantIds) &&
tenants.tenantIds.indexOf(tenantId) !== -1
)
})
}
export const tryAddTenant = async (
tenantId: string,
userId: string,
email: string,
afterCreateTenant: () => Promise<void>
) => {
return doWithDB(PLATFORM_INFO_DB, async (db: any) => {
const getDoc = async (id: string) => {
if (!id) {
return null
}
try {
return await db.get(id)
} catch (err) {
return { _id: id }
}
}
let [tenants, userIdDoc, emailDoc] = await Promise.all([
getDoc(TENANT_DOC),
getDoc(userId),
getDoc(email),
])
if (!Array.isArray(tenants.tenantIds)) {
tenants = {
_id: TENANT_DOC,
tenantIds: [],
}
}
let promises = []
if (userIdDoc) {
userIdDoc.tenantId = tenantId
promises.push(db.put(userIdDoc))
}
if (emailDoc) {
emailDoc.tenantId = tenantId
emailDoc.userId = userId
promises.push(db.put(emailDoc))
}
if (tenants.tenantIds.indexOf(tenantId) === -1) {
tenants.tenantIds.push(tenantId)
promises.push(db.put(tenants))
await afterCreateTenant()
}
await Promise.all(promises)
})
}
export const doWithGlobalDB = (tenantId: string, cb: any) => {
return doWithDB(getGlobalDBName(tenantId), cb)
}
export const lookupTenantId = async (userId: string) => {
return doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: any) => {
let tenantId = env.MULTI_TENANCY ? DEFAULT_TENANT_ID : null
try {
const doc = await db.get(userId)
if (doc && doc.tenantId) {
tenantId = doc.tenantId
}
} catch (err) {
// just return the default
}
return tenantId
})
}
// lookup, could be email or userId, either will return a doc
2022-09-15 01:22:53 +12:00
export const getTenantUser = async (
identifier: string
): Promise<PlatformUser | null> => {
2022-09-02 20:12:03 +12:00
// use the view here and allow to find anyone regardless of casing
2022-09-03 03:07:30 +12:00
// Use lowercase to ensure email login is case insensitive
2022-09-15 01:22:53 +12:00
const response = queryPlatformView(ViewName.PLATFORM_USERS_LOWERCASE, {
2022-09-03 03:07:30 +12:00
keys: [identifier.toLowerCase()],
include_docs: true,
2022-09-15 01:22:53 +12:00
}) as Promise<PlatformUser>
2022-09-03 03:07:30 +12:00
return response
}
export const isUserInAppTenant = (appId: string, user?: any) => {
let userTenantId
if (user) {
userTenantId = user.tenantId || DEFAULT_TENANT_ID
} else {
userTenantId = getTenantId()
}
const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID
return tenantId === userTenantId
}
2022-01-24 23:48:59 +13:00
export const getTenantIds = async () => {
return doWithDB(PLATFORM_INFO_DB, async (db: any) => {
let tenants
try {
tenants = await db.get(TENANT_DOC)
} catch (err) {
// if theres an error the doc doesn't exist, no tenants exist
return []
}
return (tenants && tenants.tenantIds) || []
})
2022-01-24 23:48:59 +13:00
}