These changes add explicit `Content-Type` headers to direct (via `native` interceptor)
authentication requests after changes made in [PR #4931](https://github.com/hoppscotch/hoppscotch/pull/4931) that modified how `Content-Type`
headers are handled in the `relay` plugin.
In [issue #4905](https://github.com/hoppscotch/hoppscotch/issues/4905), that was about Hoppscotch Agent and Native interceptor inconsistently
handling `Content-Type` headers. The issue had two main manifestations,
duplicate headers - when overriding the `Content-Type` header in the UI or using OAuth2 authentication, the agent
would send multiple `Content-Type` headers to the web server. This caused undefined behavior
and often 400 errors for backends that don't accept duplicate headers.
And inconsistent overrides - even when the content type was explicitly set (for example to
`application/json;v=2`), the agent/native would inconsistently apply this override. Server
logs revealed that roughly 50% of requests would use the correct override value, while the
others would revert to the default `application/json`.
The two-part solution implemented first in [PR #4911](https://github.com/hoppscotch/hoppscotch/pull/4911) addressed the duplicate headers issue
by implementing header normalization before final relay. This prevented duplicate headers
with different casing from being sent and [PR #4931](https://github.com/hoppscotch/hoppscotch/pull/4931) then resolved the inconsistent override
behavior by removing the automatic `Content-Type` header insertion in the `ContentHandler`
component. As explained in the PR description, this was a temporary workaround until we
implement a HTTP/2-compliant solution with proper normalization.
While the fixes in PR #4911 and #4931 correctly resolved the header inconsistency issues
for general API requests, they introduced a new problem: **requests that previously relied
on the automatic `Content-Type` insertion now have no `Content-Type` header at all**.
This mainly affects direct calls around authentication flows in the desktop module, which
were using the `content.json()` functionality without explicitly setting `Content-Type`
headers, relying on the automatic insertion that has now been removed.
These changes add the now-required explicit `Content-Type` headers to three
authentication-related API calls in the desktop platform module:
- **The initial user details GraphQL query**:
```javascript
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
```
- **The magic link email submission endpoint**:
```javascript
headers: {
"Content-Type": "application/json",
},
```
- **The token verification endpoint**:
```javascript
headers: {
"Content-Type": "application/json",
},
```
This will make sure that authentication flows continue to work properly with the native
interceptor after the header handling changes.
As noted in [PR #4931](https://github.com/hoppscotch/hoppscotch/pull/4931), this is considered a **temporary solution**. The plan is to revisit the
content-type handling when we implement a more comprehensive HTTP/2-compliant header
normalization system in the kernel layer.
While HTTP/1.1 headers are case-insensitive
per [RFC 7230](https://tools.ietf.org/html/rfc7230), inconsistent handling across server implementations can treat differently-cased
variations as distinct headers. HTTP/2 ([RFC 7540](https://tools.ietf.org/html/rfc7540)) mandates converting all header field
names to lowercase, which would prevent these issues altogether. In such cases, relying
fully on `MediaType` interface from the kernel will help handling these edge-cases.
The current implementation causes duplicate `Content-Type` headers when users
override headers in the UI or use OAuth2 authentication with the agent.
Web servers receive multiple `Content-Type` headers which causes
undefined behavior and 400 errors for backends that don't accept duplicate headers.
This also fixes inconsistent behavior when overriding the `Content-Type` header
with custom values (e.g., `application/json;v=2`).
While HTTP/1.1 headers are case-insensitive per RFC 7230, inconsistent handling
across server implementations can treat differently-cased variations (e.g.,
"Content-Type" vs "content-type") as distinct headers. HTTP/2 (RFC 7540) mandates
converting all header field names to lowercase, which would prevent this issue.
This patch removes the automatic content-type header insertion, allowing user-defined
headers to take precedence without duplication. The is a temporary
workaround until we implement a HTTP/2-compliant solution with proper normalization.
This was implemented initially to support moving lower level handling
towards the kernel, although since the larger refactor has been slightly
deferred in favor of stability, this change is suitable for current
state.
This will be revisited when we implement HTTP/2 compliant header handling in the
kernel layer as part of our upcoming kernel efforts.
Use the following request to test this out on Desktop app and Agent and
override `Content-Type` header to `application/json;=v2`:
```
curl --request POST \
--url 'https://echo.qubit.codes/?qp=1' \
--header 'Content-Type: application/json;v=2' \
--data '{ "test-key": "test-value" }'
```
This change sorts environment variables alphabetically before they're
processed with import-meta-env that injects them into the index.html.
This makes sure consistent hashes across pod restarts when there aren't
any functional changes made to the `.env` file.
The issue was affecting desktop app reconnections after k8s pod restarts.
The cause was non-deterministic env var ordering (a sideeffect of `Map`)
during the import-meta-env injection process. Even when the env vars
themselves didn't change, their order in the injected JSON could change,
ultimately resulting in different file hashes.
This fix ensures that regardless of the order in which env vars are
provided by the runtime, they will be sorted alphabetically before being
written to the build.env file.
This is observed particularly in the cloud offering. The proposed changes ensure the relevant login state is confirmed before the network call, maintaining backwards compatibility with SH.