AdvisorSoft.Utils.Html 1.0.0

AdvisorSoft.Utils

Sdílené knihovny Advisor Software pro .NET 10, rozdělené do balíčků podle závislostí – aplikace si bere jen to, co potřebuje. Všechny balíčky mají stejnou verzi.

Balíček Závislosti Obsah
AdvisorSoft.Utils žádné řetězce (diakritika, slug), dotazy nad IQueryable (data, řazení, období), HMAC podpisy, podepsané a jednorázové tokeny, typ souboru podle obsahu, bezpečné názvy souborů, iCalendar, výčty e-mailů, porovnání objektů
AdvisorSoft.Utils.Email MailKit, MSAL IEmailSender – SMTP, Exchange Online, Microsoft Graph
AdvisorSoft.Utils.Html Markdig, HtmlSanitizer Markdown → HTML, sanitizace HTML, bezpečný Markdown od uživatelů
AdvisorSoft.Utils.Czech M.E.Http validace IČO/DIČ/RČ/PSČ/účtu, skloňování, klient ARES

Návod na přechod aplikací (APLS, DocumentFlow) je v doc/adopce-apls-documentflow.md, změny v CHANGELOG.md.

Instalace

Balíčky jsou na firemním feedu https://nuget.advisor-soft.com/v3/index.json (čtení anonymní). Doporučené nuget.config s mapováním zdrojů, aby se balíčky nikdy nestáhly odjinud:

<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="advisor-soft" value="https://nuget.advisor-soft.com/v3/index.json" protocolVersion="3" />
  </packageSources>
  <packageSourceMapping>
    <packageSource key="nuget.org"><package pattern="*" /></packageSource>
    <packageSource key="advisor-soft"><package pattern="AdvisorSoft.*" /></packageSource>
  </packageSourceMapping>
</configuration>
dotnet add package AdvisorSoft.Utils.Email

AdvisorSoft.Utils (jádro)

using AdvisorSoft.Utils.Text;       // "Žádost č. 12".ToSlug() → "zadost-c-12", RemoveDiacritics()
using AdvisorSoft.Utils.Querying;   // q.ApplySort("Nazev desc"), DateRanges.ThisWeek(), PredicateDate…
using AdvisorSoft.Utils.Security;   // HmacSignature, SignedToken, OneTimeToken
using AdvisorSoft.Utils.Files;      // FileSignature.DetectMimeType(name, header), FileNames.Sanitize(name)
using AdvisorSoft.Utils.Calendar;   // IcsCalendar.Write(...), IcsEvent
using AdvisorSoft.Utils.Mail;       // EmailAddressList.Normalize("a@x.cz, b@x.cz")
using AdvisorSoft.Utils.Diff;       // ObjectDiff.Compute(before, after, options)
  • Filtrování podle dne v EF Core – PredicateDate.ExprOnDay(x => x.Datum, den) generuje Datum >= den AND Datum < den+1 místo CAST(Datum AS date), takže SQL může použít index.
  • Podepsané odkazy – SignedToken.Create(payload, klic) / TryRead<T>(token, klic, out payload); expiraci si dejte do payloadu a ověřte po přečtení.
  • Jednorázové tokeny – var (token, hash) = OneTimeToken.Generate(); do DB jen hash, ověření OneTimeToken.Matches(token, hash).
  • Upload souborů – typ vždy podle obsahu: FileSignature.DetectMimeType(nazev, prvnich8Bajtu) (null = odmítnout), název přes FileNames.Sanitize.

AdvisorSoft.Utils.Email

using AdvisorSoft.Utils.Email;

builder.Services.AddAdvisorEmailSender(builder.Configuration, o =>
{
    o.DefaultAppPrefix = "[MOJE-APP] ";   // prefix předmětu, pokud ho konfigurace nenastaví
    // o.Mode = EmailSenderMode.Graph;    // vynucený režim (jinak EmailSender:Mode)
});

