This commit is contained in:
parent
d984e361f5
commit
57abf1340d
|
@ -4,7 +4,7 @@ import mailparser from "mailparser";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOMServer from "react-dom/server";
|
import ReactDOMServer from "react-dom/server";
|
||||||
import xml2js from "xml2js";
|
import xml2js from "xml2js";
|
||||||
import fs from "fs";
|
import { promises as fs } from "fs";
|
||||||
import cryptoRandomString from "crypto-random-string";
|
import cryptoRandomString from "crypto-random-string";
|
||||||
|
|
||||||
export const webServer = express()
|
export const webServer = express()
|
||||||
|
@ -19,10 +19,11 @@ export const webServer = express()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.post("/", (req, res) => {
|
.post("/", (req, res, next) => {
|
||||||
|
(async () => {
|
||||||
const name = req.body.name;
|
const name = req.body.name;
|
||||||
const identifier = createIdentifier();
|
const identifier = createIdentifier();
|
||||||
fs.writeFileSync(
|
await fs.writeFile(
|
||||||
feedPath(identifier),
|
feedPath(identifier),
|
||||||
renderXML(Feed({ name, identifier }))
|
renderXML(Feed({ name, identifier }))
|
||||||
);
|
);
|
||||||
|
@ -34,6 +35,7 @@ export const webServer = express()
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
})().catch(next);
|
||||||
})
|
})
|
||||||
.listen(8000);
|
.listen(8000);
|
||||||
|
|
||||||
|
@ -41,15 +43,6 @@ export const emailServer = new SMTPServer({
|
||||||
disabledCommands: ["AUTH", "STARTTLS"],
|
disabledCommands: ["AUTH", "STARTTLS"],
|
||||||
onData(stream, session, callback) {
|
onData(stream, session, callback) {
|
||||||
(async () => {
|
(async () => {
|
||||||
const paths = session.envelope.rcptTo.flatMap(({ address }) => {
|
|
||||||
const match = address.match(/^(\w+)@kill-the-newsletter.com$/);
|
|
||||||
if (match === null) return [];
|
|
||||||
const identifier = match[1];
|
|
||||||
const path = feedPath(identifier);
|
|
||||||
if (!fs.existsSync(path)) return [];
|
|
||||||
return [path];
|
|
||||||
});
|
|
||||||
if (paths.length === 0) return callback();
|
|
||||||
const email = await mailparser.simpleParser(stream);
|
const email = await mailparser.simpleParser(stream);
|
||||||
const { entry } = Entry({
|
const { entry } = Entry({
|
||||||
title: email.subject,
|
title: email.subject,
|
||||||
|
@ -57,16 +50,20 @@ export const emailServer = new SMTPServer({
|
||||||
// FIXME: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/43234 / typeof email.html !== "boolean" => email.html !== false
|
// FIXME: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/43234 / typeof email.html !== "boolean" => email.html !== false
|
||||||
content: typeof email.html !== "boolean" ? email.html : email.textAsHtml
|
content: typeof email.html !== "boolean" ? email.html : email.textAsHtml
|
||||||
});
|
});
|
||||||
for (const path of paths) {
|
for (const { address } of session.envelope.rcptTo) {
|
||||||
const xml = await new xml2js.Parser().parseStringPromise(
|
const match = address.match(/^(\w+)@kill-the-newsletter.com$/);
|
||||||
fs.readFileSync(path, "utf8")
|
if (match === null) continue;
|
||||||
);
|
const identifier = match[1];
|
||||||
|
const path = feedPath(identifier);
|
||||||
|
const xmlText = await fs.readFile(path, "utf8").catch(() => null);
|
||||||
|
if (xmlText === null) continue;
|
||||||
|
const xml = await new xml2js.Parser().parseStringPromise(xmlText);
|
||||||
xml.feed.updated = now();
|
xml.feed.updated = now();
|
||||||
if (xml.feed.entry === undefined) xml.feed.entry = [];
|
if (xml.feed.entry === undefined) xml.feed.entry = [];
|
||||||
xml.feed.entry.unshift(entry);
|
xml.feed.entry.unshift(entry);
|
||||||
while (xml.feed.entry.length > 0 && renderXML(xml).length > 500_000)
|
while (xml.feed.entry.length > 0 && renderXML(xml).length > 500_000)
|
||||||
xml.feed.entry.pop();
|
xml.feed.entry.pop();
|
||||||
fs.writeFileSync(path, renderXML(xml));
|
await fs.writeFile(path, renderXML(xml));
|
||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
})().catch(callback);
|
})().catch(callback);
|
||||||
|
|
|
@ -49,6 +49,15 @@ describe("receive email", () => {
|
||||||
expect(feed).toMatch("REPETITION 3");
|
expect(feed).toMatch("REPETITION 3");
|
||||||
expect(feed).not.toMatch("REPETITION 0");
|
expect(feed).not.toMatch("REPETITION 0");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("non-existing address", async () => {
|
||||||
|
await emailClient.sendMail({
|
||||||
|
from: "publisher@example.com",
|
||||||
|
to: `non-existing@kill-the-newsletter.com`,
|
||||||
|
subject: "New Message",
|
||||||
|
html: "<p>HTML content</p>"
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
|
Loading…
Reference in New Issue