[PR #4684] [MERGED] feat: platform independent core and the new desktop app #4900

Closed
opened 2026-03-17 02:23:36 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/hoppscotch/hoppscotch/pull/4684
Author: @CuriousCorrelation
Created: 1/21/2025
Status: Merged
Merged: 2/27/2025
Merged by: @AndrewBastin

Base: nextHead: desktop/feat/crossover


📝 Commits (10+)

  • df18e3d feat(desktop): init
  • 1bfbe4a feat(desktop): external app download and setup
  • a4ffd72 feat(desktop): offload app load to plugin system
  • c5f3ca0 perf(desktop): add rdbms facade and caching layer
  • 37657f2 feat: parallelize signing, shared trust, lru cache
  • 7706527 feat: webapp encoder + compressor + hasher server
  • 37b292d feat(desktop): app autoupdate with hashed loader
  • f1f68d3 feat(kernel): init hoppscotch-kernel
  • 2410e4c feat(kernel): io
  • cb0528d feat(kernel): network

📊 Changes

465 files changed (+53981 additions, -4017 deletions)

View changed files

📝 .dockerignore (+33 -0)
📝 .env.example (+8 -1)
.envrc (+3 -0)
📝 .gitignore (+10 -0)
📝 aio-subpath-access.Caddyfile (+5 -0)
📝 aio_run.mjs (+7 -0)
devenv.lock (+140 -0)
devenv.nix (+189 -0)
📝 devenv.yaml (+0 -0)
📝 docker-compose.yml (+91 -2)
📝 packages/codemirror-lang-graphql/tsconfig.json (+1 -0)
packages/hoppscotch-agent/.envrc (+0 -3)
📝 packages/hoppscotch-agent/package.json (+2 -0)
📝 packages/hoppscotch-agent/src-tauri/Cargo.lock (+1063 -574)
📝 packages/hoppscotch-agent/src-tauri/Cargo.toml (+6 -7)
📝 packages/hoppscotch-agent/src-tauri/capabilities/default.json (+1 -0)
packages/hoppscotch-agent/src-tauri/src/command.rs (+40 -0)
📝 packages/hoppscotch-agent/src-tauri/src/controller.rs (+271 -92)
📝 packages/hoppscotch-agent/src-tauri/src/dialog.rs (+4 -4)
📝 packages/hoppscotch-agent/src-tauri/src/error.rs (+14 -2)

...and 80 more files

📄 Description

This PR introduces the ability for the Hoppscotch Desktop app to connect to any self-hosted instances and some other major improvements. It makes the core of the Hoppscotch app platform independent via the new Hoppscotch Kernel. It also implements a new relay architecture that adds support for several flows, bringing feature parity between the web app and the desktop app.

Closes the HFE-672 initiative

Changes

  • hoppscotch-common:

    • InterceptorService or rather KernelInterceptorService now use @hoppscotch-kernel/relay

      • Browser based networking is handled by async axios
      • Desktop based networking is handled by async @hoppscotch/plugin-relay
      • Both take in RelayRequest and returns RelayResponse where response body is Uint8Array
    • Each interceptor now has its own store

    • And native interceptor (native to the platform, different from "native" named interceptors) are initialized via the InitializationService.

      • Previously interceptors depended on PersistenceService to get settings from localStorage
      • But because now native interceptor (and by extension the service) needs to be ready before PersistenceService;
        • One such reason being ability to authenticate user and sync settings at the app launch
      • Interceptors need their own dedicated stores that can be initialized independently from the PersistenceService.
      • The store itself is a separate service which now has changed from previously recursive store dependency.
        • Now each interceptor has a corresponding store.ts file that is called in the Settings page which is then called in InterceptorService
          • Meaning no dependency cycle - it's now a linear store -> settings -> interceptor flow.
      • And has domain-specific settings with version control
    • PersistenceService now use @hoppscotch-kernel/store

      • Browser based storage is handled by sync localStorage with superjson serialization
      • Desktop based storage is handled by async tauri-apps/plugin-store with serde serialization
      • Namespacing to prevent collisions, important because we need to differentiate raw store calls (see native interceptor) and calls directed through PersistenceService
      • Structured metadata storage for things like creation dates and TTL
        • This is important because we need to make sure async operations aren't colliding when changing settings
        • And they follow the zod schema, this was important during development and since it doesn't cost much in terms of storage or serialization, have kept it.
        • See how storage works in the desktop section of store kernel module.
      • getLocalConfig and setLocalConfig are now async operations that can fail (previously they'd fail silently or throw)
        • Also because getLocalConfig and setLocalConfig are now asynchronous, all of their call sites are converted to async function, some are moved to onMount to avoid Suspense.
    • InspectorService now queries active interceptor to understand capabilities

      • There are now 3 types of inspectors, request (handles authorization, headers, etc), response and environment.
      • These are O(1) lookups
    • composables/picker along with functional/domain-settings handle interceptor settings, mainly related to how settings are transformed into RelayRequest, a combination of Omit and Pick.

    • app/KernelInterceptor handles the settings page for the new interceptor services

    • src/kernel

      • This module handles how loaded kernel (this is important) is checked and initialized.
      • Essentially getModule = <K extends keyof KernelAPI>(name: K): NonNullable<KernelAPI[K]>
    • src/helpers/kernel

      • This module contains bridge to and from the underlying kernel implementation (desktop/web)
      • common/auth handles transforming type HoppAuth = HoppRESTRequest["auth"] into RelayRequest["auth"]
        • AWS signing is handled at the kernel level
          • Implementation differs between desktop vs browser
        • Uses type guards for each auth method (basic, bearer, api-key, aws, digest, oauth2)
        • OAuth2 support includes multiple grant types with type-safe transformations
          • Authorization code, client credentials, password, and implicit flows
          • Each grant type has its own processor and validation
          • This is distinct from oauth services, these are mainly for oauth rest/gql
      • common/content handles transforming HoppRESTReqBody into ContentType
        • Has separate processors for JSON, multipart, binary, urlencoded, XML and text content
          • Uses a helper function content from @hoppscotch/kernel as transformer
          • JSON processor attempts JSON parse first, falls back to plain text
          • Multipart handles files with platform-specific APIs
        • File handling differs between platforms
          • Desktop uses native filesystem APIs
          • Web uses Blob API and FormData
        • Content-type detection and transformation handled by platform-specific processors
          • Default fallback to text/plain for unknown types
      • rest/request & rest/response handle REST-specific transformations
        • Request transformation aggregates auth, content, headers and params
        • Response handles timing, size calculations and error states
      • gql/request & gql/response handle GraphQL-specific flows
        • Request enforces POST method and application/json content-type
        • Response validates GraphQL-specific structure (data/errors)
        • Handles operation types (query/mutation/subscription)
        • Preserves metadata like operation name and timing
      • rest and gql are helpers that replace usage from helpers/graphql/connection.ts and helpers/network.ts
    • Interceptors and their domain settings

      • Domain-specific settings now use @hoppscotch-kernel/store (same reason why interceptors now use separate store)
        • Settings stored with structured metadata including creation dates and TTL
          • This is important because we need to track setting modifications across async operations
          • Domain-specific settings follow zod schema for validation and type safety
      • Domain-specific configuration replaces proxy bypass lists
        • Each domain handled as independent settings context
        • Global defaults are used as fallback when domain settings not specified
        • Security parameters (validateCertificates, verifyHost, verifyPeer) are now configurable per domain
        • Certificate management (PEM/PKCS12) with full CA chain support are now also configurable per domain
      • Settings initialization now independent from PersistenceService
      • Native.vue implements unified settings management, Settings panel shows inheritance state of each option
      • Settings transformations handled by specialized processors
        • Each setting type converted to RelayRequest format
        • Domain-specific overrides merged with global defaults
        • Type-safe transformations using TypeScript's Pick/Omit
        • Validation rules enforced through zod schemas
        • All domain settings automatically migrated to "*" domain for backwards compatibility
  • hoppscotch-desktop:

  • Custom protocol handler at load level translates all web app resource requests

    • Each web request intercepted and transformed to local file fetch and a cache manager handles file retrieval through two systems
      • In-memory cache for frequently accessed files using LruCache and disk-based cache when memory pressure high or cold loads
    • Every request gets security headers injected from CSP rules from tauri.config.json, this is important especially on Windows. This also includes Headers like x-content-type-options=nosniff
    • File loading handled by FileStore abstractios which essentially is wrapper over platform-specific APIs (fs)
  • Bundle verification works through multi-stage process where the KeyManager fetches Ed25519 keys from server, at<app_config>/key/

    • Then BundleVerifier makes sure integrity at three levels, Bundle-level signature verification first, per-file blake3 hash verification next, all done in parallel.
    • To avoid redoing the same work, VerifiedBundle maintains post-verification state, files being accessible through verified content map, with priginal zip preserved for cache rebuilds
  • Window management differs per platform

    • macOS:
      • Custom NSWindowDelegate for behaviors, better traffic light repositioning based on content, and vibrancy tied to web app theme
    • Windows:
      • DWM API calls for window frame customization, theme synchronization through messages, custom window procedure for titlebar
  • Networking:

    • Networking is handled by the new realy that takes in RelayRequest, a transformation of HoppRESTRequest
      • request.rs transforms incoming requests to curl format, then sets up basic parameters (method, url, version)
        • Applies headers and query parameters, and then configures request body and auth
      • response.rs transforms curl responses back to Hopp format, it extracts status, headers and body
        • Also optionally determines correct media type, and calculates timing and size metadata
    • Content handling uses specialized processors per type
    • Authentication implements multiple schemes
      • Basic auth with username/password
      • Bearer token support
      • OAuth2 flows:
        • Client credentials grant
        • Password grant
        • Refresh token handling
      • Digest authentication with:
        • MD5/SHA256/SHA512 algorithms
        • Quality of protection modes
        • Nonce/cnonce handling
    • Security layer manages TLS/certificate configuration
      • Certificate handling:
        • Client certs (PEM/PKCS12)
        • Custom CA certificates
        • Certificate chain validation
      • Security options:
        • Host verification
        • Peer verification
        • Protocol version selection
  • hoppscotch-selfhost-web:

    • webapp-server:
      • New static server for serving built hoppscotch-selfhost-web

        • Bundles the app with crypto verification on client side;
          • one critical reason being the need to detect any partial updates, hosting changes with frontend assets
          • another being the requirement to validate bundle authenticity in offline mode, mainly for deterministic reproducibility
      • SigningKeyPair handles key management, generation and storage via ed25519

        • Namespacing for key identification, this is important because we need to track key rotation and support for multiple active keys during transitions
      • BundleManager and BundleBuilder handles bundling and packing

      • API layer exposes three core endpoints:

        • /api/v1/manifest - Bundle metadata
        • /api/v1/bundle - Bundle download
        • /api/v1/key - Public key access
  • hoppscotch-agent:

    • Added registration management interface with timestamps and masked hashes
      • This can be accessed from agent's tray icon menu
    • Implemented simpler window handling system, reusing single window for registration
      • Windows showing up for OTP and registration list should be faster and more lightweight.
      • Windows now have show/hide button + auto-hide
    • Added JSON structured logging system with RFC 3339 timestamps and daily rotation
      • Agent now logs every flow better
      • Added log forwarding capabilities with context-aware logging
      • standardized log file location at <app_data_dir>/hoppscotch-agent-YYYY-MM-DD.log.
      • Added log sink endpoint with path POST /log-sink accepting Authorization bearer token and encrypted payload
        • It expects logs from the web app that can be consolidated with a correlation id
  • hoppscotch-backend:

    • Added a new authentication flow mirroring Firebase methodology with browser-based authentication for the desktop app
      • See hoppscotch-selfhost-web's platform/auth implementation.
    • Added bearer token implementation via Authorization header
      • Considered cookie based approach but some proxy server strip those away so defaulting to web standards
    • Fixed SSL context cleanup issue in curl's SSL callback
      • Since this exchange is now handled by native interceptor
    • Added bearer token parsing in JWT strategy handler and simple auth passthrough in WebSocket upgrade calls.
    • Added general token parsing for core authentication work
    • Created new auth/desktop endpoint with browser redirection

Note to reviewers

Simplest way to test out app server and desktop app would be as follows:

❯ cp .env.example .env
❯ pnpm install

then

❯ cd packages/hoppscotch-selfhost-web/ && pnpm install && pnpm generate && cd webapp-server && RUST_LOG=debug cargo run

This will start up a webapp server (like mentioned in the web section above). This server serves selfhosted app (purely for testing purposes, for prod-like setup use docker compose --profile default up --build more info later)

Now if this is the first time running the app, do a full build via

❯ cd packages/hoppscotch-desktop && RUST_LOG=debug pnpm dev:full # or pnpm build:full

but for any subsequent run, do this instead (much faster)

❯ cd packages/hoppscotch-desktop/src-tauri && RUST_LOG=debug pnpm tauri dev

The difference being vendored vs purely selfhost shell, for all intents and purposes, pnpm dev:full is a safer bet and for build, when in doubt pnpm build:full.

Remember, all the commands assumes you have cargo (with rustup with nightly toolchain rustup default nightly) and pnpm installed on your machine, otherwise for fully reproducible development environment, best way to setup all instances and app suite would be as follows:

❯ devenv shell 

This will load a reproducible development environment (with docker powered by colima), then

❯ cp .env.example .env
❯ pnpm install

followed by

❯ colima-start 

This will setup docker with minimal system requirements, finally the same instructions as before

❯ cd packages/hoppscotch-selfhost-web/ && pnpm install && pnpm generate && cd webapp-server && RUST_LOG=debug cargo run

and then in a different terminal instance this (if it's your first time running the app from scratch)

❯ cd packages/hoppscotch-desktop && RUST_LOG=debug pnpm dev:full # or pnpm build:full

or this (if you've already built vendored app)

❯ cd packages/hoppscotch-desktop/src-tauri && RUST_LOG=debug pnpm tauri dev

or for fully functional all service setup, try

❯ docker compose --profile default up --build

See docker-compose.yml in monorepo root for more detailed information.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/hoppscotch/hoppscotch/pull/4684 **Author:** [@CuriousCorrelation](https://github.com/CuriousCorrelation) **Created:** 1/21/2025 **Status:** ✅ Merged **Merged:** 2/27/2025 **Merged by:** [@AndrewBastin](https://github.com/AndrewBastin) **Base:** `next` ← **Head:** `desktop/feat/crossover` --- ### 📝 Commits (10+) - [`df18e3d`](https://github.com/hoppscotch/hoppscotch/commit/df18e3d0e6b0f2b6fbbc8cbbec72f5121107216a) feat(desktop): init - [`1bfbe4a`](https://github.com/hoppscotch/hoppscotch/commit/1bfbe4a8500ce21b45c0e24f76dd1ce006ea7dd8) feat(desktop): external app download and setup - [`a4ffd72`](https://github.com/hoppscotch/hoppscotch/commit/a4ffd72a5c4af37781cbac1bbea3fb6a6b2c2a7c) feat(desktop): offload app load to plugin system - [`c5f3ca0`](https://github.com/hoppscotch/hoppscotch/commit/c5f3ca0d5cc68f1e678930b1ca4cd14385af732e) perf(desktop): add rdbms facade and caching layer - [`37657f2`](https://github.com/hoppscotch/hoppscotch/commit/37657f2153f947e2c3a12b683795b2190360f80c) feat: parallelize signing, shared trust, lru cache - [`7706527`](https://github.com/hoppscotch/hoppscotch/commit/7706527805902bfb12447fdd531fcfe0e28c5feb) feat: webapp encoder + compressor + hasher server - [`37b292d`](https://github.com/hoppscotch/hoppscotch/commit/37b292d42feb54a5e62a7af52065dbcca9c2bde1) feat(desktop): app autoupdate with hashed loader - [`f1f68d3`](https://github.com/hoppscotch/hoppscotch/commit/f1f68d32e2ef83c2cf246dc548f8b3892c1d49ab) feat(kernel): init `hoppscotch-kernel` - [`2410e4c`](https://github.com/hoppscotch/hoppscotch/commit/2410e4cdc193712f7bc34dafe504ef1d39622bce) feat(kernel): `io` - [`cb0528d`](https://github.com/hoppscotch/hoppscotch/commit/cb0528d81bbc9be2266cb5b4233af4c8ed999130) feat(kernel): `network` ### 📊 Changes **465 files changed** (+53981 additions, -4017 deletions) <details> <summary>View changed files</summary> 📝 `.dockerignore` (+33 -0) 📝 `.env.example` (+8 -1) ➕ `.envrc` (+3 -0) 📝 `.gitignore` (+10 -0) 📝 `aio-subpath-access.Caddyfile` (+5 -0) 📝 `aio_run.mjs` (+7 -0) ➕ `devenv.lock` (+140 -0) ➕ `devenv.nix` (+189 -0) 📝 `devenv.yaml` (+0 -0) 📝 `docker-compose.yml` (+91 -2) 📝 `packages/codemirror-lang-graphql/tsconfig.json` (+1 -0) ➖ `packages/hoppscotch-agent/.envrc` (+0 -3) 📝 `packages/hoppscotch-agent/package.json` (+2 -0) 📝 `packages/hoppscotch-agent/src-tauri/Cargo.lock` (+1063 -574) 📝 `packages/hoppscotch-agent/src-tauri/Cargo.toml` (+6 -7) 📝 `packages/hoppscotch-agent/src-tauri/capabilities/default.json` (+1 -0) ➕ `packages/hoppscotch-agent/src-tauri/src/command.rs` (+40 -0) 📝 `packages/hoppscotch-agent/src-tauri/src/controller.rs` (+271 -92) 📝 `packages/hoppscotch-agent/src-tauri/src/dialog.rs` (+4 -4) 📝 `packages/hoppscotch-agent/src-tauri/src/error.rs` (+14 -2) _...and 80 more files_ </details> ### 📄 Description This PR introduces the ability for the Hoppscotch Desktop app to connect to any self-hosted instances and some other major improvements. It makes the core of the Hoppscotch app platform independent via the new Hoppscotch Kernel. It also implements a new relay architecture that adds support for several flows, bringing feature parity between the web app and the desktop app. Closes the HFE-672 initiative ### Changes - `hoppscotch-common`: - `InterceptorService` or rather `KernelInterceptorService` now use `@hoppscotch-kernel/relay` - Browser based networking is handled by async `axios` - Desktop based networking is handled by async `@hoppscotch/plugin-relay` - Both take in `RelayRequest` and returns `RelayResponse` where response body is `Uint8Array` - Each interceptor now has its own store - And native interceptor (native to the platform, different from "native" named interceptors) are initialized via the `InitializationService`. - Previously interceptors depended on `PersistenceService` to get settings from `localStorage` - But because now native interceptor (and by extension the service) needs to be ready before `PersistenceService`; - One such reason being ability to authenticate user and sync settings at the app launch - Interceptors need their own dedicated stores that can be initialized independently from the `PersistenceService`. - The store itself is a separate service which now has changed from previously recursive store dependency. - Now each interceptor has a corresponding `store.ts` file that is called in the `Settings` page which is then called in `InterceptorService` - Meaning no dependency cycle - it's now a linear store -> settings -> interceptor flow. - And has domain-specific settings with version control - `PersistenceService` now use `@hoppscotch-kernel/store` - Browser based storage is handled by sync `localStorage` with `superjson` serialization - Desktop based storage is handled by async `tauri-apps/plugin-store` with `serde` serialization - Namespacing to prevent collisions, important because we need to differentiate raw store calls (see native interceptor) and calls directed through `PersistenceService` - Structured metadata storage for things like creation dates and TTL - This is important because we need to make sure async operations aren't colliding when changing settings - And they follow the zod schema, this was important during development and since it doesn't cost much in terms of storage or serialization, have kept it. - See how storage works in the desktop section of `store` kernel module. - `getLocalConfig` and `setLocalConfig` are now async operations that can fail (previously they'd fail silently or throw) - Also because `getLocalConfig` and `setLocalConfig` are now asynchronous, all of their call sites are converted to async function, some are moved to `onMount` to avoid `Suspense`. - `InspectorService` now queries active interceptor to understand capabilities - There are now 3 types of inspectors, request (handles authorization, headers, etc), response and environment. - These are O(1) lookups - `composables/picker` along with `functional/domain-settings` handle interceptor settings, mainly related to how settings are transformed into `RelayRequest`, a combination of `Omit` and `Pick`. - `app/KernelInterceptor` handles the settings page for the new interceptor services - `src/kernel` - This module handles how loaded kernel (this is important) is checked and initialized. - Essentially `getModule = <K extends keyof KernelAPI>(name: K): NonNullable<KernelAPI[K]>` - `src/helpers/kernel` - This module contains bridge to and from the underlying kernel implementation (desktop/web) - `common/auth` handles transforming `type HoppAuth = HoppRESTRequest["auth"]` into `RelayRequest["auth"]` - AWS signing is handled at the kernel level - Implementation differs between desktop vs browser - Uses type guards for each auth method (basic, bearer, api-key, aws, digest, oauth2) - OAuth2 support includes multiple grant types with type-safe transformations - Authorization code, client credentials, password, and implicit flows - Each grant type has its own processor and validation - This is distinct from `oauth` services, these are mainly for oauth rest/gql - `common/content` handles transforming `HoppRESTReqBody` into `ContentType` - Has separate processors for JSON, multipart, binary, urlencoded, XML and text content - Uses a helper function `content` from `@hoppscotch/kernel` as transformer - JSON processor attempts JSON parse first, falls back to plain text - Multipart handles files with platform-specific APIs - File handling differs between platforms - Desktop uses native filesystem APIs - Web uses Blob API and FormData - Content-type detection and transformation handled by platform-specific processors - Default fallback to text/plain for unknown types - `rest/request` & `rest/response` handle REST-specific transformations - Request transformation aggregates auth, content, headers and params - Response handles timing, size calculations and error states - `gql/request` & `gql/response` handle GraphQL-specific flows - Request enforces POST method and application/json content-type - Response validates GraphQL-specific structure (data/errors) - Handles operation types (query/mutation/subscription) - Preserves metadata like operation name and timing - `rest` and `gql` are helpers that replace usage from `helpers/graphql/connection.ts` and `helpers/network.ts` - Interceptors and their domain settings - Domain-specific settings now use `@hoppscotch-kernel/store` (same reason why interceptors now use separate store) - Settings stored with structured metadata including creation dates and TTL - This is important because we need to track setting modifications across async operations - Domain-specific settings follow zod schema for validation and type safety - Domain-specific configuration replaces proxy bypass lists - Each domain handled as independent settings context - Global defaults are used as fallback when domain settings not specified - Security parameters (validateCertificates, verifyHost, verifyPeer) are now configurable per domain - Certificate management (PEM/PKCS12) with full CA chain support are now also configurable per domain - Settings initialization now independent from `PersistenceService` - `Native.vue` implements unified settings management, `Settings` panel shows inheritance state of each option - Settings transformations handled by specialized processors - Each setting type converted to `RelayRequest` format - Domain-specific overrides merged with global defaults - Type-safe transformations using TypeScript's Pick/Omit - Validation rules enforced through zod schemas - All domain settings automatically migrated to "*" domain for backwards compatibility - `hoppscotch-desktop`: - Custom protocol handler at load level translates all web app resource requests - Each web request intercepted and transformed to local file fetch and a cache manager handles file retrieval through two systems - In-memory cache for frequently accessed files using `LruCache` and disk-based cache when memory pressure high or cold loads - Every request gets security headers injected from `CSP` rules from `tauri.config.json`, this is important especially on Windows. This also includes Headers like `x-content-type-options=nosniff` - File loading handled by `FileStore` abstractios which essentially is wrapper over platform-specific APIs (fs) - Bundle verification works through multi-stage process where the `KeyManager` fetches Ed25519 keys from server, at`<app_config>/key/` - Then `BundleVerifier` makes sure integrity at three levels, Bundle-level signature verification first, per-file `blake3` hash verification next, all done in parallel. - To avoid redoing the same work, `VerifiedBundle` maintains post-verification state, files being accessible through verified content map, with priginal zip preserved for cache rebuilds - Window management differs per platform - macOS: - Custom `NSWindowDelegate` for behaviors, better traffic light repositioning based on content, and vibrancy tied to web app theme - Windows: - `DWM` API calls for window frame customization, theme synchronization through messages, custom window procedure for titlebar - Networking: - Networking is handled by the new realy that takes in `RelayRequest`, a transformation of `HoppRESTRequest` - `request.rs` transforms incoming requests to curl format, then sets up basic parameters (method, url, version) - Applies headers and query parameters, and then configures request body and auth - `response.rs` transforms curl responses back to Hopp format, it extracts status, headers and body - Also optionally determines correct media type, and calculates timing and size metadata - Content handling uses specialized processors per type - Authentication implements multiple schemes - Basic auth with username/password - Bearer token support - OAuth2 flows: - Client credentials grant - Password grant - Refresh token handling - Digest authentication with: - MD5/SHA256/SHA512 algorithms - Quality of protection modes - Nonce/cnonce handling - Security layer manages TLS/certificate configuration - Certificate handling: - Client certs (PEM/PKCS12) - Custom CA certificates - Certificate chain validation - Security options: - Host verification - Peer verification - Protocol version selection - `hoppscotch-selfhost-web`: - `webapp-server`: - New static server for serving built `hoppscotch-selfhost-web` - Bundles the app with crypto verification on client side; - one critical reason being the need to detect any partial updates, hosting changes with frontend assets - another being the requirement to validate bundle authenticity in offline mode, mainly for deterministic reproducibility - `SigningKeyPair` handles key management, generation and storage via `ed25519` - Namespacing for key identification, this is important because we need to track key rotation and support for multiple active keys during transitions - `BundleManager` and `BundleBuilder` handles bundling and packing - API layer exposes three core endpoints: - /api/v1/manifest - Bundle metadata - /api/v1/bundle - Bundle download - /api/v1/key - Public key access - `hoppscotch-agent`: - Added registration management interface with timestamps and masked hashes - This can be accessed from agent's tray icon menu - Implemented simpler window handling system, reusing single window for registration - Windows showing up for OTP and registration list should be faster and more lightweight. - Windows now have show/hide button + auto-hide - Added JSON structured logging system with RFC 3339 timestamps and daily rotation - Agent now logs every flow better - Added log forwarding capabilities with context-aware logging - standardized log file location at `<app_data_dir>/hoppscotch-agent-YYYY-MM-DD.log`. - Added log sink endpoint with path `POST /log-sink` accepting Authorization bearer token and encrypted payload - It expects logs from the web app that can be consolidated with a correlation id - `hoppscotch-backend`: - Added a new authentication flow mirroring Firebase methodology with browser-based authentication for the desktop app - See `hoppscotch-selfhost-web`'s `platform/auth` implementation. - Added bearer token implementation via `Authorization` header - Considered cookie based approach but some proxy server strip those away so defaulting to web standards - Fixed SSL context cleanup issue in curl's SSL callback - Since this exchange is now handled by native interceptor - Added bearer token parsing in JWT strategy handler and simple auth passthrough in WebSocket upgrade calls. - Added general token parsing for core authentication work - Created new auth/desktop endpoint with browser redirection ### Note to reviewers Simplest way to test out app server and desktop app would be as follows: ``` ❯ cp .env.example .env ❯ pnpm install ``` then ``` ❯ cd packages/hoppscotch-selfhost-web/ && pnpm install && pnpm generate && cd webapp-server && RUST_LOG=debug cargo run ``` This will start up a webapp server (like mentioned in the web section above). This server serves selfhosted app (purely for testing purposes, for prod-like setup use `docker compose --profile default up --build` more info later) Now if this is the first time running the app, do a full build via ``` ❯ cd packages/hoppscotch-desktop && RUST_LOG=debug pnpm dev:full # or pnpm build:full ``` but for any subsequent run, do this instead (much faster) ``` ❯ cd packages/hoppscotch-desktop/src-tauri && RUST_LOG=debug pnpm tauri dev ``` The difference being vendored vs purely selfhost shell, for all intents and purposes, `pnpm dev:full` is a safer bet and for build, when in doubt `pnpm build:full`. Remember, all the commands assumes you have `cargo` (with `rustup` with `nightly` toolchain `rustup default nightly`) and `pnpm` installed on your machine, otherwise for fully reproducible development environment, best way to setup all instances and app suite would be as follows: ``` ❯ devenv shell ``` This will load a reproducible development environment (with docker powered by `colima`), then ``` ❯ cp .env.example .env ❯ pnpm install ``` followed by ``` ❯ colima-start ``` This will setup docker with minimal system requirements, finally the same instructions as before ``` ❯ cd packages/hoppscotch-selfhost-web/ && pnpm install && pnpm generate && cd webapp-server && RUST_LOG=debug cargo run ``` and then in a different terminal instance this (if it's your first time running the app from scratch) ``` ❯ cd packages/hoppscotch-desktop && RUST_LOG=debug pnpm dev:full # or pnpm build:full ``` or this (if you've already built vendored app) ``` ❯ cd packages/hoppscotch-desktop/src-tauri && RUST_LOG=debug pnpm tauri dev ``` or for fully functional all service setup, try ``` ❯ docker compose --profile default up --build ``` See `docker-compose.yml` in monorepo root for more detailed information. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-17 02:23:36 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hoppscotch#4900
No description provided.