feat: plugin support to filter email addresses

Add support for plugins to filter user email addresses.
pull/6752/head
kontrollanten 2024-12-02 13:34:28 +01:00
parent 348161da6e
commit a875ee9f43
4 changed files with 28 additions and 8 deletions

View File

@ -140,7 +140,11 @@ export const serverFilterHookObject = {
// Peertube >= 5.2
'filter:feed.podcast.video.create-custom-tags.result': true,
// Peertube >= 6.1
'filter:api.user.me.get.result': true
'filter:api.user.me.get.result': true,
// Peertube >= 7.1
'filter:api.login.params': true,
'filter:api.email-verification.ask-send-email.params': true,
'filter:api.users.reset-password.params': true
}
export type ServerFilterHookName = keyof typeof serverFilterHookObject

View File

@ -17,6 +17,7 @@ import { sha1 } from '@peertube/peertube-node-utils'
import { HttpStatusCode, ServerErrorCode, UserRegistrationState } from '@peertube/peertube-models'
import { OTP } from '../../initializers/constants.js'
import { BypassLogin, getAccessToken, getClient, getRefreshToken, getUser, revokeToken, saveToken } from './oauth-model.js'
import { Hooks } from '../plugins/hooks.js'
class MissingTwoFactorError extends Error {
code = HttpStatusCode.UNAUTHORIZED_401
@ -135,7 +136,12 @@ async function handlePasswordGrant (options: {
client: MOAuthClient
bypassLogin?: BypassLogin
}) {
const { request, client, bypassLogin } = options
const { request, client } = options
const { bypassLogin, usernameOrEmail, password } = await Hooks.wrapObject({
bypassLogin: options.bypassLogin,
usernameOrEmail: request.body.username,
password: request.body.password
}, 'filter:api.login.params')
if (!request.body.username) {
throw new InvalidRequestError('Missing parameter: `username`')
@ -145,7 +151,7 @@ async function handlePasswordGrant (options: {
throw new InvalidRequestError('Missing parameter: `password`')
}
const user = await getUser(request.body.username, request.body.password, bypassLogin)
const user = await getUser(usernameOrEmail, password, bypassLogin)
if (!user) {
const registration = await UserRegistrationModel.loadByEmailOrUsername(request.body.username)

View File

@ -6,6 +6,7 @@ import { logger } from '../../../helpers/logger.js'
import { Redis } from '../../../lib/redis.js'
import { areValidationErrors, checkUserEmailExist, checkUserIdExist } from '../shared/index.js'
import { checkRegistrationEmailExist, checkRegistrationIdExist } from './shared/user-registrations.js'
import { Hooks } from '@server/lib/plugins/hooks.js'
const usersAskSendVerifyEmailValidator = [
body('email').isEmail().not().isEmpty().withMessage('Should have a valid email'),
@ -13,13 +14,17 @@ const usersAskSendVerifyEmailValidator = [
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return
const { email } = await Hooks.wrapObject({
email: req.body.email
}, 'filter:api.email-verification.ask-send-email.params')
const [ userExists, registrationExists ] = await Promise.all([
checkUserEmailExist(req.body.email, res, false),
checkRegistrationEmailExist(req.body.email, res, false)
checkUserEmailExist(email, res, false),
checkRegistrationEmailExist(email, res, false)
])
if (!userExists && !registrationExists) {
logger.debug('User or registration with email %s does not exist (asking verify email).', req.body.email)
logger.debug('User or registration with email %s does not exist (asking verify email).', email)
// Do not leak our emails
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}

View File

@ -39,6 +39,7 @@ import {
doesVideoExist,
isValidVideoIdParam
} from '../shared/index.js'
import { Hooks } from '@server/lib/plugins/hooks.js'
export const usersListValidator = [
query('blocked')
@ -334,9 +335,13 @@ export const usersAskResetPasswordValidator = [
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return
const exists = await checkUserEmailExist(req.body.email, res, false)
const { email } = await Hooks.wrapObject({
email: req.body.email
}, 'filter:api.users.reset-password.params')
const exists = await checkUserEmailExist(email, res, false)
if (!exists) {
logger.debug('User with email %s does not exist (asking reset password).', req.body.email)
logger.debug('User with email %s does not exist (asking reset password).', email)
// Do not leak our emails
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}