diff --git a/server/core/src/pipeline.ts b/server/core/src/pipeline.ts index 5284ff127f..9afd89c5c1 100644 --- a/server/core/src/pipeline.ts +++ b/server/core/src/pipeline.ts @@ -23,16 +23,16 @@ import { MeasureContext, ModelDb, Ref, + SearchOptions, + SearchQuery, + SearchResult, ServerStorage, StorageIterator, Tx, - TxResult, - SearchQuery, - SearchOptions, - SearchResult + TxResult } from '@hcengineering/core' import { DbConfiguration, createServerStorage } from './storage' -import { BroadcastFunc, Middleware, MiddlewareCreator, Pipeline, SessionContext } from './types' +import { BroadcastFunc, HandledBroadcastFunc, Middleware, MiddlewareCreator, Pipeline, SessionContext } from './types' /** * @public @@ -44,12 +44,22 @@ export async function createPipeline ( upgrade: boolean, broadcast: BroadcastFunc ): Promise { + let broadcastHook: HandledBroadcastFunc = (): Tx[] => { + return [] + } const storage = await createServerStorage(conf, { upgrade, - broadcast + broadcast: (tx: Tx[], targets?: string[]) => { + const sendTx = broadcastHook?.(tx, targets) ?? tx + broadcast(sendTx, targets) + } }) const pipeline = PipelineImpl.create(ctx, storage, constructors, broadcast) - return await pipeline + const pipelineResult = await pipeline + broadcastHook = (tx, targets) => { + return pipelineResult.handleBroadcast(tx, targets) + } + return pipelineResult } class PipelineImpl implements Pipeline { @@ -59,6 +69,10 @@ class PipelineImpl implements Pipeline { this.modelDb = storage.modelDb } + handleBroadcast (tx: Tx[], targets?: string[]): Tx[] { + return this.head?.handleBroadcast(tx, targets) ?? tx + } + static async create ( ctx: MeasureContext, storage: ServerStorage, diff --git a/server/core/src/types.ts b/server/core/src/types.ts index 07c7a8a298..750a7dd137 100644 --- a/server/core/src/types.ts +++ b/server/core/src/types.ts @@ -64,12 +64,18 @@ export interface Middleware { options?: FindOptions ) => Promise> searchFulltext: (ctx: SessionContext, query: SearchQuery, options: SearchOptions) => Promise + + handleBroadcast: (tx: Tx[], targets?: string[]) => Tx[] } /** * @public */ export type BroadcastFunc = (tx: Tx[], targets?: string[]) => void +/** + * @public + */ +export type HandledBroadcastFunc = (tx: Tx[], targets?: string[]) => Tx[] /** * @public diff --git a/server/middleware/src/base.ts b/server/middleware/src/base.ts index f151c0cf1a..2618ef127f 100644 --- a/server/middleware/src/base.ts +++ b/server/middleware/src/base.ts @@ -20,11 +20,11 @@ import { FindOptions, FindResult, Ref, - ServerStorage, - Tx, - SearchQuery, SearchOptions, - SearchResult + SearchQuery, + SearchResult, + ServerStorage, + Tx } from '@hcengineering/core' import { Middleware, SessionContext, TxMiddlewareResult } from '@hcengineering/server-core' @@ -58,6 +58,13 @@ export abstract class BaseMiddleware { return [res[0], res[1], undefined] } + provideHandleBroadcast (tx: Tx[], targets?: string[]): Tx[] { + if (this.next !== undefined) { + return this.next.handleBroadcast(tx, targets) + } + return tx + } + protected async provideFindAll( ctx: SessionContext, _class: Ref>, diff --git a/server/middleware/src/configuration.ts b/server/middleware/src/configuration.ts index 4fb50b239a..4adcf01ca6 100644 --- a/server/middleware/src/configuration.ts +++ b/server/middleware/src/configuration.ts @@ -68,6 +68,10 @@ export class ConfigurationMiddleware extends BaseMiddleware implements Middlewar return await this.provideTx(ctx, tx) } + handleBroadcast (tx: Tx[], targets?: string[]): Tx[] { + return this.provideHandleBroadcast(tx, targets) + } + override async findAll( ctx: SessionContext, _class: Ref>, diff --git a/server/middleware/src/modified.ts b/server/middleware/src/modified.ts index c5b0f0973f..37d55163f9 100644 --- a/server/middleware/src/modified.ts +++ b/server/middleware/src/modified.ts @@ -34,6 +34,10 @@ export class ModifiedMiddleware extends BaseMiddleware implements Middleware { return new ModifiedMiddleware(storage, next) } + handleBroadcast (tx: Tx[], targets?: string[]): Tx[] { + return this.provideHandleBroadcast(tx, targets) + } + async tx (ctx: SessionContext, tx: Tx): Promise { if (tx.modifiedBy !== core.account.System && ctx.userEmail !== systemAccountEmail) { tx.modifiedOn = Date.now() diff --git a/server/middleware/src/private.ts b/server/middleware/src/private.ts index 0314b6fe00..cad7576d3e 100644 --- a/server/middleware/src/private.ts +++ b/server/middleware/src/private.ts @@ -75,6 +75,10 @@ export class PrivateMiddleware extends BaseMiddleware implements Middleware { return [res[0], res[1], mergeTargets(target, res[2])] } + handleBroadcast (tx: Tx[], targets?: string[]): Tx[] { + return this.provideHandleBroadcast(tx, targets) + } + override async findAll( ctx: SessionContext, _class: Ref>, diff --git a/server/middleware/src/queryJoin.ts b/server/middleware/src/queryJoin.ts index 9a51ea4624..5998d75f95 100644 --- a/server/middleware/src/queryJoin.ts +++ b/server/middleware/src/queryJoin.ts @@ -60,6 +60,10 @@ export class QueryJoinMiddleware extends BaseMiddleware implements Middleware { return await this.provideTx(ctx, tx) } + handleBroadcast (tx: Tx[], targets?: string[]): Tx[] { + return this.provideHandleBroadcast(tx, targets) + } + override async findAll( ctx: SessionContext, _class: Ref>, diff --git a/server/middleware/src/spaceSecurity.ts b/server/middleware/src/spaceSecurity.ts index d56692d144..ec330d1e1e 100644 --- a/server/middleware/src/spaceSecurity.ts +++ b/server/middleware/src/spaceSecurity.ts @@ -398,6 +398,15 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar return [res[0], res[1], mergeTargets(targets, res[2])] } + handleBroadcast (tx: Tx[], targets?: string[]): Tx[] { + for (const t of tx) { + if (this.storage.hierarchy.isDerived(t._class, core.class.TxCUD)) { + this.processTxSpaceDomain(t as TxCUD) + } + } + return this.provideHandleBroadcast(tx, targets) + } + private getAllAllowedSpaces (account: Account): Ref[] { let userSpaces: Ref[] = [] try {