aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/server-commands/src/users/users-command.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server-commands/src/users/users-command.ts')
-rw-r--r--packages/server-commands/src/users/users-command.ts389
1 files changed, 389 insertions, 0 deletions
diff --git a/packages/server-commands/src/users/users-command.ts b/packages/server-commands/src/users/users-command.ts
new file mode 100644
index 000000000..d3b11939e
--- /dev/null
+++ b/packages/server-commands/src/users/users-command.ts
@@ -0,0 +1,389 @@
1import { omit, pick } from '@peertube/peertube-core-utils'
2import {
3 HttpStatusCode,
4 MyUser,
5 ResultList,
6 ScopedToken,
7 User,
8 UserAdminFlagType,
9 UserCreateResult,
10 UserRole,
11 UserRoleType,
12 UserUpdate,
13 UserUpdateMe,
14 UserVideoQuota,
15 UserVideoRate
16} from '@peertube/peertube-models'
17import { unwrapBody } from '../requests/index.js'
18import { AbstractCommand, OverrideCommandOptions } from '../shared/index.js'
19
20export class UsersCommand extends AbstractCommand {
21
22 askResetPassword (options: OverrideCommandOptions & {
23 email: string
24 }) {
25 const { email } = options
26 const path = '/api/v1/users/ask-reset-password'
27
28 return this.postBodyRequest({
29 ...options,
30
31 path,
32 fields: { email },
33 implicitToken: false,
34 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
35 })
36 }
37
38 resetPassword (options: OverrideCommandOptions & {
39 userId: number
40 verificationString: string
41 password: string
42 }) {
43 const { userId, verificationString, password } = options
44 const path = '/api/v1/users/' + userId + '/reset-password'
45
46 return this.postBodyRequest({
47 ...options,
48
49 path,
50 fields: { password, verificationString },
51 implicitToken: false,
52 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
53 })
54 }
55
56 // ---------------------------------------------------------------------------
57
58 askSendVerifyEmail (options: OverrideCommandOptions & {
59 email: string
60 }) {
61 const { email } = options
62 const path = '/api/v1/users/ask-send-verify-email'
63
64 return this.postBodyRequest({
65 ...options,
66
67 path,
68 fields: { email },
69 implicitToken: false,
70 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
71 })
72 }
73
74 verifyEmail (options: OverrideCommandOptions & {
75 userId: number
76 verificationString: string
77 isPendingEmail?: boolean // default false
78 }) {
79 const { userId, verificationString, isPendingEmail = false } = options
80 const path = '/api/v1/users/' + userId + '/verify-email'
81
82 return this.postBodyRequest({
83 ...options,
84
85 path,
86 fields: {
87 verificationString,
88 isPendingEmail
89 },
90 implicitToken: false,
91 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
92 })
93 }
94
95 // ---------------------------------------------------------------------------
96
97 banUser (options: OverrideCommandOptions & {
98 userId: number
99 reason?: string
100 }) {
101 const { userId, reason } = options
102 const path = '/api/v1/users' + '/' + userId + '/block'
103
104 return this.postBodyRequest({
105 ...options,
106
107 path,
108 fields: { reason },
109 implicitToken: true,
110 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
111 })
112 }
113
114 unbanUser (options: OverrideCommandOptions & {
115 userId: number
116 }) {
117 const { userId } = options
118 const path = '/api/v1/users' + '/' + userId + '/unblock'
119
120 return this.postBodyRequest({
121 ...options,
122
123 path,
124 implicitToken: true,
125 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
126 })
127 }
128
129 // ---------------------------------------------------------------------------
130
131 getMyScopedTokens (options: OverrideCommandOptions = {}) {
132 const path = '/api/v1/users/scoped-tokens'
133
134 return this.getRequestBody<ScopedToken>({
135 ...options,
136
137 path,
138 implicitToken: true,
139 defaultExpectedStatus: HttpStatusCode.OK_200
140 })
141 }
142
143 renewMyScopedTokens (options: OverrideCommandOptions = {}) {
144 const path = '/api/v1/users/scoped-tokens'
145
146 return this.postBodyRequest({
147 ...options,
148
149 path,
150 implicitToken: true,
151 defaultExpectedStatus: HttpStatusCode.OK_200
152 })
153 }
154
155 // ---------------------------------------------------------------------------
156
157 create (options: OverrideCommandOptions & {
158 username: string
159 password?: string
160 videoQuota?: number
161 videoQuotaDaily?: number
162 role?: UserRoleType
163 adminFlags?: UserAdminFlagType
164 }) {
165 const {
166 username,
167 adminFlags,
168 password = 'password',
169 videoQuota,
170 videoQuotaDaily,
171 role = UserRole.USER
172 } = options
173
174 const path = '/api/v1/users'
175
176 return unwrapBody<{ user: UserCreateResult }>(this.postBodyRequest({
177 ...options,
178
179 path,
180 fields: {
181 username,
182 password,
183 role,
184 adminFlags,
185 email: username + '@example.com',
186 videoQuota,
187 videoQuotaDaily
188 },
189 implicitToken: true,
190 defaultExpectedStatus: HttpStatusCode.OK_200
191 })).then(res => res.user)
192 }
193
194 async generate (username: string, role?: UserRoleType) {
195 const password = 'password'
196 const user = await this.create({ username, password, role })
197
198 const token = await this.server.login.getAccessToken({ username, password })
199
200 const me = await this.getMyInfo({ token })
201
202 return {
203 token,
204 userId: user.id,
205 userChannelId: me.videoChannels[0].id,
206 userChannelName: me.videoChannels[0].name,
207 password
208 }
209 }
210
211 async generateUserAndToken (username: string, role?: UserRoleType) {
212 const password = 'password'
213 await this.create({ username, password, role })
214
215 return this.server.login.getAccessToken({ username, password })
216 }
217
218 // ---------------------------------------------------------------------------
219
220 getMyInfo (options: OverrideCommandOptions = {}) {
221 const path = '/api/v1/users/me'
222
223 return this.getRequestBody<MyUser>({
224 ...options,
225
226 path,
227 implicitToken: true,
228 defaultExpectedStatus: HttpStatusCode.OK_200
229 })
230 }
231
232 getMyQuotaUsed (options: OverrideCommandOptions = {}) {
233 const path = '/api/v1/users/me/video-quota-used'
234
235 return this.getRequestBody<UserVideoQuota>({
236 ...options,
237
238 path,
239 implicitToken: true,
240 defaultExpectedStatus: HttpStatusCode.OK_200
241 })
242 }
243
244 getMyRating (options: OverrideCommandOptions & {
245 videoId: number | string
246 }) {
247 const { videoId } = options
248 const path = '/api/v1/users/me/videos/' + videoId + '/rating'
249
250 return this.getRequestBody<UserVideoRate>({
251 ...options,
252
253 path,
254 implicitToken: true,
255 defaultExpectedStatus: HttpStatusCode.OK_200
256 })
257 }
258
259 deleteMe (options: OverrideCommandOptions = {}) {
260 const path = '/api/v1/users/me'
261
262 return this.deleteRequest({
263 ...options,
264
265 path,
266 implicitToken: true,
267 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
268 })
269 }
270
271 updateMe (options: OverrideCommandOptions & UserUpdateMe) {
272 const path = '/api/v1/users/me'
273
274 const toSend: UserUpdateMe = omit(options, [ 'expectedStatus', 'token' ])
275
276 return this.putBodyRequest({
277 ...options,
278
279 path,
280 fields: toSend,
281 implicitToken: true,
282 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
283 })
284 }
285
286 updateMyAvatar (options: OverrideCommandOptions & {
287 fixture: string
288 }) {
289 const { fixture } = options
290 const path = '/api/v1/users/me/avatar/pick'
291
292 return this.updateImageRequest({
293 ...options,
294
295 path,
296 fixture,
297 fieldname: 'avatarfile',
298
299 implicitToken: true,
300 defaultExpectedStatus: HttpStatusCode.OK_200
301 })
302 }
303
304 // ---------------------------------------------------------------------------
305
306 get (options: OverrideCommandOptions & {
307 userId: number
308 withStats?: boolean // default false
309 }) {
310 const { userId, withStats } = options
311 const path = '/api/v1/users/' + userId
312
313 return this.getRequestBody<User>({
314 ...options,
315
316 path,
317 query: { withStats },
318 implicitToken: true,
319 defaultExpectedStatus: HttpStatusCode.OK_200
320 })
321 }
322
323 list (options: OverrideCommandOptions & {
324 start?: number
325 count?: number
326 sort?: string
327 search?: string
328 blocked?: boolean
329 } = {}) {
330 const path = '/api/v1/users'
331
332 return this.getRequestBody<ResultList<User>>({
333 ...options,
334
335 path,
336 query: pick(options, [ 'start', 'count', 'sort', 'search', 'blocked' ]),
337 implicitToken: true,
338 defaultExpectedStatus: HttpStatusCode.OK_200
339 })
340 }
341
342 remove (options: OverrideCommandOptions & {
343 userId: number
344 }) {
345 const { userId } = options
346 const path = '/api/v1/users/' + userId
347
348 return this.deleteRequest({
349 ...options,
350
351 path,
352 implicitToken: true,
353 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
354 })
355 }
356
357 update (options: OverrideCommandOptions & {
358 userId: number
359 email?: string
360 emailVerified?: boolean
361 videoQuota?: number
362 videoQuotaDaily?: number
363 password?: string
364 adminFlags?: UserAdminFlagType
365 pluginAuth?: string
366 role?: UserRoleType
367 }) {
368 const path = '/api/v1/users/' + options.userId
369
370 const toSend: UserUpdate = {}
371 if (options.password !== undefined && options.password !== null) toSend.password = options.password
372 if (options.email !== undefined && options.email !== null) toSend.email = options.email
373 if (options.emailVerified !== undefined && options.emailVerified !== null) toSend.emailVerified = options.emailVerified
374 if (options.videoQuota !== undefined && options.videoQuota !== null) toSend.videoQuota = options.videoQuota
375 if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend.videoQuotaDaily = options.videoQuotaDaily
376 if (options.role !== undefined && options.role !== null) toSend.role = options.role
377 if (options.adminFlags !== undefined && options.adminFlags !== null) toSend.adminFlags = options.adminFlags
378 if (options.pluginAuth !== undefined) toSend.pluginAuth = options.pluginAuth
379
380 return this.putBodyRequest({
381 ...options,
382
383 path,
384 fields: toSend,
385 implicitToken: true,
386 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
387 })
388 }
389}