platform user casing view

This commit is contained in:
Martin McKeaveney 2022-09-02 09:12:03 +01:00
parent 55e7052273
commit f42b2d0087
8 changed files with 69 additions and 11 deletions

View File

@ -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 = {

View File

@ -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

View File

@ -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
})
}

View File

@ -42,7 +42,7 @@
</script>
<ModalContent
size="S"
size="M"
title="Accounts created!"
confirmText="Done"
showCancelButton={false}

View File

@ -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()
}

View File

@ -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
}
}
}

View File

@ -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 {

View File

@ -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
}