aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api
diff options
context:
space:
mode:
authorJosh Morel <morel.josh@hotmail.com>2018-08-31 03:18:19 -0400
committerChocobozzz <me@florianbigard.com>2018-08-31 09:18:19 +0200
commitd9eaee3939bf2e93e5d775d32bce77842201faba (patch)
treec115acb3611986b98f51b3addf29ebe66f63ee7f /server/controllers/api
parent04291e1ba44032165388758e993d385a10c1c5a1 (diff)
downloadPeerTube-d9eaee3939bf2e93e5d775d32bce77842201faba.tar.gz
PeerTube-d9eaee3939bf2e93e5d775d32bce77842201faba.tar.zst
PeerTube-d9eaee3939bf2e93e5d775d32bce77842201faba.zip
add user account email verificiation (#977)
* add user account email verificiation includes server and client code to: * enable verificationRequired via custom config * send verification email with registration * ask for verification email * verify via email * prevent login if not verified and required * conditional client links to ask for new verification email * allow login for verified=null these are users created when verification not required should still be able to login when verification is enabled * refactor email verifcation pr * change naming from verified to emailVerified * change naming from askVerifyEmail to askSendVerifyEmail * undo unrelated automatic prettier formatting on api/config * use redirectService for home * remove redundant success notification on email verified * revert test.yaml smpt host
Diffstat (limited to 'server/controllers/api')
-rw-r--r--server/controllers/api/config.ts16
-rw-r--r--server/controllers/api/users/index.ts47
2 files changed, 58 insertions, 5 deletions
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index 25ddd1fa6..6edbe4820 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -60,7 +60,8 @@ async function getConfig (req: express.Request, res: express.Response, next: exp
60 serverVersion: packageJSON.version, 60 serverVersion: packageJSON.version,
61 signup: { 61 signup: {
62 allowed, 62 allowed,
63 allowedForCurrentIP 63 allowedForCurrentIP,
64 requiresEmailVerification: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION
64 }, 65 },
65 transcoding: { 66 transcoding: {
66 enabledResolutions 67 enabledResolutions
@@ -159,12 +160,20 @@ async function updateCustomConfig (req: express.Request, res: express.Response,
159 toUpdate.transcoding.threads = parseInt('' + toUpdate.transcoding.threads, 10) 160 toUpdate.transcoding.threads = parseInt('' + toUpdate.transcoding.threads, 10)
160 161
161 // camelCase to snake_case key 162 // camelCase to snake_case key
162 const toUpdateJSON = omit(toUpdate, 'user.videoQuota', 'instance.defaultClientRoute', 'instance.shortDescription', 'cache.videoCaptions') 163 const toUpdateJSON = omit(
164 toUpdate,
165 'user.videoQuota',
166 'instance.defaultClientRoute',
167 'instance.shortDescription',
168 'cache.videoCaptions',
169 'signup.requiresEmailVerification'
170 )
163 toUpdateJSON.user['video_quota'] = toUpdate.user.videoQuota 171 toUpdateJSON.user['video_quota'] = toUpdate.user.videoQuota
164 toUpdateJSON.user['video_quota_daily'] = toUpdate.user.videoQuotaDaily 172 toUpdateJSON.user['video_quota_daily'] = toUpdate.user.videoQuotaDaily
165 toUpdateJSON.instance['default_client_route'] = toUpdate.instance.defaultClientRoute 173 toUpdateJSON.instance['default_client_route'] = toUpdate.instance.defaultClientRoute
166 toUpdateJSON.instance['short_description'] = toUpdate.instance.shortDescription 174 toUpdateJSON.instance['short_description'] = toUpdate.instance.shortDescription
167 toUpdateJSON.instance['default_nsfw_policy'] = toUpdate.instance.defaultNSFWPolicy 175 toUpdateJSON.instance['default_nsfw_policy'] = toUpdate.instance.defaultNSFWPolicy
176 toUpdateJSON.signup['requires_email_verification'] = toUpdate.signup.requiresEmailVerification
168 177
169 await writeJSON(CONFIG.CUSTOM_FILE, toUpdateJSON, { spaces: 2 }) 178 await writeJSON(CONFIG.CUSTOM_FILE, toUpdateJSON, { spaces: 2 })
170 179
@@ -220,7 +229,8 @@ function customConfig (): CustomConfig {
220 }, 229 },
221 signup: { 230 signup: {
222 enabled: CONFIG.SIGNUP.ENABLED, 231 enabled: CONFIG.SIGNUP.ENABLED,
223 limit: CONFIG.SIGNUP.LIMIT 232 limit: CONFIG.SIGNUP.LIMIT,
233 requiresEmailVerification: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION
224 }, 234 },
225 admin: { 235 admin: {
226 email: CONFIG.ADMIN.EMAIL 236 email: CONFIG.ADMIN.EMAIL
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts
index 25d51ae5e..008c34ca4 100644
--- a/server/controllers/api/users/index.ts
+++ b/server/controllers/api/users/index.ts
@@ -25,7 +25,10 @@ import {
25 usersSortValidator, 25 usersSortValidator,
26 usersUpdateValidator 26 usersUpdateValidator
27} from '../../../middlewares' 27} from '../../../middlewares'
28import { usersAskResetPasswordValidator, usersBlockingValidator, usersResetPasswordValidator } from '../../../middlewares/validators' 28import {
29 usersAskResetPasswordValidator, usersBlockingValidator, usersResetPasswordValidator,
30 usersAskSendVerifyEmailValidator, usersVerifyEmailValidator
31} from '../../../middlewares/validators'
29import { UserModel } from '../../../models/account/user' 32import { UserModel } from '../../../models/account/user'
30import { OAuthTokenModel } from '../../../models/oauth/oauth-token' 33import { OAuthTokenModel } from '../../../models/oauth/oauth-token'
31import { auditLoggerFactory, UserAuditView } from '../../../helpers/audit-logger' 34import { auditLoggerFactory, UserAuditView } from '../../../helpers/audit-logger'
@@ -110,6 +113,17 @@ usersRouter.post('/:id/reset-password',
110 asyncMiddleware(resetUserPassword) 113 asyncMiddleware(resetUserPassword)
111) 114)
112 115
116usersRouter.post('/ask-send-verify-email',
117 loginRateLimiter,
118 asyncMiddleware(usersAskSendVerifyEmailValidator),
119 asyncMiddleware(askSendVerifyUserEmail)
120)
121
122usersRouter.post('/:id/verify-email',
123 asyncMiddleware(usersVerifyEmailValidator),
124 asyncMiddleware(verifyUserEmail)
125)
126
113usersRouter.post('/token', 127usersRouter.post('/token',
114 loginRateLimiter, 128 loginRateLimiter,
115 token, 129 token,
@@ -165,7 +179,8 @@ async function registerUser (req: express.Request, res: express.Response) {
165 autoPlayVideo: true, 179 autoPlayVideo: true,
166 role: UserRole.USER, 180 role: UserRole.USER,
167 videoQuota: CONFIG.USER.VIDEO_QUOTA, 181 videoQuota: CONFIG.USER.VIDEO_QUOTA,
168 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY 182 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
183 emailVerified: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION ? false : null
169 }) 184 })
170 185
171 const { user } = await createUserAccountAndChannel(userToCreate) 186 const { user } = await createUserAccountAndChannel(userToCreate)
@@ -173,6 +188,10 @@ async function registerUser (req: express.Request, res: express.Response) {
173 auditLogger.create(body.username, new UserAuditView(user.toFormattedJSON())) 188 auditLogger.create(body.username, new UserAuditView(user.toFormattedJSON()))
174 logger.info('User %s with its channel and account registered.', body.username) 189 logger.info('User %s with its channel and account registered.', body.username)
175 190
191 if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) {
192 await sendVerifyUserEmail(user)
193 }
194
176 return res.type('json').status(204).end() 195 return res.type('json').status(204).end()
177} 196}
178 197
@@ -261,6 +280,30 @@ async function resetUserPassword (req: express.Request, res: express.Response, n
261 return res.status(204).end() 280 return res.status(204).end()
262} 281}
263 282
283async function sendVerifyUserEmail (user: UserModel) {
284 const verificationString = await Redis.Instance.setVerifyEmailVerificationString(user.id)
285 const url = CONFIG.WEBSERVER.URL + '/verify-account/email?userId=' + user.id + '&verificationString=' + verificationString
286 await Emailer.Instance.addVerifyEmailJob(user.email, url)
287 return
288}
289
290async function askSendVerifyUserEmail (req: express.Request, res: express.Response, next: express.NextFunction) {
291 const user = res.locals.user as UserModel
292
293 await sendVerifyUserEmail(user)
294
295 return res.status(204).end()
296}
297
298async function verifyUserEmail (req: express.Request, res: express.Response, next: express.NextFunction) {
299 const user = res.locals.user as UserModel
300 user.emailVerified = true
301
302 await user.save()
303
304 return res.status(204).end()
305}
306
264function success (req: express.Request, res: express.Response, next: express.NextFunction) { 307function success (req: express.Request, res: express.Response, next: express.NextFunction) {
265 res.end() 308 res.end()
266} 309}