]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/auth/oauth.ts
Implement signup approval in server
[github/Chocobozzz/PeerTube.git] / server / lib / auth / oauth.ts
index bc0d4301f082519a02a666d279c0e6bf5ad8c431..887c4f7c9449ca7d9f4adb2ae8afb8e59a3a688a 100644 (file)
@@ -10,20 +10,32 @@ import OAuth2Server, {
 } from '@node-oauth/oauth2-server'
 import { randomBytesPromise } from '@server/helpers/core-utils'
 import { isOTPValid } from '@server/helpers/otp'
+import { CONFIG } from '@server/initializers/config'
+import { UserRegistrationModel } from '@server/models/user/user-registration'
 import { MOAuthClient } from '@server/types/models'
 import { sha1 } from '@shared/extra-utils'
-import { HttpStatusCode } from '@shared/models'
-import { OAUTH_LIFETIME, OTP } from '../../initializers/constants'
+import { HttpStatusCode, ServerErrorCode, UserRegistrationState } from '@shared/models'
+import { OTP } from '../../initializers/constants'
 import { BypassLogin, getClient, getRefreshToken, getUser, revokeToken, saveToken } from './oauth-model'
 
 class MissingTwoFactorError extends Error {
   code = HttpStatusCode.UNAUTHORIZED_401
-  name = 'missing_two_factor'
+  name = ServerErrorCode.MISSING_TWO_FACTOR
 }
 
 class InvalidTwoFactorError extends Error {
   code = HttpStatusCode.BAD_REQUEST_400
-  name = 'invalid_two_factor'
+  name = ServerErrorCode.INVALID_TWO_FACTOR
+}
+
+class RegistrationWaitingForApproval extends Error {
+  code = HttpStatusCode.BAD_REQUEST_400
+  name = ServerErrorCode.ACCOUNT_WAITING_FOR_APPROVAL
+}
+
+class RegistrationApprovalRejected extends Error {
+  code = HttpStatusCode.BAD_REQUEST_400
+  name = ServerErrorCode.ACCOUNT_APPROVAL_REJECTED
 }
 
 /**
@@ -32,8 +44,9 @@ class InvalidTwoFactorError extends Error {
  *
  */
 const oAuthServer = new OAuth2Server({
-  accessTokenLifetime: OAUTH_LIFETIME.ACCESS_TOKEN,
-  refreshTokenLifetime: OAUTH_LIFETIME.REFRESH_TOKEN,
+  // Wants seconds
+  accessTokenLifetime: CONFIG.OAUTH2.TOKEN_LIFETIME.ACCESS_TOKEN / 1000,
+  refreshTokenLifetime: CONFIG.OAUTH2.TOKEN_LIFETIME.REFRESH_TOKEN / 1000,
 
   // See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications
   model: require('./oauth-model')
@@ -126,7 +139,17 @@ async function handlePasswordGrant (options: {
   }
 
   const user = await getUser(request.body.username, request.body.password, bypassLogin)
-  if (!user) throw new InvalidGrantError('Invalid grant: user credentials are invalid')
+  if (!user) {
+    const registration = await UserRegistrationModel.loadByEmailOrUsername(request.body.username)
+
+    if (registration?.state === UserRegistrationState.REJECTED) {
+      throw new RegistrationApprovalRejected('Registration approval for this account has been rejected')
+    } else if (registration?.state === UserRegistrationState.PENDING) {
+      throw new RegistrationWaitingForApproval('Registration for this account is awaiting approval')
+    }
+
+    throw new InvalidGrantError('Invalid grant: user credentials are invalid')
+  }
 
   if (user.otpSecret) {
     if (!request.headers[OTP.HEADER_NAME]) {
@@ -182,10 +205,10 @@ function generateRandomToken () {
 
 function getTokenExpiresAt (type: 'access' | 'refresh') {
   const lifetime = type === 'access'
-    ? OAUTH_LIFETIME.ACCESS_TOKEN
-    : OAUTH_LIFETIME.REFRESH_TOKEN
+    ? CONFIG.OAUTH2.TOKEN_LIFETIME.ACCESS_TOKEN
+    : CONFIG.OAUTH2.TOKEN_LIFETIME.REFRESH_TOKEN
 
-  return new Date(Date.now() + lifetime * 1000)
+  return new Date(Date.now() + lifetime)
 }
 
 async function buildToken () {