mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-09 09:20:54 +00:00
Add notifications middleware to do not send updates for all users (#6714)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
parent
f1da8ff9b1
commit
0da0d6e80a
@ -27,7 +27,6 @@ import {
|
|||||||
type Data,
|
type Data,
|
||||||
type Doc,
|
type Doc,
|
||||||
type DocumentQuery,
|
type DocumentQuery,
|
||||||
type Domain,
|
|
||||||
type IndexingConfiguration,
|
type IndexingConfiguration,
|
||||||
type Markup,
|
type Markup,
|
||||||
type Ref,
|
type Ref,
|
||||||
@ -56,6 +55,9 @@ import view, { createAction, template } from '@hcengineering/model-view'
|
|||||||
import workbench from '@hcengineering/model-workbench'
|
import workbench from '@hcengineering/model-workbench'
|
||||||
import {
|
import {
|
||||||
notificationId,
|
notificationId,
|
||||||
|
DOMAIN_USER_NOTIFY,
|
||||||
|
DOMAIN_NOTIFICATION,
|
||||||
|
DOMAIN_DOC_NOTIFY,
|
||||||
type ActivityInboxNotification,
|
type ActivityInboxNotification,
|
||||||
type ActivityNotificationViewlet,
|
type ActivityNotificationViewlet,
|
||||||
type BaseNotificationType,
|
type BaseNotificationType,
|
||||||
@ -86,16 +88,10 @@ import { type AnyComponent, type Location } from '@hcengineering/ui/src/types'
|
|||||||
|
|
||||||
import notification from './plugin'
|
import notification from './plugin'
|
||||||
|
|
||||||
export { notificationId } from '@hcengineering/notification'
|
export { notificationId, DOMAIN_USER_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_DOC_NOTIFY } from '@hcengineering/notification'
|
||||||
export { notificationOperation } from './migration'
|
export { notificationOperation } from './migration'
|
||||||
export { notification as default }
|
export { notification as default }
|
||||||
|
|
||||||
export const DOMAIN_NOTIFICATION = 'notification' as Domain
|
|
||||||
|
|
||||||
export const DOMAIN_DOC_NOTIFY = 'notification-dnc' as Domain
|
|
||||||
|
|
||||||
export const DOMAIN_USER_NOTIFY = 'notification-user' as Domain
|
|
||||||
|
|
||||||
@Model(notification.class.BrowserNotification, core.class.Doc, DOMAIN_USER_NOTIFY)
|
@Model(notification.class.BrowserNotification, core.class.Doc, DOMAIN_USER_NOTIFY)
|
||||||
export class TBrowserNotification extends TDoc implements BrowserNotification {
|
export class TBrowserNotification extends TDoc implements BrowserNotification {
|
||||||
senderId?: Ref<Account> | undefined
|
senderId?: Ref<Account> | undefined
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
Class,
|
Class,
|
||||||
Doc,
|
Doc,
|
||||||
DocumentQuery,
|
DocumentQuery,
|
||||||
|
type Domain,
|
||||||
IdMap,
|
IdMap,
|
||||||
Markup,
|
Markup,
|
||||||
Mixin,
|
Mixin,
|
||||||
@ -42,6 +43,10 @@ import { Readable, Writable } from './types'
|
|||||||
|
|
||||||
export * from './types'
|
export * from './types'
|
||||||
|
|
||||||
|
export const DOMAIN_NOTIFICATION = 'notification' as Domain
|
||||||
|
export const DOMAIN_DOC_NOTIFY = 'notification-dnc' as Domain
|
||||||
|
export const DOMAIN_USER_NOTIFY = 'notification-user' as Domain
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +31,7 @@ import type { TriggerControl, TriggerFunc } from '@hcengineering/server-core'
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export const serverNotificationId = 'server-notification' as Plugin
|
export const serverNotificationId = 'server-notification' as Plugin
|
||||||
|
export { DOMAIN_USER_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_DOC_NOTIFY } from '@hcengineering/notification'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
"@hcengineering/platform": "^0.6.11",
|
"@hcengineering/platform": "^0.6.11",
|
||||||
"@hcengineering/server-core": "^0.6.1",
|
"@hcengineering/server-core": "^0.6.1",
|
||||||
"@hcengineering/server-preference": "^0.6.0",
|
"@hcengineering/server-preference": "^0.6.0",
|
||||||
|
"@hcengineering/server-notification": "^0.6.1",
|
||||||
"@hcengineering/query": "^0.6.12",
|
"@hcengineering/query": "^0.6.12",
|
||||||
"fast-equals": "^5.0.1"
|
"fast-equals": "^5.0.1"
|
||||||
}
|
}
|
||||||
|
@ -33,3 +33,4 @@ export * from './spacePermissions'
|
|||||||
export * from './spaceSecurity'
|
export * from './spaceSecurity'
|
||||||
export * from './triggers'
|
export * from './triggers'
|
||||||
export * from './txPush'
|
export * from './txPush'
|
||||||
|
export * from './notifications'
|
||||||
|
97
server/middleware/src/notifications.ts
Normal file
97
server/middleware/src/notifications.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//
|
||||||
|
// Copyright © 2024 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License. You may
|
||||||
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
//
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import core, {
|
||||||
|
Doc,
|
||||||
|
MeasureContext,
|
||||||
|
Tx,
|
||||||
|
TxCUD,
|
||||||
|
TxProcessor,
|
||||||
|
systemAccountEmail,
|
||||||
|
type SessionData,
|
||||||
|
TxApplyIf
|
||||||
|
} from '@hcengineering/core'
|
||||||
|
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
|
||||||
|
import { BaseMiddleware, Middleware, TxMiddlewareResult, type PipelineContext } from '@hcengineering/server-core'
|
||||||
|
import { DOMAIN_USER_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_DOC_NOTIFY } from '@hcengineering/server-notification'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export class NotificationsMiddleware extends BaseMiddleware implements Middleware {
|
||||||
|
private readonly targetDomains = [DOMAIN_USER_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_DOC_NOTIFY]
|
||||||
|
|
||||||
|
private constructor (context: PipelineContext, next?: Middleware) {
|
||||||
|
super(context, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async create (
|
||||||
|
ctx: MeasureContext,
|
||||||
|
context: PipelineContext,
|
||||||
|
next: Middleware | undefined
|
||||||
|
): Promise<NotificationsMiddleware> {
|
||||||
|
return new NotificationsMiddleware(context, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
isTargetDomain (tx: Tx): boolean {
|
||||||
|
if (TxProcessor.isExtendsCUD(tx._class)) {
|
||||||
|
const txCUD = tx as TxCUD<Doc>
|
||||||
|
const domain = this.context.hierarchy.getDomain(txCUD.objectClass)
|
||||||
|
return this.targetDomains.includes(domain)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
processTx (ctx: MeasureContext<SessionData>, tx: Tx): void {
|
||||||
|
let target: string[] | undefined
|
||||||
|
if (this.isTargetDomain(tx)) {
|
||||||
|
const account = ctx.contextData.account._id
|
||||||
|
if (account !== tx.modifiedBy && account !== core.account.System) {
|
||||||
|
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
|
||||||
|
}
|
||||||
|
const modifiedByAccount = ctx.contextData.getAccount(tx.modifiedBy)
|
||||||
|
target = [ctx.contextData.userEmail, systemAccountEmail]
|
||||||
|
if (modifiedByAccount !== undefined && !target.includes(modifiedByAccount.email)) {
|
||||||
|
target.push(modifiedByAccount.email)
|
||||||
|
}
|
||||||
|
ctx.contextData.broadcast.targets['checkDomain' + account] = (tx) => {
|
||||||
|
if (this.isTargetDomain(tx)) {
|
||||||
|
return target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tx (ctx: MeasureContext<SessionData>, txes: Tx[]): Promise<TxMiddlewareResult> {
|
||||||
|
for (const tx of txes) {
|
||||||
|
if (this.context.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
|
||||||
|
for (const ttx of (tx as TxApplyIf).txes) {
|
||||||
|
this.processTx(ctx, ttx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.processTx(ctx, tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.provideTx(ctx, txes)
|
||||||
|
}
|
||||||
|
|
||||||
|
isAvailable (ctx: MeasureContext<SessionData>, doc: Doc): boolean {
|
||||||
|
const domain = this.context.hierarchy.getDomain(doc._class)
|
||||||
|
if (!this.targetDomains.includes(domain)) return true
|
||||||
|
const account = ctx.contextData.account._id
|
||||||
|
return doc.createdBy === account || account === core.account.System
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,8 @@ import {
|
|||||||
SpacePermissionsMiddleware,
|
SpacePermissionsMiddleware,
|
||||||
SpaceSecurityMiddleware,
|
SpaceSecurityMiddleware,
|
||||||
TriggersMiddleware,
|
TriggersMiddleware,
|
||||||
TxMiddleware
|
TxMiddleware,
|
||||||
|
NotificationsMiddleware
|
||||||
} from '@hcengineering/middleware'
|
} from '@hcengineering/middleware'
|
||||||
import { createMongoAdapter, createMongoTxAdapter } from '@hcengineering/mongo'
|
import { createMongoAdapter, createMongoTxAdapter } from '@hcengineering/mongo'
|
||||||
import { createPostgresAdapter, createPostgresTxAdapter } from '@hcengineering/postgres'
|
import { createPostgresAdapter, createPostgresTxAdapter } from '@hcengineering/postgres'
|
||||||
@ -121,6 +122,7 @@ export function createServerPipeline (
|
|||||||
LookupMiddleware.create,
|
LookupMiddleware.create,
|
||||||
ModifiedMiddleware.create,
|
ModifiedMiddleware.create,
|
||||||
PrivateMiddleware.create,
|
PrivateMiddleware.create,
|
||||||
|
NotificationsMiddleware.create,
|
||||||
(ctx: MeasureContext, context: PipelineContext, next?: Middleware) =>
|
(ctx: MeasureContext, context: PipelineContext, next?: Middleware) =>
|
||||||
SpaceSecurityMiddleware.create(opt.adapterSecurity ?? false, ctx, context, next),
|
SpaceSecurityMiddleware.create(opt.adapterSecurity ?? false, ctx, context, next),
|
||||||
SpacePermissionsMiddleware.create,
|
SpacePermissionsMiddleware.create,
|
||||||
|
Loading…
Reference in New Issue
Block a user