mirror of
https://github.com/MAKS-IT-COM/maksit-certs-ui.git
synced 2026-06-10 00:28:11 +02:00
20 KiB
20 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[3.5.1] - 2026-06-02
Release status: 3.3.4 is the last published release. 3.5.1 is a patch on 3.5.0 (startup health, Helm secrets alignment, RBAC docs, Web UI token refresh).
Breaking
- Helm secrets (
certsServerSecrets): RenamedauthSecret→jwtSecret,authPepper→passwordPepper. Bootstrap admin username moved from ConfigMap to secrets asadminUsername(removedcertsServerConfig.configuration.certsEngineConfiguration.admin.username). Update custom values and external secret templates before upgrade.
Added
GET /health/startup: JSON snapshot of phased database and bootstrap startup (CertsStartupState,IDatabaseStartupObserver,DatabaseStartupPhaseRunner).- Web UI:
webUiAuthRefresh.ts— single in-flight JWT refresh shared by axios (andresolveWebUiAccessTokenfor future SignalR hubs). - Docs:
assets/docs/RBAC_REFERENCE.md,assets/docs/USER_AND_API_KEY_RBAC.md; README RBAC overview and table-of-contents links. - E2E:
src/e2e-tests/README.md— PowerShell API-key E2E credentials and compose URL guidance (replacesMaksIT.CertsUI.Client.Tests/README.E2E.md).
Changed
GET /health/ready: Returns HTTP 503 until bootstrap coordination completes (CertsStartupState.IsApplicationReady), then checks PostgreSQL as before.RunMigrationsService: Reports phased startup; waits on maintenance databasepostgresbeforeEnsureDatabaseExistsand on the application database beforeMigrateUp.SchemaSyncService: Reportsschema_syncphase viaIDatabaseStartupObserver(no-op timing whenAutoSyncSchemais false).InitializationHostedService: Records bootstrap coordination phase success/failure inCertsStartupState.CertsEngineConfiguration.ConnectionString:requiredin host configuration (no empty default).IdentityDomainService: Configuration field and error messages useCertsEngineConfigurationnaming (not Vault-eraVaultEngineConfiguration).- Helm: Server
startupProbeon/health/ready(up to ~5 minutes); readinessinitialDelaySecondsreduced to 5;NOTES.txtdocuments/health/startupand external Postgres. - README / Compose examples: Admin username in
appsecrets.jsononly; JWT/pepper placeholder names aligned with Helm. - Dependencies: linq2db 6.3.0, Microsoft.Extensions.* 10.0.8, Npgsql 10.0.3, Swashbuckle 10.2.1, Testcontainers.PostgreSql 4.12.0, Microsoft.NET.Test.Sdk 18.6.0, PowerShell System.Management.Automation 7.6.2.
Removed
MaksIT.CertsUI.Client.Tests:CertsUiApiKeyE2ETestsandREADME.E2E.md(API-key E2E remains undersrc/e2e-tests/and PowerShell scripts).
Upgrade notes (from 3.5.0)
- Helm: Rename secret keys in
certsServerSecretsand setadminUsername; remove admin username from non-secret ConfigMap overrides if you duplicated it there. - Probes: Use
/health/startupfor startup diagnostics; keep load balancers on/health/ready(503 until the cluster has a bootstrapped user).
[3.5.0] - 2026-05-24
Release status: 3.3.4 is the last published release. 3.5.0 consolidates all changes since 3.3.4 (HA, Engine/Vault alignment, client libraries, Web UI shared packages).
Breaking
- HA / interactive ACME: Removed
IPrimaryReplicaWorkload,PrimaryReplicaGate,PrimaryReplicaShutdownHostedService, andCertsFlowPrimaryReplica. All replicas may run configure-client, init, orders, challenge completion, certificate download, apply, and revoke. The API no longer returns HTTP 503 withurn:maksit:certs-ui:primary-replica-required. Clients that retried on that signal should use normal error semantics only. - HTTP-01 challenge:
AcmeChallengeAsyncno longer writes tokens underAcmeFolderor reads legacy on-disk files. Challenge text is served from PostgreSQL only; ingress must reachGET /.well-known/acme-challenge/{token}on this app (or equivalent). - Startup / filesystem: Removed the shared
initmarker underDataFolder,AcmeFolder, andDataFoldersettings, and default server acme/data PVC mounts. Followers wait until the database reports at least one user. - Configuration:
CertsUIEngineConfigurationrenamed toCertsEngineConfigurationin appsettings, Helmvalues.yaml, and secrets templates. - Engine layout:
Persistance→Persistence;CertsLinq2DbMapping→CertsUILinq2DbMapping. - Engine query ports (Vault-style):
IUserQueryService,IApiKeyQueryService, andIApiKeyEntityScopeQueryServiceuse synchronousSearch/Countwith optionalExpression<Func<TDto, bool>>?predicates,skip/limit, andResulttypes — not async pagedSearch…Asyncwith string filters. - ACME session persistence:
IAcmeSessionStore,AcmePostgresSessionStore,AcmeSessionSnapshot, andAcmeSessionJsonSerializerremoved.ILetsEncryptServicedepends onIAcmeSessionPersistenceService(AcmeSessionPersistenceServiceLinq2Db) foracme_sessionsJSON load/save. ICertsFlowDomainService: Constructor takesIRegistrationCacheDomainServiceinstead ofIRegistrationCachePersistenceService.- Web UI: Removed the in-repo shared UI stack (layout, DataTable, form editors, deep/enum helpers, local toast). The SPA depends on
@maks-it.com/webui-core,webui-components, andwebui-contracts(private npm registry;src/MaksIT.WebUI/.npmrc). - E2E tests:
CertsUiApiKeyE2ETestsremoved fromMaksIT.CertsUI.Tests; API-key E2E lives inMaksIT.CertsUI.Client.Tests(Category=E2E). - Terms of Service API: Interactive ACME uses only
GET /api/certs/{sessionId}/terms-of-service(statelessisStagingvariant removed). - Startup migrations: Removed legacy EF-era baseline,
VersionInfo→version_inforename repair, PascalCase → snake_case column repair, andRunMigrationsService.BaselineVersion.MigrateUpexpects schema managed only by in-process FluentMigrator migrations. - Database:
users.JwtTokensJsonremoved; sessions live injwt_tokensonly (no duplicate JSON onusers). - Deprecated host: Removed legacy
MaksIT.WebapiandMaksIT.Webapi.Testsin favor ofMaksIT.CertsUI/MaksIT.CertsUI.Tests.
Added
MaksIT.CertsUI.Client: HTTP client library with API key auth (ICertsUIClient,CertsUIClient,ServiceCollectionExtensions,CertsUIApiException).MaksIT.CertsUI.Contracts: Shared wire types (AccountResponse,HostnameResponse,RuntimeInstanceIdResponse).MaksIT.CertsUI.Client.PowerShell: Binary module (Connect-CertsUI,Get-CertsUIAccounts,Invoke-CertsUICreateAccount, etc.; requires PowerShell 7 on .NET 10).MaksIT.CertsUI.Client.Tests: Unit tests plus relocated API-key E2E suite.- PowerShell E2E:
src/e2e-tests/scenarios andTest-CertsUiApiKeyE2E.ps1/.bat(Vault-styleCERTSUI_E2E_CREDENTIALS). - Docs:
assets/docs/POWERSHELL_CLIENT_MODULE.md,assets/docs/ARCHITECTURE_LAYERING.md, HA and login architecture docs; CONTRIBUTING.md links layering doc anddotnet testguidance. - New backend host:
MaksIT.CertsUIWebAPI with controllers, JWT and JWT-or-API-key authorization, hosted services, and mapping/configuration abstractions. - Engine platform: Domain-oriented
MaksIT.CertsUI.Engine(Domain,Dto,DomainServices,Persistence,QueryServices,Infrastructure,FluentMigrations) with Linq2Db mappings and migration services. - Engine (Vault parity):
EntityScopeBase;UserAuthorization/ApiKeyAuthorizationaggregates; splitUserEntityScope/ApiKeyEntityScope;IdentityDomainService/ApiKeyDomainServicerefactor aligned with MaksIT.Vault. ExpressionComposefor composing nested Linq2Db predicates.IRegistrationCacheDomainService/RegistrationCacheDomainService,RegistrationCachePayloadDocument, andRegistrationCachePayloadJsonTests.IAcmeSessionPersistenceService,AcmeSessionPersistenceServiceLinq2Db, andAcmeSessionPayloadMapperfor PostgreSQL-backed ACMEState.PostgresStartupWait— waits for PostgreSQL and retries FluentMigratorMigrateUpon transient startup failures.- API / RBAC:
GetActingJwtTokenDatamaps API keys to a syntheticJwtTokenDataprincipal;RbacHelpers.EnsureActorMayAssignGlobalAdmin/EnsureActorMayPatchGlobalAdminFlag. - HA runtime coordination: DB-backed HTTP-01 challenge persistence and runtime leases (
acme_http_challenges,app_runtime_leases,acme_sessions,terms_of_service_cache); coordinated bootstrap and renewal execution. - Kubernetes: Per-component Helm
replicaCount, PodDisruptionBudget support, health endpoints (/health/live,/health/ready), optionalkubernetesUpstreamHostsfor in-cluster YARP upstreams. - LetsEncrypt: Per-host ACME rate-limit cooldown on
RegistrationCache;AcmeProblemKindenumeration; in-memoryAcmeSessionStore(later superseded by PostgreSQL persistence); partialLetsEncryptServicefiles;State.TryGetAccountKey;LetsEncrypt.Testsfor retry parsing and cooldown JSON. - Frontend: Users/API Keys pages and forms; identity/API-key UX with list/filter/paging (later migrated to
webui-*packages). - Test suite:
MaksIT.CertsUI.TestsandMaksIT.CertsUI.Engine.Testswith Postgres/WebAPI fixtures. - Release tooling:
DotNetDockerPushper-imageversionEnvFiles(temporaryVITE_APP_VERSIONrewrite) and optional per-imagecontextPath(upstreamed to maksit-repoutils 1.0.11). - Helm / config:
certsEngineConfiguration.autoSyncSchema(defaulttrue) for add-only column sync on startup.
Changed
- Identity / API key controllers: Use
GetActingJwtTokenDatainstead of JWT-onlyGetJwtTokenDatafor user and API-key CRUD/search. - IdentityService / ApiKeyService: Build predicates and call
Count+Searchon query services; thin-search wiring (Pattern B). - Web UI: Migrated to
@maks-it.com/webui-*packages;createWebUiHttpClient;apiRoutes.ts; pages undersrc/pages/;webUi/dataSources.ts; models reorganized under domain folders aligned withwebui-contracts. Earlier step:axiosConfighelpers return{ payload, status, ok }. - ACME sessions: Let's Encrypt client
Statepersisted in PostgreSQLacme_sessionsso any replica can continue after load balancing. - LetsEncrypt /
HttpClient:ConfigureClientuses absolute ACME directory URL instead of assigningBaseAddresson the shared client. CertsFlowDomainService:PurgeStaleHttpChallengesAsync(HTTP-01 cleanup);AutoRenewalcalls it before renewal work; skips hostnames in ACME cooldown window.LetsEncryptService: UsesIAcmeSessionPersistenceService; droppedNewtonsoft.Jsonfrom Engine (STJ-only JSON paths).CacheService: Thin façade overIRegistrationCacheDomainService.- Bootstrap / renewal:
InitializationHostedServiceacquirescerts-ui-bootstrap(RuntimeLeaseNames.BootstrapCoordinator) for empty-database admin creation, then releases.AutoRenewalacquirescerts-ui-renewal-sweep(RuntimeLeaseNames.RenewalSweep) per sweep. Lease namecerts-ui-primaryreplaced by bootstrap and renewal sweep constants. - HA / ToS cache: Terms of Service PDF caching moved from pod filesystem to PostgreSQL
terms_of_service_cachewith TTL/HTTP validators. - FluentMigrator: Standard
VersionInfotable and columns;.ScanIn(…).For.All()discovery; migrations run inProgram.csafterBuild()before hosted services; logged host/database and migration count; coordination DDL repair afterMigrateUpwhen tables missing despite applied version. - Schema sync:
AutoSyncSchemaadd-only (ADD COLUMN IF NOT EXISTS; no DROP); desired map includesusers.IsActive,TwoFactorSharedKey. - Docker Compose / Helm: YARP upstream env vars for in-cluster vs Compose hostnames;
components.server.service.sessionAffinitydefaults tofalse(stateless LB);certsClientRuntime.apiUrldefaults to/api; optionalpreStopsleep andterminationGracePeriodSecondsfor rolling updates. - Container image:
MaksIT.CertsUIDockerfile installslibgssapi-krb5-2for Npgsql GSS support on slim images. - Namespace and solution layout: Standardized around
MaksIT.CertsUI*host/engine split; ACME contracts moved from legacyEntities/ModelsintoDomain/Dto. - LetsEncrypt: Broader nullable annotations;
CachedHostnameprimary constructor; certificate loading viaX509Certificate2.CreateFromPem/X509CertificateLoader.LoadCertificate. - Integration tests:
InMemoryUserStore,CacheServiceTests,CertsFlowServiceTests,ApiKeyQueryServiceIntegrationTests,AccountServicePatchAccountIntegrationTestsaligned with new ports. - README: Architecture references, HA guidance, E2E instructions for dotnet test and PowerShell scenarios.
Fixed
- Startup / HA: Bootstrap lease no longer blocks extra replicas when users already exist; cooperative cancel on host shutdown;
CoordinationTableProvisionerwith explicitpublic.*DDL;RuntimeLeaseServiceNpgsqlusespublic.app_runtime_leases; post-migrate verification for coordination tables. - FluentMigrator: Empty connection string no longer puts runner in connectionless/preview mode; throw when engine connection string missing; maintenance DB bootstrap warns instead of failing when role cannot
CREATE DATABASE. - Identity / PostgreSQL:
users.JwtTokensJsoncolumn dropped; new inserts no longer hit23502; token rows normalized intojwt_tokens. - Helm / reverseproxy: YARP upstreams no longer default to unresolvable Compose hostnames in Kubernetes when
kubernetesUpstreamHostsis enabled. - LetsEncrypt:
RevokeCertificatefails correctly on non-success; disposes HTTP response on success;NewOrderlogs authorization status;TryGetCachedCertificatereturnsfalsewhen private key blob missing. AccountService.PatchAccountAsync: Returns account built from cache after reload, not stale in-memory instance.- WebUI Terms of Service: PDF worker loaded from Vite-bundled asset (
pdf.worker.min.mjs?url) for dev and production.
Removed
CertsFlowPrimaryReplica,PrimaryReplicaRequiredObjectResult,CertsFlowResultExtensions/ToCertsFlowActionResult;CertsFlowControllerusesToActionResult().- Web UI (local):
DataTable,FormLayout,Layout,LazyLoadTable, editor components,Toast,Offcanvas,useFormState,localStorage/identity, legacyfunctions//models/trees superseded bywebui-*packages. - Web UI: Primary-replica 503 auto-retry in
axiosConfig.ts. - Configuration / Helm:
AcmeFolder,DataFolder, default acme/data PVC mounts;AddMemoryCache()host registration (unused). - Legacy engine layout: Obsolete top-level engine files, old
.vscodeproject files.
Upgrade notes (from 3.3.4)
3.3.4 is the last published release. 3.5.0 uses a new host, PostgreSQL-backed registration cache, and FluentMigrator schema — there is no in-place migration of Let's Encrypt account material from 3.3.4. Use backup → install → restore:
- On 3.3.4 (before upgrade): Sign in to the Web UI, open Utilities, and Download cache files (full registration-cache ZIP). Store the file safely — it contains your Let's Encrypt account keys and cached certificate data. Optionally export Postman/API backups of any other settings you rely on.
- Prepare 3.5.0: Provision a new empty PostgreSQL database (or drop and recreate the engine database). Update Helm/secrets: rename
certsUIEngineConfiguration→certsEngineConfiguration, setConnectionString, and remove legacyacme/databind mounts fromdocker-compose.override.ymlif present. - Deploy 3.5.0: Install the new server, client, and reverse-proxy images (pin tags to
3.5.0, notlatest). On first start, FluentMigrator creates the schema; bootstrap creates the default admin when the database has no users. - Restore accounts: Sign in on 3.5.0, open Utilities, and Upload cache files with the ZIP from step 1. Verify accounts and certificates in the UI before decommissioning 3.3.4.
- Re-create operators: Users, API keys, and JWT sessions from 3.3.4 are not migrated automatically — recreate users/API keys in 3.5.0 as needed.
Also check when upgrading:
- Operations: Retarget alerts from lease
certs-ui-primarytocerts-ui-bootstrapandcerts-ui-renewal-sweep. - Web UI build: Configure npm auth for
@maks-it.com/*(seesrc/MaksIT.WebUI/.npmrc) when building the client image locally. - E2E:
dotnet testonMaksIT.CertsUI.Client.TestswithCategory=E2E; setCERTSUI_E2E_EXPECT_MIN_DISTINCT_INSTANCES=2for HA (PowerShell E2E defaults to 1 for Docker Compose). - Repo utils:
utils/refreshed from maksit-repoutils 1.0.14 (engines/,plugins/,modules/,tools/). Runutils\Invoke-ReleasePackage.batfor release;utils\Invoke-TestEngine.batfor tests and coverage badges; refresh viautils\Update-RepoUtils.bat(setdryRun: false inutils/tools/Update-RepoUtils/scriptSettings.json).
[3.3.4] - 2026-04-01
Added
MaksIT.Webapi.Tests: service-level unit tests (settings, cache, identity, agent, account, certs flow) and domain tests forSettings.- Postman collections under
src/Postmanupdated to match currentMaksIT.Webapiroutes, JWT flow, and cache endpoints.
Fixed
- WebUI Terms of Service (Let's Encrypt): PDF viewer loads
pdfjs-distworker from a Vite-bundled asset (pdf.worker.min.mjs?url) so rendering works in dev and production instead of failing on missing or wrong worker URLs. AccountService.PatchAccountAsyncreturns the account built from the cache after reload, not a stale in-memory instance.
[3.3.3] - 2025-12-20
Changed
- Relicensed project from GPL-3.0 to Apache-2.0.
[3.3.2] - 2025-12-20
Changed
- Minimal Helm chart and documentation improvements.
[3.3.1] - 2025-11-22
Changed
- Public release following the v3.3.0 pre-release.
[3.3.0] - 2025-11-15
Changed
- Pre-release of the v3.3.x line.
[3.2.0] - 2025-09-11
Added
- New WebUI with authentication.
[3.1.0] - 2024-08-11
Changed
- Stabilized release following v3.0.0.
[3.0.0] - 2024-05-31
Added
- WebAPI and containerization.
[2.0.0] - 2019-11-01
Changed
- Dependency injection pattern implementation.
[1.0.0] - 2019-06-29
Added
- Initial release.