aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-06-07 15:04:41 +0200
committerChocobozzz <me@florianbigard.com>2019-06-07 15:04:41 +0200
commitb91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62 (patch)
tree754bb49026d4df8086030e28a8a7c16e3f0338b6
parent851f5daa1eec66e1faa3c45238ec9ab91be05b00 (diff)
parent03371ad9d049bab79445a1b35da44cb1272f6c28 (diff)
downloadPeerTube-b91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62.tar.gz
PeerTube-b91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62.tar.zst
PeerTube-b91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62.zip
Merge branch 'release/v1.3.0' into develop
-rw-r--r--client/src/app/menu/menu.component.scss10
-rw-r--r--client/src/app/shared/buttons/action-dropdown.component.scss4
-rw-r--r--client/src/app/shared/buttons/action-dropdown.component.ts6
-rw-r--r--client/src/app/shared/forms/form-reactive.ts2
-rw-r--r--client/src/app/shared/instance/instance-features-table.component.scss3
-rw-r--r--client/src/app/shared/user-subscription/remote-subscribe.component.ts15
-rw-r--r--client/src/app/shared/user-subscription/subscribe-button.component.html4
-rw-r--r--client/src/app/shared/user-subscription/subscribe-button.component.ts14
-rw-r--r--client/src/app/shared/video/video-actions-dropdown.component.ts32
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.ts2
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment-add.component.html2
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment-add.component.ts6
-rw-r--r--server/controllers/api/videos/import.ts16
-rw-r--r--server/controllers/static.ts13
-rw-r--r--server/tests/api/videos/video-blacklist.ts58
15 files changed, 122 insertions, 65 deletions
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss
index fa9a006af..06baa52d3 100644
--- a/client/src/app/menu/menu.component.scss
+++ b/client/src/app/menu/menu.component.scss
@@ -75,22 +75,22 @@ menu {
75 .logged-in-more { 75 .logged-in-more {
76 margin-right: 20px; 76 margin-right: 20px;
77 77
78 my-global-icon { 78 my-global-icon.dropdown-toggle {
79 @include apply-svg-color(var(--mainBackgroundColor));
80
81 cursor: pointer; 79 cursor: pointer;
82 80
83 &::after { 81 &::after {
84 border: none; 82 border: none;
85 } 83 }
84
85 /deep/ {
86 @include apply-svg-color(var(--menuForegroundColor));
87 }
86 } 88 }
87 89
88 .dropdown-item { 90 .dropdown-item {
89 @include dropdown-with-icon-item; 91 @include dropdown-with-icon-item;
90 92
91 my-global-icon { 93 my-global-icon {
92 @include apply-svg-color(var(--mainForegroundColor));
93
94 width: 22px; 94 width: 22px;
95 height: 22px; 95 height: 22px;
96 96
diff --git a/client/src/app/shared/buttons/action-dropdown.component.scss b/client/src/app/shared/buttons/action-dropdown.component.scss
index 5073190b0..7c2b0db71 100644
--- a/client/src/app/shared/buttons/action-dropdown.component.scss
+++ b/client/src/app/shared/buttons/action-dropdown.component.scss
@@ -32,6 +32,10 @@
32 32
33 .more-icon { 33 .more-icon {
34 width: 21px; 34 width: 21px;
35
36 /deep/ {
37 @include apply-svg-color(var(--mainForegroundColor));
38 }
35 } 39 }
36 40
37 &.small { 41 &.small {
diff --git a/client/src/app/shared/buttons/action-dropdown.component.ts b/client/src/app/shared/buttons/action-dropdown.component.ts
index f5345831b..c9dbbfda2 100644
--- a/client/src/app/shared/buttons/action-dropdown.component.ts
+++ b/client/src/app/shared/buttons/action-dropdown.component.ts
@@ -41,10 +41,4 @@ export class ActionDropdownComponent<T> {
41 areActionsDisplayed (actions: DropdownAction<T>[], entry: T) { 41 areActionsDisplayed (actions: DropdownAction<T>[], entry: T) {
42 return actions.some(a => a.isDisplayed === undefined || a.isDisplayed(entry)) 42 return actions.some(a => a.isDisplayed === undefined || a.isDisplayed(entry))
43 } 43 }
44
45 handleClick (event: Event, action: DropdownAction<T>) {
46 event.preventDefault()
47
48 // action.handler(entry)
49 }
50} 44}
diff --git a/client/src/app/shared/forms/form-reactive.ts b/client/src/app/shared/forms/form-reactive.ts
index 0d40b6f4a..6aec2937d 100644
--- a/client/src/app/shared/forms/form-reactive.ts
+++ b/client/src/app/shared/forms/form-reactive.ts
@@ -57,7 +57,7 @@ export abstract class FormReactive {
57 57
58 // Don't care if dirty on force check 58 // Don't care if dirty on force check
59 const isDirty = control.dirty || forceCheck === true 59 const isDirty = control.dirty || forceCheck === true
60 if (control && isDirty && !control.valid) { 60 if (control && isDirty && control.enabled && !control.valid) {
61 const messages = validationMessages[ field ] 61 const messages = validationMessages[ field ]
62 for (const key of Object.keys(control.errors)) { 62 for (const key of Object.keys(control.errors)) {
63 formErrors[ field ] += messages[ key ] + ' ' 63 formErrors[ field ] += messages[ key ] + ' '
diff --git a/client/src/app/shared/instance/instance-features-table.component.scss b/client/src/app/shared/instance/instance-features-table.component.scss
index 90fbb5c94..f9bec038d 100644
--- a/client/src/app/shared/instance/instance-features-table.component.scss
+++ b/client/src/app/shared/instance/instance-features-table.component.scss
@@ -3,6 +3,7 @@
3 3
4table { 4table {
5 font-size: 14px; 5 font-size: 14px;
6 color: var(--mainForegroundColor);
6 7
7 .label { 8 .label {
8 font-weight: $font-semibold; 9 font-weight: $font-semibold;
@@ -16,4 +17,4 @@ table {
16 .glyphicon-remove { 17 .glyphicon-remove {
17 color: $red; 18 color: $red;
18 } 19 }
19} \ No newline at end of file 20}
diff --git a/client/src/app/shared/user-subscription/remote-subscribe.component.ts b/client/src/app/shared/user-subscription/remote-subscribe.component.ts
index ba2a45df1..63e7cd5d9 100644
--- a/client/src/app/shared/user-subscription/remote-subscribe.component.ts
+++ b/client/src/app/shared/user-subscription/remote-subscribe.component.ts
@@ -11,7 +11,7 @@ import {
11 styleUrls: ['./remote-subscribe.component.scss'] 11 styleUrls: ['./remote-subscribe.component.scss']
12}) 12})
13export class RemoteSubscribeComponent extends FormReactive implements OnInit { 13export class RemoteSubscribeComponent extends FormReactive implements OnInit {
14 @Input() account: string 14 @Input() uri: string
15 @Input() interact = false 15 @Input() interact = false
16 @Input() showHelp = false 16 @Input() showHelp = false
17 17
@@ -42,19 +42,20 @@ export class RemoteSubscribeComponent extends FormReactive implements OnInit {
42 fetch(`https://${hostname}/.well-known/webfinger?resource=acct:${username}@${hostname}`) 42 fetch(`https://${hostname}/.well-known/webfinger?resource=acct:${username}@${hostname}`)
43 .then(response => response.json()) 43 .then(response => response.json())
44 .then(data => new Promise((resolve, reject) => { 44 .then(data => new Promise((resolve, reject) => {
45 console.log(data)
46
45 if (data && Array.isArray(data.links)) { 47 if (data && Array.isArray(data.links)) {
46 const link: { 48 const link: { template: string } = data.links.find((link: any) => {
47 template: string 49 return link && typeof link.template === 'string' && link.rel === 'http://ostatus.org/schema/1.0/subscribe'
48 } = data.links.find((link: any) => 50 })
49 link && typeof link.template === 'string' && link.rel === 'http://ostatus.org/schema/1.0/subscribe')
50 51
51 if (link && link.template.includes('{uri}')) { 52 if (link && link.template.includes('{uri}')) {
52 resolve(link.template.replace('{uri}', `acct:${this.account}`)) 53 resolve(link.template.replace('{uri}', encodeURIComponent(this.uri)))
53 } 54 }
54 } 55 }
55 reject() 56 reject()
56 })) 57 }))
57 .then(window.open) 58 .then(window.open)
58 .catch(() => window.open(`https://${hostname}/authorize_interaction?acct=${this.account}`)) 59 .catch(err => console.error(err))
59 } 60 }
60} 61}
diff --git a/client/src/app/shared/user-subscription/subscribe-button.component.html b/client/src/app/shared/user-subscription/subscribe-button.component.html
index dbf6a34f0..d32647b42 100644
--- a/client/src/app/shared/user-subscription/subscribe-button.component.html
+++ b/client/src/app/shared/user-subscription/subscribe-button.component.html
@@ -41,7 +41,7 @@
41 </button> 41 </button>
42 42
43 <button class="dropdown-item" i18n>Subscribe with a Mastodon account:</button> 43 <button class="dropdown-item" i18n>Subscribe with a Mastodon account:</button>
44 <my-remote-subscribe showHelp="true" account="{{ uriAccount }}"></my-remote-subscribe> 44 <my-remote-subscribe showHelp="true" [uri]="channelUri"></my-remote-subscribe>
45 45
46 <div class="dropdown-divider"></div> 46 <div class="dropdown-divider"></div>
47 47
@@ -50,4 +50,4 @@
50 50
51 </div> 51 </div>
52 </div> 52 </div>
53</div> \ No newline at end of file 53</div>
diff --git a/client/src/app/shared/user-subscription/subscribe-button.component.ts b/client/src/app/shared/user-subscription/subscribe-button.component.ts
index ef470ee44..25515f6ea 100644
--- a/client/src/app/shared/user-subscription/subscribe-button.component.ts
+++ b/client/src/app/shared/user-subscription/subscribe-button.component.ts
@@ -28,19 +28,19 @@ export class SubscribeButtonComponent implements OnInit {
28 private videoService: VideoService 28 private videoService: VideoService
29 ) { } 29 ) { }
30 30
31 get uri () { 31 get channelHandle () {
32 return this.videoChannel.name + '@' + this.videoChannel.host 32 return this.videoChannel.name + '@' + this.videoChannel.host
33 } 33 }
34 34
35 get uriAccount () { 35 get channelUri () {
36 return this.videoChannel.ownerAccount.name + '@' + this.videoChannel.host 36 return this.videoChannel.url
37 } 37 }
38 38
39 ngOnInit () { 39 ngOnInit () {
40 if (this.isUserLoggedIn()) { 40 if (this.isUserLoggedIn()) {
41 this.userSubscriptionService.doesSubscriptionExist(this.uri) 41 this.userSubscriptionService.doesSubscriptionExist(this.channelHandle)
42 .subscribe( 42 .subscribe(
43 res => this.subscribed = res[this.uri], 43 res => this.subscribed = res[this.channelHandle],
44 44
45 err => this.notifier.error(err.message) 45 err => this.notifier.error(err.message)
46 ) 46 )
@@ -56,7 +56,7 @@ export class SubscribeButtonComponent implements OnInit {
56 } 56 }
57 57
58 localSubscribe () { 58 localSubscribe () {
59 this.userSubscriptionService.addSubscription(this.uri) 59 this.userSubscriptionService.addSubscription(this.channelHandle)
60 .subscribe( 60 .subscribe(
61 () => { 61 () => {
62 this.subscribed = true 62 this.subscribed = true
@@ -78,7 +78,7 @@ export class SubscribeButtonComponent implements OnInit {
78 } 78 }
79 79
80 localUnsubscribe () { 80 localUnsubscribe () {
81 this.userSubscriptionService.deleteSubscription(this.uri) 81 this.userSubscriptionService.deleteSubscription(this.channelHandle)
82 .subscribe( 82 .subscribe(
83 () => { 83 () => {
84 this.subscribed = false 84 this.subscribed = false
diff --git a/client/src/app/shared/video/video-actions-dropdown.component.ts b/client/src/app/shared/video/video-actions-dropdown.component.ts
index 0bbc783c1..8d4e33697 100644
--- a/client/src/app/shared/video/video-actions-dropdown.component.ts
+++ b/client/src/app/shared/video/video-actions-dropdown.component.ts
@@ -188,19 +188,16 @@ export class VideoActionsDropdownComponent implements OnChanges {
188 } 188 }
189 189
190 private buildActions () { 190 private buildActions () {
191 this.videoActions = [] 191 this.videoActions = [
192 192 [
193 if (this.authService.isLoggedIn()) {
194 this.videoActions.push([
195 { 193 {
196 label: this.i18n('Save to playlist'), 194 label: this.i18n('Save to playlist'),
197 handler: () => this.playlistDropdown.toggle(), 195 handler: () => this.playlistDropdown.toggle(),
198 isDisplayed: () => this.displayOptions.playlist, 196 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.playlist,
199 iconName: 'playlist-add' 197 iconName: 'playlist-add'
200 } 198 }
201 ]) 199 ],
202 200 [
203 this.videoActions.push([
204 { 201 {
205 label: this.i18n('Download'), 202 label: this.i18n('Download'),
206 handler: () => this.showDownloadModal(), 203 handler: () => this.showDownloadModal(),
@@ -211,36 +208,35 @@ export class VideoActionsDropdownComponent implements OnChanges {
211 label: this.i18n('Update'), 208 label: this.i18n('Update'),
212 linkBuilder: ({ video }) => [ '/videos/update', video.uuid ], 209 linkBuilder: ({ video }) => [ '/videos/update', video.uuid ],
213 iconName: 'edit', 210 iconName: 'edit',
214 isDisplayed: () => this.displayOptions.update && this.isVideoUpdatable() 211 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.update && this.isVideoUpdatable()
215 }, 212 },
216 { 213 {
217 label: this.i18n('Blacklist'), 214 label: this.i18n('Blacklist'),
218 handler: () => this.showBlacklistModal(), 215 handler: () => this.showBlacklistModal(),
219 iconName: 'no', 216 iconName: 'no',
220 isDisplayed: () => this.displayOptions.blacklist && this.isVideoBlacklistable() 217 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoBlacklistable()
221 }, 218 },
222 { 219 {
223 label: this.i18n('Unblacklist'), 220 label: this.i18n('Unblacklist'),
224 handler: () => this.unblacklistVideo(), 221 handler: () => this.unblacklistVideo(),
225 iconName: 'undo', 222 iconName: 'undo',
226 isDisplayed: () => this.displayOptions.blacklist && this.isVideoUnblacklistable() 223 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoUnblacklistable()
227 }, 224 },
228 { 225 {
229 label: this.i18n('Delete'), 226 label: this.i18n('Delete'),
230 handler: () => this.removeVideo(), 227 handler: () => this.removeVideo(),
231 isDisplayed: () => this.displayOptions.delete && this.isVideoRemovable(), 228 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.delete && this.isVideoRemovable(),
232 iconName: 'delete' 229 iconName: 'delete'
233 } 230 }
234 ]) 231 ],
235 232 [
236 this.videoActions.push([
237 { 233 {
238 label: this.i18n('Report'), 234 label: this.i18n('Report'),
239 handler: () => this.showReportModal(), 235 handler: () => this.showReportModal(),
240 isDisplayed: () => this.displayOptions.report, 236 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.report,
241 iconName: 'alert' 237 iconName: 'alert'
242 } 238 }
243 ]) 239 ]
244 } 240 ]
245 } 241 }
246} 242}
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.ts b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
index a2776b73d..cea352bfb 100644
--- a/client/src/app/videos/+video-edit/shared/video-edit.component.ts
+++ b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
@@ -193,7 +193,7 @@ export class VideoEditComponent implements OnInit, OnDestroy {
193 } 193 }
194 194
195 private trackPrivacyChange () { 195 private trackPrivacyChange () {
196 // We will update the "support" field depending on the channel 196 // We will update the schedule input and the wait transcoding checkbox validators
197 this.form.controls[ 'privacy' ] 197 this.form.controls[ 'privacy' ]
198 .valueChanges 198 .valueChanges
199 .pipe(map(res => parseInt(res.toString(), 10))) 199 .pipe(map(res => parseInt(res.toString(), 10)))
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html
index d8a7a78c4..916f5d0ff 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html
+++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html
@@ -41,7 +41,7 @@
41 <span i18n> 41 <span i18n>
42 If you have an account on Mastodon or Pleroma, you can open it directly in their interface: 42 If you have an account on Mastodon or Pleroma, you can open it directly in their interface:
43 </span> 43 </span>
44 <my-remote-subscribe [interact]="true" [account]="getUrl()"></my-remote-subscribe> 44 <my-remote-subscribe [interact]="true" [uri]="getUri()"></my-remote-subscribe>
45 </div> 45 </div>
46 <div class="modal-footer inputs"> 46 <div class="modal-footer inputs">
47 <span i18n class="action-button action-button-cancel" role="button" (click)="hideVisitorModal()"> 47 <span i18n class="action-button action-button-cancel" role="button" (click)="hideVisitorModal()">
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
index fd85c28f2..ac1d02d94 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
@@ -8,7 +8,6 @@ import { User } from '../../../shared/users'
8import { Video } from '../../../shared/video/video.model' 8import { Video } from '../../../shared/video/video.model'
9import { VideoComment } from './video-comment.model' 9import { VideoComment } from './video-comment.model'
10import { VideoCommentService } from './video-comment.service' 10import { VideoCommentService } from './video-comment.service'
11import { I18n } from '@ngx-translate/i18n-polyfill'
12import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
13import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service' 12import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service'
14import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 13import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
@@ -40,8 +39,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
40 private videoCommentService: VideoCommentService, 39 private videoCommentService: VideoCommentService,
41 private authService: AuthService, 40 private authService: AuthService,
42 private modalService: NgbModal, 41 private modalService: NgbModal,
43 private router: Router, 42 private router: Router
44 private i18n: I18n
45 ) { 43 ) {
46 super() 44 super()
47 } 45 }
@@ -124,7 +122,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
124 return this.form.value['text'] 122 return this.form.value['text']
125 } 123 }
126 124
127 getUrl () { 125 getUri () {
128 return window.location.href 126 return window.location.href
129 } 127 }
130 128
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts
index bfb690906..dcba0e08f 100644
--- a/server/controllers/api/videos/import.ts
+++ b/server/controllers/api/videos/import.ts
@@ -26,6 +26,7 @@ import { sequelizeTypescript } from '../../../initializers/database'
26import { createVideoMiniatureFromExisting } from '../../../lib/thumbnail' 26import { createVideoMiniatureFromExisting } from '../../../lib/thumbnail'
27import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' 27import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
28import { ThumbnailModel } from '../../../models/video/thumbnail' 28import { ThumbnailModel } from '../../../models/video/thumbnail'
29import { UserModel } from '../../../models/account/user'
29 30
30const auditLogger = auditLoggerFactory('video-imports') 31const auditLogger = auditLoggerFactory('video-imports')
31const videoImportsRouter = express.Router() 32const videoImportsRouter = express.Router()
@@ -107,7 +108,8 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
107 previewModel, 108 previewModel,
108 videoChannel: res.locals.videoChannel, 109 videoChannel: res.locals.videoChannel,
109 tags, 110 tags,
110 videoImportAttributes 111 videoImportAttributes,
112 user
111 }) 113 })
112 114
113 // Create job to import the video 115 // Create job to import the video
@@ -151,12 +153,13 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
151 userId: user.id 153 userId: user.id
152 } 154 }
153 const videoImport = await insertIntoDB({ 155 const videoImport = await insertIntoDB({
154 video: video, 156 video,
155 thumbnailModel, 157 thumbnailModel,
156 previewModel, 158 previewModel,
157 videoChannel: res.locals.videoChannel, 159 videoChannel: res.locals.videoChannel,
158 tags, 160 tags,
159 videoImportAttributes 161 videoImportAttributes,
162 user
160 }) 163 })
161 164
162 // Create job to import the video 165 // Create job to import the video
@@ -227,9 +230,10 @@ function insertIntoDB (parameters: {
227 previewModel: ThumbnailModel, 230 previewModel: ThumbnailModel,
228 videoChannel: VideoChannelModel, 231 videoChannel: VideoChannelModel,
229 tags: string[], 232 tags: string[],
230 videoImportAttributes: Partial<VideoImportModel> 233 videoImportAttributes: Partial<VideoImportModel>,
234 user: UserModel
231}): Bluebird<VideoImportModel> { 235}): Bluebird<VideoImportModel> {
232 let { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes } = parameters 236 const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters
233 237
234 return sequelizeTypescript.transaction(async t => { 238 return sequelizeTypescript.transaction(async t => {
235 const sequelizeOptions = { transaction: t } 239 const sequelizeOptions = { transaction: t }
@@ -241,7 +245,7 @@ function insertIntoDB (parameters: {
241 if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) 245 if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t)
242 if (previewModel) await videoCreated.addAndSaveThumbnail(previewModel, t) 246 if (previewModel) await videoCreated.addAndSaveThumbnail(previewModel, t)
243 247
244 await autoBlacklistVideoIfNeeded(video, videoChannel.Account.User, t) 248 await autoBlacklistVideoIfNeeded(video, user, t)
245 249
246 // Set tags to the video 250 // Set tags to the video
247 if (tags) { 251 if (tags) {
diff --git a/server/controllers/static.ts b/server/controllers/static.ts
index d57dba6ce..a6b462443 100644
--- a/server/controllers/static.ts
+++ b/server/controllers/static.ts
@@ -156,6 +156,19 @@ staticRouter.use('/.well-known/change-password',
156 } 156 }
157) 157)
158 158
159staticRouter.use('/.well-known/host-meta',
160 (_, res: express.Response) => {
161 res.type('application/xml')
162
163 const xml = '<?xml version="1.0" encoding="UTF-8"?>\n' +
164 '<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">\n' +
165 ` <Link rel="lrdd" type="application/xrd+xml" template="${WEBSERVER.URL}/.well-known/webfinger?resource={uri}"/>\n` +
166 '</XRD>'
167
168 res.send(xml).end()
169 }
170)
171
159// --------------------------------------------------------------------------- 172// ---------------------------------------------------------------------------
160 173
161export { 174export {
diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts
index e907bbdc0..8760a4787 100644
--- a/server/tests/api/videos/video-blacklist.ts
+++ b/server/tests/api/videos/video-blacklist.ts
@@ -4,10 +4,11 @@ import * as chai from 'chai'
4import { orderBy } from 'lodash' 4import { orderBy } from 'lodash'
5import 'mocha' 5import 'mocha'
6import { 6import {
7 addVideoToBlacklist, cleanupTests, 7 addVideoToBlacklist,
8 cleanupTests,
8 createUser, 9 createUser,
9 flushAndRunMultipleServers, 10 flushAndRunMultipleServers,
10 getBlacklistedVideosList, 11 getBlacklistedVideosList, getMyUserInformation,
11 getMyVideos, 12 getMyVideos,
12 getVideosList, 13 getVideosList,
13 killallServers, 14 killallServers,
@@ -16,6 +17,7 @@ import {
16 searchVideo, 17 searchVideo,
17 ServerInfo, 18 ServerInfo,
18 setAccessTokensToServers, 19 setAccessTokensToServers,
20 setDefaultVideoChannel,
19 updateVideo, 21 updateVideo,
20 updateVideoBlacklist, 22 updateVideoBlacklist,
21 uploadVideo, 23 uploadVideo,
@@ -25,7 +27,8 @@ import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
25import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 27import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
26import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos' 28import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos'
27import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' 29import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
28import { UserRole } from '../../../../shared/models/users' 30import { User, UserRole, UserUpdateMe } from '../../../../shared/models/users'
31import { getMagnetURI, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
29 32
30const expect = chai.expect 33const expect = chai.expect
31 34
@@ -351,6 +354,7 @@ describe('Test video blacklist', function () {
351 describe('When auto blacklist videos', function () { 354 describe('When auto blacklist videos', function () {
352 let userWithoutFlag: string 355 let userWithoutFlag: string
353 let userWithFlag: string 356 let userWithFlag: string
357 let channelOfUserWithoutFlag: number
354 358
355 before(async function () { 359 before(async function () {
356 this.timeout(20000) 360 this.timeout(20000)
@@ -380,6 +384,10 @@ describe('Test video blacklist', function () {
380 }) 384 })
381 385
382 userWithoutFlag = await userLogin(servers[0], user) 386 userWithoutFlag = await userLogin(servers[0], user)
387
388 const res = await getMyUserInformation(servers[0].url, userWithoutFlag)
389 const body: User = res.body
390 channelOfUserWithoutFlag = body.videoChannels[0].id
383 } 391 }
384 392
385 { 393 {
@@ -399,7 +407,7 @@ describe('Test video blacklist', function () {
399 await waitJobs(servers) 407 await waitJobs(servers)
400 }) 408 })
401 409
402 it('Should auto blacklist a video', async function () { 410 it('Should auto blacklist a video on upload', async function () {
403 await uploadVideo(servers[0].url, userWithoutFlag, { name: 'blacklisted' }) 411 await uploadVideo(servers[0].url, userWithoutFlag, { name: 'blacklisted' })
404 412
405 const res = await getBlacklistedVideosList({ 413 const res = await getBlacklistedVideosList({
@@ -412,7 +420,45 @@ describe('Test video blacklist', function () {
412 expect(res.body.data[0].video.name).to.equal('blacklisted') 420 expect(res.body.data[0].video.name).to.equal('blacklisted')
413 }) 421 })
414 422
415 it('Should not auto blacklist a video', async function () { 423 it('Should auto blacklist a video on URL import', async function () {
424 const attributes = {
425 targetUrl: getYoutubeVideoUrl(),
426 name: 'URL import',
427 channelId: channelOfUserWithoutFlag
428 }
429 await importVideo(servers[ 0 ].url, userWithoutFlag, attributes)
430
431 const res = await getBlacklistedVideosList({
432 url: servers[ 0 ].url,
433 token: servers[ 0 ].accessToken,
434 sort: 'createdAt',
435 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
436 })
437
438 expect(res.body.total).to.equal(2)
439 expect(res.body.data[1].video.name).to.equal('URL import')
440 })
441
442 it('Should auto blacklist a video on torrent import', async function () {
443 const attributes = {
444 magnetUri: getMagnetURI(),
445 name: 'Torrent import',
446 channelId: channelOfUserWithoutFlag
447 }
448 await importVideo(servers[ 0 ].url, userWithoutFlag, attributes)
449
450 const res = await getBlacklistedVideosList({
451 url: servers[ 0 ].url,
452 token: servers[ 0 ].accessToken,
453 sort: 'createdAt',
454 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
455 })
456
457 expect(res.body.total).to.equal(3)
458 expect(res.body.data[2].video.name).to.equal('Torrent import')
459 })
460
461 it('Should not auto blacklist a video on upload if the user has the bypass blacklist flag', async function () {
416 await uploadVideo(servers[0].url, userWithFlag, { name: 'not blacklisted' }) 462 await uploadVideo(servers[0].url, userWithFlag, { name: 'not blacklisted' })
417 463
418 const res = await getBlacklistedVideosList({ 464 const res = await getBlacklistedVideosList({
@@ -421,7 +467,7 @@ describe('Test video blacklist', function () {
421 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 467 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
422 }) 468 })
423 469
424 expect(res.body.total).to.equal(1) 470 expect(res.body.total).to.equal(3)
425 }) 471 })
426 }) 472 })
427 473