Admin tools: handle bad SMTP configuration error on account creation

This commit is contained in:
yu-i-i
2026-09-22 02:41:43 +02:00
parent 539e155d6b
commit 590bf506ac
3 changed files with 30 additions and 9 deletions
@@ -77,6 +77,7 @@ function getClient() {
} }
async function sendEmail(options, emailType) { async function sendEmail(options, emailType) {
console.log("EMAIL_SETTINGS = ", EMAIL_SETTINGS)
try { try {
const canContinue = await checkCanSendEmail(options) const canContinue = await checkCanSendEmail(options)
metrics.inc('email_status', { metrics.inc('email_status', {
@@ -59,7 +59,7 @@ async function _sendActivationEmail(idString) {
.catch(error => { .catch(error => {
throw new OError('Failed to send activation email', { error: error.message, email: user.email }) throw new OError('Failed to send activation email', { error: error.message, email: user.email })
}) })
return setNewPasswordUrl return
} }
function cleanupSession(req) { function cleanupSession(req) {
@@ -112,6 +112,7 @@ async function registerNewUser(req, res, next) {
req.body.analyticsId = crypto.randomUUID() req.body.analyticsId = crypto.randomUUID()
let user let user
let emailIsNotSent = false
try { try {
user = await UserRegistrationHandler.promises.registerNewUser(req.body) user = await UserRegistrationHandler.promises.registerNewUser(req.body)
} catch (err) { } catch (err) {
@@ -141,10 +142,17 @@ async function registerNewUser(req, res, next) {
} }
if (isExternal) { if (isExternal) {
update.$unset = { hashedPassword: "" } update.$unset = { hashedPassword: "" }
} else {
await _sendActivationEmail(user._id.toString())
} }
await User.updateOne({ _id: user._id }, update).exec() 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) { } catch (err) {
OError.tag(err, 'error finishing user registration', { OError.tag(err, 'error finishing user registration', {
email: user.email, email: user.email,
@@ -155,7 +163,7 @@ async function registerNewUser(req, res, next) {
const authMethods = isExternal ? [] : ['local'] const authMethods = isExternal ? [] : ['local']
const { id, first_name, last_name, signUpDate } = user 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 } 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) { async function sendActivationEmail(req, res, next) {
@@ -164,7 +172,7 @@ async function sendActivationEmail(req, res, next) {
await _sendActivationEmail(userId) await _sendActivationEmail(userId)
} catch (err) { } catch (err) {
logger.warn({ 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) res.sendStatus(200)
} }
@@ -50,7 +50,7 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) {
const { refreshUsers, addUserToView } = useUserListContext() const { refreshUsers, addUserToView } = useUserListContext()
const [redirecting, setRedirecting] = useState(false) const [redirecting, setRedirecting] = useState(false)
const { isLoading, isError, error, runAsync } = useAsync<CreateUserResult>() const { data, isLoading, error, runAsync } = useAsync<CreateUserResult>()
const createAccount = () => { const createAccount = () => {
runAsync( runAsync(
@@ -66,7 +66,9 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) {
) )
.then(data => { .then(data => {
addUserToView(data.user) addUserToView(data.user)
if (!data.emailIsNotSent) {
handleCloseModal() handleCloseModal()
}
}) })
.catch(debugConsole.error) .catch(debugConsole.error)
} }
@@ -93,7 +95,7 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) {
</OLModalHeader> </OLModalHeader>
<OLModalBody> <OLModalBody>
{isError && ( {error && (
<div className="notification-list"> <div className="notification-list">
<Notification <Notification
type="error" type="error"
@@ -101,6 +103,14 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) {
/> />
</div> </div>
)} )}
{data?.emailIsNotSent && (
<div className="notification-list">
<Notification
type="warning"
content={'The account has been created, but the notification email was not sent to the user. Please check your SMTP configuration.'}
/>
</div>
)}
<OLForm onSubmit={handleSubmit}> <OLForm onSubmit={handleSubmit}>
<OLFormGroup controlId="email-address"> <OLFormGroup controlId="email-address">
@@ -181,7 +191,9 @@ function ModalContentNewUserForm({ handleCloseModal }: Props) {
disabled={userData.email.trim() === '' || disabled={userData.email.trim() === '' ||
userData.lastName.trim() === '' || userData.lastName.trim() === '' ||
userData.firstName.trim() === '' || userData.firstName.trim() === '' ||
isLoading || redirecting} isLoading || redirecting ||
data?.emailIsNotSent ||
(error && error.info?.statusCode !== 409)}
isLoading={isLoading} isLoading={isLoading}
loadingLabel={t('creating')} loadingLabel={t('creating')}
> >