Misc. fixes (#267)

* Misc. fixes

- Do not expose 'username' to a potential recipient.
- Make 'from' mandatory, because there is no fallback anymore.
- Validate 'from' to make shure, it contains an email address.
- Avoid namespace pollution: Use let instead of var.

* Suggested changes from codereview
This commit is contained in:
Fritz Elfert
2026-03-10 10:08:10 +01:00
committed by GitHub
parent e035119249
commit 41125078ce
3 changed files with 13 additions and 14 deletions

View File

@@ -39,10 +39,11 @@ Some features:
password: ${{secrets.MAIL_PASSWORD}}
# Required mail subject:
subject: Github Actions job result
# Required recipients' addresses:
# Optional recipients' addresses:
to: obiwan@example.com,yoda@example.com
# Required sender full name (address can be skipped):
from: Luke Skywalker # <user@example.com>
# Required sender (Either: "Plain Simple Name <user@doma.in>" or just "user@doma.in" (without the <>))
# Important: '<' and '>' are special chars in yaml. Therefore this string should be quoted
from: 'Luke Skywalker <user@example.com>'
# Optional plain body:
body: Build job of ${{github.repository}} completed successfully!
# Optional HTML body read from file:

View File

@@ -25,7 +25,7 @@ inputs:
description: Recipients mail addresses (separated with comma)
required: false
from:
description: Full name of mail sender (might be with an email address specified in <>)
description: 'Either a plain email address, or full name of the sender, followed by whitespace, followed by email address enclosed in <>'
required: true
body:
description: Body of mail message (might be a filename prefixed with file:// to read from)

18
main.js
View File

@@ -23,14 +23,6 @@ function getText(textOrFile, convertMarkdown) {
return text;
}
function getFrom(from, username) {
if (from.match(/.+ <.+@.+>/)) {
return from;
}
return `"${from}" <${username}>`;
}
async function getAttachments(attachments) {
const globber = await glob.create(attachments.split(",").join("\n"));
const files = await globber.glob();
@@ -117,6 +109,12 @@ async function main() {
const envelopeTo = core.getInput("envelope_to", { required: false });
const headers = core.getInput("headers", { required: false });
// Basic check for an email sender address
// Either: "Plain Simple Name <user@doma.in>" or just "user@doma.in" (without the <>)
if (!(/^([^<>@\s]+\s+)+<[^@\s>]+@[^@\s>]+>$/.test(from) || /^[^<>@\s]+@[^@\s<>]+$/.test(from))) {
throw new Error("'from' address is invalid");
}
// if neither to, cc or bcc is provided, throw error
if (!to && !cc && !bcc) {
throw new Error(
@@ -150,11 +148,11 @@ async function main() {
proxy: process.env.HTTP_PROXY,
});
var i = 1;
let i = 1;
while (true) {
try {
const info = await transport.sendMail({
from: getFrom(from, username),
from: from,
to: to,
subject: getText(subject, false),
cc: cc ? cc : undefined,