fix: sign in issues (#4047)

Co-authored-by: Alex Yang <himself65@outlook.com>
This commit is contained in:
Qi
2023-08-31 21:07:05 +08:00
committed by GitHub
parent 13857d59dc
commit 3f5e649295
17 changed files with 430 additions and 472 deletions

View File

@@ -85,43 +85,65 @@ export class MailService {
],
});
}
async sendSignInEmail(url: string, options: Options) {
const html = emailTemplate({
title: 'Sign in to AFFiNE',
content:
'Click the button below to securely sign in. The magic link will expire in 30 minutes.',
buttonContent: 'Sign in to AFFiNE',
buttonUrl: url,
});
return this.sendMail({
html,
subject: 'Sign in to AFFiNE',
...options,
});
}
async sendChangePasswordEmail(to: string, url: string) {
const html = `
<h1>Change password</h1>
<p>Click button to open change password page</p>
<a href="${url}">${url}</a>
`;
const html = emailTemplate({
title: 'Modify your AFFiNE password',
content:
'Click the button below to reset your password. The magic link will expire in 30 minutes.',
buttonContent: 'Set new password',
buttonUrl: url,
});
return this.sendMail({
from: this.config.auth.email.sender,
to,
subject: `Change password`,
subject: `Modify your AFFiNE password`,
html,
});
}
async sendSetPasswordEmail(to: string, url: string) {
const html = `
<h1>Set password</h1>
<p>Click button to open set password page</p>
<a href="${url}">${url}</a>
`;
const html = emailTemplate({
title: 'Set your AFFiNE password',
content:
'Click the button below to set your password. The magic link will expire in 30 minutes.',
buttonContent: 'Set your password',
buttonUrl: url,
});
return this.sendMail({
from: this.config.auth.email.sender,
to,
subject: `Change password`,
subject: `Set your AFFiNE password`,
html,
});
}
async sendChangeEmail(to: string, url: string) {
const html = `
<h1>Change Email</h1>
<p>Click button to open change email page</p>
<a href="${url}">${url}</a>
`;
const html = emailTemplate({
title: 'Verify your current email for AFFiNE',
content:
'You recently requested to change the email address associated with your AFFiNE account. To complete this process, please click on the verification link below. This magic link will expire in 30 minutes.',
buttonContent: 'Verify and set up a new email address',
buttonUrl: url,
});
return this.sendMail({
from: this.config.auth.email.sender,
to,
subject: `Change password`,
subject: `Verify your current email for AFFiNE`,
html,
});
}

View File

