@backstage/plugin-notifications-backend 0.4.0-next.2 → 0.4.1-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/dist/index.cjs.js +5 -6
- package/dist/index.cjs.js.map +1 -1
- package/package.json +17 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# @backstage/plugin-notifications-backend
|
|
2
2
|
|
|
3
|
+
## 0.4.1-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 094eaa3: Remove references to in-repo backend-common
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/plugin-notifications-node@0.2.7-next.0
|
|
10
|
+
- @backstage/plugin-signals-node@0.1.12-next.0
|
|
11
|
+
- @backstage/plugin-events-node@0.4.1-next.0
|
|
12
|
+
- @backstage/plugin-auth-node@0.5.3-next.0
|
|
13
|
+
- @backstage/backend-plugin-api@1.0.1-next.0
|
|
14
|
+
- @backstage/catalog-client@1.7.0
|
|
15
|
+
- @backstage/catalog-model@1.7.0
|
|
16
|
+
- @backstage/config@1.2.0
|
|
17
|
+
- @backstage/errors@1.2.4
|
|
18
|
+
- @backstage/plugin-catalog-node@1.13.1-next.0
|
|
19
|
+
- @backstage/plugin-notifications-common@0.0.5
|
|
20
|
+
|
|
21
|
+
## 0.4.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs.
|
|
26
|
+
|
|
27
|
+
This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config.
|
|
28
|
+
|
|
29
|
+
As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it.
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- 1c6f142: Internal refactor to avoid use of insecure coding patterns.
|
|
34
|
+
- 4a53dd0: Implement icon in backend and show icon in table if available.
|
|
35
|
+
- c2b63ab: Updated dependency `supertest` to `^7.0.0`.
|
|
36
|
+
- f195972: Validate notification link when new notification is created
|
|
37
|
+
- 5edd344: Refactor to use injected catalog client in the new backend system
|
|
38
|
+
- Updated dependencies
|
|
39
|
+
- @backstage/backend-common@0.25.0
|
|
40
|
+
- @backstage/plugin-signals-node@0.1.11
|
|
41
|
+
- @backstage/backend-plugin-api@1.0.0
|
|
42
|
+
- @backstage/plugin-auth-node@0.5.2
|
|
43
|
+
- @backstage/catalog-model@1.7.0
|
|
44
|
+
- @backstage/catalog-client@1.7.0
|
|
45
|
+
- @backstage/plugin-catalog-node@1.13.0
|
|
46
|
+
- @backstage/plugin-events-node@0.4.0
|
|
47
|
+
- @backstage/config@1.2.0
|
|
48
|
+
- @backstage/errors@1.2.4
|
|
49
|
+
- @backstage/plugin-notifications-common@0.0.5
|
|
50
|
+
- @backstage/plugin-notifications-node@0.2.6
|
|
51
|
+
|
|
3
52
|
## 0.4.0-next.2
|
|
4
53
|
|
|
5
54
|
### Patch Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -577,7 +577,7 @@ async function createRouter(options) {
|
|
|
577
577
|
store.getNotifications(opts),
|
|
578
578
|
store.getNotificationsCount(opts)
|
|
579
579
|
]);
|
|
580
|
-
res.
|
|
580
|
+
res.json({
|
|
581
581
|
totalCount,
|
|
582
582
|
notifications
|
|
583
583
|
});
|
|
@@ -585,7 +585,7 @@ async function createRouter(options) {
|
|
|
585
585
|
router.get("/status", async (req, res) => {
|
|
586
586
|
const user = await getUser(req);
|
|
587
587
|
const status = await store.getStatus({ user });
|
|
588
|
-
res.
|
|
588
|
+
res.json(status);
|
|
589
589
|
});
|
|
590
590
|
router.get("/:id", async (req, res) => {
|
|
591
591
|
const user = await getUser(req);
|
|
@@ -596,10 +596,9 @@ async function createRouter(options) {
|
|
|
596
596
|
};
|
|
597
597
|
const notifications = await store.getNotifications(opts);
|
|
598
598
|
if (notifications.length !== 1) {
|
|
599
|
-
|
|
600
|
-
return;
|
|
599
|
+
throw new errors.NotFoundError("Not found");
|
|
601
600
|
}
|
|
602
|
-
res.
|
|
601
|
+
res.json(notifications[0]);
|
|
603
602
|
});
|
|
604
603
|
router.post("/update", async (req, res) => {
|
|
605
604
|
const user = await getUser(req);
|
|
@@ -632,7 +631,7 @@ async function createRouter(options) {
|
|
|
632
631
|
await store.markUnsaved({ user, ids });
|
|
633
632
|
}
|
|
634
633
|
const notifications = await store.getNotifications({ ids, user });
|
|
635
|
-
res.
|
|
634
|
+
res.json(notifications);
|
|
636
635
|
});
|
|
637
636
|
const sendBroadcastNotification = async (baseNotification, opts, origin) => {
|
|
638
637
|
const { scope } = opts.payload;
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/database/DatabaseNotificationsStore.ts","../src/service/parseEntityOrderFieldParams.ts","../src/service/getUsersForEntityRef.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { PluginDatabaseManager } from '@backstage/backend-common';\nimport { resolvePackagePath } from '@backstage/backend-plugin-api';\nimport {\n NotificationGetOptions,\n NotificationModifyOptions,\n NotificationsStore,\n} from './NotificationsStore';\nimport {\n Notification,\n NotificationSeverity,\n notificationSeverities,\n} from '@backstage/plugin-notifications-common';\nimport { Knex } from 'knex';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage/plugin-notifications-backend',\n 'migrations',\n);\n\nconst NOTIFICATION_COLUMNS = [\n 'id',\n 'title',\n 'description',\n 'severity',\n 'link',\n 'origin',\n 'scope',\n 'topic',\n 'icon',\n 'created',\n 'updated',\n 'user',\n 'read',\n 'saved',\n];\n\nexport const normalizeSeverity = (input?: string): NotificationSeverity => {\n let lower = (input ?? 'normal').toLowerCase() as NotificationSeverity;\n if (notificationSeverities.indexOf(lower) < 0) {\n lower = 'normal';\n }\n return lower;\n};\n\n/** @internal */\nexport class DatabaseNotificationsStore implements NotificationsStore {\n private readonly isSQLite = false;\n\n private constructor(private readonly db: Knex) {\n this.isSQLite = this.db.client.config.client.includes('sqlite3');\n }\n\n static async create({\n database,\n skipMigrations,\n }: {\n database: PluginDatabaseManager;\n skipMigrations?: boolean;\n }): Promise<DatabaseNotificationsStore> {\n const client = await database.getClient();\n\n if (!database.migrations?.skip && !skipMigrations) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n\n return new DatabaseNotificationsStore(client);\n }\n\n private mapToInteger = (val: string | number | undefined): number => {\n return typeof val === 'string' ? Number.parseInt(val, 10) : val ?? 0;\n };\n\n private mapToNotifications = (rows: any[]): Notification[] => {\n return rows.map(row => ({\n id: row.id,\n user: row.user,\n created: new Date(row.created),\n saved: row.saved,\n read: row.read,\n updated: row.updated,\n origin: row.origin,\n payload: {\n title: row.title,\n description: row.description,\n link: row.link,\n topic: row.topic,\n severity: row.severity,\n scope: row.scope,\n icon: row.icon,\n },\n }));\n };\n\n private mapNotificationToDbRow = (notification: Notification) => {\n return {\n id: notification.id,\n user: notification.user,\n origin: notification.origin,\n created: notification.created,\n topic: notification.payload?.topic,\n link: notification.payload?.link,\n title: notification.payload?.title,\n description: notification.payload?.description,\n severity: normalizeSeverity(notification.payload?.severity),\n scope: notification.payload?.scope,\n icon: notification.payload.icon,\n saved: notification.saved,\n read: notification.read,\n };\n };\n\n private mapBroadcastToDbRow = (notification: Notification) => {\n return {\n id: notification.id,\n origin: notification.origin,\n created: notification.created,\n topic: notification.payload?.topic,\n link: notification.payload?.link,\n title: notification.payload?.title,\n description: notification.payload?.description,\n severity: normalizeSeverity(notification.payload?.severity),\n icon: notification.payload.icon,\n scope: notification.payload?.scope,\n };\n };\n\n private getBroadcastUnion = (user?: string | null) => {\n return this.db('broadcast')\n .leftJoin('broadcast_user_status', function clause() {\n const join = this.on('id', '=', 'broadcast_user_status.broadcast_id');\n if (user !== null && user !== undefined) {\n join.andOnVal('user', '=', user);\n }\n })\n .select(NOTIFICATION_COLUMNS);\n };\n\n private getNotificationsBaseQuery = (\n options: NotificationGetOptions | NotificationModifyOptions,\n ) => {\n const { user, orderField } = options;\n\n const subQuery = this.db('notification')\n .select(NOTIFICATION_COLUMNS)\n .unionAll([this.getBroadcastUnion(user)])\n .as('notifications');\n\n const query = this.db.from(subQuery).where(q => {\n q.where('user', user).orWhereNull('user');\n });\n\n if (orderField && orderField.length > 0) {\n orderField.forEach(orderBy => {\n query.orderBy(orderBy.field, orderBy.order);\n });\n } else if (!orderField) {\n query.orderBy('created', 'desc');\n }\n\n if (options.createdAfter) {\n if (this.isSQLite) {\n query.where('created', '>=', options.createdAfter.valueOf());\n } else {\n query.where('created', '>=', options.createdAfter.toISOString());\n }\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n if (options.search) {\n query.whereRaw(\n `(LOWER(title) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?))`,\n [`%${options.search}%`, `%${options.search}%`],\n );\n }\n\n if (options.ids) {\n query.whereIn('id', options.ids);\n }\n\n if (options.read) {\n query.whereNotNull('read');\n } else if (options.read === false) {\n query.whereNull('read');\n } // or match both if undefined\n\n if (options.topic) {\n query.where('topic', '=', options.topic);\n }\n\n if (options.saved) {\n query.whereNotNull('saved');\n } else if (options.saved === false) {\n query.whereNull('saved');\n } // or match both if undefined\n\n if (options.minimumSeverity !== undefined) {\n const idx = notificationSeverities.indexOf(options.minimumSeverity);\n const equalOrHigher = notificationSeverities.slice(0, idx + 1);\n query.whereIn('severity', equalOrHigher);\n }\n\n return query;\n };\n\n async getNotifications(options: NotificationGetOptions) {\n const notificationQuery = this.getNotificationsBaseQuery(options);\n const notifications = await notificationQuery.select(NOTIFICATION_COLUMNS);\n return this.mapToNotifications(notifications);\n }\n\n async getNotificationsCount(options: NotificationGetOptions) {\n const countOptions: NotificationGetOptions = { ...options };\n countOptions.limit = undefined;\n countOptions.offset = undefined;\n countOptions.orderField = [];\n const notificationQuery = this.getNotificationsBaseQuery(countOptions);\n const response = await notificationQuery.count('id as CNT');\n return Number(response[0].CNT);\n }\n\n async saveNotification(notification: Notification) {\n await this.db\n .insert(this.mapNotificationToDbRow(notification))\n .into('notification');\n }\n\n async saveBroadcast(notification: Notification) {\n await this.db\n .insert(this.mapBroadcastToDbRow(notification))\n .into('broadcast');\n if (notification.saved || notification.read) {\n await this.db\n .insert({\n user: notification.user,\n broadcast_id: notification.id,\n saved: notification.saved,\n read: notification.read,\n })\n .into('broadcast_user_status');\n }\n }\n\n async getStatus(options: NotificationGetOptions) {\n const notificationQuery = this.getNotificationsBaseQuery({\n ...options,\n orderField: [],\n });\n const readSubQuery = notificationQuery\n .clone()\n .count('id')\n .whereNotNull('read')\n .as('READ');\n const unreadSubQuery = notificationQuery\n .clone()\n .count('id')\n .whereNull('read')\n .as('UNREAD');\n\n const query = await notificationQuery\n .select(readSubQuery, unreadSubQuery)\n .first();\n\n return {\n unread: this.mapToInteger((query as any)?.UNREAD),\n read: this.mapToInteger((query as any)?.READ),\n };\n }\n\n async getExistingScopeNotification(options: {\n user: string;\n scope: string;\n origin: string;\n }) {\n const query = this.db('notification')\n .where('user', options.user)\n .where('scope', options.scope)\n .where('origin', options.origin)\n .limit(1);\n\n const rows = await query;\n if (!rows || rows.length === 0) {\n return null;\n }\n return rows[0] as Notification;\n }\n\n async getExistingScopeBroadcast(options: { scope: string; origin: string }) {\n const query = this.db('broadcast')\n .where('scope', options.scope)\n .where('origin', options.origin)\n .limit(1);\n\n const rows = await query;\n if (!rows || rows.length === 0) {\n return null;\n }\n return rows[0] as Notification;\n }\n\n async restoreExistingNotification({\n id,\n notification,\n }: {\n id: string;\n notification: Notification;\n }) {\n const updateColumns = {\n title: notification.payload.title,\n description: notification.payload.description,\n link: notification.payload.link,\n topic: notification.payload.topic,\n updated: new Date(),\n severity: normalizeSeverity(notification.payload?.severity),\n read: null,\n };\n\n const notificationQuery = this.db('notification')\n .where('id', id)\n .where('user', notification.user);\n const broadcastQuery = this.db('broadcast').where('id', id);\n\n await Promise.all([\n notificationQuery.update(updateColumns),\n broadcastQuery.update({ ...updateColumns, read: undefined }),\n ]);\n\n return await this.getNotification({ id, user: notification.user });\n }\n\n async getNotification(options: {\n id: string;\n user?: string | null;\n }): Promise<Notification | null> {\n const rows = await this.db\n .select('*')\n .from(\n this.db('notification')\n .select(NOTIFICATION_COLUMNS)\n .unionAll([this.getBroadcastUnion(options.user)])\n .as('notifications'),\n )\n .where('id', options.id)\n .limit(1);\n if (!rows || rows.length === 0) {\n return null;\n }\n return this.mapToNotifications(rows)[0];\n }\n\n private markReadSaved = async (\n ids: string[],\n user: string,\n read?: Date | null,\n saved?: Date | null,\n ) => {\n await this.db('notification')\n .whereIn('id', ids)\n .where('user', user)\n .update({ read, saved });\n\n const broadcasts = this.mapToNotifications(\n await this.db('broadcast').whereIn('id', ids).select(),\n );\n\n if (broadcasts.length > 0)\n if (!this.isSQLite) {\n await this.db('broadcast_user_status')\n .insert(\n broadcasts.map(b => ({\n broadcast_id: b.id,\n user,\n read,\n saved,\n })),\n )\n .onConflict(['broadcast_id', 'user'])\n .merge(['read', 'saved']);\n } else {\n // SQLite does not support upsert so fall back to this (mostly for tests and local dev)\n for (const b of broadcasts) {\n const baseQuery = this.db('broadcast_user_status')\n .where('broadcast_id', b.id)\n .where('user', user);\n const exists = await baseQuery.clone().limit(1).select().first();\n if (exists) {\n await baseQuery.clone().update({ read, saved });\n } else {\n await baseQuery\n .clone()\n .insert({ broadcast_id: b.id, user, read, saved });\n }\n }\n }\n };\n\n async markRead(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, new Date(), undefined);\n }\n\n async markUnread(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, null, undefined);\n }\n\n async markSaved(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, undefined, new Date());\n }\n\n async markUnsaved(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, undefined, null);\n }\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This file is based on the plugins/catalog-backend\n\nimport { InputError } from '@backstage/errors';\nimport { EntityOrder } from '../database';\n\n/**\n * Takes a single unknown parameter and makes sure that it's a single string or\n * an array of strings, and returns as an array.\n */\nexport function parseStringsParam(\n param: unknown,\n ctx: string,\n): string[] | undefined {\n if (param === undefined) {\n return undefined;\n }\n\n const array = [param].flat();\n if (array.some(p => typeof p !== 'string')) {\n throw new InputError(`Invalid ${ctx}, not a string`);\n }\n\n return array as string[];\n}\n\nexport function parseEntityOrderFieldParams(\n params: Record<string, unknown>,\n): EntityOrder[] | undefined {\n const orderFieldStrings = parseStringsParam(params.orderField, 'orderField');\n if (!orderFieldStrings) {\n return undefined;\n }\n\n return orderFieldStrings.map(orderFieldString => {\n const [field, order] = orderFieldString.split(',');\n\n if (order !== undefined && !isOrder(order)) {\n throw new InputError('Invalid order field order, must be asc or desc');\n }\n return { field, order };\n });\n}\n\nexport function isOrder(order: string): order is 'asc' | 'desc' {\n return ['asc', 'desc'].includes(order);\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n Entity,\n isGroupEntity,\n isUserEntity,\n parseEntityRef,\n RELATION_HAS_MEMBER,\n RELATION_OWNED_BY,\n RELATION_PARENT_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { AuthService } from '@backstage/backend-plugin-api';\nimport { CatalogApi } from '@backstage/catalog-client';\n\nconst isUserEntityRef = (ref: string) =>\n parseEntityRef(ref).kind.toLocaleLowerCase() === 'user';\n\n// Partitions array of entity references to two arrays; user entity refs and other entity refs\nconst partitionEntityRefs = (refs: string[]): string[][] =>\n refs.reduce(\n ([userEntityRefs, otherEntityRefs]: string[][], ref: string) => {\n return isUserEntityRef(ref)\n ? [[...userEntityRefs, ref], otherEntityRefs]\n : [userEntityRefs, [...otherEntityRefs, ref]];\n },\n [[], []],\n );\n\nexport const getUsersForEntityRef = async (\n entityRef: string | string[] | null,\n excludeEntityRefs: string | string[],\n options: {\n auth: AuthService;\n catalogClient: CatalogApi;\n },\n): Promise<string[]> => {\n const { auth, catalogClient } = options;\n\n if (entityRef === null) {\n return [];\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n\n const excluded = Array.isArray(excludeEntityRefs)\n ? excludeEntityRefs\n : [excludeEntityRefs];\n\n const refsArr = Array.isArray(entityRef) ? entityRef : [entityRef];\n const [userEntityRefs, otherEntityRefs] = partitionEntityRefs(refsArr);\n const users: string[] = userEntityRefs.filter(ref => !excluded.includes(ref));\n const entityRefs = otherEntityRefs.filter(ref => !excluded.includes(ref));\n\n const fields = ['kind', 'metadata.name', 'metadata.namespace', 'relations'];\n let entities: Array<Entity | undefined> = [];\n if (entityRefs.length > 0) {\n const fetchedEntities = await catalogClient.getEntitiesByRefs(\n {\n entityRefs,\n fields,\n },\n { token },\n );\n entities = fetchedEntities.items;\n }\n\n const mapEntity = async (entity: Entity | undefined): Promise<string[]> => {\n if (!entity) {\n return [];\n }\n\n const currentEntityRef = stringifyEntityRef(entity);\n if (excluded.includes(currentEntityRef)) {\n return [];\n }\n\n if (isUserEntity(entity)) {\n return [currentEntityRef];\n }\n\n if (isGroupEntity(entity)) {\n if (!entity.relations?.length) {\n return [];\n }\n\n const groupUsers = entity.relations\n .filter(\n relation =>\n relation.type === RELATION_HAS_MEMBER &&\n isUserEntityRef(relation.targetRef),\n )\n .map(r => r.targetRef);\n\n const childGroupRefs = entity.relations\n .filter(relation => relation.type === RELATION_PARENT_OF)\n .map(r => r.targetRef);\n\n let childGroupUsers: string[][] = [];\n if (childGroupRefs.length > 0) {\n const childGroups = await catalogClient.getEntitiesByRefs(\n {\n entityRefs: childGroupRefs,\n fields,\n },\n { token },\n );\n childGroupUsers = await Promise.all(childGroups.items.map(mapEntity));\n }\n\n return [...groupUsers, ...childGroupUsers.flat(2)].filter(\n ref => !excluded.includes(ref),\n );\n }\n\n if (entity.relations?.length) {\n const ownerRef = entity.relations.find(\n relation => relation.type === RELATION_OWNED_BY,\n )?.targetRef;\n\n if (!ownerRef) {\n return [];\n }\n\n if (isUserEntityRef(ownerRef)) {\n if (excluded.includes(ownerRef)) {\n return [];\n }\n return [ownerRef];\n }\n\n const owner = await catalogClient.getEntityByRef(ownerRef, { token });\n return mapEntity(owner);\n }\n\n return [];\n };\n\n for (const entity of entities) {\n const u = await mapEntity(entity);\n users.push(...u);\n }\n\n return [...new Set(users)].filter(Boolean);\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { errorHandler, PluginDatabaseManager } from '@backstage/backend-common';\nimport express, { Request } from 'express';\nimport Router from 'express-promise-router';\nimport {\n DatabaseNotificationsStore,\n normalizeSeverity,\n NotificationGetOptions,\n} from '../database';\nimport { v4 as uuid } from 'uuid';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport {\n NotificationProcessor,\n NotificationSendOptions,\n} from '@backstage/plugin-notifications-node';\nimport { InputError } from '@backstage/errors';\nimport {\n AuthService,\n HttpAuthService,\n LoggerService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { SignalsService } from '@backstage/plugin-signals-node';\nimport {\n NewNotificationSignal,\n Notification,\n NotificationPayload,\n NotificationReadSignal,\n notificationSeverities,\n NotificationStatus,\n} from '@backstage/plugin-notifications-common';\nimport { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams';\nimport { getUsersForEntityRef } from './getUsersForEntityRef';\nimport { Config } from '@backstage/config';\n\n/** @internal */\nexport interface RouterOptions {\n logger: LoggerService;\n config: Config;\n database: PluginDatabaseManager;\n auth: AuthService;\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n signals?: SignalsService;\n catalog: CatalogApi;\n processors?: NotificationProcessor[];\n}\n\n/** @internal */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n config,\n logger,\n database,\n auth,\n httpAuth,\n userInfo,\n catalog,\n processors = [],\n signals,\n } = options;\n\n const store = await DatabaseNotificationsStore.create({ database });\n const frontendBaseUrl = config.getString('app.baseUrl');\n\n const getUser = async (req: Request<unknown>) => {\n const credentials = await httpAuth.credentials(req, { allow: ['user'] });\n const info = await userInfo.getUserInfo(credentials);\n return info.userEntityRef;\n };\n\n const filterProcessors = (payload: NotificationPayload) => {\n const result: NotificationProcessor[] = [];\n\n for (const processor of processors) {\n if (processor.getNotificationFilters) {\n const filters = processor.getNotificationFilters();\n if (filters.minSeverity) {\n if (\n notificationSeverities.indexOf(payload.severity ?? 'normal') >\n notificationSeverities.indexOf(filters.minSeverity)\n ) {\n continue;\n }\n }\n\n if (filters.maxSeverity) {\n if (\n notificationSeverities.indexOf(payload.severity ?? 'normal') <\n notificationSeverities.indexOf(filters.maxSeverity)\n ) {\n continue;\n }\n }\n\n if (filters.excludedTopics && payload.topic) {\n if (filters.excludedTopics.includes(payload.topic)) {\n continue;\n }\n }\n }\n result.push(processor);\n }\n\n return result;\n };\n\n const processOptions = async (opts: NotificationSendOptions) => {\n const filtered = filterProcessors(opts.payload);\n let ret = opts;\n for (const processor of filtered) {\n try {\n ret = processor.processOptions\n ? await processor.processOptions(ret)\n : ret;\n } catch (e) {\n logger.error(\n `Error while processing notification options with ${processor.getName()}: ${e}`,\n );\n }\n }\n return ret;\n };\n\n const preProcessNotification = async (\n notification: Notification,\n opts: NotificationSendOptions,\n ) => {\n const filtered = filterProcessors(notification.payload);\n let ret = notification;\n for (const processor of filtered) {\n try {\n ret = processor.preProcess\n ? await processor.preProcess(ret, opts)\n : ret;\n } catch (e) {\n logger.error(\n `Error while pre processing notification with ${processor.getName()}: ${e}`,\n );\n }\n }\n return ret;\n };\n\n const postProcessNotification = async (\n notification: Notification,\n opts: NotificationSendOptions,\n ) => {\n const filtered = filterProcessors(notification.payload);\n for (const processor of filtered) {\n if (processor.postProcess) {\n try {\n await processor.postProcess(notification, opts);\n } catch (e) {\n logger.error(\n `Error while post processing notification with ${processor.getName()}: ${e}`,\n );\n }\n }\n }\n };\n\n const validateLink = (link: string) => {\n const stripLeadingSlash = (s: string) => s.replace(/^\\//, '');\n const ensureTrailingSlash = (s: string) => s.replace(/\\/?$/, '/');\n const url = new URL(\n stripLeadingSlash(link),\n ensureTrailingSlash(frontendBaseUrl),\n );\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n throw new Error('Only HTTP/HTTPS links are allowed');\n }\n };\n\n // TODO: Move to use OpenAPI router instead\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\n response.json({ status: 'ok' });\n });\n\n router.get('/', async (req, res) => {\n const user = await getUser(req);\n const opts: NotificationGetOptions = {\n user: user,\n };\n if (req.query.offset) {\n opts.offset = Number.parseInt(req.query.offset.toString(), 10);\n }\n if (req.query.limit) {\n opts.limit = Number.parseInt(req.query.limit.toString(), 10);\n }\n if (req.query.orderField) {\n opts.orderField = parseEntityOrderFieldParams(req.query);\n }\n if (req.query.search) {\n opts.search = req.query.search.toString();\n }\n if (req.query.read === 'true') {\n opts.read = true;\n } else if (req.query.read === 'false') {\n opts.read = false;\n // or keep undefined\n }\n\n if (req.query.topic) {\n opts.topic = req.query.topic.toString();\n }\n\n if (req.query.saved === 'true') {\n opts.saved = true;\n } else if (req.query.saved === 'false') {\n opts.saved = false;\n // or keep undefined\n }\n if (req.query.createdAfter) {\n const sinceEpoch = Date.parse(String(req.query.createdAfter));\n if (isNaN(sinceEpoch)) {\n throw new InputError('Unexpected date format');\n }\n opts.createdAfter = new Date(sinceEpoch);\n }\n if (req.query.minimumSeverity) {\n opts.minimumSeverity = normalizeSeverity(\n req.query.minimumSeverity.toString(),\n );\n }\n\n const [notifications, totalCount] = await Promise.all([\n store.getNotifications(opts),\n store.getNotificationsCount(opts),\n ]);\n res.send({\n totalCount,\n notifications,\n });\n });\n\n router.get('/status', async (req: Request<any, NotificationStatus>, res) => {\n const user = await getUser(req);\n const status = await store.getStatus({ user });\n res.send(status);\n });\n\n // Make sure this is the last \"GET\" handler\n router.get('/:id', async (req, res) => {\n const user = await getUser(req);\n const opts: NotificationGetOptions = {\n user: user,\n limit: 1,\n ids: [req.params.id],\n };\n const notifications = await store.getNotifications(opts);\n if (notifications.length !== 1) {\n res.status(404).send({ error: 'Not found' });\n return;\n }\n res.send(notifications[0]);\n });\n\n router.post('/update', async (req, res) => {\n const user = await getUser(req);\n const { ids, read, saved } = req.body;\n if (!ids || !Array.isArray(ids)) {\n throw new InputError();\n }\n\n if (read === true) {\n await store.markRead({ user, ids });\n\n if (signals) {\n await signals.publish<NotificationReadSignal>({\n recipients: { type: 'user', entityRef: [user] },\n message: { action: 'notification_read', notification_ids: ids },\n channel: 'notifications',\n });\n }\n } else if (read === false) {\n await store.markUnread({ user: user, ids });\n\n if (signals) {\n await signals.publish<NotificationReadSignal>({\n recipients: { type: 'user', entityRef: [user] },\n message: { action: 'notification_unread', notification_ids: ids },\n channel: 'notifications',\n });\n }\n }\n\n if (saved === true) {\n await store.markSaved({ user: user, ids });\n } else if (saved === false) {\n await store.markUnsaved({ user: user, ids });\n }\n\n const notifications = await store.getNotifications({ ids, user: user });\n res.status(200).send(notifications);\n });\n\n const sendBroadcastNotification = async (\n baseNotification: Omit<Notification, 'user' | 'id'>,\n opts: NotificationSendOptions,\n origin: string,\n ) => {\n const { scope } = opts.payload;\n const broadcastNotification = {\n ...baseNotification,\n user: null,\n id: uuid(),\n };\n const notification = await preProcessNotification(\n broadcastNotification,\n opts,\n );\n let existingNotification;\n if (scope) {\n existingNotification = await store.getExistingScopeBroadcast({\n scope,\n origin,\n });\n }\n\n let ret = notification;\n if (existingNotification) {\n const restored = await store.restoreExistingNotification({\n id: existingNotification.id,\n notification: { ...notification, user: '' },\n });\n ret = restored ?? notification;\n } else {\n await store.saveBroadcast(notification);\n }\n\n if (signals) {\n await signals.publish<NewNotificationSignal>({\n recipients: { type: 'broadcast' },\n message: {\n action: 'new_notification',\n notification_id: ret.id,\n },\n channel: 'notifications',\n });\n postProcessNotification(ret, opts);\n }\n return notification;\n };\n\n const sendUserNotifications = async (\n baseNotification: Omit<Notification, 'user' | 'id'>,\n users: string[],\n opts: NotificationSendOptions,\n origin: string,\n ) => {\n const notifications = [];\n const { scope } = opts.payload;\n const uniqueUsers = [...new Set(users)];\n for (const user of uniqueUsers) {\n const userNotification = {\n ...baseNotification,\n id: uuid(),\n user,\n };\n const notification = await preProcessNotification(userNotification, opts);\n\n let existingNotification;\n if (scope) {\n existingNotification = await store.getExistingScopeNotification({\n user,\n scope,\n origin,\n });\n }\n\n let ret = notification;\n if (existingNotification) {\n const restored = await store.restoreExistingNotification({\n id: existingNotification.id,\n notification,\n });\n ret = restored ?? notification;\n } else {\n await store.saveNotification(notification);\n }\n\n notifications.push(ret);\n\n if (signals) {\n await signals.publish<NewNotificationSignal>({\n recipients: { type: 'user', entityRef: [user] },\n message: {\n action: 'new_notification',\n notification_id: ret.id,\n },\n channel: 'notifications',\n });\n }\n postProcessNotification(ret, opts);\n }\n return notifications;\n };\n\n // Add new notification\n router.post(\n '/',\n async (req: Request<any, Notification[], NotificationSendOptions>, res) => {\n const opts = await processOptions(req.body);\n const { recipients, payload } = opts;\n const notifications: Notification[] = [];\n let users = [];\n\n const credentials = await httpAuth.credentials(req, {\n allow: ['service'],\n });\n\n const { title, link } = payload;\n\n if (!recipients || !title) {\n logger.error(`Invalid notification request received`);\n throw new InputError(`Invalid notification request received`);\n }\n\n if (link) {\n try {\n validateLink(link);\n } catch (e) {\n throw new InputError('Invalid link provided', e);\n }\n }\n\n const origin = credentials.principal.subject;\n const baseNotification = {\n payload: {\n ...payload,\n severity: payload.severity ?? 'normal',\n },\n origin,\n created: new Date(),\n };\n\n if (recipients.type === 'broadcast') {\n const broadcast = await sendBroadcastNotification(\n baseNotification,\n opts,\n origin,\n );\n notifications.push(broadcast);\n } else {\n const entityRef = recipients.entityRef;\n\n try {\n users = await getUsersForEntityRef(\n entityRef,\n recipients.excludeEntityRef ?? [],\n { auth, catalogClient: catalog },\n );\n } catch (e) {\n logger.error(`Failed to resolve notification receivers: ${e}`);\n throw new InputError('Failed to resolve notification receivers', e);\n }\n\n const userNotifications = await sendUserNotifications(\n baseNotification,\n users,\n opts,\n origin,\n );\n notifications.push(...userNotifications);\n }\n\n res.json(notifications);\n },\n );\n\n router.use(errorHandler());\n return router;\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\nimport { signalsServiceRef } from '@backstage/plugin-signals-node';\nimport {\n NotificationProcessor,\n notificationsProcessingExtensionPoint,\n NotificationsProcessingExtensionPoint,\n} from '@backstage/plugin-notifications-node';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\n\nclass NotificationsProcessingExtensionPointImpl\n implements NotificationsProcessingExtensionPoint\n{\n #processors = new Array<NotificationProcessor>();\n\n addProcessor(\n ...processors: Array<NotificationProcessor | Array<NotificationProcessor>>\n ): void {\n this.#processors.push(...processors.flat());\n }\n\n get processors() {\n return this.#processors;\n }\n}\n\n/**\n * Notifications backend plugin\n *\n * @public\n */\nexport const notificationsPlugin = createBackendPlugin({\n pluginId: 'notifications',\n register(env) {\n const processingExtensions =\n new NotificationsProcessingExtensionPointImpl();\n env.registerExtensionPoint(\n notificationsProcessingExtensionPoint,\n processingExtensions,\n );\n\n env.registerInit({\n deps: {\n auth: coreServices.auth,\n httpAuth: coreServices.httpAuth,\n userInfo: coreServices.userInfo,\n httpRouter: coreServices.httpRouter,\n logger: coreServices.logger,\n database: coreServices.database,\n signals: signalsServiceRef,\n config: coreServices.rootConfig,\n catalog: catalogServiceRef,\n },\n async init({\n auth,\n httpAuth,\n userInfo,\n httpRouter,\n logger,\n database,\n signals,\n config,\n catalog,\n }) {\n httpRouter.use(\n await createRouter({\n auth,\n httpAuth,\n userInfo,\n logger,\n config,\n database,\n catalog,\n signals,\n processors: processingExtensions.processors,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["resolvePackagePath","notificationSeverities","InputError","parseEntityRef","stringifyEntityRef","isUserEntity","isGroupEntity","RELATION_HAS_MEMBER","RELATION_PARENT_OF","RELATION_OWNED_BY","Router","express","uuid","errorHandler","createBackendPlugin","notificationsProcessingExtensionPoint","coreServices","signalsServiceRef","catalogServiceRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/database/DatabaseNotificationsStore.ts","../src/service/parseEntityOrderFieldParams.ts","../src/service/getUsersForEntityRef.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { PluginDatabaseManager } from '@backstage/backend-common';\nimport { resolvePackagePath } from '@backstage/backend-plugin-api';\nimport {\n NotificationGetOptions,\n NotificationModifyOptions,\n NotificationsStore,\n} from './NotificationsStore';\nimport {\n Notification,\n NotificationSeverity,\n notificationSeverities,\n} from '@backstage/plugin-notifications-common';\nimport { Knex } from 'knex';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage/plugin-notifications-backend',\n 'migrations',\n);\n\nconst NOTIFICATION_COLUMNS = [\n 'id',\n 'title',\n 'description',\n 'severity',\n 'link',\n 'origin',\n 'scope',\n 'topic',\n 'icon',\n 'created',\n 'updated',\n 'user',\n 'read',\n 'saved',\n];\n\nexport const normalizeSeverity = (input?: string): NotificationSeverity => {\n let lower = (input ?? 'normal').toLowerCase() as NotificationSeverity;\n if (notificationSeverities.indexOf(lower) < 0) {\n lower = 'normal';\n }\n return lower;\n};\n\n/** @internal */\nexport class DatabaseNotificationsStore implements NotificationsStore {\n private readonly isSQLite = false;\n\n private constructor(private readonly db: Knex) {\n this.isSQLite = this.db.client.config.client.includes('sqlite3');\n }\n\n static async create({\n database,\n skipMigrations,\n }: {\n database: PluginDatabaseManager;\n skipMigrations?: boolean;\n }): Promise<DatabaseNotificationsStore> {\n const client = await database.getClient();\n\n if (!database.migrations?.skip && !skipMigrations) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n\n return new DatabaseNotificationsStore(client);\n }\n\n private mapToInteger = (val: string | number | undefined): number => {\n return typeof val === 'string' ? Number.parseInt(val, 10) : val ?? 0;\n };\n\n private mapToNotifications = (rows: any[]): Notification[] => {\n return rows.map(row => ({\n id: row.id,\n user: row.user,\n created: new Date(row.created),\n saved: row.saved,\n read: row.read,\n updated: row.updated,\n origin: row.origin,\n payload: {\n title: row.title,\n description: row.description,\n link: row.link,\n topic: row.topic,\n severity: row.severity,\n scope: row.scope,\n icon: row.icon,\n },\n }));\n };\n\n private mapNotificationToDbRow = (notification: Notification) => {\n return {\n id: notification.id,\n user: notification.user,\n origin: notification.origin,\n created: notification.created,\n topic: notification.payload?.topic,\n link: notification.payload?.link,\n title: notification.payload?.title,\n description: notification.payload?.description,\n severity: normalizeSeverity(notification.payload?.severity),\n scope: notification.payload?.scope,\n icon: notification.payload.icon,\n saved: notification.saved,\n read: notification.read,\n };\n };\n\n private mapBroadcastToDbRow = (notification: Notification) => {\n return {\n id: notification.id,\n origin: notification.origin,\n created: notification.created,\n topic: notification.payload?.topic,\n link: notification.payload?.link,\n title: notification.payload?.title,\n description: notification.payload?.description,\n severity: normalizeSeverity(notification.payload?.severity),\n icon: notification.payload.icon,\n scope: notification.payload?.scope,\n };\n };\n\n private getBroadcastUnion = (user?: string | null) => {\n return this.db('broadcast')\n .leftJoin('broadcast_user_status', function clause() {\n const join = this.on('id', '=', 'broadcast_user_status.broadcast_id');\n if (user !== null && user !== undefined) {\n join.andOnVal('user', '=', user);\n }\n })\n .select(NOTIFICATION_COLUMNS);\n };\n\n private getNotificationsBaseQuery = (\n options: NotificationGetOptions | NotificationModifyOptions,\n ) => {\n const { user, orderField } = options;\n\n const subQuery = this.db('notification')\n .select(NOTIFICATION_COLUMNS)\n .unionAll([this.getBroadcastUnion(user)])\n .as('notifications');\n\n const query = this.db.from(subQuery).where(q => {\n q.where('user', user).orWhereNull('user');\n });\n\n if (orderField && orderField.length > 0) {\n orderField.forEach(orderBy => {\n query.orderBy(orderBy.field, orderBy.order);\n });\n } else if (!orderField) {\n query.orderBy('created', 'desc');\n }\n\n if (options.createdAfter) {\n if (this.isSQLite) {\n query.where('created', '>=', options.createdAfter.valueOf());\n } else {\n query.where('created', '>=', options.createdAfter.toISOString());\n }\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n if (options.search) {\n query.whereRaw(\n `(LOWER(title) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?))`,\n [`%${options.search}%`, `%${options.search}%`],\n );\n }\n\n if (options.ids) {\n query.whereIn('id', options.ids);\n }\n\n if (options.read) {\n query.whereNotNull('read');\n } else if (options.read === false) {\n query.whereNull('read');\n } // or match both if undefined\n\n if (options.topic) {\n query.where('topic', '=', options.topic);\n }\n\n if (options.saved) {\n query.whereNotNull('saved');\n } else if (options.saved === false) {\n query.whereNull('saved');\n } // or match both if undefined\n\n if (options.minimumSeverity !== undefined) {\n const idx = notificationSeverities.indexOf(options.minimumSeverity);\n const equalOrHigher = notificationSeverities.slice(0, idx + 1);\n query.whereIn('severity', equalOrHigher);\n }\n\n return query;\n };\n\n async getNotifications(options: NotificationGetOptions) {\n const notificationQuery = this.getNotificationsBaseQuery(options);\n const notifications = await notificationQuery.select(NOTIFICATION_COLUMNS);\n return this.mapToNotifications(notifications);\n }\n\n async getNotificationsCount(options: NotificationGetOptions) {\n const countOptions: NotificationGetOptions = { ...options };\n countOptions.limit = undefined;\n countOptions.offset = undefined;\n countOptions.orderField = [];\n const notificationQuery = this.getNotificationsBaseQuery(countOptions);\n const response = await notificationQuery.count('id as CNT');\n return Number(response[0].CNT);\n }\n\n async saveNotification(notification: Notification) {\n await this.db\n .insert(this.mapNotificationToDbRow(notification))\n .into('notification');\n }\n\n async saveBroadcast(notification: Notification) {\n await this.db\n .insert(this.mapBroadcastToDbRow(notification))\n .into('broadcast');\n if (notification.saved || notification.read) {\n await this.db\n .insert({\n user: notification.user,\n broadcast_id: notification.id,\n saved: notification.saved,\n read: notification.read,\n })\n .into('broadcast_user_status');\n }\n }\n\n async getStatus(options: NotificationGetOptions) {\n const notificationQuery = this.getNotificationsBaseQuery({\n ...options,\n orderField: [],\n });\n const readSubQuery = notificationQuery\n .clone()\n .count('id')\n .whereNotNull('read')\n .as('READ');\n const unreadSubQuery = notificationQuery\n .clone()\n .count('id')\n .whereNull('read')\n .as('UNREAD');\n\n const query = await notificationQuery\n .select(readSubQuery, unreadSubQuery)\n .first();\n\n return {\n unread: this.mapToInteger((query as any)?.UNREAD),\n read: this.mapToInteger((query as any)?.READ),\n };\n }\n\n async getExistingScopeNotification(options: {\n user: string;\n scope: string;\n origin: string;\n }) {\n const query = this.db('notification')\n .where('user', options.user)\n .where('scope', options.scope)\n .where('origin', options.origin)\n .limit(1);\n\n const rows = await query;\n if (!rows || rows.length === 0) {\n return null;\n }\n return rows[0] as Notification;\n }\n\n async getExistingScopeBroadcast(options: { scope: string; origin: string }) {\n const query = this.db('broadcast')\n .where('scope', options.scope)\n .where('origin', options.origin)\n .limit(1);\n\n const rows = await query;\n if (!rows || rows.length === 0) {\n return null;\n }\n return rows[0] as Notification;\n }\n\n async restoreExistingNotification({\n id,\n notification,\n }: {\n id: string;\n notification: Notification;\n }) {\n const updateColumns = {\n title: notification.payload.title,\n description: notification.payload.description,\n link: notification.payload.link,\n topic: notification.payload.topic,\n updated: new Date(),\n severity: normalizeSeverity(notification.payload?.severity),\n read: null,\n };\n\n const notificationQuery = this.db('notification')\n .where('id', id)\n .where('user', notification.user);\n const broadcastQuery = this.db('broadcast').where('id', id);\n\n await Promise.all([\n notificationQuery.update(updateColumns),\n broadcastQuery.update({ ...updateColumns, read: undefined }),\n ]);\n\n return await this.getNotification({ id, user: notification.user });\n }\n\n async getNotification(options: {\n id: string;\n user?: string | null;\n }): Promise<Notification | null> {\n const rows = await this.db\n .select('*')\n .from(\n this.db('notification')\n .select(NOTIFICATION_COLUMNS)\n .unionAll([this.getBroadcastUnion(options.user)])\n .as('notifications'),\n )\n .where('id', options.id)\n .limit(1);\n if (!rows || rows.length === 0) {\n return null;\n }\n return this.mapToNotifications(rows)[0];\n }\n\n private markReadSaved = async (\n ids: string[],\n user: string,\n read?: Date | null,\n saved?: Date | null,\n ) => {\n await this.db('notification')\n .whereIn('id', ids)\n .where('user', user)\n .update({ read, saved });\n\n const broadcasts = this.mapToNotifications(\n await this.db('broadcast').whereIn('id', ids).select(),\n );\n\n if (broadcasts.length > 0)\n if (!this.isSQLite) {\n await this.db('broadcast_user_status')\n .insert(\n broadcasts.map(b => ({\n broadcast_id: b.id,\n user,\n read,\n saved,\n })),\n )\n .onConflict(['broadcast_id', 'user'])\n .merge(['read', 'saved']);\n } else {\n // SQLite does not support upsert so fall back to this (mostly for tests and local dev)\n for (const b of broadcasts) {\n const baseQuery = this.db('broadcast_user_status')\n .where('broadcast_id', b.id)\n .where('user', user);\n const exists = await baseQuery.clone().limit(1).select().first();\n if (exists) {\n await baseQuery.clone().update({ read, saved });\n } else {\n await baseQuery\n .clone()\n .insert({ broadcast_id: b.id, user, read, saved });\n }\n }\n }\n };\n\n async markRead(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, new Date(), undefined);\n }\n\n async markUnread(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, null, undefined);\n }\n\n async markSaved(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, undefined, new Date());\n }\n\n async markUnsaved(options: NotificationModifyOptions): Promise<void> {\n await this.markReadSaved(options.ids, options.user, undefined, null);\n }\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This file is based on the plugins/catalog-backend\n\nimport { InputError } from '@backstage/errors';\nimport { EntityOrder } from '../database';\n\n/**\n * Takes a single unknown parameter and makes sure that it's a single string or\n * an array of strings, and returns as an array.\n */\nexport function parseStringsParam(\n param: unknown,\n ctx: string,\n): string[] | undefined {\n if (param === undefined) {\n return undefined;\n }\n\n const array = [param].flat();\n if (array.some(p => typeof p !== 'string')) {\n throw new InputError(`Invalid ${ctx}, not a string`);\n }\n\n return array as string[];\n}\n\nexport function parseEntityOrderFieldParams(\n params: Record<string, unknown>,\n): EntityOrder[] | undefined {\n const orderFieldStrings = parseStringsParam(params.orderField, 'orderField');\n if (!orderFieldStrings) {\n return undefined;\n }\n\n return orderFieldStrings.map(orderFieldString => {\n const [field, order] = orderFieldString.split(',');\n\n if (order !== undefined && !isOrder(order)) {\n throw new InputError('Invalid order field order, must be asc or desc');\n }\n return { field, order };\n });\n}\n\nexport function isOrder(order: string): order is 'asc' | 'desc' {\n return ['asc', 'desc'].includes(order);\n}\n","/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n Entity,\n isGroupEntity,\n isUserEntity,\n parseEntityRef,\n RELATION_HAS_MEMBER,\n RELATION_OWNED_BY,\n RELATION_PARENT_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { AuthService } from '@backstage/backend-plugin-api';\nimport { CatalogApi } from '@backstage/catalog-client';\n\nconst isUserEntityRef = (ref: string) =>\n parseEntityRef(ref).kind.toLocaleLowerCase() === 'user';\n\n// Partitions array of entity references to two arrays; user entity refs and other entity refs\nconst partitionEntityRefs = (refs: string[]): string[][] =>\n refs.reduce(\n ([userEntityRefs, otherEntityRefs]: string[][], ref: string) => {\n return isUserEntityRef(ref)\n ? [[...userEntityRefs, ref], otherEntityRefs]\n : [userEntityRefs, [...otherEntityRefs, ref]];\n },\n [[], []],\n );\n\nexport const getUsersForEntityRef = async (\n entityRef: string | string[] | null,\n excludeEntityRefs: string | string[],\n options: {\n auth: AuthService;\n catalogClient: CatalogApi;\n },\n): Promise<string[]> => {\n const { auth, catalogClient } = options;\n\n if (entityRef === null) {\n return [];\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n\n const excluded = Array.isArray(excludeEntityRefs)\n ? excludeEntityRefs\n : [excludeEntityRefs];\n\n const refsArr = Array.isArray(entityRef) ? entityRef : [entityRef];\n const [userEntityRefs, otherEntityRefs] = partitionEntityRefs(refsArr);\n const users: string[] = userEntityRefs.filter(ref => !excluded.includes(ref));\n const entityRefs = otherEntityRefs.filter(ref => !excluded.includes(ref));\n\n const fields = ['kind', 'metadata.name', 'metadata.namespace', 'relations'];\n let entities: Array<Entity | undefined> = [];\n if (entityRefs.length > 0) {\n const fetchedEntities = await catalogClient.getEntitiesByRefs(\n {\n entityRefs,\n fields,\n },\n { token },\n );\n entities = fetchedEntities.items;\n }\n\n const mapEntity = async (entity: Entity | undefined): Promise<string[]> => {\n if (!entity) {\n return [];\n }\n\n const currentEntityRef = stringifyEntityRef(entity);\n if (excluded.includes(currentEntityRef)) {\n return [];\n }\n\n if (isUserEntity(entity)) {\n return [currentEntityRef];\n }\n\n if (isGroupEntity(entity)) {\n if (!entity.relations?.length) {\n return [];\n }\n\n const groupUsers = entity.relations\n .filter(\n relation =>\n relation.type === RELATION_HAS_MEMBER &&\n isUserEntityRef(relation.targetRef),\n )\n .map(r => r.targetRef);\n\n const childGroupRefs = entity.relations\n .filter(relation => relation.type === RELATION_PARENT_OF)\n .map(r => r.targetRef);\n\n let childGroupUsers: string[][] = [];\n if (childGroupRefs.length > 0) {\n const childGroups = await catalogClient.getEntitiesByRefs(\n {\n entityRefs: childGroupRefs,\n fields,\n },\n { token },\n );\n childGroupUsers = await Promise.all(childGroups.items.map(mapEntity));\n }\n\n return [...groupUsers, ...childGroupUsers.flat(2)].filter(\n ref => !excluded.includes(ref),\n );\n }\n\n if (entity.relations?.length) {\n const ownerRef = entity.relations.find(\n relation => relation.type === RELATION_OWNED_BY,\n )?.targetRef;\n\n if (!ownerRef) {\n return [];\n }\n\n if (isUserEntityRef(ownerRef)) {\n if (excluded.includes(ownerRef)) {\n return [];\n }\n return [ownerRef];\n }\n\n const owner = await catalogClient.getEntityByRef(ownerRef, { token });\n return mapEntity(owner);\n }\n\n return [];\n };\n\n for (const entity of entities) {\n const u = await mapEntity(entity);\n users.push(...u);\n }\n\n return [...new Set(users)].filter(Boolean);\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { errorHandler, PluginDatabaseManager } from '@backstage/backend-common';\nimport express, { Request } from 'express';\nimport Router from 'express-promise-router';\nimport {\n DatabaseNotificationsStore,\n normalizeSeverity,\n NotificationGetOptions,\n} from '../database';\nimport { v4 as uuid } from 'uuid';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport {\n NotificationProcessor,\n NotificationSendOptions,\n} from '@backstage/plugin-notifications-node';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport {\n AuthService,\n HttpAuthService,\n LoggerService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { SignalsService } from '@backstage/plugin-signals-node';\nimport {\n NewNotificationSignal,\n Notification,\n NotificationPayload,\n NotificationReadSignal,\n notificationSeverities,\n NotificationStatus,\n} from '@backstage/plugin-notifications-common';\nimport { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams';\nimport { getUsersForEntityRef } from './getUsersForEntityRef';\nimport { Config } from '@backstage/config';\n\n/** @internal */\nexport interface RouterOptions {\n logger: LoggerService;\n config: Config;\n database: PluginDatabaseManager;\n auth: AuthService;\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n signals?: SignalsService;\n catalog: CatalogApi;\n processors?: NotificationProcessor[];\n}\n\n/** @internal */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n config,\n logger,\n database,\n auth,\n httpAuth,\n userInfo,\n catalog,\n processors = [],\n signals,\n } = options;\n\n const store = await DatabaseNotificationsStore.create({ database });\n const frontendBaseUrl = config.getString('app.baseUrl');\n\n const getUser = async (req: Request<unknown>) => {\n const credentials = await httpAuth.credentials(req, { allow: ['user'] });\n const info = await userInfo.getUserInfo(credentials);\n return info.userEntityRef;\n };\n\n const filterProcessors = (payload: NotificationPayload) => {\n const result: NotificationProcessor[] = [];\n\n for (const processor of processors) {\n if (processor.getNotificationFilters) {\n const filters = processor.getNotificationFilters();\n if (filters.minSeverity) {\n if (\n notificationSeverities.indexOf(payload.severity ?? 'normal') >\n notificationSeverities.indexOf(filters.minSeverity)\n ) {\n continue;\n }\n }\n\n if (filters.maxSeverity) {\n if (\n notificationSeverities.indexOf(payload.severity ?? 'normal') <\n notificationSeverities.indexOf(filters.maxSeverity)\n ) {\n continue;\n }\n }\n\n if (filters.excludedTopics && payload.topic) {\n if (filters.excludedTopics.includes(payload.topic)) {\n continue;\n }\n }\n }\n result.push(processor);\n }\n\n return result;\n };\n\n const processOptions = async (opts: NotificationSendOptions) => {\n const filtered = filterProcessors(opts.payload);\n let ret = opts;\n for (const processor of filtered) {\n try {\n ret = processor.processOptions\n ? await processor.processOptions(ret)\n : ret;\n } catch (e) {\n logger.error(\n `Error while processing notification options with ${processor.getName()}: ${e}`,\n );\n }\n }\n return ret;\n };\n\n const preProcessNotification = async (\n notification: Notification,\n opts: NotificationSendOptions,\n ) => {\n const filtered = filterProcessors(notification.payload);\n let ret = notification;\n for (const processor of filtered) {\n try {\n ret = processor.preProcess\n ? await processor.preProcess(ret, opts)\n : ret;\n } catch (e) {\n logger.error(\n `Error while pre processing notification with ${processor.getName()}: ${e}`,\n );\n }\n }\n return ret;\n };\n\n const postProcessNotification = async (\n notification: Notification,\n opts: NotificationSendOptions,\n ) => {\n const filtered = filterProcessors(notification.payload);\n for (const processor of filtered) {\n if (processor.postProcess) {\n try {\n await processor.postProcess(notification, opts);\n } catch (e) {\n logger.error(\n `Error while post processing notification with ${processor.getName()}: ${e}`,\n );\n }\n }\n }\n };\n\n const validateLink = (link: string) => {\n const stripLeadingSlash = (s: string) => s.replace(/^\\//, '');\n const ensureTrailingSlash = (s: string) => s.replace(/\\/?$/, '/');\n const url = new URL(\n stripLeadingSlash(link),\n ensureTrailingSlash(frontendBaseUrl),\n );\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n throw new Error('Only HTTP/HTTPS links are allowed');\n }\n };\n\n // TODO: Move to use OpenAPI router instead\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\n response.json({ status: 'ok' });\n });\n\n router.get('/', async (req, res) => {\n const user = await getUser(req);\n const opts: NotificationGetOptions = {\n user: user,\n };\n if (req.query.offset) {\n opts.offset = Number.parseInt(req.query.offset.toString(), 10);\n }\n if (req.query.limit) {\n opts.limit = Number.parseInt(req.query.limit.toString(), 10);\n }\n if (req.query.orderField) {\n opts.orderField = parseEntityOrderFieldParams(req.query);\n }\n if (req.query.search) {\n opts.search = req.query.search.toString();\n }\n if (req.query.read === 'true') {\n opts.read = true;\n } else if (req.query.read === 'false') {\n opts.read = false;\n // or keep undefined\n }\n\n if (req.query.topic) {\n opts.topic = req.query.topic.toString();\n }\n\n if (req.query.saved === 'true') {\n opts.saved = true;\n } else if (req.query.saved === 'false') {\n opts.saved = false;\n // or keep undefined\n }\n if (req.query.createdAfter) {\n const sinceEpoch = Date.parse(String(req.query.createdAfter));\n if (isNaN(sinceEpoch)) {\n throw new InputError('Unexpected date format');\n }\n opts.createdAfter = new Date(sinceEpoch);\n }\n if (req.query.minimumSeverity) {\n opts.minimumSeverity = normalizeSeverity(\n req.query.minimumSeverity.toString(),\n );\n }\n\n const [notifications, totalCount] = await Promise.all([\n store.getNotifications(opts),\n store.getNotificationsCount(opts),\n ]);\n res.json({\n totalCount,\n notifications,\n });\n });\n\n router.get('/status', async (req: Request<any, NotificationStatus>, res) => {\n const user = await getUser(req);\n const status = await store.getStatus({ user });\n res.json(status);\n });\n\n // Make sure this is the last \"GET\" handler\n router.get('/:id', async (req, res) => {\n const user = await getUser(req);\n const opts: NotificationGetOptions = {\n user: user,\n limit: 1,\n ids: [req.params.id],\n };\n const notifications = await store.getNotifications(opts);\n if (notifications.length !== 1) {\n throw new NotFoundError('Not found');\n }\n res.json(notifications[0]);\n });\n\n router.post('/update', async (req, res) => {\n const user = await getUser(req);\n const { ids, read, saved } = req.body;\n if (!ids || !Array.isArray(ids)) {\n throw new InputError();\n }\n\n if (read === true) {\n await store.markRead({ user, ids });\n\n if (signals) {\n await signals.publish<NotificationReadSignal>({\n recipients: { type: 'user', entityRef: [user] },\n message: { action: 'notification_read', notification_ids: ids },\n channel: 'notifications',\n });\n }\n } else if (read === false) {\n await store.markUnread({ user: user, ids });\n\n if (signals) {\n await signals.publish<NotificationReadSignal>({\n recipients: { type: 'user', entityRef: [user] },\n message: { action: 'notification_unread', notification_ids: ids },\n channel: 'notifications',\n });\n }\n }\n\n if (saved === true) {\n await store.markSaved({ user: user, ids });\n } else if (saved === false) {\n await store.markUnsaved({ user: user, ids });\n }\n\n const notifications = await store.getNotifications({ ids, user: user });\n res.json(notifications);\n });\n\n const sendBroadcastNotification = async (\n baseNotification: Omit<Notification, 'user' | 'id'>,\n opts: NotificationSendOptions,\n origin: string,\n ) => {\n const { scope } = opts.payload;\n const broadcastNotification = {\n ...baseNotification,\n user: null,\n id: uuid(),\n };\n const notification = await preProcessNotification(\n broadcastNotification,\n opts,\n );\n let existingNotification;\n if (scope) {\n existingNotification = await store.getExistingScopeBroadcast({\n scope,\n origin,\n });\n }\n\n let ret = notification;\n if (existingNotification) {\n const restored = await store.restoreExistingNotification({\n id: existingNotification.id,\n notification: { ...notification, user: '' },\n });\n ret = restored ?? notification;\n } else {\n await store.saveBroadcast(notification);\n }\n\n if (signals) {\n await signals.publish<NewNotificationSignal>({\n recipients: { type: 'broadcast' },\n message: {\n action: 'new_notification',\n notification_id: ret.id,\n },\n channel: 'notifications',\n });\n postProcessNotification(ret, opts);\n }\n return notification;\n };\n\n const sendUserNotifications = async (\n baseNotification: Omit<Notification, 'user' | 'id'>,\n users: string[],\n opts: NotificationSendOptions,\n origin: string,\n ) => {\n const notifications = [];\n const { scope } = opts.payload;\n const uniqueUsers = [...new Set(users)];\n for (const user of uniqueUsers) {\n const userNotification = {\n ...baseNotification,\n id: uuid(),\n user,\n };\n const notification = await preProcessNotification(userNotification, opts);\n\n let existingNotification;\n if (scope) {\n existingNotification = await store.getExistingScopeNotification({\n user,\n scope,\n origin,\n });\n }\n\n let ret = notification;\n if (existingNotification) {\n const restored = await store.restoreExistingNotification({\n id: existingNotification.id,\n notification,\n });\n ret = restored ?? notification;\n } else {\n await store.saveNotification(notification);\n }\n\n notifications.push(ret);\n\n if (signals) {\n await signals.publish<NewNotificationSignal>({\n recipients: { type: 'user', entityRef: [user] },\n message: {\n action: 'new_notification',\n notification_id: ret.id,\n },\n channel: 'notifications',\n });\n }\n postProcessNotification(ret, opts);\n }\n return notifications;\n };\n\n // Add new notification\n router.post(\n '/',\n async (req: Request<any, Notification[], NotificationSendOptions>, res) => {\n const opts = await processOptions(req.body);\n const { recipients, payload } = opts;\n const notifications: Notification[] = [];\n let users = [];\n\n const credentials = await httpAuth.credentials(req, {\n allow: ['service'],\n });\n\n const { title, link } = payload;\n\n if (!recipients || !title) {\n logger.error(`Invalid notification request received`);\n throw new InputError(`Invalid notification request received`);\n }\n\n if (link) {\n try {\n validateLink(link);\n } catch (e) {\n throw new InputError('Invalid link provided', e);\n }\n }\n\n const origin = credentials.principal.subject;\n const baseNotification = {\n payload: {\n ...payload,\n severity: payload.severity ?? 'normal',\n },\n origin,\n created: new Date(),\n };\n\n if (recipients.type === 'broadcast') {\n const broadcast = await sendBroadcastNotification(\n baseNotification,\n opts,\n origin,\n );\n notifications.push(broadcast);\n } else {\n const entityRef = recipients.entityRef;\n\n try {\n users = await getUsersForEntityRef(\n entityRef,\n recipients.excludeEntityRef ?? [],\n { auth, catalogClient: catalog },\n );\n } catch (e) {\n logger.error(`Failed to resolve notification receivers: ${e}`);\n throw new InputError('Failed to resolve notification receivers', e);\n }\n\n const userNotifications = await sendUserNotifications(\n baseNotification,\n users,\n opts,\n origin,\n );\n notifications.push(...userNotifications);\n }\n\n res.json(notifications);\n },\n );\n\n router.use(errorHandler());\n return router;\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\nimport { signalsServiceRef } from '@backstage/plugin-signals-node';\nimport {\n NotificationProcessor,\n notificationsProcessingExtensionPoint,\n NotificationsProcessingExtensionPoint,\n} from '@backstage/plugin-notifications-node';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\n\nclass NotificationsProcessingExtensionPointImpl\n implements NotificationsProcessingExtensionPoint\n{\n #processors = new Array<NotificationProcessor>();\n\n addProcessor(\n ...processors: Array<NotificationProcessor | Array<NotificationProcessor>>\n ): void {\n this.#processors.push(...processors.flat());\n }\n\n get processors() {\n return this.#processors;\n }\n}\n\n/**\n * Notifications backend plugin\n *\n * @public\n */\nexport const notificationsPlugin = createBackendPlugin({\n pluginId: 'notifications',\n register(env) {\n const processingExtensions =\n new NotificationsProcessingExtensionPointImpl();\n env.registerExtensionPoint(\n notificationsProcessingExtensionPoint,\n processingExtensions,\n );\n\n env.registerInit({\n deps: {\n auth: coreServices.auth,\n httpAuth: coreServices.httpAuth,\n userInfo: coreServices.userInfo,\n httpRouter: coreServices.httpRouter,\n logger: coreServices.logger,\n database: coreServices.database,\n signals: signalsServiceRef,\n config: coreServices.rootConfig,\n catalog: catalogServiceRef,\n },\n async init({\n auth,\n httpAuth,\n userInfo,\n httpRouter,\n logger,\n database,\n signals,\n config,\n catalog,\n }) {\n httpRouter.use(\n await createRouter({\n auth,\n httpAuth,\n userInfo,\n logger,\n config,\n database,\n catalog,\n signals,\n processors: processingExtensions.processors,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["resolvePackagePath","notificationSeverities","InputError","parseEntityRef","stringifyEntityRef","isUserEntity","isGroupEntity","RELATION_HAS_MEMBER","RELATION_PARENT_OF","RELATION_OWNED_BY","Router","express","NotFoundError","uuid","errorHandler","createBackendPlugin","notificationsProcessingExtensionPoint","coreServices","signalsServiceRef","catalogServiceRef"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-notifications-backend",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1-next.0",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"role": "backend-plugin",
|
|
6
6
|
"pluginId": "notifications",
|
|
@@ -38,18 +38,18 @@
|
|
|
38
38
|
"test": "backstage-cli package test"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@backstage/backend-common": "^0.25.0
|
|
42
|
-
"@backstage/backend-plugin-api": "^1.0.
|
|
43
|
-
"@backstage/catalog-client": "^1.7.0
|
|
44
|
-
"@backstage/catalog-model": "^1.
|
|
41
|
+
"@backstage/backend-common": "^0.25.0",
|
|
42
|
+
"@backstage/backend-plugin-api": "^1.0.1-next.0",
|
|
43
|
+
"@backstage/catalog-client": "^1.7.0",
|
|
44
|
+
"@backstage/catalog-model": "^1.7.0",
|
|
45
45
|
"@backstage/config": "^1.2.0",
|
|
46
46
|
"@backstage/errors": "^1.2.4",
|
|
47
|
-
"@backstage/plugin-auth-node": "^0.5.
|
|
48
|
-
"@backstage/plugin-catalog-node": "^1.
|
|
49
|
-
"@backstage/plugin-events-node": "^0.4.
|
|
47
|
+
"@backstage/plugin-auth-node": "^0.5.3-next.0",
|
|
48
|
+
"@backstage/plugin-catalog-node": "^1.13.1-next.0",
|
|
49
|
+
"@backstage/plugin-events-node": "^0.4.1-next.0",
|
|
50
50
|
"@backstage/plugin-notifications-common": "^0.0.5",
|
|
51
|
-
"@backstage/plugin-notifications-node": "^0.2.
|
|
52
|
-
"@backstage/plugin-signals-node": "^0.1.
|
|
51
|
+
"@backstage/plugin-notifications-node": "^0.2.7-next.0",
|
|
52
|
+
"@backstage/plugin-signals-node": "^0.1.12-next.0",
|
|
53
53
|
"express": "^4.17.1",
|
|
54
54
|
"express-promise-router": "^4.1.0",
|
|
55
55
|
"knex": "^3.0.0",
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
"yn": "^4.0.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@backstage/backend-defaults": "^0.5.
|
|
63
|
-
"@backstage/backend-test-utils": "^1.0.
|
|
64
|
-
"@backstage/cli": "^0.
|
|
65
|
-
"@backstage/plugin-auth-backend": "^0.23.
|
|
66
|
-
"@backstage/plugin-auth-backend-module-guest-provider": "^0.2.
|
|
67
|
-
"@backstage/plugin-events-backend": "^0.3.
|
|
68
|
-
"@backstage/plugin-signals-backend": "^0.2.
|
|
62
|
+
"@backstage/backend-defaults": "^0.5.1-next.0",
|
|
63
|
+
"@backstage/backend-test-utils": "^1.0.1-next.0",
|
|
64
|
+
"@backstage/cli": "^0.28.0-next.0",
|
|
65
|
+
"@backstage/plugin-auth-backend": "^0.23.1-next.0",
|
|
66
|
+
"@backstage/plugin-auth-backend-module-guest-provider": "^0.2.1-next.0",
|
|
67
|
+
"@backstage/plugin-events-backend": "^0.3.13-next.0",
|
|
68
|
+
"@backstage/plugin-signals-backend": "^0.2.1-next.0",
|
|
69
69
|
"@types/express": "^4.17.6",
|
|
70
70
|
"@types/supertest": "^2.0.8",
|
|
71
71
|
"msw": "^1.0.0",
|