fix(email): do not attempt to display logo if app URL not configured (#2125)

* fix(email): do not attempt to display logo if app URL not configured

* fix(email): prevent Gmail from turning usernames with periods into hyperlinks

* fix(email): fix(email): use displayName instead of username/plexUserName and improve Gmail link fix
pull/2213/head
TheCatLady 3 years ago committed by GitHub
parent 032c14a226
commit b3b421a674
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -178,6 +178,7 @@ export class User {
password: password, password: password,
applicationUrl, applicationUrl,
applicationTitle, applicationTitle,
recipientName: this.username,
}, },
}); });
} catch (e) { } catch (e) {
@ -214,6 +215,8 @@ export class User {
resetPasswordLink, resetPasswordLink,
applicationUrl, applicationUrl,
applicationTitle, applicationTitle,
recipientName: this.displayName,
recipientEmail: this.email,
}, },
}); });
} catch (e) { } catch (e) {

@ -46,7 +46,8 @@ class EmailAgent
private buildMessage( private buildMessage(
type: Notification, type: Notification,
payload: NotificationPayload, payload: NotificationPayload,
toEmail: string recipientEmail: string,
recipientName?: string
): EmailOptions | undefined { ): EmailOptions | undefined {
const { applicationUrl, applicationTitle } = getSettings().main; const { applicationUrl, applicationTitle } = getSettings().main;
@ -54,12 +55,14 @@ class EmailAgent
return { return {
template: path.join(__dirname, '../../../templates/email/test-email'), template: path.join(__dirname, '../../../templates/email/test-email'),
message: { message: {
to: toEmail, to: recipientEmail,
}, },
locals: { locals: {
body: payload.message, body: payload.message,
applicationUrl, applicationUrl,
applicationTitle, applicationTitle,
recipientName,
recipientEmail,
}, },
}; };
} }
@ -127,7 +130,7 @@ class EmailAgent
'../../../templates/email/media-request' '../../../templates/email/media-request'
), ),
message: { message: {
to: toEmail, to: recipientEmail,
}, },
locals: { locals: {
requestType, requestType,
@ -143,6 +146,8 @@ class EmailAgent
: undefined, : undefined,
applicationUrl, applicationUrl,
applicationTitle, applicationTitle,
recipientName,
recipientEmail,
}, },
}; };
} }
@ -179,7 +184,12 @@ class EmailAgent
payload.notifyUser.settings?.pgpKey payload.notifyUser.settings?.pgpKey
); );
await email.send( await email.send(
this.buildMessage(type, payload, payload.notifyUser.email) this.buildMessage(
type,
payload,
payload.notifyUser.email,
payload.notifyUser.displayName
)
); );
} catch (e) { } catch (e) {
logger.error('Error sending email notification', { logger.error('Error sending email notification', {
@ -228,7 +238,9 @@ class EmailAgent
this.getSettings(), this.getSettings(),
user.settings?.pgpKey user.settings?.pgpKey
); );
await email.send(this.buildMessage(type, payload, user.email)); await email.send(
this.buildMessage(type, payload, user.email, user.displayName)
);
} catch (e) { } catch (e) {
logger.error('Error sending email notification', { logger.error('Error sending email notification', {
label: 'Notifications', label: 'Notifications',

@ -109,7 +109,7 @@ router.post(
const user = new User({ const user = new User({
avatar: body.avatar ?? avatar, avatar: body.avatar ?? avatar,
username: body.username ?? body.email, username: body.username,
email: body.email, email: body.email,
password: body.password, password: body.password,
permissions: settings.main.defaultPermissions, permissions: settings.main.defaultPermissions,

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1') meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no') meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen') link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style. style.
.title:hover * { .title:hover * {
text-decoration: underline; text-decoration: underline;
@ -35,28 +16,35 @@ head
width: 100% !important; width: 100% !important;
} }
} }
div(style='display: block; background-color: #111827;') div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;') table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr tr
td(style="text-align: center;") td(style="text-align: center;")
a(href=applicationUrl) if applicationUrl
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;') a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr tr
td(style='text-align: center;') td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;') div(style='margin: 1rem 0 0; font-size: 1.25em;')
span | An account has been created for you at #{applicationTitle}.
| An account has been created for you at #{applicationTitle}.
tr tr
td(style='text-align: center;') td(style='text-align: center;')
div(style='margin: 1rem 1rem 1rem; font-size: 1.25em;') div(style='margin: 1rem 0 0; font-size: 1.25em;')
span | Your password is:
| Your new password is: div(style='font-size: 1.25em; font-weight: 500; line-height: 2.25em;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;') span(style='padding: 0.5rem; font-weight: 500; border: 1px solid rgb(100,100,100); font-family: monospace;')
span
| #{password} | #{password}
if applicationUrl if applicationUrl
tr tr
td td
a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;') a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 0; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);') span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
| Open #{applicationTitle} | Open #{applicationTitle}

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1') meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no') meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen') link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style. style.
.title:hover * { .title:hover * {
text-decoration: underline; text-decoration: underline;
@ -35,31 +16,38 @@ head
width: 100% !important; width: 100% !important;
} }
} }
div(style='display: block; background-color: #111827;') div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;') table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr tr
td(style="text-align: center;") td(style="text-align: center;")
a(href=applicationUrl) if applicationUrl
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;') a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr tr
td(style='text-align: center;') td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;') div(style='margin: 1rem 0 0; font-size: 1.25em;')
span | #{body}
| #{body}
tr tr
td td
div(style='box-sizing: border-box; margin: 0; width: 100%; color: #fff; border-radius: .75rem; padding: 1rem; border: 1px solid rgba(100, 100, 100, 1); background: linear-gradient(135deg, rgba(17, 24, 39, 0.47) 0%, rgb(17, 24, 39) 75%), url(' + imageUrl + ') center 25%/cover') div(style='box-sizing: border-box; margin: 1.5rem 0 0; width: 100%; color: #fff; border-radius: .75rem; padding: 1rem; border: 1px solid rgb(100,100,100); background: linear-gradient(135deg, rgba(17,24,39,0.47) 0%, rgb(17,24,39) 75%), url(' + imageUrl + ') center 25%/cover')
table(style='color: #fff; width: 100%;') table(style='color: #fff; width: 100%;')
tr tr
td(style='vertical-align: top;') td(style='vertical-align: top;')
a(href=actionUrl style='display: block; max-width: 20rem; color: #fff; font-weight: 700; text-decoration: none; margin: 0 1rem 0.25rem 0; font-size: 1.3em; line-height: 1.25em; margin-bottom: 5px;' class='title') a(href=actionUrl style='display: block; max-width: 20rem; color: #fff; font-weight: 700; text-decoration: none; margin: 0 1rem 0.25rem 0; font-size: 1.3em; line-height: 1.25em; margin-bottom: 5px;' class='title')
span | #{mediaName}
| #{mediaName}
div(style='overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #d1d5db; font-size: .975em; line-height: 1.45em; padding-top: .25rem; padding-bottom: .25rem;') div(style='overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #d1d5db; font-size: .975em; line-height: 1.45em; padding-top: .25rem; padding-bottom: .25rem;')
span(style='display: block;') span(style='display: block;')
b(style='color: #9ca3af; font-weight: 700;') b(style='color: #9ca3af; font-weight: 700;')
| Requested By  | Requested By 
| #{requestedBy} | #{requestedBy.replace(/\.|@/g, ((x) => x + '\ufeff'))}
each extra in mediaExtra each extra in mediaExtra
span(style='display: block;') span(style='display: block;')
b(style='color: #9ca3af; font-weight: 700;') b(style='color: #9ca3af; font-weight: 700;')
@ -76,6 +64,6 @@ div(style='display: block; background-color: #111827;')
if actionUrl if actionUrl
tr tr
td td
a(href=actionUrl style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;') a(href=actionUrl style='display: block; margin: 1.5rem 3rem 0; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);') span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
| Open in #{applicationTitle} | Open in #{applicationTitle}

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1') meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no') meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen') link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style. style.
.title:hover * { .title:hover * {
text-decoration: underline; text-decoration: underline;
@ -35,25 +16,35 @@ head
width: 100% !important; width: 100% !important;
} }
} }
div(style='display: block; background-color: #111827;') div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;') table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr tr
td(style="text-align: center;") td(style="text-align: center;")
a(href=applicationUrl) if applicationUrl
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;') a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr tr
td(style='text-align: center;') td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;') div(style='margin: 1rem 0 0; font-size: 1.25em;')
span | A request has been received to change the password for your #{applicationTitle} account.
| Your #{applicationTitle} account password was requested to be reset. Click below to reset your password. tr
if resetPasswordLink td
tr a(href=resetPasswordLink style='display: block; margin: 1.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
td span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
a(href=resetPasswordLink style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;') | Reset Password
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);') tr
| Reset Password td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| The above link will expire in 24 hours.
tr tr
td(style='text-align: center;') td(style='text-align: center;')
div(style='margin: 1rem; font-size: .85em;') div(style='margin: 1rem 1rem 0; font-size: 1.25em;')
span | If you did not initiate this request, you may safely disregard this message.
| If you did not request that your password be reset, you can safely ignore this email.

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1') meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no') meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen') link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style. style.
.title:hover * { .title:hover * {
text-decoration: underline; text-decoration: underline;
@ -35,20 +16,28 @@ head
width: 100% !important; width: 100% !important;
} }
} }
div(style='display: block; background-color: #111827;') div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;') table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr tr
td(style="text-align: center;") td(style="text-align: center;")
a(href=applicationUrl) if applicationUrl
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;') a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr tr
td(style='text-align: center;') td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;') div(style='margin: 1rem 0 0; font-size: 1.25em;')
span | #{body}
| #{body}
if applicationUrl if applicationUrl
tr tr
td td
a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;') a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 0; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);') span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
| Open #{applicationTitle} | Open #{applicationTitle}

Loading…
Cancel
Save