@@ -88,25 +88,24 @@ export const NextAuthOptionsProvider: FactoryProvider<NextAuthOptions> = {
from: config.auth.email.sender,
async sendVerificationRequest(params: SendVerificationRequestParams) {
const { identifier, url, provider } = params;
const { host, searchParams, origin } = new URL(url);
const { searchParams, origin } = new URL(url);
const callbackUrl = searchParams.get('callbackUrl') || '';
if (!callbackUrl) {
throw new Error('callbackUrl is not set');
}
// hack: check if link is opened via desktop
const schema = getSchemaFromCallbackUrl(origin, callbackUrl);
const wrappedUrl = wrapUrlWithOpenApp(origin, url, schema);
const result = await mailer.sendMail({
// hack: check if link is opened via desktop
const result = await mailer.sendSignInEmail(wrappedUrl, {
to: identifier,
from: provider.from,
subject: `Sign in to ${host}`,
text: text({ url: wrappedUrl, host }),
html: html({ url: wrappedUrl, host }),
});
logger.log(
`send verification email success: ${result.accepted.join(', ')}`
);
const failed = result.rejected
.concat(result.pending)
.filter(Boolean);
@@ -298,211 +297,3 @@ export const NextAuthOptionsProvider: FactoryProvider<NextAuthOptions> = {
},
inject: [Config, PrismaService, MailService],
};
/**
* Email HTML body
* Insert invisible space into domains from being turned into a hyperlink by email
* clients like Outlook and Apple mail, as this is confusing because it seems
* like they are supposed to click on it to sign in.
*
* @note We don't add the email address to avoid needing to escape it, if you do, remember to sanitize it!
*/
function html(params: { url: string; host: string }) {
const { url } = params;
return `
<body style="background: #f6f7fb;overflow:hidden">
<table
width="100%"
border="0"
cellpadding="24px"
style="
background: #fff;
max-width: 450px;
margin: 32px auto 0 auto;
border-radius: 16px 16px 0 0;
box-shadow: 0px 0px 20px 0px rgba(66, 65, 73, 0.04);
"
>
<tr>
<td>
<a href="https://affine.pro" target="_blank">
<img
src="https://cdn.affine.pro/mail/2023-8-9/affine-logo.png"
alt="AFFiNE log"
height="32px"
/>
</a>
</td>
</tr>
<tr>
<td
style="
font-size: 20px;
font-weight: 600;
line-height: 28px;
font-family: inter, Arial, Helvetica, sans-serif;
color: #444;
padding-top: 0;
"
>
Verify your new email for AFFiNE
</td>
</tr>
<tr>
<td
style="
font-size: 15px;
font-weight: 400;
line-height: 24px;
font-family: inter, Arial, Helvetica, sans-serif;
color: #444;
padding-top: 0;
"
>
You recently requested to change the email address associated with your
AFFiNe account. To complete this process, please click on the
verification link below.
</td>
</tr>
<tr>
<td style="margin-left: 24px; padding-top: 0; padding-bottom: 64px">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td style="border-radius: 8px" bgcolor="#1E96EB">
<a
href="${url}"
target="_blank"
style="
font-size: 15px;
font-family: inter, Arial, Helvetica, sans-serif;
font-weight: 600;
line-height: 24px;
color: #fff;
text-decoration: none;
border-radius: 8px;
padding: 8px 18px;
border: 1px solid #1e96eb;
display: inline-block;
font-weight: bold;
"
>Verify your new email address</a
>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table
width="100%"
border="0"
style="
background: #fafafa;
max-width: 450px;
margin: 0 auto 32px auto;
border-radius: 0 0 16px 16px;
box-shadow: 0px 0px 20px 0px rgba(66, 65, 73, 0.04);
padding: 20px;
"
>
<tr align="center">
<td>
<table cellpadding="0">
<tr>
<td style="padding: 0 10px">
<a href="https://github.com/toeverything/AFFiNE" target="_blank"
><img
src="https://cdn.affine.pro/mail/2023-8-9/Github.png"
alt="AFFiNE github link"
height="16px"
/></a>
</td>
<td style="padding: 0 10px">
<a href="https://twitter.com/AffineOfficial" target="_blank">
<img
src="https://cdn.affine.pro/mail/2023-8-9/Twitter.png"
alt="AFFiNE twitter link"
height="16px"
/>
</a>
</td>
<td style="padding: 0 10px">
<a href="https://discord.gg/Arn7TqJBvG" target="_blank"
><img
src="https://cdn.affine.pro/mail/2023-8-9/Discord.png"
alt="AFFiNE discord link"
height="16px"
/></a>
</td>
<td style="padding: 0 10px">
<a href="https://www.youtube.com/@affinepro" target="_blank"
><img
src="https://cdn.affine.pro/mail/2023-8-9/Youtube.png"
alt="AFFiNE youtube link"
height="16px"
/></a>
</td>
<td style="padding: 0 10px">
<a href="https://t.me/affineworkos" target="_blank"
><img
src="https://cdn.affine.pro/mail/2023-8-9/Telegram.png"
alt="AFFiNE telegram link"
height="16px"
/></a>
</td>
<td style="padding: 0 10px">
<a href="https://www.reddit.com/r/Affine/" target="_blank"
><img
src="https://cdn.affine.pro/mail/2023-8-9/Reddit.png"
alt="AFFiNE reddit link"
height="16px"
/></a>
</td>
</tr>
</table>
</td>
</tr>
<tr align="center">
<td
style="
font-size: 12px;
font-weight: 400;
line-height: 20px;
font-family: inter, Arial, Helvetica, sans-serif;
color: #8e8d91;
padding-top: 8px;
"
>
One hyper-fused platform for wildly creative minds
</td>
</tr>
<tr align="center">
<td
style="
font-size: 12px;
font-weight: 400;
line-height: 20px;
font-family: inter, Arial, Helvetica, sans-serif;
color: #8e8d91;
padding-top: 8px;
"
>
Copyright<img
src="https://cdn.affine.pro/mail/2023-8-9/copyright.png"
alt="copyright"
height="14px"
style="vertical-align: middle; margin: 0 4px"
/>2023 Toeverything
</td>
</tr>
</table>
</body>
`;
}
/** Email Text body (fallback for email clients that don't render HTML, e.g. feature phones) */
function text({ url, host }: { url: string; host: string }) {
return `Sign in to ${host}\n${url}\n\n`;
}