mirror of
https://github.com/xtr-dev/payload-notifications.git
synced 2025-12-10 10:53:23 +00:00
Refactor: Simplify notifications plugin configuration, remove unused code, and improve channel handling
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Client-side Push Notification Manager
|
||||
* Handles subscription, permission requests, and communication with the server
|
||||
*
|
||||
*
|
||||
* @description This module is designed to run in browser environments only
|
||||
*/
|
||||
|
||||
@@ -17,9 +17,9 @@ export interface PushSubscriptionData {
|
||||
const isBrowser = typeof window !== 'undefined'
|
||||
|
||||
export class ClientPushManager {
|
||||
private vapidPublicKey: string
|
||||
private serviceWorkerPath: string
|
||||
private apiEndpoint: string
|
||||
private readonly vapidPublicKey: string
|
||||
private readonly serviceWorkerPath: string
|
||||
private readonly apiEndpoint: string
|
||||
|
||||
constructor(
|
||||
vapidPublicKey: string,
|
||||
@@ -38,7 +38,7 @@ export class ClientPushManager {
|
||||
*/
|
||||
public isSupported(): boolean {
|
||||
if (!isBrowser) return false
|
||||
|
||||
|
||||
return (
|
||||
'serviceWorker' in navigator &&
|
||||
'PushManager' in window &&
|
||||
@@ -62,8 +62,7 @@ export class ClientPushManager {
|
||||
throw new Error('Push notifications are not supported')
|
||||
}
|
||||
|
||||
const permission = await Notification.requestPermission()
|
||||
return permission
|
||||
return await Notification.requestPermission()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +86,7 @@ export class ClientPushManager {
|
||||
/**
|
||||
* Subscribe to push notifications
|
||||
*/
|
||||
public async subscribe(): Promise<PushSubscriptionData> {
|
||||
public async subscribe(channels: string[]): Promise<PushSubscriptionData> {
|
||||
// Check support
|
||||
if (!this.isSupported()) {
|
||||
throw new Error('Push notifications are not supported')
|
||||
@@ -120,7 +119,7 @@ export class ClientPushManager {
|
||||
}
|
||||
|
||||
// Send subscription to server
|
||||
await this.sendSubscriptionToServer(subscriptionData)
|
||||
await this.sendSubscriptionToServer(subscriptionData, channels)
|
||||
|
||||
return subscriptionData
|
||||
}
|
||||
@@ -149,9 +148,9 @@ export class ClientPushManager {
|
||||
/**
|
||||
* Get current push subscription
|
||||
*/
|
||||
public async getSubscription(): Promise<PushSubscriptionData | null> {
|
||||
public async getSubscription(): Promise<Omit<PushSubscriptionData, 'channels'> | null> {
|
||||
if (!isBrowser || !('serviceWorker' in navigator)) return null
|
||||
|
||||
|
||||
const registration = await navigator.serviceWorker.getRegistration()
|
||||
if (!registration) {
|
||||
return null
|
||||
@@ -183,7 +182,7 @@ export class ClientPushManager {
|
||||
/**
|
||||
* Send subscription data to server
|
||||
*/
|
||||
private async sendSubscriptionToServer(subscription: PushSubscriptionData): Promise<void> {
|
||||
private async sendSubscriptionToServer(subscription: PushSubscriptionData, channels: string[]): Promise<void> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiEndpoint}/subscribe`, {
|
||||
method: 'POST',
|
||||
@@ -192,6 +191,7 @@ export class ClientPushManager {
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subscription,
|
||||
channels,
|
||||
userAgent: navigator.userAgent,
|
||||
}),
|
||||
})
|
||||
@@ -251,4 +251,4 @@ export class ClientPushManager {
|
||||
const binary = Array.from(bytes).map(b => String.fromCharCode(b)).join('')
|
||||
return window.btoa(binary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,32 @@
|
||||
import type { CollectionConfig, Field } from 'payload'
|
||||
import type { NotificationsPluginOptions, NotificationAccess } from '../types'
|
||||
import { buildRelationshipFields } from '../utils/buildFields'
|
||||
import type { NotificationsPluginOptions } from '../types'
|
||||
import { WebPushManager } from '../utils/webPush'
|
||||
import { defaultNotificationTransformer } from '../utils/richTextExtractor'
|
||||
|
||||
/**
|
||||
* Creates the notifications collection configuration
|
||||
* Includes core fields plus dynamically generated relationship fields
|
||||
*/
|
||||
export function createNotificationsCollection(options: NotificationsPluginOptions = {}): CollectionConfig {
|
||||
const {
|
||||
collections = {},
|
||||
relationships = [],
|
||||
access = {},
|
||||
fields: customFields = [],
|
||||
} = options
|
||||
|
||||
const slug = collections.slug || 'notifications'
|
||||
export function createNotificationsCollection(options: NotificationsPluginOptions): CollectionConfig {
|
||||
const slug = 'notifications'
|
||||
const labels = {
|
||||
singular: collections.labels?.singular || 'Notification',
|
||||
plural: collections.labels?.plural || 'Notifications',
|
||||
singular: 'Notification',
|
||||
plural: 'Notifications',
|
||||
}
|
||||
|
||||
if (options.channels.length === 0) {
|
||||
throw new Error('No channels defined for notifications plugin')
|
||||
}
|
||||
|
||||
// Default access control - authenticated users can read, admins can manage
|
||||
const defaultAccess: NotificationAccess = {
|
||||
const access: CollectionConfig['access'] = {
|
||||
read: ({ req }: { req: any }) => Boolean(req.user),
|
||||
create: ({ req }: { req: any }) => Boolean(req.user),
|
||||
update: ({ req }: { req: any }) => Boolean(req.user),
|
||||
delete: ({ req }: { req: any }) => Boolean(req.user?.role === 'admin'),
|
||||
}
|
||||
|
||||
// Build channel field if channels are configured
|
||||
const channelField: Field[] = options.channels && options.channels.length > 0 ? [
|
||||
{
|
||||
name: 'channel',
|
||||
type: 'select',
|
||||
label: 'Channel',
|
||||
options: options.channels.map(channel => ({
|
||||
label: channel.name,
|
||||
value: channel.id,
|
||||
})),
|
||||
required: false,
|
||||
admin: {
|
||||
description: 'The notification channel - only subscribers to this channel will receive the notification',
|
||||
position: 'sidebar',
|
||||
},
|
||||
},
|
||||
] : []
|
||||
|
||||
// Default recipient field (relationship to users)
|
||||
// Users can add custom recipient fields via the fields option and use findSubscriptions hook
|
||||
const recipientField: Field = {
|
||||
name: 'recipient',
|
||||
type: 'relationship',
|
||||
relationTo: 'users',
|
||||
label: 'Recipient',
|
||||
required: false,
|
||||
admin: {
|
||||
description: 'The user who should receive this notification (optional if using custom recipient fields)',
|
||||
},
|
||||
}
|
||||
|
||||
// Build core fields
|
||||
const coreFields: Field[] = [
|
||||
const allFields: Field[] = [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
@@ -81,8 +45,30 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
description: 'The notification message content',
|
||||
},
|
||||
},
|
||||
recipientField,
|
||||
...channelField,
|
||||
{
|
||||
name: 'recipient',
|
||||
type: 'relationship',
|
||||
relationTo: 'users',
|
||||
label: 'Recipient',
|
||||
required: false,
|
||||
admin: {
|
||||
description: 'The user who should receive this notification (optional if using custom recipient fields)',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'channel',
|
||||
type: 'select',
|
||||
label: 'Channel',
|
||||
options: options.channels.map(channel => ({
|
||||
label: channel.name,
|
||||
value: channel.id,
|
||||
})),
|
||||
required: false,
|
||||
admin: {
|
||||
description: 'The notification channel - only subscribers to this channel will receive the notification',
|
||||
position: 'sidebar',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'isRead',
|
||||
type: 'checkbox',
|
||||
@@ -105,12 +91,6 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
},
|
||||
]
|
||||
|
||||
// Build relationship fields
|
||||
const relationshipFields = buildRelationshipFields(relationships)
|
||||
|
||||
// Combine all fields
|
||||
const allFields = [...coreFields, ...relationshipFields, ...customFields]
|
||||
|
||||
const config: CollectionConfig = {
|
||||
slug,
|
||||
labels,
|
||||
@@ -120,12 +100,7 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
description: 'Manage user notifications and messaging',
|
||||
},
|
||||
fields: allFields,
|
||||
access: {
|
||||
read: access.read || defaultAccess.read!,
|
||||
create: access.create || defaultAccess.create!,
|
||||
update: access.update || defaultAccess.update!,
|
||||
delete: access.delete || defaultAccess.delete!,
|
||||
},
|
||||
access,
|
||||
timestamps: true,
|
||||
}
|
||||
|
||||
@@ -155,7 +130,7 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
// Use custom hook to find subscriptions
|
||||
console.log('[Notifications Plugin] Using custom findSubscriptions hook')
|
||||
const subscriptions = await webPushConfig.findSubscriptions(doc, req.payload)
|
||||
|
||||
|
||||
if (!subscriptions || subscriptions.length === 0) {
|
||||
console.log('[Notifications Plugin] No subscriptions found via custom hook')
|
||||
return
|
||||
@@ -199,10 +174,10 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
return { success: false, error }
|
||||
}
|
||||
})
|
||||
).then(results =>
|
||||
).then(results =>
|
||||
results.map((result) =>
|
||||
result.status === 'fulfilled'
|
||||
? result.value
|
||||
result.status === 'fulfilled'
|
||||
? result.value
|
||||
: { success: false, error: result.reason }
|
||||
)
|
||||
)
|
||||
@@ -214,7 +189,7 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
}
|
||||
|
||||
let recipientId: string
|
||||
|
||||
|
||||
if (typeof doc.recipient === 'string') {
|
||||
recipientId = doc.recipient
|
||||
} else if (doc.recipient?.id) {
|
||||
@@ -251,7 +226,7 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
console.log(`[Notifications Plugin] Push notification results: ${successful} sent, ${failed} failed`)
|
||||
|
||||
if (failed > 0) {
|
||||
console.warn('[Notifications Plugin] Some push notifications failed:',
|
||||
console.warn('[Notifications Plugin] Some push notifications failed:',
|
||||
results.filter(r => !r.success).map(r => r.error)
|
||||
)
|
||||
}
|
||||
@@ -265,5 +240,7 @@ export function createNotificationsCollection(options: NotificationsPluginOption
|
||||
}
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
return options.collectionOverrides?.notifications ?
|
||||
options.collectionOverrides.notifications(config) :
|
||||
config
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
import type { NotificationAccess, NotificationsPluginOptions } from '../types'
|
||||
import type { NotificationsPluginOptions } from '../types'
|
||||
|
||||
/**
|
||||
* Creates a collection to store web push subscriptions
|
||||
* Each user can have multiple subscriptions (different devices/browsers)
|
||||
*/
|
||||
export function createPushSubscriptionsCollection(access: NotificationAccess = {}, options: NotificationsPluginOptions = {}): CollectionConfig {
|
||||
const defaultAccess: NotificationAccess = {
|
||||
export function createPushSubscriptionsCollection(options: NotificationsPluginOptions): CollectionConfig {
|
||||
const access: CollectionConfig['access'] = {
|
||||
read: ({ req }: { req: any }) => Boolean(req.user),
|
||||
create: ({ req }: { req: any }) => Boolean(req.user),
|
||||
update: ({ req }: { req: any }) => Boolean(req.user),
|
||||
delete: ({ req }: { req: any }) => Boolean(req.user),
|
||||
}
|
||||
|
||||
return {
|
||||
const config: CollectionConfig = {
|
||||
slug: 'push-subscriptions',
|
||||
labels: {
|
||||
singular: 'Push Subscription',
|
||||
@@ -76,16 +76,11 @@ export function createPushSubscriptionsCollection(access: NotificationAccess = {
|
||||
name: 'channels',
|
||||
type: 'select',
|
||||
label: 'Subscribed Channels',
|
||||
options: options.channels && options.channels.length > 0
|
||||
? options.channels.map(channel => ({
|
||||
label: channel.name,
|
||||
value: channel.id,
|
||||
}))
|
||||
: [{ label: 'All Notifications', value: 'all' }],
|
||||
options: options.channels.map(channel => ({
|
||||
label: channel.name,
|
||||
value: channel.id,
|
||||
})),
|
||||
hasMany: true,
|
||||
defaultValue: options.channels && options.channels.length > 0
|
||||
? options.channels.filter(channel => channel.defaultEnabled !== false).map(channel => channel.id)
|
||||
: ['all'],
|
||||
admin: {
|
||||
description: 'Channels this subscription is subscribed to - leave empty for all notifications',
|
||||
},
|
||||
@@ -101,12 +96,7 @@ export function createPushSubscriptionsCollection(access: NotificationAccess = {
|
||||
},
|
||||
},
|
||||
],
|
||||
access: {
|
||||
read: access.read || defaultAccess.read!,
|
||||
create: access.create || defaultAccess.create!,
|
||||
update: access.update || defaultAccess.update!,
|
||||
delete: access.delete || defaultAccess.delete!,
|
||||
},
|
||||
access,
|
||||
timestamps: true,
|
||||
hooks: {
|
||||
beforeChange: [
|
||||
@@ -120,4 +110,7 @@ export function createPushSubscriptionsCollection(access: NotificationAccess = {
|
||||
],
|
||||
},
|
||||
}
|
||||
return options.collectionOverrides?.pushSubscriptions ?
|
||||
options.collectionOverrides.pushSubscriptions(config) :
|
||||
config
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export function createPushNotificationEndpoints(options: NotificationsPluginOpti
|
||||
}
|
||||
|
||||
const webPushConfig = options.webPush
|
||||
|
||||
|
||||
return [
|
||||
// Subscribe endpoint
|
||||
{
|
||||
@@ -35,7 +35,6 @@ export function createPushNotificationEndpoints(options: NotificationsPluginOpti
|
||||
}
|
||||
|
||||
const pushManager = new WebPushManager(webPushConfig, req.payload)
|
||||
|
||||
await pushManager.subscribe(
|
||||
String(req.user.id),
|
||||
subscription,
|
||||
@@ -247,4 +246,4 @@ export function createPushNotificationEndpoints(options: NotificationsPluginOpti
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,4 @@ export type {
|
||||
WebPushConfig,
|
||||
PushSubscription,
|
||||
NotificationsPluginOptions,
|
||||
NotificationRelationship,
|
||||
NotificationCollectionConfig,
|
||||
NotificationAccess,
|
||||
} from '../types'
|
||||
} from '../types'
|
||||
|
||||
31
src/index.ts
31
src/index.ts
@@ -4,23 +4,33 @@ import { createNotificationsCollection } from './collections/notifications'
|
||||
import { createPushSubscriptionsCollection } from './collections/push-subscriptions'
|
||||
import { createPushNotificationEndpoints } from './endpoints/push-notifications'
|
||||
|
||||
const defaultOptions: NotificationsPluginOptions = {
|
||||
channels: [
|
||||
{
|
||||
name: 'Default',
|
||||
id: 'default',
|
||||
description: 'Default channel',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* PayloadCMS Notifications Plugin
|
||||
*
|
||||
*
|
||||
* Adds a configurable notifications collection with support for:
|
||||
* - Title and rich text message content
|
||||
* - Recipient targeting
|
||||
* - Recipient targeting
|
||||
* - Read/unread status tracking
|
||||
* - Configurable relationship attachments to any collection
|
||||
*
|
||||
*
|
||||
* @param options Plugin configuration options
|
||||
* @returns Configured PayloadCMS plugin
|
||||
*/
|
||||
export const notificationsPlugin: NotificationsPlugin = (options = {}) => {
|
||||
export const notificationsPlugin: NotificationsPlugin = (options = defaultOptions) => {
|
||||
return (config: Config): Config => {
|
||||
// Create the notifications collection with provided options
|
||||
const notificationsCollection = createNotificationsCollection(options)
|
||||
|
||||
|
||||
// Add collections to the Payload config
|
||||
const collections = config.collections || []
|
||||
const newCollections = [
|
||||
@@ -30,16 +40,16 @@ export const notificationsPlugin: NotificationsPlugin = (options = {}) => {
|
||||
|
||||
// Add push subscriptions collection if web push is enabled
|
||||
if (options.webPush?.enabled) {
|
||||
const pushSubscriptionsCollection = createPushSubscriptionsCollection(options.access, options)
|
||||
const pushSubscriptionsCollection = createPushSubscriptionsCollection(options)
|
||||
newCollections.push(pushSubscriptionsCollection)
|
||||
}
|
||||
|
||||
// Create push notification endpoints if web push is enabled
|
||||
const endpoints = config.endpoints || []
|
||||
const pushEndpoints = options.webPush?.enabled
|
||||
const pushEndpoints = options.webPush?.enabled
|
||||
? createPushNotificationEndpoints(options)
|
||||
: []
|
||||
|
||||
|
||||
return {
|
||||
...config,
|
||||
collections: newCollections,
|
||||
@@ -54,12 +64,9 @@ export const notificationsPlugin: NotificationsPlugin = (options = {}) => {
|
||||
// Export types for consumers
|
||||
export type {
|
||||
NotificationsPluginOptions,
|
||||
NotificationRelationship,
|
||||
NotificationCollectionConfig,
|
||||
NotificationAccess,
|
||||
NotificationChannel,
|
||||
WebPushConfig,
|
||||
} from './types'
|
||||
|
||||
// Default export
|
||||
export default notificationsPlugin
|
||||
export default notificationsPlugin
|
||||
|
||||
66
src/types.ts
66
src/types.ts
@@ -1,44 +1,5 @@
|
||||
import type { Config, CollectionConfig, Access, Field } from 'payload'
|
||||
import type * as webpush from 'web-push'
|
||||
|
||||
/**
|
||||
* Configuration for a relationship field in the notifications collection
|
||||
*/
|
||||
export interface NotificationRelationship {
|
||||
/** Field name in the attachments group */
|
||||
name: string
|
||||
/** Target collection slug to relate to */
|
||||
relationTo: string
|
||||
/** Label displayed in admin UI */
|
||||
label?: string
|
||||
/** Whether this relationship is required */
|
||||
required?: boolean
|
||||
/** Allow multiple selections */
|
||||
hasMany?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection configuration options
|
||||
*/
|
||||
export interface NotificationCollectionConfig {
|
||||
/** Collection slug */
|
||||
slug?: string
|
||||
/** Collection labels for admin UI */
|
||||
labels?: {
|
||||
singular?: string
|
||||
plural?: string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Access control configuration for notifications collection
|
||||
*/
|
||||
export interface NotificationAccess {
|
||||
read?: Access
|
||||
create?: Access
|
||||
update?: Access
|
||||
delete?: Access
|
||||
}
|
||||
import type {CollectionConfig, Config} from 'payload'
|
||||
import type {RequestOptions} from 'web-push'
|
||||
|
||||
/**
|
||||
* Web push subscription data structure
|
||||
@@ -61,8 +22,6 @@ export interface NotificationChannel {
|
||||
name: string
|
||||
/** Channel description */
|
||||
description?: string
|
||||
/** Default enabled state for new subscriptions */
|
||||
defaultEnabled?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +37,7 @@ export interface WebPushConfig {
|
||||
/** Enable web push notifications */
|
||||
enabled?: boolean
|
||||
/** Custom push notification options */
|
||||
options?: webpush.RequestOptions
|
||||
options?: RequestOptions
|
||||
/** Automatically send push notifications when notifications are created */
|
||||
autoPush?: boolean
|
||||
/** Custom notification content transformer */
|
||||
@@ -93,8 +52,8 @@ export interface WebPushConfig {
|
||||
tag?: string
|
||||
requireInteraction?: boolean
|
||||
}
|
||||
/**
|
||||
* Custom hook to find push subscriptions for a notification
|
||||
/**
|
||||
* Custom hook to find push subscriptions for a notification
|
||||
* This allows implementing anonymous notifications or custom recipient logic
|
||||
* If not provided, defaults to user-based subscriptions
|
||||
*/
|
||||
@@ -106,20 +65,17 @@ export interface WebPushConfig {
|
||||
*/
|
||||
export interface NotificationsPluginOptions {
|
||||
/** Collection configuration */
|
||||
collections?: NotificationCollectionConfig
|
||||
/** Array of configurable relationship fields */
|
||||
relationships?: NotificationRelationship[]
|
||||
/** Custom access control functions */
|
||||
access?: NotificationAccess
|
||||
/** Additional custom fields to add to the collection */
|
||||
fields?: Field[]
|
||||
collectionOverrides?: {
|
||||
notifications: (config: CollectionConfig) => CollectionConfig
|
||||
pushSubscriptions: (config: CollectionConfig) => CollectionConfig
|
||||
}
|
||||
/** Web push notification configuration */
|
||||
webPush?: WebPushConfig
|
||||
/** Notification channels configuration */
|
||||
channels?: NotificationChannel[]
|
||||
channels: NotificationChannel[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin function type
|
||||
*/
|
||||
export type NotificationsPlugin = (options?: NotificationsPluginOptions) => (config: Config) => Config
|
||||
export type NotificationsPlugin = (options?: NotificationsPluginOptions) => (config: Config) => Config
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import type { Field } from 'payload'
|
||||
import type { NotificationRelationship } from '../types'
|
||||
|
||||
/**
|
||||
* Builds relationship fields dynamically based on plugin configuration
|
||||
* Creates individual relationship fields within an attachments group
|
||||
*/
|
||||
export function buildRelationshipFields(relationships: NotificationRelationship[]): Field[] {
|
||||
if (!relationships || relationships.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
// Create individual relationship fields
|
||||
const relationshipFields: Field[] = relationships.map((rel) => {
|
||||
const baseField = {
|
||||
name: rel.name,
|
||||
type: 'relationship' as const,
|
||||
relationTo: rel.relationTo,
|
||||
label: rel.label || `Related ${rel.relationTo}`,
|
||||
required: rel.required || false,
|
||||
}
|
||||
|
||||
// Add hasMany conditionally to satisfy the type constraints
|
||||
if (rel.hasMany) {
|
||||
return {
|
||||
...baseField,
|
||||
hasMany: true,
|
||||
}
|
||||
}
|
||||
|
||||
return baseField
|
||||
})
|
||||
|
||||
// Wrap relationship fields in a group called "attachments"
|
||||
return [
|
||||
{
|
||||
name: 'attachments',
|
||||
type: 'group',
|
||||
label: 'Attachments',
|
||||
fields: relationshipFields,
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -151,8 +151,8 @@ export class WebPushManager {
|
||||
)
|
||||
|
||||
return results.map((result) =>
|
||||
result.status === 'fulfilled'
|
||||
? result.value
|
||||
result.status === 'fulfilled'
|
||||
? result.value
|
||||
: { success: false, error: result.reason }
|
||||
)
|
||||
}
|
||||
@@ -211,11 +211,20 @@ export class WebPushManager {
|
||||
p256dh: subscription.keys.p256dh,
|
||||
auth: subscription.keys.auth,
|
||||
userAgent,
|
||||
channels: channels || ['all'],
|
||||
channels,
|
||||
isActive: true,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
console.info({
|
||||
user: userId,
|
||||
endpoint: subscription.endpoint,
|
||||
p256dh: subscription.keys.p256dh,
|
||||
auth: subscription.keys.auth,
|
||||
userAgent,
|
||||
channels,
|
||||
isActive: true,
|
||||
})
|
||||
// Create new subscription
|
||||
await this.payload.create({
|
||||
collection: 'push-subscriptions',
|
||||
@@ -225,7 +234,7 @@ export class WebPushManager {
|
||||
p256dh: subscription.keys.p256dh,
|
||||
auth: subscription.keys.auth,
|
||||
userAgent,
|
||||
channels: channels || ['all'],
|
||||
channels,
|
||||
isActive: true,
|
||||
},
|
||||
})
|
||||
@@ -268,4 +277,4 @@ export class WebPushManager {
|
||||
public getVapidPublicKey(): string {
|
||||
return this.config.vapidPublicKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user