diff options
Diffstat (limited to 'server/tests/api')
-rw-r--r-- | server/tests/api/check-params/index.ts | 5 | ||||
-rw-r--r-- | server/tests/api/check-params/two-factor.ts | 288 | ||||
-rw-r--r-- | server/tests/api/live/live-fast-restream.ts | 2 | ||||
-rw-r--r-- | server/tests/api/live/live.ts | 91 | ||||
-rw-r--r-- | server/tests/api/notifications/admin-notifications.ts | 6 | ||||
-rw-r--r-- | server/tests/api/notifications/moderation-notifications.ts | 2 | ||||
-rw-r--r-- | server/tests/api/object-storage/live.ts | 183 | ||||
-rw-r--r-- | server/tests/api/redundancy/redundancy.ts | 14 | ||||
-rw-r--r-- | server/tests/api/users/index.ts | 1 | ||||
-rw-r--r-- | server/tests/api/users/two-factor.ts | 200 | ||||
-rw-r--r-- | server/tests/api/users/users-multiple-servers.ts | 2 | ||||
-rw-r--r-- | server/tests/api/videos/multiple-servers.ts | 2 | ||||
-rw-r--r-- | server/tests/api/videos/video-files.ts | 2 | ||||
-rw-r--r-- | server/tests/api/videos/video-playlists.ts | 4 | ||||
-rw-r--r-- | server/tests/api/videos/video-privacy.ts | 2 | ||||
-rw-r--r-- | server/tests/api/videos/videos-common-filters.ts | 2 |
16 files changed, 680 insertions, 126 deletions
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts index cd7a38459..33dc8fb76 100644 --- a/server/tests/api/check-params/index.ts +++ b/server/tests/api/check-params/index.ts | |||
@@ -2,6 +2,7 @@ import './abuses' | |||
2 | import './accounts' | 2 | import './accounts' |
3 | import './blocklist' | 3 | import './blocklist' |
4 | import './bulk' | 4 | import './bulk' |
5 | import './channel-import-videos' | ||
5 | import './config' | 6 | import './config' |
6 | import './contact-form' | 7 | import './contact-form' |
7 | import './custom-pages' | 8 | import './custom-pages' |
@@ -17,6 +18,7 @@ import './redundancy' | |||
17 | import './search' | 18 | import './search' |
18 | import './services' | 19 | import './services' |
19 | import './transcoding' | 20 | import './transcoding' |
21 | import './two-factor' | ||
20 | import './upload-quota' | 22 | import './upload-quota' |
21 | import './user-notifications' | 23 | import './user-notifications' |
22 | import './user-subscriptions' | 24 | import './user-subscriptions' |
@@ -24,12 +26,11 @@ import './users-admin' | |||
24 | import './users' | 26 | import './users' |
25 | import './video-blacklist' | 27 | import './video-blacklist' |
26 | import './video-captions' | 28 | import './video-captions' |
29 | import './video-channel-syncs' | ||
27 | import './video-channels' | 30 | import './video-channels' |
28 | import './video-comments' | 31 | import './video-comments' |
29 | import './video-files' | 32 | import './video-files' |
30 | import './video-imports' | 33 | import './video-imports' |
31 | import './video-channel-syncs' | ||
32 | import './channel-import-videos' | ||
33 | import './video-playlists' | 34 | import './video-playlists' |
34 | import './video-source' | 35 | import './video-source' |
35 | import './video-studio' | 36 | import './video-studio' |
diff --git a/server/tests/api/check-params/two-factor.ts b/server/tests/api/check-params/two-factor.ts new file mode 100644 index 000000000..f8365f1b5 --- /dev/null +++ b/server/tests/api/check-params/two-factor.ts | |||
@@ -0,0 +1,288 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { HttpStatusCode } from '@shared/models' | ||
4 | import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers, TwoFactorCommand } from '@shared/server-commands' | ||
5 | |||
6 | describe('Test two factor API validators', function () { | ||
7 | let server: PeerTubeServer | ||
8 | |||
9 | let rootId: number | ||
10 | let rootPassword: string | ||
11 | let rootRequestToken: string | ||
12 | let rootOTPToken: string | ||
13 | |||
14 | let userId: number | ||
15 | let userToken = '' | ||
16 | let userPassword: string | ||
17 | let userRequestToken: string | ||
18 | let userOTPToken: string | ||
19 | |||
20 | // --------------------------------------------------------------- | ||
21 | |||
22 | before(async function () { | ||
23 | this.timeout(30000) | ||
24 | |||
25 | { | ||
26 | server = await createSingleServer(1) | ||
27 | await setAccessTokensToServers([ server ]) | ||
28 | } | ||
29 | |||
30 | { | ||
31 | const result = await server.users.generate('user1') | ||
32 | userToken = result.token | ||
33 | userId = result.userId | ||
34 | userPassword = result.password | ||
35 | } | ||
36 | |||
37 | { | ||
38 | const { id } = await server.users.getMyInfo() | ||
39 | rootId = id | ||
40 | rootPassword = server.store.user.password | ||
41 | } | ||
42 | }) | ||
43 | |||
44 | describe('When requesting two factor', function () { | ||
45 | |||
46 | it('Should fail with an unknown user id', async function () { | ||
47 | await server.twoFactor.request({ userId: 42, currentPassword: rootPassword, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
48 | }) | ||
49 | |||
50 | it('Should fail with an invalid user id', async function () { | ||
51 | await server.twoFactor.request({ | ||
52 | userId: 'invalid' as any, | ||
53 | currentPassword: rootPassword, | ||
54 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
55 | }) | ||
56 | }) | ||
57 | |||
58 | it('Should fail to request another user two factor without the appropriate rights', async function () { | ||
59 | await server.twoFactor.request({ | ||
60 | userId: rootId, | ||
61 | token: userToken, | ||
62 | currentPassword: userPassword, | ||
63 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
64 | }) | ||
65 | }) | ||
66 | |||
67 | it('Should succeed to request another user two factor with the appropriate rights', async function () { | ||
68 | await server.twoFactor.request({ userId, currentPassword: rootPassword }) | ||
69 | }) | ||
70 | |||
71 | it('Should fail to request two factor without a password', async function () { | ||
72 | await server.twoFactor.request({ | ||
73 | userId, | ||
74 | token: userToken, | ||
75 | currentPassword: undefined, | ||
76 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
77 | }) | ||
78 | }) | ||
79 | |||
80 | it('Should fail to request two factor with an incorrect password', async function () { | ||
81 | await server.twoFactor.request({ | ||
82 | userId, | ||
83 | token: userToken, | ||
84 | currentPassword: rootPassword, | ||
85 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
86 | }) | ||
87 | }) | ||
88 | |||
89 | it('Should succeed to request two factor without a password when targeting a remote user with an admin account', async function () { | ||
90 | await server.twoFactor.request({ userId }) | ||
91 | }) | ||
92 | |||
93 | it('Should fail to request two factor without a password when targeting myself with an admin account', async function () { | ||
94 | await server.twoFactor.request({ userId: rootId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
95 | await server.twoFactor.request({ userId: rootId, currentPassword: 'bad', expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
96 | }) | ||
97 | |||
98 | it('Should succeed to request my two factor auth', async function () { | ||
99 | { | ||
100 | const { otpRequest } = await server.twoFactor.request({ userId, token: userToken, currentPassword: userPassword }) | ||
101 | userRequestToken = otpRequest.requestToken | ||
102 | userOTPToken = TwoFactorCommand.buildOTP({ secret: otpRequest.secret }).generate() | ||
103 | } | ||
104 | |||
105 | { | ||
106 | const { otpRequest } = await server.twoFactor.request({ userId: rootId, currentPassword: rootPassword }) | ||
107 | rootRequestToken = otpRequest.requestToken | ||
108 | rootOTPToken = TwoFactorCommand.buildOTP({ secret: otpRequest.secret }).generate() | ||
109 | } | ||
110 | }) | ||
111 | }) | ||
112 | |||
113 | describe('When confirming two factor request', function () { | ||
114 | |||
115 | it('Should fail with an unknown user id', async function () { | ||
116 | await server.twoFactor.confirmRequest({ | ||
117 | userId: 42, | ||
118 | requestToken: rootRequestToken, | ||
119 | otpToken: rootOTPToken, | ||
120 | expectedStatus: HttpStatusCode.NOT_FOUND_404 | ||
121 | }) | ||
122 | }) | ||
123 | |||
124 | it('Should fail with an invalid user id', async function () { | ||
125 | await server.twoFactor.confirmRequest({ | ||
126 | userId: 'invalid' as any, | ||
127 | requestToken: rootRequestToken, | ||
128 | otpToken: rootOTPToken, | ||
129 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
130 | }) | ||
131 | }) | ||
132 | |||
133 | it('Should fail to confirm another user two factor request without the appropriate rights', async function () { | ||
134 | await server.twoFactor.confirmRequest({ | ||
135 | userId: rootId, | ||
136 | token: userToken, | ||
137 | requestToken: rootRequestToken, | ||
138 | otpToken: rootOTPToken, | ||
139 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
140 | }) | ||
141 | }) | ||
142 | |||
143 | it('Should fail without request token', async function () { | ||
144 | await server.twoFactor.confirmRequest({ | ||
145 | userId, | ||
146 | requestToken: undefined, | ||
147 | otpToken: userOTPToken, | ||
148 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
149 | }) | ||
150 | }) | ||
151 | |||
152 | it('Should fail with an invalid request token', async function () { | ||
153 | await server.twoFactor.confirmRequest({ | ||
154 | userId, | ||
155 | requestToken: 'toto', | ||
156 | otpToken: userOTPToken, | ||
157 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
158 | }) | ||
159 | }) | ||
160 | |||
161 | it('Should fail with request token of another user', async function () { | ||
162 | await server.twoFactor.confirmRequest({ | ||
163 | userId, | ||
164 | requestToken: rootRequestToken, | ||
165 | otpToken: userOTPToken, | ||
166 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
167 | }) | ||
168 | }) | ||
169 | |||
170 | it('Should fail without an otp token', async function () { | ||
171 | await server.twoFactor.confirmRequest({ | ||
172 | userId, | ||
173 | requestToken: userRequestToken, | ||
174 | otpToken: undefined, | ||
175 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
176 | }) | ||
177 | }) | ||
178 | |||
179 | it('Should fail with a bad otp token', async function () { | ||
180 | await server.twoFactor.confirmRequest({ | ||
181 | userId, | ||
182 | requestToken: userRequestToken, | ||
183 | otpToken: '123456', | ||
184 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
185 | }) | ||
186 | }) | ||
187 | |||
188 | it('Should succeed to confirm another user two factor request with the appropriate rights', async function () { | ||
189 | await server.twoFactor.confirmRequest({ | ||
190 | userId, | ||
191 | requestToken: userRequestToken, | ||
192 | otpToken: userOTPToken | ||
193 | }) | ||
194 | |||
195 | // Reinit | ||
196 | await server.twoFactor.disable({ userId, currentPassword: rootPassword }) | ||
197 | }) | ||
198 | |||
199 | it('Should succeed to confirm my two factor request', async function () { | ||
200 | await server.twoFactor.confirmRequest({ | ||
201 | userId, | ||
202 | token: userToken, | ||
203 | requestToken: userRequestToken, | ||
204 | otpToken: userOTPToken | ||
205 | }) | ||
206 | }) | ||
207 | |||
208 | it('Should fail to confirm again two factor request', async function () { | ||
209 | await server.twoFactor.confirmRequest({ | ||
210 | userId, | ||
211 | token: userToken, | ||
212 | requestToken: userRequestToken, | ||
213 | otpToken: userOTPToken, | ||
214 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
215 | }) | ||
216 | }) | ||
217 | }) | ||
218 | |||
219 | describe('When disabling two factor', function () { | ||
220 | |||
221 | it('Should fail with an unknown user id', async function () { | ||
222 | await server.twoFactor.disable({ | ||
223 | userId: 42, | ||
224 | currentPassword: rootPassword, | ||
225 | expectedStatus: HttpStatusCode.NOT_FOUND_404 | ||
226 | }) | ||
227 | }) | ||
228 | |||
229 | it('Should fail with an invalid user id', async function () { | ||
230 | await server.twoFactor.disable({ | ||
231 | userId: 'invalid' as any, | ||
232 | currentPassword: rootPassword, | ||
233 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
234 | }) | ||
235 | }) | ||
236 | |||
237 | it('Should fail to disable another user two factor without the appropriate rights', async function () { | ||
238 | await server.twoFactor.disable({ | ||
239 | userId: rootId, | ||
240 | token: userToken, | ||
241 | currentPassword: userPassword, | ||
242 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
243 | }) | ||
244 | }) | ||
245 | |||
246 | it('Should fail to disable two factor with an incorrect password', async function () { | ||
247 | await server.twoFactor.disable({ | ||
248 | userId, | ||
249 | token: userToken, | ||
250 | currentPassword: rootPassword, | ||
251 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
252 | }) | ||
253 | }) | ||
254 | |||
255 | it('Should succeed to disable two factor without a password when targeting a remote user with an admin account', async function () { | ||
256 | await server.twoFactor.disable({ userId }) | ||
257 | await server.twoFactor.requestAndConfirm({ userId }) | ||
258 | }) | ||
259 | |||
260 | it('Should fail to disable two factor without a password when targeting myself with an admin account', async function () { | ||
261 | await server.twoFactor.disable({ userId: rootId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
262 | await server.twoFactor.disable({ userId: rootId, currentPassword: 'bad', expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
263 | }) | ||
264 | |||
265 | it('Should succeed to disable another user two factor with the appropriate rights', async function () { | ||
266 | await server.twoFactor.disable({ userId, currentPassword: rootPassword }) | ||
267 | |||
268 | await server.twoFactor.requestAndConfirm({ userId }) | ||
269 | }) | ||
270 | |||
271 | it('Should succeed to update my two factor auth', async function () { | ||
272 | await server.twoFactor.disable({ userId, token: userToken, currentPassword: userPassword }) | ||
273 | }) | ||
274 | |||
275 | it('Should fail to disable again two factor', async function () { | ||
276 | await server.twoFactor.disable({ | ||
277 | userId, | ||
278 | token: userToken, | ||
279 | currentPassword: userPassword, | ||
280 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
281 | }) | ||
282 | }) | ||
283 | }) | ||
284 | |||
285 | after(async function () { | ||
286 | await cleanupTests([ server ]) | ||
287 | }) | ||
288 | }) | ||
diff --git a/server/tests/api/live/live-fast-restream.ts b/server/tests/api/live/live-fast-restream.ts index 502959258..3ea6be9ff 100644 --- a/server/tests/api/live/live-fast-restream.ts +++ b/server/tests/api/live/live-fast-restream.ts | |||
@@ -59,7 +59,7 @@ describe('Fast restream in live', function () { | |||
59 | const video = await server.videos.get({ id: liveId }) | 59 | const video = await server.videos.get({ id: liveId }) |
60 | expect(video.streamingPlaylists).to.have.lengthOf(1) | 60 | expect(video.streamingPlaylists).to.have.lengthOf(1) |
61 | 61 | ||
62 | await server.live.getSegment({ videoUUID: liveId, segment: 0, playlistNumber: 0 }) | 62 | await server.live.getSegmentFile({ videoUUID: liveId, segment: 0, playlistNumber: 0 }) |
63 | await makeRawRequest(video.streamingPlaylists[0].playlistUrl, HttpStatusCode.OK_200) | 63 | await makeRawRequest(video.streamingPlaylists[0].playlistUrl, HttpStatusCode.OK_200) |
64 | await makeRawRequest(video.streamingPlaylists[0].segmentsSha256Url, HttpStatusCode.OK_200) | 64 | await makeRawRequest(video.streamingPlaylists[0].segmentsSha256Url, HttpStatusCode.OK_200) |
65 | 65 | ||
diff --git a/server/tests/api/live/live.ts b/server/tests/api/live/live.ts index c436f0f01..5dd2bd9ab 100644 --- a/server/tests/api/live/live.ts +++ b/server/tests/api/live/live.ts | |||
@@ -3,7 +3,7 @@ | |||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { basename, join } from 'path' | 4 | import { basename, join } from 'path' |
5 | import { ffprobePromise, getVideoStream } from '@server/helpers/ffmpeg' | 5 | import { ffprobePromise, getVideoStream } from '@server/helpers/ffmpeg' |
6 | import { checkLiveSegmentHash, checkResolutionsInMasterPlaylist, testImage } from '@server/tests/shared' | 6 | import { testImage, testVideoResolutions } from '@server/tests/shared' |
7 | import { getAllFiles, wait } from '@shared/core-utils' | 7 | import { getAllFiles, wait } from '@shared/core-utils' |
8 | import { | 8 | import { |
9 | HttpStatusCode, | 9 | HttpStatusCode, |
@@ -372,46 +372,6 @@ describe('Test live', function () { | |||
372 | return uuid | 372 | return uuid |
373 | } | 373 | } |
374 | 374 | ||
375 | async function testVideoResolutions (liveVideoId: string, resolutions: number[]) { | ||
376 | for (const server of servers) { | ||
377 | const { data } = await server.videos.list() | ||
378 | expect(data.find(v => v.uuid === liveVideoId)).to.exist | ||
379 | |||
380 | const video = await server.videos.get({ id: liveVideoId }) | ||
381 | |||
382 | expect(video.streamingPlaylists).to.have.lengthOf(1) | ||
383 | |||
384 | const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS) | ||
385 | expect(hlsPlaylist).to.exist | ||
386 | |||
387 | // Only finite files are displayed | ||
388 | expect(hlsPlaylist.files).to.have.lengthOf(0) | ||
389 | |||
390 | await checkResolutionsInMasterPlaylist({ server, playlistUrl: hlsPlaylist.playlistUrl, resolutions }) | ||
391 | |||
392 | for (let i = 0; i < resolutions.length; i++) { | ||
393 | const segmentNum = 3 | ||
394 | const segmentName = `${i}-00000${segmentNum}.ts` | ||
395 | await commands[0].waitUntilSegmentGeneration({ videoUUID: video.uuid, playlistNumber: i, segment: segmentNum }) | ||
396 | |||
397 | const subPlaylist = await servers[0].streamingPlaylists.get({ | ||
398 | url: `${servers[0].url}/static/streaming-playlists/hls/${video.uuid}/${i}.m3u8` | ||
399 | }) | ||
400 | |||
401 | expect(subPlaylist).to.contain(segmentName) | ||
402 | |||
403 | const baseUrlAndPath = servers[0].url + '/static/streaming-playlists/hls' | ||
404 | await checkLiveSegmentHash({ | ||
405 | server, | ||
406 | baseUrlSegment: baseUrlAndPath, | ||
407 | videoUUID: video.uuid, | ||
408 | segmentName, | ||
409 | hlsPlaylist | ||
410 | }) | ||
411 | } | ||
412 | } | ||
413 | } | ||
414 | |||
415 | function updateConf (resolutions: number[]) { | 375 | function updateConf (resolutions: number[]) { |
416 | return servers[0].config.updateCustomSubConfig({ | 376 | return servers[0].config.updateCustomSubConfig({ |
417 | newConfig: { | 377 | newConfig: { |
@@ -449,7 +409,14 @@ describe('Test live', function () { | |||
449 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) | 409 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) |
450 | await waitJobs(servers) | 410 | await waitJobs(servers) |
451 | 411 | ||
452 | await testVideoResolutions(liveVideoId, [ 720 ]) | 412 | await testVideoResolutions({ |
413 | originServer: servers[0], | ||
414 | servers, | ||
415 | liveVideoId, | ||
416 | resolutions: [ 720 ], | ||
417 | objectStorage: false, | ||
418 | transcoded: true | ||
419 | }) | ||
453 | 420 | ||
454 | await stopFfmpeg(ffmpegCommand) | 421 | await stopFfmpeg(ffmpegCommand) |
455 | }) | 422 | }) |
@@ -477,7 +444,14 @@ describe('Test live', function () { | |||
477 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) | 444 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) |
478 | await waitJobs(servers) | 445 | await waitJobs(servers) |
479 | 446 | ||
480 | await testVideoResolutions(liveVideoId, resolutions.concat([ 720 ])) | 447 | await testVideoResolutions({ |
448 | originServer: servers[0], | ||
449 | servers, | ||
450 | liveVideoId, | ||
451 | resolutions: resolutions.concat([ 720 ]), | ||
452 | objectStorage: false, | ||
453 | transcoded: true | ||
454 | }) | ||
481 | 455 | ||
482 | await stopFfmpeg(ffmpegCommand) | 456 | await stopFfmpeg(ffmpegCommand) |
483 | }) | 457 | }) |
@@ -522,7 +496,14 @@ describe('Test live', function () { | |||
522 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) | 496 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) |
523 | await waitJobs(servers) | 497 | await waitJobs(servers) |
524 | 498 | ||
525 | await testVideoResolutions(liveVideoId, resolutions) | 499 | await testVideoResolutions({ |
500 | originServer: servers[0], | ||
501 | servers, | ||
502 | liveVideoId, | ||
503 | resolutions, | ||
504 | objectStorage: false, | ||
505 | transcoded: true | ||
506 | }) | ||
526 | 507 | ||
527 | await stopFfmpeg(ffmpegCommand) | 508 | await stopFfmpeg(ffmpegCommand) |
528 | await commands[0].waitUntilEnded({ videoId: liveVideoId }) | 509 | await commands[0].waitUntilEnded({ videoId: liveVideoId }) |
@@ -538,7 +519,7 @@ describe('Test live', function () { | |||
538 | } | 519 | } |
539 | 520 | ||
540 | const minBitrateLimits = { | 521 | const minBitrateLimits = { |
541 | 720: 5500 * 1000, | 522 | 720: 5000 * 1000, |
542 | 360: 1000 * 1000, | 523 | 360: 1000 * 1000, |
543 | 240: 550 * 1000 | 524 | 240: 550 * 1000 |
544 | } | 525 | } |
@@ -569,7 +550,7 @@ describe('Test live', function () { | |||
569 | if (resolution >= 720) { | 550 | if (resolution >= 720) { |
570 | expect(file.fps).to.be.approximately(60, 10) | 551 | expect(file.fps).to.be.approximately(60, 10) |
571 | } else { | 552 | } else { |
572 | expect(file.fps).to.be.approximately(30, 2) | 553 | expect(file.fps).to.be.approximately(30, 3) |
573 | } | 554 | } |
574 | 555 | ||
575 | const filename = basename(file.fileUrl) | 556 | const filename = basename(file.fileUrl) |
@@ -611,7 +592,14 @@ describe('Test live', function () { | |||
611 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) | 592 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) |
612 | await waitJobs(servers) | 593 | await waitJobs(servers) |
613 | 594 | ||
614 | await testVideoResolutions(liveVideoId, resolutions) | 595 | await testVideoResolutions({ |
596 | originServer: servers[0], | ||
597 | servers, | ||
598 | liveVideoId, | ||
599 | resolutions, | ||
600 | objectStorage: false, | ||
601 | transcoded: true | ||
602 | }) | ||
615 | 603 | ||
616 | await stopFfmpeg(ffmpegCommand) | 604 | await stopFfmpeg(ffmpegCommand) |
617 | await commands[0].waitUntilEnded({ videoId: liveVideoId }) | 605 | await commands[0].waitUntilEnded({ videoId: liveVideoId }) |
@@ -640,7 +628,14 @@ describe('Test live', function () { | |||
640 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) | 628 | await waitUntilLivePublishedOnAllServers(servers, liveVideoId) |
641 | await waitJobs(servers) | 629 | await waitJobs(servers) |
642 | 630 | ||
643 | await testVideoResolutions(liveVideoId, [ 720 ]) | 631 | await testVideoResolutions({ |
632 | originServer: servers[0], | ||
633 | servers, | ||
634 | liveVideoId, | ||
635 | resolutions: [ 720 ], | ||
636 | objectStorage: false, | ||
637 | transcoded: true | ||
638 | }) | ||
644 | 639 | ||
645 | await stopFfmpeg(ffmpegCommand) | 640 | await stopFfmpeg(ffmpegCommand) |
646 | await commands[0].waitUntilEnded({ videoId: liveVideoId }) | 641 | await commands[0].waitUntilEnded({ videoId: liveVideoId }) |
diff --git a/server/tests/api/notifications/admin-notifications.ts b/server/tests/api/notifications/admin-notifications.ts index b3bb4888e..07c981a37 100644 --- a/server/tests/api/notifications/admin-notifications.ts +++ b/server/tests/api/notifications/admin-notifications.ts | |||
@@ -37,7 +37,7 @@ describe('Test admin notifications', function () { | |||
37 | plugins: { | 37 | plugins: { |
38 | index: { | 38 | index: { |
39 | enabled: true, | 39 | enabled: true, |
40 | check_latest_versions_interval: '5 seconds' | 40 | check_latest_versions_interval: '3 seconds' |
41 | } | 41 | } |
42 | } | 42 | } |
43 | } | 43 | } |
@@ -62,7 +62,7 @@ describe('Test admin notifications', function () { | |||
62 | 62 | ||
63 | describe('Latest PeerTube version notification', function () { | 63 | describe('Latest PeerTube version notification', function () { |
64 | 64 | ||
65 | it('Should not send a notification to admins if there is not a new version', async function () { | 65 | it('Should not send a notification to admins if there is no new version', async function () { |
66 | this.timeout(30000) | 66 | this.timeout(30000) |
67 | 67 | ||
68 | joinPeerTubeServer.setLatestVersion('1.4.2') | 68 | joinPeerTubeServer.setLatestVersion('1.4.2') |
@@ -71,7 +71,7 @@ describe('Test admin notifications', function () { | |||
71 | await checkNewPeerTubeVersion({ ...baseParams, latestVersion: '1.4.2', checkType: 'absence' }) | 71 | await checkNewPeerTubeVersion({ ...baseParams, latestVersion: '1.4.2', checkType: 'absence' }) |
72 | }) | 72 | }) |
73 | 73 | ||
74 | it('Should send a notification to admins on new plugin version', async function () { | 74 | it('Should send a notification to admins on new version', async function () { |
75 | this.timeout(30000) | 75 | this.timeout(30000) |
76 | 76 | ||
77 | joinPeerTubeServer.setLatestVersion('15.4.2') | 77 | joinPeerTubeServer.setLatestVersion('15.4.2') |
diff --git a/server/tests/api/notifications/moderation-notifications.ts b/server/tests/api/notifications/moderation-notifications.ts index d8a7d576e..fc953f144 100644 --- a/server/tests/api/notifications/moderation-notifications.ts +++ b/server/tests/api/notifications/moderation-notifications.ts | |||
@@ -382,7 +382,7 @@ describe('Test moderation notifications', function () { | |||
382 | }) | 382 | }) |
383 | 383 | ||
384 | it('Should send a notification only to admin when there is a new instance follower', async function () { | 384 | it('Should send a notification only to admin when there is a new instance follower', async function () { |
385 | this.timeout(20000) | 385 | this.timeout(60000) |
386 | 386 | ||
387 | await servers[2].follows.follow({ hosts: [ servers[0].url ] }) | 387 | await servers[2].follows.follow({ hosts: [ servers[0].url ] }) |
388 | 388 | ||
diff --git a/server/tests/api/object-storage/live.ts b/server/tests/api/object-storage/live.ts index 0958ffe0f..7e16b4c89 100644 --- a/server/tests/api/object-storage/live.ts +++ b/server/tests/api/object-storage/live.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { expectStartWith } from '@server/tests/shared' | 4 | import { expectStartWith, testVideoResolutions } from '@server/tests/shared' |
5 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 5 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' |
6 | import { HttpStatusCode, LiveVideoCreate, VideoFile, VideoPrivacy } from '@shared/models' | 6 | import { HttpStatusCode, LiveVideoCreate, VideoPrivacy } from '@shared/models' |
7 | import { | 7 | import { |
8 | createMultipleServers, | 8 | createMultipleServers, |
9 | doubleFollow, | 9 | doubleFollow, |
@@ -35,41 +35,43 @@ async function createLive (server: PeerTubeServer, permanent: boolean) { | |||
35 | return uuid | 35 | return uuid |
36 | } | 36 | } |
37 | 37 | ||
38 | async function checkFiles (files: VideoFile[]) { | 38 | async function checkFilesExist (servers: PeerTubeServer[], videoUUID: string, numberOfFiles: number) { |
39 | for (const file of files) { | 39 | for (const server of servers) { |
40 | expectStartWith(file.fileUrl, ObjectStorageCommand.getPlaylistBaseUrl()) | 40 | const video = await server.videos.get({ id: videoUUID }) |
41 | 41 | ||
42 | await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200) | 42 | expect(video.files).to.have.lengthOf(0) |
43 | } | 43 | expect(video.streamingPlaylists).to.have.lengthOf(1) |
44 | } | ||
45 | 44 | ||
46 | async function getFiles (server: PeerTubeServer, videoUUID: string) { | 45 | const files = video.streamingPlaylists[0].files |
47 | const video = await server.videos.get({ id: videoUUID }) | 46 | expect(files).to.have.lengthOf(numberOfFiles) |
48 | 47 | ||
49 | expect(video.files).to.have.lengthOf(0) | 48 | for (const file of files) { |
50 | expect(video.streamingPlaylists).to.have.lengthOf(1) | 49 | expectStartWith(file.fileUrl, ObjectStorageCommand.getPlaylistBaseUrl()) |
51 | 50 | ||
52 | return video.streamingPlaylists[0].files | 51 | await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200) |
52 | } | ||
53 | } | ||
53 | } | 54 | } |
54 | 55 | ||
55 | async function streamAndEnd (servers: PeerTubeServer[], liveUUID: string) { | 56 | async function checkFilesCleanup (server: PeerTubeServer, videoUUID: string, resolutions: number[]) { |
56 | const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveUUID }) | 57 | const resolutionFiles = resolutions.map((_value, i) => `${i}.m3u8`) |
57 | await waitUntilLivePublishedOnAllServers(servers, liveUUID) | ||
58 | |||
59 | const videoLiveDetails = await servers[0].videos.get({ id: liveUUID }) | ||
60 | const liveDetails = await servers[0].live.get({ videoId: liveUUID }) | ||
61 | 58 | ||
62 | await stopFfmpeg(ffmpegCommand) | 59 | for (const playlistName of [ 'master.m3u8' ].concat(resolutionFiles)) { |
63 | 60 | await server.live.getPlaylistFile({ | |
64 | if (liveDetails.permanentLive) { | 61 | videoUUID, |
65 | await waitUntilLiveWaitingOnAllServers(servers, liveUUID) | 62 | playlistName, |
66 | } else { | 63 | expectedStatus: HttpStatusCode.NOT_FOUND_404, |
67 | await waitUntilLiveReplacedByReplayOnAllServers(servers, liveUUID) | 64 | objectStorage: true |
65 | }) | ||
68 | } | 66 | } |
69 | 67 | ||
70 | await waitJobs(servers) | 68 | await server.live.getSegmentFile({ |
71 | 69 | videoUUID, | |
72 | return { videoLiveDetails, liveDetails } | 70 | playlistNumber: 0, |
71 | segment: 0, | ||
72 | objectStorage: true, | ||
73 | expectedStatus: HttpStatusCode.NOT_FOUND_404 | ||
74 | }) | ||
73 | } | 75 | } |
74 | 76 | ||
75 | describe('Object storage for lives', function () { | 77 | describe('Object storage for lives', function () { |
@@ -100,57 +102,124 @@ describe('Object storage for lives', function () { | |||
100 | videoUUID = await createLive(servers[0], false) | 102 | videoUUID = await createLive(servers[0], false) |
101 | }) | 103 | }) |
102 | 104 | ||
103 | it('Should create a live and save the replay on object storage', async function () { | 105 | it('Should create a live and publish it on object storage', async function () { |
106 | this.timeout(220000) | ||
107 | |||
108 | const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: videoUUID }) | ||
109 | await waitUntilLivePublishedOnAllServers(servers, videoUUID) | ||
110 | |||
111 | await testVideoResolutions({ | ||
112 | originServer: servers[0], | ||
113 | servers, | ||
114 | liveVideoId: videoUUID, | ||
115 | resolutions: [ 720 ], | ||
116 | transcoded: false, | ||
117 | objectStorage: true | ||
118 | }) | ||
119 | |||
120 | await stopFfmpeg(ffmpegCommand) | ||
121 | }) | ||
122 | |||
123 | it('Should have saved the replay on object storage', async function () { | ||
104 | this.timeout(220000) | 124 | this.timeout(220000) |
105 | 125 | ||
106 | await streamAndEnd(servers, videoUUID) | 126 | await waitUntilLiveReplacedByReplayOnAllServers(servers, videoUUID) |
127 | await waitJobs(servers) | ||
107 | 128 | ||
108 | for (const server of servers) { | 129 | await checkFilesExist(servers, videoUUID, 1) |
109 | const files = await getFiles(server, videoUUID) | 130 | }) |
110 | expect(files).to.have.lengthOf(1) | ||
111 | 131 | ||
112 | await checkFiles(files) | 132 | it('Should have cleaned up live files from object storage', async function () { |
113 | } | 133 | await checkFilesCleanup(servers[0], videoUUID, [ 720 ]) |
114 | }) | 134 | }) |
115 | }) | 135 | }) |
116 | 136 | ||
117 | describe('With live transcoding', async function () { | 137 | describe('With live transcoding', async function () { |
118 | let videoUUIDPermanent: string | 138 | const resolutions = [ 720, 480, 360, 240, 144 ] |
119 | let videoUUIDNonPermanent: string | ||
120 | 139 | ||
121 | before(async function () { | 140 | before(async function () { |
122 | await servers[0].config.enableLive({ transcoding: true }) | 141 | await servers[0].config.enableLive({ transcoding: true }) |
123 | |||
124 | videoUUIDPermanent = await createLive(servers[0], true) | ||
125 | videoUUIDNonPermanent = await createLive(servers[0], false) | ||
126 | }) | 142 | }) |
127 | 143 | ||
128 | it('Should create a live and save the replay on object storage', async function () { | 144 | describe('Normal replay', function () { |
129 | this.timeout(240000) | 145 | let videoUUIDNonPermanent: string |
146 | |||
147 | before(async function () { | ||
148 | videoUUIDNonPermanent = await createLive(servers[0], false) | ||
149 | }) | ||
150 | |||
151 | it('Should create a live and publish it on object storage', async function () { | ||
152 | this.timeout(240000) | ||
153 | |||
154 | const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: videoUUIDNonPermanent }) | ||
155 | await waitUntilLivePublishedOnAllServers(servers, videoUUIDNonPermanent) | ||
156 | |||
157 | await testVideoResolutions({ | ||
158 | originServer: servers[0], | ||
159 | servers, | ||
160 | liveVideoId: videoUUIDNonPermanent, | ||
161 | resolutions, | ||
162 | transcoded: true, | ||
163 | objectStorage: true | ||
164 | }) | ||
165 | |||
166 | await stopFfmpeg(ffmpegCommand) | ||
167 | }) | ||
130 | 168 | ||
131 | await streamAndEnd(servers, videoUUIDNonPermanent) | 169 | it('Should have saved the replay on object storage', async function () { |
170 | this.timeout(220000) | ||
132 | 171 | ||
133 | for (const server of servers) { | 172 | await waitUntilLiveReplacedByReplayOnAllServers(servers, videoUUIDNonPermanent) |
134 | const files = await getFiles(server, videoUUIDNonPermanent) | 173 | await waitJobs(servers) |
135 | expect(files).to.have.lengthOf(5) | ||
136 | 174 | ||
137 | await checkFiles(files) | 175 | await checkFilesExist(servers, videoUUIDNonPermanent, 5) |
138 | } | 176 | }) |
177 | |||
178 | it('Should have cleaned up live files from object storage', async function () { | ||
179 | await checkFilesCleanup(servers[0], videoUUIDNonPermanent, resolutions) | ||
180 | }) | ||
139 | }) | 181 | }) |
140 | 182 | ||
141 | it('Should create a live and save the replay of permanent live on object storage', async function () { | 183 | describe('Permanent replay', function () { |
142 | this.timeout(240000) | 184 | let videoUUIDPermanent: string |
185 | |||
186 | before(async function () { | ||
187 | videoUUIDPermanent = await createLive(servers[0], true) | ||
188 | }) | ||
189 | |||
190 | it('Should create a live and publish it on object storage', async function () { | ||
191 | this.timeout(240000) | ||
192 | |||
193 | const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: videoUUIDPermanent }) | ||
194 | await waitUntilLivePublishedOnAllServers(servers, videoUUIDPermanent) | ||
195 | |||
196 | await testVideoResolutions({ | ||
197 | originServer: servers[0], | ||
198 | servers, | ||
199 | liveVideoId: videoUUIDPermanent, | ||
200 | resolutions, | ||
201 | transcoded: true, | ||
202 | objectStorage: true | ||
203 | }) | ||
204 | |||
205 | await stopFfmpeg(ffmpegCommand) | ||
206 | }) | ||
207 | |||
208 | it('Should have saved the replay on object storage', async function () { | ||
209 | this.timeout(220000) | ||
143 | 210 | ||
144 | const { videoLiveDetails } = await streamAndEnd(servers, videoUUIDPermanent) | 211 | await waitUntilLiveWaitingOnAllServers(servers, videoUUIDPermanent) |
212 | await waitJobs(servers) | ||
145 | 213 | ||
146 | const replay = await findExternalSavedVideo(servers[0], videoLiveDetails) | 214 | const videoLiveDetails = await servers[0].videos.get({ id: videoUUIDPermanent }) |
215 | const replay = await findExternalSavedVideo(servers[0], videoLiveDetails) | ||
147 | 216 | ||
148 | for (const server of servers) { | 217 | await checkFilesExist(servers, replay.uuid, 5) |
149 | const files = await getFiles(server, replay.uuid) | 218 | }) |
150 | expect(files).to.have.lengthOf(5) | ||
151 | 219 | ||
152 | await checkFiles(files) | 220 | it('Should have cleaned up live files from object storage', async function () { |
153 | } | 221 | await checkFilesCleanup(servers[0], videoUUIDPermanent, resolutions) |
222 | }) | ||
154 | }) | 223 | }) |
155 | }) | 224 | }) |
156 | 225 | ||
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts index 5abed358f..f349a7a76 100644 --- a/server/tests/api/redundancy/redundancy.ts +++ b/server/tests/api/redundancy/redundancy.ts | |||
@@ -5,7 +5,7 @@ import { readdir } from 'fs-extra' | |||
5 | import magnetUtil from 'magnet-uri' | 5 | import magnetUtil from 'magnet-uri' |
6 | import { basename, join } from 'path' | 6 | import { basename, join } from 'path' |
7 | import { checkSegmentHash, checkVideoFilesWereRemoved, saveVideoInServers } from '@server/tests/shared' | 7 | import { checkSegmentHash, checkVideoFilesWereRemoved, saveVideoInServers } from '@server/tests/shared' |
8 | import { root, wait } from '@shared/core-utils' | 8 | import { wait } from '@shared/core-utils' |
9 | import { | 9 | import { |
10 | HttpStatusCode, | 10 | HttpStatusCode, |
11 | VideoDetails, | 11 | VideoDetails, |
@@ -159,12 +159,12 @@ async function check2Webseeds (videoUUID?: string) { | |||
159 | const { webtorrentFilenames } = await ensureSameFilenames(videoUUID) | 159 | const { webtorrentFilenames } = await ensureSameFilenames(videoUUID) |
160 | 160 | ||
161 | const directories = [ | 161 | const directories = [ |
162 | 'test' + servers[0].internalServerNumber + '/redundancy', | 162 | servers[0].getDirectoryPath('redundancy'), |
163 | 'test' + servers[1].internalServerNumber + '/videos' | 163 | servers[1].getDirectoryPath('videos') |
164 | ] | 164 | ] |
165 | 165 | ||
166 | for (const directory of directories) { | 166 | for (const directory of directories) { |
167 | const files = await readdir(join(root(), directory)) | 167 | const files = await readdir(directory) |
168 | expect(files).to.have.length.at.least(4) | 168 | expect(files).to.have.length.at.least(4) |
169 | 169 | ||
170 | // Ensure we files exist on disk | 170 | // Ensure we files exist on disk |
@@ -214,12 +214,12 @@ async function check1PlaylistRedundancies (videoUUID?: string) { | |||
214 | const { hlsFilenames } = await ensureSameFilenames(videoUUID) | 214 | const { hlsFilenames } = await ensureSameFilenames(videoUUID) |
215 | 215 | ||
216 | const directories = [ | 216 | const directories = [ |
217 | 'test' + servers[0].internalServerNumber + '/redundancy/hls', | 217 | servers[0].getDirectoryPath('redundancy/hls'), |
218 | 'test' + servers[1].internalServerNumber + '/streaming-playlists/hls' | 218 | servers[1].getDirectoryPath('streaming-playlists/hls') |
219 | ] | 219 | ] |
220 | 220 | ||
221 | for (const directory of directories) { | 221 | for (const directory of directories) { |
222 | const files = await readdir(join(root(), directory, videoUUID)) | 222 | const files = await readdir(join(directory, videoUUID)) |
223 | expect(files).to.have.length.at.least(4) | 223 | expect(files).to.have.length.at.least(4) |
224 | 224 | ||
225 | // Ensure we files exist on disk | 225 | // Ensure we files exist on disk |
diff --git a/server/tests/api/users/index.ts b/server/tests/api/users/index.ts index c65152c6f..643f1a531 100644 --- a/server/tests/api/users/index.ts +++ b/server/tests/api/users/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import './two-factor' | ||
1 | import './user-subscriptions' | 2 | import './user-subscriptions' |
2 | import './user-videos' | 3 | import './user-videos' |
3 | import './users' | 4 | import './users' |
diff --git a/server/tests/api/users/two-factor.ts b/server/tests/api/users/two-factor.ts new file mode 100644 index 000000000..0dcab9e17 --- /dev/null +++ b/server/tests/api/users/two-factor.ts | |||
@@ -0,0 +1,200 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { expect } from 'chai' | ||
4 | import { expectStartWith } from '@server/tests/shared' | ||
5 | import { HttpStatusCode } from '@shared/models' | ||
6 | import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers, TwoFactorCommand } from '@shared/server-commands' | ||
7 | |||
8 | async function login (options: { | ||
9 | server: PeerTubeServer | ||
10 | username: string | ||
11 | password: string | ||
12 | otpToken?: string | ||
13 | expectedStatus?: HttpStatusCode | ||
14 | }) { | ||
15 | const { server, username, password, otpToken, expectedStatus } = options | ||
16 | |||
17 | const user = { username, password } | ||
18 | const { res, body: { access_token: token } } = await server.login.loginAndGetResponse({ user, otpToken, expectedStatus }) | ||
19 | |||
20 | return { res, token } | ||
21 | } | ||
22 | |||
23 | describe('Test users', function () { | ||
24 | let server: PeerTubeServer | ||
25 | let otpSecret: string | ||
26 | let requestToken: string | ||
27 | |||
28 | const userUsername = 'user1' | ||
29 | let userId: number | ||
30 | let userPassword: string | ||
31 | let userToken: string | ||
32 | |||
33 | before(async function () { | ||
34 | this.timeout(30000) | ||
35 | |||
36 | server = await createSingleServer(1) | ||
37 | |||
38 | await setAccessTokensToServers([ server ]) | ||
39 | const res = await server.users.generate(userUsername) | ||
40 | userId = res.userId | ||
41 | userPassword = res.password | ||
42 | userToken = res.token | ||
43 | }) | ||
44 | |||
45 | it('Should not add the header on login if two factor is not enabled', async function () { | ||
46 | const { res, token } = await login({ server, username: userUsername, password: userPassword }) | ||
47 | |||
48 | expect(res.header['x-peertube-otp']).to.not.exist | ||
49 | |||
50 | await server.users.getMyInfo({ token }) | ||
51 | }) | ||
52 | |||
53 | it('Should request two factor and get the secret and uri', async function () { | ||
54 | const { otpRequest } = await server.twoFactor.request({ userId, token: userToken, currentPassword: userPassword }) | ||
55 | |||
56 | expect(otpRequest.requestToken).to.exist | ||
57 | |||
58 | expect(otpRequest.secret).to.exist | ||
59 | expect(otpRequest.secret).to.have.lengthOf(32) | ||
60 | |||
61 | expect(otpRequest.uri).to.exist | ||
62 | expectStartWith(otpRequest.uri, 'otpauth://') | ||
63 | expect(otpRequest.uri).to.include(otpRequest.secret) | ||
64 | |||
65 | requestToken = otpRequest.requestToken | ||
66 | otpSecret = otpRequest.secret | ||
67 | }) | ||
68 | |||
69 | it('Should not have two factor confirmed yet', async function () { | ||
70 | const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken }) | ||
71 | expect(twoFactorEnabled).to.be.false | ||
72 | }) | ||
73 | |||
74 | it('Should confirm two factor', async function () { | ||
75 | await server.twoFactor.confirmRequest({ | ||
76 | userId, | ||
77 | token: userToken, | ||
78 | otpToken: TwoFactorCommand.buildOTP({ secret: otpSecret }).generate(), | ||
79 | requestToken | ||
80 | }) | ||
81 | }) | ||
82 | |||
83 | it('Should not add the header on login if two factor is enabled and password is incorrect', async function () { | ||
84 | const { res, token } = await login({ server, username: userUsername, password: 'fake', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
85 | |||
86 | expect(res.header['x-peertube-otp']).to.not.exist | ||
87 | expect(token).to.not.exist | ||
88 | }) | ||
89 | |||
90 | it('Should add the header on login if two factor is enabled and password is correct', async function () { | ||
91 | const { res, token } = await login({ | ||
92 | server, | ||
93 | username: userUsername, | ||
94 | password: userPassword, | ||
95 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 | ||
96 | }) | ||
97 | |||
98 | expect(res.header['x-peertube-otp']).to.exist | ||
99 | expect(token).to.not.exist | ||
100 | |||
101 | await server.users.getMyInfo({ token }) | ||
102 | }) | ||
103 | |||
104 | it('Should not login with correct password and incorrect otp secret', async function () { | ||
105 | const otp = TwoFactorCommand.buildOTP({ secret: 'a'.repeat(32) }) | ||
106 | |||
107 | const { res, token } = await login({ | ||
108 | server, | ||
109 | username: userUsername, | ||
110 | password: userPassword, | ||
111 | otpToken: otp.generate(), | ||
112 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
113 | }) | ||
114 | |||
115 | expect(res.header['x-peertube-otp']).to.not.exist | ||
116 | expect(token).to.not.exist | ||
117 | }) | ||
118 | |||
119 | it('Should not login with correct password and incorrect otp code', async function () { | ||
120 | const { res, token } = await login({ | ||
121 | server, | ||
122 | username: userUsername, | ||
123 | password: userPassword, | ||
124 | otpToken: '123456', | ||
125 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
126 | }) | ||
127 | |||
128 | expect(res.header['x-peertube-otp']).to.not.exist | ||
129 | expect(token).to.not.exist | ||
130 | }) | ||
131 | |||
132 | it('Should not login with incorrect password and correct otp code', async function () { | ||
133 | const otpToken = TwoFactorCommand.buildOTP({ secret: otpSecret }).generate() | ||
134 | |||
135 | const { res, token } = await login({ | ||
136 | server, | ||
137 | username: userUsername, | ||
138 | password: 'fake', | ||
139 | otpToken, | ||
140 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
141 | }) | ||
142 | |||
143 | expect(res.header['x-peertube-otp']).to.not.exist | ||
144 | expect(token).to.not.exist | ||
145 | }) | ||
146 | |||
147 | it('Should correctly login with correct password and otp code', async function () { | ||
148 | const otpToken = TwoFactorCommand.buildOTP({ secret: otpSecret }).generate() | ||
149 | |||
150 | const { res, token } = await login({ server, username: userUsername, password: userPassword, otpToken }) | ||
151 | |||
152 | expect(res.header['x-peertube-otp']).to.not.exist | ||
153 | expect(token).to.exist | ||
154 | |||
155 | await server.users.getMyInfo({ token }) | ||
156 | }) | ||
157 | |||
158 | it('Should have two factor enabled when getting my info', async function () { | ||
159 | const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken }) | ||
160 | expect(twoFactorEnabled).to.be.true | ||
161 | }) | ||
162 | |||
163 | it('Should disable two factor and be able to login without otp token', async function () { | ||
164 | await server.twoFactor.disable({ userId, token: userToken, currentPassword: userPassword }) | ||
165 | |||
166 | const { res, token } = await login({ server, username: userUsername, password: userPassword }) | ||
167 | expect(res.header['x-peertube-otp']).to.not.exist | ||
168 | |||
169 | await server.users.getMyInfo({ token }) | ||
170 | }) | ||
171 | |||
172 | it('Should have two factor disabled when getting my info', async function () { | ||
173 | const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken }) | ||
174 | expect(twoFactorEnabled).to.be.false | ||
175 | }) | ||
176 | |||
177 | it('Should enable two factor auth without password from an admin', async function () { | ||
178 | const { otpRequest } = await server.twoFactor.request({ userId }) | ||
179 | |||
180 | await server.twoFactor.confirmRequest({ | ||
181 | userId, | ||
182 | otpToken: TwoFactorCommand.buildOTP({ secret: otpRequest.secret }).generate(), | ||
183 | requestToken: otpRequest.requestToken | ||
184 | }) | ||
185 | |||
186 | const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken }) | ||
187 | expect(twoFactorEnabled).to.be.true | ||
188 | }) | ||
189 | |||
190 | it('Should disable two factor auth without password from an admin', async function () { | ||
191 | await server.twoFactor.disable({ userId }) | ||
192 | |||
193 | const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken }) | ||
194 | expect(twoFactorEnabled).to.be.false | ||
195 | }) | ||
196 | |||
197 | after(async function () { | ||
198 | await cleanupTests([ server ]) | ||
199 | }) | ||
200 | }) | ||
diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts index 62d668d1e..188e6f137 100644 --- a/server/tests/api/users/users-multiple-servers.ts +++ b/server/tests/api/users/users-multiple-servers.ts | |||
@@ -197,7 +197,7 @@ describe('Test users with multiple servers', function () { | |||
197 | it('Should not have actor files', async () => { | 197 | it('Should not have actor files', async () => { |
198 | for (const server of servers) { | 198 | for (const server of servers) { |
199 | for (const userAvatarFilename of userAvatarFilenames) { | 199 | for (const userAvatarFilename of userAvatarFilenames) { |
200 | await checkActorFilesWereRemoved(userAvatarFilename, server.internalServerNumber) | 200 | await checkActorFilesWereRemoved(userAvatarFilename, server) |
201 | } | 201 | } |
202 | } | 202 | } |
203 | }) | 203 | }) |
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index d47807a79..2ad749fd4 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts | |||
@@ -156,7 +156,7 @@ describe('Test multiple servers', function () { | |||
156 | }) | 156 | }) |
157 | 157 | ||
158 | it('Should upload the video on server 2 and propagate on each server', async function () { | 158 | it('Should upload the video on server 2 and propagate on each server', async function () { |
159 | this.timeout(100000) | 159 | this.timeout(240000) |
160 | 160 | ||
161 | const user = { | 161 | const user = { |
162 | username: 'user1', | 162 | username: 'user1', |
diff --git a/server/tests/api/videos/video-files.ts b/server/tests/api/videos/video-files.ts index 10277b9cf..c0b886aad 100644 --- a/server/tests/api/videos/video-files.ts +++ b/server/tests/api/videos/video-files.ts | |||
@@ -33,7 +33,7 @@ describe('Test videos files', function () { | |||
33 | let validId2: string | 33 | let validId2: string |
34 | 34 | ||
35 | before(async function () { | 35 | before(async function () { |
36 | this.timeout(120_000) | 36 | this.timeout(360_000) |
37 | 37 | ||
38 | { | 38 | { |
39 | const { uuid } = await servers[0].videos.quickUpload({ name: 'video 1' }) | 39 | const { uuid } = await servers[0].videos.quickUpload({ name: 'video 1' }) |
diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts index 47b8c7b1e..9d223de48 100644 --- a/server/tests/api/videos/video-playlists.ts +++ b/server/tests/api/videos/video-playlists.ts | |||
@@ -70,7 +70,7 @@ describe('Test video playlists', function () { | |||
70 | let commands: PlaylistsCommand[] | 70 | let commands: PlaylistsCommand[] |
71 | 71 | ||
72 | before(async function () { | 72 | before(async function () { |
73 | this.timeout(120000) | 73 | this.timeout(240000) |
74 | 74 | ||
75 | servers = await createMultipleServers(3) | 75 | servers = await createMultipleServers(3) |
76 | 76 | ||
@@ -1049,7 +1049,7 @@ describe('Test video playlists', function () { | |||
1049 | this.timeout(30000) | 1049 | this.timeout(30000) |
1050 | 1050 | ||
1051 | for (const server of servers) { | 1051 | for (const server of servers) { |
1052 | await checkPlaylistFilesWereRemoved(playlistServer1UUID, server.internalServerNumber) | 1052 | await checkPlaylistFilesWereRemoved(playlistServer1UUID, server) |
1053 | } | 1053 | } |
1054 | }) | 1054 | }) |
1055 | 1055 | ||
diff --git a/server/tests/api/videos/video-privacy.ts b/server/tests/api/videos/video-privacy.ts index b18c71c94..92f5dab3c 100644 --- a/server/tests/api/videos/video-privacy.ts +++ b/server/tests/api/videos/video-privacy.ts | |||
@@ -45,7 +45,7 @@ describe('Test video privacy', function () { | |||
45 | describe('Private and internal videos', function () { | 45 | describe('Private and internal videos', function () { |
46 | 46 | ||
47 | it('Should upload a private and internal videos on server 1', async function () { | 47 | it('Should upload a private and internal videos on server 1', async function () { |
48 | this.timeout(10000) | 48 | this.timeout(50000) |
49 | 49 | ||
50 | for (const privacy of [ VideoPrivacy.PRIVATE, VideoPrivacy.INTERNAL ]) { | 50 | for (const privacy of [ VideoPrivacy.PRIVATE, VideoPrivacy.INTERNAL ]) { |
51 | const attributes = { privacy } | 51 | const attributes = { privacy } |
diff --git a/server/tests/api/videos/videos-common-filters.ts b/server/tests/api/videos/videos-common-filters.ts index e7fc15e42..b176d90ab 100644 --- a/server/tests/api/videos/videos-common-filters.ts +++ b/server/tests/api/videos/videos-common-filters.ts | |||
@@ -232,7 +232,7 @@ describe('Test videos filter', function () { | |||
232 | }) | 232 | }) |
233 | 233 | ||
234 | it('Should display only remote videos', async function () { | 234 | it('Should display only remote videos', async function () { |
235 | this.timeout(40000) | 235 | this.timeout(120000) |
236 | 236 | ||
237 | await servers[1].videos.upload({ attributes: { name: 'remote video' } }) | 237 | await servers[1].videos.upload({ attributes: { name: 'remote video' } }) |
238 | 238 | ||