From cef534ed53e4518fe0acf581bfe880788d42fc36 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 26 Dec 2018 10:36:24 +0100 Subject: Add user notification base code --- server/controllers/api/users/index.ts | 2 + server/controllers/api/users/my-notifications.ts | 84 ++++++++++++++++++++++++ server/controllers/api/videos/abuse.ts | 3 + server/controllers/api/videos/blacklist.ts | 14 +++- server/controllers/api/videos/comment.ts | 3 + server/controllers/api/videos/index.ts | 10 ++- 6 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 server/controllers/api/users/my-notifications.ts (limited to 'server/controllers/api') diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts index bc24792a2..98be46ea2 100644 --- a/server/controllers/api/users/index.ts +++ b/server/controllers/api/users/index.ts @@ -39,6 +39,7 @@ import { meRouter } from './me' import { deleteUserToken } from '../../../lib/oauth-model' import { myBlocklistRouter } from './my-blocklist' import { myVideosHistoryRouter } from './my-history' +import { myNotificationsRouter } from './my-notifications' const auditLogger = auditLoggerFactory('users') @@ -55,6 +56,7 @@ const askSendEmailLimiter = new RateLimit({ }) const usersRouter = express.Router() +usersRouter.use('/', myNotificationsRouter) usersRouter.use('/', myBlocklistRouter) usersRouter.use('/', myVideosHistoryRouter) usersRouter.use('/', meRouter) diff --git a/server/controllers/api/users/my-notifications.ts b/server/controllers/api/users/my-notifications.ts new file mode 100644 index 000000000..cef1d237c --- /dev/null +++ b/server/controllers/api/users/my-notifications.ts @@ -0,0 +1,84 @@ +import * as express from 'express' +import 'multer' +import { + asyncMiddleware, + asyncRetryTransactionMiddleware, + authenticate, + paginationValidator, + setDefaultPagination, + setDefaultSort, + userNotificationsSortValidator +} from '../../../middlewares' +import { UserModel } from '../../../models/account/user' +import { getFormattedObjects } from '../../../helpers/utils' +import { UserNotificationModel } from '../../../models/account/user-notification' +import { meRouter } from './me' +import { + markAsReadUserNotificationsValidator, + updateNotificationSettingsValidator +} from '../../../middlewares/validators/user-notifications' +import { UserNotificationSetting } from '../../../../shared/models/users' +import { UserNotificationSettingModel } from '../../../models/account/user-notification-setting' + +const myNotificationsRouter = express.Router() + +meRouter.put('/me/notification-settings', + authenticate, + updateNotificationSettingsValidator, + asyncRetryTransactionMiddleware(updateNotificationSettings) +) + +myNotificationsRouter.get('/me/notifications', + authenticate, + paginationValidator, + userNotificationsSortValidator, + setDefaultSort, + setDefaultPagination, + asyncMiddleware(listUserNotifications) +) + +myNotificationsRouter.post('/me/notifications/read', + authenticate, + markAsReadUserNotificationsValidator, + asyncMiddleware(markAsReadUserNotifications) +) + +export { + myNotificationsRouter +} + +// --------------------------------------------------------------------------- + +async function updateNotificationSettings (req: express.Request, res: express.Response) { + const user: UserModel = res.locals.oauth.token.User + const body: UserNotificationSetting = req.body + + const query = { + where: { + userId: user.id + } + } + + await UserNotificationSettingModel.update({ + newVideoFromSubscription: body.newVideoFromSubscription, + newCommentOnMyVideo: body.newCommentOnMyVideo + }, query) + + return res.status(204).end() +} + +async function listUserNotifications (req: express.Request, res: express.Response) { + const user: UserModel = res.locals.oauth.token.User + + const resultList = await UserNotificationModel.listForApi(user.id, req.query.start, req.query.count, req.query.sort) + + return res.json(getFormattedObjects(resultList.data, resultList.total)) +} + +async function markAsReadUserNotifications (req: express.Request, res: express.Response) { + const user: UserModel = res.locals.oauth.token.User + + await UserNotificationModel.markAsRead(user.id, req.body.ids) + + return res.status(204).end() +} diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts index d0c81804b..fe0a95cd5 100644 --- a/server/controllers/api/videos/abuse.ts +++ b/server/controllers/api/videos/abuse.ts @@ -22,6 +22,7 @@ import { VideoModel } from '../../../models/video/video' import { VideoAbuseModel } from '../../../models/video/video-abuse' import { auditLoggerFactory, VideoAbuseAuditView } from '../../../helpers/audit-logger' import { UserModel } from '../../../models/account/user' +import { Notifier } from '../../../lib/notifier' const auditLogger = auditLoggerFactory('abuse') const abuseVideoRouter = express.Router() @@ -117,6 +118,8 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) { await sendVideoAbuse(reporterAccount.Actor, videoAbuseInstance, videoInstance) } + Notifier.Instance.notifyOnNewVideoAbuse(videoAbuseInstance) + auditLogger.create(reporterAccount.Actor.getIdentifier(), new VideoAbuseAuditView(videoAbuseInstance.toFormattedJSON())) return videoAbuseInstance diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index 7f803c8e9..9ef08812b 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts @@ -16,6 +16,8 @@ import { } from '../../../middlewares' import { VideoBlacklistModel } from '../../../models/video/video-blacklist' import { sequelizeTypescript } from '../../../initializers' +import { Notifier } from '../../../lib/notifier' +import { VideoModel } from '../../../models/video/video' const blacklistRouter = express.Router() @@ -67,13 +69,18 @@ async function addVideoToBlacklist (req: express.Request, res: express.Response) reason: body.reason } - await VideoBlacklistModel.create(toCreate) + const blacklist = await VideoBlacklistModel.create(toCreate) + blacklist.Video = videoInstance + + Notifier.Instance.notifyOnVideoBlacklist(blacklist) + + logger.info('Video %s blacklisted.', res.locals.video.uuid) + return res.type('json').status(204).end() } async function updateVideoBlacklistController (req: express.Request, res: express.Response) { const videoBlacklist = res.locals.videoBlacklist as VideoBlacklistModel - logger.info(videoBlacklist) if (req.body.reason !== undefined) videoBlacklist.reason = req.body.reason @@ -92,11 +99,14 @@ async function listBlacklist (req: express.Request, res: express.Response, next: async function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) { const videoBlacklist = res.locals.videoBlacklist as VideoBlacklistModel + const video: VideoModel = res.locals.video await sequelizeTypescript.transaction(t => { return videoBlacklist.destroy({ transaction: t }) }) + Notifier.Instance.notifyOnVideoUnblacklist(video) + logger.info('Video %s removed from blacklist.', res.locals.video.uuid) return res.type('json').status(204).end() diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts index 3875c8f79..70c1148ba 100644 --- a/server/controllers/api/videos/comment.ts +++ b/server/controllers/api/videos/comment.ts @@ -26,6 +26,7 @@ import { VideoCommentModel } from '../../../models/video/video-comment' import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger' import { AccountModel } from '../../../models/account/account' import { UserModel } from '../../../models/account/user' +import { Notifier } from '../../../lib/notifier' const auditLogger = auditLoggerFactory('comments') const videoCommentRouter = express.Router() @@ -119,6 +120,7 @@ async function addVideoCommentThread (req: express.Request, res: express.Respons }, t) }) + Notifier.Instance.notifyOnNewComment(comment) auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON())) return res.json({ @@ -140,6 +142,7 @@ async function addVideoCommentReply (req: express.Request, res: express.Response }, t) }) + Notifier.Instance.notifyOnNewComment(comment) auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON())) return res.json({ comment: comment.toFormattedJSON() }).end() diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 00a1302d1..94ed08fed 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -7,7 +7,8 @@ import { logger } from '../../../helpers/logger' import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' import { getFormattedObjects, getServerActor } from '../../../helpers/utils' import { - CONFIG, MIMETYPES, + CONFIG, + MIMETYPES, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE, @@ -57,6 +58,7 @@ import { videoImportsRouter } from './import' import { resetSequelizeInstance } from '../../../helpers/database-utils' import { move } from 'fs-extra' import { watchingRouter } from './watching' +import { Notifier } from '../../../lib/notifier' const auditLogger = auditLoggerFactory('videos') const videosRouter = express.Router() @@ -262,6 +264,7 @@ async function addVideo (req: express.Request, res: express.Response) { } await federateVideoIfNeeded(video, true, t) + Notifier.Instance.notifyOnNewVideo(video) auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON())) logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid) @@ -293,6 +296,7 @@ async function updateVideo (req: express.Request, res: express.Response) { const oldVideoAuditView = new VideoAuditView(videoInstance.toFormattedDetailsJSON()) const videoInfoToUpdate: VideoUpdate = req.body const wasPrivateVideo = videoInstance.privacy === VideoPrivacy.PRIVATE + const wasUnlistedVideo = videoInstance.privacy === VideoPrivacy.UNLISTED // Process thumbnail or create it from the video if (req.files && req.files['thumbnailfile']) { @@ -363,6 +367,10 @@ async function updateVideo (req: express.Request, res: express.Response) { const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t) + if (wasUnlistedVideo || wasPrivateVideo) { + Notifier.Instance.notifyOnNewVideo(videoInstanceUpdated) + } + auditLogger.update( getAuditIdFromRes(res), new VideoAuditView(videoInstanceUpdated.toFormattedDetailsJSON()), -- cgit v1.2.3