UBERF-11414: Integrations (#9610)

* UBERF-11414: Use common integration kind

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Allow multiple gmail

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Merge with develop

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Refactor integration kinds

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Add integrations package

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Integrations

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Integration state and config

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Add integration events

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Refresh integration states

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Rename to integration-client

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Add filter button

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Add translations for filters

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Synced channels count

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Actions

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Add isLoading for connect

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Create connection and integration

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Use social id from hulygram

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Remove old integrations

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Gmail state

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Gmail state and disconnect all handler

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Add tests

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Formatting

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Gmail sync state

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix rush check

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix gmail tests

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix calendar actions and config

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Calendar state

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Access config

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Github integration state

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix svelte errors

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix formatting

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix typos

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix validate

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Fix translations

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-11414: Retry on network issues

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
Artyom Savchenko
2025-08-04 15:14:06 +07:00
committed by GitHub
parent 39c40093e0
commit 7e92c12073
175 changed files with 6391 additions and 875 deletions
+19 -13
View File
@@ -26,7 +26,13 @@ import core, {
type PersonUuid,
type Ref
} from '@hcengineering/core'
import github, { GithubAuthentication, githubId, makeQuery, type GithubIntegration } from '@hcengineering/github'
import github, {
GithubAuthentication,
githubId,
makeQuery,
type GithubIntegration,
githubIntegrationKind
} from '@hcengineering/github'
import { buildStorageFromConfig, storageConfigFromEnv } from '@hcengineering/server-storage'
import { generateToken } from '@hcengineering/server-token'
import tracker from '@hcengineering/tracker'
@@ -119,7 +125,7 @@ export class PlatformWorker {
const sysToken = generateToken(systemAccountUuid, undefined, { service: 'github' })
const accountsClient = getAccountClient(config.AccountsURL, sysToken)
const allIntegrations = await accountsClient.listIntegrations({ kind: 'github' })
const allIntegrations = await accountsClient.listIntegrations({ kind: githubIntegrationKind })
this.integrations = []
@@ -140,7 +146,7 @@ export class PlatformWorker {
workspace: i.workspaceUuid
})
await accountsClient.deleteIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: i.workspaceUuid,
socialId: i.socialId
})
@@ -162,14 +168,14 @@ export class PlatformWorker {
})
if (has.length > 0) {
await accountsClient.updateIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: integr.workspace,
socialId: integr.accountId,
data: { installationId: has } satisfies IntegrationDataValue
})
} else {
await accountsClient.deleteIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: integr.workspace,
socialId: integr.accountId
})
@@ -268,13 +274,13 @@ export class PlatformWorker {
if (has.length > 0) {
oldInstallation.installationId = has
await accountsClient.updateIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: oldWorkspace,
socialId: oldInstallation.accountId
})
} else {
await accountsClient.deleteIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: oldWorkspace,
socialId: oldInstallation.accountId
})
@@ -286,14 +292,14 @@ export class PlatformWorker {
if (existingRecord !== undefined) {
existingRecord.installationId.push(installationId)
await accountsClient.updateIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: workspace,
socialId: accountId,
data: { installationId: existingRecord.installationId } satisfies IntegrationDataValue
})
} else {
await accountsClient.createIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: workspace,
socialId: accountId,
data: { installationId } satisfies IntegrationDataValue
@@ -340,7 +346,7 @@ export class PlatformWorker {
if (existing !== undefined) {
existing.installationId.push(installationId)
await accountsClient.updateIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: existing.workspace,
socialId: existing.accountId,
data: { installationId: existing.installationId } satisfies IntegrationDataValue
@@ -352,7 +358,7 @@ export class PlatformWorker {
accountId
}
await accountsClient.createIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: record.workspace,
socialId: record.accountId,
data: { installationId: record.installationId }
@@ -909,7 +915,7 @@ export class PlatformWorker {
const has = intgr.installationId.filter((it) => it !== installId)
if (has.length > 0) {
await sysAccountClient.updateIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: intgr.workspace,
socialId: intgr.accountId,
data: { installationId: has } satisfies IntegrationDataValue
@@ -917,7 +923,7 @@ export class PlatformWorker {
} else {
intgr.installationId = []
await sysAccountClient.deleteIntegration({
kind: 'github',
kind: githubIntegrationKind,
workspaceUuid: intgr.workspace,
socialId: intgr.accountId
})
+12 -8
View File
@@ -2,6 +2,7 @@ import type { AccountClient, IntegrationSecret } from '@hcengineering/account-cl
import core, { systemAccountUuid, type MeasureContext, type PersonId, type WorkspaceUuid } from '@hcengineering/core'
import { getAccountClient } from '@hcengineering/server-client'
import { generateToken } from '@hcengineering/server-token'
import { githubUserIntegrationKind } from '@hcengineering/github'
import type { GithubUserRecord } from './types'
export class UserManager {
@@ -20,7 +21,7 @@ export class UserManager {
if (res !== undefined) {
return res
}
const secrets = await this.accountClient.listIntegrationsSecrets({ kind: 'github-user', key: login })
const secrets = await this.accountClient.listIntegrationsSecrets({ kind: githubUserIntegrationKind, key: login })
if (secrets.length === 0) {
return
}
@@ -63,7 +64,10 @@ export class UserManager {
// Ignore failed refs
return
}
const secrets = await this.accountClient.listIntegrationsSecrets({ kind: 'github-user', socialId: ref })
const secrets = await this.accountClient.listIntegrationsSecrets({
kind: githubUserIntegrationKind,
socialId: ref
})
if (secrets.length === 0) {
return
}
@@ -90,14 +94,14 @@ export class UserManager {
// Need to check if user integeration exists.
const existing = await this.accountClient.getIntegration({
kind: 'github-user',
kind: githubUserIntegrationKind,
workspaceUuid: null,
socialId: dta.account
})
if (existing == null) {
await this.accountClient.createIntegration({
kind: 'github-user',
kind: githubUserIntegrationKind,
workspaceUuid: null,
socialId: dta.account,
data: {
@@ -108,7 +112,7 @@ export class UserManager {
const exists = await this.accountClient.getIntegrationSecret({
key: dta._id,
kind: 'github-user',
kind: githubUserIntegrationKind,
socialId: dta.account,
workspaceUuid: null
})
@@ -116,7 +120,7 @@ export class UserManager {
if (exists !== null) {
await this.accountClient.updateIntegrationSecret({
key: dta._id,
kind: 'github-user',
kind: githubUserIntegrationKind,
socialId: dta.account,
secret: JSON.stringify(dta),
workspaceUuid: null
@@ -124,7 +128,7 @@ export class UserManager {
} else {
await this.accountClient.addIntegrationSecret({
key: dta._id,
kind: 'github-user',
kind: githubUserIntegrationKind,
socialId: dta.account,
secret: JSON.stringify(dta),
workspaceUuid: null
@@ -140,7 +144,7 @@ export class UserManager {
this.userCache.clear()
this.refUserCache.clear()
const secerts = await this.accountClient.listIntegrationsSecrets({ kind: 'github-user', key: login })
const secerts = await this.accountClient.listIntegrationsSecrets({ kind: githubUserIntegrationKind, key: login })
for (const s of secerts) {
await this.accountClient.deleteIntegrationSecret(s)
}