platform user casing view
This commit is contained in:
parent
55e7052273
commit
f42b2d0087
|
@ -18,6 +18,7 @@ export enum ViewName {
|
|||
LINK = "by_link",
|
||||
ROUTING = "screen_routes",
|
||||
AUTOMATION_LOGS = "automation_logs",
|
||||
PLATFORM_USERS_LOWERCASE = "platform_users_lowercase",
|
||||
}
|
||||
|
||||
export const DeprecatedViews = {
|
||||
|
|
|
@ -128,12 +128,33 @@ exports.createUserBuildersView = async () => {
|
|||
await db.put(designDoc)
|
||||
}
|
||||
|
||||
exports.createPlatformUserView = async db => {
|
||||
let designDoc
|
||||
try {
|
||||
designDoc = await db.get(DESIGN_DB)
|
||||
} catch (err) {
|
||||
// no design doc, make one
|
||||
designDoc = DesignDoc()
|
||||
}
|
||||
const view = {
|
||||
map: `function(doc) {
|
||||
emit(doc._id.toLowerCase(), doc._id)
|
||||
}`,
|
||||
}
|
||||
designDoc.views = {
|
||||
...designDoc.views,
|
||||
[ViewName.PLATFORM_USERS_LOWERCASE]: view,
|
||||
}
|
||||
await db.put(designDoc)
|
||||
}
|
||||
|
||||
exports.queryGlobalView = async (viewName, params, db = null) => {
|
||||
const CreateFuncByName = {
|
||||
[ViewName.USER_BY_EMAIL]: exports.createNewUserEmailView,
|
||||
[ViewName.BY_API_KEY]: exports.createApiKeyView,
|
||||
[ViewName.USER_BY_BUILDERS]: exports.createUserBuildersView,
|
||||
[ViewName.USER_BY_APP]: exports.createUserAppView,
|
||||
[ViewName.PLATFORM_USERS_LOWERCASE]: exports.createPlatformUserView,
|
||||
}
|
||||
// can pass DB in if working with something specific
|
||||
if (!db) {
|
||||
|
@ -149,7 +170,7 @@ exports.queryGlobalView = async (viewName, params, db = null) => {
|
|||
if (err != null && err.name === "not_found") {
|
||||
const createFunc = CreateFuncByName[viewName]
|
||||
await removeDeprecated(db, viewName)
|
||||
await createFunc()
|
||||
await createFunc(db)
|
||||
return exports.queryGlobalView(viewName, params)
|
||||
} else {
|
||||
throw err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { doWithDB } from "../db"
|
||||
import { StaticDatabases } from "../db/constants"
|
||||
import { StaticDatabases, UNICODE_MAX, ViewName } from "../db/constants"
|
||||
import { baseGlobalDBName } from "./utils"
|
||||
import {
|
||||
getTenantId,
|
||||
|
@ -8,6 +8,7 @@ import {
|
|||
getTenantIDFromAppID,
|
||||
} from "../context"
|
||||
import env from "../environment"
|
||||
import { queryGlobalView } from "../db/views"
|
||||
|
||||
const TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants
|
||||
const PLATFORM_INFO_DB = StaticDatabases.PLATFORM_INFO.name
|
||||
|
@ -117,12 +118,22 @@ export const lookupTenantId = async (userId: string) => {
|
|||
|
||||
// lookup, could be email or userId, either will return a doc
|
||||
export const getTenantUser = async (identifier: string) => {
|
||||
return doWithDB(PLATFORM_INFO_DB, async (db: any) => {
|
||||
try {
|
||||
return await db.get(identifier)
|
||||
} catch (err) {
|
||||
return null
|
||||
// use the view here and allow to find anyone regardless of casing
|
||||
const lcIdentifier = identifier.toLowerCase()
|
||||
|
||||
return await doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: any) => {
|
||||
let response = await queryGlobalView(
|
||||
ViewName.PLATFORM_USERS_LOWERCASE,
|
||||
{
|
||||
startkey: lcIdentifier,
|
||||
endkey: `${lcIdentifier}${UNICODE_MAX}`,
|
||||
},
|
||||
db
|
||||
)
|
||||
if (!response) {
|
||||
response = []
|
||||
}
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
</script>
|
||||
|
||||
<ModalContent
|
||||
size="S"
|
||||
size="M"
|
||||
title="Accounts created!"
|
||||
confirmText="Done"
|
||||
showCancelButton={false}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
const { createPlatformUserView } = require("@budibase/backend-core/db")
|
||||
|
||||
/**
|
||||
* Date:
|
||||
* September 2022
|
||||
*
|
||||
* Description:
|
||||
* Create a view in platform DB with lowercase emails for all users.
|
||||
*/
|
||||
|
||||
export const run = async () => {
|
||||
await createPlatformUserView()
|
||||
}
|
|
@ -9,6 +9,7 @@ import * as appUrls from "./functions/appUrls"
|
|||
import * as developerQuota from "./functions/developerQuota"
|
||||
import * as publishedAppsQuota from "./functions/publishedAppsQuota"
|
||||
import * as backfill from "./functions/backfill"
|
||||
import * as platformUsersEmailViewCasing from "./functions/platformUserEmailViewCasing"
|
||||
|
||||
/**
|
||||
* Populate the migration function and additional configuration from
|
||||
|
@ -84,6 +85,13 @@ export const buildMigrations = () => {
|
|||
})
|
||||
break
|
||||
}
|
||||
case MigrationName.PLATFORM_USERS_EMAIL_CASING: {
|
||||
serverMigrations.push({
|
||||
...definition,
|
||||
fn: platformUsersEmailViewCasing.run,
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ export enum MigrationName {
|
|||
EVENT_GLOBAL_BACKFILL = "event_global_backfill",
|
||||
EVENT_INSTALLATION_BACKFILL = "event_installation_backfill",
|
||||
GLOBAL_INFO_SYNC_USERS = "global_info_sync_users",
|
||||
PLATFORM_USERS_EMAIL_CASING = "platform_users_email_casing",
|
||||
}
|
||||
|
||||
export interface MigrationDefinition {
|
||||
|
|
|
@ -264,11 +264,14 @@ export const bulkCreate = async (
|
|||
)
|
||||
let mapped = allUsers.rows.map((row: any) => row.id)
|
||||
|
||||
const currentUserEmails = mapped.map((x: any) => x.email) || []
|
||||
const currentUserEmails = mapped.map((x: any) => x.email.toLowerCase()) || []
|
||||
for (const newUser of newUsersRequested) {
|
||||
// Lowercase emails to ensure several users can't be created with different email casing
|
||||
if (
|
||||
newUsers.find((x: any) => x.email === newUser.email) ||
|
||||
currentUserEmails.includes(newUser.email)
|
||||
newUsers.find(
|
||||
(x: any) => x.email.toLowerCase() === newUser.email.toLowerCase()
|
||||
) ||
|
||||
currentUserEmails.includes(newUser.email.toLowerCase())
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue