diff options
author | Josh Morel <morel.josh@hotmail.com> | 2018-08-31 03:18:19 -0400 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-08-31 09:18:19 +0200 |
commit | d9eaee3939bf2e93e5d775d32bce77842201faba (patch) | |
tree | c115acb3611986b98f51b3addf29ebe66f63ee7f /server/lib | |
parent | 04291e1ba44032165388758e993d385a10c1c5a1 (diff) | |
download | PeerTube-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/lib')
-rw-r--r-- | server/lib/emailer.ts | 17 | ||||
-rw-r--r-- | server/lib/oauth-model.ts | 5 | ||||
-rw-r--r-- | server/lib/redis.ts | 18 |
3 files changed, 39 insertions, 1 deletions
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts index bf8e5b6c3..9327792fb 100644 --- a/server/lib/emailer.ts +++ b/server/lib/emailer.ts | |||
@@ -89,6 +89,23 @@ class Emailer { | |||
89 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | 89 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) |
90 | } | 90 | } |
91 | 91 | ||
92 | addVerifyEmailJob (to: string, verifyEmailUrl: string) { | ||
93 | const text = `Welcome to PeerTube,\n\n` + | ||
94 | `To start using PeerTube on ${CONFIG.WEBSERVER.HOST} you must verify your email! ` + | ||
95 | `Please follow this link to verify this email belongs to you: ${verifyEmailUrl}\n\n` + | ||
96 | `If you are not the person who initiated this request, please ignore this email.\n\n` + | ||
97 | `Cheers,\n` + | ||
98 | `PeerTube.` | ||
99 | |||
100 | const emailPayload: EmailPayload = { | ||
101 | to: [ to ], | ||
102 | subject: 'Verify your PeerTube email', | ||
103 | text | ||
104 | } | ||
105 | |||
106 | return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) | ||
107 | } | ||
108 | |||
92 | async addVideoAbuseReportJob (videoId: number) { | 109 | async addVideoAbuseReportJob (videoId: number) { |
93 | const video = await VideoModel.load(videoId) | 110 | const video = await VideoModel.load(videoId) |
94 | if (!video) throw new Error('Unknown Video id during Abuse report.') | 111 | if (!video) throw new Error('Unknown Video id during Abuse report.') |
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts index 09eaf75d1..2f8667e19 100644 --- a/server/lib/oauth-model.ts +++ b/server/lib/oauth-model.ts | |||
@@ -3,6 +3,7 @@ import { logger } from '../helpers/logger' | |||
3 | import { UserModel } from '../models/account/user' | 3 | import { UserModel } from '../models/account/user' |
4 | import { OAuthClientModel } from '../models/oauth/oauth-client' | 4 | import { OAuthClientModel } from '../models/oauth/oauth-client' |
5 | import { OAuthTokenModel } from '../models/oauth/oauth-token' | 5 | import { OAuthTokenModel } from '../models/oauth/oauth-token' |
6 | import { CONFIG } from '../initializers/constants' | ||
6 | 7 | ||
7 | type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date } | 8 | type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date } |
8 | 9 | ||
@@ -37,6 +38,10 @@ async function getUser (usernameOrEmail: string, password: string) { | |||
37 | 38 | ||
38 | if (user.blocked) throw new AccessDeniedError('User is blocked.') | 39 | if (user.blocked) throw new AccessDeniedError('User is blocked.') |
39 | 40 | ||
41 | if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION && user.emailVerified === false) { | ||
42 | throw new AccessDeniedError('User email is not verified.') | ||
43 | } | ||
44 | |||
40 | return user | 45 | return user |
41 | } | 46 | } |
42 | 47 | ||
diff --git a/server/lib/redis.ts b/server/lib/redis.ts index 0b4b41e4e..e4e435659 100644 --- a/server/lib/redis.ts +++ b/server/lib/redis.ts | |||
@@ -2,7 +2,7 @@ import * as express from 'express' | |||
2 | import { createClient, RedisClient } from 'redis' | 2 | import { createClient, RedisClient } from 'redis' |
3 | import { logger } from '../helpers/logger' | 3 | import { logger } from '../helpers/logger' |
4 | import { generateRandomString } from '../helpers/utils' | 4 | import { generateRandomString } from '../helpers/utils' |
5 | import { CONFIG, USER_PASSWORD_RESET_LIFETIME, VIDEO_VIEW_LIFETIME } from '../initializers' | 5 | import { CONFIG, USER_PASSWORD_RESET_LIFETIME, USER_EMAIL_VERIFY_LIFETIME, VIDEO_VIEW_LIFETIME } from '../initializers' |
6 | 6 | ||
7 | type CachedRoute = { | 7 | type CachedRoute = { |
8 | body: string, | 8 | body: string, |
@@ -60,6 +60,18 @@ class Redis { | |||
60 | return this.getValue(this.generateResetPasswordKey(userId)) | 60 | return this.getValue(this.generateResetPasswordKey(userId)) |
61 | } | 61 | } |
62 | 62 | ||
63 | async setVerifyEmailVerificationString (userId: number) { | ||
64 | const generatedString = await generateRandomString(32) | ||
65 | |||
66 | await this.setValue(this.generateVerifyEmailKey(userId), generatedString, USER_EMAIL_VERIFY_LIFETIME) | ||
67 | |||
68 | return generatedString | ||
69 | } | ||
70 | |||
71 | async getVerifyEmailLink (userId: number) { | ||
72 | return this.getValue(this.generateVerifyEmailKey(userId)) | ||
73 | } | ||
74 | |||
63 | setIPVideoView (ip: string, videoUUID: string) { | 75 | setIPVideoView (ip: string, videoUUID: string) { |
64 | return this.setValue(this.buildViewKey(ip, videoUUID), '1', VIDEO_VIEW_LIFETIME) | 76 | return this.setValue(this.buildViewKey(ip, videoUUID), '1', VIDEO_VIEW_LIFETIME) |
65 | } | 77 | } |
@@ -135,6 +147,10 @@ class Redis { | |||
135 | return 'reset-password-' + userId | 147 | return 'reset-password-' + userId |
136 | } | 148 | } |
137 | 149 | ||
150 | generateVerifyEmailKey (userId: number) { | ||
151 | return 'verify-email-' + userId | ||
152 | } | ||
153 | |||
138 | buildViewKey (ip: string, videoUUID: string) { | 154 | buildViewKey (ip: string, videoUUID: string) { |
139 | return videoUUID + '-' + ip | 155 | return videoUUID + '-' + ip |
140 | } | 156 | } |