mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-10 03:37:43 +02:00
Qfix: adding/deleting social ids (#9466)
Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
This commit is contained in:
@@ -33,7 +33,8 @@ import {
|
||||
Ref,
|
||||
SocialId,
|
||||
toIdMap,
|
||||
TxFactory
|
||||
TxFactory,
|
||||
DocumentUpdate
|
||||
} from '@hcengineering/core'
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import { ColorDefinition } from '@hcengineering/ui'
|
||||
@@ -459,7 +460,7 @@ export async function ensureEmployeeForPerson (
|
||||
for (const socialId of socialIds) {
|
||||
const existing = existingIdentifiers.get(socialId._id as SocialIdentityRef)
|
||||
|
||||
if (existing === undefined) {
|
||||
if (existing == null) {
|
||||
await ctx.with('create-social-identity', {}, async () => {
|
||||
if (personRef === undefined) {
|
||||
// something went wrong
|
||||
@@ -491,41 +492,45 @@ export async function ensureEmployeeForPerson (
|
||||
await client.tx(createSocialIdTx)
|
||||
})
|
||||
} else {
|
||||
// This social identity must be attached to the correct person. If it's not the case, something is wrong.
|
||||
// personRef must be readonly after creation and must NEVER be changed.
|
||||
if (existing.attachedTo !== personRef) {
|
||||
throw new Error('Social identity is attached to the wrong person')
|
||||
// If not confirmed locally can be attached to a different person (persons merge scenario)
|
||||
// Confirmed social identity should not be attached to a different person for now
|
||||
// It will change with accounts merge function
|
||||
if (existing.verifiedOn != null && existing.attachedTo !== personRef) {
|
||||
throw new Error('Confirmed social identity is attached to the wrong person')
|
||||
}
|
||||
|
||||
// Check and update if needed. It can:
|
||||
// 1. Become verified (changes verifiedOn)
|
||||
if (existing.verifiedOn == null) {
|
||||
const updateSocialIdentityTx = txFactory.createTxUpdateDoc(
|
||||
contact.class.SocialIdentity,
|
||||
contact.space.Contacts,
|
||||
existing._id,
|
||||
{
|
||||
verifiedOn: socialId.verifiedOn,
|
||||
value: socialId.value,
|
||||
key: socialId.key,
|
||||
isDeleted: socialId.isDeleted
|
||||
}
|
||||
)
|
||||
// 1. Become verified (maybe with persons merge) (changes verifiedOn, attachedTo)
|
||||
const sidUpdate: DocumentUpdate<SocialIdentity> = {}
|
||||
let needUpdate = false
|
||||
|
||||
await client.tx(updateSocialIdentityTx)
|
||||
// become verified
|
||||
if (existing.verifiedOn == null) {
|
||||
sidUpdate.verifiedOn = socialId.verifiedOn
|
||||
needUpdate = true
|
||||
}
|
||||
|
||||
// 2. Become deleted (changes value/key/isDeleted)
|
||||
// merged from another person
|
||||
if (existing.attachedTo !== personRef) {
|
||||
sidUpdate.attachedTo = personRef
|
||||
// Bump collection in Person?
|
||||
needUpdate = true
|
||||
}
|
||||
|
||||
// become deleted
|
||||
if (existing.isDeleted !== socialId.isDeleted && socialId.isDeleted === true) {
|
||||
sidUpdate.value = socialId.value
|
||||
sidUpdate.key = socialId.key
|
||||
sidUpdate.isDeleted = socialId.isDeleted
|
||||
needUpdate = true
|
||||
}
|
||||
|
||||
if (needUpdate) {
|
||||
const updateSocialIdentityTx = txFactory.createTxUpdateDoc(
|
||||
contact.class.SocialIdentity,
|
||||
contact.space.Contacts,
|
||||
existing._id,
|
||||
{
|
||||
value: socialId.value,
|
||||
key: socialId.key,
|
||||
isDeleted: socialId.isDeleted
|
||||
}
|
||||
sidUpdate
|
||||
)
|
||||
|
||||
await client.tx(updateSocialIdentityTx)
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import contact, { SocialIdentityProvider } from '@hcengineering/contact'
|
||||
import contact, { getCurrentEmployee, SocialIdentityProvider, SocialIdentityRef } from '@hcengineering/contact'
|
||||
import { EditBox, Label, Button, CodeForm, TimeLeft, Status as StatusControl } from '@hcengineering/ui'
|
||||
import { OtpInfo } from '@hcengineering/account-client'
|
||||
import { getCurrentAccount, setCurrentAccount, SocialId, Timestamp } from '@hcengineering/core'
|
||||
import { buildSocialIdString, getCurrentAccount, setCurrentAccount, SocialId, Timestamp } from '@hcengineering/core'
|
||||
import { OK, PlatformError, Severity, Status, unknownError } from '@hcengineering/platform'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
|
||||
import AddSocialId from './AddSocialId.svelte'
|
||||
import setting from '../../plugin'
|
||||
@@ -31,6 +32,7 @@
|
||||
let otpInfo: OtpInfo | null = null
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const accountClient = getAccountClient()
|
||||
const codeFields = [
|
||||
{ id: 'code-1', name: 'code-1', optional: false },
|
||||
@@ -89,6 +91,7 @@
|
||||
|
||||
try {
|
||||
const newSocialIdLoginInfo = await accountClient.validateOtp(email, code, undefined, 'verify')
|
||||
const currPerson = getCurrentEmployee()
|
||||
const currAcc = getCurrentAccount()
|
||||
const socialIds = await accountClient.getSocialIds()
|
||||
|
||||
@@ -98,6 +101,36 @@
|
||||
return
|
||||
}
|
||||
|
||||
// Create/update new social identity in the workspace
|
||||
const existing = await client.findOne(contact.class.SocialIdentity, {
|
||||
_id: newSocialIdLoginInfo.socialId as SocialIdentityRef
|
||||
})
|
||||
if (existing != null) {
|
||||
// It can only exist if it were attached to an existing person and now this person was merged into the current account
|
||||
if (existing.attachedTo !== currPerson) {
|
||||
await client.updateDoc(contact.class.SocialIdentity, contact.space.Contacts, existing._id, {
|
||||
attachedTo: currPerson,
|
||||
verifiedOn: newSocialId.verifiedOn
|
||||
})
|
||||
}
|
||||
} else {
|
||||
await client.addCollection(
|
||||
contact.class.SocialIdentity,
|
||||
contact.space.Contacts,
|
||||
currPerson,
|
||||
contact.class.Person,
|
||||
'socialIds',
|
||||
{
|
||||
type: newSocialId.type,
|
||||
value: newSocialId.value,
|
||||
key: buildSocialIdString(newSocialId), // TODO: fill it in trigger or on DB level as stored calculated column or smth?
|
||||
verifiedOn: newSocialId.verifiedOn,
|
||||
isDeleted: newSocialId.isDeleted
|
||||
},
|
||||
newSocialId._id as SocialIdentityRef
|
||||
)
|
||||
}
|
||||
|
||||
setCurrentAccount({
|
||||
...currAcc,
|
||||
fullSocialIds: socialIds,
|
||||
|
||||
@@ -44,7 +44,11 @@
|
||||
|
||||
async function doRelease (): Promise<void> {
|
||||
try {
|
||||
const currSocialIds = currAcc.fullSocialIds
|
||||
// Important to always get current account in the callback to avoid race conditions
|
||||
// with the account from the reactive variable
|
||||
// W/o it it was bringing back previously deleted social id if two are deleted in a row
|
||||
const currentAccount = getCurrentAccount()
|
||||
const currSocialIds = currentAccount.fullSocialIds
|
||||
|
||||
const deletedSocialId = await accountClient.releaseSocialId(undefined, socialId.type, socialId.value, true)
|
||||
|
||||
@@ -65,12 +69,14 @@
|
||||
}
|
||||
const newPrimarySocialId = pickPrimarySocialId(newSocialIds)._id
|
||||
|
||||
setCurrentAccount({
|
||||
...currAcc,
|
||||
// Don't need to update social ids because deleted social id retains its' _id
|
||||
const updatedAccount = {
|
||||
...currentAccount,
|
||||
fullSocialIds: newSocialIds,
|
||||
primarySocialId: newPrimarySocialId
|
||||
})
|
||||
currAcc = getCurrentAccount()
|
||||
}
|
||||
setCurrentAccount(updatedAccount)
|
||||
currAcc = updatedAccount
|
||||
dispatch('released')
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
@@ -108,7 +114,7 @@
|
||||
<div class="icon"><Icon size="full" {icon} /></div>
|
||||
|
||||
<div class="flex-col flex-gap-0-5">
|
||||
<div>{socialId.value}</div>
|
||||
<div>{socialId.displayValue ?? socialId.value}</div>
|
||||
<div class="type"><Label label={socialIdProvider.label} /></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
: loginSocialTypes.includes(socialId.type)
|
||||
? !onlyLogin
|
||||
: true}
|
||||
{#if socialIdProvider}
|
||||
{#if socialIdProvider != null && socialId.type !== SocialIdType.HULY}
|
||||
<div class="item">
|
||||
<SocialIdPresenter {socialId} {socialIdProvider} {canRelease} on:released={handleAccountUpdated} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user