A Verified Mark Certificate cannot be made here: an authority issues it after checking the organisation. What the service can do is hold the file the authority returns, serve it where the DNS record points, and refuse one that would make receivers ignore BIMI without a word. - migration 0015: domain_bimi keeps the PEM chain next to the logo - bimi.InspectCertificate reads a chain and reports every reason it would not work: private key blocks refused outright, the brand-indicator usage, the validity period, the domain (exact, wildcard or organisational), and that the logo embedded in the certificate (gzipped data URI in the logotype extension) is byte for byte the logo being published. Tested against two real public VMCs (eBay via DigiCert, CNN via Valimail) plus mutations - GET /.well-known/bimi/vmc.pem (public, conditional, cacheable for an hour), and PUT/DELETE /api/v1/admin/bimi/certificate; the GET of the logo now reports the certificate as it stands against the logo being served, and replacing a logo under a held certificate says it no longer matches - GET /api/v1/admin/bimi/check looks at what a receiver would: the logo, DMARC enforcement, the BIMI record, the public logo URL, the certificate and its public URL. Its HTTP client is HTTPS only and refuses non-public addresses after DNS, since the URLs come from DNS and an operator field - the DNS record points a= at the held certificate when there is one Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
58 lines
2.3 KiB
TypeScript
58 lines
2.3 KiB
TypeScript
import type { NextConfig } from "next";
|
|
|
|
const PROTOCOLS_SERVICE_URL = process.env.PROTOCOLS_SERVICE_URL ?? "http://protocols:8080";
|
|
|
|
const nextConfig: NextConfig = {
|
|
output: "standalone",
|
|
|
|
// The event stream is a WebSocket upgrade, which a route handler cannot
|
|
// proxy: a handler sees a finished request, not the raw connection. A
|
|
// rewrite hands the socket to Next's own proxy, which does upgrade.
|
|
// Everything else under /api/v1 keeps going through the route handler,
|
|
// which needs to read and rewrite Set-Cookie.
|
|
async rewrites() {
|
|
return [
|
|
{
|
|
source: "/api/v1/events",
|
|
destination: `${PROTOCOLS_SERVICE_URL}/api/v1/events`,
|
|
},
|
|
// The well-known documents belong to the protocols service, but the
|
|
// hostnames senders ask for - mta-sts.<domain> above all - resolve to
|
|
// this app. Without these rewrites the Next 404 page was served in
|
|
// place of the MTA-STS policy: the _mta-sts TXT record advertised a
|
|
// policy that could not be fetched, so every sender fell back to
|
|
// "no-policy-found" and no TLS policy was enforced on inbound mail.
|
|
// Google's daily TLS-RPT report reports precisely that.
|
|
//
|
|
// A rewrite rather than a redirect, because RFC 8461 section 3.3 has
|
|
// the sender fetch that exact HTTPS path and it need not follow one.
|
|
{
|
|
source: "/.well-known/mta-sts.txt",
|
|
destination: `${PROTOCOLS_SERVICE_URL}/.well-known/mta-sts.txt`,
|
|
},
|
|
{
|
|
// Fetched by receiving mail providers evaluating a message, which
|
|
// hold no session and never will.
|
|
source: "/.well-known/bimi/default.svg",
|
|
destination: `${PROTOCOLS_SERVICE_URL}/.well-known/bimi/default.svg`,
|
|
},
|
|
{
|
|
// The BIMI certificate (VMC/CMC) the DNS record's a= tag points at,
|
|
// fetched the same way as the logo above.
|
|
source: "/.well-known/bimi/vmc.pem",
|
|
destination: `${PROTOCOLS_SERVICE_URL}/.well-known/bimi/vmc.pem`,
|
|
},
|
|
{
|
|
source: "/.well-known/security.txt",
|
|
destination: `${PROTOCOLS_SERVICE_URL}/.well-known/security.txt`,
|
|
},
|
|
{
|
|
source: "/.well-known/autoconfig/mail/config-v1.1.xml",
|
|
destination: `${PROTOCOLS_SERVICE_URL}/.well-known/autoconfig/mail/config-v1.1.xml`,
|
|
},
|
|
];
|
|
},
|
|
};
|
|
|
|
export default nextConfig;
|