diff options
8 files changed, 69 insertions, 54 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html index dfbbfbb29..fd4d3d9c9 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html | |||
@@ -87,15 +87,19 @@ | |||
87 | 87 | ||
88 | <div i18n class="inner-form-title">Signup</div> | 88 | <div i18n class="inner-form-title">Signup</div> |
89 | 89 | ||
90 | <my-peertube-checkbox | 90 | <div class="form-group"> |
91 | inputName="signupEnabled" formControlName="signupEnabled" | 91 | <my-peertube-checkbox |
92 | i18n-labelText labelText="Signup enabled" | 92 | inputName="signupEnabled" formControlName="signupEnabled" |
93 | ></my-peertube-checkbox> | 93 | i18n-labelText labelText="Signup enabled" |
94 | ></my-peertube-checkbox> | ||
95 | </div> | ||
94 | 96 | ||
95 | <my-peertube-checkbox *ngIf="isSignupEnabled()" | 97 | <div class="form-group"> |
96 | inputName="signupRequiresEmailVerification" formControlName="signupRequiresEmailVerification" | 98 | <my-peertube-checkbox *ngIf="isSignupEnabled()" |
97 | i18n-labelText labelText="Signup requires email verification" | 99 | inputName="signupRequiresEmailVerification" formControlName="signupRequiresEmailVerification" |
98 | ></my-peertube-checkbox> | 100 | i18n-labelText labelText="Signup requires email verification" |
101 | ></my-peertube-checkbox> | ||
102 | </div> | ||
99 | 103 | ||
100 | <div *ngIf="isSignupEnabled()" class="form-group"> | 104 | <div *ngIf="isSignupEnabled()" class="form-group"> |
101 | <label i18n for="signupLimit">Signup limit</label> | 105 | <label i18n for="signupLimit">Signup limit</label> |
@@ -110,15 +114,19 @@ | |||
110 | 114 | ||
111 | <div i18n class="inner-form-title">Import</div> | 115 | <div i18n class="inner-form-title">Import</div> |
112 | 116 | ||
113 | <my-peertube-checkbox | 117 | <div class="form-group"> |
114 | inputName="importVideosHttpEnabled" formControlName="importVideosHttpEnabled" | 118 | <my-peertube-checkbox |
115 | i18n-labelText labelText="Video import with HTTP URL (i.e. YouTube) enabled" | 119 | inputName="importVideosHttpEnabled" formControlName="importVideosHttpEnabled" |
116 | ></my-peertube-checkbox> | 120 | i18n-labelText labelText="Video import with HTTP URL (i.e. YouTube) enabled" |
121 | ></my-peertube-checkbox> | ||
122 | </div> | ||
117 | 123 | ||
118 | <my-peertube-checkbox | 124 | <div class="form-group"> |
119 | inputName="importVideosTorrentEnabled" formControlName="importVideosTorrentEnabled" | 125 | <my-peertube-checkbox |
120 | i18n-labelText labelText="Video import with a torrent file or a magnet URI enabled" | 126 | inputName="importVideosTorrentEnabled" formControlName="importVideosTorrentEnabled" |
121 | ></my-peertube-checkbox> | 127 | i18n-labelText labelText="Video import with a torrent file or a magnet URI enabled" |
128 | ></my-peertube-checkbox> | ||
129 | </div> | ||
122 | 130 | ||
123 | <div i18n class="inner-form-title">Administrator</div> | 131 | <div i18n class="inner-form-title">Administrator</div> |
124 | 132 | ||
@@ -184,13 +192,15 @@ | |||
184 | </div> | 192 | </div> |
185 | </div> | 193 | </div> |
186 | 194 | ||
187 | <my-peertube-checkbox | 195 | <div class="form-group"> |
188 | inputName="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted" | 196 | <my-peertube-checkbox |
189 | i18n-labelText labelText="Instance whitelisted by Twitter" | 197 | inputName="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted" |
190 | i18n-helpHtml helpHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> | 198 | i18n-labelText labelText="Instance whitelisted by Twitter" |
191 | If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br /> | 199 | i18n-helpHtml helpHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> |
192 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted." | 200 | If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br /> |
193 | ></my-peertube-checkbox> | 201 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted." |
202 | ></my-peertube-checkbox> | ||
203 | </div> | ||
194 | </ng-template> | 204 | </ng-template> |
195 | </ngb-tab> | 205 | </ngb-tab> |
196 | 206 | ||
@@ -199,11 +209,13 @@ | |||
199 | 209 | ||
200 | <div i18n class="inner-form-title">Transcoding</div> | 210 | <div i18n class="inner-form-title">Transcoding</div> |
201 | 211 | ||
202 | <my-peertube-checkbox | 212 | <div class="form-group"> |
203 | inputName="transcodingEnabled" formControlName="transcodingEnabled" | 213 | <my-peertube-checkbox |
204 | i18n-labelText labelText="Transcoding enabled" | 214 | inputName="transcodingEnabled" formControlName="transcodingEnabled" |
205 | i18n-helpHtml helpHtml="If you disable transcoding, many videos from your users will not work!" | 215 | i18n-labelText labelText="Transcoding enabled" |
206 | ></my-peertube-checkbox> | 216 | i18n-helpHtml helpHtml="If you disable transcoding, many videos from your users will not work!" |
217 | ></my-peertube-checkbox> | ||
218 | </div> | ||
207 | 219 | ||
208 | <ng-template [ngIf]="isTranscodingEnabled()"> | 220 | <ng-template [ngIf]="isTranscodingEnabled()"> |
209 | 221 | ||
@@ -226,7 +238,6 @@ | |||
226 | [inputName]="getResolutionKey(resolution)" [formControlName]="getResolutionKey(resolution)" | 238 | [inputName]="getResolutionKey(resolution)" [formControlName]="getResolutionKey(resolution)" |
227 | i18n-labelText labelText="Resolution {{resolution}} enabled" | 239 | i18n-labelText labelText="Resolution {{resolution}} enabled" |
228 | ></my-peertube-checkbox> | 240 | ></my-peertube-checkbox> |
229 | |||
230 | </div> | 241 | </div> |
231 | </ng-template> | 242 | </ng-template> |
232 | 243 | ||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html index 8be8a66cc..049119fa8 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html | |||
@@ -15,15 +15,19 @@ | |||
15 | </div> | 15 | </div> |
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <my-peertube-checkbox | 18 | <div class="form-group"> |
19 | inputName="webTorrentEnabled" formControlName="webTorrentEnabled" | 19 | <my-peertube-checkbox |
20 | i18n-labelText labelText="Use WebTorrent to exchange parts of the video with others" | 20 | inputName="webTorrentEnabled" formControlName="webTorrentEnabled" |
21 | ></my-peertube-checkbox> | 21 | i18n-labelText labelText="Use WebTorrent to exchange parts of the video with others" |
22 | ></my-peertube-checkbox> | ||
23 | </div> | ||
22 | 24 | ||
23 | <my-peertube-checkbox | 25 | <div class="form-group"> |
24 | inputName="autoPlayVideo" formControlName="autoPlayVideo" | 26 | <my-peertube-checkbox |
25 | i18n-labelText labelText="Automatically plays video" | 27 | inputName="autoPlayVideo" formControlName="autoPlayVideo" |
26 | ></my-peertube-checkbox> | 28 | i18n-labelText labelText="Automatically plays video" |
29 | ></my-peertube-checkbox> | ||
30 | </div> | ||
27 | 31 | ||
28 | <input type="submit" i18n-value value="Save" [disabled]="!form.valid"> | 32 | <input type="submit" i18n-value value="Save" [disabled]="!form.valid"> |
29 | </form> | 33 | </form> |
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index bcbd9be59..79b76fa0b 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import * as validator from 'validator' | 2 | import * as validator from 'validator' |
3 | import { ResultList } from '../../shared/models' | 3 | import { ResultList } from '../../shared/models' |
4 | import { Activity, ActivityPubActor } from '../../shared/models/activitypub' | 4 | import { Activity } from '../../shared/models/activitypub' |
5 | import { ACTIVITY_PUB } from '../initializers' | 5 | import { ACTIVITY_PUB } from '../initializers' |
6 | import { ActorModel } from '../models/activitypub/actor' | 6 | import { ActorModel } from '../models/activitypub/actor' |
7 | import { signJsonLDObject } from './peertube-crypto' | 7 | import { signJsonLDObject } from './peertube-crypto' |
@@ -106,10 +106,10 @@ function buildSignedActivity (byActor: ActorModel, data: Object) { | |||
106 | return signJsonLDObject(byActor, activity) as Promise<Activity> | 106 | return signJsonLDObject(byActor, activity) as Promise<Activity> |
107 | } | 107 | } |
108 | 108 | ||
109 | function getActorUrl (activityActor: string | ActivityPubActor) { | 109 | function getAPUrl (activity: string | { id: string }) { |
110 | if (typeof activityActor === 'string') return activityActor | 110 | if (typeof activity === 'string') return activity |
111 | 111 | ||
112 | return activityActor.id | 112 | return activity.id |
113 | } | 113 | } |
114 | 114 | ||
115 | function checkUrlsSameHost (url1: string, url2: string) { | 115 | function checkUrlsSameHost (url1: string, url2: string) { |
@@ -123,7 +123,7 @@ function checkUrlsSameHost (url1: string, url2: string) { | |||
123 | 123 | ||
124 | export { | 124 | export { |
125 | checkUrlsSameHost, | 125 | checkUrlsSameHost, |
126 | getActorUrl, | 126 | getAPUrl, |
127 | activityPubContextify, | 127 | activityPubContextify, |
128 | activityPubCollectionPagination, | 128 | activityPubCollectionPagination, |
129 | buildSignedActivity | 129 | buildSignedActivity |
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index 218dbc6a7..504263c99 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -5,15 +5,15 @@ import * as url from 'url' | |||
5 | import * as uuidv4 from 'uuid/v4' | 5 | import * as uuidv4 from 'uuid/v4' |
6 | import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub' | 6 | import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub' |
7 | import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects' | 7 | import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects' |
8 | import { checkUrlsSameHost, getActorUrl } from '../../helpers/activitypub' | 8 | import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' |
9 | import { isActorObjectValid, normalizeActor } from '../../helpers/custom-validators/activitypub/actor' | 9 | import { isActorObjectValid, normalizeActor } from '../../helpers/custom-validators/activitypub/actor' |
10 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | 10 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' |
11 | import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils' | 11 | import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils' |
12 | import { logger } from '../../helpers/logger' | 12 | import { logger } from '../../helpers/logger' |
13 | import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto' | 13 | import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto' |
14 | import { doRequest, doRequestAndSaveToFile, downloadImage } from '../../helpers/requests' | 14 | import { doRequest, downloadImage } from '../../helpers/requests' |
15 | import { getUrlFromWebfinger } from '../../helpers/webfinger' | 15 | import { getUrlFromWebfinger } from '../../helpers/webfinger' |
16 | import { AVATARS_SIZE, CONFIG, IMAGE_MIMETYPE_EXT, PREVIEWS_SIZE, sequelizeTypescript } from '../../initializers' | 16 | import { AVATARS_SIZE, CONFIG, IMAGE_MIMETYPE_EXT, sequelizeTypescript } from '../../initializers' |
17 | import { AccountModel } from '../../models/account/account' | 17 | import { AccountModel } from '../../models/account/account' |
18 | import { ActorModel } from '../../models/activitypub/actor' | 18 | import { ActorModel } from '../../models/activitypub/actor' |
19 | import { AvatarModel } from '../../models/avatar/avatar' | 19 | import { AvatarModel } from '../../models/avatar/avatar' |
@@ -43,7 +43,7 @@ async function getOrCreateActorAndServerAndModel ( | |||
43 | recurseIfNeeded = true, | 43 | recurseIfNeeded = true, |
44 | updateCollections = false | 44 | updateCollections = false |
45 | ) { | 45 | ) { |
46 | const actorUrl = getActorUrl(activityActor) | 46 | const actorUrl = getAPUrl(activityActor) |
47 | let created = false | 47 | let created = false |
48 | 48 | ||
49 | let actor = await fetchActorByUrl(actorUrl, fetchType) | 49 | let actor = await fetchActorByUrl(actorUrl, fetchType) |
diff --git a/server/lib/activitypub/process/process.ts b/server/lib/activitypub/process/process.ts index b9b255ddf..bcc5cac7a 100644 --- a/server/lib/activitypub/process/process.ts +++ b/server/lib/activitypub/process/process.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { Activity, ActivityType } from '../../../../shared/models/activitypub' | 1 | import { Activity, ActivityType } from '../../../../shared/models/activitypub' |
2 | import { checkUrlsSameHost, getActorUrl } from '../../../helpers/activitypub' | 2 | import { checkUrlsSameHost, getAPUrl } from '../../../helpers/activitypub' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { ActorModel } from '../../../models/activitypub/actor' | 4 | import { ActorModel } from '../../../models/activitypub/actor' |
5 | import { processAcceptActivity } from './process-accept' | 5 | import { processAcceptActivity } from './process-accept' |
@@ -40,7 +40,7 @@ async function processActivities ( | |||
40 | continue | 40 | continue |
41 | } | 41 | } |
42 | 42 | ||
43 | const actorUrl = getActorUrl(activity.actor) | 43 | const actorUrl = getAPUrl(activity.actor) |
44 | 44 | ||
45 | // When we fetch remote data, we don't have signature | 45 | // When we fetch remote data, we don't have signature |
46 | if (options.signatureActor && actorUrl !== options.signatureActor.url) { | 46 | if (options.signatureActor && actorUrl !== options.signatureActor.url) { |
diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts index d2649e2d5..5dcba778c 100644 --- a/server/lib/activitypub/share.ts +++ b/server/lib/activitypub/share.ts | |||
@@ -11,7 +11,7 @@ import { doRequest } from '../../helpers/requests' | |||
11 | import { getOrCreateActorAndServerAndModel } from './actor' | 11 | import { getOrCreateActorAndServerAndModel } from './actor' |
12 | import { logger } from '../../helpers/logger' | 12 | import { logger } from '../../helpers/logger' |
13 | import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers' | 13 | import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers' |
14 | import { checkUrlsSameHost, getActorUrl } from '../../helpers/activitypub' | 14 | import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' |
15 | 15 | ||
16 | async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) { | 16 | async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) { |
17 | if (video.privacy === VideoPrivacy.PRIVATE) return undefined | 17 | if (video.privacy === VideoPrivacy.PRIVATE) return undefined |
@@ -41,7 +41,7 @@ async function addVideoShares (shareUrls: string[], instance: VideoModel) { | |||
41 | }) | 41 | }) |
42 | if (!body || !body.actor) throw new Error('Body or body actor is invalid') | 42 | if (!body || !body.actor) throw new Error('Body or body actor is invalid') |
43 | 43 | ||
44 | const actorUrl = getActorUrl(body.actor) | 44 | const actorUrl = getAPUrl(body.actor) |
45 | if (checkUrlsSameHost(shareUrl, actorUrl) !== true) { | 45 | if (checkUrlsSameHost(shareUrl, actorUrl) !== true) { |
46 | throw new Error(`Actor url ${actorUrl} has not the same host than the share url ${shareUrl}`) | 46 | throw new Error(`Actor url ${actorUrl} has not the same host than the share url ${shareUrl}`) |
47 | } | 47 | } |
diff --git a/server/lib/activitypub/video-rates.ts b/server/lib/activitypub/video-rates.ts index 1854b44c4..2cce67f0c 100644 --- a/server/lib/activitypub/video-rates.ts +++ b/server/lib/activitypub/video-rates.ts | |||
@@ -9,7 +9,7 @@ import { AccountVideoRateModel } from '../../models/account/account-video-rate' | |||
9 | import { logger } from '../../helpers/logger' | 9 | import { logger } from '../../helpers/logger' |
10 | import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers' | 10 | import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers' |
11 | import { doRequest } from '../../helpers/requests' | 11 | import { doRequest } from '../../helpers/requests' |
12 | import { checkUrlsSameHost, getActorUrl } from '../../helpers/activitypub' | 12 | import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' |
13 | import { ActorModel } from '../../models/activitypub/actor' | 13 | import { ActorModel } from '../../models/activitypub/actor' |
14 | import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url' | 14 | import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url' |
15 | 15 | ||
@@ -26,7 +26,7 @@ async function createRates (ratesUrl: string[], video: VideoModel, rate: VideoRa | |||
26 | }) | 26 | }) |
27 | if (!body || !body.actor) throw new Error('Body or body actor is invalid') | 27 | if (!body || !body.actor) throw new Error('Body or body actor is invalid') |
28 | 28 | ||
29 | const actorUrl = getActorUrl(body.actor) | 29 | const actorUrl = getAPUrl(body.actor) |
30 | if (checkUrlsSameHost(actorUrl, rateUrl) !== true) { | 30 | if (checkUrlsSameHost(actorUrl, rateUrl) !== true) { |
31 | throw new Error(`Rate url ${rateUrl} has not the same host than actor url ${actorUrl}`) | 31 | throw new Error(`Rate url ${rateUrl} has not the same host than actor url ${actorUrl}`) |
32 | } | 32 | } |
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index 6ff9baefe..4cecf9345 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -29,7 +29,7 @@ import { createRates } from './video-rates' | |||
29 | import { addVideoShares, shareVideoByServerAndChannel } from './share' | 29 | import { addVideoShares, shareVideoByServerAndChannel } from './share' |
30 | import { AccountModel } from '../../models/account/account' | 30 | import { AccountModel } from '../../models/account/account' |
31 | import { fetchVideoByUrl, VideoFetchByUrlType } from '../../helpers/video' | 31 | import { fetchVideoByUrl, VideoFetchByUrlType } from '../../helpers/video' |
32 | import { checkUrlsSameHost } from '../../helpers/activitypub' | 32 | import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' |
33 | 33 | ||
34 | async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) { | 34 | async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) { |
35 | // If the video is not private and published, we federate it | 35 | // If the video is not private and published, we federate it |
@@ -167,7 +167,7 @@ async function getOrCreateVideoAndAccountAndChannel (options: { | |||
167 | const refreshViews = options.refreshViews || false | 167 | const refreshViews = options.refreshViews || false |
168 | 168 | ||
169 | // Get video url | 169 | // Get video url |
170 | const videoUrl = typeof options.videoObject === 'string' ? options.videoObject : options.videoObject.id | 170 | const videoUrl = getAPUrl(options.videoObject) |
171 | 171 | ||
172 | let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType) | 172 | let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType) |
173 | if (videoFromDatabase) { | 173 | if (videoFromDatabase) { |