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