Skip to content

Releases: ipjohnson/Hardened.Framework

v0.43.0-rc1000

v0.43.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 14 Oct 20:47
399c088

What's Changed

  • Document where the JWT attribute goes, contract-first JWT, and a token whose nbf is after its exp by @ipjohnson in #587
  • Document referencing a library, the Lambda Program.cs, and stream refusal media types by @ipjohnson in #588
  • Correct cors.md on Vary: Origin and the ASP.NET Core logging filter by @ipjohnson in #589
  • Log the response mode variable once in the SSE buffered-mode warning by @ipjohnson in #590
  • Log line and template .gitignore fixes by @ipjohnson in #591
  • Cover Hardened.Web.Testing for PR #592 by @ipjohnson in #593
  • Give Returns() results Headers and name field errors in its failures by @ipjohnson in #592
  • Payload 1.0 and uniform problem details by @ipjohnson in #594
  • Report every missing JWT setting in one startup failure by @ipjohnson in #595
  • Document data access, Lambda cold start, SAM and idempotency keys by @ipjohnson in #596
  • A generated doc comment has two lines by @ipjohnson in #597
  • Warn on an inline [Pattern] in the hardened-web template by @ipjohnson in #598
  • Expose WWW-Authenticate to cross-origin scripts by default by @ipjohnson in #599
  • Resolve a configuration-model interface named as a handler parameter by @ipjohnson in #600
  • Load HardenedCoreModule beside a test's entry point by @ipjohnson in #601
  • Write aws-lambda-tools-defaults.json beside each Lambda project in the templates by @ipjohnson in #603
  • Keep a relative servers URL and the whole info object in the generated document by @ipjohnson in #602
  • Scaffold a [LambdaWebTesting] test class in the aws-lambda web template by @ipjohnson in #604
  • Delete stale OpenAPI, Smithy and validator outputs after a contract rename by @ipjohnson in #605
  • Publish no 403 for [Authorize] alone by @ipjohnson in #606
  • Log the Hardened environment on the ASP.NET Core host by @ipjohnson in #607
  • Send the /docs request panel to the served origin in development by @ipjohnson in #608
  • Document named-argument construction for generated models by @ipjohnson in #609
  • Send messages unescaped and leave failure media types out of the 406 by @ipjohnson in #610
  • Generate ToWire beside TryParseWire on enum converters by @ipjohnson in #611
  • Publish problem type and Location as uri-reference strings by @ipjohnson in #612
  • Name the member's type when a record member has a value of the wrong type by @ipjohnson in #613
  • Publish minLength 1 on a [Required] string that refuses an empty one by @ipjohnson in #614
  • Publish a code-first parameter's default in its schema by @ipjohnson in #615
  • Declare 415 on every operation that reads a body by @ipjohnson in #616
  • Let a change façade send a transition with distinct before and after rows by @ipjohnson in #618
  • Report the time until a permit returns in RateLimit-Reset by @ipjohnson in #617
  • Report every parameter binding failure with the constraint errors beside it by @ipjohnson in #619
  • Report every undeclared enum value in a JSON body beside the other errors by @ipjohnson in #621
  • Let a test assembly reuse one container on the pipeline host by @ipjohnson in #623
  • Release 0.43.0-rc1000 by @ipjohnson in #624

Full Changelog: v0.42.0-rc1000...v0.43.0-rc1000

v0.42.0-rc1000

v0.42.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 29 Sep 10:39
416d938

