94 lines
2.4 KiB
TypeScript
94 lines
2.4 KiB
TypeScript
import { getGlobalUsers } from "../../utilities/global"
|
|
import { context, roles as rolesCore } from "@budibase/backend-core"
|
|
import {
|
|
getGlobalIDFromUserMetadataID,
|
|
generateUserMetadataID,
|
|
getUserMetadataParams,
|
|
InternalTables,
|
|
} from "../../db/utils"
|
|
import { isEqual } from "lodash"
|
|
import { ContextUser, UserMetadata, User } from "@budibase/types"
|
|
|
|
export function combineMetadataAndUser(
|
|
user: ContextUser,
|
|
metadata: UserMetadata | UserMetadata[]
|
|
) {
|
|
const metadataId = generateUserMetadataID(user._id!)
|
|
const found = Array.isArray(metadata)
|
|
? metadata.find(doc => doc._id === metadataId)
|
|
: metadata
|
|
// skip users with no access
|
|
if (
|
|
user.roleId == null ||
|
|
user.roleId === rolesCore.BUILTIN_ROLE_IDS.PUBLIC
|
|
) {
|
|
// If it exists and it should not, we must remove it
|
|
if (found?._id) {
|
|
return { ...found, _deleted: true }
|
|
}
|
|
return null
|
|
}
|
|
delete user._rev
|
|
const newDoc = {
|
|
...user,
|
|
_id: metadataId,
|
|
tableId: InternalTables.USER_METADATA,
|
|
}
|
|
// copy rev over for the purposes of equality check
|
|
if (found) {
|
|
newDoc._rev = found._rev
|
|
}
|
|
// clear fields that shouldn't be in metadata
|
|
delete newDoc.password
|
|
delete newDoc.forceResetPassword
|
|
delete newDoc.roles
|
|
if (found == null || !isEqual(newDoc, found)) {
|
|
return {
|
|
...found,
|
|
...newDoc,
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
export async function rawUserMetadata() {
|
|
const db = context.getAppDB()
|
|
return (
|
|
await db.allDocs(
|
|
getUserMetadataParams(null, {
|
|
include_docs: true,
|
|
})
|
|
)
|
|
).rows.map(row => row.doc)
|
|
}
|
|
|
|
export async function syncGlobalUsers() {
|
|
// sync user metadata
|
|
const db = context.getAppDB()
|
|
const resp = await Promise.all([getGlobalUsers(), rawUserMetadata()])
|
|
const users = resp[0] as User[]
|
|
const metadata = resp[1] as UserMetadata[]
|
|
const toWrite = []
|
|
for (let user of users) {
|
|
const combined = combineMetadataAndUser(user, metadata)
|
|
if (combined) {
|
|
toWrite.push(combined)
|
|
}
|
|
}
|
|
let foundEmails: string[] = []
|
|
for (let data of metadata) {
|
|
if (!data._id) {
|
|
continue
|
|
}
|
|
const alreadyExisting = data.email && foundEmails.indexOf(data.email) !== -1
|
|
const globalId = getGlobalIDFromUserMetadataID(data._id)
|
|
if (!users.find(user => user._id === globalId) || alreadyExisting) {
|
|
toWrite.push({ ...data, _deleted: true })
|
|
}
|
|
if (data.email) {
|
|
foundEmails.push(data.email)
|
|
}
|
|
}
|
|
await db.bulkDocs(toWrite)
|
|
}
|