diff --git a/devolutions-gateway/openapi/doc/index.adoc b/devolutions-gateway/openapi/doc/index.adoc index 018a77c4a2..f3c9b3efbb 100644 --- a/devolutions-gateway/openapi/doc/index.adoc +++ b/devolutions-gateway/openapi/doc/index.adoc @@ -1,6 +1,6 @@ = devolutions-gateway infos@devolutions.net -2026.2.4 +2026.3.3 :toc: left :numbered: :toclevels: 4 @@ -120,6 +120,9 @@ Delete an accepted agent by ID. - +===== Content Type + +* application/problem+json ===== Responses @@ -136,22 +139,22 @@ Delete an accepted agent by ID. | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 404 | Agent not found -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -221,6 +224,7 @@ Requires a Bearer token: an `ENROLLMENT` JWT signed by the configured provisione ===== Content Type * application/json +* application/problem+json ===== Responses @@ -237,22 +241,22 @@ Requires a Bearer token: an `ENROLLMENT` JWT signed by the configured provisione | 400 | Invalid agent name, request body, or certificate signing request -| <<>> +| <> | 401 | Invalid or missing enrollment token -| <<>> +| <> | 409 | Agent ID or name already registered, agent key previously deleted, or enrollment token already used -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -322,6 +326,7 @@ Get a single agent by ID. ===== Content Type * application/json +* application/problem+json ===== Responses @@ -338,22 +343,22 @@ Get a single agent by ID. | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 404 | Agent not found -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -403,6 +408,7 @@ array[<>] ===== Content Type * application/json +* application/problem+json ===== Responses @@ -419,17 +425,17 @@ array[<>] | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -501,6 +507,9 @@ Modifies configuration - +===== Content Type + +* application/problem+json ===== Responses @@ -517,22 +526,22 @@ Modifies configuration | 400 | Bad patch request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Failed to patch configuration -| <<>> +| <> |=== @@ -640,6 +649,7 @@ This route primary function is to help with configuration diagnosis (e.g.: ID mi ===== Content Type * application/json +* application/problem+json ===== Responses @@ -656,17 +666,17 @@ This route primary function is to help with configuration diagnosis (e.g.: ID mi | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> |=== @@ -865,6 +875,7 @@ Performs a heartbeat check ===== Content Type * application/json +* application/problem+json ===== Responses @@ -881,17 +892,17 @@ Performs a heartbeat check | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> |=== @@ -965,6 +976,7 @@ If you try to delete more than 50,000 recordings at once, you should split the l ===== Content Type * application/json +* application/problem+json ===== Responses @@ -981,27 +993,27 @@ If you try to delete more than 50,000 recordings at once, you should split the l | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 409 | A recording is still ongoing and can't be deleted yet (nothing is deleted) -| <<>> +| <> | 413 | Request payload is too large -| <<>> +| <> |=== @@ -1069,6 +1081,9 @@ Deletes a recording stored on this instance - +===== Content Type + +* application/problem+json ===== Responses @@ -1085,27 +1100,27 @@ Deletes a recording stored on this instance | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 404 | The specified recording was not found -| <<>> +| <> | 409 | The recording is still ongoing and can't be deleted yet -| <<>> +| <> |=== @@ -1176,6 +1191,7 @@ Lists all recordings stored on this instance ===== Content Type * application/json +* application/problem+json ===== Responses @@ -1192,17 +1208,17 @@ Lists all recordings stored on this instance | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> |=== @@ -1278,7 +1294,12 @@ Retrieves a recording file for a given session ===== Content Type +* video/webm +* application/x-asciicast +* application/x-ndjson +* application/json * application/octet-stream +* application/problem+json ===== Responses @@ -1295,22 +1316,22 @@ Retrieves a recording file for a given session | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 404 | File not found -| <<>> +| <> |=== @@ -1431,11 +1452,11 @@ endif::internal-generation[] `POST /jet/jrec/search` -Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance +Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs ===== Description -The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. +The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. // markup not found, no include::{specDir}jet/jrec/search/POST/spec.adoc[opts=optional] @@ -1482,6 +1503,7 @@ The query is a case-insensitive substring, and an empty query matches every line ===== Content Type * application/json +* application/problem+json ===== Responses @@ -1498,17 +1520,17 @@ The query is a case-insensitive substring, and an empty query matches every line | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> |=== @@ -1562,6 +1584,7 @@ Retrieves current JRL (Json Revocation List) info ===== Content Type * application/json +* application/problem+json ===== Responses @@ -1578,22 +1601,22 @@ Retrieves current JRL (Json Revocation List) info | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Failed to update the JRL -| <<>> +| <> |=== @@ -1641,6 +1664,9 @@ Updates JRL (Json Revocation List) using a JRL token - +===== Content Type + +* application/problem+json ===== Responses @@ -1657,22 +1683,22 @@ Updates JRL (Json Revocation List) using a JRL token | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Failed to update the JRL -| <<>> +| <> |=== @@ -1727,6 +1753,7 @@ Lists network interfaces ===== Content Type * application/json +* application/problem+json ===== Responses @@ -1743,22 +1770,22 @@ Lists network interfaces | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -1808,6 +1835,7 @@ Lists Gateway network scan sources. ===== Content Type * application/json +* application/problem+json ===== Responses @@ -1824,22 +1852,22 @@ Lists Gateway network scan sources. | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -2093,6 +2121,9 @@ The endpoint is upgraded from HTTP, so OpenAPI describes the **handshake**: the - +===== Content Type + +* application/problem+json ===== Responses @@ -2114,17 +2145,17 @@ The endpoint is upgraded from HTTP, so OpenAPI describes the **handshake**: the | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -2178,6 +2209,7 @@ Once the log is downloaded, gateway purges it from memory. ===== Content Type * application/json +* application/problem+json ===== Responses @@ -2194,22 +2226,22 @@ Once the log is downloaded, gateway purges it from memory. | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -2279,6 +2311,7 @@ Changes take effect immediately: - Starts any monitors newly defined in the payl ===== Content Type * application/json +* application/problem+json ===== Responses @@ -2295,22 +2328,22 @@ Changes take effect immediately: - Starts any monitors newly defined in the payl | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Unexpected server error while starting monitors -| <<>> +| <> |=== @@ -2384,6 +2417,7 @@ array[<>] ===== Content Type * application/json +* application/problem+json ===== Responses @@ -2400,17 +2434,17 @@ array[<>] | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> |=== @@ -2464,6 +2498,7 @@ array[<>] ===== Content Type * application/json +* application/problem+json ===== Responses @@ -2480,22 +2515,22 @@ array[<>] | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -2563,6 +2598,9 @@ Terminate forcefully a running session - +===== Content Type + +* application/problem+json ===== Responses @@ -2579,27 +2617,27 @@ Terminate forcefully a running session | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 404 | No running session found with provided ID -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -2673,6 +2711,7 @@ Returns the Task of the analysis: its state, its progress while it runs, its res ===== Content Type * application/json +* application/problem+json ===== Responses @@ -2689,27 +2728,27 @@ Returns the Task of the analysis: its state, its progress while it runs, its res | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 404 | No AI analysis has this Task ID -| <<>> +| <> | 500 | Unexpected server error -| <<>> +| <> |=== @@ -2792,6 +2831,7 @@ Gateway asks the AI provider what the user did in the session recording, and put ===== Content Type * application/json +* application/problem+json ===== Responses @@ -2813,22 +2853,22 @@ Gateway asks the AI provider what the user did in the session recording, and put | 400 | Invalid request body, AI settings or language -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 404 | The session has no recording -| <<>> +| <> | 409 @@ -2838,7 +2878,7 @@ Gateway asks the AI provider what the user did in the session recording, and put | 500 | Unexpected server error -| <<>> +| <> |=== @@ -2912,6 +2952,7 @@ Acknowledge traffic audit events and remove them from the queue ===== Content Type * application/json +* application/problem+json ===== Responses @@ -2928,27 +2969,27 @@ Acknowledge traffic audit events and remove them from the queue | 400 | Invalid request body (empty ids array) -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 413 | Payload too large (more than 10,000 IDs) -| <<>> +| <> | 500 | Internal server error -| <<>> +| <> |=== @@ -3024,6 +3065,7 @@ array[<>] ===== Content Type * application/json +* application/problem+json ===== Responses @@ -3040,22 +3082,22 @@ array[<>] | 400 | Invalid query parameters -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Internal server error -| <<>> +| <> |=== @@ -3109,6 +3151,7 @@ Reads `update_status.json`, which is written by the Devolutions Agent on startup ===== Content Type * application/json +* application/problem+json ===== Responses @@ -3125,22 +3168,22 @@ Reads `update_status.json`, which is written by the Devolutions Agent on startup | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Failed to read agent status file -| <<>> +| <> | 503 | Agent updater service is unavailable -| <<>> +| <> |=== @@ -3190,6 +3233,7 @@ Reads the `Schedule` field from `update_status.json`. When the field is absent ===== Content Type * application/json +* application/problem+json ===== Responses @@ -3206,22 +3250,22 @@ Reads the `Schedule` field from `update_status.json`. When the field is absent | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Failed to read agent status file -| <<>> +| <> | 503 | Agent updater service is unavailable -| <<>> +| <> |=== @@ -3292,6 +3336,7 @@ Writes the `Schedule` field into `update.json`. The agent watches this file and ===== Content Type * application/json +* application/problem+json ===== Responses @@ -3308,27 +3353,27 @@ Writes the `Schedule` field into `update.json`. The agent watches this file and | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Failed to write update manifest -| <<>> +| <> | 503 | Agent updater service is unavailable -| <<>> +| <> |=== @@ -3412,6 +3457,7 @@ Writes the requested version(s) into `Agent/update.json`, which is watched by De ===== Content Type * application/json +* application/problem+json ===== Responses @@ -3428,27 +3474,27 @@ Writes the requested version(s) into `Agent/update.json`, which is watched by De | 400 | Bad request -| <<>> +| <> | 401 | Invalid or missing authorization token -| <<>> +| <> | 403 | Insufficient permissions -| <<>> +| <> | 500 | Failed to write update manifest -| <<>> +| <> | 503 | Agent updater service is unavailable -| <<>> +| <> |=== @@ -4510,6 +4556,51 @@ AI provider to ask; `openai-compatible` needs a base URL |=== +[#ApiError] +=== _ApiError_ + +Body of an API error response, as defined by RFC 9457 (problem details for HTTP APIs). + +The Gateway logs the details of the error, along with its code. + + +[.fields-ApiError] +[cols="2,1,1,2,4,1"] +|=== +| Field Name| Required| Nullable | Type| Description | Format + +| error +| X +| +| String +| Machine-readable error code; the `ErrorCode` schema lists the known values. New codes can be added: treat unknown values as generic failures. +| + +| status +| X +| +| Integer +| HTTP status code. +| int32 + +| title +| X +| +| String +| Reason phrase of the HTTP status. +| + +| type +| X +| +| String +| Problem type, always `about:blank`: the HTTP status and the error code describe the problem. +| + +|=== + + + [#AppCredential] === _AppCredential_ @@ -4981,6 +5072,74 @@ Service configuration diagnostic +[#ErrorCode] +=== _ErrorCode_ + +Machine-readable reason for a rejected request. + +New codes can be added, but existing codes are never renamed or removed. Clients must treat unknown codes as generic failures. + +- `bad_request`: The request is invalid. +- `unauthorized`: The request is not authenticated. +- `forbidden`: The request is not allowed. +- `not_found`: The resource doesn't exist. +- `request_timeout`: The request took too long to complete. +- `conflict`: The request conflicts with the current state of the resource. +- `payload_too_large`: The request is too large. +- `internal_error`: The Gateway failed to process the request. +- `bad_gateway`: The Gateway received an invalid response from an upstream server. +- `service_unavailable`: The service is temporarily unavailable. +- `gateway_timeout`: An upstream server didn't respond in time. +- `insufficient_storage`: The Gateway is out of storage space. +- `missing_token`: No token was found in the `Authorization` header or in the `token` query parameter. +- `malformed_token`: The token can't be decoded or decrypted, or its claims don't match the schema expected for its type. +- `bad_signature`: The token signature doesn't match the provisioner key of the Gateway. +- `unknown_subkey`: The token refers to a key ID (`kid`) that doesn't match the sub provisioner key of the Gateway. +- `expired`: The token has expired (`exp` claim); the clocks of the token issuer and of the Gateway may be out of sync. +- `not_yet_valid`: The token is not valid yet (`nbf` claim); the clocks of the token issuer and of the Gateway may be out of sync. +- `gateway_id_mismatch`: The token is restricted to another Gateway ID (`jet_gw_id` claim). +- `revoked`: The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. +- `unexpected_replay`: The token was already used, and can't be used again in this context. +- `invalid_token`: The token is rejected for a reason not covered by another code. +- `wrong_token_type`: The type of the token is not accepted by this route. +- `insufficient_scope`: The scope of the token doesn't grant access to this route. + + + + +[.fields-ErrorCode] +[cols="1"] +|=== +| Enum Values + +| bad_request +| unauthorized +| forbidden +| not_found +| request_timeout +| conflict +| payload_too_large +| internal_error +| bad_gateway +| service_unavailable +| gateway_timeout +| insufficient_storage +| missing_token +| malformed_token +| bad_signature +| unknown_subkey +| expired +| not_yet_valid +| gateway_id_mismatch +| revoked +| unexpected_replay +| invalid_token +| wrong_token_type +| insufficient_scope + +|=== + + [#EventOutcomeResponse] === _EventOutcomeResponse_ @@ -6184,7 +6343,7 @@ A line that matches the search text. | X | | String -| Name of the `.slog` artifact holding the line, as listed in `recording.json`. +| Name of the `.slog` file holding the line, as listed in `recording.json`. | | line @@ -6212,7 +6371,7 @@ A line that matches the search text. | X | | UUID -| The recording whose artifact holds the line. +| The recording whose log holds the line. | uuid | truncated diff --git a/devolutions-gateway/openapi/dotnet-client/.openapi-generator/FILES b/devolutions-gateway/openapi/dotnet-client/.openapi-generator/FILES index 33424ccca0..a4469117ec 100644 --- a/devolutions-gateway/openapi/dotnet-client/.openapi-generator/FILES +++ b/devolutions-gateway/openapi/dotnet-client/.openapi-generator/FILES @@ -25,6 +25,7 @@ docs/AiAnalysisSucceededPayload.md docs/AiAnalysisTask.md docs/AiAnalysisUsage.md docs/AiProvider.md +docs/ApiError.md docs/AppCredential.md docs/AppCredentialKind.md docs/AppTokenContentType.md @@ -40,6 +41,7 @@ docs/DeleteManyResult.md docs/DiagnosticsApi.md docs/EnrollRequest.md docs/EnrollResponse.md +docs/ErrorCode.md docs/EventOutcomeResponse.md docs/GetUpdateProductsResponse.md docs/GetUpdateScheduleResponse.md @@ -157,6 +159,7 @@ src/Devolutions.Gateway.Client/Model/AiAnalysisSucceededPayload.cs src/Devolutions.Gateway.Client/Model/AiAnalysisTask.cs src/Devolutions.Gateway.Client/Model/AiAnalysisUsage.cs src/Devolutions.Gateway.Client/Model/AiProvider.cs +src/Devolutions.Gateway.Client/Model/ApiError.cs src/Devolutions.Gateway.Client/Model/AppCredential.cs src/Devolutions.Gateway.Client/Model/AppCredentialKind.cs src/Devolutions.Gateway.Client/Model/AppTokenContentType.cs @@ -170,6 +173,7 @@ src/Devolutions.Gateway.Client/Model/DataEncoding.cs src/Devolutions.Gateway.Client/Model/DeleteManyResult.cs src/Devolutions.Gateway.Client/Model/EnrollRequest.cs src/Devolutions.Gateway.Client/Model/EnrollResponse.cs +src/Devolutions.Gateway.Client/Model/ErrorCode.cs src/Devolutions.Gateway.Client/Model/EventOutcomeResponse.cs src/Devolutions.Gateway.Client/Model/GetUpdateProductsResponse.cs src/Devolutions.Gateway.Client/Model/GetUpdateScheduleResponse.cs diff --git a/devolutions-gateway/openapi/dotnet-client/README.md b/devolutions-gateway/openapi/dotnet-client/README.md index 27f83eb54a..8499ecd7e8 100644 --- a/devolutions-gateway/openapi/dotnet-client/README.md +++ b/devolutions-gateway/openapi/dotnet-client/README.md @@ -4,7 +4,7 @@ Protocol-aware fine-grained relay server This C# SDK is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: -- API version: 2026.2.4 +- API version: 2026.3.3 - SDK version: 2026.9.2 - Generator version: 7.9.0 - Build package: org.openapitools.codegen.languages.CSharpClientCodegen @@ -156,7 +156,7 @@ Class | Method | HTTP request | Description *JrecApi* | [**ListRecordings**](docs/JrecApi.md#listrecordings) | **GET** /jet/jrec/list | Lists all recordings stored on this instance *JrecApi* | [**PullRecordingFile**](docs/JrecApi.md#pullrecordingfile) | **GET** /jet/jrec/pull/{id}/{filename} | Retrieves a recording file for a given session *JrecApi* | [**PullRecordingSession**](docs/JrecApi.md#pullrecordingsession) | **GET** /jet/jrec/pull/{id} | Downloads an entire recorded session as a ZIP archive -*JrecApi* | [**SearchRecordings**](docs/JrecApi.md#searchrecordings) | **POST** /jet/jrec/search | Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance +*JrecApi* | [**SearchRecordings**](docs/JrecApi.md#searchrecordings) | **POST** /jet/jrec/search | Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs *JrlApi* | [**GetJrlInfo**](docs/JrlApi.md#getjrlinfo) | **GET** /jet/jrl/info | Retrieves current JRL (Json Revocation List) info *JrlApi* | [**UpdateJrl**](docs/JrlApi.md#updatejrl) | **POST** /jet/jrl | Updates JRL (Json Revocation List) using a JRL token *NetApi* | [**GetNetConfig**](docs/NetApi.md#getnetconfig) | **GET** /jet/net/config | Lists network interfaces @@ -205,6 +205,7 @@ Class | Method | HTTP request | Description - [Model.AiAnalysisTask](docs/AiAnalysisTask.md) - [Model.AiAnalysisUsage](docs/AiAnalysisUsage.md) - [Model.AiProvider](docs/AiProvider.md) + - [Model.ApiError](docs/ApiError.md) - [Model.AppCredential](docs/AppCredential.md) - [Model.AppCredentialKind](docs/AppCredentialKind.md) - [Model.AppTokenContentType](docs/AppTokenContentType.md) @@ -218,6 +219,7 @@ Class | Method | HTTP request | Description - [Model.DeleteManyResult](docs/DeleteManyResult.md) - [Model.EnrollRequest](docs/EnrollRequest.md) - [Model.EnrollResponse](docs/EnrollResponse.md) + - [Model.ErrorCode](docs/ErrorCode.md) - [Model.EventOutcomeResponse](docs/EventOutcomeResponse.md) - [Model.GetUpdateProductsResponse](docs/GetUpdateProductsResponse.md) - [Model.GetUpdateScheduleResponse](docs/GetUpdateScheduleResponse.md) diff --git a/devolutions-gateway/openapi/dotnet-client/docs/AgentApi.md b/devolutions-gateway/openapi/dotnet-client/docs/AgentApi.md index 5e75e46720..e7ec869033 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/AgentApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/AgentApi.md @@ -91,7 +91,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/problem+json ### HTTP response details @@ -193,7 +193,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -293,7 +293,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -388,7 +388,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/ApiError.md b/devolutions-gateway/openapi/dotnet-client/docs/ApiError.md new file mode 100644 index 0000000000..25055993cb --- /dev/null +++ b/devolutions-gateway/openapi/dotnet-client/docs/ApiError.md @@ -0,0 +1,14 @@ +# Devolutions.Gateway.Client.Model.ApiError +Body of an API error response, as defined by RFC 9457 (problem details for HTTP APIs). The Gateway logs the details of the error, along with its code. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Error** | **string** | Machine-readable error code; the `ErrorCode` schema lists the known values. New codes can be added: treat unknown values as generic failures. | +**Status** | **int** | HTTP status code. | +**Title** | **string** | Reason phrase of the HTTP status. | +**Type** | **string** | Problem type, always `about:blank`: the HTTP status and the error code describe the problem. | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/devolutions-gateway/openapi/dotnet-client/docs/ConfigApi.md b/devolutions-gateway/openapi/dotnet-client/docs/ConfigApi.md index 0a7817f46e..1bdb619124 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/ConfigApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/ConfigApi.md @@ -88,7 +88,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: Not defined + - **Accept**: application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/DiagnosticsApi.md b/devolutions-gateway/openapi/dotnet-client/docs/DiagnosticsApi.md index 51c637037e..22cb4f8118 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/DiagnosticsApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/DiagnosticsApi.md @@ -181,7 +181,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/ErrorCode.md b/devolutions-gateway/openapi/dotnet-client/docs/ErrorCode.md new file mode 100644 index 0000000000..b8834e669e --- /dev/null +++ b/devolutions-gateway/openapi/dotnet-client/docs/ErrorCode.md @@ -0,0 +1,10 @@ +# Devolutions.Gateway.Client.Model.ErrorCode +Machine-readable reason for a rejected request. New codes can be added, but existing codes are never renamed or removed. Clients must treat unknown codes as generic failures. - `bad_request`: The request is invalid. - `unauthorized`: The request is not authenticated. - `forbidden`: The request is not allowed. - `not_found`: The resource doesn't exist. - `request_timeout`: The request took too long to complete. - `conflict`: The request conflicts with the current state of the resource. - `payload_too_large`: The request is too large. - `internal_error`: The Gateway failed to process the request. - `bad_gateway`: The Gateway received an invalid response from an upstream server. - `service_unavailable`: The service is temporarily unavailable. - `gateway_timeout`: An upstream server didn't respond in time. - `insufficient_storage`: The Gateway is out of storage space. - `missing_token`: No token was found in the `Authorization` header or in the `token` query parameter. - `malformed_token`: The token can't be decoded or decrypted, or its claims don't match the schema expected for its type. - `bad_signature`: The token signature doesn't match the provisioner key of the Gateway. - `unknown_subkey`: The token refers to a key ID (`kid`) that doesn't match the sub provisioner key of the Gateway. - `expired`: The token has expired (`exp` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `not_yet_valid`: The token is not valid yet (`nbf` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `gateway_id_mismatch`: The token is restricted to another Gateway ID (`jet_gw_id` claim). - `revoked`: The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. - `unexpected_replay`: The token was already used, and can't be used again in this context. - `invalid_token`: The token is rejected for a reason not covered by another code. - `wrong_token_type`: The type of the token is not accepted by this route. - `insufficient_scope`: The scope of the token doesn't grant access to this route. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/devolutions-gateway/openapi/dotnet-client/docs/HeartbeatApi.md b/devolutions-gateway/openapi/dotnet-client/docs/HeartbeatApi.md index 8440f0371b..de89d08792 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/HeartbeatApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/HeartbeatApi.md @@ -87,7 +87,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/JrecApi.md b/devolutions-gateway/openapi/dotnet-client/docs/JrecApi.md index a376db1eb0..e8efd86ec9 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/JrecApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/JrecApi.md @@ -9,7 +9,7 @@ All URIs are relative to *http://localhost* | [**ListRecordings**](JrecApi.md#listrecordings) | **GET** /jet/jrec/list | Lists all recordings stored on this instance | | [**PullRecordingFile**](JrecApi.md#pullrecordingfile) | **GET** /jet/jrec/pull/{id}/{filename} | Retrieves a recording file for a given session | | [**PullRecordingSession**](JrecApi.md#pullrecordingsession) | **GET** /jet/jrec/pull/{id} | Downloads an entire recorded session as a ZIP archive | -| [**SearchRecordings**](JrecApi.md#searchrecordings) | **POST** /jet/jrec/search | Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance | +| [**SearchRecordings**](JrecApi.md#searchrecordings) | **POST** /jet/jrec/search | Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs | # **DeleteManyRecordings** @@ -99,7 +99,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -196,7 +196,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/problem+json ### HTTP response details @@ -297,7 +297,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -398,7 +398,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/octet-stream + - **Accept**: video/webm, application/x-asciicast, application/x-ndjson, application/json, application/octet-stream, application/problem+json ### HTTP response details @@ -518,9 +518,9 @@ catch (ApiException e) # **SearchRecordings** > RecordingSearchResponse SearchRecordings (RecordingSearchRequest recordingSearchRequest) -Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance +Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs -The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. +The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. ### Example ```csharp @@ -550,7 +550,7 @@ namespace Example try { - // Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance + // Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs RecordingSearchResponse result = apiInstance.SearchRecordings(recordingSearchRequest); Debug.WriteLine(result); } @@ -571,7 +571,7 @@ This returns an ApiResponse object which contains the response data, status code ```csharp try { - // Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance + // Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs ApiResponse response = apiInstance.SearchRecordingsWithHttpInfo(recordingSearchRequest); Debug.Write("Status Code: " + response.StatusCode); Debug.Write("Response Headers: " + response.Headers); @@ -602,7 +602,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/JrlApi.md b/devolutions-gateway/openapi/dotnet-client/docs/JrlApi.md index 3c3b1cac74..0aeea6d45a 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/JrlApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/JrlApi.md @@ -88,7 +88,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -179,7 +179,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/NetApi.md b/devolutions-gateway/openapi/dotnet-client/docs/NetApi.md index b3e5663e98..2d75b12869 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/NetApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/NetApi.md @@ -89,7 +89,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -184,7 +184,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -344,7 +344,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/NetworkMonitoringApi.md b/devolutions-gateway/openapi/dotnet-client/docs/NetworkMonitoringApi.md index 7f74cd0eb0..5afc845fe8 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/NetworkMonitoringApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/NetworkMonitoringApi.md @@ -90,7 +90,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -192,7 +192,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/PreflightApi.md b/devolutions-gateway/openapi/dotnet-client/docs/PreflightApi.md index cb51dd42ed..cb321fd47f 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/PreflightApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/PreflightApi.md @@ -92,7 +92,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/RecordingSearchHit.md b/devolutions-gateway/openapi/dotnet-client/docs/RecordingSearchHit.md index bfab56ff4a..47bc9c7ce4 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/RecordingSearchHit.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/RecordingSearchHit.md @@ -5,11 +5,11 @@ A line that matches the search text. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**FileName** | **string** | Name of the `.slog` artifact holding the line, as listed in `recording.json`. | +**FileName** | **string** | Name of the `.slog` file holding the line, as listed in `recording.json`. | **Line** | **string** | The line's text without its line break; bytes that are not UTF-8 read as U+FFFD. | **LineNumber** | **long** | Number of the line in the file, counting from 1. | **Offset** | **long** | Byte offset of the line in the file. | -**RecordingId** | **Guid** | The recording whose artifact holds the line. | +**RecordingId** | **Guid** | The recording whose log holds the line. | **Truncated** | **bool** | The line is longer than 256 KiB, so `line` holds only its start, and the file holds the rest. | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/devolutions-gateway/openapi/dotnet-client/docs/SessionsApi.md b/devolutions-gateway/openapi/dotnet-client/docs/SessionsApi.md index 4bb9e5ca97..86d3fc3b91 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/SessionsApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/SessionsApi.md @@ -88,7 +88,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -184,7 +184,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/TasksApi.md b/devolutions-gateway/openapi/dotnet-client/docs/TasksApi.md index bedda0b0a9..42ed5c6248 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/TasksApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/TasksApi.md @@ -95,7 +95,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -200,7 +200,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/TrafficApi.md b/devolutions-gateway/openapi/dotnet-client/docs/TrafficApi.md index d5fb93fab0..8a8f6b2405 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/TrafficApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/TrafficApi.md @@ -93,7 +93,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -196,7 +196,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/docs/UpdateApi.md b/devolutions-gateway/openapi/dotnet-client/docs/UpdateApi.md index ffd85c00a5..e66a01e49f 100644 --- a/devolutions-gateway/openapi/dotnet-client/docs/UpdateApi.md +++ b/devolutions-gateway/openapi/dotnet-client/docs/UpdateApi.md @@ -92,7 +92,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -189,7 +189,7 @@ This endpoint does not need any parameter. ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -291,7 +291,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details @@ -396,7 +396,7 @@ catch (ApiException e) ### HTTP request headers - **Content-Type**: application/json - - **Accept**: application/json + - **Accept**: application/json, application/problem+json ### HTTP response details diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/AgentApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/AgentApi.cs index 928dd66bcf..2d94cba363 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/AgentApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/AgentApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -439,6 +439,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse DeleteAgentWithHttp // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -497,6 +498,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse DeleteAgentWithHttp // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; @@ -560,7 +562,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse EnrollAgent // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -625,7 +628,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse EnrollAgent // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -684,7 +688,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetAgentWithHttp // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -744,7 +749,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetAgentWithHttp // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -801,7 +807,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> ListAgents // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -858,7 +865,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> ListAgents // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/ConfigApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/ConfigApi.cs index 49012f143a..62947775c7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/ConfigApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/ConfigApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -322,6 +322,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse PatchConfigWithHttp // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -385,6 +386,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse PatchConfigWithHttp // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/DiagnosticsApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/DiagnosticsApi.cs index 9d95407159..24da245ef3 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/DiagnosticsApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/DiagnosticsApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -493,7 +493,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetConfig // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -550,7 +551,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetConfig // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HealthApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HealthApi.cs index 328a0ba4a4..9e07b686b9 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HealthApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HealthApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HeartbeatApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HeartbeatApi.cs index 5a5a673021..b5f568d29b 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HeartbeatApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/HeartbeatApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -312,7 +312,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetHeartbeatWith // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -369,7 +370,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetHeartbeatWith // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrecApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrecApi.cs index 59869f69ad..6b10d185cc 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrecApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrecApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -127,10 +127,10 @@ public interface IJrecApiSync : IApiAccessor /// ApiResponse of FileParameter ApiResponse PullRecordingSessionWithHttpInfo(Guid id); /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs /// /// - /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -138,10 +138,10 @@ public interface IJrecApiSync : IApiAccessor RecordingSearchResponse SearchRecordings(RecordingSearchRequest recordingSearchRequest); /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs /// /// - /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -274,10 +274,10 @@ public interface IJrecApiAsync : IApiAccessor /// Task of ApiResponse (FileParameter) System.Threading.Tasks.Task> PullRecordingSessionWithHttpInfoAsync(Guid id, System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)); /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs /// /// - /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -286,10 +286,10 @@ public interface IJrecApiAsync : IApiAccessor System.Threading.Tasks.Task SearchRecordingsAsync(RecordingSearchRequest recordingSearchRequest, System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)); /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs /// /// - /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -541,7 +541,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse DeleteMan // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -606,7 +607,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse DeleteMan // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -664,6 +666,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse DeleteRecordingWith // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -722,6 +725,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse DeleteRecordingWith // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; @@ -780,7 +784,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> ListRecordingsW // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -840,7 +845,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> ListRecordingsW // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -905,7 +911,12 @@ public Devolutions.Gateway.Client.Client.ApiResponse PullRecordin // to determine the Accept header string[] _accepts = new string[] { - "application/octet-stream" + "video/webm", + "application/x-asciicast", + "application/x-ndjson", + "application/json", + "application/octet-stream", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -972,7 +983,12 @@ public Devolutions.Gateway.Client.Client.ApiResponse PullRecordin // to determine the Accept header string[] _accepts = new string[] { - "application/octet-stream" + "video/webm", + "application/x-asciicast", + "application/x-ndjson", + "application/json", + "application/octet-stream", + "application/problem+json" }; @@ -1125,7 +1141,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse PullRecordin } /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -1137,7 +1153,7 @@ public RecordingSearchResponse SearchRecordings(RecordingSearchRequest recording } /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -1156,7 +1172,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse Se // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -1187,7 +1204,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse Se } /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -1200,7 +1217,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse Se } /// - /// Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. + /// Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read once unescaped, so field names, numbers, booleans and null never match. Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. To get the next page, send the same `query`, `recordings` and `startTime` again, with the `nextCursor` of the previous page as `cursor`. Pages never go back, so a recording that starts, or a log that grows, behind the cursor while paging is not searched. /// /// Thrown when fails to make API call /// JSON-encoded search request @@ -1221,7 +1238,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse Se // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrlApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrlApi.cs index 79c8443e53..9a1901d8ee 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrlApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/JrlApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -349,7 +349,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetJrlInfoWithHttp // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -406,7 +407,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetJrlInfoWithHttp // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -461,6 +463,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse UpdateJrlWithHttpIn // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -516,6 +519,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse UpdateJrlWithHttpIn // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetApi.cs index 265d086e9f..21167b8de2 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -517,7 +517,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -687,7 +690,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -806,6 +810,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -1053,6 +1058,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetworkMonitoringApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetworkMonitoringApi.cs index cb7415dc35..a1497c963d 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetworkMonitoringApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/NetworkMonitoringApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -359,7 +359,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse Drai // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -416,7 +417,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse Drai // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -479,7 +481,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse SetMonit // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -544,7 +547,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse SetMonit // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/PreflightApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/PreflightApi.cs index 03f20799bb..5416a7b318 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/PreflightApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/PreflightApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -323,7 +323,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> Post // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -388,7 +389,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> Post // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/SessionsApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/SessionsApi.cs index f08d09dc17..b3dfad4959 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/SessionsApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/SessionsApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -353,7 +353,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> GetSessi // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -410,7 +411,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> GetSessi // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -467,6 +469,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse TerminateSessionWit // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -525,6 +528,7 @@ public Devolutions.Gateway.Client.Client.ApiResponse TerminateSessionWit // to determine the Accept header string[] _accepts = new string[] { + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TasksApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TasksApi.cs index af46850ae2..6f14160936 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TasksApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TasksApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -369,7 +369,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetAiAnalys // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -429,7 +430,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse GetAiAnalys // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -495,7 +497,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse StartAiAnal // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -563,7 +566,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse StartAiAnal // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TrafficApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TrafficApi.cs index 127ae622a0..1ec576fa5a 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TrafficApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/TrafficApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -368,7 +368,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse AckTrafficEven // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -433,7 +434,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse AckTrafficEven // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -494,7 +496,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -557,7 +560,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse> // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/UpdateApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/UpdateApi.cs index 0eb72c1870..cb08b9abfe 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/UpdateApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/UpdateApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -447,7 +447,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -504,7 +505,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -560,7 +562,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -617,7 +620,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -680,7 +684,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse SetUpdateScheduleWi // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -745,7 +750,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse SetUpdateScheduleWi // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; @@ -807,7 +813,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse SetUpdateScheduleWi // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; var localVarContentType = Devolutions.Gateway.Client.Client.ClientUtils.SelectHeaderContentType(_contentTypes); @@ -874,7 +881,8 @@ public Devolutions.Gateway.Client.Client.ApiResponse SetUpdateScheduleWi // to determine the Accept header string[] _accepts = new string[] { - "application/json" + "application/json", + "application/problem+json" }; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/WebAppApi.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/WebAppApi.cs index ae2be8539d..8b07b75bee 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/WebAppApi.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Api/WebAppApi.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiClient.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiClient.cs index 4d77365cc7..72613be75b 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiClient.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiClient.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiException.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiException.cs index 19461fa464..bf136cb0f4 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiException.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiException.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiResponse.cs index 955894c8f0..e395b0e39e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ApiResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ClientUtils.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ClientUtils.cs index 89ef69ff9d..61afbba9db 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ClientUtils.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ClientUtils.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Configuration.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Configuration.cs index ac253bf0b5..10d936c3ac 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Configuration.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Configuration.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -540,7 +540,7 @@ public static string ToDebugReport() string report = "C# SDK (Devolutions.Gateway.Client) Debug Report:\n"; report += " OS: " + System.Environment.OSVersion + "\n"; report += " .NET Framework Version: " + System.Environment.Version + "\n"; - report += " Version of the API: 2026.2.4\n"; + report += " Version of the API: 2026.3.3\n"; report += " SDK Package Version: 2026.9.2\n"; return report; diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ExceptionFactory.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ExceptionFactory.cs index 1e2698d5ad..86e31c7dd7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ExceptionFactory.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ExceptionFactory.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/FileParameter.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/FileParameter.cs index f557e590dd..41ae899a28 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/FileParameter.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/FileParameter.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/GlobalConfiguration.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/GlobalConfiguration.cs index 06ba08891f..725fe779d8 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/GlobalConfiguration.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/GlobalConfiguration.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IApiAccessor.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IApiAccessor.cs index de69db1b16..f3145a101c 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IApiAccessor.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IApiAccessor.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IAsynchronousClient.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IAsynchronousClient.cs index 81c81f40c1..a2b4363020 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IAsynchronousClient.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IAsynchronousClient.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IReadableConfiguration.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IReadableConfiguration.cs index 5ad5279b4b..a0aa3d8456 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IReadableConfiguration.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/IReadableConfiguration.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ISynchronousClient.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ISynchronousClient.cs index 24fa46df0a..b72c1e846c 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ISynchronousClient.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/ISynchronousClient.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Multimap.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Multimap.cs index 6c6c6dd47b..ce98f64c17 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Multimap.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/Multimap.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/OpenAPIDateConverter.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/OpenAPIDateConverter.cs index a2c6d86ca3..656abdb128 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/OpenAPIDateConverter.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/OpenAPIDateConverter.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RequestOptions.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RequestOptions.cs index 3d250a880c..12200c3fc6 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RequestOptions.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RequestOptions.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RetryConfiguration.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RetryConfiguration.cs index 5a7dad3153..52b5459609 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RetryConfiguration.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/RetryConfiguration.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/WebRequestPathBuilder.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/WebRequestPathBuilder.cs index 0246ad865a..61b668c9f0 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/WebRequestPathBuilder.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Client/WebRequestPathBuilder.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AbstractOpenAPISchema.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AbstractOpenAPISchema.cs index f704f6a04a..1c0cfa1181 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AbstractOpenAPISchema.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AbstractOpenAPISchema.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AccessScope.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AccessScope.cs index 1f751b189c..4aad5608d9 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AccessScope.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AccessScope.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckRequest.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckRequest.cs index 453b72feab..a0e4143477 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckRequest.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckRequest.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckResponse.cs index 217abd0693..65863ec6b5 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AckResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AddressFamily.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AddressFamily.cs index d288af632f..33877307c4 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AddressFamily.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AddressFamily.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentDomainAdvertisement.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentDomainAdvertisement.cs index fe66c8372c..0e0ff990d1 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentDomainAdvertisement.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentDomainAdvertisement.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentInfo.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentInfo.cs index a4e1c16ff4..c1efc603df 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentInfo.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentInfo.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentStatus.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentStatus.cs index dcbe4e2a2b..c366071e2e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentStatus.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AgentStatus.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisBadAnswer.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisBadAnswer.cs index 3eb5329b7e..5c1f1f35a9 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisBadAnswer.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisBadAnswer.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflict.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflict.cs index 7fc19bc470..49287d9499 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflict.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflict.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflictCode.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflictCode.cs index 52284a5d8b..4e8ae038e4 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflictCode.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisConflictCode.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisError.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisError.cs index 14f4a633b5..e637937bf4 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisError.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisError.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisErrorKind.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisErrorKind.cs index c1c9c144af..6430dbd332 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisErrorKind.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisErrorKind.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisFailedPayload.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisFailedPayload.cs index 2ff1c9c54a..101c549b9b 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisFailedPayload.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisFailedPayload.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisParams.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisParams.cs index 98c231bf57..46ef2a63e8 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisParams.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisParams.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisPayload.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisPayload.cs index 757200da16..5a596b3a6b 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisPayload.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisPayload.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableError.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableError.cs index 329a2557f3..f5259fa56a 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableError.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableError.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableErrorKind.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableErrorKind.cs index 0189ed2a79..11a69edb0e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableErrorKind.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRecoverableErrorKind.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRequest.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRequest.cs index 50d5acd6c9..31ded1f7d2 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRequest.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRequest.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRunningPayload.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRunningPayload.cs index ac46ed3027..c5cc79a87e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRunningPayload.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisRunningPayload.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisSucceededPayload.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisSucceededPayload.cs index b9a6a9055f..76d039973d 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisSucceededPayload.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisSucceededPayload.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisTask.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisTask.cs index 236a1d1b8d..5f21cffe0e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisTask.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisTask.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisUsage.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisUsage.cs index 59c7be453c..8cb1cdffac 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisUsage.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiAnalysisUsage.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiProvider.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiProvider.cs index da7b2dbe9a..08db33669f 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiProvider.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AiProvider.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ApiError.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ApiError.cs new file mode 100644 index 0000000000..c1638c0ab5 --- /dev/null +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ApiError.cs @@ -0,0 +1,141 @@ +/* + * devolutions-gateway + * + * Protocol-aware fine-grained relay server + * + * The version of the OpenAPI document: 2026.3.3 + * Contact: infos@devolutions.net + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using System.ComponentModel.DataAnnotations; +using FileParameter = Devolutions.Gateway.Client.Client.FileParameter; +using OpenAPIDateConverter = Devolutions.Gateway.Client.Client.OpenAPIDateConverter; + +namespace Devolutions.Gateway.Client.Model +{ + /// + /// Body of an API error response, as defined by RFC 9457 (problem details for HTTP APIs). The Gateway logs the details of the error, along with its code. + /// + [DataContract(Name = "ApiError")] + public partial class ApiError : IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + protected ApiError() { } + /// + /// Initializes a new instance of the class. + /// + /// Machine-readable error code; the `ErrorCode` schema lists the known values. New codes can be added: treat unknown values as generic failures. (required). + /// HTTP status code. (required). + /// Reason phrase of the HTTP status. (required). + /// Problem type, always `about:blank`: the HTTP status and the error code describe the problem. (required). + public ApiError(string error = default(string), int status = default(int), string title = default(string), string type = default(string)) + { + // to ensure "error" is required (not null) + if (error == null) + { + throw new ArgumentNullException("error is a required property for ApiError and cannot be null"); + } + this.Error = error; + this.Status = status; + // to ensure "title" is required (not null) + if (title == null) + { + throw new ArgumentNullException("title is a required property for ApiError and cannot be null"); + } + this.Title = title; + // to ensure "type" is required (not null) + if (type == null) + { + throw new ArgumentNullException("type is a required property for ApiError and cannot be null"); + } + this.Type = type; + } + + /// + /// Machine-readable error code; the `ErrorCode` schema lists the known values. New codes can be added: treat unknown values as generic failures. + /// + /// Machine-readable error code; the `ErrorCode` schema lists the known values. New codes can be added: treat unknown values as generic failures. + [DataMember(Name = "error", IsRequired = true, EmitDefaultValue = true)] + public string Error { get; set; } + + /// + /// HTTP status code. + /// + /// HTTP status code. + [DataMember(Name = "status", IsRequired = true, EmitDefaultValue = true)] + public int Status { get; set; } + + /// + /// Reason phrase of the HTTP status. + /// + /// Reason phrase of the HTTP status. + [DataMember(Name = "title", IsRequired = true, EmitDefaultValue = true)] + public string Title { get; set; } + + /// + /// Problem type, always `about:blank`: the HTTP status and the error code describe the problem. + /// + /// Problem type, always `about:blank`: the HTTP status and the error code describe the problem. + [DataMember(Name = "type", IsRequired = true, EmitDefaultValue = true)] + public string Type { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class ApiError {\n"); + sb.Append(" Error: ").Append(Error).Append("\n"); + sb.Append(" Status: ").Append(Status).Append("\n"); + sb.Append(" Title: ").Append(Title).Append("\n"); + sb.Append(" Type: ").Append(Type).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + // Status (int) minimum + if (this.Status < (int)0) + { + yield return new ValidationResult("Invalid value for Status, must be a value greater than or equal to 0.", new [] { "Status" }); + } + + yield break; + } + } + +} diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredential.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredential.cs index 37d90237bb..ee166823e7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredential.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredential.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredentialKind.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredentialKind.cs index c6bf83bbf6..7d86a39d47 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredentialKind.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppCredentialKind.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenContentType.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenContentType.cs index 50fcc49624..2d2e14796e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenContentType.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenContentType.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenSignRequest.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenSignRequest.cs index fb54ffa0d5..d39f9c0ac5 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenSignRequest.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/AppTokenSignRequest.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClaimedTrafficEvent.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClaimedTrafficEvent.cs index a69d86bda9..8e7635dbb7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClaimedTrafficEvent.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClaimedTrafficEvent.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClockDiagnostic.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClockDiagnostic.cs index 119d37def9..a740d59b03 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClockDiagnostic.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ClockDiagnostic.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigDiagnostic.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigDiagnostic.cs index b5c6c4a98b..996e05daf6 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigDiagnostic.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigDiagnostic.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigPatch.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigPatch.cs index b23cdace12..5acb60b8a7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigPatch.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConfigPatch.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConnectionMode.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConnectionMode.cs index 1b02f83831..764fe4ab9f 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConnectionMode.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ConnectionMode.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DataEncoding.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DataEncoding.cs index 43551f3c4a..30cee9e0b6 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DataEncoding.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DataEncoding.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DeleteManyResult.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DeleteManyResult.cs index d0c3420bcc..66767c8e0e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DeleteManyResult.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/DeleteManyResult.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollRequest.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollRequest.cs index a8a4b507d4..5b67c27bab 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollRequest.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollRequest.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollResponse.cs index 00fd3ef98b..d0f7b7a48a 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EnrollResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ErrorCode.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ErrorCode.cs new file mode 100644 index 0000000000..772f32febe --- /dev/null +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ErrorCode.cs @@ -0,0 +1,245 @@ +/* + * devolutions-gateway + * + * Protocol-aware fine-grained relay server + * + * The version of the OpenAPI document: 2026.3.3 + * Contact: infos@devolutions.net + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using System.ComponentModel.DataAnnotations; +using FileParameter = Devolutions.Gateway.Client.Client.FileParameter; +using OpenAPIDateConverter = Devolutions.Gateway.Client.Client.OpenAPIDateConverter; + +namespace Devolutions.Gateway.Client.Model +{ + /// + /// Machine-readable reason for a rejected request. New codes can be added, but existing codes are never renamed or removed. Clients must treat unknown codes as generic failures. - `bad_request`: The request is invalid. - `unauthorized`: The request is not authenticated. - `forbidden`: The request is not allowed. - `not_found`: The resource doesn't exist. - `request_timeout`: The request took too long to complete. - `conflict`: The request conflicts with the current state of the resource. - `payload_too_large`: The request is too large. - `internal_error`: The Gateway failed to process the request. - `bad_gateway`: The Gateway received an invalid response from an upstream server. - `service_unavailable`: The service is temporarily unavailable. - `gateway_timeout`: An upstream server didn't respond in time. - `insufficient_storage`: The Gateway is out of storage space. - `missing_token`: No token was found in the `Authorization` header or in the `token` query parameter. - `malformed_token`: The token can't be decoded or decrypted, or its claims don't match the schema expected for its type. - `bad_signature`: The token signature doesn't match the provisioner key of the Gateway. - `unknown_subkey`: The token refers to a key ID (`kid`) that doesn't match the sub provisioner key of the Gateway. - `expired`: The token has expired (`exp` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `not_yet_valid`: The token is not valid yet (`nbf` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `gateway_id_mismatch`: The token is restricted to another Gateway ID (`jet_gw_id` claim). - `revoked`: The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. - `unexpected_replay`: The token was already used, and can't be used again in this context. - `invalid_token`: The token is rejected for a reason not covered by another code. - `wrong_token_type`: The type of the token is not accepted by this route. - `insufficient_scope`: The scope of the token doesn't grant access to this route. + /// + /// Machine-readable reason for a rejected request. New codes can be added, but existing codes are never renamed or removed. Clients must treat unknown codes as generic failures. - `bad_request`: The request is invalid. - `unauthorized`: The request is not authenticated. - `forbidden`: The request is not allowed. - `not_found`: The resource doesn't exist. - `request_timeout`: The request took too long to complete. - `conflict`: The request conflicts with the current state of the resource. - `payload_too_large`: The request is too large. - `internal_error`: The Gateway failed to process the request. - `bad_gateway`: The Gateway received an invalid response from an upstream server. - `service_unavailable`: The service is temporarily unavailable. - `gateway_timeout`: An upstream server didn't respond in time. - `insufficient_storage`: The Gateway is out of storage space. - `missing_token`: No token was found in the `Authorization` header or in the `token` query parameter. - `malformed_token`: The token can't be decoded or decrypted, or its claims don't match the schema expected for its type. - `bad_signature`: The token signature doesn't match the provisioner key of the Gateway. - `unknown_subkey`: The token refers to a key ID (`kid`) that doesn't match the sub provisioner key of the Gateway. - `expired`: The token has expired (`exp` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `not_yet_valid`: The token is not valid yet (`nbf` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `gateway_id_mismatch`: The token is restricted to another Gateway ID (`jet_gw_id` claim). - `revoked`: The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. - `unexpected_replay`: The token was already used, and can't be used again in this context. - `invalid_token`: The token is rejected for a reason not covered by another code. - `wrong_token_type`: The type of the token is not accepted by this route. - `insufficient_scope`: The scope of the token doesn't grant access to this route. + [JsonConverter(typeof(StringEnumConverter))] + public enum ErrorCode + { + /// + /// Enum BadRequest for value: bad_request + /// + [EnumMember(Value = "bad_request")] + BadRequest = 1, + + /// + /// Enum Unauthorized for value: unauthorized + /// + [EnumMember(Value = "unauthorized")] + Unauthorized = 2, + + /// + /// Enum Forbidden for value: forbidden + /// + [EnumMember(Value = "forbidden")] + Forbidden = 3, + + /// + /// Enum NotFound for value: not_found + /// + [EnumMember(Value = "not_found")] + NotFound = 4, + + /// + /// Enum RequestTimeout for value: request_timeout + /// + [EnumMember(Value = "request_timeout")] + RequestTimeout = 5, + + /// + /// Enum Conflict for value: conflict + /// + [EnumMember(Value = "conflict")] + Conflict = 6, + + /// + /// Enum PayloadTooLarge for value: payload_too_large + /// + [EnumMember(Value = "payload_too_large")] + PayloadTooLarge = 7, + + /// + /// Enum InternalError for value: internal_error + /// + [EnumMember(Value = "internal_error")] + InternalError = 8, + + /// + /// Enum BadGateway for value: bad_gateway + /// + [EnumMember(Value = "bad_gateway")] + BadGateway = 9, + + /// + /// Enum ServiceUnavailable for value: service_unavailable + /// + [EnumMember(Value = "service_unavailable")] + ServiceUnavailable = 10, + + /// + /// Enum GatewayTimeout for value: gateway_timeout + /// + [EnumMember(Value = "gateway_timeout")] + GatewayTimeout = 11, + + /// + /// Enum InsufficientStorage for value: insufficient_storage + /// + [EnumMember(Value = "insufficient_storage")] + InsufficientStorage = 12, + + /// + /// Enum MissingToken for value: missing_token + /// + [EnumMember(Value = "missing_token")] + MissingToken = 13, + + /// + /// Enum MalformedToken for value: malformed_token + /// + [EnumMember(Value = "malformed_token")] + MalformedToken = 14, + + /// + /// Enum BadSignature for value: bad_signature + /// + [EnumMember(Value = "bad_signature")] + BadSignature = 15, + + /// + /// Enum UnknownSubkey for value: unknown_subkey + /// + [EnumMember(Value = "unknown_subkey")] + UnknownSubkey = 16, + + /// + /// Enum Expired for value: expired + /// + [EnumMember(Value = "expired")] + Expired = 17, + + /// + /// Enum NotYetValid for value: not_yet_valid + /// + [EnumMember(Value = "not_yet_valid")] + NotYetValid = 18, + + /// + /// Enum GatewayIdMismatch for value: gateway_id_mismatch + /// + [EnumMember(Value = "gateway_id_mismatch")] + GatewayIdMismatch = 19, + + /// + /// Enum Revoked for value: revoked + /// + [EnumMember(Value = "revoked")] + Revoked = 20, + + /// + /// Enum UnexpectedReplay for value: unexpected_replay + /// + [EnumMember(Value = "unexpected_replay")] + UnexpectedReplay = 21, + + /// + /// Enum InvalidToken for value: invalid_token + /// + [EnumMember(Value = "invalid_token")] + InvalidToken = 22, + + /// + /// Enum WrongTokenType for value: wrong_token_type + /// + [EnumMember(Value = "wrong_token_type")] + WrongTokenType = 23, + + /// + /// Enum InsufficientScope for value: insufficient_scope + /// + [EnumMember(Value = "insufficient_scope")] + InsufficientScope = 24 + } + + public static class ErrorCodeExtensions + { + /// + /// Returns the value as string for a given variant + /// + public static string ToValue(this ErrorCode variant) + { + switch (variant) + { + case ErrorCode.BadRequest: + return "bad_request"; + case ErrorCode.Unauthorized: + return "unauthorized"; + case ErrorCode.Forbidden: + return "forbidden"; + case ErrorCode.NotFound: + return "not_found"; + case ErrorCode.RequestTimeout: + return "request_timeout"; + case ErrorCode.Conflict: + return "conflict"; + case ErrorCode.PayloadTooLarge: + return "payload_too_large"; + case ErrorCode.InternalError: + return "internal_error"; + case ErrorCode.BadGateway: + return "bad_gateway"; + case ErrorCode.ServiceUnavailable: + return "service_unavailable"; + case ErrorCode.GatewayTimeout: + return "gateway_timeout"; + case ErrorCode.InsufficientStorage: + return "insufficient_storage"; + case ErrorCode.MissingToken: + return "missing_token"; + case ErrorCode.MalformedToken: + return "malformed_token"; + case ErrorCode.BadSignature: + return "bad_signature"; + case ErrorCode.UnknownSubkey: + return "unknown_subkey"; + case ErrorCode.Expired: + return "expired"; + case ErrorCode.NotYetValid: + return "not_yet_valid"; + case ErrorCode.GatewayIdMismatch: + return "gateway_id_mismatch"; + case ErrorCode.Revoked: + return "revoked"; + case ErrorCode.UnexpectedReplay: + return "unexpected_replay"; + case ErrorCode.InvalidToken: + return "invalid_token"; + case ErrorCode.WrongTokenType: + return "wrong_token_type"; + case ErrorCode.InsufficientScope: + return "insufficient_scope"; + default: + throw new ArgumentOutOfRangeException(nameof(variant), $"Unexpected variant: {variant}"); + } + } + } + +} diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EventOutcomeResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EventOutcomeResponse.cs index 25dd7a7c9b..ccf8811f6b 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EventOutcomeResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/EventOutcomeResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateProductsResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateProductsResponse.cs index e45b5346a6..39427f9a60 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateProductsResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateProductsResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateScheduleResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateScheduleResponse.cs index 214610d2c6..a99eb0c30c 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateScheduleResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/GetUpdateScheduleResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Heartbeat.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Heartbeat.cs index 70e8d5fced..6f484aabc5 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Heartbeat.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Heartbeat.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/HostScanStateDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/HostScanStateDto.cs index a8773544a5..9df6e3d289 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/HostScanStateDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/HostScanStateDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Identity.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Identity.cs index f27bb51dcb..eca39adaad 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Identity.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Identity.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/InterfaceInfo.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/InterfaceInfo.cs index 9acb50e903..8f0037503a 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/InterfaceInfo.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/InterfaceInfo.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/JrlInfo.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/JrlInfo.cs index 44ae29e6b2..3e71cd18d4 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/JrlInfo.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/JrlInfo.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ListenerUrls.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ListenerUrls.cs index ccd051a68d..2e8270d561 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ListenerUrls.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ListenerUrls.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinition.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinition.cs index 1c5ced8dee..7d5e2b08f6 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinition.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinition.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinitionProbeTypeError.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinitionProbeTypeError.cs index e6319f7fb2..0e1738594b 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinitionProbeTypeError.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorDefinitionProbeTypeError.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorResult.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorResult.cs index 3d326db439..5dfaeeabb7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorResult.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorResult.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringLogResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringLogResponse.cs index 5178361b79..fdcf6aeb3d 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringLogResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringLogResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeType.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeType.cs index d5940114cd..71726d54b2 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeType.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeType.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeTypeOneOf.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeTypeOneOf.cs index c54f19afd5..ae3c42a194 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeTypeOneOf.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitoringProbeTypeOneOf.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorsConfig.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorsConfig.cs index e2023b36eb..0ad9d636ff 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorsConfig.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/MonitorsConfig.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfaceDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfaceDto.cs index 82dd1c5eef..65b68eaa73 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfaceDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfaceDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfacesResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfacesResponse.cs index 35cdcf5e7e..b88d8eeaa7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfacesResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkInterfacesResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultEventDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultEventDto.cs index b55c29445f..18b6a2728d 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultEventDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultEventDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultKindDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultKindDto.cs index a06d6f44a7..20ca844f82 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultKindDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanResultKindDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceCapabilitiesDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceCapabilitiesDto.cs index 5a67d2b4ff..850936344a 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceCapabilitiesDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceCapabilitiesDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceDto.cs index 5c10a9c6d8..ec2c62f254 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/NetworkScanSourceDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightAlertStatus.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightAlertStatus.cs index f943d4fb6f..6797a48939 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightAlertStatus.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightAlertStatus.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperation.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperation.cs index e0fbcd5730..b35a349f24 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperation.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperation.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperationKind.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperationKind.cs index 7ec380fdd2..d1e020b64c 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperationKind.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOperationKind.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutput.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutput.cs index 35b5cd0576..fe1e1116eb 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutput.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutput.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutputKind.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutputKind.cs index b05ad143ec..66a80be23e 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutputKind.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PreflightOutputKind.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PubKeyFormat.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PubKeyFormat.cs index 805d381c3d..d4e82414be 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PubKeyFormat.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/PubKeyFormat.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchHit.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchHit.cs index 4191f310b0..d12671722d 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchHit.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchHit.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ @@ -41,11 +41,11 @@ protected RecordingSearchHit() { } /// /// Initializes a new instance of the class. /// - /// Name of the `.slog` artifact holding the line, as listed in `recording.json`. (required). + /// Name of the `.slog` file holding the line, as listed in `recording.json`. (required). /// The line's text without its line break; bytes that are not UTF-8 read as U+FFFD. (required). /// Number of the line in the file, counting from 1. (required). /// Byte offset of the line in the file. (required). - /// The recording whose artifact holds the line. (required). + /// The recording whose log holds the line. (required). /// The line is longer than 256 KiB, so `line` holds only its start, and the file holds the rest. (required). public RecordingSearchHit(string fileName = default(string), string line = default(string), long lineNumber = default(long), long offset = default(long), Guid recordingId = default(Guid), bool truncated = default(bool)) { @@ -68,9 +68,9 @@ protected RecordingSearchHit() { } } /// - /// Name of the `.slog` artifact holding the line, as listed in `recording.json`. + /// Name of the `.slog` file holding the line, as listed in `recording.json`. /// - /// Name of the `.slog` artifact holding the line, as listed in `recording.json`. + /// Name of the `.slog` file holding the line, as listed in `recording.json`. [DataMember(Name = "fileName", IsRequired = true, EmitDefaultValue = true)] public string FileName { get; set; } @@ -96,9 +96,9 @@ protected RecordingSearchHit() { } public long Offset { get; set; } /// - /// The recording whose artifact holds the line. + /// The recording whose log holds the line. /// - /// The recording whose artifact holds the line. + /// The recording whose log holds the line. [DataMember(Name = "recordingId", IsRequired = true, EmitDefaultValue = true)] public Guid RecordingId { get; set; } diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchRequest.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchRequest.cs index b9c98407af..881d1f9863 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchRequest.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchRequest.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchResponse.cs index 9119308fb5..fecf01e7e6 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSearchResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSelection.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSelection.cs index c5953fc73e..6c7af0feef 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSelection.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/RecordingSelection.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanOriginDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanOriginDto.cs index a47ef1ba34..f2b962fca2 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanOriginDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanOriginDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanResultSourceDto.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanResultSourceDto.cs index a98ab0a980..a3b2b03558 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanResultSourceDto.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/ScanResultSourceDto.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionInfo.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionInfo.cs index a630216192..6f31493ad2 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionInfo.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionInfo.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenContentType.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenContentType.cs index 20b9a17735..f1b87dbacb 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenContentType.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenContentType.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenSignRequest.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenSignRequest.cs index 611233691a..d780cfa0b6 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenSignRequest.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SessionTokenSignRequest.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetConfigResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetConfigResponse.cs index 1914cf188f..d530d09187 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetConfigResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetConfigResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetUpdateScheduleRequest.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetUpdateScheduleRequest.cs index e12658b419..f70ba2764c 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetUpdateScheduleRequest.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SetUpdateScheduleRequest.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/StartTimeRange.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/StartTimeRange.cs index 1bc5d4e9b6..a6d95787c9 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/StartTimeRange.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/StartTimeRange.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SubProvisionerKey.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SubProvisionerKey.cs index 404ab0fed4..3fd3073fd2 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SubProvisionerKey.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/SubProvisionerKey.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Subscriber.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Subscriber.cs index ac570f1477..22601895cb 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Subscriber.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/Subscriber.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TargetConnectionOptions.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TargetConnectionOptions.cs index 8e7e742d09..2dbb15f2cd 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TargetConnectionOptions.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TargetConnectionOptions.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TaskState.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TaskState.cs index 4257977889..ee9a6fb130 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TaskState.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TaskState.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TrafficEventResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TrafficEventResponse.cs index 317a12c356..07c065285d 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TrafficEventResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TrafficEventResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TransportProtocolResponse.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TransportProtocolResponse.cs index dc275b1a81..20d52a23d0 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TransportProtocolResponse.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/TransportProtocolResponse.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateProductInfo.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateProductInfo.cs index 30008605cb..2c8448f041 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateProductInfo.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateProductInfo.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateRequestSchema.cs b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateRequestSchema.cs index 8adad30c17..3422dbcff7 100644 --- a/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateRequestSchema.cs +++ b/devolutions-gateway/openapi/dotnet-client/src/Devolutions.Gateway.Client/Model/UpdateRequestSchema.cs @@ -3,7 +3,7 @@ * * Protocol-aware fine-grained relay server * - * The version of the OpenAPI document: 2026.2.4 + * The version of the OpenAPI document: 2026.3.3 * Contact: infos@devolutions.net * Generated by: https://github.com/openapitools/openapi-generator.git */ diff --git a/devolutions-gateway/openapi/gateway-api.yaml b/devolutions-gateway/openapi/gateway-api.yaml index f3ed77ab0e..6bb8b3a8ae 100644 --- a/devolutions-gateway/openapi/gateway-api.yaml +++ b/devolutions-gateway/openapi/gateway-api.yaml @@ -7,7 +7,7 @@ info: email: infos@devolutions.net license: name: MIT/Apache-2.0 - version: 2026.2.4 + version: 2026.3.3 paths: /jet/config: patch: @@ -27,12 +27,28 @@ paths: description: Configuration has been patched with success '400': description: Bad patch request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Failed to patch configuration + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.config.write @@ -76,10 +92,22 @@ paths: $ref: '#/components/schemas/ConfigDiagnostic' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.diagnostics.read @@ -137,10 +165,22 @@ paths: $ref: '#/components/schemas/Heartbeat' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.heartbeat.read @@ -182,14 +222,34 @@ paths: $ref: '#/components/schemas/DeleteManyResult' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '409': description: A recording is still ongoing and can't be deleted yet (nothing is deleted) + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '413': description: Request payload is too large + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.recording.delete @@ -212,14 +272,34 @@ paths: description: Recording matching the ID in the path has been deleted '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '404': description: The specified recording was not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '409': description: The recording is still ongoing and can't be deleted yet + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.recording.delete @@ -248,10 +328,22 @@ paths: format: uuid '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.recordings.read @@ -337,12 +429,28 @@ paths: format: binary '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '404': description: File not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - jrec_token: - pull @@ -350,7 +458,7 @@ paths: post: tags: - Jrec - summary: Searches the `.slog` artifacts, such as AI analysis logs, of recordings stored on this instance + summary: Searches the `.slog` files of recordings stored on this instance, such as Active Directory Console logs description: |- The query is a case-insensitive substring, and an empty query matches every line. In a line holding a JSON object, it is matched against the string values of the object at any depth, as they read @@ -358,7 +466,7 @@ paths: Any other line, such as one still being written, is matched as raw text. A line longer than 256 KiB is matched on its first 256 KiB only, by the same rule, so a cut JSON object is usually matched as raw text. - Only the files listed under `artifacts` in `recording.json` with the `slog` type are searched. + Only the files listed in `recording.json` with the `slog` type are searched, under `files` and under `artifacts`. Recordings without a readable `recording.json` and IDs with no recording on this instance give no hits. Results come in pages. @@ -383,10 +491,22 @@ paths: $ref: '#/components/schemas/RecordingSearchResponse' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.recordings.search @@ -401,12 +521,28 @@ paths: description: JRL updated successfully '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Failed to update the JRL + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - jrl_token: [] /jet/jrl/info: @@ -424,12 +560,28 @@ paths: $ref: '#/components/schemas/JrlInfo' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Failed to update the JRL + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.jrl.read @@ -454,12 +606,28 @@ paths: $ref: '#/components/schemas/InterfaceInfo' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - netscan_token: [] /jet/net/interfaces: @@ -477,12 +645,28 @@ paths: $ref: '#/components/schemas/NetworkInterfacesResponse' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - netscan_token: [] /jet/net/monitor/config: @@ -516,12 +700,28 @@ paths: $ref: '#/components/schemas/SetConfigResponse' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error while starting monitors + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.net.monitor.config @@ -541,12 +741,28 @@ paths: $ref: '#/components/schemas/MonitoringLogResponse' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.net.monitor.drain @@ -849,10 +1065,22 @@ paths: description: Invalid query, mixed target/range, oversized range, or selected interface error '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - netscan_token: [] /jet/preflight: @@ -880,10 +1108,22 @@ paths: $ref: '#/components/schemas/PreflightOutput' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.preflight @@ -906,14 +1146,34 @@ paths: description: Session terminated successfully '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '404': description: No running session found with provided ID + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.session.terminate @@ -934,12 +1194,28 @@ paths: $ref: '#/components/schemas/SessionInfo' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.sessions.read @@ -970,14 +1246,34 @@ paths: $ref: '#/components/schemas/AiAnalysisTask' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '404': description: No AI analysis has this Task ID + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.tasks.recording-ai-analysis.read @@ -1034,12 +1330,28 @@ paths: $ref: '#/components/schemas/AiAnalysisTask' '400': description: Invalid request body, AI settings or language + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '404': description: The session has no recording + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '409': description: The AI analysis cannot start now content: @@ -1048,6 +1360,10 @@ paths: $ref: '#/components/schemas/AiAnalysisConflict' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.tasks.recording-ai-analysis.start @@ -1073,14 +1389,34 @@ paths: $ref: '#/components/schemas/AckResponse' '400': description: Invalid request body (empty ids array) + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '413': description: Payload too large (more than 10,000 IDs) + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Internal server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.traffic.ack @@ -1117,12 +1453,28 @@ paths: $ref: '#/components/schemas/ClaimedTrafficEvent' '400': description: Invalid query parameters + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Internal server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.traffic.claim @@ -1143,10 +1495,22 @@ paths: $ref: '#/components/schemas/AgentInfo' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.agent.read @@ -1173,12 +1537,28 @@ paths: $ref: '#/components/schemas/AgentInfo' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '404': description: Agent not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.agent.read @@ -1200,12 +1580,28 @@ paths: description: Agent deleted '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '404': description: Agent not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.agent.delete @@ -1237,12 +1633,28 @@ paths: $ref: '#/components/schemas/EnrollResponse' '400': description: Invalid agent name, request body, or certificate signing request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing enrollment token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '409': description: Agent ID or name already registered, agent key previously deleted, or enrollment token already used + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Unexpected server error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - enrollment_token: [] /jet/update: @@ -1265,12 +1677,28 @@ paths: $ref: '#/components/schemas/GetUpdateProductsResponse' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Failed to read agent status file + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '503': description: Agent updater service is unavailable + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.update.read @@ -1317,14 +1745,34 @@ paths: $ref: '#/components/schemas/UpdateResponse' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Failed to write update manifest + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '503': description: Agent updater service is unavailable + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.update @@ -1346,12 +1794,28 @@ paths: $ref: '#/components/schemas/GetUpdateScheduleResponse' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Failed to read agent status file + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '503': description: Agent updater service is unavailable + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.update.read @@ -1382,14 +1846,34 @@ paths: $ref: '#/components/schemas/SetUpdateScheduleResponse' '400': description: Bad request + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '401': description: Invalid or missing authorization token + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '403': description: Insufficient permissions + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '500': description: Failed to write update manifest + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' '503': description: Agent updater service is unavailable + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApiError' security: - scope_token: - gateway.update @@ -1857,6 +2341,40 @@ components: - mistral - gemini - openai-compatible + ApiError: + type: object + description: |- + Body of an API error response, as defined by RFC 9457 (problem details for HTTP APIs). + + The Gateway logs the details of the error, along with its code. + required: + - type + - title + - status + - error + properties: + error: + type: string + description: |- + Machine-readable error code; the `ErrorCode` schema lists the known values. + + New codes can be added: treat unknown values as generic failures. + status: + type: integer + format: int32 + description: HTTP status code. + minimum: 0 + title: + type: string + description: Reason phrase of the HTTP status. + type: + type: string + description: 'Problem type, always `about:blank`: the HTTP status and the error code describe the problem.' + example: + error: gateway_id_mismatch + status: 401 + title: Unauthorized + type: about:blank AppCredential: type: object required: @@ -2042,6 +2560,62 @@ components: description: |- SHA-256 hash of the server certificate's SPKI (hex-encoded). Used by the agent to pin the server's public key. + ErrorCode: + type: string + description: |- + Machine-readable reason for a rejected request. + + New codes can be added, but existing codes are never renamed or removed. Clients must treat unknown codes as generic failures. + + - `bad_request`: The request is invalid. + - `unauthorized`: The request is not authenticated. + - `forbidden`: The request is not allowed. + - `not_found`: The resource doesn't exist. + - `request_timeout`: The request took too long to complete. + - `conflict`: The request conflicts with the current state of the resource. + - `payload_too_large`: The request is too large. + - `internal_error`: The Gateway failed to process the request. + - `bad_gateway`: The Gateway received an invalid response from an upstream server. + - `service_unavailable`: The service is temporarily unavailable. + - `gateway_timeout`: An upstream server didn't respond in time. + - `insufficient_storage`: The Gateway is out of storage space. + - `missing_token`: No token was found in the `Authorization` header or in the `token` query parameter. + - `malformed_token`: The token can't be decoded or decrypted, or its claims don't match the schema expected for its type. + - `bad_signature`: The token signature doesn't match the provisioner key of the Gateway. + - `unknown_subkey`: The token refers to a key ID (`kid`) that doesn't match the sub provisioner key of the Gateway. + - `expired`: The token has expired (`exp` claim); the clocks of the token issuer and of the Gateway may be out of sync. + - `not_yet_valid`: The token is not valid yet (`nbf` claim); the clocks of the token issuer and of the Gateway may be out of sync. + - `gateway_id_mismatch`: The token is restricted to another Gateway ID (`jet_gw_id` claim). + - `revoked`: The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. + - `unexpected_replay`: The token was already used, and can't be used again in this context. + - `invalid_token`: The token is rejected for a reason not covered by another code. + - `wrong_token_type`: The type of the token is not accepted by this route. + - `insufficient_scope`: The scope of the token doesn't grant access to this route. + enum: + - bad_request + - unauthorized + - forbidden + - not_found + - request_timeout + - conflict + - payload_too_large + - internal_error + - bad_gateway + - service_unavailable + - gateway_timeout + - insufficient_storage + - missing_token + - malformed_token + - bad_signature + - unknown_subkey + - expired + - not_yet_valid + - gateway_id_mismatch + - revoked + - unexpected_replay + - invalid_token + - wrong_token_type + - insufficient_scope EventOutcomeResponse: type: string enum: @@ -2664,7 +3238,7 @@ components: properties: fileName: type: string - description: Name of the `.slog` artifact holding the line, as listed in `recording.json`. + description: Name of the `.slog` file holding the line, as listed in `recording.json`. line: type: string description: The line's text without its line break; bytes that are not UTF-8 read as U+FFFD. @@ -2681,7 +3255,7 @@ components: recordingId: type: string format: uuid - description: The recording whose artifact holds the line. + description: The recording whose log holds the line. truncated: type: boolean description: The line is longer than 256 KiB, so `line` holds only its start, and the file holds the rest. diff --git a/devolutions-gateway/openapi/ts-angular-client/README.md b/devolutions-gateway/openapi/ts-angular-client/README.md index 87153eb065..8f98bf4739 100644 --- a/devolutions-gateway/openapi/ts-angular-client/README.md +++ b/devolutions-gateway/openapi/ts-angular-client/README.md @@ -2,7 +2,7 @@ Protocol-aware fine-grained relay server -The version of the OpenAPI document: 2026.2.4 +The version of the OpenAPI document: 2026.3.3 ### Building diff --git a/devolutions-gateway/openapi/ts-angular-client/api/agent.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/agent.service.ts index 04ed13cdab..3ac36bd4e9 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/agent.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/agent.service.ts @@ -19,6 +19,8 @@ import { Observable } from 'rxjs'; // @ts-ignore import { AgentInfo } from '../model/agentInfo'; // @ts-ignore +import { ApiError } from '../model/apiError'; +// @ts-ignore import { EnrollRequest } from '../model/enrollRequest'; // @ts-ignore import { EnrollResponse } from '../model/enrollResponse'; @@ -100,10 +102,10 @@ export class AgentService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public deleteAgent(agentId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; - public deleteAgent(agentId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public deleteAgent(agentId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public deleteAgent(agentId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { + public deleteAgent(agentId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public deleteAgent(agentId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteAgent(agentId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteAgent(agentId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (agentId === null || agentId === undefined) { throw new Error('Required parameter agentId was null or undefined when calling deleteAgent.'); } @@ -121,6 +123,7 @@ export class AgentService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -171,10 +174,10 @@ export class AgentService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public enrollAgent(enrollRequest: EnrollRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public enrollAgent(enrollRequest: EnrollRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public enrollAgent(enrollRequest: EnrollRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public enrollAgent(enrollRequest: EnrollRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public enrollAgent(enrollRequest: EnrollRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public enrollAgent(enrollRequest: EnrollRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public enrollAgent(enrollRequest: EnrollRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public enrollAgent(enrollRequest: EnrollRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (enrollRequest === null || enrollRequest === undefined) { throw new Error('Required parameter enrollRequest was null or undefined when calling enrollAgent.'); } @@ -192,7 +195,8 @@ export class AgentService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -252,10 +256,10 @@ export class AgentService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getAgent(agentId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getAgent(agentId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getAgent(agentId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getAgent(agentId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getAgent(agentId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getAgent(agentId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getAgent(agentId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getAgent(agentId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (agentId === null || agentId === undefined) { throw new Error('Required parameter agentId was null or undefined when calling getAgent.'); } @@ -273,7 +277,8 @@ export class AgentService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -322,10 +327,10 @@ export class AgentService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public listAgents(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public listAgents(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public listAgents(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public listAgents(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public listAgents(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public listAgents(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public listAgents(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public listAgents(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -340,7 +345,8 @@ export class AgentService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/config.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/config.service.ts index f2586e77e4..2f8506930b 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/config.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/config.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { ConfigPatch } from '../model/configPatch'; @@ -96,10 +98,10 @@ export class ConfigService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public patchConfig(configPatch: ConfigPatch, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; - public patchConfig(configPatch: ConfigPatch, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public patchConfig(configPatch: ConfigPatch, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public patchConfig(configPatch: ConfigPatch, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { + public patchConfig(configPatch: ConfigPatch, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public patchConfig(configPatch: ConfigPatch, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public patchConfig(configPatch: ConfigPatch, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public patchConfig(configPatch: ConfigPatch, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (configPatch === null || configPatch === undefined) { throw new Error('Required parameter configPatch was null or undefined when calling patchConfig.'); } @@ -117,6 +119,7 @@ export class ConfigService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/diagnostics.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/diagnostics.service.ts index 72b1d8da38..4147c8734a 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/diagnostics.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/diagnostics.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { ClockDiagnostic } from '../model/clockDiagnostic'; // @ts-ignore @@ -159,10 +161,10 @@ export class DiagnosticsService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getConfigurationDiagnostic(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getConfigurationDiagnostic(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getConfigurationDiagnostic(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getConfigurationDiagnostic(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getConfigurationDiagnostic(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getConfigurationDiagnostic(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getConfigurationDiagnostic(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getConfigurationDiagnostic(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -177,7 +179,8 @@ export class DiagnosticsService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/heartbeat.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/heartbeat.service.ts index 26040f8632..73a5702c3f 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/heartbeat.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/heartbeat.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { Heartbeat } from '../model/heartbeat'; @@ -95,10 +97,10 @@ export class HeartbeatService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getHeartbeat(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getHeartbeat(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getHeartbeat(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getHeartbeat(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getHeartbeat(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getHeartbeat(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getHeartbeat(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getHeartbeat(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -113,7 +115,8 @@ export class HeartbeatService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/jrec.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/jrec.service.ts index 130ff953ac..f1d8afc416 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/jrec.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/jrec.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { DeleteManyResult } from '../model/deleteManyResult'; // @ts-ignore @@ -101,10 +103,10 @@ export class JrecService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public deleteManyRecordings(requestBody: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public deleteManyRecordings(requestBody: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public deleteManyRecordings(requestBody: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public deleteManyRecordings(requestBody: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public deleteManyRecordings(requestBody: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public deleteManyRecordings(requestBody: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteManyRecordings(requestBody: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteManyRecordings(requestBody: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (requestBody === null || requestBody === undefined) { throw new Error('Required parameter requestBody was null or undefined when calling deleteManyRecordings.'); } @@ -122,7 +124,8 @@ export class JrecService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -182,10 +185,10 @@ export class JrecService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public deleteRecording(id: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; - public deleteRecording(id: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public deleteRecording(id: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public deleteRecording(id: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { + public deleteRecording(id: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public deleteRecording(id: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteRecording(id: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteRecording(id: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling deleteRecording.'); } @@ -203,6 +206,7 @@ export class JrecService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -252,10 +256,10 @@ export class JrecService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public listRecordings(active: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public listRecordings(active: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public listRecordings(active: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public listRecordings(active: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public listRecordings(active: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public listRecordings(active: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public listRecordings(active: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public listRecordings(active: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (active === null || active === undefined) { throw new Error('Required parameter active was null or undefined when calling listRecordings.'); } @@ -279,7 +283,8 @@ export class JrecService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -331,10 +336,10 @@ export class JrecService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public pullRecordingFile(id: string, filename: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/octet-stream', context?: HttpContext, transferCache?: boolean}): Observable; - public pullRecordingFile(id: string, filename: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/octet-stream', context?: HttpContext, transferCache?: boolean}): Observable>; - public pullRecordingFile(id: string, filename: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/octet-stream', context?: HttpContext, transferCache?: boolean}): Observable>; - public pullRecordingFile(id: string, filename: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/octet-stream', context?: HttpContext, transferCache?: boolean}): Observable { + public pullRecordingFile(id: string, filename: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'video/webm' | 'application/x-asciicast' | 'application/x-ndjson' | 'application/json' | 'application/octet-stream' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public pullRecordingFile(id: string, filename: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'video/webm' | 'application/x-asciicast' | 'application/x-ndjson' | 'application/json' | 'application/octet-stream' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public pullRecordingFile(id: string, filename: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'video/webm' | 'application/x-asciicast' | 'application/x-ndjson' | 'application/json' | 'application/octet-stream' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public pullRecordingFile(id: string, filename: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'video/webm' | 'application/x-asciicast' | 'application/x-ndjson' | 'application/json' | 'application/octet-stream' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling pullRecordingFile.'); } @@ -355,7 +360,12 @@ export class JrecService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/octet-stream' + 'video/webm', + 'application/x-asciicast', + 'application/x-ndjson', + 'application/json', + 'application/octet-stream', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -456,10 +466,10 @@ export class JrecService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public searchRecordings(recordingSearchRequest: RecordingSearchRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (recordingSearchRequest === null || recordingSearchRequest === undefined) { throw new Error('Required parameter recordingSearchRequest was null or undefined when calling searchRecordings.'); } @@ -477,7 +487,8 @@ export class JrecService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/jrl.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/jrl.service.ts index 4063f75ae1..76c54d5eb5 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/jrl.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/jrl.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { JrlInfo } from '../model/jrlInfo'; @@ -95,10 +97,10 @@ export class JrlService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getJrlInfo(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getJrlInfo(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getJrlInfo(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getJrlInfo(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getJrlInfo(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getJrlInfo(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getJrlInfo(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getJrlInfo(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -113,7 +115,8 @@ export class JrlService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -162,10 +165,10 @@ export class JrlService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public updateJrl(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; - public updateJrl(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public updateJrl(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public updateJrl(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { + public updateJrl(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public updateJrl(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public updateJrl(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public updateJrl(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -180,6 +183,7 @@ export class JrlService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/net.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/net.service.ts index f34155875c..308b1ed899 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/net.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/net.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { InterfaceInfo } from '../model/interfaceInfo'; // @ts-ignore @@ -97,10 +99,10 @@ export class NetService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getNetConfig(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; }>>; - public getNetConfig(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; }>>>; - public getNetConfig(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; }>>>; - public getNetConfig(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getNetConfig(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; }>>; + public getNetConfig(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; }>>>; + public getNetConfig(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; }>>>; + public getNetConfig(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -115,7 +117,8 @@ export class NetService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -164,10 +167,10 @@ export class NetService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getNetInterfaces(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getNetInterfaces(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getNetInterfaces(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getNetInterfaces(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getNetInterfaces(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getNetInterfaces(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getNetInterfaces(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getNetInterfaces(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -182,7 +185,8 @@ export class NetService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -264,10 +268,10 @@ export class NetService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; - public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { + public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getNetScan(pingInterval?: number, pingTimeout?: number, broadcastTimeout?: number, portScanTimeout?: number, netbiosTimeout?: number, netbiosInterval?: number, mdnsQueryTimeout?: number, maxWait?: number, range?: Array, target?: Array, interfaceId?: Array, probe?: Array, enablePingStart?: boolean, enableBroadcast?: boolean, enableSubnetScan?: boolean, enableZeroconf?: boolean, enableNetbios?: boolean, enableResolveDns?: boolean, includeHostResults?: boolean, reportPingStart?: boolean, reportPingSuccess?: boolean, reportPingFailure?: boolean, enableTcpProbes?: boolean, rangeInterfacePolicy?: string, allowCrossInterfaceRange?: boolean, responseFormat?: string, maxConcurrency?: number, maxPingConcurrency?: number, maxTcpProbeConcurrency?: number, enableFailure?: boolean, reportTcpFailure?: boolean, interfaceBindStrict?: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarQueryParameters = new HttpParams({encoder: this.encoder}); if (pingInterval !== undefined && pingInterval !== null) { @@ -420,6 +424,7 @@ export class NetService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/networkMonitoring.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/networkMonitoring.service.ts index 1bfa710852..a121a30a00 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/networkMonitoring.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/networkMonitoring.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { MonitoringLogResponse } from '../model/monitoringLogResponse'; // @ts-ignore @@ -100,10 +102,10 @@ export class NetworkMonitoringService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public drainMonitoringLog(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public drainMonitoringLog(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public drainMonitoringLog(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public drainMonitoringLog(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public drainMonitoringLog(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public drainMonitoringLog(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public drainMonitoringLog(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public drainMonitoringLog(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -118,7 +120,8 @@ export class NetworkMonitoringService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -169,10 +172,10 @@ export class NetworkMonitoringService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public setMonitoringConfig(monitorsConfig: MonitorsConfig, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (monitorsConfig === null || monitorsConfig === undefined) { throw new Error('Required parameter monitorsConfig was null or undefined when calling setMonitoringConfig.'); } @@ -190,7 +193,8 @@ export class NetworkMonitoringService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/preflight.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/preflight.service.ts index d49f63b203..2552d0d2c5 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/preflight.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/preflight.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { PreflightOperation } from '../model/preflightOperation'; // @ts-ignore @@ -98,10 +100,10 @@ export class PreflightService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public postPreflight(preflightOperation: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public postPreflight(preflightOperation: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public postPreflight(preflightOperation: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public postPreflight(preflightOperation: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public postPreflight(preflightOperation: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public postPreflight(preflightOperation: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public postPreflight(preflightOperation: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public postPreflight(preflightOperation: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (preflightOperation === null || preflightOperation === undefined) { throw new Error('Required parameter preflightOperation was null or undefined when calling postPreflight.'); } @@ -119,7 +121,8 @@ export class PreflightService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/sessions.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/sessions.service.ts index 4c2b60cc49..db23a0568f 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/sessions.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/sessions.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { SessionInfo } from '../model/sessionInfo'; @@ -95,10 +97,10 @@ export class SessionsService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getSessions(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getSessions(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public getSessions(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public getSessions(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getSessions(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getSessions(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public getSessions(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public getSessions(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -113,7 +115,8 @@ export class SessionsService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -163,10 +166,10 @@ export class SessionsService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public terminateSession(id: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; - public terminateSession(id: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public terminateSession(id: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; - public terminateSession(id: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { + public terminateSession(id: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public terminateSession(id: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public terminateSession(id: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public terminateSession(id: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling terminateSession.'); } @@ -184,6 +187,7 @@ export class SessionsService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/traffic.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/traffic.service.ts index 981f61315d..25bfa352b1 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/traffic.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/traffic.service.ts @@ -21,6 +21,8 @@ import { AckRequest } from '../model/ackRequest'; // @ts-ignore import { AckResponse } from '../model/ackResponse'; // @ts-ignore +import { ApiError } from '../model/apiError'; +// @ts-ignore import { ClaimedTrafficEvent } from '../model/claimedTrafficEvent'; // @ts-ignore @@ -100,10 +102,10 @@ export class TrafficService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public ackTrafficEvents(ackRequest: AckRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public ackTrafficEvents(ackRequest: AckRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public ackTrafficEvents(ackRequest: AckRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public ackTrafficEvents(ackRequest: AckRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public ackTrafficEvents(ackRequest: AckRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public ackTrafficEvents(ackRequest: AckRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public ackTrafficEvents(ackRequest: AckRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public ackTrafficEvents(ackRequest: AckRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (ackRequest === null || ackRequest === undefined) { throw new Error('Required parameter ackRequest was null or undefined when calling ackTrafficEvents.'); } @@ -121,7 +123,8 @@ export class TrafficService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -182,10 +185,10 @@ export class TrafficService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public claimTrafficEvents(leaseMs: number, max: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public claimTrafficEvents(leaseMs: number, max: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public claimTrafficEvents(leaseMs: number, max: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; - public claimTrafficEvents(leaseMs: number, max: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public claimTrafficEvents(leaseMs: number, max: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public claimTrafficEvents(leaseMs: number, max: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public claimTrafficEvents(leaseMs: number, max: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public claimTrafficEvents(leaseMs: number, max: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (leaseMs === null || leaseMs === undefined) { throw new Error('Required parameter leaseMs was null or undefined when calling claimTrafficEvents.'); } @@ -216,7 +219,8 @@ export class TrafficService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/api/update.service.ts b/devolutions-gateway/openapi/ts-angular-client/api/update.service.ts index 446252e569..4f3b0b0a96 100644 --- a/devolutions-gateway/openapi/ts-angular-client/api/update.service.ts +++ b/devolutions-gateway/openapi/ts-angular-client/api/update.service.ts @@ -16,6 +16,8 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +// @ts-ignore +import { ApiError } from '../model/apiError'; // @ts-ignore import { GetUpdateProductsResponse } from '../model/getUpdateProductsResponse'; // @ts-ignore @@ -102,10 +104,10 @@ export class UpdateService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getUpdateProducts(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getUpdateProducts(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getUpdateProducts(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getUpdateProducts(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getUpdateProducts(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getUpdateProducts(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUpdateProducts(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUpdateProducts(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -120,7 +122,8 @@ export class UpdateService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -170,10 +173,10 @@ export class UpdateService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public getUpdateSchedule(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getUpdateSchedule(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getUpdateSchedule(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getUpdateSchedule(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getUpdateSchedule(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public getUpdateSchedule(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUpdateSchedule(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUpdateSchedule(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -188,7 +191,8 @@ export class UpdateService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -239,10 +243,10 @@ export class UpdateService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public setUpdateSchedule(setUpdateScheduleRequest: SetUpdateScheduleRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { if (setUpdateScheduleRequest === null || setUpdateScheduleRequest === undefined) { throw new Error('Required parameter setUpdateScheduleRequest was null or undefined when calling setUpdateSchedule.'); } @@ -260,7 +264,8 @@ export class UpdateService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } @@ -322,10 +327,10 @@ export class UpdateService { * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. */ - public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable; + public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable>; + public triggerUpdate(version?: string, updateRequestSchema?: UpdateRequestSchema, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json' | 'application/problem+json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarQueryParameters = new HttpParams({encoder: this.encoder}); if (version !== undefined && version !== null) { @@ -346,7 +351,8 @@ export class UpdateService { if (localVarHttpHeaderAcceptSelected === undefined) { // to determine the Accept header const httpHeaderAccepts: string[] = [ - 'application/json' + 'application/json', + 'application/problem+json' ]; localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); } diff --git a/devolutions-gateway/openapi/ts-angular-client/model/apiError.ts b/devolutions-gateway/openapi/ts-angular-client/model/apiError.ts new file mode 100644 index 0000000000..d5c295123b --- /dev/null +++ b/devolutions-gateway/openapi/ts-angular-client/model/apiError.ts @@ -0,0 +1,33 @@ +/** + * devolutions-gateway + * + * Contact: infos@devolutions.net + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * Body of an API error response, as defined by RFC 9457 (problem details for HTTP APIs). The Gateway logs the details of the error, along with its code. + */ +export interface ApiError { + /** + * Machine-readable error code; the `ErrorCode` schema lists the known values. New codes can be added: treat unknown values as generic failures. + */ + error: string; + /** + * HTTP status code. + */ + status: number; + /** + * Reason phrase of the HTTP status. + */ + title: string; + /** + * Problem type, always `about:blank`: the HTTP status and the error code describe the problem. + */ + type: string; +} + diff --git a/devolutions-gateway/openapi/ts-angular-client/model/errorCode.ts b/devolutions-gateway/openapi/ts-angular-client/model/errorCode.ts new file mode 100644 index 0000000000..d7813470a5 --- /dev/null +++ b/devolutions-gateway/openapi/ts-angular-client/model/errorCode.ts @@ -0,0 +1,43 @@ +/** + * devolutions-gateway + * + * Contact: infos@devolutions.net + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * Machine-readable reason for a rejected request. New codes can be added, but existing codes are never renamed or removed. Clients must treat unknown codes as generic failures. - `bad_request`: The request is invalid. - `unauthorized`: The request is not authenticated. - `forbidden`: The request is not allowed. - `not_found`: The resource doesn\'t exist. - `request_timeout`: The request took too long to complete. - `conflict`: The request conflicts with the current state of the resource. - `payload_too_large`: The request is too large. - `internal_error`: The Gateway failed to process the request. - `bad_gateway`: The Gateway received an invalid response from an upstream server. - `service_unavailable`: The service is temporarily unavailable. - `gateway_timeout`: An upstream server didn\'t respond in time. - `insufficient_storage`: The Gateway is out of storage space. - `missing_token`: No token was found in the `Authorization` header or in the `token` query parameter. - `malformed_token`: The token can\'t be decoded or decrypted, or its claims don\'t match the schema expected for its type. - `bad_signature`: The token signature doesn\'t match the provisioner key of the Gateway. - `unknown_subkey`: The token refers to a key ID (`kid`) that doesn\'t match the sub provisioner key of the Gateway. - `expired`: The token has expired (`exp` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `not_yet_valid`: The token is not valid yet (`nbf` claim); the clocks of the token issuer and of the Gateway may be out of sync. - `gateway_id_mismatch`: The token is restricted to another Gateway ID (`jet_gw_id` claim). - `revoked`: The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. - `unexpected_replay`: The token was already used, and can\'t be used again in this context. - `invalid_token`: The token is rejected for a reason not covered by another code. - `wrong_token_type`: The type of the token is not accepted by this route. - `insufficient_scope`: The scope of the token doesn\'t grant access to this route. + */ +export type ErrorCode = 'bad_request' | 'unauthorized' | 'forbidden' | 'not_found' | 'request_timeout' | 'conflict' | 'payload_too_large' | 'internal_error' | 'bad_gateway' | 'service_unavailable' | 'gateway_timeout' | 'insufficient_storage' | 'missing_token' | 'malformed_token' | 'bad_signature' | 'unknown_subkey' | 'expired' | 'not_yet_valid' | 'gateway_id_mismatch' | 'revoked' | 'unexpected_replay' | 'invalid_token' | 'wrong_token_type' | 'insufficient_scope'; + +export const ErrorCode = { + BadRequest: 'bad_request' as ErrorCode, + Unauthorized: 'unauthorized' as ErrorCode, + Forbidden: 'forbidden' as ErrorCode, + NotFound: 'not_found' as ErrorCode, + RequestTimeout: 'request_timeout' as ErrorCode, + Conflict: 'conflict' as ErrorCode, + PayloadTooLarge: 'payload_too_large' as ErrorCode, + InternalError: 'internal_error' as ErrorCode, + BadGateway: 'bad_gateway' as ErrorCode, + ServiceUnavailable: 'service_unavailable' as ErrorCode, + GatewayTimeout: 'gateway_timeout' as ErrorCode, + InsufficientStorage: 'insufficient_storage' as ErrorCode, + MissingToken: 'missing_token' as ErrorCode, + MalformedToken: 'malformed_token' as ErrorCode, + BadSignature: 'bad_signature' as ErrorCode, + UnknownSubkey: 'unknown_subkey' as ErrorCode, + Expired: 'expired' as ErrorCode, + NotYetValid: 'not_yet_valid' as ErrorCode, + GatewayIdMismatch: 'gateway_id_mismatch' as ErrorCode, + Revoked: 'revoked' as ErrorCode, + UnexpectedReplay: 'unexpected_replay' as ErrorCode, + InvalidToken: 'invalid_token' as ErrorCode, + WrongTokenType: 'wrong_token_type' as ErrorCode, + InsufficientScope: 'insufficient_scope' as ErrorCode +}; + diff --git a/devolutions-gateway/src/api/config.rs b/devolutions-gateway/src/api/config.rs index 5a4c00c51a..0de039d00e 100644 --- a/devolutions-gateway/src/api/config.rs +++ b/devolutions-gateway/src/api/config.rs @@ -22,10 +22,10 @@ const KEY_ALLOWLIST: &[&str] = &["Id", "SubProvisionerPublicKey", "Subscriber"]; request_body(content = ConfigPatch, description = "JSON-encoded configuration patch", content_type = "application/json"), responses( (status = 200, description = "Configuration has been patched with success"), - (status = 400, description = "Bad patch request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Failed to patch configuration"), + (status = 400, description = "Bad patch request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Failed to patch configuration", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.config.write"])), ))] diff --git a/devolutions-gateway/src/api/diagnostics.rs b/devolutions-gateway/src/api/diagnostics.rs index 2bc44a2735..513c55f393 100644 --- a/devolutions-gateway/src/api/diagnostics.rs +++ b/devolutions-gateway/src/api/diagnostics.rs @@ -111,6 +111,7 @@ impl ClockDiagnostic { path = "/jet/diagnostics/logs", responses( (status = 200, description = "Latest logs", body = String), + // No error body declared: generated clients pick the first JSON media type of all responses, and would expect JSON on success. (status = 400, description = "Bad request"), (status = 401, description = "Invalid or missing authorization token"), (status = 403, description = "Insufficient permissions"), @@ -150,9 +151,9 @@ async fn get_logs( path = "/jet/diagnostics/configuration", responses( (status = 200, description = "Service configuration diagnostic (including version)", body = ConfigDiagnostic), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.diagnostics.read"])), ))] diff --git a/devolutions-gateway/src/api/heartbeat.rs b/devolutions-gateway/src/api/heartbeat.rs index 19cf2c52a8..bfd47e757f 100644 --- a/devolutions-gateway/src/api/heartbeat.rs +++ b/devolutions-gateway/src/api/heartbeat.rs @@ -104,9 +104,9 @@ impl NoDiskState { path = "/jet/heartbeat", responses( (status = 200, description = "Heartbeat for this Gateway", body = Heartbeat), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.heartbeat.read"])), ))] diff --git a/devolutions-gateway/src/api/jrec/mod.rs b/devolutions-gateway/src/api/jrec/mod.rs index 4dfa03784c..967fc85fa5 100644 --- a/devolutions-gateway/src/api/jrec/mod.rs +++ b/devolutions-gateway/src/api/jrec/mod.rs @@ -226,11 +226,11 @@ const RECORDING_ENDED_CLOSE_CODE: u16 = 4011; ), responses( (status = 200, description = "Recording matching the ID in the path has been deleted"), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 404, description = "The specified recording was not found"), - (status = 409, description = "The recording is still ongoing and can't be deleted yet"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 404, description = "The specified recording was not found", body = ApiError, content_type = "application/problem+json"), + (status = 409, description = "The recording is still ongoing and can't be deleted yet", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.recording.delete"])), ))] @@ -296,11 +296,11 @@ pub(crate) struct DeleteManyResult { request_body(content = Vec, description = "JSON-encoded list of session IDs", content_type = "application/json"), responses( (status = 200, description = "Mass recording deletion task was successfully started", body = DeleteManyResult), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 409, description = "A recording is still ongoing and can't be deleted yet (nothing is deleted)"), - (status = 413, description = "Request payload is too large"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 409, description = "A recording is still ongoing and can't be deleted yet (nothing is deleted)", body = ApiError, content_type = "application/problem+json"), + (status = 413, description = "Request payload is too large", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.recording.delete"])), ))] @@ -455,9 +455,9 @@ async fn delete_recording(recording_path: &Utf8Path) -> anyhow::Result<()> { ), responses( (status = 200, description = "List of recordings on this Gateway instance", body = [Uuid]), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.recordings.read"])), ))] @@ -521,6 +521,7 @@ pub(crate) async fn list_recordings( ), responses( (status = 200, description = "ZIP archive containing the recording session", body = Vec, content_type = "application/zip"), + // No error body declared: generated clients pick the first JSON media type of all responses, and would expect JSON on success. (status = 401, description = "Invalid or missing authorization token"), (status = 403, description = "Insufficient permissions"), (status = 404, description = "Recording not found"), @@ -594,10 +595,10 @@ pub(crate) async fn pull_recording_session( "application/octet-stream", ], ), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 404, description = "File not found"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 404, description = "File not found", body = ApiError, content_type = "application/problem+json"), ), security(("jrec_token" = ["pull"])), ))] diff --git a/devolutions-gateway/src/api/jrec/search.rs b/devolutions-gateway/src/api/jrec/search.rs index 4d4a0cf2e3..266b6e649e 100644 --- a/devolutions-gateway/src/api/jrec/search.rs +++ b/devolutions-gateway/src/api/jrec/search.rs @@ -185,9 +185,9 @@ pub(crate) struct RecordingSearchHit { request_body(content = RecordingSearchRequest, description = "JSON-encoded search request", content_type = "application/json"), responses( (status = 200, description = "Matching log lines", body = RecordingSearchResponse), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.recordings.search"])), ))] diff --git a/devolutions-gateway/src/api/jrl.rs b/devolutions-gateway/src/api/jrl.rs index d95f29af68..1888fdb1a5 100644 --- a/devolutions-gateway/src/api/jrl.rs +++ b/devolutions-gateway/src/api/jrl.rs @@ -24,10 +24,10 @@ pub fn make_router(state: DgwState) -> Router { path = "/jet/jrl", responses( (status = 200, description = "JRL updated successfully"), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Failed to update the JRL"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Failed to update the JRL", body = ApiError, content_type = "application/problem+json"), ), security(("jrl_token" = [])), ))] @@ -91,10 +91,10 @@ pub(crate) struct JrlInfo { path = "/jet/jrl/info", responses( (status = 200, description = "Current JRL Info", body = JrlInfo), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Failed to update the JRL"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Failed to update the JRL", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.jrl.read"])), ))] diff --git a/devolutions-gateway/src/api/monitoring.rs b/devolutions-gateway/src/api/monitoring.rs index 5e252574f2..2cc1436f2a 100644 --- a/devolutions-gateway/src/api/monitoring.rs +++ b/devolutions-gateway/src/api/monitoring.rs @@ -34,10 +34,10 @@ pub fn make_router(state: DgwState) -> Router { request_body(content = MonitorsConfig, description = "JSON object containing a list of monitors", content_type = "application/json"), responses( (status = 200, description = "New configuration was accepted, but not necessarily fully understood.", body = SetConfigResponse), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Unexpected server error while starting monitors"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error while starting monitors", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.net.monitor.config"])), ))] @@ -67,10 +67,10 @@ async fn handle_set_monitoring_config( path = "/jet/net/monitor/log/drain", responses( (status = 200, description = "Log was flushed and returned in the response body", body = MonitoringLogResponse), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Unexpected server error"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.net.monitor.drain"])), ))] diff --git a/devolutions-gateway/src/api/net.rs b/devolutions-gateway/src/api/net.rs index c5d2d45acf..f51628f498 100644 --- a/devolutions-gateway/src/api/net.rs +++ b/devolutions-gateway/src/api/net.rs @@ -48,10 +48,11 @@ pub fn make_router(state: DgwState) -> Router { params(NetworkScanQueryParams), responses( (status = 101, description = "WebSocket upgrade; subsequent text frames carry NetworkScanResultEvent or LegacyScanEvent JSON"), + // Query validation errors carry their own JSON body, not ApiError. (status = 400, description = "Invalid query, mixed target/range, oversized range, or selected interface error"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Unexpected server error"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("netscan_token" = [])), ))] @@ -646,10 +647,10 @@ impl TryFrom for (NetworkScannerParams, ScanEventFilter) path = "/jet/net/config", responses( (status = 200, description = "Network interfaces", body = [HashMap>]), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Unexpected server error"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("netscan_token" = [])), ))] @@ -710,10 +711,10 @@ pub(crate) async fn get_net_config(_token: crate::extract::NetScanToken) -> Resu path = "/jet/net/interfaces", responses( (status = 200, description = "Gateway network scan sources", body = NetworkInterfacesResponse), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Unexpected server error"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("netscan_token" = [])), ))] diff --git a/devolutions-gateway/src/api/preflight.rs b/devolutions-gateway/src/api/preflight.rs index 1477f737d2..769a760879 100644 --- a/devolutions-gateway/src/api/preflight.rs +++ b/devolutions-gateway/src/api/preflight.rs @@ -193,9 +193,9 @@ impl Outputs { request_body = [PreflightOperation], responses( (status = 200, description = "Preflight outputs", body = [PreflightOutput]), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.preflight"])), ))] diff --git a/devolutions-gateway/src/api/session.rs b/devolutions-gateway/src/api/session.rs index 19d7d45c4e..0b75a49f06 100644 --- a/devolutions-gateway/src/api/session.rs +++ b/devolutions-gateway/src/api/session.rs @@ -25,11 +25,11 @@ pub fn make_router(state: DgwState) -> Router { ), responses( (status = 200, description = "Session terminated successfully"), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 404, description = "No running session found with provided ID"), - (status = 500, description = "Unexpected server error"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 404, description = "No running session found with provided ID", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.session.terminate"])), ))] diff --git a/devolutions-gateway/src/api/sessions.rs b/devolutions-gateway/src/api/sessions.rs index 37116ec67e..5b9b1f195d 100644 --- a/devolutions-gateway/src/api/sessions.rs +++ b/devolutions-gateway/src/api/sessions.rs @@ -19,10 +19,10 @@ pub fn make_router(state: DgwState) -> Router { path = "/jet/sessions", responses( (status = 200, description = "Running sessions", body = [SessionInfo]), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Unexpected server error"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.sessions.read"])), ))] diff --git a/devolutions-gateway/src/api/tasks/recording_ai_analysis.rs b/devolutions-gateway/src/api/tasks/recording_ai_analysis.rs index 00a9fcd963..cf375260e8 100644 --- a/devolutions-gateway/src/api/tasks/recording_ai_analysis.rs +++ b/devolutions-gateway/src/api/tasks/recording_ai_analysis.rs @@ -347,12 +347,12 @@ fn ai_analysis_conflict(code: AiAnalysisConflictCode, task_id: Option) -> (status = 202, description = "The AI analysis Task is created and runs in the background", body = AiAnalysisTask, headers( ("Location" = String, description = "Path of the new Task, `/jet/tasks/recording-ai-analysis/{task_id}`"), )), - (status = 400, description = "Invalid request body, AI settings or language"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 404, description = "The session has no recording"), + (status = 400, description = "Invalid request body, AI settings or language", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 404, description = "The session has no recording", body = ApiError, content_type = "application/problem+json"), (status = 409, description = "The AI analysis cannot start now", body = AiAnalysisConflict), - (status = 500, description = "Unexpected server error"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.tasks.recording-ai-analysis.start"])), ))] @@ -443,11 +443,11 @@ pub(crate) async fn start_ai_analysis( ), responses( (status = 200, description = "The AI analysis Task", body = AiAnalysisTask), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 404, description = "No AI analysis has this Task ID"), - (status = 500, description = "Unexpected server error"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 404, description = "No AI analysis has this Task ID", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.tasks.recording-ai-analysis.read"])), ))] diff --git a/devolutions-gateway/src/api/traffic.rs b/devolutions-gateway/src/api/traffic.rs index 0a71436a8b..324b7e8a5d 100644 --- a/devolutions-gateway/src/api/traffic.rs +++ b/devolutions-gateway/src/api/traffic.rs @@ -31,10 +31,10 @@ pub fn make_router(state: crate::DgwState) -> Router { ), responses( (status = 200, description = "Successfully claimed traffic events", body = Vec), - (status = 400, description = "Invalid query parameters"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Internal server error"), + (status = 400, description = "Invalid query parameters", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Internal server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.traffic.claim"])), ))] @@ -89,11 +89,11 @@ pub(crate) async fn post_traffic_claim( request_body(content = AckRequest, description = "Array of event IDs to acknowledge", content_type = "application/json"), responses( (status = 200, description = "Successfully acknowledged events", body = AckResponse), - (status = 400, description = "Invalid request body (empty ids array)"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 413, description = "Payload too large (more than 10,000 IDs)"), - (status = 500, description = "Internal server error"), + (status = 400, description = "Invalid request body (empty ids array)", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 413, description = "Payload too large (more than 10,000 IDs)", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Internal server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.traffic.ack"])), ))] diff --git a/devolutions-gateway/src/api/tunnel.rs b/devolutions-gateway/src/api/tunnel.rs index f5ff604a10..10a29f7778 100644 --- a/devolutions-gateway/src/api/tunnel.rs +++ b/devolutions-gateway/src/api/tunnel.rs @@ -100,10 +100,10 @@ pub fn make_router(state: DgwState) -> Router { request_body(content = EnrollRequest, description = "Agent identity and certificate signing request", content_type = "application/json"), responses( (status = 200, description = "Agent enrolled", body = EnrollResponse), - (status = 400, description = "Invalid agent name, request body, or certificate signing request"), - (status = 401, description = "Invalid or missing enrollment token"), - (status = 409, description = "Agent ID or name already registered, agent key previously deleted, or enrollment token already used"), - (status = 500, description = "Unexpected server error"), + (status = 400, description = "Invalid agent name, request body, or certificate signing request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing enrollment token", body = ApiError, content_type = "application/problem+json"), + (status = 409, description = "Agent ID or name already registered, agent key previously deleted, or enrollment token already used", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("enrollment_token" = [])), ))] @@ -282,9 +282,9 @@ fn agent_info( path = "/jet/tunnel/agents", responses( (status = 200, description = "Accepted agents and their current status", body = [AgentInfo]), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Unexpected server error"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.agent.read"])), ))] @@ -322,10 +322,10 @@ pub(crate) async fn list_agents( ), responses( (status = 200, description = "Agent status", body = AgentInfo), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 404, description = "Agent not found"), - (status = 500, description = "Unexpected server error"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 404, description = "Agent not found", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.agent.read"])), ))] @@ -361,10 +361,10 @@ pub(crate) async fn get_agent( ), responses( (status = 204, description = "Agent deleted"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 404, description = "Agent not found"), - (status = 500, description = "Unexpected server error"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 404, description = "Agent not found", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Unexpected server error", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.agent.delete"])), ))] diff --git a/devolutions-gateway/src/api/update.rs b/devolutions-gateway/src/api/update.rs index ae1f832acb..a2c9bce46f 100644 --- a/devolutions-gateway/src/api/update.rs +++ b/devolutions-gateway/src/api/update.rs @@ -298,11 +298,11 @@ fn apply_products(req: UpdateRequest, manifest: &mut UpdateManifestV2, was_v2: b request_body(content = Option, description = "Products and target versions to update", content_type = "application/json"), responses( (status = 200, description = "Update request accepted", body = UpdateResponse), - (status = 400, description = "Bad request"), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Failed to write update manifest"), - (status = 503, description = "Agent updater service is unavailable"), + (status = 400, description = "Bad request", body = ApiError, content_type = "application/problem+json"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Failed to write update manifest", body = ApiError, content_type = "application/problem+json"), + (status = 503, description = "Agent updater service is unavailable", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.update"])), ))] @@ -386,10 +386,10 @@ pub(crate) struct GetUpdateProductsResponse { path = "/jet/update", responses( (status = 200, description = "Installed product versions", body = GetUpdateProductsResponse), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Failed to read agent status file"), - (status = 503, description = "Agent updater service is unavailable"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Failed to read agent status file", body = ApiError, content_type = "application/problem+json"), + (status = 503, description = "Agent updater service is unavailable", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.update.read"])), ))] @@ -505,10 +505,10 @@ pub(crate) struct SetUpdateScheduleResponse {} path = "/jet/update/schedule", responses( (status = 200, description = "Current auto-update schedule", body = GetUpdateScheduleResponse), - (status = 401, description = "Invalid or missing authorization token"), - (status = 403, description = "Insufficient permissions"), - (status = 500, description = "Failed to read agent status file"), - (status = 503, description = "Agent updater service is unavailable"), + (status = 401, description = "Invalid or missing authorization token", body = ApiError, content_type = "application/problem+json"), + (status = 403, description = "Insufficient permissions", body = ApiError, content_type = "application/problem+json"), + (status = 500, description = "Failed to read agent status file", body = ApiError, content_type = "application/problem+json"), + (status = 503, description = "Agent updater service is unavailable", body = ApiError, content_type = "application/problem+json"), ), security(("scope_token" = ["gateway.update.read"])), ))] @@ -558,11 +558,11 @@ pub(super) async fn get_update_schedule(_scope: UpdateReadScope) -> Result $code:literal, + )+ + ) => { + /// Machine-readable reason for a rejected request. + /// + /// Only the code leaves the Gateway. + /// The details explaining it (error sources, key names, claim values…) are logged, never sent. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum ErrorCode { + $( + $( #[doc = $doc] )+ + $variant, + )+ + } + + impl ErrorCode { + /// All the codes, in declaration order. + pub const ALL: &[Self] = &[$( Self::$variant ),+]; + + /// Returns the snake_case string sent to clients. + pub const fn as_str(self) -> &'static str { + match self { + $( Self::$variant => $code, )+ + } + } + + /// Returns a one-sentence description of the code, for documentation purposes. + pub const fn description(self) -> &'static str { + match self { + $( Self::$variant => concat!($( $doc ),+).trim_ascii(), )+ + } + } + } + }; +} + +// Append new codes at the end: generated clients number enum members by position. +// Keep each description on a single line. +define_error_codes! { + // -- Generic codes, used when no specific code applies -- // + + /// The request is invalid. + BadRequest => "bad_request", + /// The request is not authenticated. + Unauthorized => "unauthorized", + /// The request is not allowed. + Forbidden => "forbidden", + /// The resource doesn't exist. + NotFound => "not_found", + /// The request took too long to complete. + RequestTimeout => "request_timeout", + /// The request conflicts with the current state of the resource. + Conflict => "conflict", + /// The request is too large. + PayloadTooLarge => "payload_too_large", + /// The Gateway failed to process the request. + InternalError => "internal_error", + /// The Gateway received an invalid response from an upstream server. + BadGateway => "bad_gateway", + /// The service is temporarily unavailable. + ServiceUnavailable => "service_unavailable", + /// An upstream server didn't respond in time. + GatewayTimeout => "gateway_timeout", + /// The Gateway is out of storage space. + InsufficientStorage => "insufficient_storage", + + // -- Token and authorization codes -- // + + /// No token was found in the `Authorization` header or in the `token` query parameter. + MissingToken => "missing_token", + /// The token can't be decoded or decrypted, or its claims don't match the schema expected for its type. + MalformedToken => "malformed_token", + /// The token signature doesn't match the provisioner key of the Gateway. + BadSignature => "bad_signature", + /// The token refers to a key ID (`kid`) that doesn't match the sub provisioner key of the Gateway. + UnknownSubkey => "unknown_subkey", + /// The token has expired (`exp` claim); the clocks of the token issuer and of the Gateway may be out of sync. + Expired => "expired", + /// The token is not valid yet (`nbf` claim); the clocks of the token issuer and of the Gateway may be out of sync. + NotYetValid => "not_yet_valid", + /// The token is restricted to another Gateway ID (`jet_gw_id` claim). + GatewayIdMismatch => "gateway_id_mismatch", + /// The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. + Revoked => "revoked", + /// The token was already used, and can't be used again in this context. + UnexpectedReplay => "unexpected_replay", + /// The token is rejected for a reason not covered by another code. + InvalidToken => "invalid_token", + /// The type of the token is not accepted by this route. + WrongTokenType => "wrong_token_type", + /// The scope of the token doesn't grant access to this route. + InsufficientScope => "insufficient_scope", +} + +impl fmt::Display for ErrorCode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +impl serde::Serialize for ErrorCode { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(self.as_str()) + } +} + +#[cfg(feature = "openapi")] +impl<'s> utoipa::ToSchema<'s> for ErrorCode { + fn schema() -> (&'s str, utoipa::openapi::RefOr) { + use core::fmt::Write as _; + + use utoipa::openapi::schema::{ObjectBuilder, SchemaType}; + + let mut description = String::from( + "Machine-readable reason for a rejected request.\n\n\ + New codes can be added, but existing codes are never renamed or removed. \ + Clients must treat unknown codes as generic failures.\n", + ); + + for code in Self::ALL { + let _ = write!(description, "\n- `{}`: {}", code.as_str(), code.description()); + } + + let schema = ObjectBuilder::new() + .schema_type(SchemaType::String) + .description(Some(description)) + .enum_values(Some(Self::ALL.iter().map(|code| code.as_str()))) + .build(); + + ("ErrorCode", schema.into()) + } +} + +#[cfg(test)] +mod tests { + use expect_test::expect; + + use super::*; + + /// Codes are public API: existing codes are never renamed or removed, and new codes are appended. + // oracle: spec docs/API-spec.md §errors + #[test] + fn codes_are_stable() { + let codes = ErrorCode::ALL + .iter() + .map(|code| code.as_str()) + .collect::>() + .join("\n"); + + expect![[r#" + bad_request + unauthorized + forbidden + not_found + request_timeout + conflict + payload_too_large + internal_error + bad_gateway + service_unavailable + gateway_timeout + insufficient_storage + missing_token + malformed_token + bad_signature + unknown_subkey + expired + not_yet_valid + gateway_id_mismatch + revoked + unexpected_replay + invalid_token + wrong_token_type + insufficient_scope"#]] + .assert_eq(&codes); + } +} diff --git a/devolutions-gateway/src/extract.rs b/devolutions-gateway/src/extract.rs index 4f5f1549ae..60819c5e56 100644 --- a/devolutions-gateway/src/extract.rs +++ b/devolutions-gateway/src/extract.rs @@ -5,6 +5,7 @@ use axum::extract::{ConnectInfo, FromRequest, FromRequestParts, Path, RawQuery, use axum::http::request::Parts; use crate::DgwState; +use crate::error_code::ErrorCode; use crate::http::HttpError; use crate::token::{ AccessScope, AccessTokenClaims, AssociationTokenClaims, BridgeTokenClaims, EnrollmentTokenClaims, JmuxTokenClaims, @@ -42,7 +43,9 @@ where if let AccessTokenClaims::Association(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected ASSOCIATION)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected ASSOCIATION)")) } } } @@ -60,7 +63,9 @@ where if let AccessTokenClaims::Jrl(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected JRL)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected JRL)")) } } } @@ -78,7 +83,9 @@ where if let AccessTokenClaims::Jrec(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected JREC)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected JREC)")) } } } @@ -96,7 +103,9 @@ where if let AccessTokenClaims::Jmux(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected JMUX)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected JMUX)")) } } } @@ -132,11 +141,13 @@ impl FromRequestParts for KdcToken { &state.recordings.active_recordings, None, ) - .map_err(HttpError::unauthorized().err())?; + .map_err(|error| HttpError::unauthorized().with_error_code(error.code()).build(error))?; match claims { AccessTokenClaims::Kdc(claims) => Ok(Self(claims)), - _ => Err(HttpError::forbidden().msg("token not allowed (expected KDC token)")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected KDC token)")), } } } @@ -154,7 +165,9 @@ where if let AccessTokenClaims::Scope(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected SCOPE)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected SCOPE)")) } } } @@ -172,7 +185,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::SessionsRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -190,7 +205,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::SessionTerminate => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -208,7 +225,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::AssociationsRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -226,7 +245,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::DiagnosticsRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -244,7 +265,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::JrlRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -262,7 +285,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::ConfigWrite => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -280,7 +305,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::HeartbeatRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -298,7 +325,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::RecordingDelete => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -316,7 +345,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::RecordingsRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -335,7 +366,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::RecordingAiAnalysisStart => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -354,7 +387,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::RecordingAiAnalysisRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -372,7 +407,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::RecordingsSearch => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -390,7 +427,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::Update => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -410,7 +449,9 @@ where // The full write scope also grants read access. AccessScope::Update => Ok(Self), AccessScope::UpdateRead => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -428,7 +469,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::Preflight => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -446,7 +489,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::TrafficClaim => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -464,7 +509,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::TrafficAck => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -482,7 +529,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::NetMonitorConfig => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -500,7 +549,9 @@ where match ScopeToken::from_request_parts(parts, state).await?.0.scope { AccessScope::Wildcard => Ok(Self), AccessScope::NetMonitorDrain => Ok(Self), - _ => Err(HttpError::forbidden().msg("invalid scope for route")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) + .msg("invalid scope for route")), } } } @@ -527,9 +578,12 @@ where AccessTokenClaims::Scope(scope) => match scope.scope { AccessScope::Wildcard | AccessScope::AgentRead => Ok(Self), _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) .msg("invalid scope for agent management read (require one of: gateway.agent.read, *)")), }, - _ => Err(HttpError::forbidden().msg("scope token required for agent management read")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("scope token required for agent management read")), } } } @@ -556,9 +610,12 @@ where AccessTokenClaims::Scope(scope) => match scope.scope { AccessScope::Wildcard | AccessScope::AgentDelete => Ok(Self), _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::InsufficientScope) .msg("invalid scope for agent management delete (require one of: gateway.agent.delete, *)")), }, - _ => Err(HttpError::forbidden().msg("scope token required for agent management delete")), + _ => Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("scope token required for agent management delete")), } } } @@ -576,7 +633,9 @@ where if let AccessTokenClaims::WebApp(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected WEBAPP)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected WEBAPP)")) } } } @@ -594,7 +653,9 @@ where if let AccessTokenClaims::NetScan(_) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self) } else { - Err(HttpError::forbidden().msg("token not allowed (expected NETSCAN)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected NETSCAN)")) } } } @@ -612,7 +673,9 @@ where if let AccessTokenClaims::Bridge(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected BRIDGE)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected BRIDGE)")) } } } @@ -631,7 +694,9 @@ where if let AccessTokenClaims::Enrollment(claims) = AccessToken::from_request_parts(parts, state).await?.0 { Ok(Self(claims)) } else { - Err(HttpError::forbidden().msg("token not allowed (expected ENROLLMENT token)")) + Err(HttpError::forbidden() + .with_error_code(ErrorCode::WrongTokenType) + .msg("token not allowed (expected ENROLLMENT token)")) } } } diff --git a/devolutions-gateway/src/http.rs b/devolutions-gateway/src/http.rs index 5a85b9b8c4..01d60dce16 100644 --- a/devolutions-gateway/src/http.rs +++ b/devolutions-gateway/src/http.rs @@ -2,13 +2,17 @@ use core::fmt; use core::panic::Location; use std::error::Error as StdError; -use axum::http::StatusCode; +use axum::Json; +use axum::http::{HeaderValue, StatusCode, header}; use axum::response::{IntoResponse, Response}; +use crate::error_code::ErrorCode; + pub struct HttpErrorBuilder { pub code: StatusCode, pub loc: &'static Location<'static>, pub msg: Option<&'static str>, + pub error_code: Option, } impl HttpErrorBuilder { @@ -19,6 +23,7 @@ impl HttpErrorBuilder { code, loc: Location::caller(), msg: None, + error_code: None, } } @@ -28,6 +33,7 @@ impl HttpErrorBuilder { code: self.code, loc: self.loc, msg: self.msg, + error_code: self.error_code, source: Some(source.into()), } } @@ -38,6 +44,7 @@ impl HttpErrorBuilder { code: self.code, loc: self.loc, msg: self.msg, + error_code: self.error_code, source: Some(source.into()), } } @@ -49,12 +56,23 @@ impl HttpErrorBuilder { self } + /// Sets the machine-readable code sent to the client. + /// + /// Without one, the response carries the generic code matching the HTTP status. + #[inline] + #[must_use] + pub fn with_error_code(mut self, error_code: ErrorCode) -> HttpErrorBuilder { + self.error_code = Some(error_code); + self + } + #[inline] pub fn msg(self, msg: &'static str) -> HttpError { HttpError { code: self.code, loc: self.loc, msg: Some(msg), + error_code: self.error_code, source: None, } } @@ -63,7 +81,11 @@ impl HttpErrorBuilder { pub struct HttpError { pub code: StatusCode, pub loc: &'static Location<'static>, + /// Internal context, logged but never sent to the client. pub msg: Option<&'static str>, + /// Machine-readable code sent to the client. + pub error_code: Option, + /// Internal error, logged but never sent to the client. pub source: Option>, } @@ -127,8 +149,122 @@ impl fmt::Display for HttpError { impl IntoResponse for HttpError { fn into_response(self) -> Response { - error!(error = %self); - self.code.into_response() + let error_code = self.error_code.unwrap_or_else(|| generic_error_code(self.code)); + error!(error = %self, %error_code); + ApiError::new(self.code, error_code).into_response() + } +} + +/// Returns the code describing an HTTP status, for errors without a more specific code. +fn generic_error_code(status: StatusCode) -> ErrorCode { + match status { + StatusCode::BAD_REQUEST => ErrorCode::BadRequest, + StatusCode::UNAUTHORIZED => ErrorCode::Unauthorized, + StatusCode::FORBIDDEN => ErrorCode::Forbidden, + StatusCode::NOT_FOUND => ErrorCode::NotFound, + StatusCode::REQUEST_TIMEOUT => ErrorCode::RequestTimeout, + StatusCode::CONFLICT => ErrorCode::Conflict, + StatusCode::PAYLOAD_TOO_LARGE => ErrorCode::PayloadTooLarge, + StatusCode::INTERNAL_SERVER_ERROR => ErrorCode::InternalError, + StatusCode::BAD_GATEWAY => ErrorCode::BadGateway, + StatusCode::SERVICE_UNAVAILABLE => ErrorCode::ServiceUnavailable, + StatusCode::GATEWAY_TIMEOUT => ErrorCode::GatewayTimeout, + StatusCode::INSUFFICIENT_STORAGE => ErrorCode::InsufficientStorage, + _ if status.is_client_error() => ErrorCode::BadRequest, + _ => ErrorCode::InternalError, + } +} + +// Only the code is sent to the client: never add internal details, such as error sources or claim values. +// The `utoipa::path` annotations of the API handlers refer to this schema by name, without importing it. + +/// Body of an API error response, as defined by RFC 9457 (problem details for HTTP APIs). +/// +/// The Gateway logs the details of the error, along with its code. +#[derive(Debug, Clone, Serialize)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[cfg_attr(feature = "openapi", schema( + example = json!({ "type": "about:blank", "title": "Unauthorized", "status": 401, "error": "gateway_id_mismatch" }) +))] +pub struct ApiError { + /// Problem type, always `about:blank`: the HTTP status and the error code describe the problem. + #[serde(rename = "type")] + problem_type: &'static str, + /// Reason phrase of the HTTP status. + title: &'static str, + /// HTTP status code. + #[serde(serialize_with = "serialize_status")] + #[cfg_attr(feature = "openapi", schema(value_type = u16))] + status: StatusCode, + /// Machine-readable error code; the `ErrorCode` schema lists the known values. + /// + /// New codes can be added: treat unknown values as generic failures. + // Typed as a string in the OpenAPI document, so that generated clients keep parsing the body when they get an unknown code. + #[cfg_attr(feature = "openapi", schema(value_type = String))] + error: ErrorCode, +} + +impl ApiError { + pub const CONTENT_TYPE: &'static str = "application/problem+json"; + + pub fn new(status: StatusCode, error: ErrorCode) -> Self { + Self { + problem_type: "about:blank", + title: status.canonical_reason().unwrap_or("Unknown"), + status, + error, + } + } +} + +impl IntoResponse for ApiError { + fn into_response(self) -> Response { + let status = self.status; + let challenge = bearer_challenge(self.error); + + let mut response = (status, Json(self)).into_response(); + + let headers = response.headers_mut(); + headers.insert(header::CONTENT_TYPE, HeaderValue::from_static(Self::CONTENT_TYPE)); + if let Some(challenge) = challenge { + headers.insert(header::WWW_AUTHENTICATE, HeaderValue::from_static(challenge)); + } + + response + } +} + +fn serialize_status(status: &StatusCode, serializer: S) -> Result { + serializer.serialize_u16(status.as_u16()) +} + +/// Returns the `WWW-Authenticate` challenge for a rejected bearer token, as described by RFC 6750. +fn bearer_challenge(error_code: ErrorCode) -> Option<&'static str> { + match error_code { + ErrorCode::MissingToken => Some("Bearer"), + ErrorCode::MalformedToken + | ErrorCode::BadSignature + | ErrorCode::UnknownSubkey + | ErrorCode::Expired + | ErrorCode::NotYetValid + | ErrorCode::GatewayIdMismatch + | ErrorCode::Revoked + | ErrorCode::UnexpectedReplay + | ErrorCode::InvalidToken => Some(r#"Bearer error="invalid_token""#), + ErrorCode::InsufficientScope => Some(r#"Bearer error="insufficient_scope""#), + ErrorCode::BadRequest + | ErrorCode::Unauthorized + | ErrorCode::Forbidden + | ErrorCode::NotFound + | ErrorCode::RequestTimeout + | ErrorCode::Conflict + | ErrorCode::PayloadTooLarge + | ErrorCode::InternalError + | ErrorCode::BadGateway + | ErrorCode::ServiceUnavailable + | ErrorCode::GatewayTimeout + | ErrorCode::InsufficientStorage + | ErrorCode::WrongTokenType => None, } } diff --git a/devolutions-gateway/src/lib.rs b/devolutions-gateway/src/lib.rs index 56dca423a6..551df3010a 100644 --- a/devolutions-gateway/src/lib.rs +++ b/devolutions-gateway/src/lib.rs @@ -18,6 +18,7 @@ pub mod cli; pub mod config; pub mod credential; pub mod credential_injection; +pub mod error_code; pub mod extract; pub mod generic_client; pub mod http; @@ -167,7 +168,10 @@ pub fn make_http_service(state: DgwState) -> axum::Router<()> { )) // This middleware goes above `TimeoutLayer` because it will receive errors returned by `TimeoutLayer`. .layer(HandleErrorLayer::new(|_: axum::BoxError| async { - hyper::StatusCode::REQUEST_TIMEOUT + http::ApiError::new( + hyper::StatusCode::REQUEST_TIMEOUT, + error_code::ErrorCode::RequestTimeout, + ) })) .layer(TimeoutLayer::new(Duration::from_secs(15))), ) diff --git a/devolutions-gateway/src/middleware/auth.rs b/devolutions-gateway/src/middleware/auth.rs index c96462254b..7b1578288f 100644 --- a/devolutions-gateway/src/middleware/auth.rs +++ b/devolutions-gateway/src/middleware/auth.rs @@ -11,6 +11,7 @@ use axum_extra::headers::Authorization; use axum_extra::headers::authorization::Bearer; use crate::config::Conf; +use crate::error_code::ErrorCode; use crate::http::HttpError; use crate::recording::ActiveRecordings; use crate::session::DisconnectedInfo; @@ -135,6 +136,7 @@ pub async fn auth_middleware( let Ok(query) = serde_urlencoded::from_str::>(query) else { return Err(HttpError::unauthorized() + .with_error_code(ErrorCode::MissingToken) .msg("both authorization header and token query param invalid or missing")); }; @@ -163,19 +165,22 @@ pub async fn auth_middleware( let access_token_claims = match result { Ok(access_token_claims) => access_token_claims, Err(error) => { + // The event log entry carries the same code as the response. + let error_code = error.code(); + match &error { crate::token::TokenError::SignatureVerification { source, key } => { let _ = SYSTEM_LOGGER.emit( - sysevent_codes::jwt_rejected("bad_signature", format!("{source:#}")).field("key", key), + sysevent_codes::jwt_rejected(error_code.as_str(), format!("{source:#}")).field("key", key), ); } crate::token::TokenError::UnexpectedReplay { reason } => { - let _ = SYSTEM_LOGGER.emit(sysevent_codes::jwt_rejected("unexpected_replay", reason)); + let _ = SYSTEM_LOGGER.emit(sysevent_codes::jwt_rejected(error_code.as_str(), reason)); } _ => {} } - return Err(HttpError::unauthorized().err()(error)); + return Err(HttpError::unauthorized().with_error_code(error_code).build(error)); } }; diff --git a/devolutions-gateway/src/openapi.rs b/devolutions-gateway/src/openapi.rs index e1166a9396..fb91702ea9 100644 --- a/devolutions-gateway/src/openapi.rs +++ b/devolutions-gateway/src/openapi.rs @@ -139,6 +139,8 @@ use crate::provisioner_tasks::recording_ai_analysis::{BadAnswer, Failure, Recove crate::api::tunnel::AgentDomainAdvertisement, crate::api::tunnel::AgentStatus, crate::api::tunnel::AgentInfo, + crate::http::ApiError, + crate::error_code::ErrorCode, )), modifiers(&SecurityAddon), )] diff --git a/devolutions-gateway/src/token.rs b/devolutions-gateway/src/token.rs index d645c2e095..c8b95054b7 100644 --- a/devolutions-gateway/src/token.rs +++ b/devolutions-gateway/src/token.rs @@ -16,6 +16,7 @@ use smol_str::SmolStr; use thiserror::Error; use uuid::Uuid; +use crate::error_code::ErrorCode; use crate::recording::ActiveRecordings; use crate::session::DisconnectedInfo; use crate::target_addr::TargetAddr; @@ -899,6 +900,47 @@ pub enum TokenError { TooLongLifetime, } +impl TokenError { + /// Returns the machine-readable code reported to the client. + /// + /// The signature is verified before any claim is checked. + /// Errors raised before the signature check map to `malformed_token`, `bad_signature` or `unknown_subkey`, + /// so a caller without a token signed by a trusted key learns nothing about the claims. + pub fn code(&self) -> ErrorCode { + use picky::jose::jwt::JwtError; + + match self { + // Raised before the signature is verified. + Self::MissingDelegationKey | Self::Jwe { .. } | Self::JwePayload { .. } | Self::Jws { .. } => { + ErrorCode::MalformedToken + } + Self::SignatureVerification { .. } => ErrorCode::BadSignature, + Self::UnknownSubkey { .. } => ErrorCode::UnknownSubkey, + + // Raised after the signature is verified. + Self::Jwt { source } => match source { + JwtError::Expired { .. } => ErrorCode::Expired, + JwtError::NotYetValid { .. } => ErrorCode::NotYetValid, + JwtError::Json { .. } + | JwtError::InvalidRegisteredClaimType { .. } + | JwtError::RequiredClaimMissing { .. } => ErrorCode::MalformedToken, + _ => ErrorCode::InvalidToken, + }, + Self::BadContentType { .. } | Self::MalformedClaim { .. } | Self::InvalidClaimScheme { .. } => { + ErrorCode::MalformedToken + } + Self::GatewayIdScopeMismatch => ErrorCode::GatewayIdMismatch, + Self::Revoked => ErrorCode::Revoked, + Self::UnexpectedReplay { .. } => ErrorCode::UnexpectedReplay, + Self::ContentTypeNotAllowedForSubkey { .. } + | Self::PlaintextSecrets + | Self::OldJrl + | Self::SubkeySignedAndTooLongLifetime + | Self::TooLongLifetime => ErrorCode::InvalidToken, + } + } +} + #[derive(typed_builder::TypedBuilder)] pub struct TokenValidator<'a> { source_ip: IpAddr, @@ -2011,4 +2053,92 @@ mod tests { assert_eq!(recording_file_type.content_type(), expected_content_type); } } + + mod error_code { + use picky::jose::jwe::JweError; + use picky::jose::jws::JwsError; + use picky::jose::jwt::{JwtDate, JwtError}; + use rstest::rstest; + + use super::super::*; + + fn invalid_utf8() -> std::str::Utf8Error { + std::str::from_utf8(std::hint::black_box(&[0xC0])).expect_err("invalid UTF-8") + } + + fn json_error() -> serde_json::Error { + serde_json::from_str::("not JSON").expect_err("invalid JSON") + } + + fn jws_error() -> JwsError { + JwsError::InvalidEncoding { input: String::new() } + } + + // oracle: spec docs/API-spec.md §token-errors + #[rstest] + // Raised before the signature is verified. + #[case::missing_delegation_key(TokenError::MissingDelegationKey, ErrorCode::MalformedToken)] + #[case::jwe(TokenError::Jwe { source: JweError::AesGcm }, ErrorCode::MalformedToken)] + #[case::jwe_payload(TokenError::JwePayload { source: invalid_utf8() }, ErrorCode::MalformedToken)] + #[case::jws(TokenError::Jws { source: jws_error() }, ErrorCode::MalformedToken)] + #[case::signature_verification( + TokenError::SignatureVerification { source: jws_error(), key: "main provisioner key" }, + ErrorCode::BadSignature + )] + #[case::unknown_subkey(TokenError::UnknownSubkey { provided_kid: String::new() }, ErrorCode::UnknownSubkey)] + // Raised after the signature is verified. + #[case::bad_content_type( + TokenError::BadContentType { source: "UNKNOWN".parse::().expect_err("unknown content type") }, + ErrorCode::MalformedToken + )] + #[case::expired( + TokenError::Jwt { source: JwtError::Expired { not_after: 0, now: JwtDate::new(1) } }, + ErrorCode::Expired + )] + #[case::not_yet_valid( + TokenError::Jwt { source: JwtError::NotYetValid { not_before: 1, now: JwtDate::new(0) } }, + ErrorCode::NotYetValid + )] + #[case::required_claim_missing( + TokenError::Jwt { source: JwtError::RequiredClaimMissing { claim: "exp" } }, + ErrorCode::MalformedToken + )] + #[case::invalid_registered_claim_type( + TokenError::Jwt { source: JwtError::InvalidRegisteredClaimType { claim: "exp" } }, + ErrorCode::MalformedToken + )] + #[case::claims_json(TokenError::Jwt { source: JwtError::Json { source: json_error() } }, ErrorCode::MalformedToken)] + #[case::invalid_validator( + TokenError::Jwt { source: JwtError::InvalidValidator { description: "" } }, + ErrorCode::InvalidToken + )] + #[case::content_type_not_allowed_for_subkey( + TokenError::ContentTypeNotAllowedForSubkey { content_type: ContentType::Scope }, + ErrorCode::InvalidToken + )] + #[case::malformed_claim( + TokenError::MalformedClaim { name: "jet_gw_id", source: anyhow::anyhow!("invalid UUID") }, + ErrorCode::MalformedToken + )] + #[case::gateway_id_scope_mismatch(TokenError::GatewayIdScopeMismatch, ErrorCode::GatewayIdMismatch)] + #[case::revoked(TokenError::Revoked, ErrorCode::Revoked)] + #[case::invalid_claim_scheme( + TokenError::InvalidClaimScheme { content_type: ContentType::Scope, source: json_error() }, + ErrorCode::MalformedToken + )] + #[case::plaintext_secrets(TokenError::PlaintextSecrets, ErrorCode::InvalidToken)] + #[case::unexpected_replay( + TokenError::UnexpectedReplay { reason: "different source IP" }, + ErrorCode::UnexpectedReplay + )] + #[case::old_jrl(TokenError::OldJrl, ErrorCode::InvalidToken)] + #[case::subkey_signed_and_too_long_lifetime( + TokenError::SubkeySignedAndTooLongLifetime, + ErrorCode::InvalidToken + )] + #[case::too_long_lifetime(TokenError::TooLongLifetime, ErrorCode::InvalidToken)] + fn token_error_code(#[case] error: TokenError, #[case] expected_code: ErrorCode) { + assert_eq!(error.code(), expected_code); + } + } } diff --git a/devolutions-gateway/tests/webapp.rs b/devolutions-gateway/tests/webapp.rs index 25755d7e0f..5e4a06f983 100644 --- a/devolutions-gateway/tests/webapp.rs +++ b/devolutions-gateway/tests/webapp.rs @@ -258,7 +258,7 @@ async fn sign_app_token_bad_password() -> anyhow::Result<()> { assert_eq!(response.status(), StatusCode::UNAUTHORIZED); let body = response.into_body().collect().await?.to_bytes(); - assert!(body.is_empty()); + assert_unauthorized_body(&body)?; Ok(()) } @@ -296,7 +296,19 @@ async fn sign_app_token_username_mismatch() -> anyhow::Result<()> { assert_eq!(response.status(), StatusCode::UNAUTHORIZED); let body = response.into_body().collect().await?.to_bytes(); - assert!(body.is_empty()); + assert_unauthorized_body(&body)?; + + Ok(()) +} + +/// Asserts that a rejected login carries the generic code only, whatever the reason. +fn assert_unauthorized_body(body: &[u8]) -> anyhow::Result<()> { + let body: serde_json::Value = serde_json::from_slice(body)?; + + assert_eq!( + body, + json!({ "type": "about:blank", "title": "Unauthorized", "status": 401, "error": "unauthorized" }) + ); Ok(()) } diff --git a/docs/API-spec.md b/docs/API-spec.md index 27943ca4df..d0a864574b 100644 --- a/docs/API-spec.md +++ b/docs/API-spec.md @@ -212,6 +212,8 @@ Once jetsocat is successfully connected to the Devolutions Gateway, you can conf ### SCOPE +A SCOPE token is valid for a single request: the Gateway rejects a token it has already accepted with the `unexpected_replay` error code. + #### Claims ```json5 @@ -470,6 +472,69 @@ i.e.: } ``` + +## Errors + +Error responses carry a machine-readable body, following [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) (problem details for HTTP APIs), with the `application/problem+json` content type: + +```json +{ + "type": "about:blank", + "title": "Unauthorized", + "status": 401, + "error": "gateway_id_mismatch" +} +``` + +- `type` is always `about:blank`: the HTTP status and the error code describe the problem. +- `title` is the reason phrase of the HTTP status. +- `status` is the HTTP status code. +- `error` is the error code. + +.NET clients can read the body with the `ProblemDetails` type, which stores the error code in its `Extensions` dictionary, under the `error` key. + +The body never contains internal details, such as error messages, key names or claim values. +The Gateway logs these details along with the error code. + +Error codes are public API. +New codes can be added, but existing codes are never renamed or removed. +Clients must treat unknown codes as generic failures, and rely on the HTTP status. + +When no specific code applies, the error code is derived from the HTTP status: +`bad_request`, `unauthorized`, `forbidden`, `not_found`, `request_timeout`, `conflict`, `payload_too_large`, `internal_error`, `bad_gateway`, `service_unavailable`, `gateway_timeout` or `insufficient_storage`. + +Some errors don't carry this body yet, such as the errors raised while parsing a request body, and the `400` responses of `/jet/net/scan`, which have their own format. + + +### Token and authorization errors + +| Code | Status | Meaning | +|------|--------|---------| +| `missing_token` | 401 | No token was found in the `Authorization` header or in the `token` query parameter. | +| `malformed_token` | 401 | The token can't be decoded or decrypted, or its claims don't match the schema expected for its type. | +| `bad_signature` | 401 | The token signature doesn't match the provisioner key of the Gateway. | +| `unknown_subkey` | 401 | The token refers to a key ID (`kid`) that doesn't match the sub provisioner key of the Gateway. | +| `expired` | 401 | The token has expired (`exp` claim). | +| `not_yet_valid` | 401 | The token is not valid yet (`nbf` claim). | +| `gateway_id_mismatch` | 401 | The token is restricted to another Gateway ID (`jet_gw_id` claim). | +| `revoked` | 401 | The token contains a value revoked by the JSON Revocation List (JRL) of the Gateway. | +| `unexpected_replay` | 401 | The token was already used, and can't be used again in this context. | +| `invalid_token` | 401 | The token is rejected for a reason not covered by another code. | +| `wrong_token_type` | 403 | The type of the token is not accepted by this route. | +| `insufficient_scope` | 403 | The scope of the token doesn't grant access to this route. | + +`expired` and `not_yet_valid` often mean that the clocks of the token issuer and of the Gateway are out of sync: compare them with `GET /jet/diagnostics/clock`. +For `gateway_id_mismatch`, the Gateway reports its ID in `GET /jet/health`, when requested with `Accept: application/json`. + +The Gateway verifies the token signature before checking any claim. +Unless the token is signed by a key the Gateway trusts, the error code is `missing_token`, `malformed_token`, `bad_signature` or `unknown_subkey`. + +Token errors also carry a `WWW-Authenticate` header, as described by [RFC 6750](https://www.rfc-editor.org/rfc/rfc6750): + +- `Bearer` when the token is missing. +- `Bearer error="invalid_token"` when the token is rejected (status 401). +- `Bearer error="insufficient_scope"` when the scope of the token doesn't grant access to the route. + ## OpenAPI Endpoints are documented using [OpenAPI specification](../devolutions-gateway/openapi/doc/index.adoc). diff --git a/testsuite/Cargo.toml b/testsuite/Cargo.toml index 1f47e506db..62c6e1e14a 100644 --- a/testsuite/Cargo.toml +++ b/testsuite/Cargo.toml @@ -18,23 +18,25 @@ harness = true [dependencies] anyhow = "1.0" assert_cmd = "2.2" +base64 = "0.23" dynosaur = "0.3" escargot = "0.5" expect-test = "1.5" fastrand = "2" +picky = { version = "7.0.0-rc.25", default-features = false, features = ["jose"] } serde_json = "1" serde = { version = "1", features = ["derive"] } tempfile = "3" tokio = { version = "1", features = ["rt-multi-thread", "macros", "time", "net", "process"] } tokio-util = "0.7" typed-builder = "0.21" +uuid = { version = "1", features = ["v4"] } tokio-tungstenite = { version = "0.29", features = ["rustls-tls-native-roots"] } [dev-dependencies] agent-sysevent-codes.path = "../crates/agent-sysevent-codes" agent-tunnel = { path = "../crates/agent-tunnel", features = ["test-utils"] } agent-tunnel-proto = { path = "../crates/agent-tunnel-proto", features = ["serde"] } -base64 = "0.23" camino = "1" devolutions-gateway-task = { path = "../crates/devolutions-gateway-task" } devolutions-gateway = { path = "../devolutions-gateway" } @@ -50,7 +52,6 @@ network-scanner = { path = "../crates/network-scanner", features = ["test-utils" network-scanner-proto = { path = "../crates/network-scanner-proto" } nonempty = "0.12" private-fs.path = "../crates/private-fs" -picky = { version = "7.0.0-rc.25", default-features = false, features = ["jose"] } proxy-socks = { path = "../crates/proxy-socks" } quinn = "0.11" rcgen = { version = "0.13", features = ["pem", "x509-parser"] } @@ -66,7 +67,6 @@ tempfile = "3" test-utils.path = "../crates/test-utils" time = { version = "0.3", default-features = false, features = ["std", "parsing"] } tokio-rustls = { version = "0.26", features = ["ring"] } -uuid = { version = "1", features = ["v4"] } [target.'cfg(unix)'.dev-dependencies] # Sets POSIX ACLs in the private-fs tests, which `setfacl` would need a package for. diff --git a/testsuite/src/dgw_config.rs b/testsuite/src/dgw_config.rs index 37d05ef64a..7c012d7346 100644 --- a/testsuite/src/dgw_config.rs +++ b/testsuite/src/dgw_config.rs @@ -59,6 +59,9 @@ impl fmt::Display for ProxyMode { #[derive(TypedBuilder)] pub struct DgwConfig { + /// Gateway ID, matched against the `jet_gw_id` token claim. + #[builder(default, setter(into))] + id: Option, #[builder(default, setter(into))] hostname: Option, #[builder(default = "127.0.0.1".to_owned(), setter(into))] @@ -124,6 +127,7 @@ pub struct DgwConfigHandle { impl DgwConfigHandle { pub fn init(config: DgwConfig) -> anyhow::Result { let DgwConfig { + id, hostname, listener_host, provisioner_public_key_data, @@ -193,6 +197,15 @@ impl DgwConfigHandle { }) .unwrap_or_default(); + let id_json = id + .map(|id| { + format!( + r#" "Id": "{id}", +"# + ) + }) + .unwrap_or_default(); + let hostname_json = hostname .map(|hostname| { format!( @@ -207,7 +220,7 @@ impl DgwConfigHandle { let config = format!( r#"{{ -{hostname_json} "ProvisionerPublicKeyData": {{ +{id_json}{hostname_json} "ProvisionerPublicKeyData": {{ "Value": "{provisioner_public_key_data}" }}, "Listeners": [ diff --git a/testsuite/src/lib.rs b/testsuite/src/lib.rs index f69cbd5519..3e94839082 100644 --- a/testsuite/src/lib.rs +++ b/testsuite/src/lib.rs @@ -9,3 +9,4 @@ pub mod dgw_config; pub mod http; pub mod mcp_client; pub mod mcp_server; +pub mod token; diff --git a/testsuite/src/token.rs b/testsuite/src/token.rs new file mode 100644 index 0000000000..143dd9d4fd --- /dev/null +++ b/testsuite/src/token.rs @@ -0,0 +1,93 @@ +//! Token signing helpers, for tests running the Gateway with token validation enabled. + +use base64::Engine as _; +use picky::jose::jws::JwsAlg; +use picky::jose::jwt::CheckedJwtSig; +use picky::key::PrivateKey; + +/// Private key matching [`provisioner_public_key_data`]. +const PROVISIONER_KEY: &str = "-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDkrPiL/5dmGIT5 +/KuC3H/jIjeLoLoddsLhAlikO5JQQo3Zs71GwT4Wd2z8WLMe0lVZu/Jr2S28p0M8 +F3Lnz4IgzjocQomFgucFWWQRyD03ZE2BHfEeelFsp+/4GZaM6lKZauYlIMtjR1vD +lflgvxNTr0iaii4JR9K3IKCunCRy1HQYPcZ9waNtlG5xXtW9Uf1tLWPJpP/3I5HL +M85JPBv4r286vpeUlfQIa/NB4g5w6KZ6MfEAIU4KeEQpeLAyyYvwUzPR2uQZ4y4I +4Nj84dWYB1cMTlSGugvSgOFKYit1nwLGeA7EevVYPbILRfSMBU/+avGNJJ8HCaaq +FIyY42W9AgMBAAECggEBAImsGXcvydaNrIFUvW1rkxML5qUJfwN+HJWa9ALsWoo3 +h28p5ypR7S9ZdyP1wuErgHcl0C1d80tA6BmlhGhLZeyaPCIHbQQUa0GtL7IE+9X9 +bSvu+tt+iMcB1FdqEFmGOXRkB2sS82Ax9e0qvZihcOFRBkUEK/MqapIV8qctGkSG +wIE6yn5LHRls/fJU8BJeeqJmYpuWljipwTkp9hQ7SdRYFLNjwjlz/b0hjmgFs5QZ +LUNMyTHdHtXQHNsf/GayRUAKf5wzN/jru+nK6lMob2Ehfx9/RAfgaDHzy5BNFMj0 +i9+sAycgIW1HpTuDvSEs3qP26NeQ82GbJzATmdAKa4ECgYEA9Vti0YG+eXJI3vdS +uXInU0i1SY4aEG397OlGMwh0yQnp2KGruLZGkTvqxG/Adj1ObDyjFH9XUhMrd0za +Nk/VJFybWafljUPcrfyPAVLQLjsBfMg3Y34sTF6QjUnhg49X2jfvy9QpC5altCtA +46/KVAGREnQJ3wMjfGGIFP8BUZsCgYEA7phYE/cYyWg7a/o8eKOFGqs11ojSqG3y +0OE7kvW2ugUuy3ex+kr19Q/8pOWEc7M1UEV8gmc11xgB70EhIFt9Jq379H0X4ahS ++mgLiPzKAdNCRPpkxwwN9HxFDgGWoYcgMplhoAmg9lWSDuE1Exy8iu5inMWuF4MT +/jG+cLnUZ4cCgYAfMIXIUjDvaUrAJTp73noHSUfaWNkRW5oa4rCMzjdiUwNKCYs1 +yN4BmldGr1oM7dApTDAC7AkiotM0sC1RGCblH2yUIha5NXY5G9Dl/yv9pHyU6zK3 +UBO7hY3kmA611aP6VoACLi8ljPn1hEYUa4VR1n0llmCm29RH/HH7EUuOnwKBgExH +OCFp5eq+AAFNRvfqjysvgU7M/0wJmo9c8obRN1HRRlyWL7gtLuTh74toNSgoKus2 +y8+E35mce0HaOJT3qtMq3FoVhAUIoz6a9NUevBZJS+5xfraEDBIViJ4ps9aANLL4 +hlV7vpICWWeYaDdsAHsKK0yjhjzOEx45GQFA578RAoGBAOB42BG53tL0G9pPeJPt +S2LM6vQKeYx+gXTk6F335UTiiC8t0CgNNQUkW105P/SdpCTTKojAsOPMKOF7z4mL +lj/bWmNq7xu9uVOcBKrboVFGO/n6FXyWZxHPOTdjTkpe8kvvmSwl2iaTNllvSr46 +Z/fDKMxHxeXla54kfV+HiGkH +-----END PRIVATE KEY-----"; + +/// Private key the Gateway doesn't know about. +const UNTRUSTED_KEY: &str = "-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWw +kWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mr +m/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEi +NQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV +3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2 +QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQABAoIBACiARq2wkltjtcjs +kFvZ7w1JAORHbEufEO1Eu27zOIlqbgyAcAl7q+/1bip4Z/x1IVES84/yTaM8p0go +amMhvgry/mS8vNi1BN2SAZEnb/7xSxbflb70bX9RHLJqKnp5GZe2jexw+wyXlwaM ++bclUCrh9e1ltH7IvUrRrQnFJfh+is1fRon9Co9Li0GwoN0x0byrrngU8Ak3Y6D9 +D8GjQA4Elm94ST3izJv8iCOLSDBmzsPsXfcCUZfmTfZ5DbUDMbMxRnSo3nQeoKGC +0Lj9FkWcfmLcpGlSXTO+Ww1L7EGq+PT3NtRae1FZPwjddQ1/4V905kyQFLamAA5Y +lSpE2wkCgYEAy1OPLQcZt4NQnQzPz2SBJqQN2P5u3vXl+zNVKP8w4eBv0vWuJJF+ +hkGNnSxXQrTkvDOIUddSKOzHHgSg4nY6K02ecyT0PPm/UZvtRpWrnBjcEVtHEJNp +bU9pLD5iZ0J9sbzPU/LxPmuAP2Bs8JmTn6aFRspFrP7W0s1Nmk2jsm0CgYEAyH0X ++jpoqxj4efZfkUrg5GbSEhf+dZglf0tTOA5bVg8IYwtmNk/pniLG/zI7c+GlTc9B +BwfMr59EzBq/eFMI7+LgXaVUsM/sS4Ry+yeK6SJx/otIMWtDfqxsLD8CPMCRvecC +2Pip4uSgrl0MOebl9XKp57GoaUWRWRHqwV4Y6h8CgYAZhI4mh4qZtnhKjY4TKDjx +QYufXSdLAi9v3FxmvchDwOgn4L+PRVdMwDNms2bsL0m5uPn104EzM6w1vzz1zwKz +5pTpPI0OjgWN13Tq8+PKvm/4Ga2MjgOgPWQkslulO/oMcXbPwWC3hcRdr9tcQtn9 +Imf9n2spL/6EDFId+Hp/7QKBgAqlWdiXsWckdE1Fn91/NGHsc8syKvjjk1onDcw0 +NvVi5vcba9oGdElJX3e9mxqUKMrw7msJJv1MX8LWyMQC5L6YNYHDfbPF1q5L4i8j +8mRex97UVokJQRRA452V2vCO6S5ETgpnad36de3MUxHgCOX3qL382Qx9/THVmbma +3YfRAoGAUxL/Eu5yvMK8SAt/dJK6FedngcM3JEFNplmtLYVLWhkIlNRGDwkg3I5K +y18Ae9n7dHVueyslrb6weq7dTkYDi3iOYRW8HRkIQh06wEdbxt0shTzAJvvCQfrB +jg/3747WSsf/zBTcHihTRBdAv6OmdhV4/dD5YBfLAkLrd+mX7iE= +-----END RSA PRIVATE KEY-----"; + +/// Returns the provisioner private key, whose public key [`provisioner_public_key_data`] returns. +pub fn provisioner_key() -> PrivateKey { + PrivateKey::from_pem_str(PROVISIONER_KEY).expect("parse the provisioner key") +} + +/// Returns a private key the Gateway doesn't trust. +pub fn untrusted_key() -> PrivateKey { + PrivateKey::from_pem_str(UNTRUSTED_KEY).expect("parse the untrusted key") +} + +/// Returns the provisioner public key, encoded for [`crate::dgw_config::DgwConfig`]. +pub fn provisioner_public_key_data() -> String { + let der = provisioner_key() + .to_public_key() + .and_then(|public_key| public_key.to_der()) + .expect("encode the provisioner public key"); + + // The `m` multibase prefix stands for base64 without padding. + format!("m{}", base64::engine::general_purpose::STANDARD_NO_PAD.encode(der)) +} + +/// Signs a token with the given content type (`cty` header) and key ID (`kid` header). +pub fn sign_token(key: &PrivateKey, content_type: &str, kid: Option<&str>, claims: &serde_json::Value) -> String { + let mut jwt = CheckedJwtSig::new_with_cty(JwsAlg::RS256, content_type, claims); + jwt.header.kid = kid.map(str::to_owned); + jwt.encode(key).expect("sign the token") +} diff --git a/testsuite/tests/cli/dgw/api_errors.rs b/testsuite/tests/cli/dgw/api_errors.rs new file mode 100644 index 0000000000..c4bd50b3e6 --- /dev/null +++ b/testsuite/tests/cli/dgw/api_errors.rs @@ -0,0 +1,351 @@ +//! Machine-readable error responses of the HTTP API, with token validation enabled. + +use std::time::{Duration, SystemTime}; + +use rstest::rstest; +use serde_json::{Value, json}; +use testsuite::cli::start_dgw; +use testsuite::dgw_config::{DgwConfig, DgwConfigHandle}; +use testsuite::token::{provisioner_key, provisioner_public_key_data, sign_token, untrusted_key}; +use uuid::Uuid; + +const GATEWAY_ID: Uuid = Uuid::from_u128(0x0b7b_8c8e_6e61_4a2c_9a3f_5d1e_7c2b_4f10); + +const INVALID_TOKEN_CHALLENGE: &str = r#"Bearer error="invalid_token""#; + +/// Gateway running with token validation enabled, trusting the provisioner key of the testsuite. +struct Gateway { + config: DgwConfigHandle, + process: tokio::process::Child, +} + +impl Gateway { + async fn start() -> Self { + let config = DgwConfig::builder() + .id(GATEWAY_ID) + .provisioner_public_key_data(provisioner_public_key_data()) + .build() + .init() + .expect("init gateway config"); + let process = start_dgw(&config).await.expect("start gateway"); + + Self { config, process } + } + + async fn request(&self, method: reqwest::Method, path: &str, token: Option<&str>) -> Response { + let url = format!("http://127.0.0.1:{}{path}", self.config.http_port()); + let mut request = reqwest::Client::new() + .request(method, url) + .timeout(Duration::from_secs(10)); + + if let Some(token) = token { + request = request.bearer_auth(token); + } + + let response = request.send().await.expect("send request"); + + let header = |name| { + response + .headers() + .get(name) + .map(|value| value.to_str().expect("header value is ASCII").to_owned()) + }; + + Response { + status: response.status().as_u16(), + content_type: header(reqwest::header::CONTENT_TYPE), + www_authenticate: header(reqwest::header::WWW_AUTHENTICATE), + body: response.text().await.expect("read response body"), + } + } + + async fn get_heartbeat(&self, token: Option<&str>) -> Response { + self.request(reqwest::Method::GET, "/jet/heartbeat", token).await + } + + async fn stop(mut self) { + let _ = self.process.start_kill(); + let _ = self.process.wait().await; + } +} + +#[derive(Debug)] +struct Response { + status: u16, + content_type: Option, + www_authenticate: Option, + body: String, +} + +impl Response { + /// Asserts that the response is a problem details error, and that the body carries nothing but the code. + #[track_caller] + fn assert_problem(&self, status: u16, title: &str, error: &str, challenge: Option<&str>) { + assert_eq!(self.status, status, "{self:?}"); + assert_eq!( + self.content_type.as_deref(), + Some("application/problem+json"), + "{self:?}" + ); + assert_eq!(self.www_authenticate.as_deref(), challenge, "{self:?}"); + + let body: Value = serde_json::from_str(&self.body).expect("JSON body"); + assert_eq!( + body, + json!({ "type": "about:blank", "title": title, "status": status, "error": error }), + ); + } + + #[track_caller] + fn assert_unauthorized(&self, error: &str) { + self.assert_problem(401, "Unauthorized", error, Some(INVALID_TOKEN_CHALLENGE)); + } +} + +fn now() -> i64 { + let since_epoch = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("time after UNIX epoch"); + i64::try_from(since_epoch.as_secs()).expect("timestamp fits in i64") +} + +/// Claims of a scope token granting access to `GET /jet/heartbeat`. +fn heartbeat_claims() -> Value { + let now = now(); + json!({ + "jti": Uuid::new_v4(), + "nbf": now - 60, + "exp": now + 3600, + "scope": "gateway.heartbeat.read", + }) +} + +fn with_claims(mut claims: Value, overrides: Value) -> Value { + let claims_map = claims.as_object_mut().expect("claims object"); + for (name, value) in overrides.as_object().expect("overrides object") { + claims_map.insert(name.clone(), value.clone()); + } + claims +} + +fn without_claim(mut claims: Value, name: &str) -> Value { + claims.as_object_mut().expect("claims object").remove(name); + claims +} + +fn expired_claims() -> Value { + with_claims(heartbeat_claims(), json!({ "nbf": now() - 7200, "exp": now() - 3600 })) +} + +fn not_yet_valid_claims() -> Value { + with_claims(heartbeat_claims(), json!({ "nbf": now() + 3600, "exp": now() + 7200 })) +} + +fn other_gateway_claims() -> Value { + with_claims(heartbeat_claims(), json!({ "jet_gw_id": Uuid::new_v4() })) +} + +fn scope_token(claims: &Value) -> String { + sign_token(&provisioner_key(), "SCOPE", None, claims) +} + +fn jrl_token(iat: i64, jrl: Value) -> String { + let claims = json!({ "jti": Uuid::new_v4(), "iat": iat, "jrl": jrl }); + sign_token(&provisioner_key(), "JRL", None, &claims) +} + +// oracle: spec docs/API-spec.md §errors +#[tokio::test] +async fn missing_token() { + let gateway = Gateway::start().await; + + let response = gateway.get_heartbeat(None).await; + + // Per RFC 6750, the challenge carries no error code when the request has no token at all. + response.assert_problem(401, "Unauthorized", "missing_token", Some("Bearer")); + + gateway.stop().await; +} + +// oracle: spec docs/API-spec.md §errors +#[rstest] +#[case::malformed_token("not-a-token".to_owned(), "malformed_token")] +#[case::malformed_claims(scope_token(&without_claim(heartbeat_claims(), "scope")), "malformed_token")] +#[case::bad_signature(sign_token(&untrusted_key(), "SCOPE", None, &heartbeat_claims()), "bad_signature")] +#[case::unknown_subkey(sign_token(&provisioner_key(), "SCOPE", Some("unknown"), &heartbeat_claims()), "unknown_subkey")] +#[case::expired(scope_token(&expired_claims()), "expired")] +#[case::not_yet_valid(scope_token(¬_yet_valid_claims()), "not_yet_valid")] +#[case::gateway_id_mismatch(scope_token(&other_gateway_claims()), "gateway_id_mismatch")] +#[tokio::test] +async fn rejected_token(#[case] token: String, #[case] expected_error: &str) { + let gateway = Gateway::start().await; + + let response = gateway.get_heartbeat(Some(&token)).await; + + response.assert_unauthorized(expected_error); + + gateway.stop().await; +} + +/// The signature is verified before any claim: without a token signed by a trusted key, +/// a caller learns nothing about the claims the Gateway expects. +// oracle: spec docs/API-spec.md §errors +#[rstest] +#[case::expired(expired_claims())] +#[case::not_yet_valid(not_yet_valid_claims())] +#[case::gateway_id_mismatch(other_gateway_claims())] +#[case::malformed_claims(without_claim(heartbeat_claims(), "scope"))] +#[tokio::test] +async fn claims_are_not_disclosed_without_a_valid_signature(#[case] claims: Value) { + let gateway = Gateway::start().await; + + let token = sign_token(&untrusted_key(), "SCOPE", None, &claims); + let response = gateway.get_heartbeat(Some(&token)).await; + + response.assert_unauthorized("bad_signature"); + + gateway.stop().await; +} + +// oracle: spec docs/API-spec.md §errors +// oracle: spec docs/API-spec.md §SCOPE +#[tokio::test] +async fn unexpected_replay() { + let gateway = Gateway::start().await; + + let token = scope_token(&heartbeat_claims()); + + let first = gateway.get_heartbeat(Some(&token)).await; + assert_eq!(first.status, 200, "{first:?}"); + + // A SCOPE token is valid for a single request. + let second = gateway.get_heartbeat(Some(&token)).await; + second.assert_unauthorized("unexpected_replay"); + + gateway.stop().await; +} + +// oracle: spec docs/API-spec.md §errors +// oracle: spec docs/API-spec.md §JRL (JWT Revocation List) +#[tokio::test] +async fn revoked() { + let gateway = Gateway::start().await; + + let claims = heartbeat_claims(); + + let jrl_update = gateway + .request( + reqwest::Method::POST, + "/jet/jrl", + Some(&jrl_token(now(), json!({ "jti": [claims["jti"]] }))), + ) + .await; + assert_eq!(jrl_update.status, 200, "{jrl_update:?}"); + + let response = gateway.get_heartbeat(Some(&scope_token(&claims))).await; + + response.assert_unauthorized("revoked"); + + gateway.stop().await; +} + +// oracle: spec docs/API-spec.md §errors +// oracle: spec docs/API-spec.md §JRL (JWT Revocation List) +#[tokio::test] +async fn outdated_revocation_list() { + let gateway = Gateway::start().await; + + let now = now(); + + let jrl_update = gateway + .request(reqwest::Method::POST, "/jet/jrl", Some(&jrl_token(now, json!({})))) + .await; + assert_eq!(jrl_update.status, 200, "{jrl_update:?}"); + + // The Gateway only accepts a revocation list newer than its current one. + let response = gateway + .request( + reqwest::Method::POST, + "/jet/jrl", + Some(&jrl_token(now - 3600, json!({}))), + ) + .await; + + response.assert_unauthorized("invalid_token"); + + gateway.stop().await; +} + +// oracle: spec docs/API-spec.md §errors +// oracle: spec docs/API-spec.md §About scopes +#[tokio::test] +async fn wrong_token_type() { + let gateway = Gateway::start().await; + + // A valid token, but the route expects a SCOPE token. + let response = gateway.get_heartbeat(Some(&jrl_token(now(), json!({})))).await; + + response.assert_problem(403, "Forbidden", "wrong_token_type", None); + + gateway.stop().await; +} + +// oracle: spec docs/API-spec.md §errors +// oracle: spec docs/API-spec.md §About scopes +#[tokio::test] +async fn insufficient_scope() { + let gateway = Gateway::start().await; + + let claims = with_claims(heartbeat_claims(), json!({ "scope": "gateway.sessions.read" })); + let response = gateway.get_heartbeat(Some(&scope_token(&claims))).await; + + response.assert_problem( + 403, + "Forbidden", + "insufficient_scope", + Some(r#"Bearer error="insufficient_scope""#), + ); + + gateway.stop().await; +} + +// oracle: spec docs/API-spec.md §errors +// oracle: spec docs/API-spec.md §OpenAPI +#[tokio::test] +async fn generic_code_derived_from_status() { + let gateway = Gateway::start().await; + + let claims = with_claims(heartbeat_claims(), json!({ "scope": "gateway.session.terminate" })); + let path = format!("/jet/session/{}/terminate", Uuid::new_v4()); + let response = gateway + .request(reqwest::Method::POST, &path, Some(&scope_token(&claims))) + .await; + + response.assert_problem(404, "Not Found", "not_found", None); + + gateway.stop().await; +} + +/// The KDC proxy reads its token from the path, and validates it outside of the authentication middleware. +// oracle: spec docs/API-spec.md §errors +#[tokio::test] +async fn rejected_kdc_token() { + let gateway = Gateway::start().await; + + let now = now(); + let claims = json!({ + "krb_realm": "example.com", + "krb_kdc": "tcp://127.0.0.1:88", + "jti": Uuid::new_v4(), + "nbf": now - 60, + "exp": now + 3600, + }); + let token = sign_token(&untrusted_key(), "KDC", None, &claims); + let response = gateway + .request(reqwest::Method::POST, &format!("/jet/KdcProxy/{token}"), None) + .await; + + response.assert_unauthorized("bad_signature"); + + gateway.stop().await; +} diff --git a/testsuite/tests/cli/dgw/mod.rs b/testsuite/tests/cli/dgw/mod.rs index 85e2b02bcd..0b6dfd94f8 100644 --- a/testsuite/tests/cli/dgw/mod.rs +++ b/testsuite/tests/cli/dgw/mod.rs @@ -1,4 +1,5 @@ mod ai_analysis; +mod api_errors; mod benign_disconnect; mod cli_args; mod heartbeat;