diff options
author | Chocobozzz <me@florianbigard.com> | 2019-06-07 15:04:41 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-06-07 15:04:41 +0200 |
commit | b91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62 (patch) | |
tree | 754bb49026d4df8086030e28a8a7c16e3f0338b6 | |
parent | 851f5daa1eec66e1faa3c45238ec9ab91be05b00 (diff) | |
parent | 03371ad9d049bab79445a1b35da44cb1272f6c28 (diff) | |
download | PeerTube-b91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62.tar.gz PeerTube-b91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62.tar.zst PeerTube-b91bc1d1f3591c35ab4426f6ab594b4bd9f1ef62.zip |
Merge branch 'release/v1.3.0' into develop
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 | ||
4 | table { | 4 | table { |
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 | }) |
13 | export class RemoteSubscribeComponent extends FormReactive implements OnInit { | 13 | export 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' | |||
8 | import { Video } from '../../../shared/video/video.model' | 8 | import { Video } from '../../../shared/video/video.model' |
9 | import { VideoComment } from './video-comment.model' | 9 | import { VideoComment } from './video-comment.model' |
10 | import { VideoCommentService } from './video-comment.service' | 10 | import { VideoCommentService } from './video-comment.service' |
11 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
12 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' | 11 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' |
13 | import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service' | 12 | import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service' |
14 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' | 13 | import { 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' | |||
26 | import { createVideoMiniatureFromExisting } from '../../../lib/thumbnail' | 26 | import { createVideoMiniatureFromExisting } from '../../../lib/thumbnail' |
27 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' | 27 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' |
28 | import { ThumbnailModel } from '../../../models/video/thumbnail' | 28 | import { ThumbnailModel } from '../../../models/video/thumbnail' |
29 | import { UserModel } from '../../../models/account/user' | ||
29 | 30 | ||
30 | const auditLogger = auditLoggerFactory('video-imports') | 31 | const auditLogger = auditLoggerFactory('video-imports') |
31 | const videoImportsRouter = express.Router() | 32 | const 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 | ||
159 | staticRouter.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 | ||
161 | export { | 174 | export { |
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' | |||
4 | import { orderBy } from 'lodash' | 4 | import { orderBy } from 'lodash' |
5 | import 'mocha' | 5 | import 'mocha' |
6 | import { | 6 | import { |
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' | |||
25 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | 27 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' |
26 | import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos' | 28 | import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos' |
27 | import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' | 29 | import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' |
28 | import { UserRole } from '../../../../shared/models/users' | 30 | import { User, UserRole, UserUpdateMe } from '../../../../shared/models/users' |
31 | import { getMagnetURI, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports' | ||
29 | 32 | ||
30 | const expect = chai.expect | 33 | const 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 | ||