diff options
41 files changed, 186 insertions, 136 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/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts b/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts index 26b3bf4b1..e4a5522c8 100644 --- a/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts +++ b/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts | |||
@@ -25,7 +25,6 @@ export class VerifyAccountEmailComponent implements OnInit { | |||
25 | } | 25 | } |
26 | 26 | ||
27 | ngOnInit () { | 27 | ngOnInit () { |
28 | |||
29 | this.userId = this.route.snapshot.queryParams['userId'] | 28 | this.userId = this.route.snapshot.queryParams['userId'] |
30 | this.verificationString = this.route.snapshot.queryParams['verificationString'] | 29 | this.verificationString = this.route.snapshot.queryParams['verificationString'] |
31 | 30 | ||
diff --git a/scripts/travis.sh b/scripts/travis.sh index 49b7233e1..509b40d87 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh | |||
@@ -11,28 +11,25 @@ killall -q peertube || true | |||
11 | 11 | ||
12 | if [ "$1" = "misc" ]; then | 12 | if [ "$1" = "misc" ]; then |
13 | npm run build -- --light-fr | 13 | npm run build -- --light-fr |
14 | mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/client.ts \ | 14 | mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/client.ts \ |
15 | server/tests/feeds/index.ts \ | 15 | server/tests/feeds/index.ts \ |
16 | server/tests/misc-endpoints.ts \ | 16 | server/tests/misc-endpoints.ts \ |
17 | server/tests/helpers/index.ts | 17 | server/tests/helpers/index.ts |
18 | elif [ "$1" = "api" ]; then | ||
19 | npm run build:server | ||
20 | mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index.ts | ||
21 | elif [ "$1" = "cli" ]; then | 18 | elif [ "$1" = "cli" ]; then |
22 | npm run build:server | 19 | npm run build:server |
23 | mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/cli/index.ts | 20 | mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/cli/index.ts |
24 | elif [ "$1" = "api-1" ]; then | 21 | elif [ "$1" = "api-1" ]; then |
25 | npm run build:server | 22 | npm run build:server |
26 | mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-1.ts | 23 | mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-1.ts |
27 | elif [ "$1" = "api-2" ]; then | 24 | elif [ "$1" = "api-2" ]; then |
28 | npm run build:server | 25 | npm run build:server |
29 | mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-2.ts | 26 | mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-2.ts |
30 | elif [ "$1" = "api-3" ]; then | 27 | elif [ "$1" = "api-3" ]; then |
31 | npm run build:server | 28 | npm run build:server |
32 | mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-3.ts | 29 | mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-3.ts |
33 | elif [ "$1" = "api-4" ]; then | 30 | elif [ "$1" = "api-4" ]; then |
34 | npm run build:server | 31 | npm run build:server |
35 | mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-4.ts | 32 | mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-4.ts |
36 | elif [ "$1" = "lint" ]; then | 33 | elif [ "$1" = "lint" ]; then |
37 | npm run tslint -- --project ./tsconfig.json -c ./tslint.json server.ts "server/**/*.ts" "shared/**/*.ts" | 34 | npm run tslint -- --project ./tsconfig.json -c ./tslint.json server.ts "server/**/*.ts" "shared/**/*.ts" |
38 | 35 | ||
@@ -204,9 +204,11 @@ async function startApplication () { | |||
204 | 204 | ||
205 | // Email initialization | 205 | // Email initialization |
206 | Emailer.Instance.init() | 206 | Emailer.Instance.init() |
207 | await Emailer.Instance.checkConnectionOrDie() | ||
208 | 207 | ||
209 | await JobQueue.Instance.init() | 208 | await Promise.all([ |
209 | Emailer.Instance.checkConnectionOrDie(), | ||
210 | JobQueue.Instance.init() | ||
211 | ]) | ||
210 | 212 | ||
211 | // Caches initializations | 213 | // Caches initializations |
212 | VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, CACHE.PREVIEWS.MAX_AGE) | 214 | VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, CACHE.PREVIEWS.MAX_AGE) |
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/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index 8b9045038..b59e7e40e 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as ffmpeg from 'fluent-ffmpeg' | 1 | import * as ffmpeg from 'fluent-ffmpeg' |
2 | import { join } from 'path' | 2 | import { join } from 'path' |
3 | import { getTargetBitrate, VideoResolution } from '../../shared/models/videos' | 3 | import { getTargetBitrate, VideoResolution } from '../../shared/models/videos' |
4 | import { CONFIG, FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers' | 4 | import { CONFIG, FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers/constants' |
5 | import { processImage } from './image-utils' | 5 | import { processImage } from './image-utils' |
6 | import { logger } from './logger' | 6 | import { logger } from './logger' |
7 | import { checkFFmpegEncoders } from '../initializers/checker-before-init' | 7 | import { checkFFmpegEncoders } from '../initializers/checker-before-init' |
diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts index 3eaa674ed..da3285b13 100644 --- a/server/helpers/image-utils.ts +++ b/server/helpers/image-utils.ts | |||
@@ -1,13 +1,28 @@ | |||
1 | import 'multer' | 1 | import 'multer' |
2 | import * as sharp from 'sharp' | 2 | import * as sharp from 'sharp' |
3 | import { remove } from 'fs-extra' | 3 | import { move, remove } from 'fs-extra' |
4 | 4 | ||
5 | async function processImage ( | 5 | async function processImage ( |
6 | physicalFile: { path: string }, | 6 | physicalFile: { path: string }, |
7 | destination: string, | 7 | destination: string, |
8 | newSize: { width: number, height: number } | 8 | newSize: { width: number, height: number } |
9 | ) { | 9 | ) { |
10 | await sharp(physicalFile.path) | 10 | if (physicalFile.path === destination) { |
11 | throw new Error('Sharp needs an input path different that the output path.') | ||
12 | } | ||
13 | |||
14 | const sharpInstance = sharp(physicalFile.path) | ||
15 | const metadata = await sharpInstance.metadata() | ||
16 | |||
17 | // No need to resize | ||
18 | if (metadata.width === newSize.width && metadata.height === newSize.height) { | ||
19 | await move(physicalFile.path, destination, { overwrite: true }) | ||
20 | return | ||
21 | } | ||
22 | |||
23 | await remove(destination) | ||
24 | |||
25 | await sharpInstance | ||
11 | .resize(newSize.width, newSize.height) | 26 | .resize(newSize.width, newSize.height) |
12 | .toFile(destination) | 27 | .toFile(destination) |
13 | 28 | ||
diff --git a/server/initializers/database.ts b/server/initializers/database.ts index dd5b9bf67..40cd659ab 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts | |||
@@ -119,25 +119,27 @@ export { | |||
119 | // --------------------------------------------------------------------------- | 119 | // --------------------------------------------------------------------------- |
120 | 120 | ||
121 | async function checkPostgresExtensions () { | 121 | async function checkPostgresExtensions () { |
122 | const extensions = [ | 122 | const promises = [ |
123 | 'pg_trgm', | 123 | checkPostgresExtension('pg_trgm'), |
124 | 'unaccent' | 124 | checkPostgresExtension('unaccent') |
125 | ] | 125 | ] |
126 | 126 | ||
127 | for (const extension of extensions) { | 127 | return Promise.all(promises) |
128 | const query = `SELECT true AS enabled FROM pg_available_extensions WHERE name = '${extension}' AND installed_version IS NOT NULL;` | 128 | } |
129 | const [ res ] = await sequelizeTypescript.query(query, { raw: true }) | 129 | |
130 | async function checkPostgresExtension (extension: string) { | ||
131 | const query = `SELECT true AS enabled FROM pg_available_extensions WHERE name = '${extension}' AND installed_version IS NOT NULL;` | ||
132 | const [ res ] = await sequelizeTypescript.query(query, { raw: true }) | ||
130 | 133 | ||
131 | if (!res || res.length === 0 || res[ 0 ][ 'enabled' ] !== true) { | 134 | if (!res || res.length === 0 || res[ 0 ][ 'enabled' ] !== true) { |
132 | // Try to create the extension ourself | 135 | // Try to create the extension ourself |
133 | try { | 136 | try { |
134 | await sequelizeTypescript.query(`CREATE EXTENSION ${extension};`, { raw: true }) | 137 | await sequelizeTypescript.query(`CREATE EXTENSION ${extension};`, { raw: true }) |
135 | 138 | ||
136 | } catch { | 139 | } catch { |
137 | const errorMessage = `You need to enable ${extension} extension in PostgreSQL. ` + | 140 | const errorMessage = `You need to enable ${extension} extension in PostgreSQL. ` + |
138 | `You can do so by running 'CREATE EXTENSION ${extension};' as a PostgreSQL super user in ${CONFIG.DATABASE.DBNAME} database.` | 141 | `You can do so by running 'CREATE EXTENSION ${extension};' as a PostgreSQL super user in ${CONFIG.DATABASE.DBNAME} database.` |
139 | throw new Error(errorMessage) | 142 | throw new Error(errorMessage) |
140 | } | ||
141 | } | 143 | } |
142 | } | 144 | } |
143 | } | 145 | } |
diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts index c952ad46c..b9a9da183 100644 --- a/server/initializers/installer.ts +++ b/server/initializers/installer.ts | |||
@@ -12,12 +12,21 @@ import { remove, ensureDir } from 'fs-extra' | |||
12 | 12 | ||
13 | async function installApplication () { | 13 | async function installApplication () { |
14 | try { | 14 | try { |
15 | await sequelizeTypescript.sync() | 15 | await Promise.all([ |
16 | await removeCacheDirectories() | 16 | // Database related |
17 | await createDirectoriesIfNotExist() | 17 | sequelizeTypescript.sync() |
18 | await createApplicationIfNotExist() | 18 | .then(() => { |
19 | await createOAuthClientIfNotExist() | 19 | return Promise.all([ |
20 | await createOAuthAdminIfNotExist() | 20 | createApplicationIfNotExist(), |
21 | createOAuthClientIfNotExist(), | ||
22 | createOAuthAdminIfNotExist() | ||
23 | ]) | ||
24 | }), | ||
25 | |||
26 | // Directories | ||
27 | removeCacheDirectories() | ||
28 | .then(() => createDirectoriesIfNotExist()) | ||
29 | ]) | ||
21 | } catch (err) { | 30 | } catch (err) { |
22 | logger.error('Cannot install application.', { err }) | 31 | logger.error('Cannot install application.', { err }) |
23 | process.exit(-1) | 32 | process.exit(-1) |
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 80de92f24..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) { |
@@ -242,10 +242,6 @@ async function updateVideoFromAP (options: { | |||
242 | if (options.updateViews === true) options.video.set('views', videoData.views) | 242 | if (options.updateViews === true) options.video.set('views', videoData.views) |
243 | await options.video.save(sequelizeOptions) | 243 | await options.video.save(sequelizeOptions) |
244 | 244 | ||
245 | // Don't block on request | ||
246 | generateThumbnailFromUrl(options.video, options.videoObject.icon) | ||
247 | .catch(err => logger.warn('Cannot generate thumbnail of %s.', options.videoObject.id, { err })) | ||
248 | |||
249 | { | 245 | { |
250 | const videoFileAttributes = videoFileActivityUrlToDBAttributes(options.video, options.videoObject) | 246 | const videoFileAttributes = videoFileActivityUrlToDBAttributes(options.video, options.videoObject) |
251 | const newVideoFiles = videoFileAttributes.map(a => new VideoFileModel(a)) | 247 | const newVideoFiles = videoFileAttributes.map(a => new VideoFileModel(a)) |
@@ -293,6 +289,12 @@ async function updateVideoFromAP (options: { | |||
293 | logger.debug('Cannot update the remote video.', { err }) | 289 | logger.debug('Cannot update the remote video.', { err }) |
294 | throw err | 290 | throw err |
295 | } | 291 | } |
292 | |||
293 | try { | ||
294 | await generateThumbnailFromUrl(options.video, options.videoObject.icon) | ||
295 | } catch (err) { | ||
296 | logger.warn('Cannot generate thumbnail of %s.', options.videoObject.id, { err }) | ||
297 | } | ||
296 | } | 298 | } |
297 | 299 | ||
298 | export { | 300 | export { |
diff --git a/server/lib/user.ts b/server/lib/user.ts index db29469eb..29d6d087d 100644 --- a/server/lib/user.ts +++ b/server/lib/user.ts | |||
@@ -18,7 +18,7 @@ async function createUserAccountAndChannel (userToCreate: UserModel, validateUse | |||
18 | } | 18 | } |
19 | 19 | ||
20 | const userCreated = await userToCreate.save(userOptions) | 20 | const userCreated = await userToCreate.save(userOptions) |
21 | const accountCreated = await createLocalAccountWithoutKeys(userToCreate.username, userToCreate.id, null, t) | 21 | const accountCreated = await createLocalAccountWithoutKeys(userCreated.username, userCreated.id, null, t) |
22 | userCreated.Account = accountCreated | 22 | userCreated.Account = accountCreated |
23 | 23 | ||
24 | let channelName = userCreated.username + '_channel' | 24 | let channelName = userCreated.username + '_channel' |
@@ -37,8 +37,13 @@ async function createUserAccountAndChannel (userToCreate: UserModel, validateUse | |||
37 | return { user: userCreated, account: accountCreated, videoChannel } | 37 | return { user: userCreated, account: accountCreated, videoChannel } |
38 | }) | 38 | }) |
39 | 39 | ||
40 | account.Actor = await setAsyncActorKeys(account.Actor) | 40 | const [ accountKeys, channelKeys ] = await Promise.all([ |
41 | videoChannel.Actor = await setAsyncActorKeys(videoChannel.Actor) | 41 | setAsyncActorKeys(account.Actor), |
42 | setAsyncActorKeys(videoChannel.Actor) | ||
43 | ]) | ||
44 | |||
45 | account.Actor = accountKeys | ||
46 | videoChannel.Actor = channelKeys | ||
42 | 47 | ||
43 | return { user, account, videoChannel } as { user: UserModel, account: AccountModel, videoChannel: VideoChannelModel } | 48 | return { user, account, videoChannel } as { user: UserModel, account: AccountModel, videoChannel: VideoChannelModel } |
44 | } | 49 | } |
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 34aafa1a7..1843603f1 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { | 2 | import { |
3 | AfterDelete, | 3 | AfterDestroy, |
4 | AfterUpdate, | 4 | AfterUpdate, |
5 | AllowNull, | 5 | AllowNull, |
6 | BeforeCreate, | 6 | BeforeCreate, |
@@ -179,7 +179,7 @@ export class UserModel extends Model<UserModel> { | |||
179 | } | 179 | } |
180 | 180 | ||
181 | @AfterUpdate | 181 | @AfterUpdate |
182 | @AfterDelete | 182 | @AfterDestroy |
183 | static removeTokenCache (instance: UserModel) { | 183 | static removeTokenCache (instance: UserModel) { |
184 | return clearCacheByUserId(instance.id) | 184 | return clearCacheByUserId(instance.id) |
185 | } | 185 | } |
diff --git a/server/models/oauth/oauth-token.ts b/server/models/oauth/oauth-token.ts index ecf846821..08d892da4 100644 --- a/server/models/oauth/oauth-token.ts +++ b/server/models/oauth/oauth-token.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { | 1 | import { |
2 | AfterDelete, | 2 | AfterDestroy, |
3 | AfterUpdate, | 3 | AfterUpdate, |
4 | AllowNull, | 4 | AllowNull, |
5 | BelongsTo, | 5 | BelongsTo, |
@@ -126,7 +126,7 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> { | |||
126 | OAuthClients: OAuthClientModel[] | 126 | OAuthClients: OAuthClientModel[] |
127 | 127 | ||
128 | @AfterUpdate | 128 | @AfterUpdate |
129 | @AfterDelete | 129 | @AfterDestroy |
130 | static removeTokenCache (token: OAuthTokenModel) { | 130 | static removeTokenCache (token: OAuthTokenModel) { |
131 | return clearCacheByToken(token.accessToken) | 131 | return clearCacheByToken(token.accessToken) |
132 | } | 132 | } |
diff --git a/server/tests/api/activitypub/security.ts b/server/tests/api/activitypub/security.ts index 69b7c0148..b71a61c8c 100644 --- a/server/tests/api/activitypub/security.ts +++ b/server/tests/api/activitypub/security.ts | |||
@@ -8,15 +8,12 @@ import { | |||
8 | killallServers, | 8 | killallServers, |
9 | ServerInfo | 9 | ServerInfo |
10 | } from '../../../../shared/utils' | 10 | } from '../../../../shared/utils' |
11 | import { | ||
12 | makePOSTAPRequest, | ||
13 | makeFollowRequest, | ||
14 | } from '../../utils/requests/activitypub' | ||
15 | import { HTTP_SIGNATURE } from '../../../initializers' | 11 | import { HTTP_SIGNATURE } from '../../../initializers' |
16 | import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' | 12 | import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' |
17 | import * as chai from 'chai' | 13 | import * as chai from 'chai' |
18 | import { setActorField } from '../../utils/miscs/sql' | 14 | import { setActorField } from '../../utils/miscs/sql' |
19 | import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub' | 15 | import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub' |
16 | import { makeFollowRequest, makePOSTAPRequest } from '../../utils/requests/activitypub' | ||
20 | 17 | ||
21 | const expect = chai.expect | 18 | const expect = chai.expect |
22 | 19 | ||
diff --git a/server/tests/api/users/index.ts b/server/tests/api/users/index.ts index 0a1b8b0b2..ff433315d 100644 --- a/server/tests/api/users/index.ts +++ b/server/tests/api/users/index.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import './blocklist' | 1 | import './blocklist' |
2 | import './user-subscriptions' | 2 | import './user-subscriptions' |
3 | import './users' | 3 | import './users' |
4 | import './users-verification' | ||
5 | import './users-multiple-servers' | 4 | import './users-multiple-servers' |
5 | import './users-verification' | ||
diff --git a/server/tests/api/videos/video-blacklist-management.ts b/server/tests/api/videos/video-blacklist-management.ts index 06d80a270..61411e30d 100644 --- a/server/tests/api/videos/video-blacklist-management.ts +++ b/server/tests/api/videos/video-blacklist-management.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | 1 | /* tslint:disable:no-unused-expression */ |
2 | 2 | ||
3 | import * as chai from 'chai' | 3 | import * as chai from 'chai' |
4 | import * as lodash from 'lodash' | 4 | import { orderBy } from 'lodash' |
5 | import 'mocha' | 5 | import 'mocha' |
6 | import { | 6 | import { |
7 | addVideoToBlacklist, | 7 | addVideoToBlacklist, |
@@ -22,7 +22,6 @@ import { waitJobs } from '../../../../shared/utils/server/jobs' | |||
22 | import { VideoAbuse } from '../../../../shared/models/videos' | 22 | import { VideoAbuse } from '../../../../shared/models/videos' |
23 | 23 | ||
24 | const expect = chai.expect | 24 | const expect = chai.expect |
25 | const orderBy = lodash.orderBy | ||
26 | 25 | ||
27 | describe('Test video blacklist management', function () { | 26 | describe('Test video blacklist management', function () { |
28 | let servers: ServerInfo[] = [] | 27 | let servers: ServerInfo[] = [] |
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts index 5bffffc66..63514d69c 100644 --- a/server/tests/api/videos/video-channels.ts +++ b/server/tests/api/videos/video-channels.ts | |||
@@ -7,10 +7,12 @@ import { | |||
7 | createUser, | 7 | createUser, |
8 | doubleFollow, | 8 | doubleFollow, |
9 | flushAndRunMultipleServers, | 9 | flushAndRunMultipleServers, |
10 | getVideoChannelVideos, serverLogin, testImage, | 10 | getVideoChannelVideos, |
11 | testImage, | ||
11 | updateVideo, | 12 | updateVideo, |
12 | updateVideoChannelAvatar, | 13 | updateVideoChannelAvatar, |
13 | uploadVideo, wait, userLogin | 14 | uploadVideo, |
15 | userLogin | ||
14 | } from '../../../../shared/utils' | 16 | } from '../../../../shared/utils' |
15 | import { | 17 | import { |
16 | addVideoChannel, | 18 | addVideoChannel, |
diff --git a/server/tests/api/videos/video-schedule-update.ts b/server/tests/api/videos/video-schedule-update.ts index ecfc5e034..632c4244c 100644 --- a/server/tests/api/videos/video-schedule-update.ts +++ b/server/tests/api/videos/video-schedule-update.ts | |||
@@ -16,7 +16,6 @@ import { | |||
16 | uploadVideo, | 16 | uploadVideo, |
17 | wait | 17 | wait |
18 | } from '../../../../shared/utils' | 18 | } from '../../../../shared/utils' |
19 | import { join } from 'path' | ||
20 | import { waitJobs } from '../../../../shared/utils/server/jobs' | 19 | import { waitJobs } from '../../../../shared/utils/server/jobs' |
21 | 20 | ||
22 | const expect = chai.expect | 21 | const expect = chai.expect |
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts index f9458f0ec..68cf00194 100644 --- a/server/tests/api/videos/video-transcoder.ts +++ b/server/tests/api/videos/video-transcoder.ts | |||
@@ -3,13 +3,13 @@ | |||
3 | import * as chai from 'chai' | 3 | import * as chai from 'chai' |
4 | import 'mocha' | 4 | import 'mocha' |
5 | import { omit } from 'lodash' | 5 | import { omit } from 'lodash' |
6 | import * as ffmpeg from 'fluent-ffmpeg' | ||
7 | import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos' | 6 | import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos' |
8 | import { audio, getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' | 7 | import { audio, getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' |
9 | import { | 8 | import { |
10 | buildAbsoluteFixturePath, | 9 | buildAbsoluteFixturePath, |
11 | doubleFollow, | 10 | doubleFollow, |
12 | flushAndRunMultipleServers, | 11 | flushAndRunMultipleServers, |
12 | generateHighBitrateVideo, | ||
13 | getMyVideos, | 13 | getMyVideos, |
14 | getVideo, | 14 | getVideo, |
15 | getVideosList, | 15 | getVideosList, |
@@ -18,8 +18,7 @@ import { | |||
18 | ServerInfo, | 18 | ServerInfo, |
19 | setAccessTokensToServers, | 19 | setAccessTokensToServers, |
20 | uploadVideo, | 20 | uploadVideo, |
21 | webtorrentAdd, | 21 | webtorrentAdd |
22 | generateHighBitrateVideo | ||
23 | } from '../../../../shared/utils' | 22 | } from '../../../../shared/utils' |
24 | import { join } from 'path' | 23 | import { join } from 'path' |
25 | import { waitJobs } from '../../../../shared/utils/server/jobs' | 24 | import { waitJobs } from '../../../../shared/utils/server/jobs' |
diff --git a/shared/utils/requests/check-api-params.ts b/shared/utils/requests/check-api-params.ts index edb47e0e9..a2a549682 100644 --- a/shared/utils/requests/check-api-params.ts +++ b/shared/utils/requests/check-api-params.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { makeGetRequest } from './requests' | 1 | import { makeGetRequest } from './requests' |
2 | import { immutableAssign } from '..' | 2 | import { immutableAssign } from '../miscs/miscs' |
3 | 3 | ||
4 | function checkBadStartPagination (url: string, path: string, token?: string, query = {}) { | 4 | function checkBadStartPagination (url: string, path: string, token?: string, query = {}) { |
5 | return makeGetRequest({ | 5 | return makeGetRequest({ |
diff --git a/shared/utils/search/videos.ts b/shared/utils/search/videos.ts index 115b3ff9a..ba4627017 100644 --- a/shared/utils/search/videos.ts +++ b/shared/utils/search/videos.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import * as request from 'supertest' | 3 | import * as request from 'supertest' |
4 | import { VideosSearchQuery } from '../../models/search' | 4 | import { VideosSearchQuery } from '../../models/search' |
5 | import { immutableAssign } from '..' | 5 | import { immutableAssign } from '../miscs/miscs' |
6 | 6 | ||
7 | function searchVideo (url: string, search: string) { | 7 | function searchVideo (url: string, search: string) { |
8 | const path = '/api/v1/search/videos' | 8 | const path = '/api/v1/search/videos' |
diff --git a/shared/utils/server/config.ts b/shared/utils/server/config.ts index 15a94432b..5b888b061 100644 --- a/shared/utils/server/config.ts +++ b/shared/utils/server/config.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../' | 1 | import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../requests/requests' |
2 | import { CustomConfig } from '../../models/server/custom-config.model' | 2 | import { CustomConfig } from '../../models/server/custom-config.model' |
3 | 3 | ||
4 | function getConfig (url: string) { | 4 | function getConfig (url: string) { |
diff --git a/shared/utils/server/jobs.ts b/shared/utils/server/jobs.ts index 3eec1d7d7..7c7e89824 100644 --- a/shared/utils/server/jobs.ts +++ b/shared/utils/server/jobs.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { Job, JobState } from '../../models' | 2 | import { Job, JobState } from '../../models' |
3 | import { ServerInfo, wait } from '../index' | 3 | import { wait } from '../miscs/miscs' |
4 | import { ServerInfo } from './servers' | ||
4 | 5 | ||
5 | function getJobsList (url: string, accessToken: string, state: JobState) { | 6 | function getJobsList (url: string, accessToken: string, state: JobState) { |
6 | const path = '/api/v1/jobs/' + state | 7 | const path = '/api/v1/jobs/' + state |
diff --git a/shared/utils/server/stats.ts b/shared/utils/server/stats.ts index 01989d952..6f079ad18 100644 --- a/shared/utils/server/stats.ts +++ b/shared/utils/server/stats.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { makeGetRequest } from '../' | 1 | import { makeGetRequest } from '../requests/requests' |
2 | 2 | ||
3 | function getStats (url: string, useCache = false) { | 3 | function getStats (url: string, useCache = false) { |
4 | const path = '/api/v1/server/stats' | 4 | const path = '/api/v1/server/stats' |
diff --git a/shared/utils/users/accounts.ts b/shared/utils/users/accounts.ts index 5601f2a77..388eb6973 100644 --- a/shared/utils/users/accounts.ts +++ b/shared/utils/users/accounts.ts | |||
@@ -4,7 +4,7 @@ import { expect } from 'chai' | |||
4 | import { existsSync, readdir } from 'fs-extra' | 4 | import { existsSync, readdir } from 'fs-extra' |
5 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { Account } from '../../models/actors' | 6 | import { Account } from '../../models/actors' |
7 | import { root } from '../index' | 7 | import { root } from '../miscs/miscs' |
8 | import { makeGetRequest } from '../requests/requests' | 8 | import { makeGetRequest } from '../requests/requests' |
9 | 9 | ||
10 | function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) { | 10 | function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) { |
diff --git a/shared/utils/users/blocklist.ts b/shared/utils/users/blocklist.ts index 35b537571..0ead5e5f6 100644 --- a/shared/utils/users/blocklist.ts +++ b/shared/utils/users/blocklist.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | 1 | /* tslint:disable:no-unused-expression */ |
2 | 2 | ||
3 | import { makeDeleteRequest, makePostBodyRequest } from '../index' | 3 | import { makeDeleteRequest, makePostBodyRequest } from '../requests/requests' |
4 | import { makeGetRequest } from '../requests/requests' | 4 | import { makeGetRequest } from '../requests/requests' |
5 | 5 | ||
6 | function getAccountBlocklistByAccount ( | 6 | function getAccountBlocklistByAccount ( |
diff --git a/shared/utils/users/user-subscriptions.ts b/shared/utils/users/user-subscriptions.ts index b0e7da7cc..7148fbfca 100644 --- a/shared/utils/users/user-subscriptions.ts +++ b/shared/utils/users/user-subscriptions.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../' | 1 | import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../requests/requests' |
2 | 2 | ||
3 | function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) { | 3 | function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) { |
4 | const path = '/api/v1/users/me/subscriptions' | 4 | const path = '/api/v1/users/me/subscriptions' |
diff --git a/shared/utils/users/users.ts b/shared/utils/users/users.ts index 1b385aaf7..d5d62a507 100644 --- a/shared/utils/users/users.ts +++ b/shared/utils/users/users.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../' | 2 | import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests' |
3 | 3 | ||
4 | import { UserRole } from '../../index' | 4 | import { UserRole } from '../../index' |
5 | import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type' | 5 | import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type' |
diff --git a/shared/utils/videos/video-abuses.ts b/shared/utils/videos/video-abuses.ts index 8be891a9b..7f011ec0f 100644 --- a/shared/utils/videos/video-abuses.ts +++ b/shared/utils/videos/video-abuses.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { VideoAbuseUpdate } from '../../models/videos/abuse/video-abuse-update.model' | 2 | import { VideoAbuseUpdate } from '../../models/videos/abuse/video-abuse-update.model' |
3 | import { makeDeleteRequest, makePutBodyRequest } from '..' | 3 | import { makeDeleteRequest, makePutBodyRequest } from '../requests/requests' |
4 | 4 | ||
5 | function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) { | 5 | function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) { |
6 | const path = '/api/v1/videos/' + videoId + '/abuse' | 6 | const path = '/api/v1/videos/' + videoId + '/abuse' |
diff --git a/shared/utils/videos/video-captions.ts b/shared/utils/videos/video-captions.ts index 41e52be07..8d67f617b 100644 --- a/shared/utils/videos/video-captions.ts +++ b/shared/utils/videos/video-captions.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { makeDeleteRequest, makeGetRequest } from '../' | 1 | import { makeDeleteRequest, makeGetRequest, makeUploadRequest } from '../requests/requests' |
2 | import { buildAbsoluteFixturePath, makeUploadRequest } from '../index' | ||
3 | import * as request from 'supertest' | 2 | import * as request from 'supertest' |
4 | import * as chai from 'chai' | 3 | import * as chai from 'chai' |
4 | import { buildAbsoluteFixturePath } from '../miscs/miscs' | ||
5 | 5 | ||
6 | const expect = chai.expect | 6 | const expect = chai.expect |
7 | 7 | ||
diff --git a/shared/utils/videos/video-channels.ts b/shared/utils/videos/video-channels.ts index 3d37f0e4c..3935c261e 100644 --- a/shared/utils/videos/video-channels.ts +++ b/shared/utils/videos/video-channels.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { VideoChannelCreate, VideoChannelUpdate } from '../../models/videos' | 2 | import { VideoChannelCreate, VideoChannelUpdate } from '../../models/videos' |
3 | import { updateAvatarRequest } from '../index' | 3 | import { updateAvatarRequest } from '../requests/requests' |
4 | 4 | ||
5 | function getVideoChannelsList (url: string, start: number, count: number, sort?: string) { | 5 | function getVideoChannelsList (url: string, start: number, count: number, sort?: string) { |
6 | const path = '/api/v1/video-channels' | 6 | const path = '/api/v1/video-channels' |
diff --git a/shared/utils/videos/video-comments.ts b/shared/utils/videos/video-comments.ts index 7d4cae364..0ebf69ced 100644 --- a/shared/utils/videos/video-comments.ts +++ b/shared/utils/videos/video-comments.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { makeDeleteRequest } from '../' | 2 | import { makeDeleteRequest } from '../requests/requests' |
3 | 3 | ||
4 | function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) { | 4 | function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) { |
5 | const path = '/api/v1/videos/' + videoId + '/comment-threads' | 5 | const path = '/api/v1/videos/' + videoId + '/comment-threads' |
diff --git a/shared/utils/videos/video-imports.ts b/shared/utils/videos/video-imports.ts index bf5062cd1..3fa49b432 100644 --- a/shared/utils/videos/video-imports.ts +++ b/shared/utils/videos/video-imports.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | |||
1 | import { VideoImportCreate } from '../../models/videos' | 2 | import { VideoImportCreate } from '../../models/videos' |
2 | import { makeGetRequest, makeUploadRequest } from '..' | 3 | import { makeGetRequest, makeUploadRequest } from '../requests/requests' |
3 | 4 | ||
4 | function getYoutubeVideoUrl () { | 5 | function getYoutubeVideoUrl () { |
5 | return 'https://youtu.be/msX3jv1XdvM' | 6 | return 'https://youtu.be/msX3jv1XdvM' |
diff --git a/shared/utils/videos/videos.ts b/shared/utils/videos/videos.ts index b3206e566..1ab3e7c4b 100644 --- a/shared/utils/videos/videos.ts +++ b/shared/utils/videos/videos.ts | |||
@@ -16,9 +16,10 @@ import { | |||
16 | ServerInfo, | 16 | ServerInfo, |
17 | testImage | 17 | testImage |
18 | } from '../' | 18 | } from '../' |
19 | |||
19 | import { VideoDetails, VideoPrivacy } from '../../models/videos' | 20 | import { VideoDetails, VideoPrivacy } from '../../models/videos' |
20 | import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers' | 21 | import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' |
21 | import { dateIsValid, webtorrentAdd } from '../index' | 22 | import { dateIsValid, webtorrentAdd } from '../miscs/miscs' |
22 | 23 | ||
23 | type VideoAttributes = { | 24 | type VideoAttributes = { |
24 | name?: string | 25 | name?: string |
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml index af829cc62..aa6be7e87 100644 --- a/support/doc/api/openapi.yaml +++ b/support/doc/api/openapi.yaml | |||
@@ -101,14 +101,13 @@ x-tagGroups: | |||
101 | - Video | 101 | - Video |
102 | - Video Channel | 102 | - Video Channel |
103 | - Video Comment | 103 | - Video Comment |
104 | - Video Abuse | ||
105 | - Video Following | 104 | - Video Following |
106 | - Video Rate | 105 | - Video Rate |
107 | - name: Moderation | 106 | - name: Moderation |
108 | tags: | 107 | tags: |
109 | - Video Abuse | 108 | - Video Abuse |
110 | - Video Blacklist | 109 | - Video Blacklist |
111 | - name: Public Instance Information | 110 | - name: Instance Configuration |
112 | tags: | 111 | tags: |
113 | - Config | 112 | - Config |
114 | - Server Following | 113 | - Server Following |
@@ -301,7 +300,7 @@ paths: | |||
301 | responses: | 300 | responses: |
302 | '200': | 301 | '200': |
303 | description: successful operation | 302 | description: successful operation |
304 | /jobs: | 303 | /jobs/{state}: |
305 | get: | 304 | get: |
306 | summary: Get list of jobs | 305 | summary: Get list of jobs |
307 | security: | 306 | security: |
@@ -316,6 +315,12 @@ paths: | |||
316 | description: The state of the job | 315 | description: The state of the job |
317 | schema: | 316 | schema: |
318 | type: string | 317 | type: string |
318 | enum: | ||
319 | - active | ||
320 | - completed | ||
321 | - failed | ||
322 | - waiting | ||
323 | - delayed | ||
319 | - $ref: '#/components/parameters/start' | 324 | - $ref: '#/components/parameters/start' |
320 | - $ref: '#/components/parameters/count' | 325 | - $ref: '#/components/parameters/count' |
321 | - $ref: '#/components/parameters/sort' | 326 | - $ref: '#/components/parameters/sort' |
diff --git a/support/doc/api/quickstart.md b/support/doc/api/quickstart.md index 844248a7f..6c19b59ee 100644 --- a/support/doc/api/quickstart.md +++ b/support/doc/api/quickstart.md | |||
@@ -43,7 +43,7 @@ Response example: | |||
43 | Just use the `access_token` in the `Authorization` header: | 43 | Just use the `access_token` in the `Authorization` header: |
44 | 44 | ||
45 | ``` | 45 | ``` |
46 | $ curl -H 'Authorization: Bearer 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0' https://peertube.example.com/api/v1/jobs/complete | 46 | $ curl -H 'Authorization: Bearer 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0' https://peertube.example.com/api/v1/jobs/completed |
47 | ``` | 47 | ``` |
48 | 48 | ||
49 | 49 | ||
@@ -51,4 +51,4 @@ $ curl -H 'Authorization: Bearer 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0' https | |||
51 | 51 | ||
52 | ``` | 52 | ``` |
53 | $ curl https://peertube.example.com/api/v1/videos | 53 | $ curl https://peertube.example.com/api/v1/videos |
54 | ``` \ No newline at end of file | 54 | ``` |