diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 909637159..d744f4693 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,4 +3,13 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" \ No newline at end of file + interval: "daily" + labels: + - "packaging :package:" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + labels: + - "packaging :package:" \ No newline at end of file diff --git a/.github/workflows/VirusTotal.yml b/.github/workflows/VirusTotal.yml index 70ac995db..0c699caef 100644 --- a/.github/workflows/VirusTotal.yml +++ b/.github/workflows/VirusTotal.yml @@ -19,7 +19,7 @@ on: - cron: '0 12 * * *' env: - INVOKE_BUILD_VERSION: '5.12.0' + INVOKE_BUILD_VERSION: '5.12.2' POWERSHELL_VERSION: 'lts' jobs: diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml index c64594877..5021e6fde 100644 --- a/.github/workflows/ci-coverage.yml +++ b/.github/workflows/ci-coverage.yml @@ -20,7 +20,7 @@ on: - '.github/workflows/ci-coverage.yml' env: - INVOKE_BUILD_VERSION: '5.12.0' + INVOKE_BUILD_VERSION: '5.12.2' jobs: build: diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index 02ad1c82f..bd86c46e4 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -24,7 +24,7 @@ on: - 'src/Pode.psd1' env: - INVOKE_BUILD_VERSION: '5.12.0' + INVOKE_BUILD_VERSION: '5.12.2' jobs: build: diff --git a/.github/workflows/ci-powershell.yml b/.github/workflows/ci-powershell.yml index adc4cd1f2..4ebc70cf4 100644 --- a/.github/workflows/ci-powershell.yml +++ b/.github/workflows/ci-powershell.yml @@ -20,7 +20,7 @@ on: - '.github/workflows/ci-powershell.yml' env: - INVOKE_BUILD_VERSION: '5.12.0' + INVOKE_BUILD_VERSION: '5.12.2' jobs: build: diff --git a/.github/workflows/ci-pwsh7_5.yml b/.github/workflows/ci-pwsh7_5.yml index 1bf1704ea..e1ec489f6 100644 --- a/.github/workflows/ci-pwsh7_5.yml +++ b/.github/workflows/ci-pwsh7_5.yml @@ -24,9 +24,8 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.12.0' - POWERSHELL_VERSION: '7.5.0' - + INVOKE_BUILD_VERSION: '5.12.2' + POWERSHELL_VERSION: '7.5.1' jobs: build: diff --git a/.github/workflows/ci-pwsh_lts.yml b/.github/workflows/ci-pwsh_lts.yml index 70ab3d0d3..da41d2bf4 100644 --- a/.github/workflows/ci-pwsh_lts.yml +++ b/.github/workflows/ci-pwsh_lts.yml @@ -24,7 +24,7 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.12.0' + INVOKE_BUILD_VERSION: '5.12.2' POWERSHELL_VERSION: 'lts' jobs: diff --git a/.github/workflows/ci-pwsh_preview.yml b/.github/workflows/ci-pwsh_preview.yml index 43198540f..580ce9663 100644 --- a/.github/workflows/ci-pwsh_preview.yml +++ b/.github/workflows/ci-pwsh_preview.yml @@ -24,7 +24,7 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.12.0' + INVOKE_BUILD_VERSION: '5.12.2' POWERSHELL_VERSION: 'Preview' jobs: diff --git a/.gitignore b/.gitignore index 6938c5f15..def48a121 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Pode files and directories pode_modules/ ps_modules/ +src/Misc/third_party/ docs/[Ff]unctions/ examples/state.json examples/issue-* @@ -11,6 +12,7 @@ examples/issues/ pkg/ deliverable/ .vs/ +yarn.lock # Code Runner tempCodeRunnerFile.ps1 diff --git a/docs/Getting-Started/build.md b/docs/Getting-Started/build.md index 419d6acf8..d3d8b1f8e 100644 --- a/docs/Getting-Started/build.md +++ b/docs/Getting-Started/build.md @@ -7,13 +7,13 @@ If you have Pode's source code checked out locally on your machine, you can foll 1. Install InvokeBuild Module - ### Using Powershell Gallery + ### Using Powershell Gallery ```powershell Install-Module InvokeBuild -Scope CurrentUser ``` - ### Using Chocolatey + ### Using Chocolatey ```powershell choco install invoke-build @@ -52,11 +52,11 @@ If you have Pode's source code checked out locally on your machine, you can foll ``` To uninstall, use: + ```powershell Invoke-Build Remove-Module ``` - 6. CleanUp To clean up after a build or a pack, run the following: @@ -65,23 +65,26 @@ If you have Pode's source code checked out locally on your machine, you can foll Invoke-Build clean ``` -## Linux +### Linux 1. Register the Microsoft Repository #### CentOS + ```shell sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo curl -o /etc/yum.repos.d/microsoft.repo https://packages.microsoft.com/config/centos/8/prod.repo ``` #### RedHat + ```shell sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo curl -o /etc/yum.repos.d/microsoft.repo https://packages.microsoft.com/config/rhel/9/prod.repo ``` #### Debian / Ubuntu + ```shell sudo apt-get update sudo apt-get install -y wget apt-transport-https software-properties-common @@ -89,14 +92,12 @@ If you have Pode's source code checked out locally on your machine, you can foll sudo apt-get update; ``` - 2. Install InvokeBuild Module ```powershell Install-Module InvokeBuild -Scope CurrentUser ``` - 3. Test To run the unit tests, run the following command from the root of the repository (this will build Pode and, if needed, auto-install Pester/.NET): @@ -135,7 +136,6 @@ If you have Pode's source code checked out locally on your machine, you can foll Invoke-Build Remove-Module ``` - ## MacOS An easy way to install the required components is to use [brew](https://brew.sh/): diff --git a/docs/Tutorials/Authentication/Overview.md b/docs/Tutorials/Authentication/Overview.md index 19ddacece..77882682d 100644 --- a/docs/Tutorials/Authentication/Overview.md +++ b/docs/Tutorials/Authentication/Overview.md @@ -16,7 +16,7 @@ The [`New-PodeAuthScheme`](../../../Functions/Authentication/New-PodeAuthScheme) The following schemes are supported: * [API Key](../Methods/ApiKey) -* [Azure AD](../Methods/AzureAD) +* [Azure AD](../Inbuilt/AzureAD) * [Basic](../Methods/Basic) * [Bearer](../Methods/Bearer) * [Client Certificate](../Methods/ClientCertificate) diff --git a/docs/Tutorials/Endpoints/Favicon.md b/docs/Tutorials/Endpoints/Favicon.md new file mode 100644 index 000000000..64fa48487 --- /dev/null +++ b/docs/Tutorials/Endpoints/Favicon.md @@ -0,0 +1,100 @@ +# Favicons + +Pode allows you to customize favicons served from HTTP/HTTPS endpoints using a set of dedicated commands. By default, Pode does not serve any favicon until one is explicitly configured using the provided favicon commands. + +## Overview + +Favicons are the small icons displayed in browser tabs, bookmarks, and other UI elements. Pode supports using favicons in the standard ICO format, as well as other common web image formats such as PNG or SVG (depending on browser support). + +## Managing Favicons + +Pode provides the following functions to manage favicons: + +- `Add-PodeFavicon`: Adds a favicon to one or more endpoints. +- `Remove-PodeFavicon`: Removes the favicon from one or more endpoints. +- `Get-PodeFavicon`: Retrieves the current favicons assigned to endpoints. +- `Test-PodeFavicon`: Checks whether a favicon is configured on one or more endpoints. + +These functions support targeting specific endpoints by name, or applying changes globally to all endpoints. You can also limit operations to only endpoints marked as default using the `-DefaultEndpoint` switch. + +## Supported Formats + +Favicons are typically stored in `.ico` format but Pode also supports: + +- `.ico`: Multi-resolution raster format. Preferred for compatibility. +- `.png`: Lossless compressed raster format. Supported in modern browsers. +- `.svg`: Vector-based, resolution-independent. Supported in modern browsers with limitations. + +Other formats like `.jpg` or `.gif` may work but are not recommended due to lack of transparency or limited quality. + +For further details on favicon formats and specifications, refer to the [Favicon specification]([https://en.wikipedia.org/wiki/Favicon](https://en.wikipedia.org/wiki/Favicon)) and [RFC 5988]([https://datatracker.ietf.org/doc/html/rfc5988](https://datatracker.ietf.org/doc/html/rfc5988)). + +## Recommended Sizes + +Favicons should include multiple resolutions for optimal display across different devices. Recommended sizes include: + +- **16x16** : Used in browser tabs, bookmarks, and address bars. +- **32x32** : Used in browser tabs on higher-resolution displays. +- **48x48** : Used by some older browsers and web applications. +- **64x64** : Generally not used by browsers but can be helpful for scalability in web apps. +- **256x256** : Mainly for **Windows app icons** (not typically used as a favicon in browsers). + +## Usage Examples + +### Add default Pode favicon to all HTTP/S endpoints + +```powershell +Add-PodeFavicon -Default +``` + +### Add a custom favicon from file to all endpoints + +```powershell +Add-PodeFavicon -Path './assets/favicon.ico' +``` + +### Add a favicon to a specific endpoint using binary data + +```powershell +$icon = [System.IO.File]::ReadAllBytes('C:\icons\custom.ico') +Add-PodeFavicon -Binary $icon -EndpointName 'api' +``` + +### Add a favicon only to endpoints marked as default + +```powershell +Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http +$iconBytes = [System.IO.File]::ReadAllBytes("C:\path\to\custom.ico") +Add-PodeFavicon -Binary $iconBytes -DefaultEndpoint +``` + +### Remove all favicons from all endpoints + +```powershell +Remove-PodeFavicon +``` + +### Remove favicon from a specific endpoint + +```powershell +Remove-PodeFavicon -EndpointName 'admin' +``` + +### Get all currently assigned favicons + +```powershell +Get-PodeFavicon +``` + +### Test if a favicon exists on all default endpoints + +```powershell +Test-PodeFavicon -DefaultEndpoint +``` + +## Notes + +- Only HTTP and HTTPS endpoints support favicons. +- You can assign favicons only after endpoints are created. +- Favicons are stored in-memory as part of the endpoint object. +- Use `-DefaultEndpoint` with any command to target only default endpoints. diff --git a/docs/Tutorials/WebSockets/Endpoints.md b/docs/Tutorials/WebSockets/Endpoints.md index 0dba3d59b..23b1f9b32 100644 --- a/docs/Tutorials/WebSockets/Endpoints.md +++ b/docs/Tutorials/WebSockets/Endpoints.md @@ -2,6 +2,14 @@ Pode has support for creating WebSocket endpoints, for server-to-client and/or client-to-server communications. WebSockets allow you to broadcast messages directly from your server to connected clients. This allows you to get real-time continuous updates on the frontend without having to constantly refresh the page, or by using async javascript. +!!! note + The maximum size for WebSocket payloads in Pode depends on the version of PowerShell being used: + + - For **PowerShell ≤ 6.0**, the maximum payload size is **32KB**. + - For **PowerShell ≥ 7.0**, the maximum payload size is **16KB**. + + If a message exceeds these limits, the connection may be closed or the message may not be delivered correctly. + ## Server Side ### Listening diff --git a/docs/release-notes.md b/docs/release-notes.md index d973f24ab..9666bf056 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,1484 +1,1524 @@ -# Release Notes - -## v2.12.0 - -Date: 23rd February 2025 - -```plain -### Features -* #1445: Adds support for Kerberos/NTLM authentication -* #1461: Adds Disable/Enable functionality, so you can block the server from accepting new requests (thanks @mdaneri!) -* #1461: Adds Suspend/Resume functionality, so you can pause all runspaces/operations (thanks @mdaneri!) - -### Enhancements -* #1461: Improves console output, and adds more key bindings for more control (thanks @mdaneri!) -* #1469: Improved Access and Rate Limiting Middleware -* #1487: Adds support for retrying failed Task processes -* #1488: Adds support for retrieving the IP address from the X-Forwarded-For header, for Access/Rate Limit rules - -### Bugs -* #1454: Fix OpenAPI Route Parameter Handling in Pode (thanks @mdaneri!) -* #1460: Fixes ObjectDisposedException in during SSL/TLS operations (thanks @mdaneri!) -* #1482: Fix for how the content-transfer-encoding SMTP header is extracted -* #1483: Set initial runspace location to be the Server Root path - -### Documentation -* #1447: Documentation Spelling Fixes (thanks @ArieHein!) -* #1484: Add documentation for the various Route response type functions - -### Packaging -* #1448: Update PowerShell to 7.2.24 for CI environment due to unavailability of 7.2.19 (thanks @mdaneri!) -* #1452: Adds PS7.5 workflow (thanks @mdaneri!) -* #1452: Bumps .NET version to .NET9 (thanks @mdaneri!) -* #1452: Bumps InvokeBuild to v5.12.0 (thanks @mdaneri!) -* #1452: Bumps MkDocs to v1.6.1 (thanks @mdaneri!) -* #1457: Bump Alpine version in Docker image to v3.20 -* #1457: Remove PS7.2 and .NET6 support, as they're EOL now -* #1486: Bumps PowerShell in Dockerfiles to v7.5 -* #1489: Bumps Pester to v5.7.1 (thanks @mdaneri!) -* #1490: Bump MkDocs-Material theme to v9.6.4 - -### Security -* #1444: Adds VirusTotal package scanning Action -``` - -## v2.11.1 - -Date: 3rd November 2024 - -```plain -### Enhancements -* #1409: Adds new/missing CSP parameters in security headers - -### Bugs -* #1407: 'Initialize-PodeOpenApiTable' fails to initialize OpenAPI table when 'DefaultDefinitionTag' param is Null (thanks @mdaneri!) -* #1413: Fixes Test-PodeCacheStorage being called with incorrect -Key parameter (thanks @willgladstone!) -* #1418: Fix for ConvertTo-PodeYaml failing, when passed object contains a Key named "Count" (thanks @mdaneri!) -* #1420: Fix for OpenAPI Component Properties, Server Endpoint, and Path Filtering Issues (thanks @mdaneri!) -* #1423: Fix OpenAPI Route Path Conversion for Placeholder Unescaping and Relocate Function (#1422) (thanks @mdaneri!) -* #1424: Refactor Byte Conversion Functions (thanks @mdaneri!) -* #1424: Remove Duplicate Task Process Definitions (thanks @mdaneri!) -* #1427: Fixes "collection modified" error when cleaning up sessions -* #1430: Add-PodeOAComponentRequestBody now supports hashtable/ordered input (thanks @mdaneri!) -* #1430: Fix OpenAPI Route parameters so they respect the DefinitionTag (thanks @mdaneri!) -* #1430: More appropriately order responses, parameters, and request bodies in OpenAPI (thanks @mdaneri!) -* #1430: Order Routes in OpenAPI specification by creation, and HTTP methods in a more conventional order (thanks @mdaneri!) -* #1434: Fixes the clean-up of old log files (thanks @DoLearnWhileAlive!) -* #1436: Add -AllowNonStandardBody Parameter to Enable Request Bodies for Non-Standard HTTP Methods in OpenAPI (thanks @mdaneri!) -* #1438: Fixes the unnecessary Error Logging on HTTP Request Timeouts (thanks @mdaneri!) -* #1439: Don't setup the Caching Housekeeper Timer in a Serverless context -* #1440: Fixes error message appearing when using self-signed certificates on localhost - -### Security -* #1428: Migrates Stream functions into the .NET Listener - -### Packaging -* #1404: Add Pester Test to Check for Duplicate Function Definitions (thanks @mdaneri!) -``` - -## v2.11.0 - -Date: 29th September 2024 - -```plain -### Features -* #1320: Enhanced Internationalization Support (i18n) (thanks @mdaneri!) - -### Enhancements -* #1338: Automate Endpoint Assignment for OAViewer in Pode (thanks @mdaneri!) -* #1339: Add 'Rename-PodeOADefinitionTag' Function (thanks @mdaneri!) -* #1340: Add configuration parameter 'Web.OpenApi.UsePodeYamlInternal' (thanks @mdaneri!) -* #1352: Update MIME types to comply with RFC9512 and RFC5323 (thanks @mdaneri!) -* #1356: Dutch language support (thanks @mdaneri!) -* #1373: Dynamically load the Pode DLL relevant to the version of PowerShell (thanks @mdaneri!) -* #1384: Customizing and Managing Runspace Names (thanks @mdaneri!) -* #1388: Support passing Arrays to Functions Using Piping (thanks @mdaneri!) -* #1393: Adds functions for retrieving Schedule and Task Processes -* #1393: Improves Error Handling in Schedules, Timers, Tasks, and Logging -* #1393: Removes Global scope from TimerEvent -* #1399: Replaces occurrences of New-Object with new() - -### Bugs -* #1319: Fixes the Write-Pode(*)Response functions so the Value parameter appropriately handles when an array is passed using piping (thanks @mdaneri!) -* #1321: Fixes a misspelled variable in Add-PodeOAExternalRoute (thanks @mdaneri!) -* #1347: '-AdditionalProperties' doesn't appear on the OpenAPI document despite using the '-NoAdditionalProperties' parameter. (thanks @mdaneri!) -* #1358: Fixes [ordered] comparisons in PowerShell 5.1 (thanks @mdaneri!) -* #1358: Fixes for various OpenAPI issues (thanks @mdaneri!) -* #1358: Fixes OpenAPI version validation check in PowerShell 5.1 (thanks @mdaneri!) -* #1359: Fixes the login redirect URL logic for OAuth2 flows when using -SuccessUseOrigin -* #1360: Fixes a bug when exporting more than 1 module -* #1369: Accurate Output with -NoDefaultResponses (thanks @mdaneri!) -* #1369: Correct Schema with -NoProperties (thanks @mdaneri!) -* #1369: Fixes for OpenAPI Generation: Exception with oneOf/anyOf/allOf (thanks @mdaneri!) -* #1369: Include Min/Max Properties (thanks @mdaneri!) -* #1369: Prevent Request Body on GET Operations (thanks @mdaneri!) -* #1379: Fixes SSL timeouts when running Pode in PS7.4+ -* #1390: Changes "-ContentMediaType" and "-MediaType" parameters to "-ContentType" on most OpenAPI functions (thanks @mdaneri!) -* #1390: Ensures the generated OpenAPI document now maintains element ordering (thanks @mdaneri!) -* #1390: Fixes OpenAPI DefinitionTag being null in some functions (thanks @mdaneri!) -* #1390: Fixes OpenAPI PowerShell 5.1 compatibility issue while testing schemas (thanks @mdaneri!) -* #1397: Fixes retrieving DNS domain name on macOS -* #1400: Fixes session scoped variable when remapping while setting values -* #1400: Fixes User being needlessly splatted when passed to scriptblock for some Authentication methods - -### Documentation -* #1332: Adds documentation for CORS (thanks @mdaneri!) -* #1332: Adds missing features to the Feature List (thanks @mdaneri!) -* #1332: Splits OpenAPI documentation into multiple pages (thanks @mdaneri!) -* #1332: Updates Known Issues for PowerShell classes with PS7.4's SafeThread support (thanks @mdaneri!) -* #1333: Cleans up the Examples in the repository, and adds them to the Documentation (thanks @mdaneri!) - -### Packaging -* #1322: Applies a fix for a PS7.5 bug with Remove-Item throwing divide by zero error -* #1323: Fix build error when dotnet tries to restore from offline NuGet cache -* #1328: Make preview builds optional for PR merges -* #1342: Add GitHub Codespace Configuration and Getting Started Guide for Pode (thanks @mdaneri!) - -### Dependencies -* #1341: Bump actions/add-to-project from 1.0.1 to 1.0.2 -``` - -## v2.10.1 - -Date: 27th May 2024 - -```plain -### Bugs -* #1300: Adds a Test-Path check when loading modules -* #1300: Fixes a stack overflow exception when using: scoped variables are remapped -* #1301: Adds missing Name property to WindowsAd, WindowsLocal, and UserFile authentications -* #1303: Handle SecretStore vaults better with inbuilt defaults -* #1303: Resolve a threading issue with secrets - -### Documentation -* #1290: Fixes a typo in Tasks.md (thanks @fatherofinvention!) -* #1302: Alter Pode views documentation page to use Get-LocalUser instead of dummy function -* #1303: Write documentation for SecretStore vaults -* #1313: Adds documentation for CIM modules, and needing to import them first - -### Packaging -* #1304: Bumps InvokeBuild to 5.11.1 -* #1304: Ported a more concise and stable version of the PowerShell installer for workflows -* #1305: Only run CI workflows when required -* #1312: Adds auto release notes generator to build file -* #1315: Fixes docker builds on GitHub runners -* #1315: Removes support for PS7.3 GitHub runners, and NET7 now that they are EOL -* #1316: Split the license file up, add missing ones, and add the dependency licenses to be released with Pode - -### Dependencies -* #1309: Bump the version of mkdocs to 1.6.0 -* #1309: Bump the version of mkdocs-material theme to 9.5.23 -* #1310: Have Dependabot ensure that GitHub actions are up-to-date -* #1311: Bump actions/add-to-project from 0.3.0 to 1.0.1 -* #1314: Bump Dockerfiles to PowerShell 7.4 -``` - -## v2.10.0 - -Date: 15th April 2024 - -```plain -### Features -* #1197: Adds support for inbuilt caching of values -* #1238: Adds support for creating custom scoped variables -* #1256: Adds support for converting HTTP connections into SSE connections -* #1266: Adds support for a File Browsing page on static routes (thanks @mdaneri!) - -### Enhancements -* #1136: Adds full support for OpenAPI v3.0.3 and v3.1 (**huge** thanks to @mdaneri! 🎉) -* #1239: Adds the missing HTTP 425 response status code -* #1242: Adds support for enabling "session per browser Tab" -* #1265: Adds support for customising the default folder paths, such as `/views` (thanks @mdaneri!) -* #1267: Adds support for `-DualMode` on `Add-PodeEndpoint`, allowing endpoints to listen on IPv4 and IPv6 -* #1276: Adds supported and EOL PowerShell checks during server start (thanks @mdaneri!) - -### Bugs -* #1246: Fixes static route ordering, and redirecting to default file -* #1258: Fixes a script modification issue when using scriptblocks with `Add-PodePage` (thanks @mdaneri!) -* #1279: Fixes a scoping issue when using `Add-PodeRouteGroup` -* #1281: Removes an erroneous `break` command when broadcasting messages to websockets -* #1138: Fixes the status code for expired JWT, from 400 to 401 (thanks @mdaneri!) - -### Documentation -* #1232: Updates Sessions page to fix Redis example (thanks @Szeraax!) -* #1234: Updates Tasks page to explain Task concurrency and Argument passing (thanks @Szeraax!) -* #1276: Adds supported PowerShell documentation (thanks @mdaneri!) -* #1277: Fix for missing merged authentication documentation -* #1282: Adds documentation describing how to debug Pode - -### Packaging -* #1261: Add support to the build script for Linux and Mac (thanks @mdaneri!) -* #1262: Migrates tests to Pester 5.5.0 (thanks @mdaneri!) -* #1269: Adds PSScriptAnalyzerSettings to run during CI pipelines (thanks @mdaneri!) -* #1264, #1273: Adds CI pipelines per supported PowerShell version (thanks @mdaneri!) -* #1276: Adds .NET8 support (thanks @mdaneri!) -* #1284: Adds additional unit tests to verify PowerShell syntax and structure -* #1286: General tidy-up and release prep -``` - -## v2.9.0 - -Date: 30th October 2023 - -```plain -### Features -* #992: Introduces new Authorisation middleware support - -### Enhancements -* #588: Adds support for merging Authentication methods into a new Authentication method -* #1082, #1107: Adds a new "Running" event type, which will be triggered once all Runspaces have started -* #1101: Adds a new `-SslProtocol` parameter to `Add-PodeEndpoint`, to allow setting SSL Protocols per endpoint -* #1106: Adds two new Security functions to control the hiding/showing of the Server header in responses -* #1142: The `Test-PodeJwt` function is now public (thanks @alan-null!) -* #1163: Adds a new "Session" authentication method, useful if you need multiple authentication methods and the user can choose one - -### Bugs -* #1030: Fixes an issue with some Authentication methods when `-AsCredential` was supplied on the scheme -* #1081: Don't attempt to parse the query string if there is no query string supplied -* #1083: Fixes a time-zone issue when verifying JWT "exp" and "nbf" properties (thanks @avin3sh!) -* #1087: Fixes an SMTP body parsing issue when multiple headers are in the request -* #1093: Allow greater JSON depths to be used when saving/restoring State (thanks @plk!) -* #1125: Fixes an issue where Verbs weren't being cleared down appropriately on server restart -* #1130: When request logging is enabled, and an authenticated user is available, the username will now be used and not "-" -* #1137: Fixes the loading of AutoImport configuration - it was being ignored! - -### Documentation -* #1078: Adds release dates to the releases notes page -* #1099: Adds a reference to the "Protected Users" group in the AD Authentication page -* #1115, #1116: Fixes incorrect ports in Example scripts (thanks @ArieHein!) -* #1117, #1118, #1119: Fixes markdown syntax in pages (thanks @ArieHein!) -* #1123: Adds reference link about using the SecretManagement module in automation scenarios -* #1133: Fixes broken links to functions (thanks @Chris--A!) -* #1141: Updates the IIS page to reference the use of Maximum Worker Processes, and Sessions being stored in-memory - -### Packaging -* #1169: Adds a `.vscode` workspace settings file, with PowerShell code formatting settings -* #1170: Bumps the Alpine version to 3.17, and Ubuntu to 22.04 in Dockerfiles -* #1171: Bumps the versions of MkDocs and the Material theme -``` - -## v2.8.0 - -Date: 2nd February 2023 - -```plain -### Features -* #980: Adds support for Secret Management, either via the SecretManagement module or using custom logic -* #1063: Adds support for File Watchers, allowing you to run logic on file events -* #1067: Adds support for Mutexes and Semaphores - -### Enhancements -* #647: Adds a new helper function, `New-PodeCron`, to help with creating cron expressions for schedules -* #964: Adds a new `-IfExists` parameter for Routes, letting you now specify if Pode should overwrite a Route if it already exists -* #996: Multiple `-Method` values can now be passed for Routes -* #1036: Adds functions to reset and retrieve the current session's expiry -* #1071: Adds support for the `CONNECT` HTTP method - -### Bugs -* #1028: Fixes the QUIT command on the SMTP server to also return a "221 OK" response -* #1029: Resolves the "A drive with this name already exists" message -* #1041: Fixes a parsing error when sending form data from `Invoke-WebRequest` -* #1044: Fixes a duplicate key error when using the `multiple` attribute on HTML file inputs -* #1046: Fixes the version of Pode within its runspaces, so it's no "0.0" -* #1065: Fixes query string parsing when key is null (thanks @ili101!) - -### Documentation -* #1009: Adds clarification around password formats when using a file to store user authentication details (thanks @fatherofinvention!) -* #1054: Fixes rendering issue with `Write-PodeHtmlResponse` example -* #1056: Fixes typo in logging documentation (thanks @fatherofinvention!) - -### Packaging -* #1050: Bump Dockerfiles to use PS7.3 -* #1051: Bump the PodeListener to use .NET7 -* #1052: Bump version of mkdocs and material theme -``` - -## v2.7.2 - -Date: 18th October 2022 - -```plain -### Enhancements -* #1002: Adds a `-KeepCredential` switch for `Add-PodeAuthWindowsAd` (thanks @TheBakaBandit!) - -### Bugs -* #988: Add missing `-ListenerType` parameter description for `Start-PodeServer` -* #1001: Fix no Verbs being defined from crashing the server on restart - -### Documentation -* #975: Update the code sample image in the README to an SVG (thanks @pcgeek86!) -* #987: Adds the beginnings of a Roadmap and Project board -* #993: Improves documentation for the WebEvent variable -``` - -## v2.7.1 - -Date: 21st July 2022 - -```plain -### Bugs -* #990: Fix SMTP attachment name parsing, when the name contains a space - -### Security -* #997: Fix an XSS exploit on the default error pages -``` - -## v2.7.0 - -Date: 22nd June 2022 - -```plain -### Features -* #895: Add support for server to be able to connect to external WebSockets -* #902: New TCP server, listener, and endpoints; plus Verbs support -* #976: Add support for grouping Routes - -### Enhancements -* #901: Enable support for multiple SMTP endpoints, and certificates -* #954: Add anonymous route access support, when authentication is enabled on a route -* #960: Add RSET and NOOP SMTP commands -* #981: Add switch for AccessControl to create global Options route -* #982: Add * level for errors to enable everything - -### Bugs -* #956: Fix for importing functions with inline parameters -* #957: Fix for some OpenAPI properties being dropped -* #958: Some SMTP attachment boundaries can include double quotes -* #965: Fix for importing ps1 files -* #974: Add Position=0 to most response write functions - -### Documentation -* #978: Icon and Donation link updates - -### Packaging -* #984: Bump Docker images to use PS7.2.4 -``` - -## v2.6.2 - -Date: 2nd March 2022 - -```plain -### Bugs -* #948: Hotfix to resolve issue with importing ActiveDirectory module into runspaces -``` - -## v2.6.1 - -Date: 21st February 2022 - -```plain -### Bugs -* #915: Fix regex issue preventing Pode listening on IPv6 addresses -* #934: Fix relative path issue when using `-FilePath` on `Start-PodeServer` - -### Performance -* #913: Add new `-DirectGroups`/`-ADModule` switch for WindowsAD authentication - -### Documentation -* #940: Add a list of available options for server.psd1 files to configuration docs page -``` - -## v2.6.0 - -Date: 10th February 2022 - -```plain -### Features -* #893: Add async/sync Task support -* #894: Add helper support and middleware for security HTTP headers - -### Enhancements -* #867: Add support for PKCE on OAuth2 authentication -* #868: Add support for building OAuth2 schemes from OpenID Connect Discovery URLs -* #869: Update support to also get the count of currently processing requests -* #891: Add `-ArgumentList` to `Invoke-PodeTimer` and `Invoke-PodeSchedule` - -### Bugs -* #905: Fix for route creation and matching order -* #917: Fix for OpenAPI definition not being generated correctly -* #932: Dispose of completed Schedule runspaces/pipelines - -### Performance -* #896: Open and close RunspacePools in parallel - speeds server start-up and close -* #910: Only create RunspacePools when they're needed - -### Packaging -* #871: Compile the PodeListener into netstandard2.0, and now net6.0 -``` - -## v2.5.2 - -Date: 4th January 2022 - -```plain -### Bugs -* #892: Fixes a bug with importing modules, where the wrong file was being used -``` - -## v2.5.1 - -Date: 21st December 2021 - -```plain -### Bugs -* #877: Fix for `ConvertFrom-PodeJwt` expecting string not byte[] -* #879: Fix for retrieving Client Certificates from IIS -* #883: Fix for view engine extensions not being ToLower'd - -### Documentation -* #805: Add announcement bar to docs, referencing official docs on GitHub - -### Packaging -* #873: Bump PowerShell to v7.2.1 in Docker images -* #881: Bump mkdocs to v1.2.3, and Material theme to v8.1.2 -``` - -## v2.5.0 - -Date: 13th November 2021 - -```plain -### Enhancements -* #771: Adds more `Use-PodeXYZ` functions for auto-loading scripts -* #813: Adds new `Out-PodeVariable` to set variables on the Host when the server stops -* #817: Adds LastTriggerTime property for Schedules and Timers -* #825: Adds new Crash server event hook -* #826: Add support for HTTP and WebSocket endpoints to listen on the same Address/Port -* #827: Add `-Compress` switch to `Save-PodeState` -* #828: Add `-Merge` switch to `Restore-PodeState`, to stop overwriting of state on restore -* #830: Make `ConvertFrom-PodeJwt` public, and use `id_token` from the TokenUrl during OAuth2 for the user object -* #836: If `-Object` on `Lock-PodeObject` isn't supplied, use the global Lockable by default -* #837: Adds new Stop server event hook -* #851: Enable signals to be sent directly back to the sending client via WebSockets -* #852: Add new `$session:` and `$state:` variable scopes -* #862: Use `-Threads` on `Start-PodeServer` for WebSockets as well, if endpoint supplied -* #864: Add `-Force` to `Get-PodeSessionId` to allow the retrieval of unauthorised SessionIds -* #865: Add support for hosting Pode servers as IIS website applications -* #869: Add new metric functions for retrieving count of current active Requests/Signals - -### Bugs -* #808: Fix syntax errors in generated OpenAPI definitions -* #829: Fix issue with Range header returning 200 instead of 404 for invalid URI -* #845: Fix for single item arrays being converted to JSON -* #860: Fix duplicate limits being added during IP/Route/Endpoint middleware checks - -### Performance -* #856: Replace occurrences of piping to `Out-Null` with `$null =` instead (thanks @RobinBeismann!) - -### Documentation -* #842: Adds additional documentation around IIS and Kerberos (thanks @ittchmh!) - -### Packaging -* #843: Split up the Core.ps1 file into separate files (thanks @mark05e!) -* #872: Bumps PowerShell to v7.1.5 in Docker images -``` - -## v2.4.2 - -Date: 13th September 2021 - -```plain -### Bugs -* #810: Fixes a Local/UTC datetime issue on Cookies, expiring sessions early -* #811: Fixes the HTTPS parameter set on `Start-PodeStaticServer` -* #814: Fixes a route ordering issue on Swagger pages - -### Documentation -* #816: Fixes a typo on LoginPage (thanks @phatmandrake!) - -### Packaging -* #818: Bumps PowerShell to v7.1.4 in Docker images -``` - -## v2.4.1 - -Date: 9th August 2021 - -```plain -### Enhancements -* #801: Add new `-SearchBase` parameter to `Add-PodeAuthWindowsAD` for OpenLDAP -* #802: Add PEM certificate/key pair support for HTTPS endpoints - -### Bugs -* #796: Fix text wrapping issue when using ldapsearch (thanks @phatmandrake!) -* #797: When on MacOS, the default SSL protocol should only be TLS1.2 - -### Documentation -* #798: Update IIS hosting page to reference the minimum features required -* #800: Add examples to Route creation for Functions/Modules (thanks @phatmandrake!) -* #801: Update Windows AD authentication page to better reference Domain and OpenLDAP -``` - -## v2.4.0 - -Date: 21st July 2021 - -```plain -### Features -* #766: Add support for server Event Hooks, to run scripts on events like terminating the server -* #769: Add support for custom Lockable objects - -### Enhancements -* #763: Add support for SMTP attachments -* #765: Use a random secure GUID for Session `-Secret` if not supplied -* #767: Add new `Restart-PodeServer` to manually restart the server internally -* #779: Replace uses of `Join-Path` with `[System.IO.Path]::Combine` -* #786: Add new `Get-PodeStateNames` to get array of current Names with shared state - -### Bugs -* #768: Fix for a rare multithreading bug when serialising session data -* #770: `-SuccessUseOrigin` should only work for GET requests -* #776: Fix for the PodeResponse class and the handling of AggregateExceptions - -### Documentation -* #757: Add information about using `netsh interface portproxy` for external access as non-admin -* #762: Update `Add-PodeMiddleware` function summary to reference returning a boolean value -``` - -## v2.3.0 - -Date: 1st June 2021 - -```plain -### Features -* #723: Add support for logging to Windows Event Viewer -* #749: Add support for API key authentication - -### Enhancements -* #731: New `Use-PodeRoutes` to auto-load routes from a `/routes` directory -* #741: Add support for IIS to more gracefully close the site on recycle -* #743: Add `-AsCredential` switch for Basic/Form authentication -* #752: Add `-AsJWT` switch for Bearer/API key authentication - -### Bugs -* #738: Fix a bug where the body wasn't reset on new requests - -### Documentation -* #739: Flesh out the documentation on creating sites in IIS -* #741: Add documentation on IIS application pool recycling -* #751: Minor update to Bearer documentation to make header more visible -``` - -## v2.2.3 - -Date: 10th April 2021 - -```plain -### Bugs -* #736: Fix issue with v2.2.2 PowerShell Gallery packaging -``` - -## v2.2.2 - -Date: 9th April 2021 - -```plain -### Enhancements -* #727: Allow referencing an OpenAPI component schema from another component schema (thanks @glatzert!) -* #732: Allow changing of Bearer and Digest Authorization header tags - -### Packaging -* #726: Bump docker images to v7.1.3, and also add a new Alpine image -``` - -## v2.2.1 - -Date: 27th March 2021 - -```plain -### Bugs -* #716: Fix bug with `$TimerEvent` object within Timers -* #717: Fix bug with looping services exiting immediately -* #720: Fix bug with enabling termination in PS ISE -``` - -## v2.2.0 - -Date: 21st March 2021 - -```plain -### Features -* #682: Add support for the HTTP Range request header - -### Enhancements -* #684: Add support for login pages to redirect to the originating page -* #696: Fast processing of form data in requests -* #696: Add support for Request Timeout and Request Body Size -* #711: Add support for custom Signal Routes for WebSockets - -### Bugs -* #690: Fix bug with high CPU/Memory on IIS authentication with sessions, from WinIdentity -* #702: Fix bug with loading manifest modules - such as the ActiveDirectory module -* #709: Fix bug with `multipart/form-data` requests in Azure Functions - -### Documentation -* #704: Fix LoginPage docs so it matches the repository example (thanks @mark05e!) -``` - -## v2.1.1 - -Date: 19th February 2021 - -```plain -### Enhancements -* #693: Add OperationId OpenAPI support on routes (thanks @glatzert) -* #698: Add support for Certificate Store Name and Location on `Add-PodeEndpoint` - -### Bugs -* #686: Add EndpointName support on `Set-PodeResponseAttachment` -* #689: Fix bug with rate limiting preventing requests when no endpoint names - -### Documentation -* #661: Multiple additions to docs - error logging, cookies, headers, etc -* #683: Bump version of mkdocs-material theme -``` - -## v2.1.0 - -Date: 3rd February 2021 - -```plain -### Enhancements -* #655: Update the Socket Listener to handle larger request payloads, and fix receiving SSL requests -* #657: Adds `-ScriptBlock` parameters to inbuilt authentication methods -* #667: Set the WinIdentity from IIS auth, and add documentation for Kerberos Constrained Delegation (thanks @RobinBeismann!) - -### Bugs -* #648: Fixes for using global authentication in OpenAPI and Swagger -* #650: Fix for redirecting HTTP to HTTPS on default 80/443 ports -* #652: Fix for sessions not extending from AJAX requests, or when session data wasn't updated -* #654: Fix for `-Title` and `-Version` in `Get-PodeOpenApiDefinition` being mandatory -* #660: Fix for removing cookies in AJAX responses -* #663: Fix for when an endpoint's `-Hostname` is localhost, and bound to a route -* #669: Further fixes and improvements for more `-EndpointName` validation use-cases on routes -* #670: Remove extra NewLine from form files (thanks @ili101!) -* #673: Fix to make headers in request/response case-insensitive - -### Documentation -* #651: Update Azure AD authentication documentation to reference using Basic authentication as well (thanks @RobinBeismann) - -### Packaging -* #629: Update dockerfile to use Ubuntu 18.04 -* #630: Update dockerfiles to use PowerShell 7.1.1 -``` - -## v2.0.3 - -Date: 21st December 2020 - -```plain -### Bugs -* #641: Fix an issue with Invalid Request Lines being received when running via SSL and using a Proxy -* #642: Fix certificate X509FindType enum - -### Documentation -* #639: Fix the docker example ports to match documentation (thanks @ArieHein!) -``` - -## v2.0.2 - -Date: 5th December 2020 - -```plain -### Bugs -* #636: Fixes bug with OAuth2 RedirectUrl when behind IIS -``` - -## v2.0.1 - -Date: 29th November 2020 - -```plain -### Bugs -* #631: Parse username during Windows AD authentication -* #632: Fixes null reference exception during server restart -``` - -## v2.0.0 - -Date: 14th September 2020 - -```plain -### Features -* #472: Adds support for client certificate authentication -* #524: Adds support for rate limiting endpoints and routes -* #551: Adds support for OAuth2 and Azure AD authentication -* #585: Enables support for client-to-server web sockets -* #612: Adds support for Kestrel as a listener - via a new Pode.Kestrel module -* #625: Adds support for local Windows user authentication - -### Enhancements -* #572: Removes `-Endpoint` and `-Protocol` parameters in favur of `-EndpointName` -* #575: Changes and improvements to Authentication on Routes and Middleware -* #577: Massive improvements to alleviate of scoping with Modules, Snapins, Functions, and Variables -* #590: Enable support for Chrome in `Show-PodeGui` -* #618: The `$WebEvent` object is no longer passed to Routes, Middleware, etc., and should be accessed directly -* #619: Improved support for hostnames on endpoints -* #622: Allows support for a server to run endpoints of differing protocols - -### Bugs -* #600: Fixes public functions that weren't prefixed with "Pode" - -### Internal Code -* #573: Drop support for HttpListener, and rewrite Pode listener using .NET Core -* #584: Alter SMTP server to use the new Pode listener - -### Documentation -* #592: Updates IIS example to allow PUT/DELETE in web.config -``` - -## v1.8.4 - -Date: 16th October 2020 - -```plain -### Bugs -* #615: Fixes a bug with Azure Functions V3, where the sys property has now been removed -``` - -## v1.8.3 - -Date: 20th September 2020 - -```plain -### Enhancements -* #602: Adds a new `Remove-PodeOAResponse` function to allow removing of default responses -* #603: Adds a new `-Enum` parameter onto the OpenAPI property functions -``` - -## v1.8.2 - -Date: 31st July 2020 - -```plain -### Bugs -* #594: Add `Import-PodeSnapIn` to FunctionsToExport list -``` - -## v1.8.1 - -Date: 26th June 2020 - -```plain -### Bugs -* #578: Fixes OpenAPI functions with rogue "=" on returning a value -* #581: Fixes large messages being sent via web sockets -``` - -## v1.8.0 - -Date: 24th May 2020 - -```plain -### Enhancements -* #533: Support on states for inclusion/exlcusions when saving, and scopes on states -* #538: Support to batch log items together before sending them off to be recorded -* #540: Adds a Ctrl+B shortcut to open the server in the default browser -* #542: Add new switch to help toggling of Status Page exception message -* #548: Adds new `Get-PodeSchedule` and `Get-PodeTimer` functions -* #549: Support for calculating a schedule's next trigger datetime - -### Bugs -* #532: Fixes a bug in `Get-PodeRoute` when a route is bound to multiple endpoints -* #547: Fixes a bug where not all data was being read on SMTP messages -* #558: Paths with URL encoded characters fail when trying to load static content - -### Documentation -* #381: Documentation on using Pode in Heroku (plus auto-detection support) - -### Packaging -* #546: Adds automated integration tests -* #562: Remove AppVeyor and TravisCI in favour of GitHub Actions -* #567: Bump Powershell version in Docker to 7.0.1 -* #569: Bump version of MkDocs and Material Theme -``` - -## v1.7.3 - -Date: 10th May 2020 - -```plain -### Bugs -* #554: Fixes an issue where HTML static files would be treated as dynamic files -``` - -## v1.7.2 - -Date: 27th April 2020 - -```plain -### Bugs -* #543: Fixes an internal issue that was causing errors in the SMTP server -``` - -## v1.7.1 - -Date: 17th April 2020 - -```plain -### Bugs -* #534: Fixes an issue with IIS Windows Authentication when using foreign trusted domains (thanks @RobinBeismann!) -``` - -## v1.7.0 - -Date: 10th April 2020 - -```plain -### Features -* #504: Support for GZip and Deflate compression on Requests -* #507: Support for GZip and Deflate compression on Responses -* #510: New inbuilt authenticator to allow authenticating users from a file - -### Enhancements -* #511: Adds middleware support to `Add-PodeStaticRoute` -* #518: New `Get-PodeEndpoint` function to retrieve and filter endpoints -* #525: Support for Azure Web Apps, fixes DisableTermination, and adds Quiet switch - -### Bugs -* #509: Fixes a freezing bug caused by sessions - and improves performance of sessions - -### Documentation -* #517: Adds missing `-Sessionless` parameter in IIS docs (thanks @RobinBeismann!) - -### Packaging -* #503: Bump the Docker images to PowerShell v7.0 -``` - -## v1.6.1 - -Date: 7th March 2020 - -```plain -### Bugs -* 495: Fix issue with parsing query strings when using the Pode server type - -### Documentation -* #496: When using IIS, install Pode using AllUsers scope -* #497: Comments about using PowerShell classes in Pode, under Known Issues -``` - -## v1.6.0 - -Date: 3rd March 2020 - -```plain -### Features -* #464: Request metrics for routes for the number of requests -* #473: Digest Authentication support (with added support for PostValidator scripts) -* #478: Bearer Authentication support (with support for scope validation) - -### Enhancements -* #425: Adds functions to get routes: `Get-PodeRoute` and `Get-PodeStaticRoute` -* #474: The inbuilt Windows AD authentication now works cross-platform! -* #475: Adds support for hosting a Pode server via IIS - -### Bugs -* #477: Fix QueryString parsing on Pode server type - -### Documentation -* #484: Information about Web Events and their structure -``` - -## v1.5.0 - -Date: 2nd February 2020 - -```plain -### Features -* #218: Adds OpenAPI with Swagger and ReDoc support - -### Enhancements -* #458: Adds a Timestamp to the event object passed to Routes/Middleware -* #459: Ability to get the Uptime and Restart Count of the server - -### Bugs -* #461: Fix the parsing of payloads in Azure Functions and AWS Lambdas -* #465: Format fix in the OpenAPI examples (thanks @haidouks!) - -### Packaging -* #470: Bumps the version of the MkDocs Material theme to 4.6.0 -``` - -## v1.4.0 - -Date: 10th January 2020 - -```plain -### Enhancements -* #447: Sessions can now be used via Headers for better CLI support -* #448: `-EndpointName` on routes can now take an array of endpoint names -* #454: New wrapper function, `Start-PodeStaticServer`, for simple static websites - -### Bugs -* #446: Fixes functions that were not in accordence with Coding Guidelines (thanks @jhainau!) - -### Documentation -* #445: Improved documentation on using CSRF middleware -``` - -## v1.3.0 - -Date: 27th December 2019 - -```plain -### Enhancements -* #421: Adds a new `-FilePath` parameter to the `Add-PodeTimer` and `Add-PodeSchedule` functions -* #422: Adds a new `-FilePath` parameter to the `Start-PodeServer` function -* #423: New `Edit-PodeSchedule` and `Edit-PodeSchedule` functions -* #431: Support for the `WWW-Authenticate` header on failed Authentication (401) responses -* #433: Support in custom Authentication types to allow returning extra Headers on the response -* #435: New `Set-PodeScheduleConcurrency` function to set the max number of concurrent schedules -* #440: Adds support in the `package.json` for custom PowerShell Repositories - -### Bugs -* #429: Running `pode start` failed to invoke server script on some platforms -* #441: Fixes an issue where local modules failed to resolve correct path -``` - -## v1.2.1 - -Date: 2nd December 2019 - -```plain -### Enhancements -* #415: New functions for invoking Timer and Schedules adhoc - -### Bugs -* #416: Fix for using `*/INT` in cron-expressions - -### Documentation -* #418: Docs and examples typo fixes -``` - -## v1.2.0 - -Date: 13th November 2019 - -```plain -### Features -* #395: Built-in support for using Server-to-Client websockets -* #389: Support for defining custom body/payload parsers for specific ContentTypes - -### Enhancements -* #401: Support for running a Schedule/Timer's logic when the server starts/restarts -* #400: Helper wrapper method `Out-PodeHost` to output data to the main host terminal -* #390: Support for setting a Status Code on all "Write-Pode[Type]Response" functions -* #386: Support to set a fixed ContentType on `Set-PodeResponseAttachment` (thanks @Windos!) -* #383: If a called route exists but for a different HTTP method, then return a 405 not a 404 -* #382: Support on Unix environments to terminate/restart a server using Shift+C/R - -### Documentation -* #405: How to create a server that has endpoints accessible externally -* #399: Reference to the literal parameter names on Schedules -* #396: How to return a custom Status Code and/or message from an Authenticator -``` - -## v1.1.0 - -Date: 28th September 2019 - -```plain -### Features -* #376: *Experimental* support for cross-platform HTTPS! - -### Bugs -* #372: Fixed an issue when getting the length of strings in `Get-PodeCount` (thanks @Fraham!) -* #384: Fixed `Set-PodeResponseAttachment` not setting the ContentLength (plus support of literal paths) - -### Packaging -* #375: Update the Dockerfiles to PowerShell 6.2.3 -* #253: Publish the Docker images on the GitHub Package Registry -``` - -## v1.0.1 - -Date: 4th September 2019 - -```plain -### Bugs -* #367: If a "server.psd1" file is not present, Logging will not work -* #368: Logging will attempt to mask everything if no mask patterns are supplied -``` - -## v1.0.0 - -Date: 2nd September 2019 - -```plain -### Features -* #228: Support for rendering Markdown as HTML (Fully supported in PowerShell 7+) -* #334: New "ConvertTo-PodeRoute" function to automatically make Routes from Functions/Modules -* #344: New "Add-PodePage" function to more easily make GET Routes for simple pages - -### Enhancements -* #328: New "Get-PodeAuthADUser" parameter -NoGroups, to skip retrieving groups from AD -* #330: Allow for -ArgumentList on Routes, Handlers, Timers, Schedules, etc - now they can be more dynamic -* #341: Allow Show-PodeGui to work under PowerShell 7 on Windows -* #343: Ability to mask data in logs using Regex -* #352: On "Add-PodeEndpoint", split the -Address parameter into -Address/-Port parameters -* #354: Two new functions for Sessions to Save and Remove them -* #355: Support on "Add-PodeEndpoint" for a -RedirectTo parameter, to automatically build a redirect Route - -### Bugs -* #312: On Static Routes, don't create a PSDrive when the Source is a File Share -* #318: For Cron Expressions, split the DayOfWeek and DayOfMonth -* #324: Setting Authentication middleware globally didn't save the Session object -* #347: Route parameters fail if the value contains a dot, or other special characters -* #351: Stop the "Done" message appearing when the server errors - -### Packaging -* #338: Update the version of MkDocs Material Theme to v4.4.0 -* #349: Update the Dockerfiles to PowerShell 6.2.2 - -### Internal Code -* #279, #279, #287, #289, #290, #291, #292, #294, #295, #296, #297, #305, #306, #314, #315 - - Convert all functions to PowerShell Syntax -* #303: Change from using "pode..json" files to "server..psd1" files - -### Documentation -* #299: Rebuild Documentation's Functions section using PlatyPS -* #316: Write a migration guide for going from v0.X to v1.0 -* #321: Go through all documentation, ensuring it's up-to-date with new Syntax -``` - -## v0.32.0 - -Date: 28th June 2019 - -```plain -### Enhancements -* #270: Support on `gui` to specify the width and height of the window -* #280: Support when file monitoring to output the files that caused the server to restart -* #282: New actions on `state` to save and restore to to/from a file - -### Bugs -* #271: Fix in `Convert-PodePathPatternsToRegex` when converting file names - thanks @Fraham! - -### Documentation -* #284: Notes in documentation about referencing JSON payload data in PowerShell 4/5 -``` - -## v0.31.0 - -Date: 11th June 2019 - -```plain -### Features -* #264: Support for Azure Functions and AWS Lambda -* #264: New `header` function for adding/setting and getting header values from the Request/Response - -### Enhancements -* #264: Cookies are now done via the "Set-Cookie" header, meaning `cookie` now appropriately sets multiple cookies -* #266: Have a `-Browse` flag on the `server` to auto-launch the website in a browser - -### Bugs -* #264: The `text` function now sets the content-type to "text/plain" by default -``` - -## v0.30.0 - -Date: 26th May 2019 - -```plain -### Enhancements -* #245: Support for Windows AD group validation on the inbuilt 'windows-ad' authentication validator -* #250: Support for bulk importing/loading scripts and modules -* #251: Support on routes to supply a FilePath to a script that contains the route's scriptblock -* #252: Support on the server function to supply a custom RootPath - -### Performance -* #258: Performance improvements to all aspects of a web request, reducing response times - -### Packaging -* #261: Docker images updated to PowerShell Core v6.2.1 -``` - -## v0.29.0 - -Date: 10th May 2019 - -```plain -### Enhancements -* #216: Multi-content-type support on Error Pages -* #232: Support for setting/forcing default content types on routes -* #243: Support on Static Routes to flag them as "Download Only" -* #248: Ability to alter the server's root path - -### Packaging -* #227: Docker images updated to PowerShell Core v6.2.0 -* #233: New ARM32 docker image, enabling support for Raspberry Pi - -### Build -* #237, #238, #239: Updates to CI tools -``` - -## v0.28.1 - -Date: 16th April 2019 - -```plain -### Bugs -* #226: Adds the "gui" function to export list -``` - -## v0.28.0 - -Date: 13th April 2019 - -```plain -### Features -* #210: New "cookie" function added, to support setting/getting cookies - including signing them -* #211: Support for CSRF via the new "csrf" function, which generates valid middleware and random tokens - -### Enhancements -* #204: Support on the "import" function to import PSSnapIns -* #223: Support for using a Thumbprint on the "listen" function instead of Certificate name - -### Bugs -* #206: When disposing/restarting the SMTP server, send a "QUIT" message if still connected - -### Clean-Up -* #209: Rename of internal function to avoid collisions, and change "Get-PodeConfiguration" to "config" -``` - -## v0.27.3 - -Date: 4th April 2019 - -```plain -### Bugs -* #217: Binding to hostname throws error -``` - -## v0.27.2 - -Date: 27th March 2019 - -```plain -### Bugs -* #212: Incorrect variable name used in html, csv, xml and json functions when referencing files -``` - -## v0.27.1 - -Date: 16th March 2019 - -```plain -### Bugs -* #199: Fix issues with relative paths when running server as a service -* #200: Fix issue with file monitor, where folder patterns fail to match on new files -``` - -## v0.27.0 - -Date: 14th March 2019 - -```plain -### Features -* #185: Support for Server Restarts either Periodically or at specific Times, with support for cron expressions -* #188: Support for Custom Error pages, with inbuilt Pode error pages - -### Enhancements -* #189: SMTP server to parse data headers and have them set on the event object - -### Performance -* #196: Massive improvements to performance when loading static content - -### Bugs -* #181: Importing modules into the current scope should be done Globally, making them instantly accessible -* #183: TCP Reads and Writes should be Async so they can be terminated more easily -* #184: SMTP and TCP servers fail to Restart -* #196: Default paths on Static Content fail when using nested directories - -### General -* #194: Update Dockerfile from using PSCore 6.1.0 to 6.1.3 -``` - -## v0.26.0 - -Date: 17th February 2019 - -```plain -### Features -* #162: Basic support for local modules in "package.json" on "pode install" -* #175: Support for flash messages on sessions, and in authentication - -### Bugs -* #72: RunspacePools aren't being recreated during a restart, and modules fail to import into other RunspacePools -``` - -## v0.25.0 - -Date: 5th February 2019 - -```plain -### Features -* #170: Support for Static Content Caching, with ability to include/exclude routes/extensions - -### Enhancements -* #161: New method to return configuration from the pode.json file, plus improved docs and support for environment configs -* #165: Support on the inbuilt SMTP server for Subject and decoded Body -* #168: Ability to exclude/include paths/extensions when triggering an Internal Restart - -### Documentation -* #45: Add "Known Issues" pages to documentation - -### Clean-Up -* #160: Internally, rename occurrences of $PodeSession to $PodeContext -``` - -## v0.24.0 - -Date: 18th January 2019 - -```plain -### Features -* #125: Helper support function for uploading files from a web form - -### Enhancements -* #149: Inbuilt support for Windows AD Authentication - -### Bugs -* #152: Fix the Choco install script so it installs the module for PowerShell Core as well -* #155: After an Internal Restart, the View Engine is not set back to the default -* #158: If views/public directories don't exist, the creation of PSDrive fails -``` - -## v0.23.0 - -Date: 24th December 2018 - -```plain -### Features -* #77: Ability to run a web server, and view it through a Desktop Application (Windows only) - -### Enhancements -* #137: Don't require admin privileges when listening on Localhost -* #140: Add a Custom switch to the Logger function - no need to use the "custom_" format any more! -* #142: Ability to listen on multiple endpoints - especially useful for hostnames against a single IP address -* #143: Support on routes to allow them to be bound against specific hostnames/protocols -* #146: Listen function to have Name parameter - so we can select which one to bind a Route/Gui to better -``` - -## v0.22.0 - -Date: 7th December 2018 - -```plain -### Enhancements -* #123: Ability to remove a `route` -* #124: Views, Public and custom static routes now use `New-PSDrive` to prevent directory tranversing -* #128: Ability to `listen` using a host name -* #130: `auth` now allows re-using inbuilt/custom parsers. Rather than `name` the type, the name is now any custom name you want to use and yuo specify the `-type` (like basic, etc). If no `-type` supplied, `name` is used as the type instead -* #131: There's now a route parameter on `middleware`, so you can define global middleware that only run on requests for specific routes. -``` - -## v0.21.0 - -Date: 2nd November 2018 - -```plain -### Enhancements -* #110: Return a 401 for inaccessible files -* #116: Support on custom static content, for returning `index.html` or `default.html` (plus others), if a directory is requested - -### Bugs -* #111: Separate out the `service` server type into own runspace -* #112: Server should return a 500 if middleware/route fails unexpectedly, rather than a 200 - -### Documentation -* #120: Added examples of running scripts as Windows or Linux services [here](https://badgerati.github.io/Pode/Getting-Started/RunAsService/) - -### Clean-Up -* #118: Rename `$WebSession` to `$WebEvent` - internal references only -``` - -## v0.20.0 - -Date: 20th October 2018 - -```plain -### Documentation -* Extended documentation for third-party template engines -* "Building your first app" documentation - -### Features -* #103: Adds support for custom static routes - -### Enhancements -* #101: Adds a `-Limit` parameter to schedules -* `import` function now supports installed modules - -### Clean-Up -* #102: Logging converted to internal `endware` script -``` - -## v0.19.1 - -Date: 9th October 2018 - -```plain -### Documentation -* #91: This release contains far better documentation for Pode: https://badgerati.github.io/Pode - -### Enhancements -* #93: Updates PowerShell Docker image to 6.1.0, so internal restarts now work -* #96: Chocolatey package now contains the module, rather than downloading from GitHub -* Adds more aliases for parameters on core functions -* Renames `script` function to `import` (the former is still supported) -* New CI builder: Travis CI, used to test Pode on *nix and PowerShell Core -* Minor miscellaneous stability fixes -``` - -## v0.19.0 - -Date: 14th September 2018 - -```plain -### Features -* #84: Session cookie support, with in-mem/custom data storage -* #86: Request authentication support. Currently implemented: Basic, Forms, Custom - -### Enhancements -* #88: Enabling Ctrl+R to be pressed on the CLI to trigger a server restart - similar to using `-FileMonitor`. -``` - -## v0.18.0 - -Date: 25th August 2018 - -```plain -### Features -* #78: Middleware support for web servers, allowing custom logic and extension modules on web request/responses - -### Enhancements -* #81: Added aliases onto some of the `Server` parameters -``` - -## v0.17.0 - -Date: 19th August 2018 - -```plain -### Features -* #43: Ability to generate self-signed certificates, and bind those certs - or pre-installed certs - when using HTTPS -* #71: New `scripts` call to specify external modules that should be imported into each runspace - -### Bugs -* #71: Unable to access functions from external scripts -* #73: Calling `pode start` fails to import Pode module into runspaces -``` - -## v0.16.0 - -Date: 8th August 2018 - -```plain -### Features -* #66: Support for basic rate limiting of requests per x seconds from IPs -* #68: Support for scheduled tasks using cron expressions - -### Enhancements -* #62: Helper function to ease URL redirection -* #64: Have a '*' HTTP method so a route can be used on every method -``` - -## v0.15.0 - -Date: 13th July 2018 - -```plain - -### Features -* #31: Support for multithreaded responses on web, smtp and tcp servers using `-Threads` on your Server block - -### Misc -* #59: Removal of obsolete functions, such as the older `Write-JsonResponse` which is now just `Json` -* #31: Addition of some minor performance tests using `k6` -* Addition of new icon and logo for Pode -``` - -## v0.14.0 - -Date: 6th July 2018 - -```plain -### Features -* #21: Ability for Pode to Internally Restart when a File Change is Detected -* #52: Support for Allowing/Denying IP and Subnet Addresses - -### Enhancements -* #44: Setup Unit Tests with Pester and run on AppVeyor - -### Bugs -* #51: Set Dockerfile to use a fixed version of the PowerShell container, rather than latest -* #55: Setup SMTP/TCP listeners to run in separate runspace like Web -``` - -## v0.13.0 - -Date: 23rd June 2018 - -```plain -### Features -* #40: Ability to add variables to a shared state, so you can re-use variables in timers, loggers, and routes -``` - -## v0.12.0 - -Date: 15th June 2018 - -```plain -### Features -* #33: Support for logging to the terminal, files, and custom loggers for LogStash/Fluentd/etc -* #35: New `Attach` function to help attach files from the public directory to the response for downloading - -### Enhancements -* #32: Ability to listen on a specific IP address using `-IP` on a `Server` -* #36: Support for relative paths on views/public content, when running server script from non-root directory -``` - -## v0.11.3 - -Date: 10th June 2018 - -```plain -### Bugs and Enhancements -* #22: Proper fix for high CPU usage, by using `Task.Wait` with `CancellationTokens`; A Runspace is setup to monitor for key presses, and on `Ctrl+C` will `Cancel()` the token and terminate Pode -``` - -## v0.11.2 - -Date: 8th June 2018 - -```plain -### Bugs -* #22: Hot fix patch for reducing high CPU usage when idle -``` - -## v0.11.1 - -Date: 1st June 2018 - -```plain -### Bugs -* #16: Status and Include functions were missing from module export list -``` - -## v0.11.0 - -Date: 30th May 2018 - -```plain -### Features -* #5: Async timers to run tasks and processes in a separate thread (see timers sections in README) - -### Enhancements -* #7: New `status` function to easily alter the StatusCode of a Response -* #8: New `json`, `xml`, `html`, `csv`, `view` and `tcp` functions to replace current "Write-Response" - now obsolete - functions (see ticket for explanation, and README for usage) - -### Bugs -* #12: Fixed an issue that caused image files (and others) to not render appropriately -``` +# Release Notes + +## v2.12.1 + +Date: 27th April 2025 + +```plain +### Enhancements +* #1495: Adds Hostname, Scheme, Query, and UtcDate to raw Request item for logging (thanks @chris-dma!) +* #1509: Support for Custom and default Favicons in Pode Endpoints (thanks @mdaneri!) +* #1518: Improved Compatibility for 'Write-PodeHostDivider' on Older Windows Versions (thanks @mdaneri!) +* #1535: Adds new mapping for .mjs files, to application/javascript content-type +* #1537: Adds support for fragmented WebSocket frames, and larger payloads +* #1538: Bundles the OpenAPI Libraries with the Pode Module, for stability and to support offline servers (thanks @mdaneri!) + +### Bugs +* #1507: Fixes Pode removing more log files than expected due to too broad of a filter (thanks @nightroman!) +* #1507: Fixes the way logs are removed when using MaxDays, and servers restart daily (thanks @nightroman!) +* #1515: Fix: Prevent Early Invocation of Write-PodeErrorLog in Console Setup (thanks @mdaneri!) +* #1532: Fix buffer reuse issue in WebSockets (thanks @mdaneri!) +* #1534: Fixes an issue with loading static content paths which contain wildcard characters +* #1536: Fix crash during server restart, by clearing existing limit rules +* #1539: Fixes a scoping issue in .pode files, where $_ would sometimes be $null +* #1542: Fixes the file browser icons, so they render on PS5 +* #1542: Fixes the file browser parent directory create/update dates +* #1546: Fixes unquoted YAML strings starting with special characters, incorrect indentation for standalone block literals, and incorrect line endings (CRLF) (thanks @mdaneri!) + +### Documentation +* #1524: Fixes AzureAD link in Authentication Overview page + +### Packaging +* #1541: Bump MkDocs-Material theme to v9.6.12 +* #1549: Bumps the InvokeBuild version in GitHub Actions to 5.12.2 +* #1549: Bumps the PS7.5 version in GitHub Actions to 7.5.1 +* #1550: Bump swagger-ui-dist from 5.20.8 to 5.21.0 +* #1551: Bump redoc from 2.4.0 to 2.5.0 + +### Performance +* #1540: Re-use existing FileInfo objects for reading/writing byte streams +* #1540: Removes redundant MemoryStream which doubled memory-use when writing to Responses +``` + +## v2.12.0 + +Date: 23rd February 2025 + +```plain +### Features +* #1445: Adds support for Kerberos/NTLM authentication +* #1461: Adds Disable/Enable functionality, so you can block the server from accepting new requests (thanks @mdaneri!) +* #1461: Adds Suspend/Resume functionality, so you can pause all runspaces/operations (thanks @mdaneri!) + +### Enhancements +* #1461: Improves console output, and adds more key bindings for more control (thanks @mdaneri!) +* #1469: Improved Access and Rate Limiting Middleware +* #1487: Adds support for retrying failed Task processes +* #1488: Adds support for retrieving the IP address from the X-Forwarded-For header, for Access/Rate Limit rules + +### Bugs +* #1454: Fix OpenAPI Route Parameter Handling in Pode (thanks @mdaneri!) +* #1460: Fixes ObjectDisposedException in during SSL/TLS operations (thanks @mdaneri!) +* #1482: Fix for how the content-transfer-encoding SMTP header is extracted +* #1483: Set initial runspace location to be the Server Root path + +### Documentation +* #1447: Documentation Spelling Fixes (thanks @ArieHein!) +* #1484: Add documentation for the various Route response type functions + +### Packaging +* #1448: Update PowerShell to 7.2.24 for CI environment due to unavailability of 7.2.19 (thanks @mdaneri!) +* #1452: Adds PS7.5 workflow (thanks @mdaneri!) +* #1452: Bumps .NET version to .NET9 (thanks @mdaneri!) +* #1452: Bumps InvokeBuild to v5.12.0 (thanks @mdaneri!) +* #1452: Bumps MkDocs to v1.6.1 (thanks @mdaneri!) +* #1457: Bump Alpine version in Docker image to v3.20 +* #1457: Remove PS7.2 and .NET6 support, as they're EOL now +* #1486: Bumps PowerShell in Dockerfiles to v7.5 +* #1489: Bumps Pester to v5.7.1 (thanks @mdaneri!) +* #1490: Bump MkDocs-Material theme to v9.6.4 + +### Security +* #1444: Adds VirusTotal package scanning Action +``` + +## v2.11.1 + +Date: 3rd November 2024 + +```plain +### Enhancements +* #1409: Adds new/missing CSP parameters in security headers + +### Bugs +* #1407: 'Initialize-PodeOpenApiTable' fails to initialize OpenAPI table when 'DefaultDefinitionTag' param is Null (thanks @mdaneri!) +* #1413: Fixes Test-PodeCacheStorage being called with incorrect -Key parameter (thanks @willgladstone!) +* #1418: Fix for ConvertTo-PodeYaml failing, when passed object contains a Key named "Count" (thanks @mdaneri!) +* #1420: Fix for OpenAPI Component Properties, Server Endpoint, and Path Filtering Issues (thanks @mdaneri!) +* #1423: Fix OpenAPI Route Path Conversion for Placeholder Unescaping and Relocate Function (#1422) (thanks @mdaneri!) +* #1424: Refactor Byte Conversion Functions (thanks @mdaneri!) +* #1424: Remove Duplicate Task Process Definitions (thanks @mdaneri!) +* #1427: Fixes "collection modified" error when cleaning up sessions +* #1430: Add-PodeOAComponentRequestBody now supports hashtable/ordered input (thanks @mdaneri!) +* #1430: Fix OpenAPI Route parameters so they respect the DefinitionTag (thanks @mdaneri!) +* #1430: More appropriately order responses, parameters, and request bodies in OpenAPI (thanks @mdaneri!) +* #1430: Order Routes in OpenAPI specification by creation, and HTTP methods in a more conventional order (thanks @mdaneri!) +* #1434: Fixes the clean-up of old log files (thanks @DoLearnWhileAlive!) +* #1436: Add -AllowNonStandardBody Parameter to Enable Request Bodies for Non-Standard HTTP Methods in OpenAPI (thanks @mdaneri!) +* #1438: Fixes the unnecessary Error Logging on HTTP Request Timeouts (thanks @mdaneri!) +* #1439: Don't setup the Caching Housekeeper Timer in a Serverless context +* #1440: Fixes error message appearing when using self-signed certificates on localhost + +### Security +* #1428: Migrates Stream functions into the .NET Listener + +### Packaging +* #1404: Add Pester Test to Check for Duplicate Function Definitions (thanks @mdaneri!) +``` + +## v2.11.0 + +Date: 29th September 2024 + +```plain +### Features +* #1320: Enhanced Internationalization Support (i18n) (thanks @mdaneri!) + +### Enhancements +* #1338: Automate Endpoint Assignment for OAViewer in Pode (thanks @mdaneri!) +* #1339: Add 'Rename-PodeOADefinitionTag' Function (thanks @mdaneri!) +* #1340: Add configuration parameter 'Web.OpenApi.UsePodeYamlInternal' (thanks @mdaneri!) +* #1352: Update MIME types to comply with RFC9512 and RFC5323 (thanks @mdaneri!) +* #1356: Dutch language support (thanks @mdaneri!) +* #1373: Dynamically load the Pode DLL relevant to the version of PowerShell (thanks @mdaneri!) +* #1384: Customizing and Managing Runspace Names (thanks @mdaneri!) +* #1388: Support passing Arrays to Functions Using Piping (thanks @mdaneri!) +* #1393: Adds functions for retrieving Schedule and Task Processes +* #1393: Improves Error Handling in Schedules, Timers, Tasks, and Logging +* #1393: Removes Global scope from TimerEvent +* #1399: Replaces occurrences of New-Object with new() + +### Bugs +* #1319: Fixes the Write-Pode(*)Response functions so the Value parameter appropriately handles when an array is passed using piping (thanks @mdaneri!) +* #1321: Fixes a misspelled variable in Add-PodeOAExternalRoute (thanks @mdaneri!) +* #1347: '-AdditionalProperties' doesn't appear on the OpenAPI document despite using the '-NoAdditionalProperties' parameter. (thanks @mdaneri!) +* #1358: Fixes [ordered] comparisons in PowerShell 5.1 (thanks @mdaneri!) +* #1358: Fixes for various OpenAPI issues (thanks @mdaneri!) +* #1358: Fixes OpenAPI version validation check in PowerShell 5.1 (thanks @mdaneri!) +* #1359: Fixes the login redirect URL logic for OAuth2 flows when using -SuccessUseOrigin +* #1360: Fixes a bug when exporting more than 1 module +* #1369: Accurate Output with -NoDefaultResponses (thanks @mdaneri!) +* #1369: Correct Schema with -NoProperties (thanks @mdaneri!) +* #1369: Fixes for OpenAPI Generation: Exception with oneOf/anyOf/allOf (thanks @mdaneri!) +* #1369: Include Min/Max Properties (thanks @mdaneri!) +* #1369: Prevent Request Body on GET Operations (thanks @mdaneri!) +* #1379: Fixes SSL timeouts when running Pode in PS7.4+ +* #1390: Changes "-ContentMediaType" and "-MediaType" parameters to "-ContentType" on most OpenAPI functions (thanks @mdaneri!) +* #1390: Ensures the generated OpenAPI document now maintains element ordering (thanks @mdaneri!) +* #1390: Fixes OpenAPI DefinitionTag being null in some functions (thanks @mdaneri!) +* #1390: Fixes OpenAPI PowerShell 5.1 compatibility issue while testing schemas (thanks @mdaneri!) +* #1397: Fixes retrieving DNS domain name on macOS +* #1400: Fixes session scoped variable when remapping while setting values +* #1400: Fixes User being needlessly splatted when passed to scriptblock for some Authentication methods + +### Documentation +* #1332: Adds documentation for CORS (thanks @mdaneri!) +* #1332: Adds missing features to the Feature List (thanks @mdaneri!) +* #1332: Splits OpenAPI documentation into multiple pages (thanks @mdaneri!) +* #1332: Updates Known Issues for PowerShell classes with PS7.4's SafeThread support (thanks @mdaneri!) +* #1333: Cleans up the Examples in the repository, and adds them to the Documentation (thanks @mdaneri!) + +### Packaging +* #1322: Applies a fix for a PS7.5 bug with Remove-Item throwing divide by zero error +* #1323: Fix build error when dotnet tries to restore from offline NuGet cache +* #1328: Make preview builds optional for PR merges +* #1342: Add GitHub Codespace Configuration and Getting Started Guide for Pode (thanks @mdaneri!) + +### Dependencies +* #1341: Bump actions/add-to-project from 1.0.1 to 1.0.2 +``` + +## v2.10.1 + +Date: 27th May 2024 + +```plain +### Bugs +* #1300: Adds a Test-Path check when loading modules +* #1300: Fixes a stack overflow exception when using: scoped variables are remapped +* #1301: Adds missing Name property to WindowsAd, WindowsLocal, and UserFile authentications +* #1303: Handle SecretStore vaults better with inbuilt defaults +* #1303: Resolve a threading issue with secrets + +### Documentation +* #1290: Fixes a typo in Tasks.md (thanks @fatherofinvention!) +* #1302: Alter Pode views documentation page to use Get-LocalUser instead of dummy function +* #1303: Write documentation for SecretStore vaults +* #1313: Adds documentation for CIM modules, and needing to import them first + +### Packaging +* #1304: Bumps InvokeBuild to 5.11.1 +* #1304: Ported a more concise and stable version of the PowerShell installer for workflows +* #1305: Only run CI workflows when required +* #1312: Adds auto release notes generator to build file +* #1315: Fixes docker builds on GitHub runners +* #1315: Removes support for PS7.3 GitHub runners, and NET7 now that they are EOL +* #1316: Split the license file up, add missing ones, and add the dependency licenses to be released with Pode + +### Dependencies +* #1309: Bump the version of mkdocs to 1.6.0 +* #1309: Bump the version of mkdocs-material theme to 9.5.23 +* #1310: Have Dependabot ensure that GitHub actions are up-to-date +* #1311: Bump actions/add-to-project from 0.3.0 to 1.0.1 +* #1314: Bump Dockerfiles to PowerShell 7.4 +``` + +## v2.10.0 + +Date: 15th April 2024 + +```plain +### Features +* #1197: Adds support for inbuilt caching of values +* #1238: Adds support for creating custom scoped variables +* #1256: Adds support for converting HTTP connections into SSE connections +* #1266: Adds support for a File Browsing page on static routes (thanks @mdaneri!) + +### Enhancements +* #1136: Adds full support for OpenAPI v3.0.3 and v3.1 (**huge** thanks to @mdaneri! 🎉) +* #1239: Adds the missing HTTP 425 response status code +* #1242: Adds support for enabling "session per browser Tab" +* #1265: Adds support for customising the default folder paths, such as `/views` (thanks @mdaneri!) +* #1267: Adds support for `-DualMode` on `Add-PodeEndpoint`, allowing endpoints to listen on IPv4 and IPv6 +* #1276: Adds supported and EOL PowerShell checks during server start (thanks @mdaneri!) + +### Bugs +* #1246: Fixes static route ordering, and redirecting to default file +* #1258: Fixes a script modification issue when using scriptblocks with `Add-PodePage` (thanks @mdaneri!) +* #1279: Fixes a scoping issue when using `Add-PodeRouteGroup` +* #1281: Removes an erroneous `break` command when broadcasting messages to websockets +* #1138: Fixes the status code for expired JWT, from 400 to 401 (thanks @mdaneri!) + +### Documentation +* #1232: Updates Sessions page to fix Redis example (thanks @Szeraax!) +* #1234: Updates Tasks page to explain Task concurrency and Argument passing (thanks @Szeraax!) +* #1276: Adds supported PowerShell documentation (thanks @mdaneri!) +* #1277: Fix for missing merged authentication documentation +* #1282: Adds documentation describing how to debug Pode + +### Packaging +* #1261: Add support to the build script for Linux and Mac (thanks @mdaneri!) +* #1262: Migrates tests to Pester 5.5.0 (thanks @mdaneri!) +* #1269: Adds PSScriptAnalyzerSettings to run during CI pipelines (thanks @mdaneri!) +* #1264, #1273: Adds CI pipelines per supported PowerShell version (thanks @mdaneri!) +* #1276: Adds .NET8 support (thanks @mdaneri!) +* #1284: Adds additional unit tests to verify PowerShell syntax and structure +* #1286: General tidy-up and release prep +``` + +## v2.9.0 + +Date: 30th October 2023 + +```plain +### Features +* #992: Introduces new Authorisation middleware support + +### Enhancements +* #588: Adds support for merging Authentication methods into a new Authentication method +* #1082, #1107: Adds a new "Running" event type, which will be triggered once all Runspaces have started +* #1101: Adds a new `-SslProtocol` parameter to `Add-PodeEndpoint`, to allow setting SSL Protocols per endpoint +* #1106: Adds two new Security functions to control the hiding/showing of the Server header in responses +* #1142: The `Test-PodeJwt` function is now public (thanks @alan-null!) +* #1163: Adds a new "Session" authentication method, useful if you need multiple authentication methods and the user can choose one + +### Bugs +* #1030: Fixes an issue with some Authentication methods when `-AsCredential` was supplied on the scheme +* #1081: Don't attempt to parse the query string if there is no query string supplied +* #1083: Fixes a time-zone issue when verifying JWT "exp" and "nbf" properties (thanks @avin3sh!) +* #1087: Fixes an SMTP body parsing issue when multiple headers are in the request +* #1093: Allow greater JSON depths to be used when saving/restoring State (thanks @plk!) +* #1125: Fixes an issue where Verbs weren't being cleared down appropriately on server restart +* #1130: When request logging is enabled, and an authenticated user is available, the username will now be used and not "-" +* #1137: Fixes the loading of AutoImport configuration - it was being ignored! + +### Documentation +* #1078: Adds release dates to the releases notes page +* #1099: Adds a reference to the "Protected Users" group in the AD Authentication page +* #1115, #1116: Fixes incorrect ports in Example scripts (thanks @ArieHein!) +* #1117, #1118, #1119: Fixes markdown syntax in pages (thanks @ArieHein!) +* #1123: Adds reference link about using the SecretManagement module in automation scenarios +* #1133: Fixes broken links to functions (thanks @Chris--A!) +* #1141: Updates the IIS page to reference the use of Maximum Worker Processes, and Sessions being stored in-memory + +### Packaging +* #1169: Adds a `.vscode` workspace settings file, with PowerShell code formatting settings +* #1170: Bumps the Alpine version to 3.17, and Ubuntu to 22.04 in Dockerfiles +* #1171: Bumps the versions of MkDocs and the Material theme +``` + +## v2.8.0 + +Date: 2nd February 2023 + +```plain +### Features +* #980: Adds support for Secret Management, either via the SecretManagement module or using custom logic +* #1063: Adds support for File Watchers, allowing you to run logic on file events +* #1067: Adds support for Mutexes and Semaphores + +### Enhancements +* #647: Adds a new helper function, `New-PodeCron`, to help with creating cron expressions for schedules +* #964: Adds a new `-IfExists` parameter for Routes, letting you now specify if Pode should overwrite a Route if it already exists +* #996: Multiple `-Method` values can now be passed for Routes +* #1036: Adds functions to reset and retrieve the current session's expiry +* #1071: Adds support for the `CONNECT` HTTP method + +### Bugs +* #1028: Fixes the QUIT command on the SMTP server to also return a "221 OK" response +* #1029: Resolves the "A drive with this name already exists" message +* #1041: Fixes a parsing error when sending form data from `Invoke-WebRequest` +* #1044: Fixes a duplicate key error when using the `multiple` attribute on HTML file inputs +* #1046: Fixes the version of Pode within its runspaces, so it's no "0.0" +* #1065: Fixes query string parsing when key is null (thanks @ili101!) + +### Documentation +* #1009: Adds clarification around password formats when using a file to store user authentication details (thanks @fatherofinvention!) +* #1054: Fixes rendering issue with `Write-PodeHtmlResponse` example +* #1056: Fixes typo in logging documentation (thanks @fatherofinvention!) + +### Packaging +* #1050: Bump Dockerfiles to use PS7.3 +* #1051: Bump the PodeListener to use .NET7 +* #1052: Bump version of mkdocs and material theme +``` + +## v2.7.2 + +Date: 18th October 2022 + +```plain +### Enhancements +* #1002: Adds a `-KeepCredential` switch for `Add-PodeAuthWindowsAd` (thanks @TheBakaBandit!) + +### Bugs +* #988: Add missing `-ListenerType` parameter description for `Start-PodeServer` +* #1001: Fix no Verbs being defined from crashing the server on restart + +### Documentation +* #975: Update the code sample image in the README to an SVG (thanks @pcgeek86!) +* #987: Adds the beginnings of a Roadmap and Project board +* #993: Improves documentation for the WebEvent variable +``` + +## v2.7.1 + +Date: 21st July 2022 + +```plain +### Bugs +* #990: Fix SMTP attachment name parsing, when the name contains a space + +### Security +* #997: Fix an XSS exploit on the default error pages +``` + +## v2.7.0 + +Date: 22nd June 2022 + +```plain +### Features +* #895: Add support for server to be able to connect to external WebSockets +* #902: New TCP server, listener, and endpoints; plus Verbs support +* #976: Add support for grouping Routes + +### Enhancements +* #901: Enable support for multiple SMTP endpoints, and certificates +* #954: Add anonymous route access support, when authentication is enabled on a route +* #960: Add RSET and NOOP SMTP commands +* #981: Add switch for AccessControl to create global Options route +* #982: Add * level for errors to enable everything + +### Bugs +* #956: Fix for importing functions with inline parameters +* #957: Fix for some OpenAPI properties being dropped +* #958: Some SMTP attachment boundaries can include double quotes +* #965: Fix for importing ps1 files +* #974: Add Position=0 to most response write functions + +### Documentation +* #978: Icon and Donation link updates + +### Packaging +* #984: Bump Docker images to use PS7.2.4 +``` + +## v2.6.2 + +Date: 2nd March 2022 + +```plain +### Bugs +* #948: Hotfix to resolve issue with importing ActiveDirectory module into runspaces +``` + +## v2.6.1 + +Date: 21st February 2022 + +```plain +### Bugs +* #915: Fix regex issue preventing Pode listening on IPv6 addresses +* #934: Fix relative path issue when using `-FilePath` on `Start-PodeServer` + +### Performance +* #913: Add new `-DirectGroups`/`-ADModule` switch for WindowsAD authentication + +### Documentation +* #940: Add a list of available options for server.psd1 files to configuration docs page +``` + +## v2.6.0 + +Date: 10th February 2022 + +```plain +### Features +* #893: Add async/sync Task support +* #894: Add helper support and middleware for security HTTP headers + +### Enhancements +* #867: Add support for PKCE on OAuth2 authentication +* #868: Add support for building OAuth2 schemes from OpenID Connect Discovery URLs +* #869: Update support to also get the count of currently processing requests +* #891: Add `-ArgumentList` to `Invoke-PodeTimer` and `Invoke-PodeSchedule` + +### Bugs +* #905: Fix for route creation and matching order +* #917: Fix for OpenAPI definition not being generated correctly +* #932: Dispose of completed Schedule runspaces/pipelines + +### Performance +* #896: Open and close RunspacePools in parallel - speeds server start-up and close +* #910: Only create RunspacePools when they're needed + +### Packaging +* #871: Compile the PodeListener into netstandard2.0, and now net6.0 +``` + +## v2.5.2 + +Date: 4th January 2022 + +```plain +### Bugs +* #892: Fixes a bug with importing modules, where the wrong file was being used +``` + +## v2.5.1 + +Date: 21st December 2021 + +```plain +### Bugs +* #877: Fix for `ConvertFrom-PodeJwt` expecting string not byte[] +* #879: Fix for retrieving Client Certificates from IIS +* #883: Fix for view engine extensions not being ToLower'd + +### Documentation +* #805: Add announcement bar to docs, referencing official docs on GitHub + +### Packaging +* #873: Bump PowerShell to v7.2.1 in Docker images +* #881: Bump mkdocs to v1.2.3, and Material theme to v8.1.2 +``` + +## v2.5.0 + +Date: 13th November 2021 + +```plain +### Enhancements +* #771: Adds more `Use-PodeXYZ` functions for auto-loading scripts +* #813: Adds new `Out-PodeVariable` to set variables on the Host when the server stops +* #817: Adds LastTriggerTime property for Schedules and Timers +* #825: Adds new Crash server event hook +* #826: Add support for HTTP and WebSocket endpoints to listen on the same Address/Port +* #827: Add `-Compress` switch to `Save-PodeState` +* #828: Add `-Merge` switch to `Restore-PodeState`, to stop overwriting of state on restore +* #830: Make `ConvertFrom-PodeJwt` public, and use `id_token` from the TokenUrl during OAuth2 for the user object +* #836: If `-Object` on `Lock-PodeObject` isn't supplied, use the global Lockable by default +* #837: Adds new Stop server event hook +* #851: Enable signals to be sent directly back to the sending client via WebSockets +* #852: Add new `$session:` and `$state:` variable scopes +* #862: Use `-Threads` on `Start-PodeServer` for WebSockets as well, if endpoint supplied +* #864: Add `-Force` to `Get-PodeSessionId` to allow the retrieval of unauthorised SessionIds +* #865: Add support for hosting Pode servers as IIS website applications +* #869: Add new metric functions for retrieving count of current active Requests/Signals + +### Bugs +* #808: Fix syntax errors in generated OpenAPI definitions +* #829: Fix issue with Range header returning 200 instead of 404 for invalid URI +* #845: Fix for single item arrays being converted to JSON +* #860: Fix duplicate limits being added during IP/Route/Endpoint middleware checks + +### Performance +* #856: Replace occurrences of piping to `Out-Null` with `$null =` instead (thanks @RobinBeismann!) + +### Documentation +* #842: Adds additional documentation around IIS and Kerberos (thanks @ittchmh!) + +### Packaging +* #843: Split up the Core.ps1 file into separate files (thanks @mark05e!) +* #872: Bumps PowerShell to v7.1.5 in Docker images +``` + +## v2.4.2 + +Date: 13th September 2021 + +```plain +### Bugs +* #810: Fixes a Local/UTC datetime issue on Cookies, expiring sessions early +* #811: Fixes the HTTPS parameter set on `Start-PodeStaticServer` +* #814: Fixes a route ordering issue on Swagger pages + +### Documentation +* #816: Fixes a typo on LoginPage (thanks @phatmandrake!) + +### Packaging +* #818: Bumps PowerShell to v7.1.4 in Docker images +``` + +## v2.4.1 + +Date: 9th August 2021 + +```plain +### Enhancements +* #801: Add new `-SearchBase` parameter to `Add-PodeAuthWindowsAD` for OpenLDAP +* #802: Add PEM certificate/key pair support for HTTPS endpoints + +### Bugs +* #796: Fix text wrapping issue when using ldapsearch (thanks @phatmandrake!) +* #797: When on MacOS, the default SSL protocol should only be TLS1.2 + +### Documentation +* #798: Update IIS hosting page to reference the minimum features required +* #800: Add examples to Route creation for Functions/Modules (thanks @phatmandrake!) +* #801: Update Windows AD authentication page to better reference Domain and OpenLDAP +``` + +## v2.4.0 + +Date: 21st July 2021 + +```plain +### Features +* #766: Add support for server Event Hooks, to run scripts on events like terminating the server +* #769: Add support for custom Lockable objects + +### Enhancements +* #763: Add support for SMTP attachments +* #765: Use a random secure GUID for Session `-Secret` if not supplied +* #767: Add new `Restart-PodeServer` to manually restart the server internally +* #779: Replace uses of `Join-Path` with `[System.IO.Path]::Combine` +* #786: Add new `Get-PodeStateNames` to get array of current Names with shared state + +### Bugs +* #768: Fix for a rare multithreading bug when serialising session data +* #770: `-SuccessUseOrigin` should only work for GET requests +* #776: Fix for the PodeResponse class and the handling of AggregateExceptions + +### Documentation +* #757: Add information about using `netsh interface portproxy` for external access as non-admin +* #762: Update `Add-PodeMiddleware` function summary to reference returning a boolean value +``` + +## v2.3.0 + +Date: 1st June 2021 + +```plain +### Features +* #723: Add support for logging to Windows Event Viewer +* #749: Add support for API key authentication + +### Enhancements +* #731: New `Use-PodeRoutes` to auto-load routes from a `/routes` directory +* #741: Add support for IIS to more gracefully close the site on recycle +* #743: Add `-AsCredential` switch for Basic/Form authentication +* #752: Add `-AsJWT` switch for Bearer/API key authentication + +### Bugs +* #738: Fix a bug where the body wasn't reset on new requests + +### Documentation +* #739: Flesh out the documentation on creating sites in IIS +* #741: Add documentation on IIS application pool recycling +* #751: Minor update to Bearer documentation to make header more visible +``` + +## v2.2.3 + +Date: 10th April 2021 + +```plain +### Bugs +* #736: Fix issue with v2.2.2 PowerShell Gallery packaging +``` + +## v2.2.2 + +Date: 9th April 2021 + +```plain +### Enhancements +* #727: Allow referencing an OpenAPI component schema from another component schema (thanks @glatzert!) +* #732: Allow changing of Bearer and Digest Authorization header tags + +### Packaging +* #726: Bump docker images to v7.1.3, and also add a new Alpine image +``` + +## v2.2.1 + +Date: 27th March 2021 + +```plain +### Bugs +* #716: Fix bug with `$TimerEvent` object within Timers +* #717: Fix bug with looping services exiting immediately +* #720: Fix bug with enabling termination in PS ISE +``` + +## v2.2.0 + +Date: 21st March 2021 + +```plain +### Features +* #682: Add support for the HTTP Range request header + +### Enhancements +* #684: Add support for login pages to redirect to the originating page +* #696: Fast processing of form data in requests +* #696: Add support for Request Timeout and Request Body Size +* #711: Add support for custom Signal Routes for WebSockets + +### Bugs +* #690: Fix bug with high CPU/Memory on IIS authentication with sessions, from WinIdentity +* #702: Fix bug with loading manifest modules - such as the ActiveDirectory module +* #709: Fix bug with `multipart/form-data` requests in Azure Functions + +### Documentation +* #704: Fix LoginPage docs so it matches the repository example (thanks @mark05e!) +``` + +## v2.1.1 + +Date: 19th February 2021 + +```plain +### Enhancements +* #693: Add OperationId OpenAPI support on routes (thanks @glatzert) +* #698: Add support for Certificate Store Name and Location on `Add-PodeEndpoint` + +### Bugs +* #686: Add EndpointName support on `Set-PodeResponseAttachment` +* #689: Fix bug with rate limiting preventing requests when no endpoint names + +### Documentation +* #661: Multiple additions to docs - error logging, cookies, headers, etc +* #683: Bump version of mkdocs-material theme +``` + +## v2.1.0 + +Date: 3rd February 2021 + +```plain +### Enhancements +* #655: Update the Socket Listener to handle larger request payloads, and fix receiving SSL requests +* #657: Adds `-ScriptBlock` parameters to inbuilt authentication methods +* #667: Set the WinIdentity from IIS auth, and add documentation for Kerberos Constrained Delegation (thanks @RobinBeismann!) + +### Bugs +* #648: Fixes for using global authentication in OpenAPI and Swagger +* #650: Fix for redirecting HTTP to HTTPS on default 80/443 ports +* #652: Fix for sessions not extending from AJAX requests, or when session data wasn't updated +* #654: Fix for `-Title` and `-Version` in `Get-PodeOpenApiDefinition` being mandatory +* #660: Fix for removing cookies in AJAX responses +* #663: Fix for when an endpoint's `-Hostname` is localhost, and bound to a route +* #669: Further fixes and improvements for more `-EndpointName` validation use-cases on routes +* #670: Remove extra NewLine from form files (thanks @ili101!) +* #673: Fix to make headers in request/response case-insensitive + +### Documentation +* #651: Update Azure AD authentication documentation to reference using Basic authentication as well (thanks @RobinBeismann) + +### Packaging +* #629: Update dockerfile to use Ubuntu 18.04 +* #630: Update dockerfiles to use PowerShell 7.1.1 +``` + +## v2.0.3 + +Date: 21st December 2020 + +```plain +### Bugs +* #641: Fix an issue with Invalid Request Lines being received when running via SSL and using a Proxy +* #642: Fix certificate X509FindType enum + +### Documentation +* #639: Fix the docker example ports to match documentation (thanks @ArieHein!) +``` + +## v2.0.2 + +Date: 5th December 2020 + +```plain +### Bugs +* #636: Fixes bug with OAuth2 RedirectUrl when behind IIS +``` + +## v2.0.1 + +Date: 29th November 2020 + +```plain +### Bugs +* #631: Parse username during Windows AD authentication +* #632: Fixes null reference exception during server restart +``` + +## v2.0.0 + +Date: 14th September 2020 + +```plain +### Features +* #472: Adds support for client certificate authentication +* #524: Adds support for rate limiting endpoints and routes +* #551: Adds support for OAuth2 and Azure AD authentication +* #585: Enables support for client-to-server web sockets +* #612: Adds support for Kestrel as a listener - via a new Pode.Kestrel module +* #625: Adds support for local Windows user authentication + +### Enhancements +* #572: Removes `-Endpoint` and `-Protocol` parameters in favur of `-EndpointName` +* #575: Changes and improvements to Authentication on Routes and Middleware +* #577: Massive improvements to alleviate of scoping with Modules, Snapins, Functions, and Variables +* #590: Enable support for Chrome in `Show-PodeGui` +* #618: The `$WebEvent` object is no longer passed to Routes, Middleware, etc., and should be accessed directly +* #619: Improved support for hostnames on endpoints +* #622: Allows support for a server to run endpoints of differing protocols + +### Bugs +* #600: Fixes public functions that weren't prefixed with "Pode" + +### Internal Code +* #573: Drop support for HttpListener, and rewrite Pode listener using .NET Core +* #584: Alter SMTP server to use the new Pode listener + +### Documentation +* #592: Updates IIS example to allow PUT/DELETE in web.config +``` + +## v1.8.4 + +Date: 16th October 2020 + +```plain +### Bugs +* #615: Fixes a bug with Azure Functions V3, where the sys property has now been removed +``` + +## v1.8.3 + +Date: 20th September 2020 + +```plain +### Enhancements +* #602: Adds a new `Remove-PodeOAResponse` function to allow removing of default responses +* #603: Adds a new `-Enum` parameter onto the OpenAPI property functions +``` + +## v1.8.2 + +Date: 31st July 2020 + +```plain +### Bugs +* #594: Add `Import-PodeSnapIn` to FunctionsToExport list +``` + +## v1.8.1 + +Date: 26th June 2020 + +```plain +### Bugs +* #578: Fixes OpenAPI functions with rogue "=" on returning a value +* #581: Fixes large messages being sent via web sockets +``` + +## v1.8.0 + +Date: 24th May 2020 + +```plain +### Enhancements +* #533: Support on states for inclusion/exlcusions when saving, and scopes on states +* #538: Support to batch log items together before sending them off to be recorded +* #540: Adds a Ctrl+B shortcut to open the server in the default browser +* #542: Add new switch to help toggling of Status Page exception message +* #548: Adds new `Get-PodeSchedule` and `Get-PodeTimer` functions +* #549: Support for calculating a schedule's next trigger datetime + +### Bugs +* #532: Fixes a bug in `Get-PodeRoute` when a route is bound to multiple endpoints +* #547: Fixes a bug where not all data was being read on SMTP messages +* #558: Paths with URL encoded characters fail when trying to load static content + +### Documentation +* #381: Documentation on using Pode in Heroku (plus auto-detection support) + +### Packaging +* #546: Adds automated integration tests +* #562: Remove AppVeyor and TravisCI in favour of GitHub Actions +* #567: Bump Powershell version in Docker to 7.0.1 +* #569: Bump version of MkDocs and Material Theme +``` + +## v1.7.3 + +Date: 10th May 2020 + +```plain +### Bugs +* #554: Fixes an issue where HTML static files would be treated as dynamic files +``` + +## v1.7.2 + +Date: 27th April 2020 + +```plain +### Bugs +* #543: Fixes an internal issue that was causing errors in the SMTP server +``` + +## v1.7.1 + +Date: 17th April 2020 + +```plain +### Bugs +* #534: Fixes an issue with IIS Windows Authentication when using foreign trusted domains (thanks @RobinBeismann!) +``` + +## v1.7.0 + +Date: 10th April 2020 + +```plain +### Features +* #504: Support for GZip and Deflate compression on Requests +* #507: Support for GZip and Deflate compression on Responses +* #510: New inbuilt authenticator to allow authenticating users from a file + +### Enhancements +* #511: Adds middleware support to `Add-PodeStaticRoute` +* #518: New `Get-PodeEndpoint` function to retrieve and filter endpoints +* #525: Support for Azure Web Apps, fixes DisableTermination, and adds Quiet switch + +### Bugs +* #509: Fixes a freezing bug caused by sessions - and improves performance of sessions + +### Documentation +* #517: Adds missing `-Sessionless` parameter in IIS docs (thanks @RobinBeismann!) + +### Packaging +* #503: Bump the Docker images to PowerShell v7.0 +``` + +## v1.6.1 + +Date: 7th March 2020 + +```plain +### Bugs +* 495: Fix issue with parsing query strings when using the Pode server type + +### Documentation +* #496: When using IIS, install Pode using AllUsers scope +* #497: Comments about using PowerShell classes in Pode, under Known Issues +``` + +## v1.6.0 + +Date: 3rd March 2020 + +```plain +### Features +* #464: Request metrics for routes for the number of requests +* #473: Digest Authentication support (with added support for PostValidator scripts) +* #478: Bearer Authentication support (with support for scope validation) + +### Enhancements +* #425: Adds functions to get routes: `Get-PodeRoute` and `Get-PodeStaticRoute` +* #474: The inbuilt Windows AD authentication now works cross-platform! +* #475: Adds support for hosting a Pode server via IIS + +### Bugs +* #477: Fix QueryString parsing on Pode server type + +### Documentation +* #484: Information about Web Events and their structure +``` + +## v1.5.0 + +Date: 2nd February 2020 + +```plain +### Features +* #218: Adds OpenAPI with Swagger and ReDoc support + +### Enhancements +* #458: Adds a Timestamp to the event object passed to Routes/Middleware +* #459: Ability to get the Uptime and Restart Count of the server + +### Bugs +* #461: Fix the parsing of payloads in Azure Functions and AWS Lambdas +* #465: Format fix in the OpenAPI examples (thanks @haidouks!) + +### Packaging +* #470: Bumps the version of the MkDocs Material theme to 4.6.0 +``` + +## v1.4.0 + +Date: 10th January 2020 + +```plain +### Enhancements +* #447: Sessions can now be used via Headers for better CLI support +* #448: `-EndpointName` on routes can now take an array of endpoint names +* #454: New wrapper function, `Start-PodeStaticServer`, for simple static websites + +### Bugs +* #446: Fixes functions that were not in accordence with Coding Guidelines (thanks @jhainau!) + +### Documentation +* #445: Improved documentation on using CSRF middleware +``` + +## v1.3.0 + +Date: 27th December 2019 + +```plain +### Enhancements +* #421: Adds a new `-FilePath` parameter to the `Add-PodeTimer` and `Add-PodeSchedule` functions +* #422: Adds a new `-FilePath` parameter to the `Start-PodeServer` function +* #423: New `Edit-PodeSchedule` and `Edit-PodeSchedule` functions +* #431: Support for the `WWW-Authenticate` header on failed Authentication (401) responses +* #433: Support in custom Authentication types to allow returning extra Headers on the response +* #435: New `Set-PodeScheduleConcurrency` function to set the max number of concurrent schedules +* #440: Adds support in the `package.json` for custom PowerShell Repositories + +### Bugs +* #429: Running `pode start` failed to invoke server script on some platforms +* #441: Fixes an issue where local modules failed to resolve correct path +``` + +## v1.2.1 + +Date: 2nd December 2019 + +```plain +### Enhancements +* #415: New functions for invoking Timer and Schedules adhoc + +### Bugs +* #416: Fix for using `*/INT` in cron-expressions + +### Documentation +* #418: Docs and examples typo fixes +``` + +## v1.2.0 + +Date: 13th November 2019 + +```plain +### Features +* #395: Built-in support for using Server-to-Client websockets +* #389: Support for defining custom body/payload parsers for specific ContentTypes + +### Enhancements +* #401: Support for running a Schedule/Timer's logic when the server starts/restarts +* #400: Helper wrapper method `Out-PodeHost` to output data to the main host terminal +* #390: Support for setting a Status Code on all "Write-Pode[Type]Response" functions +* #386: Support to set a fixed ContentType on `Set-PodeResponseAttachment` (thanks @Windos!) +* #383: If a called route exists but for a different HTTP method, then return a 405 not a 404 +* #382: Support on Unix environments to terminate/restart a server using Shift+C/R + +### Documentation +* #405: How to create a server that has endpoints accessible externally +* #399: Reference to the literal parameter names on Schedules +* #396: How to return a custom Status Code and/or message from an Authenticator +``` + +## v1.1.0 + +Date: 28th September 2019 + +```plain +### Features +* #376: *Experimental* support for cross-platform HTTPS! + +### Bugs +* #372: Fixed an issue when getting the length of strings in `Get-PodeCount` (thanks @Fraham!) +* #384: Fixed `Set-PodeResponseAttachment` not setting the ContentLength (plus support of literal paths) + +### Packaging +* #375: Update the Dockerfiles to PowerShell 6.2.3 +* #253: Publish the Docker images on the GitHub Package Registry +``` + +## v1.0.1 + +Date: 4th September 2019 + +```plain +### Bugs +* #367: If a "server.psd1" file is not present, Logging will not work +* #368: Logging will attempt to mask everything if no mask patterns are supplied +``` + +## v1.0.0 + +Date: 2nd September 2019 + +```plain +### Features +* #228: Support for rendering Markdown as HTML (Fully supported in PowerShell 7+) +* #334: New "ConvertTo-PodeRoute" function to automatically make Routes from Functions/Modules +* #344: New "Add-PodePage" function to more easily make GET Routes for simple pages + +### Enhancements +* #328: New "Get-PodeAuthADUser" parameter -NoGroups, to skip retrieving groups from AD +* #330: Allow for -ArgumentList on Routes, Handlers, Timers, Schedules, etc - now they can be more dynamic +* #341: Allow Show-PodeGui to work under PowerShell 7 on Windows +* #343: Ability to mask data in logs using Regex +* #352: On "Add-PodeEndpoint", split the -Address parameter into -Address/-Port parameters +* #354: Two new functions for Sessions to Save and Remove them +* #355: Support on "Add-PodeEndpoint" for a -RedirectTo parameter, to automatically build a redirect Route + +### Bugs +* #312: On Static Routes, don't create a PSDrive when the Source is a File Share +* #318: For Cron Expressions, split the DayOfWeek and DayOfMonth +* #324: Setting Authentication middleware globally didn't save the Session object +* #347: Route parameters fail if the value contains a dot, or other special characters +* #351: Stop the "Done" message appearing when the server errors + +### Packaging +* #338: Update the version of MkDocs Material Theme to v4.4.0 +* #349: Update the Dockerfiles to PowerShell 6.2.2 + +### Internal Code +* #279, #279, #287, #289, #290, #291, #292, #294, #295, #296, #297, #305, #306, #314, #315 + - Convert all functions to PowerShell Syntax +* #303: Change from using "pode..json" files to "server..psd1" files + +### Documentation +* #299: Rebuild Documentation's Functions section using PlatyPS +* #316: Write a migration guide for going from v0.X to v1.0 +* #321: Go through all documentation, ensuring it's up-to-date with new Syntax +``` + +## v0.32.0 + +Date: 28th June 2019 + +```plain +### Enhancements +* #270: Support on `gui` to specify the width and height of the window +* #280: Support when file monitoring to output the files that caused the server to restart +* #282: New actions on `state` to save and restore to to/from a file + +### Bugs +* #271: Fix in `Convert-PodePathPatternsToRegex` when converting file names - thanks @Fraham! + +### Documentation +* #284: Notes in documentation about referencing JSON payload data in PowerShell 4/5 +``` + +## v0.31.0 + +Date: 11th June 2019 + +```plain +### Features +* #264: Support for Azure Functions and AWS Lambda +* #264: New `header` function for adding/setting and getting header values from the Request/Response + +### Enhancements +* #264: Cookies are now done via the "Set-Cookie" header, meaning `cookie` now appropriately sets multiple cookies +* #266: Have a `-Browse` flag on the `server` to auto-launch the website in a browser + +### Bugs +* #264: The `text` function now sets the content-type to "text/plain" by default +``` + +## v0.30.0 + +Date: 26th May 2019 + +```plain +### Enhancements +* #245: Support for Windows AD group validation on the inbuilt 'windows-ad' authentication validator +* #250: Support for bulk importing/loading scripts and modules +* #251: Support on routes to supply a FilePath to a script that contains the route's scriptblock +* #252: Support on the server function to supply a custom RootPath + +### Performance +* #258: Performance improvements to all aspects of a web request, reducing response times + +### Packaging +* #261: Docker images updated to PowerShell Core v6.2.1 +``` + +## v0.29.0 + +Date: 10th May 2019 + +```plain +### Enhancements +* #216: Multi-content-type support on Error Pages +* #232: Support for setting/forcing default content types on routes +* #243: Support on Static Routes to flag them as "Download Only" +* #248: Ability to alter the server's root path + +### Packaging +* #227: Docker images updated to PowerShell Core v6.2.0 +* #233: New ARM32 docker image, enabling support for Raspberry Pi + +### Build +* #237, #238, #239: Updates to CI tools +``` + +## v0.28.1 + +Date: 16th April 2019 + +```plain +### Bugs +* #226: Adds the "gui" function to export list +``` + +## v0.28.0 + +Date: 13th April 2019 + +```plain +### Features +* #210: New "cookie" function added, to support setting/getting cookies - including signing them +* #211: Support for CSRF via the new "csrf" function, which generates valid middleware and random tokens + +### Enhancements +* #204: Support on the "import" function to import PSSnapIns +* #223: Support for using a Thumbprint on the "listen" function instead of Certificate name + +### Bugs +* #206: When disposing/restarting the SMTP server, send a "QUIT" message if still connected + +### Clean-Up +* #209: Rename of internal function to avoid collisions, and change "Get-PodeConfiguration" to "config" +``` + +## v0.27.3 + +Date: 4th April 2019 + +```plain +### Bugs +* #217: Binding to hostname throws error +``` + +## v0.27.2 + +Date: 27th March 2019 + +```plain +### Bugs +* #212: Incorrect variable name used in html, csv, xml and json functions when referencing files +``` + +## v0.27.1 + +Date: 16th March 2019 + +```plain +### Bugs +* #199: Fix issues with relative paths when running server as a service +* #200: Fix issue with file monitor, where folder patterns fail to match on new files +``` + +## v0.27.0 + +Date: 14th March 2019 + +```plain +### Features +* #185: Support for Server Restarts either Periodically or at specific Times, with support for cron expressions +* #188: Support for Custom Error pages, with inbuilt Pode error pages + +### Enhancements +* #189: SMTP server to parse data headers and have them set on the event object + +### Performance +* #196: Massive improvements to performance when loading static content + +### Bugs +* #181: Importing modules into the current scope should be done Globally, making them instantly accessible +* #183: TCP Reads and Writes should be Async so they can be terminated more easily +* #184: SMTP and TCP servers fail to Restart +* #196: Default paths on Static Content fail when using nested directories + +### General +* #194: Update Dockerfile from using PSCore 6.1.0 to 6.1.3 +``` + +## v0.26.0 + +Date: 17th February 2019 + +```plain +### Features +* #162: Basic support for local modules in "package.json" on "pode install" +* #175: Support for flash messages on sessions, and in authentication + +### Bugs +* #72: RunspacePools aren't being recreated during a restart, and modules fail to import into other RunspacePools +``` + +## v0.25.0 + +Date: 5th February 2019 + +```plain +### Features +* #170: Support for Static Content Caching, with ability to include/exclude routes/extensions + +### Enhancements +* #161: New method to return configuration from the pode.json file, plus improved docs and support for environment configs +* #165: Support on the inbuilt SMTP server for Subject and decoded Body +* #168: Ability to exclude/include paths/extensions when triggering an Internal Restart + +### Documentation +* #45: Add "Known Issues" pages to documentation + +### Clean-Up +* #160: Internally, rename occurrences of $PodeSession to $PodeContext +``` + +## v0.24.0 + +Date: 18th January 2019 + +```plain +### Features +* #125: Helper support function for uploading files from a web form + +### Enhancements +* #149: Inbuilt support for Windows AD Authentication + +### Bugs +* #152: Fix the Choco install script so it installs the module for PowerShell Core as well +* #155: After an Internal Restart, the View Engine is not set back to the default +* #158: If views/public directories don't exist, the creation of PSDrive fails +``` + +## v0.23.0 + +Date: 24th December 2018 + +```plain +### Features +* #77: Ability to run a web server, and view it through a Desktop Application (Windows only) + +### Enhancements +* #137: Don't require admin privileges when listening on Localhost +* #140: Add a Custom switch to the Logger function - no need to use the "custom_" format any more! +* #142: Ability to listen on multiple endpoints - especially useful for hostnames against a single IP address +* #143: Support on routes to allow them to be bound against specific hostnames/protocols +* #146: Listen function to have Name parameter - so we can select which one to bind a Route/Gui to better +``` + +## v0.22.0 + +Date: 7th December 2018 + +```plain +### Enhancements +* #123: Ability to remove a `route` +* #124: Views, Public and custom static routes now use `New-PSDrive` to prevent directory tranversing +* #128: Ability to `listen` using a host name +* #130: `auth` now allows re-using inbuilt/custom parsers. Rather than `name` the type, the name is now any custom name you want to use and yuo specify the `-type` (like basic, etc). If no `-type` supplied, `name` is used as the type instead +* #131: There's now a route parameter on `middleware`, so you can define global middleware that only run on requests for specific routes. +``` + +## v0.21.0 + +Date: 2nd November 2018 + +```plain +### Enhancements +* #110: Return a 401 for inaccessible files +* #116: Support on custom static content, for returning `index.html` or `default.html` (plus others), if a directory is requested + +### Bugs +* #111: Separate out the `service` server type into own runspace +* #112: Server should return a 500 if middleware/route fails unexpectedly, rather than a 200 + +### Documentation +* #120: Added examples of running scripts as Windows or Linux services [here](https://badgerati.github.io/Pode/Getting-Started/RunAsService/) + +### Clean-Up +* #118: Rename `$WebSession` to `$WebEvent` - internal references only +``` + +## v0.20.0 + +Date: 20th October 2018 + +```plain +### Documentation +* Extended documentation for third-party template engines +* "Building your first app" documentation + +### Features +* #103: Adds support for custom static routes + +### Enhancements +* #101: Adds a `-Limit` parameter to schedules +* `import` function now supports installed modules + +### Clean-Up +* #102: Logging converted to internal `endware` script +``` + +## v0.19.1 + +Date: 9th October 2018 + +```plain +### Documentation +* #91: This release contains far better documentation for Pode: https://badgerati.github.io/Pode + +### Enhancements +* #93: Updates PowerShell Docker image to 6.1.0, so internal restarts now work +* #96: Chocolatey package now contains the module, rather than downloading from GitHub +* Adds more aliases for parameters on core functions +* Renames `script` function to `import` (the former is still supported) +* New CI builder: Travis CI, used to test Pode on *nix and PowerShell Core +* Minor miscellaneous stability fixes +``` + +## v0.19.0 + +Date: 14th September 2018 + +```plain +### Features +* #84: Session cookie support, with in-mem/custom data storage +* #86: Request authentication support. Currently implemented: Basic, Forms, Custom + +### Enhancements +* #88: Enabling Ctrl+R to be pressed on the CLI to trigger a server restart - similar to using `-FileMonitor`. +``` + +## v0.18.0 + +Date: 25th August 2018 + +```plain +### Features +* #78: Middleware support for web servers, allowing custom logic and extension modules on web request/responses + +### Enhancements +* #81: Added aliases onto some of the `Server` parameters +``` + +## v0.17.0 + +Date: 19th August 2018 + +```plain +### Features +* #43: Ability to generate self-signed certificates, and bind those certs - or pre-installed certs - when using HTTPS +* #71: New `scripts` call to specify external modules that should be imported into each runspace + +### Bugs +* #71: Unable to access functions from external scripts +* #73: Calling `pode start` fails to import Pode module into runspaces +``` + +## v0.16.0 + +Date: 8th August 2018 + +```plain +### Features +* #66: Support for basic rate limiting of requests per x seconds from IPs +* #68: Support for scheduled tasks using cron expressions + +### Enhancements +* #62: Helper function to ease URL redirection +* #64: Have a '*' HTTP method so a route can be used on every method +``` + +## v0.15.0 + +Date: 13th July 2018 + +```plain + +### Features +* #31: Support for multithreaded responses on web, smtp and tcp servers using `-Threads` on your Server block + +### Misc +* #59: Removal of obsolete functions, such as the older `Write-JsonResponse` which is now just `Json` +* #31: Addition of some minor performance tests using `k6` +* Addition of new icon and logo for Pode +``` + +## v0.14.0 + +Date: 6th July 2018 + +```plain +### Features +* #21: Ability for Pode to Internally Restart when a File Change is Detected +* #52: Support for Allowing/Denying IP and Subnet Addresses + +### Enhancements +* #44: Setup Unit Tests with Pester and run on AppVeyor + +### Bugs +* #51: Set Dockerfile to use a fixed version of the PowerShell container, rather than latest +* #55: Setup SMTP/TCP listeners to run in separate runspace like Web +``` + +## v0.13.0 + +Date: 23rd June 2018 + +```plain +### Features +* #40: Ability to add variables to a shared state, so you can re-use variables in timers, loggers, and routes +``` + +## v0.12.0 + +Date: 15th June 2018 + +```plain +### Features +* #33: Support for logging to the terminal, files, and custom loggers for LogStash/Fluentd/etc +* #35: New `Attach` function to help attach files from the public directory to the response for downloading + +### Enhancements +* #32: Ability to listen on a specific IP address using `-IP` on a `Server` +* #36: Support for relative paths on views/public content, when running server script from non-root directory +``` + +## v0.11.3 + +Date: 10th June 2018 + +```plain +### Bugs and Enhancements +* #22: Proper fix for high CPU usage, by using `Task.Wait` with `CancellationTokens`; A Runspace is setup to monitor for key presses, and on `Ctrl+C` will `Cancel()` the token and terminate Pode +``` + +## v0.11.2 + +Date: 8th June 2018 + +```plain +### Bugs +* #22: Hot fix patch for reducing high CPU usage when idle +``` + +## v0.11.1 + +Date: 1st June 2018 + +```plain +### Bugs +* #16: Status and Include functions were missing from module export list +``` + +## v0.11.0 + +Date: 30th May 2018 + +```plain +### Features +* #5: Async timers to run tasks and processes in a separate thread (see timers sections in README) + +### Enhancements +* #7: New `status` function to easily alter the StatusCode of a Response +* #8: New `json`, `xml`, `html`, `csv`, `view` and `tcp` functions to replace current "Write-Response" - now obsolete - functions (see ticket for explanation, and README for usage) + +### Bugs +* #12: Fixed an issue that caused image files (and others) to not render appropriately +``` diff --git a/examples/OpenApi-TuttiFrutti.ps1 b/examples/OpenApi-TuttiFrutti.ps1 index e80ff8023..5b70abed6 100644 --- a/examples/OpenApi-TuttiFrutti.ps1 +++ b/examples/OpenApi-TuttiFrutti.ps1 @@ -1029,10 +1029,10 @@ Some useful links: } - $yaml = Get-PodeOADefinition -Format Yaml -DefinitionTag 'v3.1' - $json = Get-PodeOADefinition -Format Json -DefinitionTag 'v3' + # $yaml = Get-PodeOADefinition -Format Yaml -DefinitionTag 'v3.1' + # $json = Get-PodeOADefinition -Format Json -DefinitionTag 'v3' - Write-PodeHost "`rYAML Tag: v3.1 Output:`r $yaml" + # Write-PodeHost "`rYAML Tag: v3.1 Output:`r $yaml" - Write-PodeHost "`rJSON Tag: v3 Output:`r $json" + # Write-PodeHost "`rJSON Tag: v3 Output:`r $json" } \ No newline at end of file diff --git a/examples/PetStore/Petstore-OpenApi.ps1 b/examples/PetStore/Petstore-OpenApi.ps1 index ed78f7f96..983df0ff8 100644 --- a/examples/PetStore/Petstore-OpenApi.ps1 +++ b/examples/PetStore/Petstore-OpenApi.ps1 @@ -111,6 +111,9 @@ Start-PodeServer -Threads 1 -ScriptBlock { Add-PodeEndpoint -Address (Get-PodeConfig).Address -Port (Get-PodeConfig).RestFulPort -Protocol Http -Default } + # Set the default endpoint to use the PodeFavicon icon + Add-PodeFavicon -Default + # Enable error logging New-PodeLoggingMethod -Terminal | Enable-PodeErrorLogging diff --git a/examples/assets/[metadata].json b/examples/assets/[metadata].json new file mode 100644 index 000000000..de4836e81 --- /dev/null +++ b/examples/assets/[metadata].json @@ -0,0 +1,3 @@ +{ + "name": "example" +} \ No newline at end of file diff --git a/examples/public/[brackets].txt b/examples/public/[brackets].txt new file mode 100644 index 000000000..72cf1fa71 --- /dev/null +++ b/examples/public/[brackets].txt @@ -0,0 +1 @@ +Brackets test file \ No newline at end of file diff --git a/licenses/LICENSE.Font-Awesome.txt b/licenses/LICENSE.Font-Awesome.txt deleted file mode 100644 index 92f7c13b5..000000000 --- a/licenses/LICENSE.Font-Awesome.txt +++ /dev/null @@ -1,167 +0,0 @@ -Project URL: https://github.com/FortAwesome/Font-Awesome - -Fonticons, Inc. (https://fontawesome.com) - --------------------------------------------------------------------------------- - -Font Awesome Free License - -Font Awesome Free is free, open source, and GPL friendly. You can use it for -commercial projects, open source projects, or really almost whatever you want. -Full Font Awesome Free license: https://fontawesome.com/license/free. - --------------------------------------------------------------------------------- - -# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) - -The Font Awesome Free download is licensed under a Creative Commons -Attribution 4.0 International License and applies to all icons packaged -as SVG and JS file types. - --------------------------------------------------------------------------------- - -# Fonts: SIL OFL 1.1 License - -In the Font Awesome Free download, the SIL OFL license applies to all icons -packaged as web and desktop font files. - -Copyright (c) 2024 Fonticons, Inc. (https://fontawesome.com) -with Reserved Font Name: "Font Awesome". - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - -SIL OPEN FONT LICENSE -Version 1.1 - 26 February 2007 - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting — in part or in whole — any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. - --------------------------------------------------------------------------------- - -# Code: MIT License (https://opensource.org/licenses/MIT) - -In the Font Awesome Free download, the MIT license applies to all non-font and -non-icon files. - -Copyright 2024 Fonticons, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in the -Software without restriction, including without limitation the rights to use, copy, -modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, subject to the -following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - --------------------------------------------------------------------------------- - -# Attribution - -Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font -Awesome Free files already contain embedded comments with sufficient -attribution, so you shouldn't need to do anything additional when using these -files normally. - -We've kept attribution comments terse, so we ask that you do not actively work -to remove them from files, especially code. They're a great way for folks to -learn about Font Awesome. - --------------------------------------------------------------------------------- - -# Brand Icons - -All brand icons are trademarks of their respective owners. The use of these -trademarks does not indicate endorsement of the trademark holder by Font -Awesome, nor vice versa. **Please do not use brand logos for any purpose except -to represent the company, product, or service to which they refer.** \ No newline at end of file diff --git a/licenses/LICENSE.bootstrap.txt b/licenses/LICENSE.bootstrap.txt index 9bdc9993e..4a8a573a0 100644 --- a/licenses/LICENSE.bootstrap.txt +++ b/licenses/LICENSE.bootstrap.txt @@ -2,7 +2,7 @@ Project URL: https://github.com/twbs/bootstrap The MIT License (MIT) -Copyright (c) 2011-2024 The Bootstrap Authors +Copyright (c) 2011-2025 The Bootstrap Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/licenses/LICENSE.highlightjs.txt b/licenses/LICENSE.highlightjs.txt index fb67067ed..c06946655 100644 --- a/licenses/LICENSE.highlightjs.txt +++ b/licenses/LICENSE.highlightjs.txt @@ -1,4 +1,4 @@ -Project URL: https://github.com/highlightjs/highlight.js/ +Project URL: https://github.com/highlightjs/highlight.js BSD 3-Clause License diff --git a/licenses/LICENSE.redoc.txt b/licenses/LICENSE.redoc.txt index fece4b3d5..6f659418e 100644 --- a/licenses/LICENSE.redoc.txt +++ b/licenses/LICENSE.redoc.txt @@ -2,7 +2,7 @@ Project URL: https://github.com/Redocly/redoc The MIT License (MIT) -Copyright (c) 2015-present, Rebilly, Inc. +Copyright (c) 2015-present, Rebilly, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 000000000..412cf85c9 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "pode", + "description": "Web Component for use with the Pode PowerShell web server", + "repository": "https://github.com/Badgerati/Pode.git", + "author": "Matthew Kelly ", + "license": "MIT", + "dependencies": { + "@highlightjs/cdn-assets": "11.11.1", + "@stoplight/elements": "9.0.1", + "bootstrap": "5.3.5", + "openapi-explorer": "2.2.734", + "rapidoc": "9.3.8", + "rapipdf": "2.2.1", + "redoc": "2.5.0", + "swagger-editor-dist": "4.14.5", + "swagger-ui-dist": "5.21.0" + } +} \ No newline at end of file diff --git a/pode.build.ps1 b/pode.build.ps1 index ae8862739..3222d086e 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -86,6 +86,7 @@ [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUSeDeclaredVarsMoreThanAssignments', '')] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPositionalParameters', '')] param( [string] $Version = '0.0.0', @@ -118,8 +119,9 @@ $Versions = @{ MkDocs = '1.6.1' PSCoveralls = '1.0.0' DotNet = $SdkVersion - MkDocsTheme = '9.6.4' + MkDocsTheme = '9.6.12' PlatyPS = '0.14.2' + Yarn = '1.22.22' } @@ -881,8 +883,6 @@ function Split-PodeBuildPwshPath { } } - - # Check if the script is running under Invoke-Build if (($null -eq $PSCmdlet.MyInvocation) -or ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('BuildRoot') -and ($null -eq $BuildRoot))) { Write-Host 'This script is intended to be run with Invoke-Build. Please use Invoke-Build to execute the tasks defined in this script.' -ForegroundColor Yellow @@ -932,7 +932,6 @@ Add-BuildTask Default { Write-Host '- ReleaseNotes: Generates release notes based on merged pull requests.' } - <# # Helper Tasks #> @@ -1003,6 +1002,10 @@ Add-BuildTask BuildDeps { Write-Warning "The requested SDK version '$SdkVersion' is superseded by the installed '$($script:AvailableSdkVersion)' framework." } + if (!(Test-PodeBuildCommand 'yarn')) { + Invoke-PodeBuildInstall 'yarn' $Versions.Yarn + } + } # Synopsis: Install dependencies for running tests @@ -1043,7 +1046,7 @@ Add-BuildTask IndexSamples { $excludeDirs = @('scripts', 'views', 'static', 'public', 'assets', 'timers', 'modules', 'Authentication', 'certs', 'logs', 'relative', 'routes', 'issues') - # Convert exlusion list into single regex pattern for directory matching + # Convert exclusion list into single regex pattern for directory matching $dirSeparator = [IO.Path]::DirectorySeparatorChar $excludeDirs = "\$($dirSeparator)($($excludeDirs -join '|'))\$($dirSeparator)" @@ -1075,17 +1078,11 @@ Add-BuildTask IndexSamples { #> # Synopsis: Build the .NET Listener -Add-BuildTask Build BuildDeps, { +Add-BuildTask Build BuildDeps, Yarn, { if (Test-Path ./src/Libs) { Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null } - - - - # Retrieve the SDK version being used - # $dotnetVersion = dotnet --version - # Display the SDK version Write-Output "Building targets '$($targetFrameworks -join "','")' using .NET '$AvailableSdkVersion' framework." @@ -1102,9 +1099,88 @@ Add-BuildTask Build BuildDeps, { finally { Pop-Location } - } +# synopsis: Download the npm packages to pode_modules folder +Add-BuildTask Yarn { + if ($PSVersionTable.PSEdition -eq 'Desktop') { + yarn install --force --ignore-scripts --ignore-optional --ignore-engines --modules-folder pode_modules + } + else { + yarn install --force --ignore-scripts --ignore-optional --ignore-engines --modules-folder pode_modules 2>&1 | Select-String -NotMatch '^warning' + } + + if (!$? -or ($LASTEXITCODE -ne 0)) { + throw "yarn install failed with exit code $($LASTEXITCODE)" + } +}, MoveLibs + +# Synopsis: Move the libraries to the public directory +Add-BuildTask MoveLibs { + + # Define source and target + $NodeModules = Join-Path -Path $PSScriptRoot -ChildPath 'pode_modules' + $Target = Join-Path -Path $PSScriptRoot -ChildPath '/src/Misc/libs' + $LicenseTarget = Join-Path -Path $PSScriptRoot -ChildPath '/licenses' + + # Clean third_party (optional: only if you want to start fresh) + if (Test-Path $Target) { + Remove-Item -Recurse -Force -Path $Target | Out-Null + } + New-Item -ItemType Directory -Force -Path $Target | Out-Null + + # Create subfolders and copy only needed files + $CopyList = @( + @{ From = "$NodeModules/swagger-ui-dist/swagger-ui.css"; To = "$Target/swagger/" }, + @{ From = "$NodeModules/swagger-ui-dist/swagger-ui-bundle.js"; To = "$Target/swagger/" }, + @{ From = "$NodeModules/swagger-ui-dist/LICENSE"; To = "$LicenseTarget/LICENSE.swagger-ui.txt" ; Comment = 'Project URL: https://github.com/swagger-api/swagger-ui' }, + + @{ From = "$NodeModules/swagger-editor-dist/swagger-editor.css"; To = "$Target/swagger-editor/" }, + @{ From = "$NodeModules/swagger-editor-dist/swagger-editor-bundle.js"; To = "$Target/swagger-editor/" }, + @{ From = "$NodeModules/swagger-editor-dist/swagger-editor-standalone-preset.js"; To = "$Target/swagger-editor/" }, + @{ From = "$NodeModules/swagger-editor-dist/LICENSE"; To = "$LicenseTarget/LICENSE.swagger-editor.txt" ; Comment = 'Project URL: https://github.com/swagger-api/swagger-editor' }, + + @{ From = "$NodeModules/redoc/bundles/redoc.standalone.js"; To = "$Target/redoc/" }, + @{ From = "$NodeModules/redoc/LICENSE"; To = "$LicenseTarget/LICENSE.redoc.txt" ; Comment = 'Project URL: https://github.com/Redocly/redoc' }, + + @{ From = "$NodeModules/@stoplight/elements/styles.min.css"; To = "$Target/stoplight/elements/" }, + @{ From = "$NodeModules/@stoplight/elements/web-components.min.js"; To = "$Target/stoplight/elements/" }, + @{ From = "$NodeModules/@stoplight/elements/LICENSE"; To = "$LicenseTarget/LICENSE.stoplight.txt" ; Comment = 'Project URL: https://github.com/stoplightio/elements' }, + + @{ From = "$NodeModules/@highlightjs/cdn-assets/styles/monokai-sublime.min.css"; To = "$Target/highlightjs/styles/" }, + @{ From = "$NodeModules/@highlightjs/cdn-assets/highlight.min.js"; To = "$Target/highlightjs/" }, + @{ From = "$NodeModules/@highlightjs/cdn-assets/LICENSE"; To = "$LicenseTarget/LICENSE.highlightjs.txt" ; Comment = 'Project URL: https://github.com/highlightjs/highlight.js' }, + + @{ From = "$NodeModules/rapipdf/dist/rapipdf-min.js"; To = "$Target/rapipdf/" }, + @{ From = "$NodeModules/rapipdf/LICENSE.txt"; To = "$LicenseTarget/LICENSE.rapipdf.txt" ; Comment = 'Project URL: https://github.com/mrin9/RapiPdf' }, + + + @{ From = "$NodeModules/rapidoc/dist/rapidoc-min.js"; To = "$Target/rapidoc/" }, + @{ From = "$NodeModules/rapidoc/LICENSE.txt"; To = "$LicenseTarget/LICENSE.rapidoc.txt" ; Comment = 'Project URL: https://github.com/rapi-doc/RapiDoc' }, + + @{ From = "$NodeModules/openapi-explorer/dist/browser/openapi-explorer.min.js"; To = "$Target/explorer/browser/" } + @{ From = "$NodeModules/openapi-explorer/LICENSE"; To = "$LicenseTarget/LICENSE.openapi-explorer.txt" ; Comment = 'Project URL: https://github.com/Authress-Engineering/openapi-explorer' }, + + @{ From = "$NodeModules/bootstrap/dist/css/bootstrap.min.css"; To = "$Target/explorer/css/" }, + + @{ From = "$NodeModules/bootstrap/dist/css/bootstrap.min.css"; To = "$Target/bootstrap/css/" }, + @{ From = "$NodeModules/bootstrap/LICENSE"; To = "$LicenseTarget/LICENSE.bootstrap.txt" ; Comment = 'Project URL: https://github.com/twbs/bootstrap' } + ) + + foreach ($Item in $CopyList) { + # If Comment exists, prepend it properly depending on file type + if ($Item.Comment) { + $fileContent = Get-Content -Raw -Path $Item.From + ($Item.Comment + "`n`n" + $fileContent).Trim() | Out-File -FilePath $Item.To -Encoding utf8 -Force -NoNewline + } + else { + New-Item -ItemType Directory -Force -Path $Item.To | Out-Null + Copy-Item -Force -Path $Item.From -Destination $Item.To | Out-Null + } + } + + Write-Output "All third-party files copied to $Target" +} <# # Packaging @@ -1234,9 +1310,10 @@ Add-BuildTask TestNoBuild TestDeps, { $configuration = [PesterConfiguration]::Default $configuration.run.path = @('./tests/unit', './tests/integration') $configuration.run.PassThru = $true - $configuration.TestResult.OutputFormat = 'NUnitXml' $configuration.Output.Verbosity = $PesterVerbosity $configuration.TestResult.OutputPath = $Script:TestResultFile + $configuration.TestResult.OutputFormat = 'NUnitXml' + $configuration.TestResult.Enabled = $true # if run code coverage if enabled if (Test-PodeBuildCanCodeCoverage) { @@ -1265,7 +1342,7 @@ Add-BuildTask CheckFailedTests { } } -# Synopsis: If AppyVeyor or GitHub, push code coverage stats +# Synopsis: If AppVeyor or GitHub, push code coverage stats Add-BuildTask PushCodeCoverage -If (Test-PodeBuildCanCodeCoverage) { try { $service = Get-PodeBuildService @@ -1315,7 +1392,7 @@ Add-BuildTask DocsHelpBuild IndexSamples, DocsDeps, Build, { $content = (Get-Content -Path $_.FullName | ForEach-Object { $line = $_ - while ($line -imatch '\[`(?[a-z]+\-pode[a-z]+)`\](?([^(]|$))') { + while ($line -imatch '\[`(?[a-z]+\-pode[a-z]+)`\](?([^(] | $))') { $updated = $true $name = $Matches['name'] $char = $Matches['char'] @@ -1344,8 +1421,8 @@ Add-BuildTask DocsBuild DocsDeps, DocsHelpBuild, { # Clean-up #> -# Synopsis: Clean the build enviroment -Add-BuildTask Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs +# Synopsis: Clean the build environment +Add-BuildTask Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs, CleanYarn # Synopsis: Clean the Deliverable folder Add-BuildTask CleanDeliverable { @@ -1407,6 +1484,19 @@ Add-BuildTask CleanDocs { Remove-Item -Path $path -Force | Out-Null } } + +Add-BuildTask CleanYarn { + $path = Join-Path -Path $PSScriptRoot -ChildPath 'pode_modules' + if (Test-Path -Path $path -PathType Container) { + Write-Host "Removing $path" + Remove-Item -Path $path -Recurse -Force | Out-Null + } + $path = Join-Path -Path $PSScriptRoot -ChildPath '/src/Misc/libs' + if (Test-Path -Path $path -PathType Container) { + Write-Host "Removing $path" + Remove-Item -Path $path -Recurse -Force | Out-Null + } +} <# # Local module management #> @@ -1613,6 +1703,8 @@ task ReleaseNotes { foreach ($pr in $prs) { $labels = @($pr.labels.name) + + # skip PRs with certain labels if ($labels -icontains 'superseded' -or $labels -icontains 'new-release' -or $labels -icontains 'internal-code :hammer:' -or @@ -1620,7 +1712,20 @@ task ReleaseNotes { continue } - $label = ($pr.labels[0].name -split ' ')[0] + # filter out labels that are not relevant + $label = @(foreach ($label in $labels) { + if ($label -imatch '^(story|priority)') { + continue + } + + if ($label -inotmatch '\s\:') { + continue + } + + ($label -split ' ', 2)[0] + break + })[0] + if ([string]::IsNullOrWhiteSpace($label)) { $label = 'misc' } @@ -1689,7 +1794,7 @@ task ReleaseNotes { # add dependabot aggregated PRs if ($dependabot.Count -gt 0) { - $label = 'dependencies' + $label = 'Packaging' if (!$categories.Contains($label)) { $categories[$label] = @() } diff --git a/src/Listener/PodeContext.cs b/src/Listener/PodeContext.cs index 48be3955c..a8ec70a74 100644 --- a/src/Listener/PodeContext.cs +++ b/src/Listener/PodeContext.cs @@ -261,7 +261,8 @@ private void SetContextType() /// public void CancelTimeout() { - TimeoutTimer.Dispose(); + TimeoutTimer?.Dispose(); + TimeoutTimer = null; } /// @@ -272,12 +273,16 @@ public async Task Receive() { try { - // Start timeout + // Start timeout - unless receiving a WebSocket request. ContextTimeoutToken = new CancellationTokenSource(); - TimeoutTimer = new Timer(TimeoutCallback, null, Listener.RequestTimeout * 1000, Timeout.Infinite); + if (!IsWebSocketUpgraded) + { + TimeoutTimer = new Timer(TimeoutCallback, null, Listener.RequestTimeout * 1000, Timeout.Infinite); + } // Start receiving data. State = PodeContextState.Receiving; + try { PodeHelpers.WriteErrorMessage($"Receiving request", Listener, PodeLoggingLevel.Verbose, this); @@ -285,6 +290,14 @@ public async Task Receive() SetContextType(); await EndReceive(close).ConfigureAwait(false); } + catch (Exception ex) when (ex is IOException || ex is SocketException) + { + // ignore if listener is closing, else re-throw + if (Listener.IsConnected) + { + throw; + } + } catch (OperationCanceledException ex) when (ContextTimeoutToken.IsCancellationRequested) { PodeHelpers.WriteErrorMessage("Request timed out during receive operation", Listener, PodeLoggingLevel.Warning, this); @@ -373,6 +386,9 @@ public async Task UpgradeWebSocket(string clientId = null) // Send response to upgrade to WebSocket. await Response.Send().ConfigureAwait(false); + // Cancel the timeout timer before upgrading. + CancelTimeout(); + // Add the upgraded WebSocket to the listener. var signal = new PodeSignal(this, HttpRequest.Url.AbsolutePath, clientId); Request = new PodeSignalRequest(HttpRequest, signal); diff --git a/src/Listener/PodeHelpers.cs b/src/Listener/PodeHelpers.cs index 657f57668..50adc84c6 100644 --- a/src/Listener/PodeHelpers.cs +++ b/src/Listener/PodeHelpers.cs @@ -57,12 +57,12 @@ public static void WriteException(Exception ex, PodeConnector connector = defaul // write the exception to terminal Console.WriteLine($"[{level}] {ex.GetType().Name}: {ex.Message}"); - Console.WriteLine(ex.StackTrace); + Console.WriteLine(string.IsNullOrEmpty(ex.StackTrace) ? " [No Stack Trace]" : ex.StackTrace); if (ex.InnerException != null) { Console.WriteLine($"[{level}] {ex.InnerException.GetType().Name}: {ex.InnerException.Message}"); - Console.WriteLine(ex.InnerException.StackTrace); + Console.WriteLine(string.IsNullOrEmpty(ex.InnerException.StackTrace) ? " [No Stack Trace]" : ex.InnerException.StackTrace); } } diff --git a/src/Listener/PodeListener.cs b/src/Listener/PodeListener.cs index 46bea89b3..c0443c319 100644 --- a/src/Listener/PodeListener.cs +++ b/src/Listener/PodeListener.cs @@ -264,16 +264,6 @@ public override void Start() protected override void Close() { - // shutdown the sockets - PodeHelpers.WriteErrorMessage($"Closing sockets", this, PodeLoggingLevel.Verbose); - for (var i = Sockets.Count - 1; i >= 0; i--) - { - Sockets[i].Dispose(); - } - - Sockets.Clear(); - PodeHelpers.WriteErrorMessage($"Closed sockets", this, PodeLoggingLevel.Verbose); - // close existing contexts PodeHelpers.WriteErrorMessage($"Closing contexts", this, PodeLoggingLevel.Verbose); foreach (var _context in Contexts.ToArray()) @@ -308,6 +298,16 @@ protected override void Close() ServerEvents.Clear(); PodeHelpers.WriteErrorMessage($"Closed server events", this, PodeLoggingLevel.Verbose); + + // shutdown the sockets + PodeHelpers.WriteErrorMessage($"Closing sockets", this, PodeLoggingLevel.Verbose); + for (var i = Sockets.Count - 1; i >= 0; i--) + { + Sockets[i].Dispose(); + } + + Sockets.Clear(); + PodeHelpers.WriteErrorMessage($"Closed sockets", this, PodeLoggingLevel.Verbose); } } } \ No newline at end of file diff --git a/src/Listener/PodeProtocol.cs b/src/Listener/PodeProtocol.cs index b8316ecff..7eda55cd2 100644 --- a/src/Listener/PodeProtocol.cs +++ b/src/Listener/PodeProtocol.cs @@ -6,12 +6,12 @@ public class PodeProtocol public bool IsHttp { - get => (Type == PodeProtocolType.Http || Type == PodeProtocolType.HttpAndWs); + get => Type == PodeProtocolType.Http || Type == PodeProtocolType.HttpAndWs; } public bool IsWebSocket { - get => (Type == PodeProtocolType.Ws || Type == PodeProtocolType.HttpAndWs); + get => Type == PodeProtocolType.Ws || Type == PodeProtocolType.HttpAndWs; } public bool IsSmtp diff --git a/src/Listener/PodeRequest.cs b/src/Listener/PodeRequest.cs index 021d7ea1a..f8625735e 100644 --- a/src/Listener/PodeRequest.cs +++ b/src/Listener/PodeRequest.cs @@ -16,6 +16,9 @@ namespace Pode /// public class PodeRequest : PodeProtocol, IDisposable { + // Maximum buffer size for reading data from the input stream + protected const int MAX_BUFFER_SIZE = 16384; + // Endpoint information for remote and local addresses public EndPoint RemoteEndPoint { get; private set; } public EndPoint LocalEndPoint { get; private set; } @@ -60,10 +63,8 @@ public class PodeRequest : PodeProtocol, IDisposable // A fixed buffer used to temporarily store data read from the input stream. // This buffer is readonly to prevent reassignment and reduce memory allocations. - private readonly byte[] Buffer; - + private byte[] _buffer; private MemoryStream BufferStream; - private const int BufferSize = 16384; /// /// Initializes a new instance of the PodeRequest class. @@ -83,7 +84,6 @@ public PodeRequest(Socket socket, PodeSocket podeSocket, PodeContext context) Protocols = podeSocket.Protocols; Context = context; State = PodeStreamState.New; - Buffer = new byte[BufferSize]; // Allocate buffer once } /// @@ -229,6 +229,23 @@ private bool ValidateCertificateCallback(object sender, X509Certificate certific return true; } + /// + /// Provides access to a buffer. The buffer is allocated only when first requested, + /// saving memory if it is never needed. + /// This property is virtual to allow derived classes to override the buffer allocation behavior. + /// + protected virtual byte[] Buffer + { + get + { + if (_buffer == null) + { + _buffer = new byte[MAX_BUFFER_SIZE]; + } + return _buffer; + } + } + /// /// Receives data from the input stream and processes it. /// @@ -244,7 +261,7 @@ public async Task Receive(CancellationToken cancellationToken) } Error = null; - + var localBuffer = Buffer; using (BufferStream = new MemoryStream()) { var close = true; @@ -261,25 +278,29 @@ public async Task Receive(CancellationToken cancellationToken) { // Read data from the input stream #if NETCOREAPP2_1_OR_GREATER - read = await InputStream.ReadAsync(Buffer.AsMemory(0, BufferSize), cancellationToken).ConfigureAwait(false); + read = await InputStream.ReadAsync(localBuffer.AsMemory(0, MAX_BUFFER_SIZE), cancellationToken).ConfigureAwait(false); #else - read = await InputStream.ReadAsync(Buffer, 0, BufferSize, cancellationToken).ConfigureAwait(false); + read = await InputStream.ReadAsync(localBuffer, 0, MAX_BUFFER_SIZE, cancellationToken).ConfigureAwait(false); #endif } catch (Exception ex) when (ex is IOException || ex is ObjectDisposedException) { - PodeHelpers.WriteException(ex, Context.Listener, PodeLoggingLevel.Debug); + if (Context.Listener.IsConnected) + { + PodeHelpers.WriteException(ex, Context.Listener, PodeLoggingLevel.Debug); + } break; } + if (read <= 0) { break; } #if NETCOREAPP2_1_OR_GREATER - await BufferStream.WriteAsync(Buffer.AsMemory(0, read), cancellationToken).ConfigureAwait(false); + await BufferStream.WriteAsync(localBuffer.AsMemory(0, read), cancellationToken).ConfigureAwait(false); #else - await BufferStream.WriteAsync(Buffer, 0, read, cancellationToken).ConfigureAwait(false); + await BufferStream.WriteAsync(localBuffer, 0, read, cancellationToken).ConfigureAwait(false); #endif // Validate and parse the data if available @@ -342,31 +363,31 @@ public async Task Read(byte[] checkBytes, CancellationToken cancellation } // Read data from the input stream until the check bytes are found - var buffer = new byte[BufferSize]; + var localBuffer = Buffer; using (var bufferStream = new MemoryStream()) { while (true) { #if NETCOREAPP2_1_OR_GREATER // Read data from the input stream - var read = await InputStream.ReadAsync(buffer.AsMemory(0, BufferSize), cancellationToken).ConfigureAwait(false); + var read = await InputStream.ReadAsync(localBuffer.AsMemory(0, MAX_BUFFER_SIZE), cancellationToken).ConfigureAwait(false); if (read <= 0) { break; } // Write the data to the buffer stream - await bufferStream.WriteAsync(buffer.AsMemory(0, read), cancellationToken).ConfigureAwait(false); + await bufferStream.WriteAsync(localBuffer.AsMemory(0, read), cancellationToken).ConfigureAwait(false); #else // Read data from the input stream - var read = await InputStream.ReadAsync(buffer, 0, BufferSize, cancellationToken).ConfigureAwait(false); + var read = await InputStream.ReadAsync(localBuffer, 0, MAX_BUFFER_SIZE, cancellationToken).ConfigureAwait(false); if (read <= 0) { break; } // Write the data to the buffer stream - await bufferStream.WriteAsync(buffer, 0, read, cancellationToken).ConfigureAwait(false); + await bufferStream.WriteAsync(localBuffer, 0, read, cancellationToken).ConfigureAwait(false); #endif // Validate the input data if (Socket.Available > 0 || !ValidateInputInternal(bufferStream.ToArray(), checkBytes)) diff --git a/src/Listener/PodeResponse.cs b/src/Listener/PodeResponse.cs index 3bd9ed78d..bd4e54e13 100644 --- a/src/Listener/PodeResponse.cs +++ b/src/Listener/PodeResponse.cs @@ -11,6 +11,8 @@ namespace Pode { public class PodeResponse : IDisposable { + protected const int MAX_FRAME_SIZE = 8192; + public PodeResponseHeaders Headers { get; private set; } public int StatusCode = 200; public bool SendChunked = false; @@ -308,33 +310,55 @@ public async Task WriteFrame(string message, PodeWsOpCode opCode = PodeWsOpCode. } var msgBytes = Encoding.GetBytes(message); - var buffer = new List() { (byte)((byte)0x80 | (byte)opCode) }; + var msgLength = msgBytes.Length; + var offset = 0; + var firstFrame = true; - if (msgBytes.Length < 126) - { - buffer.Add((byte)((byte)0x00 | (byte)msgBytes.Length)); - } - else if (msgBytes.Length <= UInt16.MaxValue) + while (offset < msgLength || (msgLength == 0 && firstFrame)) { - buffer.Add((byte)((byte)0x00 | (byte)126)); - buffer.Add((byte)((msgBytes.Length >> 8) & (byte)255)); - buffer.Add((byte)(msgBytes.Length & (byte)255)); - } - else - { - buffer.Add((byte)((byte)0x00 | (byte)127)); - buffer.Add((byte)((msgBytes.Length >> 56) & (byte)255)); - buffer.Add((byte)((msgBytes.Length >> 48) & (byte)255)); - buffer.Add((byte)((msgBytes.Length >> 40) & (byte)255)); - buffer.Add((byte)((msgBytes.Length >> 32) & (byte)255)); - buffer.Add((byte)((msgBytes.Length >> 24) & (byte)255)); - buffer.Add((byte)((msgBytes.Length >> 16) & (byte)255)); - buffer.Add((byte)((msgBytes.Length >> 8) & (byte)255)); - buffer.Add((byte)(msgBytes.Length & (byte)255)); - } + var frameSize = Math.Min(msgLength - offset, MAX_FRAME_SIZE); + var frame = new byte[frameSize]; + Array.Copy(msgBytes, offset, frame, 0, frameSize); + + // fin bit and op code + var isFinal = offset + frameSize >= msgLength; + var finBit = (byte)(isFinal ? 0x80 : 0x00); + var opCodeByte = (byte)(firstFrame ? opCode : PodeWsOpCode.Continuation); + + // build the frame buffer + var buffer = new List { (byte)(finBit | opCodeByte) }; + + if (frameSize < 126) + { + buffer.Add((byte)((byte)0x00 | (byte)frameSize)); + } + else if (frameSize <= UInt16.MaxValue) + { + buffer.Add((byte)((byte)0x00 | (byte)126)); + buffer.Add((byte)((frameSize >> 8) & (byte)255)); + buffer.Add((byte)(frameSize & (byte)255)); + } + else + { + buffer.Add((byte)((byte)0x00 | (byte)127)); + buffer.Add((byte)((frameSize >> 56) & (byte)255)); + buffer.Add((byte)((frameSize >> 48) & (byte)255)); + buffer.Add((byte)((frameSize >> 40) & (byte)255)); + buffer.Add((byte)((frameSize >> 32) & (byte)255)); + buffer.Add((byte)((frameSize >> 24) & (byte)255)); + buffer.Add((byte)((frameSize >> 16) & (byte)255)); + buffer.Add((byte)((frameSize >> 8) & (byte)255)); + buffer.Add((byte)(frameSize & (byte)255)); + } + + // add the payload + buffer.AddRange(frame); - buffer.AddRange(msgBytes); - await Write(buffer.ToArray(), flush).ConfigureAwait(false); + // send + await Write(buffer.ToArray(), flush).ConfigureAwait(false); + offset += frameSize; + firstFrame = false; + } } public async Task WriteLine(string message, bool flush = false) @@ -342,6 +366,7 @@ public async Task WriteLine(string message, bool flush = false) await Write(Encoding.GetBytes($"{message}{PodeHelpers.NEW_LINE}"), flush).ConfigureAwait(false); } + // write a byte array to the actual client stream public async Task Write(byte[] buffer, bool flush = false) { if (Request.IsDisposed || !Request.InputStream.CanWrite) @@ -375,6 +400,30 @@ public async Task Write(byte[] buffer, bool flush = false) } } + public void WriteFile(string path) + { + WriteFile(new FileInfo(path)); + } + + public void WriteFile(FileSystemInfo file) + { + if (IsDisposed) + { + return; + } + + if (!(file is FileInfo fileInfo) || !fileInfo.Exists) + { + throw new FileNotFoundException($"File not found: {file.FullName}"); + } + + ContentLength64 = fileInfo.Length; + using (var fileStream = fileInfo.OpenRead()) + { + fileStream.CopyTo(OutputStream); + } + } + private void SetDefaultHeaders() { // ensure content length (remove for 1xx responses, ensure added otherwise) diff --git a/src/Listener/PodeServerSignal.cs b/src/Listener/PodeServerSignal.cs index fbb421ba8..e69f9825b 100644 --- a/src/Listener/PodeServerSignal.cs +++ b/src/Listener/PodeServerSignal.cs @@ -2,14 +2,45 @@ namespace Pode { + /// + /// Represents a server signal used by Pode that includes signal details and associated listener management. + /// public class PodeServerSignal : IDisposable { + private bool _disposed = false; + + /// + /// Gets the value of the server signal. + /// public string Value { get; private set; } + + /// + /// Gets the path associated with the signal. + /// public string Path { get; private set; } + + /// + /// Gets the client identifier that originated the signal. + /// public string ClientId { get; private set; } + + /// + /// Gets the timestamp when the signal was created (in UTC). + /// public DateTime Timestamp { get; private set; } + + /// + /// Gets the listener associated with processing the signal. + /// public PodeListener Listener { get; private set; } + /// + /// Initializes a new instance of the class. + /// + /// The value representing the signal. + /// The path associated with the signal request. + /// The unique identifier of the client. + /// The listener managing the server signal. public PodeServerSignal(string value, string path, string clientId, PodeListener listener) { Value = value; @@ -19,9 +50,38 @@ public PodeServerSignal(string value, string path, string clientId, PodeListener Listener = listener; } + /// + /// Releases the unmanaged and optionally managed resources used by the instance. + /// + /// + /// If set to true, both managed and unmanaged resources are disposed; if false, only unmanaged resources are disposed. + /// + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // Dispose managed resources. + Listener?.RemoveProcessingServerSignal(this); + } + // Clean up unmanaged resources here if there are any. + + _disposed = true; + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + /// + /// This method calls with true and suppresses the finalization + /// of the object, preventing any derived class finalizers from running unnecessarily. + /// public void Dispose() { - Listener.RemoveProcessingServerSignal(this); + Dispose(true); + GC.SuppressFinalize(this); } } -} \ No newline at end of file +} diff --git a/src/Listener/PodeSignalFrame.cs b/src/Listener/PodeSignalFrame.cs new file mode 100644 index 000000000..8af8e552a --- /dev/null +++ b/src/Listener/PodeSignalFrame.cs @@ -0,0 +1,112 @@ +using System; + +namespace Pode +{ + public class PodeSignalFrame + { + public bool IsFinalFrame { get; private set; } + public PodeWsOpCode OpCode { get; private set; } + public bool IsMasked { get; private set; } + public int PayloadLength { get; private set; } + public int Offset { get; private set; } + public byte[] MaskingKey { get; private set; } + public int Length { get; private set; } + + public bool AwaitingBody + { + get + { + return Length < Offset + PayloadLength; + } + } + + public PodeSignalFrame(byte[] bytes) + { + // total length of the frame currently supplied + Length = bytes.Length; + + // parse the first 2 bytes of the frame + IsFinalFrame = (bytes[0] & 0b10000000) != 0; + PayloadLength = bytes[1] & 0b01111111; + IsMasked = (bytes[1] & 0b10000000) != 0; + OpCode = (PodeWsOpCode)(bytes[0] & 0b00001111); + + // calculate the payload offset + Offset = 2; + if (PayloadLength == 126) + { + Offset += 2; + PayloadLength = BitConverter.ToUInt16(new byte[] { bytes[3], bytes[2] }, 0); + } + else if (PayloadLength >= 127) + { + Offset += 8; + PayloadLength = (int)BitConverter.ToUInt64(new byte[] { bytes[9], bytes[8], bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2] }, 0); + } + + // calculate the masking key + MaskingKey = default; + if (IsMasked) + { + MaskingKey = new byte[] { bytes[Offset], bytes[Offset + 1], bytes[Offset + 2], bytes[Offset + 3] }; + Offset += 4; + } + } + + public void Update(byte[] bytes) + { + Length = bytes.Length; + } + + public byte[] Decode(byte[] bytes) + { + if (AwaitingBody) + { + throw new InvalidOperationException("Frame is not complete"); + } + + // decode the payload + var payload = new byte[PayloadLength]; + for (var i = 0; i < PayloadLength; i++) + { + payload[i] = IsMasked + ? (byte)(bytes[Offset + i] ^ MaskingKey[i % 4]) + : bytes[Offset + i]; + } + + return payload; + } + + public static bool ValidateHeader(byte[] bytes) + { + // if the length is less than 2, we can't parse the header - missing code/length + if (bytes == default || bytes.Length < 2) + { + return false; + } + + // length offset + var length = bytes[1] & 0b01111111; + + var offset = 2; + if (length == 126) + { + offset += 2; + } + else if (length >= 127) + { + offset += 8; + } + + // mask offset + var isMasked = (bytes[1] & 0b10000000) != 0; + if (isMasked) + { + offset += 4; + } + + // do we have enough bytes for the header? + return bytes.Length >= offset; + } + } +} \ No newline at end of file diff --git a/src/Listener/PodeSignalRequest.cs b/src/Listener/PodeSignalRequest.cs index 13e2fa420..2848b891e 100644 --- a/src/Listener/PodeSignalRequest.cs +++ b/src/Listener/PodeSignalRequest.cs @@ -1,124 +1,237 @@ using System; +using System.IO; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; namespace Pode { + /// + /// Represents a WebSocket signal request. Inherits from PodeRequest to leverage the base connection + /// and stream handling, and implements WebSocket-specific logic like frame parsing, op-code handling, + /// and resource cleanup. + /// public class PodeSignalRequest : PodeRequest { + // The WebSocket operation code extracted from the incoming frame. public PodeWsOpCode OpCode { get; private set; } + + // The decoded message body as a string. public string Body { get; private set; } + + // The stream used to read the message body. + private MemoryStream BodyStream; + + // The raw data received (entire WebSocket frame). public byte[] RawBody { get; private set; } + + // The signal object associated with this request. public PodeSignal Signal { get; private set; } + + // The URL constructed from the original HTTP request. public Uri Url { get; private set; } + + // The Host header from the original HTTP request. public string Host { get; private set; } + + // Total length of the content/body. public int ContentLength { get; private set; } + // Private field to hold the WebSocket close status. private WebSocketCloseStatus _closeStatus = WebSocketCloseStatus.Empty; + + // Public property exposing the close status. public WebSocketCloseStatus CloseStatus { get => _closeStatus; } + // Private field to hold the close description. private string _closeDescription = string.Empty; + + // Public property exposing the close description. public string CloseDescription { get => _closeDescription; } + // Indicates whether the connection should be closed immediately. + // For WebSocket, this is true if the received op-code is 'Close'. public override bool CloseImmediately { get => OpCode == PodeWsOpCode.Close; } + // Determines if the request is processable. + // It excludes control frames (Ping/Pong) and ensures that a non-empty body exists. public override bool IsProcessable { get => !CloseImmediately && OpCode != PodeWsOpCode.Pong && OpCode != PodeWsOpCode.Ping && !string.IsNullOrEmpty(Body); } + // The current frame being processed. + private PodeSignalFrame CurrentFrame { get; set; } = default; + + /// + /// Overrides the base Buffer property to always return a new buffer. + /// This ensures that every time a buffer is needed for parsing a WebSocket frame, + /// a fresh array is allocated, avoiding any residual data from previous operations. + /// Although this introduces a small allocation overhead, it ensures data integrity + /// for WebSocket communication. + /// + protected override byte[] Buffer + { + get + { + return new byte[MAX_BUFFER_SIZE]; + } + } + + /// + /// Constructs a new PodeSignalRequest from an existing HTTP request and an associated signal. + /// Sets up the connection as a WebSocket request, preserving the original host and URL details. + /// + /// The original HTTP request. + /// The associated PodeSignal. public PodeSignalRequest(PodeHttpRequest request, PodeSignal signal) - : base(request) + : base(request) // Copy base request properties from the HTTP request. { Signal = signal; IsKeepAlive = true; + + // Set protocol type to WebSocket. Type = PodeProtocolType.Ws; + // Determine the protocol prefix based on SSL usage. var _proto = IsSsl ? "wss" : "ws"; Host = request.Host; + + // Build the WebSocket URL from the original request's authority and path/query. Url = new Uri($"{_proto}://{request.Url.Authority}{request.Url.PathAndQuery}"); } + /// + /// Creates a new client signal object from this request. + /// This allows further processing of the signal within the Pode framework. + /// + /// A new PodeClientSignal instance. public PodeClientSignal NewClientSignal() { return new PodeClientSignal(Signal, Body, Context.Listener); } - protected override async Task Parse(byte[] bytes, CancellationToken cancellationToken) + protected override bool ValidateInput(byte[] bytes) { - // get the length and op-code - var dataLength = bytes[1] - 128; - OpCode = (PodeWsOpCode)(bytes[0] & 0b00001111); - var offset = 0; + // if we have a current frame, update it with the new bytes and check if it's still awaiting a body + if (CurrentFrame != default) + { + CurrentFrame.Update(bytes); + return !CurrentFrame.AwaitingBody; + } - // set the offset relevant to the data's length - if (dataLength < 126) + // otherwise, make sure we have enough bytes to parse the header + if (!PodeSignalFrame.ValidateHeader(bytes)) { - offset = 2; + return false; } - else if (dataLength == 126) + + // create initial frame + CurrentFrame = new PodeSignalFrame(bytes); + return !CurrentFrame.AwaitingBody; + } + + /// + /// Parses the raw WebSocket frame bytes. + /// This method extracts the frame's operation code, decodes the payload using the masking key, + /// and handles control frames (e.g., Close, Ping) accordingly. + /// + /// The raw bytes of the WebSocket frame. + /// Cancellation token to cancel the operation if needed. + /// True if parsing is successful. + protected override async Task Parse(byte[] bytes, CancellationToken cancellationToken) + { + // if there are no bytes, return (0 bytes read means we can close the socket) + if (bytes == default || bytes.Length == 0 || CurrentFrame == default) { - dataLength = BitConverter.ToInt16(new byte[] { bytes[3], bytes[2] }, 0); - offset = 4; + return true; } - else + + // set the body stream + if (BodyStream == default) { - dataLength = (int)BitConverter.ToInt64(new byte[] { bytes[9], bytes[8], bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2] }, 0); - offset = 10; + BodyStream = new MemoryStream(); } - // read in the mask - var mask = new byte[] { bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3] }; - offset += 4; + // set the OpCode from the current frame + if (CurrentFrame.OpCode != PodeWsOpCode.Continuation) + { + OpCode = CurrentFrame.OpCode; + } + + try + { + // Decode the message by applying the mask to each byte of the payload. + var decoded = CurrentFrame.Decode(bytes); - // build the decoded message - var decoded = new byte[dataLength]; - for (var i = 0; i < dataLength; ++i) + // handle continuation final frames, and build the body stream + await PodeHelpers.WriteTo(BodyStream, decoded, 0, decoded.Length, cancellationToken).ConfigureAwait(false); + if (!CurrentFrame.IsFinalFrame) + { + // returning false tells the receiver to wait for more frames + return false; + } + } + catch (Exception ex) + { + // Log the error and return false to indicate failure. + PodeHelpers.WriteErrorMessage($"Error decoding WebSocket frame: {ex.Message}", Context.Listener, PodeLoggingLevel.Error, Context); + throw; + } + finally { - decoded[i] = (byte)(bytes[offset + i] ^ mask[i % 4]); + CurrentFrame = default; + } + + // Store the raw frame and set the content length. + RawBody = BodyStream.ToArray(); + if (BodyStream != default) + { + BodyStream.Dispose(); + BodyStream = default; } - // set the raw/body - RawBody = bytes; ContentLength = RawBody.Length; - Body = Encoding.GetString(decoded); + Body = Encoding.GetString(RawBody); - // determine action based on code + // Process the frame based on its operation code. switch (OpCode) { - // get the close status and description + // For a Close frame, extract the close status and description. case PodeWsOpCode.Close: _closeStatus = WebSocketCloseStatus.Empty; _closeDescription = string.Empty; - if (dataLength >= 2) + if (ContentLength >= 2) { - Array.Reverse(decoded, 0, 2); - var code = (int)BitConverter.ToUInt16(decoded, 0); + // Reverse the first two bytes to correctly interpret the close code. + Array.Reverse(RawBody, 0, 2); + var code = (int)BitConverter.ToUInt16(RawBody, 0); + // Validate and assign the close status. _closeStatus = Enum.IsDefined(typeof(WebSocketCloseStatus), code) ? (WebSocketCloseStatus)code : WebSocketCloseStatus.Empty; - var descCount = dataLength - 2; + var descCount = ContentLength - 2; if (descCount > 0) { - _closeDescription = Encoding.GetString(decoded, 2, descCount); + // Extract the close description text, if available. + _closeDescription = Encoding.GetString(RawBody, 2, descCount); } } break; - // send back a pong + // For a Ping frame, send back a Pong frame. case PodeWsOpCode.Ping: await Context.Response.WriteFrame(string.Empty, PodeWsOpCode.Pong).ConfigureAwait(false); break; @@ -128,28 +241,28 @@ protected override async Task Parse(byte[] bytes, CancellationToken cancel } /// - /// Dispose managed and unmanaged resources. + /// Disposes of managed and unmanaged resources used by the PodeSignalRequest. + /// In addition to base cleanup, it sends a WebSocket Close frame and removes the client signal. /// - /// Indicates if the method is called explicitly or by garbage collection. + /// Indicates whether the method is called explicitly or by the garbage collector. protected override void Dispose(bool disposing) { if (IsDisposed) return; - + if (disposing) { - // Send close frame + // Log a message indicating the WebSocket is being closed. PodeHelpers.WriteErrorMessage($"Closing Websocket", Context.Listener, PodeLoggingLevel.Verbose, Context); - // Wait for the close frame to be sent + // Send a Close frame to the client and wait for the operation to complete. Context.Response.WriteFrame(string.Empty, PodeWsOpCode.Close).Wait(); - // Remove the client signal + // Remove the associated client signal from the listener's collection. Context.Listener.Signals.Remove(Signal.ClientId); } - // Call the base Dispose to clean up other resources + // Call the base class Dispose to clean up other resources. base.Dispose(disposing); } - } -} \ No newline at end of file +} diff --git a/src/Listener/PodeWsOpCode.cs b/src/Listener/PodeWsOpCode.cs index 13f441e6b..88c252b74 100644 --- a/src/Listener/PodeWsOpCode.cs +++ b/src/Listener/PodeWsOpCode.cs @@ -2,7 +2,7 @@ namespace Pode { public enum PodeWsOpCode { - Fragment = 0, + Continuation = 0, Text = 1, Binary = 2, Close = 8, diff --git a/src/Misc/default-doc-bookmarks.html.pode b/src/Misc/default-doc-bookmarks.html.pode index d9418eacc..1bfca813b 100644 --- a/src/Misc/default-doc-bookmarks.html.pode +++ b/src/Misc/default-doc-bookmarks.html.pode @@ -1,169 +1,238 @@ - + + OpenAPI Documentation Bookmarks - - - - - + + + + - -

$($data.Title)

-

Documentation

- - -
-

OpenAPI Definition

- - + + +
+

$($data.Title)

-
- - + + - -
-
Loading JSON content...
-
-