aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-07-13 14:23:01 +0200
committerChocobozzz <me@florianbigard.com>2021-07-20 15:27:18 +0200
commit7926c5f9b3ffcabb1ffb0dcfa5e48b8e0b88fbc0 (patch)
tree7a166515e4d57a06eb3c08be569f106ed049988b /shared
parentd0a0fa429d4651710ed951a3c11af0219e408964 (diff)
downloadPeerTube-7926c5f9b3ffcabb1ffb0dcfa5e48b8e0b88fbc0.tar.gz
PeerTube-7926c5f9b3ffcabb1ffb0dcfa5e48b8e0b88fbc0.tar.zst
PeerTube-7926c5f9b3ffcabb1ffb0dcfa5e48b8e0b88fbc0.zip
Introduce user command
Diffstat (limited to 'shared')
-rw-r--r--shared/extra-utils/server/servers.ts4
-rw-r--r--shared/extra-utils/users/index.ts1
-rw-r--r--shared/extra-utils/users/login-command.ts12
-rw-r--r--shared/extra-utils/users/notifications.ts18
-rw-r--r--shared/extra-utils/users/users-command.ts414
-rw-r--r--shared/extra-utils/users/users.ts400
-rw-r--r--shared/extra-utils/videos/channels.ts6
-rw-r--r--shared/extra-utils/videos/videos.ts4
-rw-r--r--shared/models/users/index.ts1
-rw-r--r--shared/models/users/user-create-result.model.ts7
10 files changed, 443 insertions, 424 deletions
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index 4d9599680..b6d597c5d 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -16,7 +16,7 @@ import { AbusesCommand } from '../moderation'
16import { OverviewsCommand } from '../overviews' 16import { OverviewsCommand } from '../overviews'
17import { SearchCommand } from '../search' 17import { SearchCommand } from '../search'
18import { SocketIOCommand } from '../socket' 18import { SocketIOCommand } from '../socket'
19import { AccountsCommand, BlocklistCommand, LoginCommand, NotificationsCommand, SubscriptionsCommand } from '../users' 19import { AccountsCommand, BlocklistCommand, LoginCommand, NotificationsCommand, SubscriptionsCommand, UsersCommand } from '../users'
20import { 20import {
21 BlacklistCommand, 21 BlacklistCommand,
22 CaptionsCommand, 22 CaptionsCommand,
@@ -127,6 +127,7 @@ interface ServerInfo {
127 notificationsCommand?: NotificationsCommand 127 notificationsCommand?: NotificationsCommand
128 serversCommand?: ServersCommand 128 serversCommand?: ServersCommand
129 loginCommand?: LoginCommand 129 loginCommand?: LoginCommand
130 usersCommand?: UsersCommand
130} 131}
131 132
132function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) { 133function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) {
@@ -359,6 +360,7 @@ function assignCommands (server: ServerInfo) {
359 server.notificationsCommand = new NotificationsCommand(server) 360 server.notificationsCommand = new NotificationsCommand(server)
360 server.serversCommand = new ServersCommand(server) 361 server.serversCommand = new ServersCommand(server)
361 server.loginCommand = new LoginCommand(server) 362 server.loginCommand = new LoginCommand(server)
363 server.usersCommand = new UsersCommand(server)
362} 364}
363 365
364async function reRunServer (server: ServerInfo, configOverride?: any) { 366async function reRunServer (server: ServerInfo, configOverride?: any) {
diff --git a/shared/extra-utils/users/index.ts b/shared/extra-utils/users/index.ts
index b200ae705..e6107afa5 100644
--- a/shared/extra-utils/users/index.ts
+++ b/shared/extra-utils/users/index.ts
@@ -6,4 +6,5 @@ export * from './login-command'
6export * from './notifications' 6export * from './notifications'
7export * from './notifications-command' 7export * from './notifications-command'
8export * from './subscriptions-command' 8export * from './subscriptions-command'
9export * from './users-command'
9export * from './users' 10export * from './users'
diff --git a/shared/extra-utils/users/login-command.ts b/shared/extra-utils/users/login-command.ts
index 8af3531f9..b4e3bb602 100644
--- a/shared/extra-utils/users/login-command.ts
+++ b/shared/extra-utils/users/login-command.ts
@@ -7,7 +7,7 @@ export class LoginCommand extends AbstractCommand {
7 7
8 login (options: OverrideCommandOptions & { 8 login (options: OverrideCommandOptions & {
9 client?: { id?: string, secret?: string } 9 client?: { id?: string, secret?: string }
10 user?: { username: string, password: string } 10 user?: { username: string, password?: string }
11 } = {}) { 11 } = {}) {
12 const { client = this.server.client, user = this.server.user } = options 12 const { client = this.server.client, user = this.server.user } = options
13 const path = '/api/v1/users/token' 13 const path = '/api/v1/users/token'
@@ -16,7 +16,7 @@ export class LoginCommand extends AbstractCommand {
16 client_id: client.id, 16 client_id: client.id,
17 client_secret: client.secret, 17 client_secret: client.secret,
18 username: user.username, 18 username: user.username,
19 password: user.password, 19 password: user.password ?? 'password',
20 response_type: 'code', 20 response_type: 'code',
21 grant_type: 'password', 21 grant_type: 'password',
22 scope: 'upload' 22 scope: 'upload'
@@ -33,10 +33,10 @@ export class LoginCommand extends AbstractCommand {
33 })) 33 }))
34 } 34 }
35 35
36 getAccessToken (arg1?: { username: string, password: string }): Promise<string> 36 getAccessToken (arg1?: { username: string, password?: string }): Promise<string>
37 getAccessToken (arg1: string, password: string): Promise<string> 37 getAccessToken (arg1: string, password?: string): Promise<string>
38 async getAccessToken (arg1?: { username: string, password: string } | string, password?: string) { 38 async getAccessToken (arg1?: { username: string, password?: string } | string, password?: string) {
39 let user: { username: string, password: string } 39 let user: { username: string, password?: string }
40 40
41 if (!arg1) user = this.server.user 41 if (!arg1) user = this.server.user
42 else if (typeof arg1 === 'object') user = arg1 42 else if (typeof arg1 === 'object') user = arg1
diff --git a/shared/extra-utils/users/notifications.ts b/shared/extra-utils/users/notifications.ts
index 79cb6f617..0af7d8a18 100644
--- a/shared/extra-utils/users/notifications.ts
+++ b/shared/extra-utils/users/notifications.ts
@@ -8,7 +8,6 @@ import { MockSmtpServer } from '../mock-servers/mock-email'
8import { doubleFollow } from '../server/follows' 8import { doubleFollow } from '../server/follows'
9import { flushAndRunMultipleServers, ServerInfo } from '../server/servers' 9import { flushAndRunMultipleServers, ServerInfo } from '../server/servers'
10import { setAccessTokensToServers } from './login' 10import { setAccessTokensToServers } from './login'
11import { createUser, getMyUserInformation } from './users'
12 11
13function getAllNotificationsSettings (): UserNotificationSetting { 12function getAllNotificationsSettings (): UserNotificationSetting {
14 return { 13 return {
@@ -651,17 +650,8 @@ async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: an
651 await doubleFollow(servers[0], servers[1]) 650 await doubleFollow(servers[0], servers[1])
652 } 651 }
653 652
654 const user = { 653 const user = { username: 'user_1', password: 'super password' }
655 username: 'user_1', 654 await servers[0].usersCommand.create({ ...user, videoQuota: 10 * 1000 * 1000 })
656 password: 'super password'
657 }
658 await createUser({
659 url: servers[0].url,
660 accessToken: servers[0].accessToken,
661 username: user.username,
662 password: user.password,
663 videoQuota: 10 * 1000 * 1000
664 })
665 const userAccessToken = await servers[0].loginCommand.getAccessToken(user) 655 const userAccessToken = await servers[0].loginCommand.getAccessToken(user)
666 656
667 await servers[0].notificationsCommand.updateMySettings({ token: userAccessToken, settings: getAllNotificationsSettings() }) 657 await servers[0].notificationsCommand.updateMySettings({ token: userAccessToken, settings: getAllNotificationsSettings() })
@@ -685,8 +675,8 @@ async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: an
685 socket.on('new-notification', n => adminNotificationsServer2.push(n)) 675 socket.on('new-notification', n => adminNotificationsServer2.push(n))
686 } 676 }
687 677
688 const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken) 678 const { videoChannels } = await servers[0].usersCommand.getMyInfo()
689 const channelId = resChannel.body.videoChannels[0].id 679 const channelId = videoChannels[0].id
690 680
691 return { 681 return {
692 userNotifications, 682 userNotifications,
diff --git a/shared/extra-utils/users/users-command.ts b/shared/extra-utils/users/users-command.ts
new file mode 100644
index 000000000..202528b8d
--- /dev/null
+++ b/shared/extra-utils/users/users-command.ts
@@ -0,0 +1,414 @@
1import { omit, pick } from 'lodash'
2import { HttpStatusCode } from '@shared/core-utils'
3import {
4 MyUser,
5 ResultList,
6 User,
7 UserAdminFlag,
8 UserCreateResult,
9 UserRole,
10 UserUpdate,
11 UserUpdateMe,
12 UserVideoQuota,
13 UserVideoRate
14} from '@shared/models'
15import { ScopedToken } from '@shared/models/users/user-scoped-token'
16import { unwrapBody } from '../requests'
17import { AbstractCommand, OverrideCommandOptions } from '../shared'
18
19export class UsersCommand extends AbstractCommand {
20
21 askResetPassword (options: OverrideCommandOptions & {
22 email: string
23 }) {
24 const { email } = options
25 const path = '/api/v1/users/ask-reset-password'
26
27 return this.postBodyRequest({
28 ...options,
29
30 path,
31 fields: { email },
32 implicitToken: false,
33 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
34 })
35 }
36
37 resetPassword (options: OverrideCommandOptions & {
38 userId: number
39 verificationString: string
40 password: string
41 }) {
42 const { userId, verificationString, password } = options
43 const path = '/api/v1/users/' + userId + '/reset-password'
44
45 return this.postBodyRequest({
46 ...options,
47
48 path,
49 fields: { password, verificationString },
50 implicitToken: false,
51 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
52 })
53 }
54
55 // ---------------------------------------------------------------------------
56
57 askSendVerifyEmail (options: OverrideCommandOptions & {
58 email: string
59 }) {
60 const { email } = options
61 const path = '/api/v1/users/ask-send-verify-email'
62
63 return this.postBodyRequest({
64 ...options,
65
66 path,
67 fields: { email },
68 implicitToken: false,
69 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
70 })
71 }
72
73 verifyEmail (options: OverrideCommandOptions & {
74 userId: number
75 verificationString: string
76 isPendingEmail?: boolean // default false
77 }) {
78 const { userId, verificationString, isPendingEmail = false } = options
79 const path = '/api/v1/users/' + userId + '/verify-email'
80
81 return this.postBodyRequest({
82 ...options,
83
84 path,
85 fields: {
86 verificationString,
87 isPendingEmail
88 },
89 implicitToken: false,
90 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
91 })
92 }
93
94 // ---------------------------------------------------------------------------
95
96 banUser (options: OverrideCommandOptions & {
97 userId: number
98 reason?: string
99 }) {
100 const { userId, reason } = options
101 const path = '/api/v1/users' + '/' + userId + '/block'
102
103 return this.postBodyRequest({
104 ...options,
105
106 path,
107 fields: { reason },
108 implicitToken: true,
109 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
110 })
111 }
112
113 unbanUser (options: OverrideCommandOptions & {
114 userId: number
115 }) {
116 const { userId } = options
117 const path = '/api/v1/users' + '/' + userId + '/unblock'
118
119 return this.postBodyRequest({
120 ...options,
121
122 path,
123 implicitToken: true,
124 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
125 })
126 }
127
128 // ---------------------------------------------------------------------------
129
130 getMyScopedTokens (options: OverrideCommandOptions = {}) {
131 const path = '/api/v1/users/scoped-tokens'
132
133 return this.getRequestBody<ScopedToken>({
134 ...options,
135
136 path,
137 implicitToken: true,
138 defaultExpectedStatus: HttpStatusCode.OK_200
139 })
140 }
141
142 renewMyScopedTokens (options: OverrideCommandOptions = {}) {
143 const path = '/api/v1/users/scoped-tokens'
144
145 return this.postBodyRequest({
146 ...options,
147
148 path,
149 implicitToken: true,
150 defaultExpectedStatus: HttpStatusCode.OK_200
151 })
152 }
153
154 // ---------------------------------------------------------------------------
155
156 create (options: OverrideCommandOptions & {
157 username: string
158 password?: string
159 videoQuota?: number
160 videoQuotaDaily?: number
161 role?: UserRole
162 adminFlags?: UserAdminFlag
163 }) {
164 const {
165 username,
166 adminFlags,
167 password = 'password',
168 videoQuota = 42000000,
169 videoQuotaDaily = -1,
170 role = UserRole.USER
171 } = options
172
173 const path = '/api/v1/users'
174
175 return unwrapBody<{ user: UserCreateResult }>(this.postBodyRequest({
176 ...options,
177
178 path,
179 fields: {
180 username,
181 password,
182 role,
183 adminFlags,
184 email: username + '@example.com',
185 videoQuota,
186 videoQuotaDaily
187 },
188 implicitToken: true,
189 defaultExpectedStatus: HttpStatusCode.OK_200
190 })).then(res => res.user)
191 }
192
193 async generate (username: string) {
194 const password = 'password'
195 const user = await this.create({ username, password })
196
197 const token = await this.server.loginCommand.getAccessToken({ username, password })
198
199 const me = await this.getMyInfo({ token })
200
201 return {
202 token,
203 userId: user.id,
204 userChannelId: me.videoChannels[0].id
205 }
206 }
207
208 async generateUserAndToken (username: string) {
209 const password = 'password'
210 await this.create({ username, password })
211
212 return this.server.loginCommand.getAccessToken({ username, password })
213 }
214
215 register (options: OverrideCommandOptions & {
216 username: string
217 password?: string
218 displayName?: string
219 channel?: {
220 name: string
221 displayName: string
222 }
223 }) {
224 const { username, password = 'password', displayName, channel } = options
225 const path = '/api/v1/users/register'
226
227 return this.postBodyRequest({
228 ...options,
229
230 path,
231 fields: {
232 username,
233 password,
234 email: username + '@example.com',
235 displayName,
236 channel
237 },
238 implicitToken: false,
239 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
240 })
241 }
242
243 // ---------------------------------------------------------------------------
244
245 getMyInfo (options: OverrideCommandOptions = {}) {
246 const path = '/api/v1/users/me'
247
248 return this.getRequestBody<MyUser>({
249 ...options,
250
251 path,
252 implicitToken: true,
253 defaultExpectedStatus: HttpStatusCode.OK_200
254 })
255 }
256
257 getMyQuotaUsed (options: OverrideCommandOptions = {}) {
258 const path = '/api/v1/users/me/video-quota-used'
259
260 return this.getRequestBody<UserVideoQuota>({
261 ...options,
262
263 path,
264 implicitToken: true,
265 defaultExpectedStatus: HttpStatusCode.OK_200
266 })
267 }
268
269 getMyRating (options: OverrideCommandOptions & {
270 videoId: number | string
271 }) {
272 const { videoId } = options
273 const path = '/api/v1/users/me/videos/' + videoId + '/rating'
274
275 return this.getRequestBody<UserVideoRate>({
276 ...options,
277
278 path,
279 implicitToken: true,
280 defaultExpectedStatus: HttpStatusCode.OK_200
281 })
282 }
283
284 deleteMe (options: OverrideCommandOptions = {}) {
285 const path = '/api/v1/users/me'
286
287 return this.deleteRequest({
288 ...options,
289
290 path,
291 implicitToken: true,
292 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
293 })
294 }
295
296 updateMe (options: OverrideCommandOptions & UserUpdateMe) {
297 const path = '/api/v1/users/me'
298
299 const toSend: UserUpdateMe = omit(options, 'url', 'accessToken')
300
301 return this.putBodyRequest({
302 ...options,
303
304 path,
305 fields: toSend,
306 implicitToken: true,
307 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
308 })
309 }
310
311 updateMyAvatar (options: OverrideCommandOptions & {
312 fixture: string
313 }) {
314 const { fixture } = options
315 const path = '/api/v1/users/me/avatar/pick'
316
317 return this.updateImageRequest({
318 ...options,
319
320 path,
321 fixture,
322 fieldname: 'avatarfile',
323
324 implicitToken: true,
325 defaultExpectedStatus: HttpStatusCode.OK_200
326 })
327 }
328
329 // ---------------------------------------------------------------------------
330
331 get (options: OverrideCommandOptions & {
332 userId: number
333 withStats?: boolean // default false
334 }) {
335 const { userId, withStats } = options
336 const path = '/api/v1/users/' + userId
337
338 return this.getRequestBody<User>({
339 ...options,
340
341 path,
342 query: { withStats },
343 implicitToken: true,
344 defaultExpectedStatus: HttpStatusCode.OK_200
345 })
346 }
347
348 list (options: OverrideCommandOptions & {
349 start?: number
350 count?: number
351 sort?: string
352 search?: string
353 blocked?: boolean
354 } = {}) {
355 const path = '/api/v1/users'
356
357 return this.getRequestBody<ResultList<User>>({
358 ...options,
359
360 path,
361 query: pick(options, [ 'start', 'count', 'sort', 'search', 'blocked' ]),
362 implicitToken: true,
363 defaultExpectedStatus: HttpStatusCode.OK_200
364 })
365 }
366
367 remove (options: OverrideCommandOptions & {
368 userId: number
369 }) {
370 const { userId } = options
371 const path = '/api/v1/users/' + userId
372
373 return this.deleteRequest({
374 ...options,
375
376 path,
377 implicitToken: true,
378 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
379 })
380 }
381
382 update (options: OverrideCommandOptions & {
383 userId: number
384 email?: string
385 emailVerified?: boolean
386 videoQuota?: number
387 videoQuotaDaily?: number
388 password?: string
389 adminFlags?: UserAdminFlag
390 pluginAuth?: string
391 role?: UserRole
392 }) {
393 const path = '/api/v1/users/' + options.userId
394
395 const toSend: UserUpdate = {}
396 if (options.password !== undefined && options.password !== null) toSend.password = options.password
397 if (options.email !== undefined && options.email !== null) toSend.email = options.email
398 if (options.emailVerified !== undefined && options.emailVerified !== null) toSend.emailVerified = options.emailVerified
399 if (options.videoQuota !== undefined && options.videoQuota !== null) toSend.videoQuota = options.videoQuota
400 if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend.videoQuotaDaily = options.videoQuotaDaily
401 if (options.role !== undefined && options.role !== null) toSend.role = options.role
402 if (options.adminFlags !== undefined && options.adminFlags !== null) toSend.adminFlags = options.adminFlags
403 if (options.pluginAuth !== undefined) toSend.pluginAuth = options.pluginAuth
404
405 return this.putBodyRequest({
406 ...options,
407
408 path,
409 fields: toSend,
410 implicitToken: true,
411 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
412 })
413 }
414}
diff --git a/shared/extra-utils/users/users.ts b/shared/extra-utils/users/users.ts
index 835ad08ba..6cf61d60e 100644
--- a/shared/extra-utils/users/users.ts
+++ b/shared/extra-utils/users/users.ts
@@ -1,118 +1,8 @@
1import { omit } from 'lodash'
2import * as request from 'supertest' 1import * as request from 'supertest'
3import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' 2import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
4import { UserUpdateMe } from '../../models/users'
5import { UserAdminFlag } from '../../models/users/user-flag.model'
6import { UserRegister } from '../../models/users/user-register.model'
7import { UserRole } from '../../models/users/user-role'
8import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateImageRequest } from '../requests/requests'
9import { ServerInfo } from '../server/servers'
10 3
11function createUser (parameters: { 4// FIXME: delete once videos does not use it anymore
12 url: string 5function xxxgetMyUserInformation (url: string, accessToken: string, specialStatus = HttpStatusCode.OK_200) {
13 accessToken: string
14 username: string
15 password: string
16 videoQuota?: number
17 videoQuotaDaily?: number
18 role?: UserRole
19 adminFlags?: UserAdminFlag
20 specialStatus?: number
21}) {
22 const {
23 url,
24 accessToken,
25 username,
26 adminFlags,
27 password = 'password',
28 videoQuota = 1000000,
29 videoQuotaDaily = -1,
30 role = UserRole.USER,
31 specialStatus = HttpStatusCode.OK_200
32 } = parameters
33
34 const path = '/api/v1/users'
35 const body = {
36 username,
37 password,
38 role,
39 adminFlags,
40 email: username + '@example.com',
41 videoQuota,
42 videoQuotaDaily
43 }
44
45 return request(url)
46 .post(path)
47 .set('Accept', 'application/json')
48 .set('Authorization', 'Bearer ' + accessToken)
49 .send(body)
50 .expect(specialStatus)
51}
52
53async function generateUser (server: ServerInfo, username: string) {
54 const password = 'my super password'
55 const resCreate = await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password })
56
57 const token = await server.loginCommand.getAccessToken({ username, password })
58
59 const resMe = await getMyUserInformation(server.url, token)
60
61 return {
62 token,
63 userId: resCreate.body.user.id,
64 userChannelId: resMe.body.videoChannels[0].id
65 }
66}
67
68async function generateUserAccessToken (server: ServerInfo, username: string) {
69 const password = 'my super password'
70 await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password })
71
72 return server.loginCommand.getAccessToken({ username, password })
73}
74
75function registerUser (url: string, username: string, password: string, specialStatus = HttpStatusCode.NO_CONTENT_204) {
76 const path = '/api/v1/users/register'
77 const body = {
78 username,
79 password,
80 email: username + '@example.com'
81 }
82
83 return request(url)
84 .post(path)
85 .set('Accept', 'application/json')
86 .send(body)
87 .expect(specialStatus)
88}
89
90function registerUserWithChannel (options: {
91 url: string
92 user: { username: string, password: string, displayName?: string }
93 channel: { name: string, displayName: string }
94}) {
95 const path = '/api/v1/users/register'
96 const body: UserRegister = {
97 username: options.user.username,
98 password: options.user.password,
99 email: options.user.username + '@example.com',
100 channel: options.channel
101 }
102
103 if (options.user.displayName) {
104 Object.assign(body, { displayName: options.user.displayName })
105 }
106
107 return makePostBodyRequest({
108 url: options.url,
109 path,
110 fields: body,
111 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
112 })
113}
114
115function getMyUserInformation (url: string, accessToken: string, specialStatus = HttpStatusCode.OK_200) {
116 const path = '/api/v1/users/me' 6 const path = '/api/v1/users/me'
117 7
118 return request(url) 8 return request(url)
@@ -123,292 +13,8 @@ function getMyUserInformation (url: string, accessToken: string, specialStatus =
123 .expect('Content-Type', /json/) 13 .expect('Content-Type', /json/)
124} 14}
125 15
126function getUserScopedTokens (url: string, token: string, statusCodeExpected = HttpStatusCode.OK_200) {
127 const path = '/api/v1/users/scoped-tokens'
128
129 return makeGetRequest({
130 url,
131 path,
132 token,
133 statusCodeExpected
134 })
135}
136
137function renewUserScopedTokens (url: string, token: string, statusCodeExpected = HttpStatusCode.OK_200) {
138 const path = '/api/v1/users/scoped-tokens'
139
140 return makePostBodyRequest({
141 url,
142 path,
143 token,
144 statusCodeExpected
145 })
146}
147
148function deleteMe (url: string, accessToken: string, specialStatus = HttpStatusCode.NO_CONTENT_204) {
149 const path = '/api/v1/users/me'
150
151 return request(url)
152 .delete(path)
153 .set('Accept', 'application/json')
154 .set('Authorization', 'Bearer ' + accessToken)
155 .expect(specialStatus)
156}
157
158function getMyUserVideoQuotaUsed (url: string, accessToken: string, specialStatus = HttpStatusCode.OK_200) {
159 const path = '/api/v1/users/me/video-quota-used'
160
161 return request(url)
162 .get(path)
163 .set('Accept', 'application/json')
164 .set('Authorization', 'Bearer ' + accessToken)
165 .expect(specialStatus)
166 .expect('Content-Type', /json/)
167}
168
169function getUserInformation (url: string, accessToken: string, userId: number, withStats = false) {
170 const path = '/api/v1/users/' + userId
171
172 return request(url)
173 .get(path)
174 .query({ withStats })
175 .set('Accept', 'application/json')
176 .set('Authorization', 'Bearer ' + accessToken)
177 .expect(HttpStatusCode.OK_200)
178 .expect('Content-Type', /json/)
179}
180
181function getMyUserVideoRating (url: string, accessToken: string, videoId: number | string, specialStatus = HttpStatusCode.OK_200) {
182 const path = '/api/v1/users/me/videos/' + videoId + '/rating'
183
184 return request(url)
185 .get(path)
186 .set('Accept', 'application/json')
187 .set('Authorization', 'Bearer ' + accessToken)
188 .expect(specialStatus)
189 .expect('Content-Type', /json/)
190}
191
192function getUsersList (url: string, accessToken: string) {
193 const path = '/api/v1/users'
194
195 return request(url)
196 .get(path)
197 .set('Accept', 'application/json')
198 .set('Authorization', 'Bearer ' + accessToken)
199 .expect(HttpStatusCode.OK_200)
200 .expect('Content-Type', /json/)
201}
202
203function getUsersListPaginationAndSort (
204 url: string,
205 accessToken: string,
206 start: number,
207 count: number,
208 sort: string,
209 search?: string,
210 blocked?: boolean
211) {
212 const path = '/api/v1/users'
213
214 const query = {
215 start,
216 count,
217 sort,
218 search,
219 blocked
220 }
221
222 return request(url)
223 .get(path)
224 .query(query)
225 .set('Accept', 'application/json')
226 .set('Authorization', 'Bearer ' + accessToken)
227 .expect(HttpStatusCode.OK_200)
228 .expect('Content-Type', /json/)
229}
230
231function removeUser (url: string, userId: number | string, accessToken: string, expectedStatus = HttpStatusCode.NO_CONTENT_204) {
232 const path = '/api/v1/users'
233
234 return request(url)
235 .delete(path + '/' + userId)
236 .set('Accept', 'application/json')
237 .set('Authorization', 'Bearer ' + accessToken)
238 .expect(expectedStatus)
239}
240
241function blockUser (
242 url: string,
243 userId: number | string,
244 accessToken: string,
245 expectedStatus = HttpStatusCode.NO_CONTENT_204,
246 reason?: string
247) {
248 const path = '/api/v1/users'
249 let body: any
250 if (reason) body = { reason }
251
252 return request(url)
253 .post(path + '/' + userId + '/block')
254 .send(body)
255 .set('Accept', 'application/json')
256 .set('Authorization', 'Bearer ' + accessToken)
257 .expect(expectedStatus)
258}
259
260function unblockUser (url: string, userId: number | string, accessToken: string, expectedStatus = HttpStatusCode.NO_CONTENT_204) {
261 const path = '/api/v1/users'
262
263 return request(url)
264 .post(path + '/' + userId + '/unblock')
265 .set('Accept', 'application/json')
266 .set('Authorization', 'Bearer ' + accessToken)
267 .expect(expectedStatus)
268}
269
270function updateMyUser (options: { url: string, accessToken: string, statusCodeExpected?: HttpStatusCode } & UserUpdateMe) {
271 const path = '/api/v1/users/me'
272
273 const toSend: UserUpdateMe = omit(options, 'url', 'accessToken')
274
275 return makePutBodyRequest({
276 url: options.url,
277 path,
278 token: options.accessToken,
279 fields: toSend,
280 statusCodeExpected: options.statusCodeExpected || HttpStatusCode.NO_CONTENT_204
281 })
282}
283
284function updateMyAvatar (options: {
285 url: string
286 accessToken: string
287 fixture: string
288}) {
289 const path = '/api/v1/users/me/avatar/pick'
290
291 return updateImageRequest({ ...options, path, fieldname: 'avatarfile' })
292}
293
294function updateUser (options: {
295 url: string
296 userId: number
297 accessToken: string
298 email?: string
299 emailVerified?: boolean
300 videoQuota?: number
301 videoQuotaDaily?: number
302 password?: string
303 adminFlags?: UserAdminFlag
304 pluginAuth?: string
305 role?: UserRole
306}) {
307 const path = '/api/v1/users/' + options.userId
308
309 const toSend = {}
310 if (options.password !== undefined && options.password !== null) toSend['password'] = options.password
311 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
312 if (options.emailVerified !== undefined && options.emailVerified !== null) toSend['emailVerified'] = options.emailVerified
313 if (options.videoQuota !== undefined && options.videoQuota !== null) toSend['videoQuota'] = options.videoQuota
314 if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily
315 if (options.role !== undefined && options.role !== null) toSend['role'] = options.role
316 if (options.adminFlags !== undefined && options.adminFlags !== null) toSend['adminFlags'] = options.adminFlags
317 if (options.pluginAuth !== undefined) toSend['pluginAuth'] = options.pluginAuth
318
319 return makePutBodyRequest({
320 url: options.url,
321 path,
322 token: options.accessToken,
323 fields: toSend,
324 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
325 })
326}
327
328function askResetPassword (url: string, email: string) {
329 const path = '/api/v1/users/ask-reset-password'
330
331 return makePostBodyRequest({
332 url,
333 path,
334 fields: { email },
335 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
336 })
337}
338
339function resetPassword (
340 url: string,
341 userId: number,
342 verificationString: string,
343 password: string,
344 statusCodeExpected = HttpStatusCode.NO_CONTENT_204
345) {
346 const path = '/api/v1/users/' + userId + '/reset-password'
347
348 return makePostBodyRequest({
349 url,
350 path,
351 fields: { password, verificationString },
352 statusCodeExpected
353 })
354}
355
356function askSendVerifyEmail (url: string, email: string) {
357 const path = '/api/v1/users/ask-send-verify-email'
358
359 return makePostBodyRequest({
360 url,
361 path,
362 fields: { email },
363 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
364 })
365}
366
367function verifyEmail (
368 url: string,
369 userId: number,
370 verificationString: string,
371 isPendingEmail = false,
372 statusCodeExpected = HttpStatusCode.NO_CONTENT_204
373) {
374 const path = '/api/v1/users/' + userId + '/verify-email'
375
376 return makePostBodyRequest({
377 url,
378 path,
379 fields: {
380 verificationString,
381 isPendingEmail
382 },
383 statusCodeExpected
384 })
385}
386
387// --------------------------------------------------------------------------- 16// ---------------------------------------------------------------------------
388 17
389export { 18export {
390 createUser, 19 xxxgetMyUserInformation
391 registerUser,
392 getMyUserInformation,
393 getMyUserVideoRating,
394 deleteMe,
395 registerUserWithChannel,
396 getMyUserVideoQuotaUsed,
397 getUsersList,
398 getUsersListPaginationAndSort,
399 removeUser,
400 updateUser,
401 updateMyUser,
402 getUserInformation,
403 blockUser,
404 unblockUser,
405 askResetPassword,
406 resetPassword,
407 renewUserScopedTokens,
408 updateMyAvatar,
409 generateUser,
410 askSendVerifyEmail,
411 generateUserAccessToken,
412 verifyEmail,
413 getUserScopedTokens
414} 20}
diff --git a/shared/extra-utils/videos/channels.ts b/shared/extra-utils/videos/channels.ts
index a77543c92..9e7ec565d 100644
--- a/shared/extra-utils/videos/channels.ts
+++ b/shared/extra-utils/videos/channels.ts
@@ -1,13 +1,11 @@
1import { User } from '../../models/users/user.model'
2import { ServerInfo } from '../server/servers' 1import { ServerInfo } from '../server/servers'
3import { getMyUserInformation } from '../users/users'
4 2
5function setDefaultVideoChannel (servers: ServerInfo[]) { 3function setDefaultVideoChannel (servers: ServerInfo[]) {
6 const tasks: Promise<any>[] = [] 4 const tasks: Promise<any>[] = []
7 5
8 for (const server of servers) { 6 for (const server of servers) {
9 const p = getMyUserInformation(server.url, server.accessToken) 7 const p = server.usersCommand.getMyInfo()
10 .then(res => { server.videoChannel = (res.body as User).videoChannels[0] }) 8 .then(user => { server.videoChannel = user.videoChannels[0] })
11 9
12 tasks.push(p) 10 tasks.push(p)
13 } 11 }
diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts
index 5dd71ce8b..5e20f8010 100644
--- a/shared/extra-utils/videos/videos.ts
+++ b/shared/extra-utils/videos/videos.ts
@@ -17,7 +17,7 @@ import { buildAbsoluteFixturePath, dateIsValid, testImage, wait, webtorrentAdd }
17import { makeGetRequest, makePutBodyRequest, makeRawRequest, makeUploadRequest } from '../requests/requests' 17import { makeGetRequest, makePutBodyRequest, makeRawRequest, makeUploadRequest } from '../requests/requests'
18import { waitJobs } from '../server/jobs' 18import { waitJobs } from '../server/jobs'
19import { ServerInfo } from '../server/servers' 19import { ServerInfo } from '../server/servers'
20import { getMyUserInformation } from '../users/users' 20import { xxxgetMyUserInformation } from '../users'
21 21
22loadLanguages() 22loadLanguages()
23 23
@@ -339,7 +339,7 @@ async function uploadVideo (
339 let defaultChannelId = '1' 339 let defaultChannelId = '1'
340 340
341 try { 341 try {
342 const res = await getMyUserInformation(url, accessToken) 342 const res = await xxxgetMyUserInformation(url, accessToken)
343 defaultChannelId = res.body.videoChannels[0].id 343 defaultChannelId = res.body.videoChannels[0].id
344 } catch (e) { /* empty */ } 344 } catch (e) { /* empty */ }
345 345
diff --git a/shared/models/users/index.ts b/shared/models/users/index.ts
index a9d578054..b61a8cd40 100644
--- a/shared/models/users/index.ts
+++ b/shared/models/users/index.ts
@@ -1,3 +1,4 @@
1export * from './user-create-result.model'
1export * from './user-create.model' 2export * from './user-create.model'
2export * from './user-flag.model' 3export * from './user-flag.model'
3export * from './user-login.model' 4export * from './user-login.model'
diff --git a/shared/models/users/user-create-result.model.ts b/shared/models/users/user-create-result.model.ts
new file mode 100644
index 000000000..835b241ed
--- /dev/null
+++ b/shared/models/users/user-create-result.model.ts
@@ -0,0 +1,7 @@
1export interface UserCreateResult {
2 id: number
3
4 account: {
5 id: number
6 }
7}