From 590bf506ac6afd28dc6b4aae780c98e5cdd7f36a Mon Sep 17 00:00:00 2001 From: yu-i-i Date: Thu, 9 Jul 2026 18:20:33 +0200 Subject: [PATCH] Admin tools: handle bad SMTP configuration error on account creation --- .../app/src/Features/Email/EmailSender.mjs | 1 + .../app/src/UserListController.mjs | 18 ++++++++++++----- .../modal-content-new-user-form.tsx | 20 +++++++++++++++---- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/services/web/app/src/Features/Email/EmailSender.mjs b/services/web/app/src/Features/Email/EmailSender.mjs index 117d19d77c..6a275d0193 100644 --- a/services/web/app/src/Features/Email/EmailSender.mjs +++ b/services/web/app/src/Features/Email/EmailSender.mjs @@ -77,6 +77,7 @@ function getClient() { } async function sendEmail(options, emailType) { +console.log("EMAIL_SETTINGS = ", EMAIL_SETTINGS) try { const canContinue = await checkCanSendEmail(options) metrics.inc('email_status', { diff --git a/services/web/modules/admin-tools/app/src/UserListController.mjs b/services/web/modules/admin-tools/app/src/UserListController.mjs index f8b61ac952..8db559b311 100644 --- a/services/web/modules/admin-tools/app/src/UserListController.mjs +++ b/services/web/modules/admin-tools/app/src/UserListController.mjs @@ -59,7 +59,7 @@ async function _sendActivationEmail(idString) { .catch(error => { throw new OError('Failed to send activation email', { error: error.message, email: user.email }) }) - return setNewPasswordUrl + return } function cleanupSession(req) { @@ -112,6 +112,7 @@ async function registerNewUser(req, res, next) { req.body.analyticsId = crypto.randomUUID() let user + let emailIsNotSent = false try { user = await UserRegistrationHandler.promises.registerNewUser(req.body) } catch (err) { @@ -141,10 +142,17 @@ async function registerNewUser(req, res, next) { } if (isExternal) { update.$unset = { hashedPassword: "" } - } else { - await _sendActivationEmail(user._id.toString()) } await User.updateOne({ _id: user._id }, update).exec() + + if (!isExternal) { + try { + await _sendActivationEmail(user._id.toString()) + } catch (error) { + logger.warn({ error }) + emailIsNotSent = true + } + } } catch (err) { OError.tag(err, 'error finishing user registration', { email: user.email, @@ -155,7 +163,7 @@ async function registerNewUser(req, res, next) { const authMethods = isExternal ? [] : ['local'] const { id, first_name, last_name, signUpDate } = user const newUser = { id, email, firstName: first_name, lastName: last_name, isAdmin, signUpDate, inactive: true, deleted: false, authMethods } - res.json({ user: newUser }) + res.json({ user: newUser, emailIsNotSent }) } async function sendActivationEmail(req, res, next) { @@ -164,7 +172,7 @@ async function sendActivationEmail(req, res, next) { await _sendActivationEmail(userId) } catch (err) { logger.warn({ err }) - return HttpErrorHandler.unprocessableEntity(req, res, 'Error sending activation email') + return HttpErrorHandler.unprocessableEntity(req, res, 'Error sending activation email. Please check your SMTP configuration.') } res.sendStatus(200) } diff --git a/services/web/modules/admin-tools/frontend/js/user-list/components/create-account-button/modal-content-new-user-form.tsx b/services/web/modules/admin-tools/frontend/js/user-list/components/create-account-button/modal-content-new-user-form.tsx index a785b328cf..c3055188a3 100644 --- a/services/web/modules/admin-tools/frontend/js/user-list/components/create-account-button/modal-content-new-user-form.tsx +++ b/services/web/modules/admin-tools/frontend/js/user-list/components/create-account-button/modal-content-new-user-form.tsx @@ -50,7 +50,7 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) { const { refreshUsers, addUserToView } = useUserListContext() const [redirecting, setRedirecting] = useState(false) - const { isLoading, isError, error, runAsync } = useAsync() + const { data, isLoading, error, runAsync } = useAsync() const createAccount = () => { runAsync( @@ -66,7 +66,9 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) { ) .then(data => { addUserToView(data.user) - handleCloseModal() + if (!data.emailIsNotSent) { + handleCloseModal() + } }) .catch(debugConsole.error) } @@ -93,7 +95,7 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) { - {isError && ( + {error && (
)} + {data?.emailIsNotSent && ( +
+ +
+ )} @@ -181,7 +191,9 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) { disabled={userData.email.trim() === '' || userData.lastName.trim() === '' || userData.firstName.trim() === '' || - isLoading || redirecting} + isLoading || redirecting || + data?.emailIsNotSent || + (error && error.info?.statusCode !== 409)} isLoading={isLoading} loadingLabel={t('creating')} >