Registrace přidá přímého odesílatele pod konkrétním typem, pod klíčem EmailSenderKeys.Direct a jako výchozí IEmailSender (jedna instance). Výchozí registraci lze přebít vlastním wrapperem (např. fronta úloh).

Sekce Režim Typ options
EmailSender společná (Mode: Legacy / OnlineExchange / Graph) všechny
SMTP Legacy EmailSenderOptions
ExchangeOnline OnlineExchange ExchangeOnlineEmailSenderOptions
GraphEmail Graph GraphEmailSenderOptions
{
  "EmailSender": {
    "Mode": "Graph",
    "TenantId": "…", "ClientId": "…", "ClientSecret": "…",
    "FromEmail": "automat@firma.cz",
    "AppPrefix": "[APP-TEST] ",
    "UseTestEmails": true,
    "TestEmails": "vyvojar@firma.cz",
    "CCEmails": "",
    "TemplatesFolder": "EmailTemplates"
  }
}
  • UseTestEmails = true přesměruje veškerou poštu na TestEmails (středníkem oddělené).
  • CCEmails = skrytá kopie všech e-mailů v produkčním režimu (místo natvrdo zapsaných adres v kódu).
  • TemplatesFolder – relativní vůči ContentRootPath, nebo absolutní; ReadTemplate(soubor) čte odtud.
  • Graph posílá MIME obsah (limit 4 MB po zakódování); Exchange Online potřebuje v tenantu povolené SMTP AUTH.

AdvisorSoft.Utils.Html

using AdvisorSoft.Utils.Html;

string html = SafeMarkdown.ToHtml(poznamkaOdUzivatele);        // bezpečné do MarkupString / Html.Raw
string email = SafeMarkdown.ToEmailHtml(poznamkaOdUzivatele);  // užší whitelist pro e-mail
string cisty = HtmlSanitization.Default.Sanitize(htmlZEditoru); // sanitizace hotového HTML
string docs = new MarkdownService().MdToHtml(dokumentaceZRepa); // jen důvěryhodný obsah (nesanitizuje)

AdvisorSoft.Utils.Czech

using AdvisorSoft.Utils.Czech;
using AdvisorSoft.Utils.Czech.Ares;
using AdvisorSoft.Utils.Czech.Validation;

IcoValidator.Normalize("6947");               // "00006947" (null = neplatné)
BirthNumberValidator.TryParse("736228/5161", out var narozen, out var pohlavi);
BankAccountValidator.IsValid("19-2000145399/0800");
CzechPlural.Format(5, "terminál", "terminály", "terminálů"); // "5 terminálů"

builder.Services.AddAresClient()               // IAresClient
    .AddStandardResilienceHandler();           // odolnost dle volby aplikace (Microsoft.Extensions.Http.Resilience)

AresLookupResult r = await ares.LookupAsync(ico, nazev);
if (r.IsFound) { var (ulice, mesto) = AresAddressFormatter.Split(r.First!.Address); }

Vývoj

dotnet build AdvisorSoft.Utils.slnx
dotnet test AdvisorSoft.Utils.slnx

Verze = git tag X.Y.Z (MinVer). Vydání: /publish v Claude Code, resp. nugetpub.ps1 (API klíč v NUGET_API_KEY). Lokální ladění s konzumentem bez publikace: deploy/deploy-nuget-local.ps1 -Version 1.0.1-local.1.

No packages depend on AdvisorSoft.Utils.Html.

