aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/users/index.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-01-19 09:27:16 +0100
committerChocobozzz <chocobozzz@cpy.re>2023-01-19 13:53:40 +0100
commite364e31e25bd1d4b8d801c845a96d6be708f0a18 (patch)
tree220785a42af361706eb8243960c5da9cddf4d2be /server/controllers/api/users/index.ts
parentbc48e33b80f357767b98c1d310b04bdda24c6d46 (diff)
downloadPeerTube-e364e31e25bd1d4b8d801c845a96d6be708f0a18.tar.gz
PeerTube-e364e31e25bd1d4b8d801c845a96d6be708f0a18.tar.zst
PeerTube-e364e31e25bd1d4b8d801c845a96d6be708f0a18.zip
Implement signup approval in server
Diffstat (limited to 'server/controllers/api/users/index.ts')
-rw-r--r--server/controllers/api/users/index.ts99
1 files changed, 7 insertions, 92 deletions
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts
index a8677a1d3..5a5a12e82 100644
--- a/server/controllers/api/users/index.ts
+++ b/server/controllers/api/users/index.ts
@@ -4,26 +4,21 @@ import { Hooks } from '@server/lib/plugins/hooks'
4import { OAuthTokenModel } from '@server/models/oauth/oauth-token' 4import { OAuthTokenModel } from '@server/models/oauth/oauth-token'
5import { MUserAccountDefault } from '@server/types/models' 5import { MUserAccountDefault } from '@server/types/models'
6import { pick } from '@shared/core-utils' 6import { pick } from '@shared/core-utils'
7import { HttpStatusCode, UserCreate, UserCreateResult, UserRegister, UserRight, UserUpdate } from '@shared/models' 7import { HttpStatusCode, UserCreate, UserCreateResult, UserRight, UserUpdate } from '@shared/models'
8import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger' 8import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger'
9import { logger } from '../../../helpers/logger' 9import { logger } from '../../../helpers/logger'
10import { generateRandomString, getFormattedObjects } from '../../../helpers/utils' 10import { generateRandomString, getFormattedObjects } from '../../../helpers/utils'
11import { CONFIG } from '../../../initializers/config'
12import { WEBSERVER } from '../../../initializers/constants' 11import { WEBSERVER } from '../../../initializers/constants'
13import { sequelizeTypescript } from '../../../initializers/database' 12import { sequelizeTypescript } from '../../../initializers/database'
14import { Emailer } from '../../../lib/emailer' 13import { Emailer } from '../../../lib/emailer'
15import { Notifier } from '../../../lib/notifier'
16import { Redis } from '../../../lib/redis' 14import { Redis } from '../../../lib/redis'
17import { buildUser, createUserAccountAndChannelAndPlaylist, sendVerifyUserEmail } from '../../../lib/user' 15import { buildUser, createUserAccountAndChannelAndPlaylist } from '../../../lib/user'
18import { 16import {
19 adminUsersSortValidator, 17 adminUsersSortValidator,
20 asyncMiddleware, 18 asyncMiddleware,
21 asyncRetryTransactionMiddleware, 19 asyncRetryTransactionMiddleware,
22 authenticate, 20 authenticate,
23 buildRateLimiter,
24 ensureUserHasRight, 21 ensureUserHasRight,
25 ensureUserRegistrationAllowed,
26 ensureUserRegistrationAllowedForIP,
27 paginationValidator, 22 paginationValidator,
28 setDefaultPagination, 23 setDefaultPagination,
29 setDefaultSort, 24 setDefaultSort,
@@ -31,19 +26,17 @@ import {
31 usersAddValidator, 26 usersAddValidator,
32 usersGetValidator, 27 usersGetValidator,
33 usersListValidator, 28 usersListValidator,
34 usersRegisterValidator,
35 usersRemoveValidator, 29 usersRemoveValidator,
36 usersUpdateValidator 30 usersUpdateValidator
37} from '../../../middlewares' 31} from '../../../middlewares'
38import { 32import {
39 ensureCanModerateUser, 33 ensureCanModerateUser,
40 usersAskResetPasswordValidator, 34 usersAskResetPasswordValidator,
41 usersAskSendVerifyEmailValidator,
42 usersBlockingValidator, 35 usersBlockingValidator,
43 usersResetPasswordValidator, 36 usersResetPasswordValidator
44 usersVerifyEmailValidator
45} from '../../../middlewares/validators' 37} from '../../../middlewares/validators'
46import { UserModel } from '../../../models/user/user' 38import { UserModel } from '../../../models/user/user'
39import { emailVerificationRouter } from './email-verification'
47import { meRouter } from './me' 40import { meRouter } from './me'
48import { myAbusesRouter } from './my-abuses' 41import { myAbusesRouter } from './my-abuses'
49import { myBlocklistRouter } from './my-blocklist' 42import { myBlocklistRouter } from './my-blocklist'
@@ -51,22 +44,14 @@ import { myVideosHistoryRouter } from './my-history'
51import { myNotificationsRouter } from './my-notifications' 44import { myNotificationsRouter } from './my-notifications'
52import { mySubscriptionsRouter } from './my-subscriptions' 45import { mySubscriptionsRouter } from './my-subscriptions'
53import { myVideoPlaylistsRouter } from './my-video-playlists' 46import { myVideoPlaylistsRouter } from './my-video-playlists'
47import { registrationsRouter } from './registrations'
54import { twoFactorRouter } from './two-factor' 48import { twoFactorRouter } from './two-factor'
55 49
56const auditLogger = auditLoggerFactory('users') 50const auditLogger = auditLoggerFactory('users')
57 51
58const signupRateLimiter = buildRateLimiter({
59 windowMs: CONFIG.RATES_LIMIT.SIGNUP.WINDOW_MS,
60 max: CONFIG.RATES_LIMIT.SIGNUP.MAX,
61 skipFailedRequests: true
62})
63
64const askSendEmailLimiter = buildRateLimiter({
65 windowMs: CONFIG.RATES_LIMIT.ASK_SEND_EMAIL.WINDOW_MS,
66 max: CONFIG.RATES_LIMIT.ASK_SEND_EMAIL.MAX
67})
68
69const usersRouter = express.Router() 52const usersRouter = express.Router()
53usersRouter.use('/', emailVerificationRouter)
54usersRouter.use('/', registrationsRouter)
70usersRouter.use('/', twoFactorRouter) 55usersRouter.use('/', twoFactorRouter)
71usersRouter.use('/', tokensRouter) 56usersRouter.use('/', tokensRouter)
72usersRouter.use('/', myNotificationsRouter) 57usersRouter.use('/', myNotificationsRouter)
@@ -122,14 +107,6 @@ usersRouter.post('/',
122 asyncRetryTransactionMiddleware(createUser) 107 asyncRetryTransactionMiddleware(createUser)
123) 108)
124 109
125usersRouter.post('/register',
126 signupRateLimiter,
127 asyncMiddleware(ensureUserRegistrationAllowed),
128 ensureUserRegistrationAllowedForIP,
129 asyncMiddleware(usersRegisterValidator),
130 asyncRetryTransactionMiddleware(registerUser)
131)
132
133usersRouter.put('/:id', 110usersRouter.put('/:id',
134 authenticate, 111 authenticate,
135 ensureUserHasRight(UserRight.MANAGE_USERS), 112 ensureUserHasRight(UserRight.MANAGE_USERS),
@@ -156,17 +133,6 @@ usersRouter.post('/:id/reset-password',
156 asyncMiddleware(resetUserPassword) 133 asyncMiddleware(resetUserPassword)
157) 134)
158 135
159usersRouter.post('/ask-send-verify-email',
160 askSendEmailLimiter,
161 asyncMiddleware(usersAskSendVerifyEmailValidator),
162 asyncMiddleware(reSendVerifyUserEmail)
163)
164
165usersRouter.post('/:id/verify-email',
166 asyncMiddleware(usersVerifyEmailValidator),
167 asyncMiddleware(verifyUserEmail)
168)
169
170// --------------------------------------------------------------------------- 136// ---------------------------------------------------------------------------
171 137
172export { 138export {
@@ -218,35 +184,6 @@ async function createUser (req: express.Request, res: express.Response) {
218 }) 184 })
219} 185}
220 186
221async function registerUser (req: express.Request, res: express.Response) {
222 const body: UserRegister = req.body
223
224 const userToCreate = buildUser({
225 ...pick(body, [ 'username', 'password', 'email' ]),
226
227 emailVerified: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION ? false : null
228 })
229
230 const { user, account, videoChannel } = await createUserAccountAndChannelAndPlaylist({
231 userToCreate,
232 userDisplayName: body.displayName || undefined,
233 channelNames: body.channel
234 })
235
236 auditLogger.create(body.username, new UserAuditView(user.toFormattedJSON()))
237 logger.info('User %s with its channel and account registered.', body.username)
238
239 if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) {
240 await sendVerifyUserEmail(user)
241 }
242
243 Notifier.Instance.notifyOnNewUserRegistration(user)
244
245 Hooks.runAction('action:api.user.registered', { body, user, account, videoChannel, req, res })
246
247 return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end()
248}
249
250async function unblockUser (req: express.Request, res: express.Response) { 187async function unblockUser (req: express.Request, res: express.Response) {
251 const user = res.locals.user 188 const user = res.locals.user
252 189
@@ -360,28 +297,6 @@ async function resetUserPassword (req: express.Request, res: express.Response) {
360 return res.status(HttpStatusCode.NO_CONTENT_204).end() 297 return res.status(HttpStatusCode.NO_CONTENT_204).end()
361} 298}
362 299
363async function reSendVerifyUserEmail (req: express.Request, res: express.Response) {
364 const user = res.locals.user
365
366 await sendVerifyUserEmail(user)
367
368 return res.status(HttpStatusCode.NO_CONTENT_204).end()
369}
370
371async function verifyUserEmail (req: express.Request, res: express.Response) {
372 const user = res.locals.user
373 user.emailVerified = true
374
375 if (req.body.isPendingEmail === true) {
376 user.email = user.pendingEmail
377 user.pendingEmail = null
378 }
379
380 await user.save()
381
382 return res.status(HttpStatusCode.NO_CONTENT_204).end()
383}
384
385async function changeUserBlock (res: express.Response, user: MUserAccountDefault, block: boolean, reason?: string) { 300async function changeUserBlock (res: express.Response, user: MUserAccountDefault, block: boolean, reason?: string) {
386 const oldUserAuditView = new UserAuditView(user.toFormattedJSON()) 301 const oldUserAuditView = new UserAuditView(user.toFormattedJSON())
387 302