New packages

  • Hardened.Requests.Jwt validates JWT bearer tokens. It depends on Microsoft.IdentityModel.JsonWebTokens 8.23.0, and it is the only package that does. Hardened.Requests.Jwt.Testing mints tokens for tests (#510).

Breaking changes

Source and binary

  • Hardened.Shared.Runtime.Json.IJsonSerializerConfiguration and JsonSerializerConfiguration are renamed to ISharedJsonConfiguration and SharedJsonConfiguration. The Hardened.Requests.Runtime.Configuration pair is unchanged (#506).
  • The constructors of ExecutionRequestHandlerInfo and ResponseCacheFilter gained trailing optional parameters, and the constructors of AotJsonSerializer and JsonSerializerImpl changed a parameter type. A library compiled against 0.41.0-rc1000 must be rebuilt, because its generated handler info calls the old constructor (#476, #491, #506).
  • [EnvironmentValue] is now valid on a method, a class and an assembly, with AllowMultiple = true. It no longer compiles on any other target (#482).
  • Hardened.Refit.Testing depends on Refit 16.3.0, up from 8.0.0. A test project that pins Refit 8 must move to 16.3.0 (#480).
  • The hardened-web template pins Refitter 2.2.1 and sets "optionalParameters": true in .refitter. A regenerated client makes optional parameters optional arguments, and a streamed operation returns IAsyncEnumerable<T> (#480).
  • An OpenAPI scalar request body with a format binds to the formatted type. int64 binds to long, date-time to DateTimeOffset and binary to byte[]. The handler's parameter type changes (#477).

Diagnostics

  • HSMT035 is a new error. It fires on a Smithy @paginated trait that names a missing member or a member of the wrong type. The Smithy CLI already refuses these models, so only a committed AST reaches it (#511).
  • HRDR011 is reported at the handler's method name in the project that compiles the handler. A handler project with no entry point can now fail with it (#506).
  • HRDW009 is a new warning. It fires when a [CacheResponse<VaryByQuery>] key names no query key the operation binds (#506).
  • HRDR012 now covers contract-first operations. It warns on a declared media type that nothing writes (#472).
  • A build that skips the extract task reports that task's last warnings again, such as HSMT006. With warnings as errors, every incremental build fails, not only the first (#479).

Wire behaviour

  • Problem records such as NotFound, Conflict and BadRequest implement IProblemDetails and go out as application/problem+json. A failure negotiates within the media types its operation declares for failures (#472).
  • A framework refusal at a status where the operation declares its own body sends that body. This covers validation, a malformed body, a deadline, a binding BadRequestException, an unhandled 500 and the 406. A validation failure at a declared status carries no field errors (#473).
  • A path value that fails an OpenAPI pattern or a Smithy @pattern label answers 400 naming the parameter. It used to answer 404 with no body (#475).
  • In throws mode, a thrown framework record under a contract that declares its own body at that status sends the declared body (#476).
  • A Smithy @httpPayload blob and an OpenAPI format: binary body are the raw request body. A client that sent base64 in a JSON string must send the bytes (#477).
  • A Smithy error member with @httpHeader is sent as a response header and left out of the body. A service's errors apply to every operation in it, so an operation's 400 can become the service's declared error in place of RequestValidationError (#478).
  • [Authorize<TScheme>], [AuthorizeGrants] or another IAuthorizeAttribute on a [HardenedModule] class guards every handler compiled with that module. It used to guard nothing, so anonymous requests those handlers served now get 401. [AllowAnonymous] on a handler still exempts it (#470).
  • The health probes send {"status":"Healthy"} over Kestrel and ASP.NET Core. They used to send an empty 200 (#487).
  • A handler that cleared ShouldSerialize, set a status and then threw before writing answers with the failure's status and body. It used to answer the status it had set, with no body (#487).
  • A CorsConfiguration registered in a library module takes effect on the host. A route with [Cors], and every response once an origin is configured, carries Vary: Origin. A preflight allows the headers the operation reads (#506).
  • A response that compression would compress carries Vary: Accept-Encoding even when it goes out uncompressed, and so does /openapi.json (#506).
  • A [CacheResponse<VaryByQuery>] with no keys varies on every query key the operation binds. It used to throw while the chain was built (#506).
  • In a contract-first implementation, the method's filters come before the class's, and the method's [Timeout] wins. With a class and a method [CacheResponse], the method's key parts come first, so existing cache keys change (#506).
  • A stream that times out before its first item answers its timeout status, 504 by default, with its body. It used to answer 500 with no body (#506).
  • A stream reads Accept. Under Strict negotiation, a request whose Accept names types but not the stream's media type gets 406 (#506).
  • On AWS Lambda and Azure Functions, a request with no Accept header names nothing. These hosts used to read it as application/json (#506).
  • A request cancelled on its own token is logged as one Information line with event id 78006. It used to be logged at Error with a stack trace (#506).
  • A body whose Content-Type no deserializer reads answers 415 with an Accept header. It used to be read as JSON. A body with no Content-Type is still read as JSON, and text/json and +json types are now read as JSON (#506).
  • The test harness sends application/json for a body with no Content-Type (#506).
  • On Kestrel and ASP.NET Core, a body over MaxRequestBodySize answers 413. It used to answer 500 (#506).
  • A DateTimeOffset in a JSON request body must state its offset. 2030-01-01T00:00:00 gets 400. Query, route and header values are unchanged (#506).
  • The 400 message for a value of the wrong type changed. "The JSON value could not be converted to System.Int32." is now "The value is not an integer this field can hold." (#506).
  • A Lambda function with no HARDENED_ENVIRONMENT defaults to production when AWS_LAMBDA_RUNTIME_API is set, so it no longer serves /docs. A local run through LambdaEmulator.StartIfLocal stays development (#506).
  • Environment values are parsed with the invariant culture, and a Nullable<T> converts as its underlying type (#506).
  • A spec-first body whose constraints exist only in the models it holds is validated. Requests that used to reach the handler can now get 400 (#509).
  • On Lambda, startup services run as the bootstrap's initializer, and one that throws is reported as an init error. A function whose AWS_LAMBDA_LOG_FORMAT is not JSON logs a warning at startup. LambdaEmulator.StartIfLocal sets it to JSON (#508).

Published OpenAPI document

  • A failure status whose bodies are all problem records is published under application/problem+json (#472).
  • An operation guarded by a module-level requirement publishes security, a 401 and a 403. An [AllowAnonymous] method under a guarded class no longer publishes its class's requirement (#470).
  • Every guarded operation publishes a 401 with WWW-Authenticate. When the document declares exactly one scheme, a guarded operation that names none is published under it. The 403 lists a WWW-Authenticate header (#486).
  • A [Required] member no longer publishes null in its schema (#506).
  • Without [OpenApiInfo], the title is the assembly's name, not the module's class name (#506).
  • [ConditionalGet] publishes If-Modified-Since only where the operation declares Last-Modified on its 200, with [AnswersHeader(200, KnownHeaders.LastModified)] (#506).
  • [RateLimit] publishes RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset on every response the operation lists (#506).
  • A header-bound Smithy member is no longer listed under the body schema's properties (#478).
  • A path parameter with a pattern publishes the validation 400 (#475).

Testing

  • [Shared] is honoured by Kiota clients, by a factory that calls context.CreateHttpClient, beside [Grants], [Subject] or [Anonymous], and by a shared ITestWebApp's clients. Tests that relied on a fresh container per request there now share one (#481).
  • TestWebResponse.Deserialize<T>() and DeserializeAsyncEnumerable<T>() read with the application's JSON options and resolvers (#482).

What's Changed

  • Store the handler's 200 when a revalidation fills the response cache by @ipjohnson in #468
  • Apply [Authorize] on a module class to every handler compiled with it by @ipjohnson in #470
  • Send problem documents as application/problem+json by @ipjohnson in #472
  • Send the declared body for the framework's own refusals by @ipjohnson in #473
  • Answer a path value that fails its pattern with 400, not a bodyless 404 by @ipjohnson in #475
  • Send a thrown framework record as the body the contract declares by @ipjohnson in #476
  • Bind a described binary request body to the raw bytes by @ipjohnson in #477
  • Bind a Smithy error's header members and apply a service's errors by @ipjohnson in #478
  • Replay a build task's warnings, prune stale generated files, and fix two Smithy notes by @ipjohnson in https://githu...
Read more

v0.41.0-rc1000

v0.41.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 26 Sep 12:33
4d2a7cd

Breaking changes

  • Hardened.Validation.SourceGenerator is removed. Replace <PackageReference Include="Hardened.Validation.SourceGenerator" /> with <PackageReference Include="ValidationModules.SourceGenerator" Version="1.2.0" />. A nested type's validator is renamed from InnerValidator to Outer_InnerValidator. HRDV002, HRDV003 and HRDV004 are gone. A project with two [HardenedModule] classes now reports VM6001 (#432).
  • ValidationModules 1.2.0 changes [StringLength]. [StringLength(min, max)] no longer compiles, and [StringLength(n)] is now a maximum of n where it was a minimum. A value that times out a pattern answers 400 instead of 500 (#431).
  • Every entity tag [ConditionalGet] computes changes, because tags are now SHA-1. A client holding an old tag gets a 200 with the new tag on its first conditional request after the upgrade, and 304s after that. A response cache store an application wrote that outlives the deploy replays each entry's old tag until the entry expires (#435).
  • IOFilterProvider and AsyncEnumerableIoFilter each gained an optional IMemoryStreamPool constructor parameter. Source that calls them compiles unchanged. A binary compiled against 0.40.0 that calls either constructor must be rebuilt (#434).

What's Changed

  • Move repeated project settings into props files, pack the solution, and prune redundant references by @ipjohnson in #430
  • Take ValidationModules 1.2.0 by @ipjohnson in #431
  • Replace Hardened.Validation.SourceGenerator with ValidationModules' generator by @ipjohnson in #432
  • Write each streamed item to the transport as one write by @ipjohnson in #434
  • Tag conditional responses with SHA-1 and hold the body in a pooled MemoryStream by @ipjohnson in #435
  • Release 0.41.0-rc1000 by @ipjohnson in #436

Full Changelog: v0.40.0-rc1000...v0.41.0-rc1000

v0.40.0-rc1000

v0.40.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 25 Sep 18:46
7d2ff0c

Security

  • Azure Functions enforced no authorization. On every release up to and including 0.39.0-rc1000, the isolated worker never ran the application's startup services, so authorization, authentication and CORS were not installed. Under [RequireAuthorization] or [AuthorizeGrants], a guarded HTTP route answered a caller with no credential. The trigger is emitted at AuthorizationLevel.Anonymous, so function keys were not a backstop. Fixed by #395 (#386, #412). Upgrade any Azure Functions application that uses Hardened's authorization.
  • A MessagePack request body could stop the process. Bodies were read with TrustedData, which sets no depth limit, so a small, deeply nested body ended in a StackOverflowException, which cannot be caught. Bodies are now read with UntrustedData (#404). An application that set its own MessagePackSecurity keeps it.

Breaking changes

  • Hardened.Shared.Testing.xUnit and Hardened.Shared.Testing.NUnit are removed, and [HardenedTest] with them. A test project uses [ModuleTest] from DependencyModules.xUnit, DependencyModules.xUnit4 or DependencyModules.NUnit. CurrentTest and ICurrentTestProvider are removed from Hardened.Shared.Testing (#424).
  • A form handler answers 415 for a body that is not a form, and 413 for a url-encoded body over FormConfiguration.MaxBodyBytes. A form with more than 1,024 fields answers 400. A FormatException thrown by a handler answers 500 instead of 400 (#420).
  • HAUTH002 is a new warning: [AllowAnonymous] cancels an authorization attribute on the same handler's method (#423). A build that treats warnings as errors fails on it.
  • A <see cref> in a handler's doc comment now puts the name it points at into the OpenAPI summary or description, in place (#428). An exported document changes for every handler that uses one.

What's Changed

  • Rewrite the documentation site by @ipjohnson in #389
  • Fix UseHttps and SIGTERM on the Kestrel host, and run startup services on Azure Functions by @ipjohnson in #395
  • Install Azure Functions Core Tools from its GitHub release by @ipjohnson in #403
  • Read MessagePack request bodies with UntrustedData by @ipjohnson in #404
  • Keep Roslyn out of applications, and stamp the release version into the assemblies by @ipjohnson in #413
  • Refuse oversized and non-form bodies on form handlers, and answer a handler's FormatException with 500 by @ipjohnson in #420
  • Count keys and headers against the response cache's size limit, and document cache durations from configuration by @ipjohnson in #421
  • Give contract patterns a match timeout, and add [ValidateNever] to skip validation by @ipjohnson in #422
  • Warn when [AllowAnonymous] cancels a handler's requirement, and document cross-site requests and public trigger services by @ipjohnson in #423
  • Serve a run-time static content directory under a route prefix by @ipjohnson in #425
  • Replace [HardenedTest] with DependencyModules' [ModuleTest], and remove the runner packages by @ipjohnson in #424
  • Accept a Lambda deadline more than 49.7 days away by @ipjohnson in #427
  • Ship symbol packages and XML documentation from every Hardened library by @ipjohnson in #428
  • Release 0.40.0-rc1000 by @ipjohnson in #429

Full Changelog: v0.39.0-rc1000...v0.40.0-rc1000

v0.39.0-rc1000

v0.39.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 24 Sep 17:26
2aa7338

What's Changed

Full Changelog: v0.38.0-rc1000...v0.39.0-rc1000

v0.38.0-rc1000

v0.38.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 23 Sep 20:32
23efb61

Breaking changes

  • A spec-first property that references a named map is now Dictionary<string, T>? rather than JsonElement? (#382). Handler code that read it as a JsonElement stops compiling.
  • HRDW007 fails the build for a [FromForm] or [FromQueryString] model the binder cannot construct (#381). Before this release such a parameter compiled and answered 400 to every request.

What's Changed

Full Changelog: v0.37.0-rc1000...v0.38.0-rc1000

v0.37.0-rc1000

v0.37.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 17 Sep 15:19
978cf39

What's Changed

  • Escape a backslash when the handler catalog writes a C# literal by @ipjohnson in #368
  • Record an attributed parameter as unresolved rather than dereferencing null by @ipjohnson in #369
  • Give a registered route its own operation by @ipjohnson in #370
  • Hold a lambda registration to the constraint its tokens need by @ipjohnson in #371
  • Read what a lambda registration declares about its response by @ipjohnson in #372
  • Answer with the bytes a response set's success case carries by @ipjohnson in #373
  • Drop the async from a binder that has nothing to await by @ipjohnson in #375
  • Write the object under the portable name in the blob adapters by @ipjohnson in #376
  • Verify the combinations the templates refuse by @ipjohnson in #377
  • Take validators from ValidationModules' own generator by @ipjohnson in #378
  • Carry Ok's single header without a dictionary by @ipjohnson in #379
  • Release 0.37.0-rc1000 by @ipjohnson in #380

Full Changelog: v0.36.0-rc1000...v0.37.0-rc1000

v0.36.0-rc1000

v0.36.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 14 Sep 15:45
a3d7a8d

What's Changed

  • Write the documented version in one place by @ipjohnson in #354
  • Use a semicolon body for type declarations with no members by @ipjohnson in #355
  • Adopt CSharpier as the formatter by @ipjohnson in #356
  • Render a view for every caller, and publish what it writes by @ipjohnson in #357
  • Key a cached response on the representation it holds by @ipjohnson in #358
  • Bind a byte[] or Stream body to the bytes by @ipjohnson in #359
  • Register routes whose paths only exist at run time by @ipjohnson in #360
  • Register a route with a lambda by @ipjohnson in #361
  • Describe the registered routes in the document by @ipjohnson in #362
  • Speed up route matching and fix a generator crash by @ipjohnson in #363
  • Write path tokens into the request, not into RequestHandlerInfo by @ipjohnson in #364
  • Read the registered-routes documentation as one page by @ipjohnson in #365
  • Run a Hardened application as a Cloud Functions 2nd gen function by @ipjohnson in #366
  • Release 0.36.0-rc1000 by @ipjohnson in #367

Full Changelog: v0.35.0-rc1000...v0.36.0-rc1000

v0.35.0-rc1000

v0.35.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 13 Sep 16:11
c3701cd

What's Changed

  • Rewrite validation, routing and response caching in Simple Technical English by @ipjohnson in #347
  • Decode MessagePack in the reference page, and restore a nested case type's schema by @ipjohnson in #348
  • Verify the constraints the templates declare, on the wire and in the document by @ipjohnson in #349
  • Describe seven things the generated document was getting wrong by @ipjohnson in #350
  • Support static handler methods by @ipjohnson in #351
  • Describe rendering HTML from a .cshtml view in the README by @ipjohnson in #352
  • Point the documentation at 0.35.0-rc1000, and open the 0.36.0 line by @ipjohnson in #353

Full Changelog: v0.34.0-rc1000...v0.35.0-rc1000

v0.34.0-rc1000

v0.34.0-rc1000 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 12 Sep 16:15
753918c

What's Changed

  • Issue a 13-character correlation id when nothing is tracing by @ipjohnson in #333
  • Decide the response content type at compile time by @ipjohnson in #334
  • Remove three allocations from the path every request takes by @ipjohnson in #335
  • Gate allocation on every pull request, and give the harnesses their 404 back by @ipjohnson in #336
  • Serve MessagePack, and describe every media type an operation produces by @ipjohnson in #338
  • Move the build inputs out of the repository root, and stop tracking .claude by @ipjohnson in #337
  • Carry a MessagePack key from the contract to the generated client by @ipjohnson in #339
  • Skip a verb attribute on an interface instead of crashing the generator by @ipjohnson in #340
  • Give each template its own options table in the README by @ipjohnson in #341
  • Give the generated client a MessagePack serializer, and say what Refit will not do by @ipjohnson in #342
  • Point the documentation at 0.34.0-rc1000, and open the 0.35.0 line by @ipjohnson in #345
  • Rename [ApiGatewayModule] to [LambdaHttpModule], package included by @ipjohnson in #346

Full Changelog: v0.33.0-rc1000...v0.34.0-rc1000