mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03: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 Doc,
|
||||
type DocumentQuery,
|
||||
type Domain,
|
||||
type IndexingConfiguration,
|
||||
type Markup,
|
||||
type Ref,
|
||||
@ -56,6 +55,9 @@ import view, { createAction, template } from '@hcengineering/model-view'
|
||||
import workbench from '@hcengineering/model-workbench'
|
||||
import {
|
||||
notificationId,
|
||||
DOMAIN_USER_NOTIFY,
|
||||
DOMAIN_NOTIFICATION,
|
||||
DOMAIN_DOC_NOTIFY,
|
||||
type ActivityInboxNotification,
|
||||
type ActivityNotificationViewlet,
|
||||
type BaseNotificationType,
|
||||
@ -86,16 +88,10 @@ import { type AnyComponent, type Location } from '@hcengineering/ui/src/types'
|
||||
|
||||
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 { 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)
|
||||
export class TBrowserNotification extends TDoc implements BrowserNotification {
|
||||
senderId?: Ref<Account> | undefined
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
Class,
|
||||
Doc,
|
||||
DocumentQuery,
|
||||
type Domain,
|
||||
IdMap,
|
||||
Markup,
|
||||
Mixin,
|
||||
@ -42,6 +43,10 @@ import { Readable, Writable } 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
|
||||
*/
|
||||
|
@ -31,6 +31,7 @@ import type { TriggerControl, TriggerFunc } from '@hcengineering/server-core'
|
||||
* @public
|
||||
*/
|
||||
export const serverNotificationId = 'server-notification' as Plugin
|
||||
export { DOMAIN_USER_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_DOC_NOTIFY } from '@hcengineering/notification'
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
@ -41,6 +41,7 @@
|
||||
"@hcengineering/platform": "^0.6.11",
|
||||
"@hcengineering/server-core": "^0.6.1",
|
||||
"@hcengineering/server-preference": "^0.6.0",
|
||||
"@hcengineering/server-notification": "^0.6.1",
|
||||
"@hcengineering/query": "^0.6.12",
|
||||
"fast-equals": "^5.0.1"
|
||||
}
|
||||
|
@ -33,3 +33,4 @@ export * from './spacePermissions'
|
||||
export * from './spaceSecurity'
|
||||
export * from './triggers'
|
||||
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,
|
||||
SpaceSecurityMiddleware,
|
||||
TriggersMiddleware,
|
||||
TxMiddleware
|
||||
TxMiddleware,
|
||||
NotificationsMiddleware
|
||||
} from '@hcengineering/middleware'
|
||||
import { createMongoAdapter, createMongoTxAdapter } from '@hcengineering/mongo'
|
||||
import { createPostgresAdapter, createPostgresTxAdapter } from '@hcengineering/postgres'
|
||||
@ -121,6 +122,7 @@ export function createServerPipeline (
|
||||
LookupMiddleware.create,
|
||||
ModifiedMiddleware.create,
|
||||
PrivateMiddleware.create,
|
||||
NotificationsMiddleware.create,
|
||||
(ctx: MeasureContext, context: PipelineContext, next?: Middleware) =>
|
||||
SpaceSecurityMiddleware.create(opt.adapterSecurity ?? false, ctx, context, next),
|
||||
SpacePermissionsMiddleware.create,
|
||||
|
Loading…
Reference in New Issue
Block a user