1 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
2 import { omit } from '@shared/core-utils'
3 import { HttpStatusCode, UserRole } from '@shared/models'
9 setAccessTokensToServers,
10 setDefaultAccountAvatar,
11 setDefaultChannelAvatar
12 } from '@shared/server-commands'
14 describe('Test registrations API validators', function () {
15 let server: PeerTubeServer
17 let moderatorToken: string
19 // ---------------------------------------------------------------
21 before(async function () {
24 server = await createSingleServer(1)
26 await setAccessTokensToServers([ server ])
27 await setDefaultAccountAvatar([ server ])
28 await setDefaultChannelAvatar([ server ])
30 await server.config.enableSignup(false);
32 ({ token: moderatorToken } = await server.users.generate('moderator', UserRole.MODERATOR));
33 ({ token: userToken } = await server.users.generate('user', UserRole.USER))
36 describe('Register', function () {
37 const registrationPath = '/api/v1/users/register'
38 const registrationRequestPath = '/api/v1/users/registrations/request'
40 const baseCorrectParams = {
42 displayName: 'super user',
43 email: 'test3@example.com',
44 password: 'my super password',
45 registrationReason: 'my super registration reason'
48 describe('When registering a new user or requesting user registration', function () {
50 async function check (fields: any, expectedStatus = HttpStatusCode.BAD_REQUEST_400) {
51 await server.config.enableSignup(false)
52 await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus })
54 await server.config.enableSignup(true)
55 await makePostBodyRequest({ url: server.url, path: registrationRequestPath, fields, expectedStatus })
58 it('Should fail with a too small username', async function () {
59 const fields = { ...baseCorrectParams, username: '' }
64 it('Should fail with a too long username', async function () {
65 const fields = { ...baseCorrectParams, username: 'super'.repeat(50) }
70 it('Should fail with an incorrect username', async function () {
71 const fields = { ...baseCorrectParams, username: 'my username' }
76 it('Should fail with a missing email', async function () {
77 const fields = omit(baseCorrectParams, [ 'email' ])
82 it('Should fail with an invalid email', async function () {
83 const fields = { ...baseCorrectParams, email: 'test_example.com' }
88 it('Should fail with a too small password', async function () {
89 const fields = { ...baseCorrectParams, password: 'bla' }
94 it('Should fail with a too long password', async function () {
95 const fields = { ...baseCorrectParams, password: 'super'.repeat(61) }
100 it('Should fail if we register a user with the same username', async function () {
101 const fields = { ...baseCorrectParams, username: 'root' }
103 await check(fields, HttpStatusCode.CONFLICT_409)
106 it('Should fail with a "peertube" username', async function () {
107 const fields = { ...baseCorrectParams, username: 'peertube' }
109 await check(fields, HttpStatusCode.CONFLICT_409)
112 it('Should fail if we register a user with the same email', async function () {
113 const fields = { ...baseCorrectParams, email: 'admin' + server.internalServerNumber + '@example.com' }
115 await check(fields, HttpStatusCode.CONFLICT_409)
118 it('Should fail with a bad display name', async function () {
119 const fields = { ...baseCorrectParams, displayName: 'a'.repeat(150) }
124 it('Should fail with a bad channel name', async function () {
125 const fields = { ...baseCorrectParams, channel: { name: '[]azf', displayName: 'toto' } }
130 it('Should fail with a bad channel display name', async function () {
131 const fields = { ...baseCorrectParams, channel: { name: 'toto', displayName: '' } }
136 it('Should fail with a channel name that is the same as username', async function () {
137 const source = { username: 'super_user', channel: { name: 'super_user', displayName: 'display name' } }
138 const fields = { ...baseCorrectParams, ...source }
143 it('Should fail with an existing channel', async function () {
144 const attributes = { name: 'existing_channel', displayName: 'hello', description: 'super description' }
145 await server.channels.create({ attributes })
147 const fields = { ...baseCorrectParams, channel: { name: 'existing_channel', displayName: 'toto' } }
149 await check(fields, HttpStatusCode.CONFLICT_409)
152 it('Should fail on a server with registration disabled', async function () {
155 await server.config.updateExistingSubConfig({
163 await server.registrations.register({ username: 'user4', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
164 await server.registrations.requestRegistration({
166 registrationReason: 'reason',
167 expectedStatus: HttpStatusCode.FORBIDDEN_403
171 it('Should fail if the user limit is reached', async function () {
174 const { total } = await server.users.list()
176 await server.config.enableSignup(false, total)
177 await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
179 await server.config.enableSignup(true, total)
180 await server.registrations.requestRegistration({
182 registrationReason: 'reason',
183 expectedStatus: HttpStatusCode.FORBIDDEN_403
187 it('Should succeed if the user limit is not reached', async function () {
190 const { total } = await server.users.list()
192 await server.config.enableSignup(false, total + 1)
193 await server.registrations.register({ username: 'user43', expectedStatus: HttpStatusCode.NO_CONTENT_204 })
195 await server.config.enableSignup(true, total + 2)
196 await server.registrations.requestRegistration({
198 registrationReason: 'reason',
199 expectedStatus: HttpStatusCode.OK_200
204 describe('On direct registration', function () {
206 it('Should succeed with the correct params', async function () {
207 await server.config.enableSignup(false)
210 username: 'user_direct_1',
211 displayName: 'super user direct 1',
212 email: 'user_direct_1@example.com',
213 password: 'my super password',
214 channel: { name: 'super_user_direct_1_channel', displayName: 'super user direct 1 channel' }
217 await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
220 it('Should fail if the instance requires approval', async function () {
223 await server.config.enableSignup(true)
224 await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
228 describe('On registration request', function () {
230 before(async function () {
233 await server.config.enableSignup(true)
236 it('Should fail with an invalid registration reason', async function () {
237 for (const registrationReason of [ '', 't', 't'.repeat(5000) ]) {
238 await server.registrations.requestRegistration({
239 username: 'user_request_1',
241 expectedStatus: HttpStatusCode.BAD_REQUEST_400
246 it('Should succeed with the correct params', async function () {
247 await server.registrations.requestRegistration({
248 username: 'user_request_2',
249 registrationReason: 'tt',
251 displayName: 'my user request 2 channel',
252 name: 'user_request_2_channel'
257 it('Should fail if the username is already awaiting registration approval', async function () {
258 await server.registrations.requestRegistration({
259 username: 'user_request_2',
260 registrationReason: 'tt',
262 displayName: 'my user request 42 channel',
263 name: 'user_request_42_channel'
265 expectedStatus: HttpStatusCode.CONFLICT_409
269 it('Should fail if the email is already awaiting registration approval', async function () {
270 await server.registrations.requestRegistration({
272 email: 'user_request_2@example.com',
273 registrationReason: 'tt',
275 displayName: 'my user request 42 channel',
276 name: 'user_request_42_channel'
278 expectedStatus: HttpStatusCode.CONFLICT_409
282 it('Should fail if the channel is already awaiting registration approval', async function () {
283 await server.registrations.requestRegistration({
285 registrationReason: 'tt',
287 displayName: 'my user request 2 channel',
288 name: 'user_request_2_channel'
290 expectedStatus: HttpStatusCode.CONFLICT_409
294 it('Should fail if the instance does not require approval', async function () {
297 await server.config.enableSignup(false)
299 await server.registrations.requestRegistration({
301 registrationReason: 'toto',
302 expectedStatus: HttpStatusCode.BAD_REQUEST_400
308 describe('Registrations accept/reject', function () {
312 before(async function () {
315 await server.config.enableSignup(true);
317 ({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_2', registrationReason: 'toto' }));
318 ({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_3', registrationReason: 'toto' }))
321 it('Should fail to accept/reject registration without token', async function () {
322 const options = { id: id1, moderationResponse: 'tt', token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }
323 await server.registrations.accept(options)
324 await server.registrations.reject(options)
327 it('Should fail to accept/reject registration with a non moderator user', async function () {
328 const options = { id: id1, moderationResponse: 'tt', token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }
329 await server.registrations.accept(options)
330 await server.registrations.reject(options)
333 it('Should fail to accept/reject registration with a bad registration id', async function () {
335 const options = { id: 't' as any, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }
336 await server.registrations.accept(options)
337 await server.registrations.reject(options)
341 const options = { id: 42, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }
342 await server.registrations.accept(options)
343 await server.registrations.reject(options)
347 it('Should fail to accept/reject registration with a bad moderation resposne', async function () {
348 for (const moderationResponse of [ '', 't', 't'.repeat(5000) ]) {
349 const options = { id: id1, moderationResponse, token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }
350 await server.registrations.accept(options)
351 await server.registrations.reject(options)
355 it('Should succeed to accept a registration', async function () {
356 await server.registrations.accept({ id: id1, moderationResponse: 'tt', token: moderatorToken })
359 it('Should succeed to reject a registration', async function () {
360 await server.registrations.reject({ id: id2, moderationResponse: 'tt', token: moderatorToken })
363 it('Should fail to accept/reject a registration that was already accepted/rejected', async function () {
364 for (const id of [ id1, id2 ]) {
365 const options = { id, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.CONFLICT_409 }
366 await server.registrations.accept(options)
367 await server.registrations.reject(options)
372 describe('Registrations deletion', function () {
377 before(async function () {
378 ({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_4', registrationReason: 'toto' }));
379 ({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_5', registrationReason: 'toto' }));
380 ({ id: id3 } = await server.registrations.requestRegistration({ username: 'request_6', registrationReason: 'toto' }))
382 await server.registrations.accept({ id: id2, moderationResponse: 'tt' })
383 await server.registrations.reject({ id: id3, moderationResponse: 'tt' })
386 it('Should fail to delete registration without token', async function () {
387 await server.registrations.delete({ id: id1, token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
390 it('Should fail to delete registration with a non moderator user', async function () {
391 await server.registrations.delete({ id: id1, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
394 it('Should fail to delete registration with a bad registration id', async function () {
395 await server.registrations.delete({ id: 't' as any, token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
396 await server.registrations.delete({ id: 42, token: moderatorToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
399 it('Should succeed with the correct params', async function () {
400 await server.registrations.delete({ id: id1, token: moderatorToken })
401 await server.registrations.delete({ id: id2, token: moderatorToken })
402 await server.registrations.delete({ id: id3, token: moderatorToken })
406 describe('Listing registrations', function () {
407 const path = '/api/v1/users/registrations'
409 it('Should fail with a bad start pagination', async function () {
410 await checkBadStartPagination(server.url, path, server.accessToken)
413 it('Should fail with a bad count pagination', async function () {
414 await checkBadCountPagination(server.url, path, server.accessToken)
417 it('Should fail with an incorrect sort', async function () {
418 await checkBadSortPagination(server.url, path, server.accessToken)
421 it('Should fail with a non authenticated user', async function () {
422 await server.registrations.list({
424 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
428 it('Should fail with a non admin user', async function () {
429 await server.registrations.list({
431 expectedStatus: HttpStatusCode.FORBIDDEN_403
435 it('Should succeed with the correct params', async function () {
436 await server.registrations.list({
437 token: moderatorToken,
443 after(async function () {
444 await cleanupTests([ server ])