2022-08-19 15:08:03 +02:00
|
|
|
import {
|
2022-08-11 14:50:05 +02:00
|
|
|
ViewName,
|
2022-07-25 19:57:10 +02:00
|
|
|
getUsersByAppParams,
|
|
|
|
getProdAppID,
|
|
|
|
generateAppUserID,
|
2022-11-17 14:31:54 +01:00
|
|
|
queryGlobalView,
|
|
|
|
UNICODE_MAX,
|
|
|
|
} from "./db"
|
2022-09-21 14:55:10 +02:00
|
|
|
import { BulkDocsResponse, User } from "@budibase/types"
|
2022-09-21 13:43:09 +02:00
|
|
|
import { getGlobalDB } from "./context"
|
2023-02-21 09:23:53 +01:00
|
|
|
import * as context from "./context"
|
2022-09-21 13:43:09 +02:00
|
|
|
|
2023-02-23 12:28:18 +01:00
|
|
|
type GetOpts = { cleanup?: boolean }
|
|
|
|
|
|
|
|
function cleanupUsers(users: User | User[]) {
|
|
|
|
if (Array.isArray(users)) {
|
|
|
|
return users.map(user => {
|
2023-02-23 18:23:06 +01:00
|
|
|
if (user) {
|
|
|
|
delete user.password
|
|
|
|
return user
|
|
|
|
}
|
2023-02-23 12:28:18 +01:00
|
|
|
})
|
2023-02-23 18:23:06 +01:00
|
|
|
} else if (users) {
|
2023-02-23 12:28:18 +01:00
|
|
|
delete users.password
|
|
|
|
return users
|
|
|
|
}
|
2023-02-23 18:23:06 +01:00
|
|
|
return users
|
2023-02-23 12:28:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export const bulkGetGlobalUsersById = async (
|
|
|
|
userIds: string[],
|
|
|
|
opts?: GetOpts
|
|
|
|
) => {
|
2022-11-09 17:53:42 +01:00
|
|
|
const db = getGlobalDB()
|
2023-02-23 12:28:18 +01:00
|
|
|
let users = (
|
2022-09-21 13:43:09 +02:00
|
|
|
await db.allDocs({
|
|
|
|
keys: userIds,
|
|
|
|
include_docs: true,
|
|
|
|
})
|
|
|
|
).rows.map(row => row.doc) as User[]
|
2023-02-23 12:28:18 +01:00
|
|
|
if (opts?.cleanup) {
|
|
|
|
users = cleanupUsers(users) as User[]
|
|
|
|
}
|
|
|
|
return users
|
2022-09-21 13:43:09 +02:00
|
|
|
}
|
2022-04-08 02:28:22 +02:00
|
|
|
|
2022-09-21 14:55:10 +02:00
|
|
|
export const bulkUpdateGlobalUsers = async (users: User[]) => {
|
2022-11-09 17:53:42 +01:00
|
|
|
const db = getGlobalDB()
|
2022-09-21 14:55:10 +02:00
|
|
|
return (await db.bulkDocs(users)) as BulkDocsResponse
|
|
|
|
}
|
|
|
|
|
2023-02-23 12:28:18 +01:00
|
|
|
export async function getById(id: string, opts?: GetOpts): Promise<User> {
|
2023-02-21 09:23:53 +01:00
|
|
|
const db = context.getGlobalDB()
|
2023-02-23 12:28:18 +01:00
|
|
|
let user = await db.get(id)
|
|
|
|
if (opts?.cleanup) {
|
|
|
|
user = cleanupUsers(user)
|
|
|
|
}
|
|
|
|
return user
|
2023-02-21 09:23:53 +01:00
|
|
|
}
|
|
|
|
|
2022-04-08 02:28:22 +02:00
|
|
|
/**
|
|
|
|
* Given an email address this will use a view to search through
|
|
|
|
* all the users to find one with this email address.
|
|
|
|
* @param {string} email the email to lookup the user by.
|
|
|
|
*/
|
2022-09-06 13:25:57 +02:00
|
|
|
export const getGlobalUserByEmail = async (
|
2023-02-23 12:28:18 +01:00
|
|
|
email: String,
|
|
|
|
opts?: GetOpts
|
2022-09-06 13:25:57 +02:00
|
|
|
): Promise<User | undefined> => {
|
2022-04-08 02:28:22 +02:00
|
|
|
if (email == null) {
|
|
|
|
throw "Must supply an email address to view"
|
|
|
|
}
|
|
|
|
|
2022-08-19 15:08:03 +02:00
|
|
|
const response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {
|
2022-04-08 02:28:22 +02:00
|
|
|
key: email.toLowerCase(),
|
|
|
|
include_docs: true,
|
|
|
|
})
|
2022-04-12 13:34:36 +02:00
|
|
|
|
2022-07-18 22:11:52 +02:00
|
|
|
if (Array.isArray(response)) {
|
|
|
|
// shouldn't be able to happen, but need to handle just in case
|
|
|
|
throw new Error(`Multiple users found with email address: ${email}`)
|
|
|
|
}
|
|
|
|
|
2023-02-23 12:28:18 +01:00
|
|
|
let user = response as User
|
|
|
|
if (opts?.cleanup) {
|
|
|
|
user = cleanupUsers(user) as User
|
|
|
|
}
|
|
|
|
|
|
|
|
return user
|
2022-04-08 02:28:22 +02:00
|
|
|
}
|
2022-06-30 16:39:26 +02:00
|
|
|
|
2023-02-23 12:28:18 +01:00
|
|
|
export const searchGlobalUsersByApp = async (
|
|
|
|
appId: any,
|
|
|
|
opts: any,
|
|
|
|
getOpts?: GetOpts
|
|
|
|
) => {
|
2022-07-06 17:09:05 +02:00
|
|
|
if (typeof appId !== "string") {
|
|
|
|
throw new Error("Must provide a string based app ID")
|
|
|
|
}
|
|
|
|
const params = getUsersByAppParams(appId, {
|
|
|
|
include_docs: true,
|
|
|
|
})
|
|
|
|
params.startkey = opts && opts.startkey ? opts.startkey : params.startkey
|
2022-08-11 14:50:05 +02:00
|
|
|
let response = await queryGlobalView(ViewName.USER_BY_APP, params)
|
2022-07-06 17:09:05 +02:00
|
|
|
if (!response) {
|
|
|
|
response = []
|
|
|
|
}
|
2023-02-23 12:28:18 +01:00
|
|
|
let users: User[] = Array.isArray(response) ? response : [response]
|
|
|
|
if (getOpts?.cleanup) {
|
|
|
|
users = cleanupUsers(users) as User[]
|
|
|
|
}
|
|
|
|
return users
|
2022-07-06 17:09:05 +02:00
|
|
|
}
|
|
|
|
|
2022-08-19 15:08:03 +02:00
|
|
|
export const getGlobalUserByAppPage = (appId: string, user: User) => {
|
2022-07-06 17:09:05 +02:00
|
|
|
if (!user) {
|
|
|
|
return
|
|
|
|
}
|
2022-11-11 12:57:50 +01:00
|
|
|
return generateAppUserID(getProdAppID(appId)!, user._id!)
|
2022-04-08 02:28:22 +02:00
|
|
|
}
|
2022-06-30 16:39:26 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Performs a starts with search on the global email view.
|
|
|
|
*/
|
2023-02-23 12:28:18 +01:00
|
|
|
export const searchGlobalUsersByEmail = async (
|
|
|
|
email: string,
|
|
|
|
opts: any,
|
|
|
|
getOpts?: GetOpts
|
|
|
|
) => {
|
2022-06-30 16:39:26 +02:00
|
|
|
if (typeof email !== "string") {
|
|
|
|
throw new Error("Must provide a string to search by")
|
|
|
|
}
|
|
|
|
const lcEmail = email.toLowerCase()
|
|
|
|
// handle if passing up startkey for pagination
|
|
|
|
const startkey = opts && opts.startkey ? opts.startkey : lcEmail
|
2022-08-19 15:08:03 +02:00
|
|
|
let response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {
|
2022-06-30 16:39:26 +02:00
|
|
|
...opts,
|
|
|
|
startkey,
|
|
|
|
endkey: `${lcEmail}${UNICODE_MAX}`,
|
|
|
|
})
|
|
|
|
if (!response) {
|
|
|
|
response = []
|
|
|
|
}
|
2023-02-23 12:28:18 +01:00
|
|
|
let users: User[] = Array.isArray(response) ? response : [response]
|
|
|
|
if (getOpts?.cleanup) {
|
|
|
|
users = cleanupUsers(users) as User[]
|
|
|
|
}
|
|
|
|
return users
|
2022-06-30 16:39:26 +02:00
|
|
|
}
|