diff options
| author | Leitwolf11 | 2026-08-28 18:45:11 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-08-28 18:45:11 +0300 |
| commit | 397a80b245a235ae0e3958787273ed5cdd61acf1 (patch) | |
| tree | 1186208c0f1e8453c7f235b633a8d7cd0c8c2849 | |
| parent | 319c9800ba6cb4e1311846ed538cf0e5c8df3288 (diff) | |
| download | website-397a80b245a235ae0e3958787273ed5cdd61acf1.tar.gz | |
Move transactional mail identity to Progmasoft infrastructure
| -rw-r--r-- | README.md | 9 | ||||
| -rw-r--r-- | backend/Email/EmailOptions.cs | 2 | ||||
| -rw-r--r-- | backend/appsettings.json | 2 | ||||
| -rw-r--r-- | frontend/src/components/AuthPanel.astro | 2 | ||||
| -rw-r--r-- | ops/mail/README.md | 27 | ||||
| -rw-r--r-- | ops/mail/dovecot-local.conf | 4 | ||||
| -rw-r--r-- | ops/mail/opendkim.conf | 4 | ||||
| -rw-r--r-- | ops/mail/postfix-settings.txt | 8 | ||||
| -rw-r--r-- | ops/mail/sender_login | 2 |
9 files changed, 33 insertions, 27 deletions
@@ -27,9 +27,10 @@ the compiler package contract is completed. Registry tokens follow the Cargo mod only a SHA-256 digest is retained, and a user can revoke each token independently. Account deletion permanently removes the Identity account, external logins, verification records, and registry tokens. -The PostgreSQL provider is selected solely by `ConnectionStrings__Registry`; production can use a Supabase PostgreSQL -connection without exposing database or service credentials to the browser. Google OAuth client credentials, the -database connection, auth-code pepper, and data-protection certificate stay in host-managed secrets. +The PostgreSQL provider is selected solely by `ConnectionStrings__Registry`. Production uses the PostgreSQL instance on +the project-owned server over a local Unix socket; the database is not delegated to a hosted database service or exposed +to the browser. Google OAuth client credentials, the database connection, auth-code pepper, and data-protection +certificate stay in host-managed secrets. The Google OAuth web client callback is `https://viget.xsharp-lang.xyz/api/v1/auth/google/callback`. Configure it through @@ -85,7 +86,7 @@ dotnet tool run dotnet-ef migrations add <Name> --project backend/XSharp.Web.Api ``` Email verification and recovery use an eight-character, short-lived, single-use code. Messages are sent by the -automated `noreply@xsharp-lang.xyz` identity; it is not a mailbox. See `ops/mail/README.md` for the transport boundary. +automated `noreply@progmasoft.com` identity; it is not a mailbox. See `ops/mail/README.md` for the transport boundary. ## Release policy diff --git a/backend/Email/EmailOptions.cs b/backend/Email/EmailOptions.cs index 0d55c56..5ec8387 100644 --- a/backend/Email/EmailOptions.cs +++ b/backend/Email/EmailOptions.cs @@ -7,6 +7,6 @@ internal sealed class EmailOptions { public string Host { get; init; } = "127.0.0.1"; public int Port { get; init; } = 25; - public string From { get; init; } = "noreply@xsharp-lang.xyz"; + public string From { get; init; } = "noreply@progmasoft.com"; public string SenderName { get; init; } = "Visual X# Package Registry"; } diff --git a/backend/appsettings.json b/backend/appsettings.json index 3b54bf3..b490a26 100644 --- a/backend/appsettings.json +++ b/backend/appsettings.json @@ -26,7 +26,7 @@ "Email": { "Host": "127.0.0.1", "Port": 25, - "From": "noreply@xsharp-lang.xyz", + "From": "noreply@progmasoft.com", "SenderName": "Visual X# Package Registry" } } diff --git a/frontend/src/components/AuthPanel.astro b/frontend/src/components/AuthPanel.astro index 3c537aa..246c017 100644 --- a/frontend/src/components/AuthPanel.astro +++ b/frontend/src/components/AuthPanel.astro @@ -148,7 +148,7 @@ const content = copy[mode]; required /> <p class="field-hint"> - The code is sent by <code>noreply@xsharp-lang.xyz</code>. It expires and can only be used once. If it does not + The code is sent by <code>noreply@progmasoft.com</code>. It expires and can only be used once. If it does not appear in your inbox, check your spam or junk folder. </p> <button class="auth-submit" type="submit">Verify email</button> diff --git a/ops/mail/README.md b/ops/mail/README.md index a9f1c63..a796896 100644 --- a/ops/mail/README.md +++ b/ops/mail/README.md @@ -6,20 +6,21 @@ SPDX-License-Identifier: AGPL-3.0-or-later # Transactional mail boundary The registry API submits verification and password-recovery messages to Postfix over the loopback interface. Postfix -requires TLS for remote SMTP delivery and signs `xsharp-lang.xyz` mail with OpenDKIM selector `registry`. The automated -`noreply@xsharp-lang.xyz` sender remains non-login. `support@xsharp-lang.xyz` is the only interactive mailbox and is +requires TLS for remote SMTP delivery and signs `progmasoft.com` mail with OpenDKIM selector `registry`. The automated +`noreply@progmasoft.com` sender remains non-login. `support@progmasoft.com` is the only interactive mailbox and is delivered as Maildir to the dedicated, non-shell `support` account. Production DNS publishes: -- an unproxied `mail.xsharp-lang.xyz` address record; -- an MX record with priority 10 targeting `mail.xsharp-lang.xyz`; +- an unproxied `mail.progmasoft.com` address record; +- an MX record with priority 10 targeting `mail.progmasoft.com`; - a strict SPF record authorizing the registry host; -- the `registry._domainkey` public key; -- a strict-alignment DMARC policy. +- a 2048-bit `registry._domainkey` public key; +- a strict-alignment DMARC policy, initially in monitor mode and raised to enforcement after SPF, DKIM, and alignment + have been verified in received messages. The private DKIM key and ASP.NET Core connection/OAuth secrets live only on the host. They are never committed. The -hosting provider should set reverse DNS for `193.111.77.89` to `mail.xsharp-lang.xyz`; this cannot be configured through +hosting provider should set reverse DNS for `193.111.77.89` to `mail.progmasoft.com`; this cannot be configured through Cloudflare DNS. Install `postfix`, `opendkim`, `opendkim-tools`, `dovecot`, and `certbot`. Keep the selector private key owned by @@ -38,11 +39,15 @@ allows login but blocks both Postfix delivery and Dovecot index writes. Client settings: -- address and username: `support@xsharp-lang.xyz`; -- incoming mail: IMAPS at `mail.xsharp-lang.xyz:993`, TLS required; -- outgoing mail: submission at `mail.xsharp-lang.xyz:587`, STARTTLS required; -- SMTP sender: exactly `support@xsharp-lang.xyz`. +- address and username: `support@progmasoft.com`; +- incoming mail: IMAPS at `mail.progmasoft.com:993`, TLS required; +- outgoing mail: submission at `mail.progmasoft.com:587`, STARTTLS required; +- SMTP sender: exactly `support@progmasoft.com`. Port 25 accepts mail for the local domain but never authenticates users or acts as an open relay. Port 587 requires Dovecot authentication and rejects an authenticated account that tries to use another sender address. Certificate renewal installs `certbot-deploy-hook.sh` so Postfix and Dovecot reload the renewed key material. + +The deployment follows Gmail's sender requirements: the SMTP hostname has matching forward and reverse DNS, outbound +mail uses TLS, messages are RFC 5322 compliant, and the visible `From` domain aligns with both SPF and DKIM. Registry +verification and recovery messages are transactional; the service does not send subscription or promotional mail. diff --git a/ops/mail/dovecot-local.conf b/ops/mail/dovecot-local.conf index 81947a2..c4ae1ff 100644 --- a/ops/mail/dovecot-local.conf +++ b/ops/mail/dovecot-local.conf @@ -14,8 +14,8 @@ auth_username_format = %Ln ssl = required ssl_min_protocol = TLSv1.2 ssl_prefer_server_ciphers = yes -ssl_cert = </etc/letsencrypt/live/mail.xsharp-lang.xyz/fullchain.pem -ssl_key = </etc/letsencrypt/live/mail.xsharp-lang.xyz/privkey.pem +ssl_cert = </etc/letsencrypt/live/mail.progmasoft.com/fullchain.pem +ssl_key = </etc/letsencrypt/live/mail.progmasoft.com/privkey.pem service auth { unix_listener /var/spool/postfix/private/auth { diff --git a/ops/mail/opendkim.conf b/ops/mail/opendkim.conf index 46d5d02..ab1995f 100644 --- a/ops/mail/opendkim.conf +++ b/ops/mail/opendkim.conf @@ -8,9 +8,9 @@ Canonicalization relaxed/simple Mode s SubDomains no OversignHeaders From -Domain xsharp-lang.xyz +Domain progmasoft.com Selector registry -KeyFile /etc/opendkim/keys/xsharp-lang.xyz/registry.private +KeyFile /etc/opendkim/keys/progmasoft.com/registry.private Socket inet:8891@127.0.0.1 PidFile /run/opendkim/opendkim.pid UMask 007 diff --git a/ops/mail/postfix-settings.txt b/ops/mail/postfix-settings.txt index f5e7425..048b8cb 100644 --- a/ops/mail/postfix-settings.txt +++ b/ops/mail/postfix-settings.txt @@ -1,8 +1,8 @@ # SPDX-FileCopyrightText: 2026 Leitwolf <xs-lang.chess031@slmails.com> # SPDX-License-Identifier: Apache-2.0 -myhostname = mail.xsharp-lang.xyz -mydomain = xsharp-lang.xyz +myhostname = mail.progmasoft.com +mydomain = progmasoft.com myorigin = $mydomain inet_interfaces = all inet_protocols = ipv4 @@ -15,8 +15,8 @@ smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,rejec smtp_tls_security_level = encrypt smtp_tls_CApath = /etc/pki/tls/certs smtp_tls_loglevel = 1 -smtpd_tls_cert_file = /etc/letsencrypt/live/mail.xsharp-lang.xyz/fullchain.pem -smtpd_tls_key_file = /etc/letsencrypt/live/mail.xsharp-lang.xyz/privkey.pem +smtpd_tls_cert_file = /etc/letsencrypt/live/mail.progmasoft.com/fullchain.pem +smtpd_tls_key_file = /etc/letsencrypt/live/mail.progmasoft.com/privkey.pem smtpd_tls_security_level = may smtpd_tls_auth_only = yes smtpd_sasl_type = dovecot diff --git a/ops/mail/sender_login b/ops/mail/sender_login index def4f4d..f732aee 100644 --- a/ops/mail/sender_login +++ b/ops/mail/sender_login @@ -1,4 +1,4 @@ # SPDX-FileCopyrightText: 2026 Leitwolf <xs-lang.chess031@slmails.com> # SPDX-License-Identifier: Apache-2.0 -support@xsharp-lang.xyz support +support@progmasoft.com support |