Files
speckle-server/packages/server/modules/notifications/services/notificationPreferences.ts
T
Gergő Jedlicska d1d5984e30 gergo/summaryEmails (#979)
* refactor(server emails): email transports module refactor to TypeScript

* refactor(docker-compose deps): move local email server to common dev compose file

* chore(server launch.json): add ts-node script running example

* chore(server deps): add nodemailer types package

* refactor(server activitystream): add strongly typed activity definitions

* feat(server activitystream): add activity repository

* feat(server info): add canonical url on the service level

* feat(server): add static file serving route to server core

* feat(server): add dependencies for periodical email digests

* feat(server activity stream): call the initialization step from the activity stream module

* feat(server activity digest): add WIP weekly email digest implementation

* feat(server digest email): smul upgrades and fixes to the email template and its contents

* just for Fabs to test

* chore(root package.json): remove deleted docker-compose references

* feat(frontend profile): add notification preferences panel

* feat(server digest emails): set prod ready cron tab and timespan

* refactor(server email digest): move templates into the email module

* refactor(server activity digests): refactor to use notifications infrastructure

* test(server activities): add tests and some refactor to activities and notification preferences

* refactor(notification preferences): fix minor issues

* test(server notification preferences test): fix describe nesting

* fix(server activities): add missing action types

* fix(server activities): fix errors after merging main

* test(server activity notifications): add test coverage for activity notifications service

* refactor(server activities): fixing tests and some cleanup

* feat(server cli): add summary notification command to cli

* chore(dev env db versions): upgrade local dev env versions

* chore(server deps): upgrade local dev db to pg 14

* fix(docker-compose): bind maildev to localhost

* process-scoped notifications test queues

* test(activity tests): add  sleep to fix flaky CI

* feat(activity digests): add demo date for digest trigger

* feat(activity digest): add UK timezone trigger date

Co-authored-by: Iain Sproat <68657+iainsproat@users.noreply.github.com>
Co-authored-by: Fabians <fabis94@live.com>
2022-09-09 12:46:57 +02:00

64 lines
2.4 KiB
TypeScript

import * as repo from '@/modules/notifications/repositories'
import {
NotificationChannel,
NotificationType,
NotificationPreferences
} from '@/modules/notifications/helpers/types'
import { InvalidArgumentError } from '@/modules/shared/errors'
export async function getUserNotificationPreferences(
userId: string
): Promise<NotificationPreferences> {
const savedPreferences = await repo.getUserNotificationPreferences(userId)
return addDefaultPreferenceValues(savedPreferences)
}
export function addDefaultPreferenceValues(
preferences: NotificationPreferences
): NotificationPreferences {
const savedPreferences = { ...preferences }
Object.values(NotificationType).forEach((nt) => {
const notificationTypeSettings = savedPreferences[nt] ?? {}
Object.values(NotificationChannel).forEach((nc) => {
notificationTypeSettings[nc] = notificationTypeSettings[nc] ?? true
})
savedPreferences[nt] = notificationTypeSettings
})
return savedPreferences
}
export async function updateNotificationPreferences(
userId: string,
rawPreferences: Record<string, unknown>
): Promise<void> {
const parsedPreferences: NotificationPreferences = {}
// lets do some nested attribute copying, to sanitize the input
for (const key in rawPreferences) {
if (!Object.values(NotificationType).includes(key as NotificationType))
throw new InvalidArgumentError(
`Notification preferences input contains an unknown setting: ${key}`
)
const nt = key as NotificationType
const notificationTypePreferences: Partial<Record<NotificationChannel, boolean>> =
{}
const notificationTypeSettings = rawPreferences[nt] as Record<string, unknown>
for (const ncKey in notificationTypeSettings) {
if (!Object.values(NotificationChannel).includes(ncKey as NotificationChannel))
throw new InvalidArgumentError(
`Notification preferences input contains an unknown setting: ${ncKey}`
)
const nc = ncKey as NotificationChannel
const preferenceValue = notificationTypeSettings[nc]
if (typeof preferenceValue !== 'boolean')
throw new InvalidArgumentError(
`Notification preferences input contains and invalid value: ${preferenceValue}`
)
notificationTypePreferences[nc] = preferenceValue
}
parsedPreferences[nt] = notificationTypePreferences
}
return await repo.saveUserNotificationPreferences(userId, parsedPreferences)
}