diff options
Diffstat (limited to 'shared/server-commands')
-rw-r--r-- | shared/server-commands/miscs/sql-command.ts | 102 | ||||
-rw-r--r-- | shared/server-commands/requests/requests.ts | 2 | ||||
-rw-r--r-- | shared/server-commands/server/config-command.ts | 50 | ||||
-rw-r--r-- | shared/server-commands/server/server.ts | 3 | ||||
-rw-r--r-- | shared/server-commands/users/index.ts | 1 | ||||
-rw-r--r-- | shared/server-commands/users/registrations-command.ts | 151 | ||||
-rw-r--r-- | shared/server-commands/users/users-command.ts | 29 |
7 files changed, 243 insertions, 95 deletions
diff --git a/shared/server-commands/miscs/sql-command.ts b/shared/server-commands/miscs/sql-command.ts index 823fc9e38..35cc2253f 100644 --- a/shared/server-commands/miscs/sql-command.ts +++ b/shared/server-commands/miscs/sql-command.ts | |||
@@ -13,101 +13,87 @@ export class SQLCommand extends AbstractCommand { | |||
13 | return seq.query(`DELETE FROM "${table}"`, options) | 13 | return seq.query(`DELETE FROM "${table}"`, options) |
14 | } | 14 | } |
15 | 15 | ||
16 | async getCount (table: string) { | 16 | async getVideoShareCount () { |
17 | const seq = this.getSequelize() | 17 | const [ { total } ] = await this.selectQuery<{ total: string }>(`SELECT COUNT(*) as total FROM "videoShare"`) |
18 | |||
19 | const options = { type: QueryTypes.SELECT as QueryTypes.SELECT } | ||
20 | |||
21 | const [ { total } ] = await seq.query<{ total: string }>(`SELECT COUNT(*) as total FROM "${table}"`, options) | ||
22 | if (total === null) return 0 | 18 | if (total === null) return 0 |
23 | 19 | ||
24 | return parseInt(total, 10) | 20 | return parseInt(total, 10) |
25 | } | 21 | } |
26 | 22 | ||
27 | async getInternalFileUrl (fileId: number) { | 23 | async getInternalFileUrl (fileId: number) { |
28 | return this.selectQuery(`SELECT "fileUrl" FROM "videoFile" WHERE id = ${fileId}`) | 24 | return this.selectQuery<{ fileUrl: string }>(`SELECT "fileUrl" FROM "videoFile" WHERE id = :fileId`, { fileId }) |
29 | .then(rows => rows[0].fileUrl as string) | 25 | .then(rows => rows[0].fileUrl) |
30 | } | 26 | } |
31 | 27 | ||
32 | setActorField (to: string, field: string, value: string) { | 28 | setActorField (to: string, field: string, value: string) { |
33 | const seq = this.getSequelize() | 29 | return this.updateQuery(`UPDATE actor SET ${this.escapeColumnName(field)} = :value WHERE url = :to`, { value, to }) |
34 | |||
35 | const options = { type: QueryTypes.UPDATE } | ||
36 | |||
37 | return seq.query(`UPDATE actor SET "${field}" = '${value}' WHERE url = '${to}'`, options) | ||
38 | } | 30 | } |
39 | 31 | ||
40 | setVideoField (uuid: string, field: string, value: string) { | 32 | setVideoField (uuid: string, field: string, value: string) { |
41 | const seq = this.getSequelize() | 33 | return this.updateQuery(`UPDATE video SET ${this.escapeColumnName(field)} = :value WHERE uuid = :uuid`, { value, uuid }) |
42 | |||
43 | const options = { type: QueryTypes.UPDATE } | ||
44 | |||
45 | return seq.query(`UPDATE video SET "${field}" = '${value}' WHERE uuid = '${uuid}'`, options) | ||
46 | } | 34 | } |
47 | 35 | ||
48 | setPlaylistField (uuid: string, field: string, value: string) { | 36 | setPlaylistField (uuid: string, field: string, value: string) { |
49 | const seq = this.getSequelize() | 37 | return this.updateQuery(`UPDATE "videoPlaylist" SET ${this.escapeColumnName(field)} = :value WHERE uuid = :uuid`, { value, uuid }) |
50 | |||
51 | const options = { type: QueryTypes.UPDATE } | ||
52 | |||
53 | return seq.query(`UPDATE "videoPlaylist" SET "${field}" = '${value}' WHERE uuid = '${uuid}'`, options) | ||
54 | } | 38 | } |
55 | 39 | ||
56 | async countVideoViewsOf (uuid: string) { | 40 | async countVideoViewsOf (uuid: string) { |
57 | const seq = this.getSequelize() | ||
58 | |||
59 | const query = 'SELECT SUM("videoView"."views") AS "total" FROM "videoView" ' + | 41 | const query = 'SELECT SUM("videoView"."views") AS "total" FROM "videoView" ' + |
60 | `INNER JOIN "video" ON "video"."id" = "videoView"."videoId" WHERE "video"."uuid" = '${uuid}'` | 42 | `INNER JOIN "video" ON "video"."id" = "videoView"."videoId" WHERE "video"."uuid" = :uuid` |
61 | |||
62 | const options = { type: QueryTypes.SELECT as QueryTypes.SELECT } | ||
63 | const [ { total } ] = await seq.query<{ total: number }>(query, options) | ||
64 | 43 | ||
44 | const [ { total } ] = await this.selectQuery<{ total: number }>(query, { uuid }) | ||
65 | if (!total) return 0 | 45 | if (!total) return 0 |
66 | 46 | ||
67 | return forceNumber(total) | 47 | return forceNumber(total) |
68 | } | 48 | } |
69 | 49 | ||
70 | getActorImage (filename: string) { | 50 | getActorImage (filename: string) { |
71 | return this.selectQuery(`SELECT * FROM "actorImage" WHERE filename = '${filename}'`) | 51 | return this.selectQuery<{ width: number, height: number }>(`SELECT * FROM "actorImage" WHERE filename = :filename`, { filename }) |
72 | .then(rows => rows[0]) | 52 | .then(rows => rows[0]) |
73 | } | 53 | } |
74 | 54 | ||
75 | selectQuery (query: string) { | 55 | // --------------------------------------------------------------------------- |
76 | const seq = this.getSequelize() | ||
77 | const options = { type: QueryTypes.SELECT as QueryTypes.SELECT } | ||
78 | 56 | ||
79 | return seq.query<any>(query, options) | 57 | setPluginVersion (pluginName: string, newVersion: string) { |
58 | return this.setPluginField(pluginName, 'version', newVersion) | ||
80 | } | 59 | } |
81 | 60 | ||
82 | updateQuery (query: string) { | 61 | setPluginLatestVersion (pluginName: string, newVersion: string) { |
83 | const seq = this.getSequelize() | 62 | return this.setPluginField(pluginName, 'latestVersion', newVersion) |
84 | const options = { type: QueryTypes.UPDATE as QueryTypes.UPDATE } | 63 | } |
85 | 64 | ||
86 | return seq.query(query, options) | 65 | setPluginField (pluginName: string, field: string, value: string) { |
66 | return this.updateQuery( | ||
67 | `UPDATE "plugin" SET ${this.escapeColumnName(field)} = :value WHERE "name" = :pluginName`, | ||
68 | { pluginName, value } | ||
69 | ) | ||
87 | } | 70 | } |
88 | 71 | ||
89 | // --------------------------------------------------------------------------- | 72 | // --------------------------------------------------------------------------- |
90 | 73 | ||
91 | setPluginField (pluginName: string, field: string, value: string) { | 74 | selectQuery <T extends object> (query: string, replacements: { [id: string]: string | number } = {}) { |
92 | const seq = this.getSequelize() | 75 | const seq = this.getSequelize() |
76 | const options = { | ||
77 | type: QueryTypes.SELECT as QueryTypes.SELECT, | ||
78 | replacements | ||
79 | } | ||
93 | 80 | ||
94 | const options = { type: QueryTypes.UPDATE } | 81 | return seq.query<T>(query, options) |
95 | |||
96 | return seq.query(`UPDATE "plugin" SET "${field}" = '${value}' WHERE "name" = '${pluginName}'`, options) | ||
97 | } | 82 | } |
98 | 83 | ||
99 | setPluginVersion (pluginName: string, newVersion: string) { | 84 | updateQuery (query: string, replacements: { [id: string]: string | number } = {}) { |
100 | return this.setPluginField(pluginName, 'version', newVersion) | 85 | const seq = this.getSequelize() |
101 | } | 86 | const options = { type: QueryTypes.UPDATE as QueryTypes.UPDATE, replacements } |
102 | 87 | ||
103 | setPluginLatestVersion (pluginName: string, newVersion: string) { | 88 | return seq.query(query, options) |
104 | return this.setPluginField(pluginName, 'latestVersion', newVersion) | ||
105 | } | 89 | } |
106 | 90 | ||
107 | // --------------------------------------------------------------------------- | 91 | // --------------------------------------------------------------------------- |
108 | 92 | ||
109 | async getPlaylistInfohash (playlistId: number) { | 93 | async getPlaylistInfohash (playlistId: number) { |
110 | const result = await this.selectQuery('SELECT "p2pMediaLoaderInfohashes" FROM "videoStreamingPlaylist" WHERE id = ' + playlistId) | 94 | const query = 'SELECT "p2pMediaLoaderInfohashes" FROM "videoStreamingPlaylist" WHERE id = :playlistId' |
95 | |||
96 | const result = await this.selectQuery<{ p2pMediaLoaderInfohashes: string }>(query, { playlistId }) | ||
111 | if (!result || result.length === 0) return [] | 97 | if (!result || result.length === 0) return [] |
112 | 98 | ||
113 | return result[0].p2pMediaLoaderInfohashes | 99 | return result[0].p2pMediaLoaderInfohashes |
@@ -116,19 +102,14 @@ export class SQLCommand extends AbstractCommand { | |||
116 | // --------------------------------------------------------------------------- | 102 | // --------------------------------------------------------------------------- |
117 | 103 | ||
118 | setActorFollowScores (newScore: number) { | 104 | setActorFollowScores (newScore: number) { |
119 | const seq = this.getSequelize() | 105 | return this.updateQuery(`UPDATE "actorFollow" SET "score" = :newScore`, { newScore }) |
120 | |||
121 | const options = { type: QueryTypes.UPDATE } | ||
122 | |||
123 | return seq.query(`UPDATE "actorFollow" SET "score" = ${newScore}`, options) | ||
124 | } | 106 | } |
125 | 107 | ||
126 | setTokenField (accessToken: string, field: string, value: string) { | 108 | setTokenField (accessToken: string, field: string, value: string) { |
127 | const seq = this.getSequelize() | 109 | return this.updateQuery( |
128 | 110 | `UPDATE "oAuthToken" SET ${this.escapeColumnName(field)} = :value WHERE "accessToken" = :accessToken`, | |
129 | const options = { type: QueryTypes.UPDATE } | 111 | { value, accessToken } |
130 | 112 | ) | |
131 | return seq.query(`UPDATE "oAuthToken" SET "${field}" = '${value}' WHERE "accessToken" = '${accessToken}'`, options) | ||
132 | } | 113 | } |
133 | 114 | ||
134 | async cleanup () { | 115 | async cleanup () { |
@@ -157,4 +138,9 @@ export class SQLCommand extends AbstractCommand { | |||
157 | return this.sequelize | 138 | return this.sequelize |
158 | } | 139 | } |
159 | 140 | ||
141 | private escapeColumnName (columnName: string) { | ||
142 | return this.getSequelize().escape(columnName) | ||
143 | .replace(/^'/, '"') | ||
144 | .replace(/'$/, '"') | ||
145 | } | ||
160 | } | 146 | } |
diff --git a/shared/server-commands/requests/requests.ts b/shared/server-commands/requests/requests.ts index dc9cf4e01..cb0e1a5fb 100644 --- a/shared/server-commands/requests/requests.ts +++ b/shared/server-commands/requests/requests.ts | |||
@@ -199,7 +199,7 @@ function buildRequest (req: request.Test, options: CommonRequestParams) { | |||
199 | return req.expect((res) => { | 199 | return req.expect((res) => { |
200 | if (options.expectedStatus && res.status !== options.expectedStatus) { | 200 | if (options.expectedStatus && res.status !== options.expectedStatus) { |
201 | throw new Error(`Expected status ${options.expectedStatus}, got ${res.status}. ` + | 201 | throw new Error(`Expected status ${options.expectedStatus}, got ${res.status}. ` + |
202 | `\nThe server responded this error: "${res.body?.error ?? res.text}".\n` + | 202 | `\nThe server responded: "${res.body?.error ?? res.text}".\n` + |
203 | 'You may take a closer look at the logs. To see how to do so, check out this page: ' + | 203 | 'You may take a closer look at the logs. To see how to do so, check out this page: ' + |
204 | 'https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/development/tests.md#debug-server-logs') | 204 | 'https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/development/tests.md#debug-server-logs') |
205 | } | 205 | } |
diff --git a/shared/server-commands/server/config-command.ts b/shared/server-commands/server/config-command.ts index 1c2315ed1..eb6bb95a5 100644 --- a/shared/server-commands/server/config-command.ts +++ b/shared/server-commands/server/config-command.ts | |||
@@ -18,6 +18,33 @@ export class ConfigCommand extends AbstractCommand { | |||
18 | } | 18 | } |
19 | } | 19 | } |
20 | 20 | ||
21 | // --------------------------------------------------------------------------- | ||
22 | |||
23 | static getEmailOverrideConfig (emailPort: number) { | ||
24 | return { | ||
25 | smtp: { | ||
26 | hostname: '127.0.0.1', | ||
27 | port: emailPort | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | |||
32 | // --------------------------------------------------------------------------- | ||
33 | |||
34 | enableSignup (requiresApproval: boolean, limit = -1) { | ||
35 | return this.updateExistingSubConfig({ | ||
36 | newConfig: { | ||
37 | signup: { | ||
38 | enabled: true, | ||
39 | requiresApproval, | ||
40 | limit | ||
41 | } | ||
42 | } | ||
43 | }) | ||
44 | } | ||
45 | |||
46 | // --------------------------------------------------------------------------- | ||
47 | |||
21 | disableImports () { | 48 | disableImports () { |
22 | return this.setImportsEnabled(false) | 49 | return this.setImportsEnabled(false) |
23 | } | 50 | } |
@@ -44,6 +71,16 @@ export class ConfigCommand extends AbstractCommand { | |||
44 | }) | 71 | }) |
45 | } | 72 | } |
46 | 73 | ||
74 | // --------------------------------------------------------------------------- | ||
75 | |||
76 | enableChannelSync () { | ||
77 | return this.setChannelSyncEnabled(true) | ||
78 | } | ||
79 | |||
80 | disableChannelSync () { | ||
81 | return this.setChannelSyncEnabled(false) | ||
82 | } | ||
83 | |||
47 | private setChannelSyncEnabled (enabled: boolean) { | 84 | private setChannelSyncEnabled (enabled: boolean) { |
48 | return this.updateExistingSubConfig({ | 85 | return this.updateExistingSubConfig({ |
49 | newConfig: { | 86 | newConfig: { |
@@ -56,13 +93,7 @@ export class ConfigCommand extends AbstractCommand { | |||
56 | }) | 93 | }) |
57 | } | 94 | } |
58 | 95 | ||
59 | enableChannelSync () { | 96 | // --------------------------------------------------------------------------- |
60 | return this.setChannelSyncEnabled(true) | ||
61 | } | ||
62 | |||
63 | disableChannelSync () { | ||
64 | return this.setChannelSyncEnabled(false) | ||
65 | } | ||
66 | 97 | ||
67 | enableLive (options: { | 98 | enableLive (options: { |
68 | allowReplay?: boolean | 99 | allowReplay?: boolean |
@@ -142,6 +173,8 @@ export class ConfigCommand extends AbstractCommand { | |||
142 | }) | 173 | }) |
143 | } | 174 | } |
144 | 175 | ||
176 | // --------------------------------------------------------------------------- | ||
177 | |||
145 | enableStudio () { | 178 | enableStudio () { |
146 | return this.updateExistingSubConfig({ | 179 | return this.updateExistingSubConfig({ |
147 | newConfig: { | 180 | newConfig: { |
@@ -152,6 +185,8 @@ export class ConfigCommand extends AbstractCommand { | |||
152 | }) | 185 | }) |
153 | } | 186 | } |
154 | 187 | ||
188 | // --------------------------------------------------------------------------- | ||
189 | |||
155 | getConfig (options: OverrideCommandOptions = {}) { | 190 | getConfig (options: OverrideCommandOptions = {}) { |
156 | const path = '/api/v1/config' | 191 | const path = '/api/v1/config' |
157 | 192 | ||
@@ -304,6 +339,7 @@ export class ConfigCommand extends AbstractCommand { | |||
304 | signup: { | 339 | signup: { |
305 | enabled: false, | 340 | enabled: false, |
306 | limit: 5, | 341 | limit: 5, |
342 | requiresApproval: true, | ||
307 | requiresEmailVerification: false, | 343 | requiresEmailVerification: false, |
308 | minimumAge: 16 | 344 | minimumAge: 16 |
309 | }, | 345 | }, |
diff --git a/shared/server-commands/server/server.ts b/shared/server-commands/server/server.ts index ae1395a74..793fae3a8 100644 --- a/shared/server-commands/server/server.ts +++ b/shared/server-commands/server/server.ts | |||
@@ -18,6 +18,7 @@ import { | |||
18 | BlocklistCommand, | 18 | BlocklistCommand, |
19 | LoginCommand, | 19 | LoginCommand, |
20 | NotificationsCommand, | 20 | NotificationsCommand, |
21 | RegistrationsCommand, | ||
21 | SubscriptionsCommand, | 22 | SubscriptionsCommand, |
22 | TwoFactorCommand, | 23 | TwoFactorCommand, |
23 | UsersCommand | 24 | UsersCommand |
@@ -147,6 +148,7 @@ export class PeerTubeServer { | |||
147 | views?: ViewsCommand | 148 | views?: ViewsCommand |
148 | twoFactor?: TwoFactorCommand | 149 | twoFactor?: TwoFactorCommand |
149 | videoToken?: VideoTokenCommand | 150 | videoToken?: VideoTokenCommand |
151 | registrations?: RegistrationsCommand | ||
150 | 152 | ||
151 | constructor (options: { serverNumber: number } | { url: string }) { | 153 | constructor (options: { serverNumber: number } | { url: string }) { |
152 | if ((options as any).url) { | 154 | if ((options as any).url) { |
@@ -430,5 +432,6 @@ export class PeerTubeServer { | |||
430 | this.views = new ViewsCommand(this) | 432 | this.views = new ViewsCommand(this) |
431 | this.twoFactor = new TwoFactorCommand(this) | 433 | this.twoFactor = new TwoFactorCommand(this) |
432 | this.videoToken = new VideoTokenCommand(this) | 434 | this.videoToken = new VideoTokenCommand(this) |
435 | this.registrations = new RegistrationsCommand(this) | ||
433 | } | 436 | } |
434 | } | 437 | } |
diff --git a/shared/server-commands/users/index.ts b/shared/server-commands/users/index.ts index 1afc02dc1..404756539 100644 --- a/shared/server-commands/users/index.ts +++ b/shared/server-commands/users/index.ts | |||
@@ -4,6 +4,7 @@ export * from './blocklist-command' | |||
4 | export * from './login' | 4 | export * from './login' |
5 | export * from './login-command' | 5 | export * from './login-command' |
6 | export * from './notifications-command' | 6 | export * from './notifications-command' |
7 | export * from './registrations-command' | ||
7 | export * from './subscriptions-command' | 8 | export * from './subscriptions-command' |
8 | export * from './two-factor-command' | 9 | export * from './two-factor-command' |
9 | export * from './users-command' | 10 | export * from './users-command' |
diff --git a/shared/server-commands/users/registrations-command.ts b/shared/server-commands/users/registrations-command.ts new file mode 100644 index 000000000..f57f54b34 --- /dev/null +++ b/shared/server-commands/users/registrations-command.ts | |||
@@ -0,0 +1,151 @@ | |||
1 | import { pick } from '@shared/core-utils' | ||
2 | import { HttpStatusCode, ResultList, UserRegistration, UserRegistrationRequest, UserRegistrationUpdateState } from '@shared/models' | ||
3 | import { unwrapBody } from '../requests' | ||
4 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | ||
5 | |||
6 | export class RegistrationsCommand extends AbstractCommand { | ||
7 | |||
8 | register (options: OverrideCommandOptions & Partial<UserRegistrationRequest> & Pick<UserRegistrationRequest, 'username'>) { | ||
9 | const { password = 'password', email = options.username + '@example.com' } = options | ||
10 | const path = '/api/v1/users/register' | ||
11 | |||
12 | return this.postBodyRequest({ | ||
13 | ...options, | ||
14 | |||
15 | path, | ||
16 | fields: { | ||
17 | ...pick(options, [ 'username', 'displayName', 'channel' ]), | ||
18 | |||
19 | password, | ||
20 | |||
21 | }, | ||
22 | implicitToken: false, | ||
23 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
24 | }) | ||
25 | } | ||
26 | |||
27 | requestRegistration ( | ||
28 | options: OverrideCommandOptions & Partial<UserRegistrationRequest> & Pick<UserRegistrationRequest, 'username' | 'registrationReason'> | ||
29 | ) { | ||
30 | const { password = 'password', email = options.username + '@example.com' } = options | ||
31 | const path = '/api/v1/users/registrations/request' | ||
32 | |||
33 | return unwrapBody<UserRegistration>(this.postBodyRequest({ | ||
34 | ...options, | ||
35 | |||
36 | path, | ||
37 | fields: { | ||
38 | ...pick(options, [ 'username', 'displayName', 'channel', 'registrationReason' ]), | ||
39 | |||
40 | password, | ||
41 | |||
42 | }, | ||
43 | implicitToken: false, | ||
44 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
45 | })) | ||
46 | } | ||
47 | |||
48 | // --------------------------------------------------------------------------- | ||
49 | |||
50 | accept (options: OverrideCommandOptions & { id: number } & UserRegistrationUpdateState) { | ||
51 | const { id } = options | ||
52 | const path = '/api/v1/users/registrations/' + id + '/accept' | ||
53 | |||
54 | return this.postBodyRequest({ | ||
55 | ...options, | ||
56 | |||
57 | path, | ||
58 | fields: pick(options, [ 'moderationResponse', 'preventEmailDelivery' ]), | ||
59 | implicitToken: true, | ||
60 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
61 | }) | ||
62 | } | ||
63 | |||
64 | reject (options: OverrideCommandOptions & { id: number } & UserRegistrationUpdateState) { | ||
65 | const { id } = options | ||
66 | const path = '/api/v1/users/registrations/' + id + '/reject' | ||
67 | |||
68 | return this.postBodyRequest({ | ||
69 | ...options, | ||
70 | |||
71 | path, | ||
72 | fields: pick(options, [ 'moderationResponse', 'preventEmailDelivery' ]), | ||
73 | implicitToken: true, | ||
74 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
75 | }) | ||
76 | } | ||
77 | |||
78 | // --------------------------------------------------------------------------- | ||
79 | |||
80 | delete (options: OverrideCommandOptions & { | ||
81 | id: number | ||
82 | }) { | ||
83 | const { id } = options | ||
84 | const path = '/api/v1/users/registrations/' + id | ||
85 | |||
86 | return this.deleteRequest({ | ||
87 | ...options, | ||
88 | |||
89 | path, | ||
90 | implicitToken: true, | ||
91 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
92 | }) | ||
93 | } | ||
94 | |||
95 | // --------------------------------------------------------------------------- | ||
96 | |||
97 | list (options: OverrideCommandOptions & { | ||
98 | start?: number | ||
99 | count?: number | ||
100 | sort?: string | ||
101 | search?: string | ||
102 | } = {}) { | ||
103 | const path = '/api/v1/users/registrations' | ||
104 | |||
105 | return this.getRequestBody<ResultList<UserRegistration>>({ | ||
106 | ...options, | ||
107 | |||
108 | path, | ||
109 | query: pick(options, [ 'start', 'count', 'sort', 'search' ]), | ||
110 | implicitToken: true, | ||
111 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
112 | }) | ||
113 | } | ||
114 | |||
115 | // --------------------------------------------------------------------------- | ||
116 | |||
117 | askSendVerifyEmail (options: OverrideCommandOptions & { | ||
118 | email: string | ||
119 | }) { | ||
120 | const { email } = options | ||
121 | const path = '/api/v1/users/registrations/ask-send-verify-email' | ||
122 | |||
123 | return this.postBodyRequest({ | ||
124 | ...options, | ||
125 | |||
126 | path, | ||
127 | fields: { email }, | ||
128 | implicitToken: false, | ||
129 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
130 | }) | ||
131 | } | ||
132 | |||
133 | verifyEmail (options: OverrideCommandOptions & { | ||
134 | registrationId: number | ||
135 | verificationString: string | ||
136 | }) { | ||
137 | const { registrationId, verificationString } = options | ||
138 | const path = '/api/v1/users/registrations/' + registrationId + '/verify-email' | ||
139 | |||
140 | return this.postBodyRequest({ | ||
141 | ...options, | ||
142 | |||
143 | path, | ||
144 | fields: { | ||
145 | verificationString | ||
146 | }, | ||
147 | implicitToken: false, | ||
148 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
149 | }) | ||
150 | } | ||
151 | } | ||
diff --git a/shared/server-commands/users/users-command.ts b/shared/server-commands/users/users-command.ts index 811b9685b..8a42fafc8 100644 --- a/shared/server-commands/users/users-command.ts +++ b/shared/server-commands/users/users-command.ts | |||
@@ -214,35 +214,6 @@ export class UsersCommand extends AbstractCommand { | |||
214 | return this.server.login.getAccessToken({ username, password }) | 214 | return this.server.login.getAccessToken({ username, password }) |
215 | } | 215 | } |
216 | 216 | ||
217 | register (options: OverrideCommandOptions & { | ||
218 | username: string | ||
219 | password?: string | ||
220 | displayName?: string | ||
221 | email?: string | ||
222 | channel?: { | ||
223 | name: string | ||
224 | displayName: string | ||
225 | } | ||
226 | }) { | ||
227 | const { username, password = 'password', displayName, channel, email = username + '@example.com' } = options | ||
228 | const path = '/api/v1/users/register' | ||
229 | |||
230 | return this.postBodyRequest({ | ||
231 | ...options, | ||
232 | |||
233 | path, | ||
234 | fields: { | ||
235 | username, | ||
236 | password, | ||
237 | email, | ||
238 | displayName, | ||
239 | channel | ||
240 | }, | ||
241 | implicitToken: false, | ||
242 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
243 | }) | ||
244 | } | ||
245 | |||
246 | // --------------------------------------------------------------------------- | 217 | // --------------------------------------------------------------------------- |
247 | 218 | ||
248 | getMyInfo (options: OverrideCommandOptions = {}) { | 219 | getMyInfo (options: OverrideCommandOptions = {}) { |