aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-03-11 16:54:52 +0100
committerChocobozzz <me@florianbigard.com>2021-03-24 18:18:41 +0100
commit32a18cbf33a7cdbbe3d4885d32e4b67e19cdc1cf (patch)
tree1db53245688a6b7839cab00f9d65e6c1c1774b00 /server/lib
parent3fbc6974334ca58c068f0f9def0b0a40db2a6de1 (diff)
downloadPeerTube-32a18cbf33a7cdbbe3d4885d32e4b67e19cdc1cf.tar.gz
PeerTube-32a18cbf33a7cdbbe3d4885d32e4b67e19cdc1cf.tar.zst
PeerTube-32a18cbf33a7cdbbe3d4885d32e4b67e19cdc1cf.zip
Add new plugin/peertube version notifs
Diffstat (limited to 'server/lib')
-rw-r--r--server/lib/emailer.ts42
-rw-r--r--server/lib/emails/peertube-version-new/html.pug9
-rw-r--r--server/lib/emails/plugin-version-new/html.pug9
-rw-r--r--server/lib/notifier.ts74
-rw-r--r--server/lib/schedulers/peertube-version-check-scheduler.ts55
-rw-r--r--server/lib/schedulers/plugins-check-scheduler.ts6
-rw-r--r--server/lib/user.ts4
7 files changed, 194 insertions, 5 deletions
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts
index 969eae77b..187d4e86d 100644
--- a/server/lib/emailer.ts
+++ b/server/lib/emailer.ts
@@ -12,7 +12,7 @@ import { isTestInstance, root } from '../helpers/core-utils'
12import { bunyanLogger, logger } from '../helpers/logger' 12import { bunyanLogger, logger } from '../helpers/logger'
13import { CONFIG, isEmailEnabled } from '../initializers/config' 13import { CONFIG, isEmailEnabled } from '../initializers/config'
14import { WEBSERVER } from '../initializers/constants' 14import { WEBSERVER } from '../initializers/constants'
15import { MAbuseFull, MAbuseMessage, MAccountDefault, MActorFollowActors, MActorFollowFull, MUser } from '../types/models' 15import { MAbuseFull, MAbuseMessage, MAccountDefault, MActorFollowActors, MActorFollowFull, MPlugin, MUser } from '../types/models'
16import { MCommentOwnerVideo, MVideo, MVideoAccountLight } from '../types/models/video' 16import { MCommentOwnerVideo, MVideo, MVideoAccountLight } from '../types/models/video'
17import { JobQueue } from './job-queue' 17import { JobQueue } from './job-queue'
18 18
@@ -403,7 +403,7 @@ class Emailer {
403 } 403 }
404 404
405 async addVideoAutoBlacklistModeratorsNotification (to: string[], videoBlacklist: MVideoBlacklistLightVideo) { 405 async addVideoAutoBlacklistModeratorsNotification (to: string[], videoBlacklist: MVideoBlacklistLightVideo) {
406 const VIDEO_AUTO_BLACKLIST_URL = WEBSERVER.URL + '/admin/moderation/video-auto-blacklist/list' 406 const videoAutoBlacklistUrl = WEBSERVER.URL + '/admin/moderation/video-auto-blacklist/list'
407 const videoUrl = WEBSERVER.URL + videoBlacklist.Video.getWatchStaticPath() 407 const videoUrl = WEBSERVER.URL + videoBlacklist.Video.getWatchStaticPath()
408 const channel = (await VideoChannelModel.loadByIdAndPopulateAccount(videoBlacklist.Video.channelId)).toFormattedSummaryJSON() 408 const channel = (await VideoChannelModel.loadByIdAndPopulateAccount(videoBlacklist.Video.channelId)).toFormattedSummaryJSON()
409 409
@@ -417,7 +417,7 @@ class Emailer {
417 videoName: videoBlacklist.Video.name, 417 videoName: videoBlacklist.Video.name,
418 action: { 418 action: {
419 text: 'Review autoblacklist', 419 text: 'Review autoblacklist',
420 url: VIDEO_AUTO_BLACKLIST_URL 420 url: videoAutoBlacklistUrl
421 } 421 }
422 } 422 }
423 } 423 }
@@ -472,6 +472,42 @@ class Emailer {
472 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) 472 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
473 } 473 }
474 474
475 addNewPeerTubeVersionNotification (to: string[], latestVersion: string) {
476 const subject = `A new PeerTube version is available: ${latestVersion}`
477
478 const emailPayload: EmailPayload = {
479 to,
480 template: 'peertube-version-new',
481 subject,
482 text: subject,
483 locals: {
484 latestVersion
485 }
486 }
487
488 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
489 }
490
491 addNewPlugionVersionNotification (to: string[], plugin: MPlugin) {
492 const pluginUrl = WEBSERVER.URL + '/admin/plugins/list-installed?pluginType=' + plugin.type
493
494 const subject = `A new plugin/theme version is available: ${plugin.name}@${plugin.latestVersion}`
495
496 const emailPayload: EmailPayload = {
497 to,
498 template: 'plugin-version-new',
499 subject,
500 text: subject,
501 locals: {
502 pluginName: plugin.name,
503 latestVersion: plugin.latestVersion,
504 pluginUrl
505 }
506 }
507
508 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
509 }
510
475 addPasswordResetEmailJob (username: string, to: string, resetPasswordUrl: string) { 511 addPasswordResetEmailJob (username: string, to: string, resetPasswordUrl: string) {
476 const emailPayload: EmailPayload = { 512 const emailPayload: EmailPayload = {
477 template: 'password-reset', 513 template: 'password-reset',
diff --git a/server/lib/emails/peertube-version-new/html.pug b/server/lib/emails/peertube-version-new/html.pug
new file mode 100644
index 000000000..2f4d9399d
--- /dev/null
+++ b/server/lib/emails/peertube-version-new/html.pug
@@ -0,0 +1,9 @@
1extends ../common/greetings
2
3block title
4 | New PeerTube version available
5
6block content
7 p
8 | A new version of PeerTube is available: #{latestVersion}.
9 | You can check the latest news on #[a(href="https://joinpeertube.org/news") JoinPeerTube].
diff --git a/server/lib/emails/plugin-version-new/html.pug b/server/lib/emails/plugin-version-new/html.pug
new file mode 100644
index 000000000..86d3d87e8
--- /dev/null
+++ b/server/lib/emails/plugin-version-new/html.pug
@@ -0,0 +1,9 @@
1extends ../common/greetings
2
3block title
4 | New plugin version available
5
6block content
7 p
8 | A new version of the plugin/theme #{pluginName} is available: #{latestVersion}.
9 | You might want to upgrade it on #[a(href=pluginUrl) the PeerTube admin interface].
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts
index 740c274d7..da7f7cc05 100644
--- a/server/lib/notifier.ts
+++ b/server/lib/notifier.ts
@@ -19,7 +19,7 @@ import { CONFIG } from '../initializers/config'
19import { AccountBlocklistModel } from '../models/account/account-blocklist' 19import { AccountBlocklistModel } from '../models/account/account-blocklist'
20import { UserModel } from '../models/account/user' 20import { UserModel } from '../models/account/user'
21import { UserNotificationModel } from '../models/account/user-notification' 21import { UserNotificationModel } from '../models/account/user-notification'
22import { MAbuseFull, MAbuseMessage, MAccountServer, MActorFollowFull } from '../types/models' 22import { MAbuseFull, MAbuseMessage, MAccountServer, MActorFollowFull, MApplication, MPlugin } from '../types/models'
23import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../types/models/video' 23import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../types/models/video'
24import { isBlockedByServerOrAccount } from './blocklist' 24import { isBlockedByServerOrAccount } from './blocklist'
25import { Emailer } from './emailer' 25import { Emailer } from './emailer'
@@ -144,6 +144,20 @@ class Notifier {
144 }) 144 })
145 } 145 }
146 146
147 notifyOfNewPeerTubeVersion (application: MApplication, latestVersion: string) {
148 this.notifyAdminsOfNewPeerTubeVersion(application, latestVersion)
149 .catch(err => {
150 logger.error('Cannot notify on new PeerTubeb version %s.', latestVersion, { err })
151 })
152 }
153
154 notifyOfNewPluginVersion (plugin: MPlugin) {
155 this.notifyAdminsOfNewPluginVersion(plugin)
156 .catch(err => {
157 logger.error('Cannot notify on new plugin version %s.', plugin.name, { err })
158 })
159 }
160
147 private async notifySubscribersOfNewVideo (video: MVideoAccountLight) { 161 private async notifySubscribersOfNewVideo (video: MVideoAccountLight) {
148 // List all followers that are users 162 // List all followers that are users
149 const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId) 163 const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId)
@@ -667,6 +681,64 @@ class Notifier {
667 return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) 681 return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender })
668 } 682 }
669 683
684 private async notifyAdminsOfNewPeerTubeVersion (application: MApplication, latestVersion: string) {
685 // Use the debug right to know who is an administrator
686 const admins = await UserModel.listWithRight(UserRight.MANAGE_DEBUG)
687 if (admins.length === 0) return
688
689 logger.info('Notifying %s admins of new PeerTube version %s.', admins.length, latestVersion)
690
691 function settingGetter (user: MUserWithNotificationSetting) {
692 return user.NotificationSetting.newPeerTubeVersion
693 }
694
695 async function notificationCreator (user: MUserWithNotificationSetting) {
696 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
697 type: UserNotificationType.NEW_PEERTUBE_VERSION,
698 userId: user.id,
699 applicationId: application.id
700 })
701 notification.Application = application
702
703 return notification
704 }
705
706 function emailSender (emails: string[]) {
707 return Emailer.Instance.addNewPeerTubeVersionNotification(emails, latestVersion)
708 }
709
710 return this.notify({ users: admins, settingGetter, notificationCreator, emailSender })
711 }
712
713 private async notifyAdminsOfNewPluginVersion (plugin: MPlugin) {
714 // Use the debug right to know who is an administrator
715 const admins = await UserModel.listWithRight(UserRight.MANAGE_DEBUG)
716 if (admins.length === 0) return
717
718 logger.info('Notifying %s admins of new plugin version %s@%s.', admins.length, plugin.name, plugin.latestVersion)
719
720 function settingGetter (user: MUserWithNotificationSetting) {
721 return user.NotificationSetting.newPluginVersion
722 }
723
724 async function notificationCreator (user: MUserWithNotificationSetting) {
725 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
726 type: UserNotificationType.NEW_PLUGIN_VERSION,
727 userId: user.id,
728 pluginId: plugin.id
729 })
730 notification.Plugin = plugin
731
732 return notification
733 }
734
735 function emailSender (emails: string[]) {
736 return Emailer.Instance.addNewPlugionVersionNotification(emails, plugin)
737 }
738
739 return this.notify({ users: admins, settingGetter, notificationCreator, emailSender })
740 }
741
670 private async notify<T extends MUserWithNotificationSetting> (options: { 742 private async notify<T extends MUserWithNotificationSetting> (options: {
671 users: T[] 743 users: T[]
672 notificationCreator: (user: T) => Promise<UserNotificationModelForApi> 744 notificationCreator: (user: T) => Promise<UserNotificationModelForApi>
diff --git a/server/lib/schedulers/peertube-version-check-scheduler.ts b/server/lib/schedulers/peertube-version-check-scheduler.ts
new file mode 100644
index 000000000..c8960465c
--- /dev/null
+++ b/server/lib/schedulers/peertube-version-check-scheduler.ts
@@ -0,0 +1,55 @@
1
2import { doJSONRequest } from '@server/helpers/requests'
3import { ApplicationModel } from '@server/models/application/application'
4import { compareSemVer } from '@shared/core-utils'
5import { JoinPeerTubeVersions } from '@shared/models'
6import { logger } from '../../helpers/logger'
7import { CONFIG } from '../../initializers/config'
8import { PEERTUBE_VERSION, SCHEDULER_INTERVALS_MS } from '../../initializers/constants'
9import { Notifier } from '../notifier'
10import { AbstractScheduler } from './abstract-scheduler'
11
12export class PeerTubeVersionCheckScheduler extends AbstractScheduler {
13
14 private static instance: AbstractScheduler
15
16 protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.checkPeerTubeVersion
17
18 private constructor () {
19 super()
20 }
21
22 protected async internalExecute () {
23 return this.checkLatestVersion()
24 }
25
26 private async checkLatestVersion () {
27 if (CONFIG.PEERTUBE.CHECK_LATEST_VERSION.ENABLED === false) return
28
29 logger.info('Checking latest PeerTube version.')
30
31 const { body } = await doJSONRequest<JoinPeerTubeVersions>(CONFIG.PEERTUBE.CHECK_LATEST_VERSION.URL)
32
33 if (!body?.peertube?.latestVersion) {
34 logger.warn('Cannot check latest PeerTube version: body is invalid.', { body })
35 return
36 }
37
38 const latestVersion = body.peertube.latestVersion
39 const application = await ApplicationModel.load()
40
41 // Already checked this version
42 if (application.latestPeerTubeVersion === latestVersion) return
43
44 if (compareSemVer(PEERTUBE_VERSION, latestVersion) < 0) {
45 application.latestPeerTubeVersion = latestVersion
46 await application.save()
47
48 Notifier.Instance.notifyOfNewPeerTubeVersion(application, latestVersion)
49 }
50 }
51
52 static get Instance () {
53 return this.instance || (this.instance = new this())
54 }
55}
diff --git a/server/lib/schedulers/plugins-check-scheduler.ts b/server/lib/schedulers/plugins-check-scheduler.ts
index 014993e94..9a1ae3ec5 100644
--- a/server/lib/schedulers/plugins-check-scheduler.ts
+++ b/server/lib/schedulers/plugins-check-scheduler.ts
@@ -6,6 +6,7 @@ import { PluginModel } from '../../models/server/plugin'
6import { chunk } from 'lodash' 6import { chunk } from 'lodash'
7import { getLatestPluginsVersion } from '../plugins/plugin-index' 7import { getLatestPluginsVersion } from '../plugins/plugin-index'
8import { compareSemVer } from '../../../shared/core-utils/miscs/miscs' 8import { compareSemVer } from '../../../shared/core-utils/miscs/miscs'
9import { Notifier } from '../notifier'
9 10
10export class PluginsCheckScheduler extends AbstractScheduler { 11export class PluginsCheckScheduler extends AbstractScheduler {
11 12
@@ -53,6 +54,11 @@ export class PluginsCheckScheduler extends AbstractScheduler {
53 plugin.latestVersion = result.latestVersion 54 plugin.latestVersion = result.latestVersion
54 await plugin.save() 55 await plugin.save()
55 56
57 // Notify if there is an higher plugin version available
58 if (compareSemVer(plugin.version, result.latestVersion) < 0) {
59 Notifier.Instance.notifyOfNewPluginVersion(plugin)
60 }
61
56 logger.info('Plugin %s has a new latest version %s.', result.npmName, plugin.latestVersion) 62 logger.info('Plugin %s has a new latest version %s.', result.npmName, plugin.latestVersion)
57 } 63 }
58 } 64 }
diff --git a/server/lib/user.ts b/server/lib/user.ts
index e1892f22c..9b0a0a2f1 100644
--- a/server/lib/user.ts
+++ b/server/lib/user.ts
@@ -193,7 +193,9 @@ function createDefaultUserNotificationSettings (user: MUserId, t: Transaction |
193 newInstanceFollower: UserNotificationSettingValue.WEB, 193 newInstanceFollower: UserNotificationSettingValue.WEB,
194 abuseNewMessage: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 194 abuseNewMessage: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
195 abuseStateChange: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 195 abuseStateChange: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
196 autoInstanceFollowing: UserNotificationSettingValue.WEB 196 autoInstanceFollowing: UserNotificationSettingValue.WEB,
197 newPeerTubeVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
198 newPluginVersion: UserNotificationSettingValue.WEB
197 } 199 }
198 200
199 return UserNotificationSettingModel.create(values, { transaction: t }) 201 return UserNotificationSettingModel.create(values, { transaction: t })