From 92a266fc9e040e2c558a919e005b023a442e72a2 Mon Sep 17 00:00:00 2001 From: Milan Mertens Date: Mon, 13 May 2024 15:20:25 +0200 Subject: [PATCH] do not require email for signup with invite --- app/controllers/api/v1/users_controller.rb | 23 +++++++++++-------- .../users/authentication/Signup.jsx | 2 +- .../users/authentication/forms/SignupForm.jsx | 6 +++-- .../users/authentication/useSignUpForm.js | 22 ++++++++++-------- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index e891d596c9..687aa869bc 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -49,8 +49,19 @@ def create registration_method = SettingGetter.new(setting_name: 'RegistrationMethod', provider: current_provider).call - if registration_method == SiteSetting::REGISTRATION_METHODS[:invite] && !valid_invite_token && !admin_create - return render_error errors: Rails.configuration.custom_error_msgs[:invite_token_invalid] + if registration_method == SiteSetting::REGISTRATION_METHODS[:invite] && !admin_create + if create_user_params[:invite_token].blank? + return render_error errors: Rails.configuration.custom_error_msgs[:invite_token_invalid] + end + + invite = Invitation.find_by(provider: current_provider, token: create_user_params[:invite_token]) + if !invite.present? + return render_error errors: Rails.configuration.custom_error_msgs[:invite_token_invalid] + end + + create_user_params[:email] = invite.email + + invite.destroy end # TODO: Add proper error logging for non-verified token hcaptcha @@ -172,14 +183,6 @@ def update_user_params def change_password_params params.require(:user).permit(:old_password, :new_password) end - - def valid_invite_token - return false if create_user_params[:invite_token].blank? - - # Try to delete the invitation and return true if it succeeds - Invitation.destroy_by(email: create_user_params[:email].downcase, provider: current_provider, - token: create_user_params[:invite_token]).present? - end end end end diff --git a/app/javascript/components/users/authentication/Signup.jsx b/app/javascript/components/users/authentication/Signup.jsx index 7cbe8b3aa6..5c0d81a4a9 100644 --- a/app/javascript/components/users/authentication/Signup.jsx +++ b/app/javascript/components/users/authentication/Signup.jsx @@ -52,7 +52,7 @@ export default function Signup() { { t('authentication.create_an_account') } - + { t('authentication.already_have_account') } { t('authentication.sign_in') } diff --git a/app/javascript/components/users/authentication/forms/SignupForm.jsx b/app/javascript/components/users/authentication/forms/SignupForm.jsx index c59e2f2b8d..5702b6f2dc 100644 --- a/app/javascript/components/users/authentication/forms/SignupForm.jsx +++ b/app/javascript/components/users/authentication/forms/SignupForm.jsx @@ -24,9 +24,9 @@ import useCreateUser from '../../../../hooks/mutations/users/useCreateUser'; import useSignUpForm from '../../../../hooks/forms/users/authentication/useSignUpForm'; import HCaptcha from '../../../shared_components/utilities/HCaptcha'; -export default function SignupForm() { +export default function SignupForm({registrationMethod}) { const { t } = useTranslation(); - const { fields, methods } = useSignUpForm(); + const { fields, methods } = useSignUpForm(registrationMethod); const createUserAPI = useCreateUser(); const captchaRef = useRef(null); @@ -40,7 +40,9 @@ export default function SignupForm() { return (
+ { registrationMethod !== 'invite' && ( + )} diff --git a/app/javascript/hooks/forms/users/authentication/useSignUpForm.js b/app/javascript/hooks/forms/users/authentication/useSignUpForm.js index 22ed756045..642bd91477 100644 --- a/app/javascript/hooks/forms/users/authentication/useSignUpForm.js +++ b/app/javascript/hooks/forms/users/authentication/useSignUpForm.js @@ -20,16 +20,12 @@ import { useTranslation } from 'react-i18next'; import { useForm } from 'react-hook-form'; import { useCallback, useMemo } from 'react'; -export function useSignUpFormValidation() { - return useMemo(() => (yup.object({ +export function useSignUpFormValidation(registrationMethod) { + const spec = { name: yup.string().required('forms.validations.full_name.required') .min(2, 'forms.validations.full_name.min') .max(255, 'forms.validations.full_name.max'), - email: yup.string().required('forms.validations.email.required').email('forms.validations.email.email') - .min(6, 'forms.validations.email.min') - .max(255, 'forms.validations.email.max'), - password: yup.string().max(255, 'forms.validations.password.max') .matches( /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[`@%~!#£$\\^&*()\][+={}/|:;"'<>\-,.?_ ]).{8,}$/, @@ -42,10 +38,18 @@ export function useSignUpFormValidation() { .test('oneSymbol', 'forms.validations.password.symbol', (pwd) => pwd.match(/[`@%~!#£$\\^&*()\][+={}/|:;"'<>\-,.?_ ]/)), password_confirmation: yup.string().required('forms.validations.password_confirmation.required') .oneOf([yup.ref('password')], 'forms.validations.password_confirmation.match'), - })), []); + } + + if (registrationMethod !== 'invite') { + spec.email = yup.string().required('forms.validations.email.required').email('forms.validations.email.email') + .min(6, 'forms.validations.email.min') + .max(255, 'forms.validations.email.max') + } + + return useMemo(() => (yup.object(spec)), []); } -export default function useSignUpForm({ defaultValues: _defaultValues, ..._config } = {}) { +export default function useSignUpForm(registrationMethod, { defaultValues: _defaultValues, ..._config } = {}) { const { t, i18n } = useTranslation(); const fields = useMemo(() => ({ @@ -89,7 +93,7 @@ export default function useSignUpForm({ defaultValues: _defaultValues, ..._confi }, }), [i18n.resolvedLanguage]); - const validationSchema = useSignUpFormValidation(); + const validationSchema = useSignUpFormValidation(registrationMethod); const config = useMemo(() => ({ ...{