1
0
Fork 0

Increase abuse length to 3000

And correctly handle new lines
This commit is contained in:
Chocobozzz 2019-01-14 16:48:38 +01:00
parent 9a39392a7e
commit 1506307f2f
No known key found for this signature in database
GPG key ID: 583A612D890159BE
28 changed files with 136 additions and 80 deletions

View file

@ -1,9 +1,9 @@
import { Component, OnInit, ViewChild } from '@angular/core' import { Component, OnInit, ViewChild } from '@angular/core'
import { Notifier, ServerService } from '@app/core' import { Notifier, ServerService } from '@app/core'
import { MarkdownService } from '@app/videos/shared'
import { I18n } from '@ngx-translate/i18n-polyfill' import { I18n } from '@ngx-translate/i18n-polyfill'
import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component' import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
import { InstanceService } from '@app/shared/instance/instance.service' import { InstanceService } from '@app/shared/instance/instance.service'
import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-about-instance', selector: 'my-about-instance',

View file

@ -1,9 +1,9 @@
import { Component, OnInit, OnDestroy } from '@angular/core' import { Component, OnDestroy, OnInit } from '@angular/core'
import { Account } from '@app/shared/account/account.model' import { Account } from '@app/shared/account/account.model'
import { AccountService } from '@app/shared/account/account.service' import { AccountService } from '@app/shared/account/account.service'
import { I18n } from '@ngx-translate/i18n-polyfill' import { I18n } from '@ngx-translate/i18n-polyfill'
import { Subscription } from 'rxjs' import { Subscription } from 'rxjs'
import { MarkdownService } from '@app/videos/shared' import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-account-about', selector: 'my-account-about',

View file

