mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
UBERF-8083: Optimize account by email search (#6538)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
49113d8cd8
commit
04ce0d70ef
@ -32,6 +32,7 @@ export abstract class MemDb extends TxProcessor implements Storage {
|
|||||||
private readonly objectById = new Map<Ref<Doc>, Doc>()
|
private readonly objectById = new Map<Ref<Doc>, Doc>()
|
||||||
|
|
||||||
private readonly accountByPersonId = new Map<Ref<Doc>, Account[]>()
|
private readonly accountByPersonId = new Map<Ref<Doc>, Account[]>()
|
||||||
|
private readonly accountByEmail = new Map<string, Account>()
|
||||||
|
|
||||||
constructor (protected readonly hierarchy: Hierarchy) {
|
constructor (protected readonly hierarchy: Hierarchy) {
|
||||||
super()
|
super()
|
||||||
@ -81,6 +82,10 @@ export abstract class MemDb extends TxProcessor implements Storage {
|
|||||||
return this.accountByPersonId.get(ref) ?? []
|
return this.accountByPersonId.get(ref) ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAccountByEmail (email: Account['email']): Account | undefined {
|
||||||
|
return this.accountByEmail.get(email)
|
||||||
|
}
|
||||||
|
|
||||||
findObject<T extends Doc>(_id: Ref<T>): T | undefined {
|
findObject<T extends Doc>(_id: Ref<T>): T | undefined {
|
||||||
const doc = this.objectById.get(_id)
|
const doc = this.objectById.get(_id)
|
||||||
return doc as T
|
return doc as T
|
||||||
@ -227,6 +232,7 @@ export abstract class MemDb extends TxProcessor implements Storage {
|
|||||||
})
|
})
|
||||||
if (this.hierarchy.isDerived(doc._class, core.class.Account)) {
|
if (this.hierarchy.isDerived(doc._class, core.class.Account)) {
|
||||||
const account = doc as Account
|
const account = doc as Account
|
||||||
|
this.accountByEmail.set(account.email, account)
|
||||||
if (account.person !== undefined) {
|
if (account.person !== undefined) {
|
||||||
this.accountByPersonId.set(account.person, [...(this.accountByPersonId.get(account.person) ?? []), account])
|
this.accountByPersonId.set(account.person, [...(this.accountByPersonId.get(account.person) ?? []), account])
|
||||||
}
|
}
|
||||||
@ -245,6 +251,7 @@ export abstract class MemDb extends TxProcessor implements Storage {
|
|||||||
})
|
})
|
||||||
if (this.hierarchy.isDerived(doc._class, core.class.Account)) {
|
if (this.hierarchy.isDerived(doc._class, core.class.Account)) {
|
||||||
const account = doc as Account
|
const account = doc as Account
|
||||||
|
this.accountByEmail.delete(account.email)
|
||||||
if (account.person !== undefined) {
|
if (account.person !== undefined) {
|
||||||
const acc = this.accountByPersonId.get(account.person) ?? []
|
const acc = this.accountByPersonId.get(account.person) ?? []
|
||||||
this.accountByPersonId.set(
|
this.accountByPersonId.set(
|
||||||
|
@ -23,7 +23,7 @@ async function connect (token: string): Promise<Client> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getTxOperations (client: Client, token: Token, isDerived: boolean = false): Promise<TxOperations> {
|
async function getTxOperations (client: Client, token: Token, isDerived: boolean = false): Promise<TxOperations> {
|
||||||
const account = await client.findOne(core.class.Account, { email: token.email })
|
const account = client.getModel().getAccountByEmail(token.email)
|
||||||
const accountId = account?._id ?? core.account.System
|
const accountId = account?._id ?? core.account.System
|
||||||
|
|
||||||
return new TxOperations(client, accountId, isDerived)
|
return new TxOperations(client, accountId, isDerived)
|
||||||
|
@ -140,7 +140,7 @@ export function getUser (modelDb: ModelDb, userEmail: string | undefined, admin?
|
|||||||
if (userEmail === undefined) {
|
if (userEmail === undefined) {
|
||||||
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
|
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
|
||||||
}
|
}
|
||||||
const account = modelDb.findAllSync(core.class.Account, { email: userEmail })[0]
|
const account = modelDb.getAccountByEmail(userEmail)
|
||||||
if (account === undefined) {
|
if (account === undefined) {
|
||||||
if (userEmail === systemAccountEmail || admin === true) {
|
if (userEmail === systemAccountEmail || admin === true) {
|
||||||
return {
|
return {
|
||||||
@ -181,7 +181,7 @@ export class SessionDataImpl implements SessionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getAccount (account: Ref<Account>): Account | undefined {
|
getAccount (account: Ref<Account>): Account | undefined {
|
||||||
return this.modelDb.findAllSync(core.class.Account, { _id: account })[0]
|
return this.modelDb.findObject(account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,12 +113,10 @@ export class ClientSession implements Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getAccount (ctx: ClientSessionCtx): Promise<void> {
|
async getAccount (ctx: ClientSessionCtx): Promise<void> {
|
||||||
const account = this._pipeline.context.modelDb.findAllSync(core.class.Account, { email: this.token.email })
|
const account = this._pipeline.context.modelDb.getAccountByEmail(this.token.email)
|
||||||
if (account.length === 0 && this.token.extra?.admin === 'true') {
|
if (account === undefined && this.token.extra?.admin === 'true') {
|
||||||
const systemAccount = this._pipeline.context.modelDb.findAllSync(core.class.Account, {
|
const systemAccount = this._pipeline.context.modelDb.findObject(this.token.email as Ref<Account>)
|
||||||
_id: this.token.email as Ref<Account>
|
if (systemAccount === undefined) {
|
||||||
})
|
|
||||||
if (systemAccount.length === 0) {
|
|
||||||
// Generate account for admin user
|
// Generate account for admin user
|
||||||
const factory = new TxFactory(core.account.System)
|
const factory = new TxFactory(core.account.System)
|
||||||
const email = `system:${this.token.email}`
|
const email = `system:${this.token.email}`
|
||||||
@ -152,11 +150,11 @@ export class ClientSession implements Session {
|
|||||||
await ctx.sendResponse(acc)
|
await ctx.sendResponse(acc)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
await ctx.sendResponse(systemAccount[0])
|
await ctx.sendResponse(systemAccount)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await ctx.sendResponse(account[0])
|
await ctx.sendResponse(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
findAllRaw<T extends Doc>(
|
findAllRaw<T extends Doc>(
|
||||||
|
@ -629,15 +629,7 @@ class TSessionManager implements SessionManager {
|
|||||||
workspaceId: WorkspaceId
|
workspaceId: WorkspaceId
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const user = (
|
const user = session.pipeline().context.modelDb.getAccountByEmail(session.getUser())
|
||||||
await session.pipeline().context.modelDb.findAll(
|
|
||||||
core.class.Account,
|
|
||||||
{
|
|
||||||
email: session.getUser()
|
|
||||||
},
|
|
||||||
{ limit: 1 }
|
|
||||||
)
|
|
||||||
)[0]
|
|
||||||
if (user === undefined) return
|
if (user === undefined) return
|
||||||
|
|
||||||
const clientCtx: ClientSessionCtx = {
|
const clientCtx: ClientSessionCtx = {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import calendar, { Event, ExternalCalendar } from '@hcengineering/calendar'
|
import calendar, { Event, ExternalCalendar } from '@hcengineering/calendar'
|
||||||
import contact, { Channel, Contact, type Employee, type PersonAccount } from '@hcengineering/contact'
|
import contact, { Channel, Contact, type Employee, type PersonAccount } from '@hcengineering/contact'
|
||||||
import core, {
|
import core, {
|
||||||
|
TxOperations,
|
||||||
TxProcessor,
|
TxProcessor,
|
||||||
toIdMap,
|
toIdMap,
|
||||||
type Account,
|
type Account,
|
||||||
@ -25,17 +26,16 @@ import core, {
|
|||||||
type Tx,
|
type Tx,
|
||||||
type TxCreateDoc,
|
type TxCreateDoc,
|
||||||
type TxRemoveDoc,
|
type TxRemoveDoc,
|
||||||
type TxUpdateDoc,
|
type TxUpdateDoc
|
||||||
TxOperations
|
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
|
import { generateToken } from '@hcengineering/server-token'
|
||||||
import setting, { Integration } from '@hcengineering/setting'
|
import setting, { Integration } from '@hcengineering/setting'
|
||||||
import { Collection, type Db } from 'mongodb'
|
import { Collection, type Db } from 'mongodb'
|
||||||
import { CalendarClient } from './calendar'
|
import { CalendarClient } from './calendar'
|
||||||
|
import { CalendarController } from './calendarController'
|
||||||
import { getClient } from './client'
|
import { getClient } from './client'
|
||||||
import config from './config'
|
import config from './config'
|
||||||
import { SyncHistory, type ProjectCredentials, type User } from './types'
|
import { SyncHistory, type ProjectCredentials, type User } from './types'
|
||||||
import { CalendarController } from './calendarController'
|
|
||||||
import { generateToken } from '@hcengineering/server-token'
|
|
||||||
|
|
||||||
export class WorkspaceClient {
|
export class WorkspaceClient {
|
||||||
private readonly txHandlers: ((...tx: Tx[]) => Promise<void>)[] = []
|
private readonly txHandlers: ((...tx: Tx[]) => Promise<void>)[] = []
|
||||||
@ -109,9 +109,7 @@ export class WorkspaceClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getUserId (email: string): Promise<Ref<Account>> {
|
async getUserId (email: string): Promise<Ref<Account>> {
|
||||||
const user = await this.client.findOne(core.class.Account, {
|
const user = this.client.getModel().getAccountByEmail(email)
|
||||||
email
|
|
||||||
})
|
|
||||||
if (user === undefined) {
|
if (user === undefined) {
|
||||||
throw new Error('User not found')
|
throw new Error('User not found')
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ export class PlatformWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We need to re-bind previously created github:login account to a proper person.
|
// We need to re-bind previously created github:login account to a proper person.
|
||||||
const account = (await client.findOne(core.class.Account, { _id: payload.accountId })) as PersonAccount
|
const account = client.getModel().getObject(payload.accountId) as PersonAccount
|
||||||
const person = (await client.findOne(contact.class.Person, { _id: account.person })) as Person
|
const person = (await client.findOne(contact.class.Person, { _id: account.person })) as Person
|
||||||
if (person !== undefined) {
|
if (person !== undefined) {
|
||||||
if (!revoke) {
|
if (!revoke) {
|
||||||
@ -424,9 +424,7 @@ export class PlatformWorker {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const githubAccount = (await client.findOne(core.class.Account, {
|
const githubAccount = client.getModel().getAccountByEmail('github:' + update.login) as PersonAccount
|
||||||
email: 'github:' + update.login
|
|
||||||
})) as PersonAccount
|
|
||||||
if (githubAccount !== undefined && githubAccount.person !== account.person) {
|
if (githubAccount !== undefined && githubAccount.person !== account.person) {
|
||||||
const dummyPerson = githubAccount.person
|
const dummyPerson = githubAccount.person
|
||||||
// To add activity entry to dummy person.
|
// To add activity entry to dummy person.
|
||||||
|
@ -19,14 +19,14 @@ import core, {
|
|||||||
type AttachedDoc,
|
type AttachedDoc,
|
||||||
type Client,
|
type Client,
|
||||||
type Doc,
|
type Doc,
|
||||||
|
MeasureContext,
|
||||||
type Ref,
|
type Ref,
|
||||||
type Tx,
|
type Tx,
|
||||||
type TxCollectionCUD,
|
type TxCollectionCUD,
|
||||||
type TxCreateDoc,
|
type TxCreateDoc,
|
||||||
TxProcessor,
|
TxProcessor,
|
||||||
type TxRemoveDoc,
|
type TxRemoveDoc,
|
||||||
type TxUpdateDoc,
|
type TxUpdateDoc
|
||||||
MeasureContext
|
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import gmailP, { type NewMessage } from '@hcengineering/gmail'
|
import gmailP, { type NewMessage } from '@hcengineering/gmail'
|
||||||
import type { StorageAdapter } from '@hcengineering/server-core'
|
import type { StorageAdapter } from '@hcengineering/server-core'
|
||||||
@ -92,9 +92,7 @@ export class WorkspaceClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getUserId (email: string): Promise<Ref<Account>> {
|
async getUserId (email: string): Promise<Ref<Account>> {
|
||||||
const user = await this.client.findOne(core.class.Account, {
|
const user = this.client.getModel().getAccountByEmail(email)
|
||||||
email
|
|
||||||
})
|
|
||||||
if (user === undefined) {
|
if (user === undefined) {
|
||||||
throw new Error('User not found')
|
throw new Error('User not found')
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ export class WorkspaceWorker {
|
|||||||
// #region Users
|
// #region Users
|
||||||
|
|
||||||
async addUser ({ email, phone, conn }: TgUser): Promise<void> {
|
async addUser ({ email, phone, conn }: TgUser): Promise<void> {
|
||||||
const user = (await this.client.findAll(core.class.Account, { email }, { limit: 1 }))[0]
|
const user = this.client.getModel().getAccountByEmail(email)
|
||||||
|
|
||||||
if (user === undefined) {
|
if (user === undefined) {
|
||||||
throw Error(`Unable to find user by email: ${email}`)
|
throw Error(`Unable to find user by email: ${email}`)
|
||||||
|
Loading…
Reference in New Issue
Block a user