mirror of
https://github.com/documenso/documenso.git
synced 2026-10-03 10:13:52 +10:00
Selecting password auth failed with a generic "Unauthorized" for users who signed up via OAuth or passkey, with no way to set one. Detect the missing password and email the existing reset link from the signing dialog and security settings. Require a 2FA code and rate limit update-password.
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { mailer } from '@documenso/email/mailer';
|
|
import { ResetPasswordTemplate } from '@documenso/email/templates/reset-password';
|
|
import { prisma } from '@documenso/prisma';
|
|
import { msg } from '@lingui/core/macro';
|
|
import { createElement } from 'react';
|
|
import { match } from 'ts-pattern';
|
|
|
|
import { getI18nInstance } from '../../client-only/providers/i18n-server';
|
|
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
|
import type { TPasswordChangeSource } from '../../jobs/definitions/emails/send-password-reset-success-email';
|
|
import { env } from '../../utils/env';
|
|
import { renderEmailWithI18N } from '../../utils/render-email-with-i18n';
|
|
|
|
export interface SendResetPasswordOptions {
|
|
userId: number;
|
|
source: TPasswordChangeSource;
|
|
}
|
|
|
|
export const sendResetPassword = async ({ userId, source }: SendResetPasswordOptions) => {
|
|
const user = await prisma.user.findFirstOrThrow({
|
|
where: {
|
|
id: userId,
|
|
},
|
|
});
|
|
|
|
const assetBaseUrl = NEXT_PUBLIC_WEBAPP_URL() || 'http://localhost:3000';
|
|
|
|
const template = createElement(ResetPasswordTemplate, {
|
|
assetBaseUrl,
|
|
userEmail: user.email,
|
|
userName: user.name || '',
|
|
source,
|
|
});
|
|
|
|
const [html, text] = await Promise.all([
|
|
renderEmailWithI18N(template),
|
|
renderEmailWithI18N(template, { plainText: true }),
|
|
]);
|
|
|
|
const i18n = await getI18nInstance();
|
|
|
|
const subject = match(source)
|
|
.with('RESET', () => i18n._(msg`Password Reset Success!`))
|
|
.with('UPDATE', () => i18n._(msg`Your password was changed`))
|
|
.exhaustive();
|
|
|
|
return await mailer.sendMail({
|
|
to: {
|
|
address: user.email,
|
|
name: user.name || '',
|
|
},
|
|
from: {
|
|
name: env('NEXT_PRIVATE_SMTP_FROM_NAME') || 'Documenso',
|
|
address: env('NEXT_PRIVATE_SMTP_FROM_ADDRESS') || 'noreply@documenso.com',
|
|
},
|
|
subject,
|
|
html,
|
|
text,
|
|
});
|
|
};
|