@ -10,6 +10,7 @@
font-weight: $font-semibold; font-weight: $font-semibold;
min-width: 200px; min-width: 200px;
display: inline-block; display: inline-block;
vertical-align: top;
} }
.moderation-expanded-text { .moderation-expanded-text {

View file

@ -51,11 +51,11 @@
<td class="moderation-expanded" colspan="6"> <td class="moderation-expanded" colspan="6">
<div> <div>
<span i18n class="moderation-expanded-label">Reason:</span> <span i18n class="moderation-expanded-label">Reason:</span>
<span class="moderation-expanded-text">{{ videoAbuse.reason }}</span> <span class="moderation-expanded-text" [innerHTML]="toHtml(videoAbuse.reason)"></span>
</div> </div>
<div *ngIf="videoAbuse.moderationComment"> <div *ngIf="videoAbuse.moderationComment">
<span i18n class="moderation-expanded-label">Moderation comment:</span> <span i18n class="moderation-expanded-label">Moderation comment:</span>
<span class="moderation-expanded-text">{{ videoAbuse.moderationComment }}</span> <span class="moderation-expanded-text" [innerHTML]="toHtml(videoAbuse.moderationComment)"></span>
</div> </div>
</td> </td>
</tr> </tr>

View file

@ -9,6 +9,7 @@ import { DropdownAction } from '../../../shared/buttons/action-dropdown.componen
import { ConfirmService } from '../../../core/index' import { ConfirmService } from '../../../core/index'
import { ModerationCommentModalComponent } from './moderation-comment-modal.component' import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
import { Video } from '../../../shared/video/video.model' import { Video } from '../../../shared/video/video.model'
import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-video-abuse-list', selector: 'my-video-abuse-list',
@ -30,7 +31,8 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
private notifier: Notifier, private notifier: Notifier,
private videoAbuseService: VideoAbuseService, private videoAbuseService: VideoAbuseService,
private confirmService: ConfirmService, private confirmService: ConfirmService,
private i18n: I18n private i18n: I18n,
private markdownRenderer: MarkdownService
) { ) {
super() super()
@ -108,6 +110,10 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
} }
toHtml (text: string) {
return this.markdownRenderer.textMarkdownToHTML(text)
}
protected loadData () { protected loadData () {
return this.videoAbuseService.getVideoAbuses(this.pagination, this.sort) return this.videoAbuseService.getVideoAbuses(this.pagination, this.sort)
.subscribe( .subscribe(

View file

@ -41,7 +41,7 @@
<tr> <tr>
<td class="moderation-expanded" colspan="6"> <td class="moderation-expanded" colspan="6">
<span i18n class="moderation-expanded-label">Blacklist reason:</span> <span i18n class="moderation-expanded-label">Blacklist reason:</span>
<span class="moderation-expanded-text">{{ videoBlacklist.reason }}</span> <span class="moderation-expanded-text" [innerHTML]="toHtml(videoBlacklist.reason)"></span>
</td> </td>
</tr> </tr>
</ng-template> </ng-template>

View file

@ -7,6 +7,7 @@ import { VideoBlacklist } from '../../../../../../shared'
import { I18n } from '@ngx-translate/i18n-polyfill' import { I18n } from '@ngx-translate/i18n-polyfill'
import { DropdownAction } from '../../../shared/buttons/action-dropdown.component' import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
import { Video } from '../../../shared/video/video.model' import { Video } from '../../../shared/video/video.model'
import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-video-blacklist-list', selector: 'my-video-blacklist-list',
@ -26,6 +27,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
private notifier: Notifier, private notifier: Notifier,
private confirmService: ConfirmService, private confirmService: ConfirmService,
private videoBlacklistService: VideoBlacklistService, private videoBlacklistService: VideoBlacklistService,
private markdownRenderer: MarkdownService,
private i18n: I18n private i18n: I18n
) { ) {
super() super()
@ -52,6 +54,10 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
return this.i18n('no') return this.i18n('no')
} }
toHtml (text: string) {
return this.markdownRenderer.textMarkdownToHTML(text)
}
async removeVideoFromBlacklist (entry: VideoBlacklist) { async removeVideoFromBlacklist (entry: VideoBlacklist) {
const confirmMessage = this.i18n( const confirmMessage = this.i18n(
'Do you really want to remove this video from the blacklist? It will be available again in the videos list.' 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.'

View file

@ -3,7 +3,7 @@ import { VideoChannelService } from '@app/shared/video-channel/video-channel.ser
import { VideoChannel } from '@app/shared/video-channel/video-channel.model' import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
import { I18n } from '@ngx-translate/i18n-polyfill' import { I18n } from '@ngx-translate/i18n-polyfill'
import { Subscription } from 'rxjs' import { Subscription } from 'rxjs'
import { MarkdownService } from '@app/videos/shared' import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-video-channel-about', selector: 'my-video-channel-about',

View file

@ -10,20 +10,20 @@ export class VideoAbuseValidatorsService {
constructor (private i18n: I18n) { constructor (private i18n: I18n) {
this.VIDEO_ABUSE_REASON = { this.VIDEO_ABUSE_REASON = {
VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ],
MESSAGES: { MESSAGES: {
'required': this.i18n('Report reason is required.'), 'required': this.i18n('Report reason is required.'),
'minlength': this.i18n('Report reason must be at least 2 characters long.'), 'minlength': this.i18n('Report reason must be at least 2 characters long.'),
'maxlength': this.i18n('Report reason cannot be more than 300 characters long.') 'maxlength': this.i18n('Report reason cannot be more than 3000 characters long.')
} }
} }
this.VIDEO_ABUSE_MODERATION_COMMENT = { this.VIDEO_ABUSE_MODERATION_COMMENT = {
VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ],
MESSAGES: { MESSAGES: {
'required': this.i18n('Moderation comment is required.'), 'required': this.i18n('Moderation comment is required.'),
'minlength': this.i18n('Moderation comment must be at least 2 characters long.'), 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'),
'maxlength': this.i18n('Moderation comment cannot be more than 300 characters long.') 'maxlength': this.i18n('Moderation comment cannot be more than 3000 characters long.')
} }
} }
} }

View file

@ -1,10 +1,10 @@
import { debounceTime, distinctUntilChanged } from 'rxjs/operators' import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
import { Component, forwardRef, Input, OnInit } from '@angular/core' import { Component, forwardRef, Input, OnInit } from '@angular/core'
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
import { MarkdownService } from '@app/videos/shared'
import { Subject } from 'rxjs' import { Subject } from 'rxjs'
import truncate from 'lodash-es/truncate' import truncate from 'lodash-es/truncate'
import { ScreenService } from '@app/shared/misc/screen.service' import { ScreenService } from '@app/shared/misc/screen.service'
import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-markdown-textarea', selector: 'my-markdown-textarea',

View file

@ -1,6 +1,6 @@
import { Component, Input, OnChanges, OnInit } from '@angular/core' import { Component, Input, OnChanges, OnInit } from '@angular/core'
import { MarkdownService } from '@app/videos/shared'
import { I18n } from '@ngx-translate/i18n-polyfill' import { I18n } from '@ngx-translate/i18n-polyfill'
import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-help', selector: 'my-help',

View file

@ -102,12 +102,18 @@ function objectToFormData (obj: any, form?: FormData, namespace?: string) {
return fd return fd
} }
function lineFeedToHtml (obj: any, keyToNormalize: string) { function objectLineFeedToHtml (obj: any, keyToNormalize: string) {
return immutableAssign(obj, { return immutableAssign(obj, {
[keyToNormalize]: obj[keyToNormalize].replace(/\r?\n|\r/g, '<br />') [keyToNormalize]: lineFeedToHtml(obj[keyToNormalize])
}) })
} }
function lineFeedToHtml (text: string) {
if (!text) return text
return text.replace(/\r?\n|\r/g, '<br />')
}
function removeElementFromArray <T> (arr: T[], elem: T) { function removeElementFromArray <T> (arr: T[], elem: T) {
const index = arr.indexOf(elem) const index = arr.indexOf(elem)
if (index !== -1) arr.splice(index, 1) if (index !== -1) arr.splice(index, 1)
@ -131,6 +137,7 @@ function scrollToTop () {
export { export {
sortBy, sortBy,
durationToString, durationToString,
lineFeedToHtml,
objectToUrlEncoded, objectToUrlEncoded,
getParameterByName, getParameterByName,
populateAsyncUserVideoChannels, populateAsyncUserVideoChannels,
@ -138,7 +145,7 @@ export {
dateToHuman, dateToHuman,
immutableAssign, immutableAssign,
objectToFormData, objectToFormData,
lineFeedToHtml, objectLineFeedToHtml,
removeElementFromArray, removeElementFromArray,
scrollToTop scrollToTop
} }

View file

@ -0,0 +1,35 @@
import { Injectable } from '@angular/core'
import { LinkifierService } from '@app/shared/renderer/linkifier.service'
import * as sanitizeHtml from 'sanitize-html'
@Injectable()
export class HtmlRendererService {
constructor (private linkifier: LinkifierService) {
}
toSafeHtml (text: string) {
// Convert possible markdown to html
const html = this.linkifier.linkify(text)
return sanitizeHtml(html, {
allowedTags: [ 'a', 'p', 'span', 'br' ],
allowedSchemes: [ 'http', 'https' ],
allowedAttributes: {
'a': [ 'href', 'class', 'target' ]
},
transformTags: {
a: (tagName, attribs) => {
return {
tagName,
attribs: Object.assign(attribs, {
target: '_blank',
rel: 'noopener noreferrer'
})
}
}
}
})
}
}

View file

@ -0,0 +1,3 @@
export * from './html-renderer.service'
export * from './linkifier.service'
export * from './markdown.service'

View file

@ -6,7 +6,6 @@ import { RouterModule } from '@angular/router'
import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component' import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component'
import { HelpComponent } from '@app/shared/misc/help.component' import { HelpComponent } from '@app/shared/misc/help.component'
import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive'
import { MarkdownService } from '@app/videos/shared'
import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes' import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes'
import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared'
@ -34,10 +33,10 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
import { import {
CustomConfigValidatorsService, CustomConfigValidatorsService,
InstanceValidatorsService,
LoginValidatorsService, LoginValidatorsService,
ReactiveFileComponent, ReactiveFileComponent,
ResetPasswordValidatorsService, ResetPasswordValidatorsService,
InstanceValidatorsService,
TextareaAutoResizeDirective, TextareaAutoResizeDirective,
UserValidatorsService, UserValidatorsService,
VideoAbuseValidatorsService, VideoAbuseValidatorsService,
@ -67,6 +66,7 @@ import { UserHistoryService } from '@app/shared/users/user-history.service'
import { UserNotificationService } from '@app/shared/users/user-notification.service' import { UserNotificationService } from '@app/shared/users/user-notification.service'
import { UserNotificationsComponent } from '@app/shared/users/user-notifications.component' import { UserNotificationsComponent } from '@app/shared/users/user-notifications.component'
import { InstanceService } from '@app/shared/instance/instance.service' import { InstanceService } from '@app/shared/instance/instance.service'
import { HtmlRendererService, LinkifierService, MarkdownService } from '@app/shared/renderer'
@NgModule({ @NgModule({
imports: [ imports: [
@ -167,7 +167,6 @@ import { InstanceService } from '@app/shared/instance/instance.service'
UserService, UserService,
VideoService, VideoService,
AccountService, AccountService,
MarkdownService,
VideoChannelService, VideoChannelService,
VideoCaptionService, VideoCaptionService,
VideoImportService, VideoImportService,
@ -192,6 +191,10 @@ import { InstanceService } from '@app/shared/instance/instance.service'
UserHistoryService, UserHistoryService,
InstanceService, InstanceService,
MarkdownService,
LinkifierService,
HtmlRendererService,
I18nPrimengCalendarService, I18nPrimengCalendarService,
ScreenService, ScreenService,

View file

@ -32,9 +32,7 @@ export class VideoAbuseService {
reportVideo (id: number, reason: string) { reportVideo (id: number, reason: string) {
const url = VideoAbuseService.BASE_VIDEO_ABUSE_URL + id + '/abuse' const url = VideoAbuseService.BASE_VIDEO_ABUSE_URL + id + '/abuse'
const body = { const body = { reason }
reason
}
return this.authHttp.post(url, body) return this.authHttp.post(url, body)
.pipe( .pipe(

View file

@ -1,11 +1,10 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core' import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'
import { LinkifierService } from '@app/videos/+video-watch/comment/linkifier.service'
import * as sanitizeHtml from 'sanitize-html'
import { UserRight } from '../../../../../../shared/models/users' import { UserRight } from '../../../../../../shared/models/users'
import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
import { AuthService } from '../../../core/auth' import { AuthService } from '../../../core/auth'
import { Video } from '../../../shared/video/video.model' import { Video } from '../../../shared/video/video.model'
import { VideoComment } from './video-comment.model' import { VideoComment } from './video-comment.model'
import { HtmlRendererService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-video-comment', selector: 'my-video-comment',
@ -29,7 +28,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
newParentComments: VideoComment[] = [] newParentComments: VideoComment[] = []
constructor ( constructor (
private linkifierService: LinkifierService, private htmlRenderer: HtmlRendererService,
private authService: AuthService private authService: AuthService
) {} ) {}
@ -87,27 +86,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
} }
private init () { private init () {
// Convert possible markdown to html this.sanitizedCommentHTML = this.htmlRenderer.toSafeHtml(this.comment.text)
const html = this.linkifierService.linkify(this.comment.text)
this.sanitizedCommentHTML = sanitizeHtml(html, {
allowedTags: [ 'a', 'p', 'span', 'br' ],
allowedSchemes: [ 'http', 'https' ],
allowedAttributes: {
'a': [ 'href', 'class', 'target' ]
},
transformTags: {
a: (tagName, attribs) => {
return {
tagName,
attribs: Object.assign(attribs, {
target: '_blank',
rel: 'noopener noreferrer'
})
}
}
}
})
this.newParentComments = this.parentComments.concat([ this.comment ]) this.newParentComments = this.parentComments.concat([ this.comment ])
} }

View file

@ -1,7 +1,7 @@
import { catchError, map } from 'rxjs/operators' import { catchError, map } from 'rxjs/operators'
import { HttpClient, HttpParams } from '@angular/common/http' import { HttpClient, HttpParams } from '@angular/common/http'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { lineFeedToHtml } from '@app/shared/misc/utils' import { objectLineFeedToHtml } from '@app/shared/misc/utils'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import { ResultList, FeedFormat } from '../../../../../../shared/models' import { ResultList, FeedFormat } from '../../../../../../shared/models'
import { import {
@ -28,7 +28,7 @@ export class VideoCommentService {
addCommentThread (videoId: number | string, comment: VideoCommentCreate) { addCommentThread (videoId: number | string, comment: VideoCommentCreate) {
const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads'
const normalizedComment = lineFeedToHtml(comment, 'text') const normalizedComment = objectLineFeedToHtml(comment, 'text')
return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment) return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
.pipe( .pipe(
@ -39,7 +39,7 @@ export class VideoCommentService {
addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) { addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) {
const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId
const normalizedComment = lineFeedToHtml(comment, 'text') const normalizedComment = objectLineFeedToHtml(comment, 'text')
return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment) return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
.pipe( .pipe(

View file

@ -1,8 +1,7 @@
import { Component, Input, ViewChild } from '@angular/core' import { Component, Input, ViewChild } from '@angular/core'
import { MarkdownService } from '@app/videos/shared'
import { VideoDetails } from '../../../shared/video/video-details.model' import { VideoDetails } from '../../../shared/video/video-details.model'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-video-support', selector: 'my-video-support',

View file

@ -19,7 +19,6 @@ import { AuthService, ConfirmService } from '../../core'
import { RestExtractor, VideoBlacklistService } from '../../shared' import { RestExtractor, VideoBlacklistService } from '../../shared'
import { VideoDetails } from '../../shared/video/video-details.model' import { VideoDetails } from '../../shared/video/video-details.model'
import { VideoService } from '../../shared/video/video.service' import { VideoService } from '../../shared/video/video.service'
import { MarkdownService } from '../shared'
import { VideoDownloadComponent } from './modal/video-download.component' import { VideoDownloadComponent } from './modal/video-download.component'
import { VideoReportComponent } from './modal/video-report.component' import { VideoReportComponent } from './modal/video-report.component'
import { VideoShareComponent } from './modal/video-share.component' import { VideoShareComponent } from './modal/video-share.component'
@ -30,6 +29,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
import { environment } from '../../../environments/environment' import { environment } from '../../../environments/environment'
import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils' import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
import { VideoCaptionService } from '@app/shared/video-caption' import { VideoCaptionService } from '@app/shared/video-caption'
import { MarkdownService } from '@app/shared/renderer'
@Component({ @Component({
selector: 'my-video-watch', selector: 'my-video-watch',

View file

@ -1,9 +1,7 @@
import { NgModule } from '@angular/core' import { NgModule } from '@angular/core'
import { LinkifierService } from '@app/videos/+video-watch/comment/linkifier.service'
import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
import { ClipboardModule } from 'ngx-clipboard' import { ClipboardModule } from 'ngx-clipboard'
import { SharedModule } from '../../shared' import { SharedModule } from '../../shared'
import { MarkdownService } from '../shared'
import { VideoCommentAddComponent } from './comment/video-comment-add.component' import { VideoCommentAddComponent } from './comment/video-comment-add.component'
import { VideoCommentComponent } from './comment/video-comment.component' import { VideoCommentComponent } from './comment/video-comment.component'
import { VideoCommentService } from './comment/video-comment.service' import { VideoCommentService } from './comment/video-comment.service'
@ -46,8 +44,6 @@ import { RecommendationsModule } from '@app/videos/recommendations/recommendatio
], ],
providers: [ providers: [
MarkdownService,
LinkifierService,
VideoCommentService VideoCommentService
] ]
}) })

View file

@ -1 +0,0 @@
export * from './markdown.service'

View file

@ -16,7 +16,7 @@ let config: IConfig = require('config')
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const LAST_MIGRATION_VERSION = 320 const LAST_MIGRATION_VERSION = 325
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -316,8 +316,8 @@ let CONSTRAINTS_FIELDS = {
BLOCKED_REASON: { min: 3, max: 250 } // Length BLOCKED_REASON: { min: 3, max: 250 } // Length
}, },
VIDEO_ABUSES: { VIDEO_ABUSES: {
REASON: { min: 2, max: 300 }, // Length REASON: { min: 2, max: 3000 }, // Length
MODERATION_COMMENT: { min: 2, max: 300 } // Length MODERATION_COMMENT: { min: 2, max: 3000 } // Length
}, },
VIDEO_BLACKLIST: { VIDEO_BLACKLIST: {
REASON: { min: 2, max: 300 } // Length REASON: { min: 2, max: 300 } // Length

View file

@ -0,0 +1,37 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize
}): Promise<void> {
{
const data = {
type: Sequelize.STRING(3000),
allowNull: false,
defaultValue: null
}
await utils.queryInterface.changeColumn('videoAbuse', 'reason', data)
}
{
const data = {
type: Sequelize.STRING(3000),
allowNull: true,
defaultValue: null
}
await utils.queryInterface.changeColumn('videoAbuse', 'moderationComment', data)
}
}
function down (options) {
throw new Error('Not implemented.')
}
export {
up,
down
}

View file

@ -1,17 +1,4 @@
import { import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
AfterCreate,
AllowNull,
BelongsTo,
Column,
CreatedAt,
DataType,
Default,
ForeignKey,
Is,
Model,
Table,
UpdatedAt
} from 'sequelize-typescript'
import { VideoAbuseObject } from '../../../shared/models/activitypub/objects' import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
import { VideoAbuse } from '../../../shared/models/videos' import { VideoAbuse } from '../../../shared/models/videos'
import { import {
@ -19,7 +6,6 @@ import {
isVideoAbuseReasonValid, isVideoAbuseReasonValid,
isVideoAbuseStateValid isVideoAbuseStateValid
} from '../../helpers/custom-validators/video-abuses' } from '../../helpers/custom-validators/video-abuses'
import { Emailer } from '../../lib/emailer'
import { AccountModel } from '../account/account' import { AccountModel } from '../account/account'
import { getSort, throwIfNotValid } from '../utils' import { getSort, throwIfNotValid } from '../utils'
import { VideoModel } from './video' import { VideoModel } from './video'
@ -40,8 +26,9 @@ import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers'
export class VideoAbuseModel extends Model<VideoAbuseModel> { export class VideoAbuseModel extends Model<VideoAbuseModel> {
@AllowNull(false) @AllowNull(false)
@Default(null)
@Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason')) @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
@Column @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.REASON.max))
reason: string reason: string
@AllowNull(false) @AllowNull(false)

View file

@ -113,8 +113,8 @@ describe('Test video abuses API validators', function () {
await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
}) })
it('Should fail with a reason too big', async function () { it('Should fail with a too big reason', async function () {
const fields = { reason: 'super'.repeat(61) } const fields = { reason: 'super'.repeat(605) }
await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
}) })
@ -154,7 +154,7 @@ describe('Test video abuses API validators', function () {
}) })
it('Should fail with a bad moderation comment', async function () { it('Should fail with a bad moderation comment', async function () {
const body = { moderationComment: 'b'.repeat(305) } const body = { moderationComment: 'b'.repeat(3001) }
await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400) await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400)
}) })