První samostatné vydání. Kód dřív žil v řešení AIS2 (projekt `src/shared/AdvisorSoft.Utils` a části `AIS.Shared`, `AIS.Polygon`, `AIS.Core`, `AIS.Evs`); historie souborů knihovny je převzatá. Veřejné API má anglické názvy, XML dokumentace je česky. ### AdvisorSoft.Utils (jádro, bez externích závislostí) - `Text.StringExtensions`: `Limit`, `ReplaceAt`, `WhiteSpaceOrValue`, nově `RemoveDiacritics` a `ToSlug`. - `Querying`: `PredicateDate`, `QueryableDateHelpers` (porovnání `DateTime` se dnem bez funkce nad sloupcem), `QueryableSortExtensions` (`OrderByProperty`, `ApplySort("Sloupec desc, Sloupec2")` – názvy nekolidují se System.Linq.Dynamic.Core), `DateRanges`/`DateRange` (dnes, včera, tento/minulý týden od pondělí, měsíc, rok). - `Security`: `HmacSignature` (HMAC-SHA256 podpis kanonického řetězce, ověření v konstantním čase, SHA-256 hex), `SignedToken` (`Base64(JSON).Base64(HMAC)` – formát kompatibilní s callback tokeny AIS2), `OneTimeToken` (jednorázový token do URL + SHA-256 hash pro DB). - `Files`: `FileSignature` (typ souboru podle magic bytes s allow-listem přípon), `FileNames.Sanitize`. - `Calendar.IcsCalendar` + `IcsEvent`: zápis iCalendar (RFC 5545) se skládáním řádků, připomínkami a volitelným PRODID. - `Mail.EmailAddressList`: rozdělení, normalizace a validace výčtu e-mailů v jednom poli. - `Diff.ObjectDiff`: čitelný výpis změn `Pole: 'a' → 'b'` s formátovacími volbami. ### AdvisorSoft.Utils.Email - `IEmailSender` se sendery SMTP, Exchange Online (XOAUTH2/MSAL) a Microsoft Graph, `MimeEmailMessageBuilder`. - Obecná registrace `AddAdvisorEmailSender(configuration, o => …)` s `EmailSenderRegistrationOptions` (názvy sekcí, vynucený režim, `DefaultAppPrefix`); `EmailSenderOptions.TemplatesFolder`. - Změny proti verzi v AIS2 (nekompatibilní): namespace `AdvisorSoft.Utils.Services` → `AdvisorSoft.Utils.Email`, `AddAisEmailSender` → `AddAdvisorEmailSender`, výchozí `AppPrefix` prázdný (dřív `"[AIS] "`), klíč `EmailSenderKeys.Primy` → `EmailSenderKeys.Direct`. - Opraveno: `ExchangeOnlineEmailSender` maže přílohy (`removeAfterSend`) i po chybě odeslání a selhání mazání jen zaloguje. ### AdvisorSoft.Utils.Html - `MarkdownService` (dřív `MarkDownService`): `MdToHtml` pro důvěryhodný obsah, nově `ToSafeHtml`. - `HtmlSanitization` (whitelist pro stránky a užší pro e-maily, odkazy `rel="noopener noreferrer nofollow"`), `SafeMarkdown` (`ToHtml`, `ToEmailHtml`, `ToPlainText` – Markdig `DisableHtml` + sanitizace). ### AdvisorSoft.Utils.Czech - Validátory s normalizací: `IcoValidator` (mod-11, i bez úvodních nul), `DicValidator`, `BirthNumberValidator` (včetně data narození a pohlaví), `PostalCodeValidator`, `BankAccountValidator` (váhy ČNB). - `CzechPlural` (1 terminál / 2 terminály / 5 terminálů). - `AresClient` (`IAresClient`) nad typed `HttpClient` + System.Text.Json: `FindByIcoAsync`, `SearchByNameAsync`, `LookupAsync` (IČO, pak název), `FindCodeListItemAsync`; výsledek `AresLookupResult` se stavem místo výjimek; `AddAresClient()` vrací `IHttpClientBuilder` pro vlastní resilience. `AresAddressFormatter` (ulice s číslem orientačním, PSČ „140 00“, obec bez ulice = část obce + číslo). Celý seznam změn: CHANGELOG.md v balíčku a https://dev.azure.com/advsoft/AdvisorSoft.Utils/_git/AdvisorSoft.Utils?path=/CHANGELOG.md

.NET 10.0

Version Downloads Last updated
1.0.1 162 09/24/2026
1.0.0 12 09/24/2026