import { createTransport, Transporter } from 'nodemailer'
+import { UserRight } from '../../shared/models/users'
import { isTestInstance } from '../helpers/core-utils'
import { logger } from '../helpers/logger'
import { CONFIG } from '../initializers'
+import { UserModel } from '../models/account/user'
+import { VideoModel } from '../models/video/video'
import { JobQueue } from './job-queue'
import { EmailPayload } from './job-queue/handlers/email'
import { readFileSync } from 'fs'
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
+ async addVideoAbuseReport (videoId: number) {
+ const video = await VideoModel.load(videoId)
+
+ const text = `Hi,\n\n` +
+ `Your instance received an abuse for video the following video ${video.url}\n\n` +
+ `Cheers,\n` +
+ `PeerTube.`
+
+ const to = await UserModel.listEmailsWithRight(UserRight.MANAGE_VIDEO_ABUSES)
+ const emailPayload: EmailPayload = {
+ to,
+ subject: '[PeerTube] Received a video abuse',
+ text
+ }
+
+ return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
+ }
+
sendMail (to: string[], subject: string, text: string) {
if (!this.transporter) {
throw new Error('Cannot send mail because SMTP is not configured.')
Scopes, Table, UpdatedAt
} from 'sequelize-typescript'
import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared'
-import { User } from '../../../shared/models/users'
+import { User, UserRole } from '../../../shared/models/users'
import {
isUserAutoPlayVideoValid, isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid,
isUserVideoQuotaValid
})
}
+ static listEmailsWithRight (right: UserRight) {
+ const roles = Object.keys(USER_ROLE_LABELS)
+ .map(k => parseInt(k, 10) as UserRole)
+ .filter(role => hasUserRight(role, right))
+
+ console.log(roles)
+
+ const query = {
+ attribute: [ 'email' ],
+ where: {
+ role: {
+ [Sequelize.Op.in]: roles
+ }
+ }
+ }
+
+ return UserModel.unscoped()
+ .findAll(query)
+ .then(u => u.map(u => u.email))
+ }
+
static loadById (id: number) {
return UserModel.findById(id)
}
-import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { AfterCreate, AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
import { isVideoAbuseReasonValid } from '../../helpers/custom-validators/videos'
import { CONFIG } from '../../initializers'
+import { Emailer } from '../../lib/emailer'
import { AccountModel } from '../account/account'
import { getSort, throwIfNotValid } from '../utils'
import { VideoModel } from './video'
})
Video: VideoModel
+ @AfterCreate
+ static sendEmailNotification (instance: VideoAbuseModel) {
+ return Emailer.Instance.addVideoAbuseReport(instance.videoId)
+ }
+
static listForApi (start: number, count: number, sort: string) {
const query = {
offset: start,
import * as chai from 'chai'
import 'mocha'
-import { askResetPassword, createUser, resetPassword, runServer, userLogin, wait } from '../../utils'
+import { askResetPassword, createUser, reportVideoAbuse, resetPassword, runServer, uploadVideo, userLogin, wait } from '../../utils'
import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index'
import { mockSmtpServer } from '../../utils/miscs/email'
describe('Test emails', function () {
let server: ServerInfo
let userId: number
+ let videoUUID: string
let verificationString: string
const emails: object[] = []
const user = {
await wait(5000)
await setAccessTokensToServers([ server ])
- const res = await createUser(server.url, server.accessToken, user.username, user.password)
- userId = res.body.user.id
+ {
+ const res = await createUser(server.url, server.accessToken, user.username, user.password)
+ userId = res.body.user.id
+ }
+
+ {
+ const attributes = {
+ name: 'my super name'
+ }
+ const res = await uploadVideo(server.url, server.accessToken, attributes)
+ videoUUID = res.body.video.uuid
+ }
})
describe('When resetting user password', function () {
})
})
+ describe('When creating a video abuse', function () {
+ it('Should send the notification email', async function () {
+ this.timeout(10000)
+
+ const reason = 'my super bad reason'
+ await reportVideoAbuse(server.url, server.accessToken, videoUUID, reason)
+
+ await wait(3000)
+ expect(emails).to.have.lengthOf(2)
+
+ const email = emails[1]
+
+ expect(email['from'][0]['address']).equal('test-admin@localhost')
+ expect(email['to'][0]['address']).equal('admin1@example.com')
+ expect(email['subject']).contains('abuse')
+ expect(email['text']).contains(videoUUID)
+ })
+ })
+
after(async function () {
killallServers([ server ])
import * as request from 'supertest'
-function reportVideoAbuse (url: string, token: string, videoId: number, reason: string, specialStatus = 204) {
+function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 204) {
const path = '/api/v1/videos/' + videoId + '/abuse'
return request(url)
USER = 2
}
-export const USER_ROLE_LABELS = {
+// TODO: use UserRole for key once https://github.com/Microsoft/TypeScript/issues/13042 is fixed
+export const USER_ROLE_LABELS: { [ id: number ]: string } = {
[UserRole.USER]: 'User',
[UserRole.MODERATOR]: 'Moderator',
[UserRole.ADMINISTRATOR]: 'Administrator'