From b4089c47d433bca6c5f26f0eed1113e4993ebedc Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Sat, 6 Jan 2024 22:45:58 +0600 Subject: [PATCH] UBERF-4846 (#4311) Signed-off-by: Denis Bykhov --- server/account/src/index.ts | 80 ++++++++++++++++++++++++++++++++++--- server/backup/src/index.ts | 6 --- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/server/account/src/index.ts b/server/account/src/index.ts index f0f35204d2..b32c4227e6 100644 --- a/server/account/src/index.ts +++ b/server/account/src/index.ts @@ -20,7 +20,8 @@ import contact, { combineName, Employee, getAvatarColorForId, - Person + Person, + PersonAccount } from '@hcengineering/contact' import core, { AccountRole, @@ -693,7 +694,9 @@ export const createUserWorkspace = // Update last workspace time. await db.collection(ACCOUNT_COLLECTION).updateOne({ _id: info._id }, { $set: { lastWorkspace: Date.now() } }) - await assignWorkspace(db, productId, email, workspace) + const initWS = getMetadata(toolPlugin.metadata.InitWorkspace) + const shouldUpdateAccount = initWS !== undefined && (await getWorkspace(db, productId, initWS)) !== null + await assignWorkspace(db, productId, email, workspace, shouldUpdateAccount) await setRole(email, workspace, productId, AccountRole.Owner) const result = { endpoint: getEndpoint(), @@ -804,7 +807,13 @@ export async function setRole (_email: string, workspace: string, productId: str /** * @public */ -export async function assignWorkspace (db: Db, productId: string, _email: string, workspace: string): Promise { +export async function assignWorkspace ( + db: Db, + productId: string, + _email: string, + workspace: string, + shouldReplaceAccount: boolean = false +): Promise { const email = cleanEmail(_email) const initWS = getMetadata(toolPlugin.metadata.InitWorkspace) if (initWS !== undefined && initWS === workspace) { @@ -813,7 +822,7 @@ export async function assignWorkspace (db: Db, productId: string, _email: string const { workspaceId, accountId } = await getWorkspaceAndAccount(db, productId, email, workspace) const account = await db.collection(ACCOUNT_COLLECTION).findOne({ _id: accountId }) - if (account !== null) await createPersonAccount(account, productId, workspace) + if (account !== null) await createPersonAccount(account, productId, workspace, shouldReplaceAccount) // Add account into workspace. await db.collection(WORKSPACE_COLLECTION).updateOne({ _id: workspaceId }, { $addToSet: { accounts: accountId } }) @@ -848,13 +857,74 @@ async function createEmployee (ops: TxOperations, name: string, _email: string): return id } -async function createPersonAccount (account: Account, productId: string, workspace: string): Promise { +async function replaceCurrentAccount ( + ops: TxOperations, + account: Account, + currentAccount: PersonAccount, + name: string +): Promise { + await ops.update(currentAccount, { email: account.email }) + const employee = await ops.findOne(contact.mixin.Employee, { _id: currentAccount.person as Ref }) + if (employee === undefined) { + // Employee was deleted, let's restore it. + const employeeId = await createEmployee(ops, name, account.email) + + await ops.updateDoc(contact.class.PersonAccount, currentAccount.space, currentAccount._id, { + person: employeeId + }) + } else { + const email = cleanEmail(account.email) + const gravatarId = buildGravatarId(email) + const hasGravatar = await checkHasGravatar(gravatarId) + + await ops.update(employee, { + name, + avatar: hasGravatar + ? `${AvatarType.GRAVATAR}://${gravatarId}` + : `${AvatarType.COLOR}://${getAvatarColorForId(employee._id)}`, + ...(employee.active ? {} : { active: true }) + }) + const currentChannel = await ops.findOne(contact.class.Channel, { + attachedTo: employee._id, + provider: contact.channelProvider.Email + }) + if (currentChannel === undefined) { + await ops.addCollection( + contact.class.Channel, + contact.space.Contacts, + employee._id, + contact.mixin.Employee, + 'channels', + { + provider: contact.channelProvider.Email, + value: email + } + ) + } else if (currentChannel.value !== email) { + await ops.update(currentChannel, { value: email }) + } + } +} + +async function createPersonAccount ( + account: Account, + productId: string, + workspace: string, + shouldReplaceCurrent: boolean = false +): Promise { const connection = await connect(getTransactor(), getWorkspaceId(workspace, productId)) try { const ops = new TxOperations(connection, core.account.System) const name = combineName(account.first, account.last) // Check if EmployeeAccoun is not exists + if (shouldReplaceCurrent) { + const currentAccount = await ops.findOne(contact.class.PersonAccount, {}) + if (currentAccount !== undefined) { + await replaceCurrentAccount(ops, account, currentAccount, name) + return + } + } const existingAccount = await ops.findOne(contact.class.PersonAccount, { email: account.email }) if (existingAccount === undefined) { const employee = await createEmployee(ops, name, account.email) diff --git a/server/backup/src/index.ts b/server/backup/src/index.ts index e016566dad..b8acada019 100644 --- a/server/backup/src/index.ts +++ b/server/backup/src/index.ts @@ -283,14 +283,10 @@ export async function cloneWorkspace ( if (collectionCud) { return { ...p, - createdBy: core.account.System, - modifiedBy: core.account.System, modifiedOn: Date.now(), createdOn: Date.now(), tx: { ...(p as TxCollectionCUD).tx, - createdBy: core.account.System, - modifiedBy: core.account.System, modifiedOn: Date.now(), createdOn: Date.now() } @@ -298,8 +294,6 @@ export async function cloneWorkspace ( } else { return { ...p, - createdBy: core.account.System, - modifiedBy: core.account.System, modifiedOn: Date.now(), createdOn: Date.now() }