[PR #3449] [MERGED] feat: support for subpath based access in SH apps #4388

Closed
opened 2026-03-17 01:55:44 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/hoppscotch/hoppscotch/pull/3449
Author: @jamesgeorge007
Created: 10/12/2023
Status: Merged
Merged: 11/22/2023
Merged by: @AndrewBastin

Base: release/2023.12.0Head: feat/subpath-based-access


📝 Commits (10+)

  • b212479 refactor: make service worker ignore important routes
  • 4fb351d chore: update aio Caddyfile
  • 6023cf0 chore: convey the base route as admin where sh-admin gets served
  • c46fea8 fix: ensure any non-existent file in the server is routed to the corresponding SPA
  • d8f7647 build: generate build with admin as the base for subpath based access
  • 2170037 refactor: infer base URL from the BASE_URL env var across the app
  • ae71134 chore: add TODO comment for pending Caddy configurations and port updates
  • 671cd01 chore: generate multiple builds for sh-admin
  • 7e10004 chore: dedicated Caddyfiles based on AIO container launch strategies
  • 15468a1 feat: subpath access for individual containers

📊 Changes

18 files changed (+262 additions, -48 deletions)

View changed files

📝 .env.example (+3 -0)
aio-multiport-setup.Caddyfile (+19 -0)
aio-subpath-access.Caddyfile (+37 -0)
aio.Caddyfile (+0 -11)
📝 aio_run.mjs (+2 -1)
📝 docker-compose.yml (+7 -3)
packages/hoppscotch-backend/backend.Caddyfile (+3 -0)
packages/hoppscotch-backend/prod_run.mjs (+66 -0)
📝 packages/hoppscotch-selfhost-web/Caddyfile (+3 -3)
packages/hoppscotch-selfhost-web/selfhost-web.Caddyfile (+5 -0)
📝 packages/hoppscotch-selfhost-web/vite.config.ts (+2 -0)
📝 packages/hoppscotch-sh-admin/Caddyfile (+3 -3)
📝 packages/hoppscotch-sh-admin/prod_run.mjs (+64 -12)
packages/hoppscotch-sh-admin/sh-admin-multiport-setup.Caddyfile (+5 -0)
packages/hoppscotch-sh-admin/sh-admin-subpath-access.Caddyfile (+11 -0)
📝 packages/hoppscotch-sh-admin/src/modules/router.ts (+1 -1)
📝 packages/hoppscotch-sh-admin/src/pages/_.vue (+3 -1)
📝 prod.Dockerfile (+28 -13)

📄 Description

Description

This PR includes the changes for providing subpath-based access support in the AIO container and for individual containers. Two builds are generated for sh-admin to make the transition from/to subpath-based access seamless. The idea is to not call for the need to rebuild the containers while switching between multiport setup and subpath-based access.

Closes HFE-252 HBE-283 HBE-284.

Changes

  • Makes the service worker ignore the /admin/* and /backend/* routes such that it is always fetched from the network. The reverse proxy takes control and routes it to the corresponding service.

  • Two builds are generated for sh-admin:

    • The legacy build with / as the base path - is generated in dist-multiport-setup.
    • With /admin set as the base path and the necessary prefixes added wherever necessary (/admin for images within the public directory and set it as a base while initializing the Vue router module so the SPA considers part of the route that appears after /admin) - generated in dist-subpath-access.
    • Both the above directories are copied to the container file system.
      • dist -> /site/-sh-admin-multiport-setup
      • dist-subpath-access -> /site/sh-admin-subpath-access
  • Dedicated Caddyfiles are introduced for the AIO container corresponding to the different launch strategies (multiport setup and subpath-based access).

    aio-subpath-access.Caddyfile

    • selfhost-web SPA is served on the root path / by default.
    • sh-admin SPA is served at the /admin path. It serves the static files from /site/sh-admin-subpath-access with /admin as the base path.
    • Backend requests hitting /backend are reverse proxied to port 8080, where the server is up and running.
    • In the context of sh-admin when you initiate a full reload while on a specific route that lacks a corresponding HTML file on the server's file system, the request is redirected to the root path. This redirection is achieved by leveraging Caddy's try_files directive. As a result, control is gracefully handed back to the SPA, allowing it to handle and render the appropriate view according to the requested route. Similarly, for "selfhost-web," we have implemented a catch-all route strategy.
    • Responds with 404 on visiting ports 3000 and 3100.

    aio-multiport-setup.Caddyfile

    • Includes the current set of changes from aio.Caddyfile serving selfhost-web on port 3000 and sh-admin legacy build on port 3100.
    • Responds with 404 on visiting port 3080 that maps to port 80 in the container.

    Both the files are copied over and picked based on the value for the ENABLE_SUBPATH_BASED_ACCESS environment variable within the aio_run.mjs launch script.

  • Introduces 2 Caddyfiles for sh-admin, sh-admin-multiport-setup.Caddyfile & sh-admin-subpath-access.Caddyfile. Both listen on ports 3100 & 80 (standard HTTP ingress port) and serve the respective directories (multiport setup/subpath-based access).

    Both the files are copied over to the container and the one to be consumed is determined in the prod_run.js script based on the value for the ENABLE_SUBPATH_BASED_ACCESS environment variable.

  • For the backend container, a new Caddyfile is added, backend.Caddyfile -> Acts as a reverse proxy on ports 80 (standard HTTP ingress port) and 3170 and forwards them to localhost:8080 where the backend server is up and running.

    The launch script prod_run.mjs starts the server and the Caddy service.

    The server is made to run on port 8080 which was previously at 3170. This was required since Caddy now sets listeners on ports 80 and 3170.

  • Additional Caddyfile added for selfhost-web, selfhost-web.Caddyfile that listens on ports (standard HTTP ingress port) 80 & 3000 and serves the static files.

The user needs to maintain a reverse proxy in front to achieve the subpath-based access behavior for individual containers. For instance, refer to the below Caddyfile.

:3500 {
	reverse_proxy /admin* localhost:3100

	handle_path /backend* {
		reverse_proxy localhost:3170
	}

	reverse_proxy localhost:3000
}

A 404 page is displayed if attempting to visit the sh-admin service individually from localhost:3100 or localhost:3280 while opting for subpath-based access since the build served is supposed to be from /admin.

Steps to verify

Spin up the AIO container with docker compose up hoppscotch-aio.

  • AIO container with multiport setup

    • Make the following updates to .env.

      WHITELISTED_ORIGINS=http://localhost:3170,http://localhost:3000,http://localhost:3100
      
      REDIRECT_URL=http://localhost:3000
      
      # Base URL
      VITE_BASE_URL=http://localhost:3000
      VITE_SHORTCODE_BASE_URL=http://localhost:3000
      VITE_ADMIN_URL=http://localhost:3100
      
      # Backend URLs
      VITE_BACKEND_GQL_URL=http://localhost:3170/graphql
      VITE_BACKEND_WS_URL=ws://localhost:3170/graphql
      VITE_BACKEND_API_URL=http://localhost:3170/v1
      
      ENABLE_SUBPATH_BASED_ACCESS=false
      
    • Access services

      selfhost-web -> localhost:3000
      sh-admin -> localhost:3100
      backend -> localhost:3170

  • AIO container with subpath-based access enabled

    • Make the following updates to .env.

      WHITELISTED_ORIGINS=http://localhost:3080,http://localhost:3080/admin
      
      REDIRECT_URL=http://localhost:3080
      
      # Base URL
      VITE_BASE_URL=http://localhost:3080
      VITE_SHORTCODE_BASE_URL=http://localhost:3080
      VITE_ADMIN_URL=http://localhost:3080/admin
      
      # Backend URLs
      VITE_BACKEND_GQL_URL=http://localhost:3080/backend/graphql
      VITE_BACKEND_WS_URL=ws://localhost:3080/backend/graphql
      VITE_BACKEND_API_URL=http://localhost:3080/backend/v1
      
      ENABLE_SUBPATH_BASED_ACCESS=true
      
    • Access services

      selfhost-web -> localhost:3080
      sh-admin -> localhost:3080/admin
      backend -> localhost:3080/backend

Spin up the individual containers with the following commands.

  • selfhost-web -> docker compose up hoppscotch-app.

  • sh-admin -> docker compose up hoppscotch-sh-admin.

  • backend -> docker compose up hoppscotch-backend (Optional since the above stages have this as a dependency).

  • Individual containers with multiport setup and bound to legacy ports.

    • Make the following updates to .env.

      WHITELISTED_ORIGINS=http://localhost:3000,http://localhost:3100,http://localhost:3170
      
      REDIRECT_URL=http://localhost:3000
      
      # Base URL
      VITE_BASE_URL=http://localhost:3000
      VITE_SHORTCODE_BASE_URL=http://localhost:3000
      VITE_ADMIN_URL=http://localhost:3100
      
      # Backend URLs
      VITE_BACKEND_GQL_URL=http://localhost:3170/graphql
      VITE_BACKEND_WS_URL=ws://localhost:3170/graphql
      VITE_BACKEND_API_URL=http://localhost:3170/v1
      
      ENABLE_SUBPATH_BASED_ACCESS=false
      
    • Access services

      selfhost-web -> localhost:3000
      sh-admin -> localhost:3100
      backend -> localhost:3170

  • Individual containers with multiport setup and bound standard HTTP port (80)

    • Make the following updates to .env.

      WHITELISTED_ORIGINS=http://localhost:3080,http://localhost:3280,http://localhost:3180
      
      REDIRECT_URL=http://localhost:3080
      
      # Base URL
      VITE_BASE_URL=http://localhost:3080
      VITE_SHORTCODE_BASE_URL=http://localhost:3080
      VITE_ADMIN_URL=http://localhost:3280
      
      # Backend URLs
      VITE_BACKEND_GQL_URL=http://localhost:3180/graphql
      VITE_BACKEND_WS_URL=ws://localhost:3180/graphql
      VITE_BACKEND_API_URL=http://localhost:3180/v1
      
      ENABLE_SUBPATH_BASED_ACCESS=false
      
    • Access services

      selfhost-web -> localhost:3080
      sh-admin -> localhost:3280
      backend -> localhost:3180

  • Individual containers with subpath-based access enabled bound to legacy ports & standard HTTP port (80)

    • Add a Caddyfile to the root path.

        :3500 {
          reverse_proxy /admin* localhost:3100
      
          handle_path /backend* {
                  reverse_proxy localhost:3170
          }
      
          reverse_proxy localhost:3000
        } 
      
    • Make the following updates to .env.

      WHITELISTED_ORIGINS=http://localhost:3500,http://localhost:3500/admin,http://localhost:3100,http://localhost:3280
      
      REDIRECT_URL=http://localhost:3500
      
      # Base URLs
      VITE_BASE_URL=http://localhost:3500
      VITE_SHORTCODE_BASE_URL=http://localhost:3500
      VITE_ADMIN_URL=http://localhost:3500/admin
      
      # Backend URLs
      VITE_BACKEND_GQL_URL=http://localhost:3500/backend/graphql
      VITE_BACKEND_WS_URL=ws://localhost:3500/backend/graphql
      VITE_BACKEND_API_URL=http://localhost:3500/backend/v1
      
      ENABLE_SUBPATH_BASED_ACCESS=true
      
    • Spin up the individual containers and start Caddy with caddy run at the path where the above Caddyfile exists to access the services.

      selfhost-web -> localhost:3500
      sh-admin -> localhost:3500/admin
      backend -> localhost:3500/backend

Checks

  • My pull request adheres to the code style of this project
  • My code requires changes to the documentation
  • Updates required to documentation are tracked in HP-174.
  • All the tests have passed

🔄 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/3449 **Author:** [@jamesgeorge007](https://github.com/jamesgeorge007) **Created:** 10/12/2023 **Status:** ✅ Merged **Merged:** 11/22/2023 **Merged by:** [@AndrewBastin](https://github.com/AndrewBastin) **Base:** `release/2023.12.0` ← **Head:** `feat/subpath-based-access` --- ### 📝 Commits (10+) - [`b212479`](https://github.com/hoppscotch/hoppscotch/commit/b212479a9de6a68467b8ef416d16c4d1c118f85b) refactor: make service worker ignore important routes - [`4fb351d`](https://github.com/hoppscotch/hoppscotch/commit/4fb351dd7d72bbd19e0c0d46b11028839b6d6880) chore: update aio Caddyfile - [`6023cf0`](https://github.com/hoppscotch/hoppscotch/commit/6023cf09080fdfe0e8ed1fffc99205bc5660b4c5) chore: convey the base route as admin where sh-admin gets served - [`c46fea8`](https://github.com/hoppscotch/hoppscotch/commit/c46fea81d9582462b0db19055253f4ea131a3fde) fix: ensure any non-existent file in the server is routed to the corresponding SPA - [`d8f7647`](https://github.com/hoppscotch/hoppscotch/commit/d8f7647fe43291aec521cb813b7d2a62d5ac2a7f) build: generate build with admin as the base for subpath based access - [`2170037`](https://github.com/hoppscotch/hoppscotch/commit/21700379382248a406b5a98c45d987350bf826ed) refactor: infer base URL from the BASE_URL env var across the app - [`ae71134`](https://github.com/hoppscotch/hoppscotch/commit/ae71134e7412d992faf5b42424aa72ad97c7b70f) chore: add TODO comment for pending Caddy configurations and port updates - [`671cd01`](https://github.com/hoppscotch/hoppscotch/commit/671cd0164ecd647c3fa30d873424683a7dce22c8) chore: generate multiple builds for sh-admin - [`7e10004`](https://github.com/hoppscotch/hoppscotch/commit/7e10004e5d9d9c8240b9b8a4878e31546617e2bc) chore: dedicated Caddyfiles based on AIO container launch strategies - [`15468a1`](https://github.com/hoppscotch/hoppscotch/commit/15468a1c8a434a3c61eed0cf2cfc17b000c99ae3) feat: subpath access for individual containers ### 📊 Changes **18 files changed** (+262 additions, -48 deletions) <details> <summary>View changed files</summary> 📝 `.env.example` (+3 -0) ➕ `aio-multiport-setup.Caddyfile` (+19 -0) ➕ `aio-subpath-access.Caddyfile` (+37 -0) ➖ `aio.Caddyfile` (+0 -11) 📝 `aio_run.mjs` (+2 -1) 📝 `docker-compose.yml` (+7 -3) ➕ `packages/hoppscotch-backend/backend.Caddyfile` (+3 -0) ➕ `packages/hoppscotch-backend/prod_run.mjs` (+66 -0) 📝 `packages/hoppscotch-selfhost-web/Caddyfile` (+3 -3) ➕ `packages/hoppscotch-selfhost-web/selfhost-web.Caddyfile` (+5 -0) 📝 `packages/hoppscotch-selfhost-web/vite.config.ts` (+2 -0) 📝 `packages/hoppscotch-sh-admin/Caddyfile` (+3 -3) 📝 `packages/hoppscotch-sh-admin/prod_run.mjs` (+64 -12) ➕ `packages/hoppscotch-sh-admin/sh-admin-multiport-setup.Caddyfile` (+5 -0) ➕ `packages/hoppscotch-sh-admin/sh-admin-subpath-access.Caddyfile` (+11 -0) 📝 `packages/hoppscotch-sh-admin/src/modules/router.ts` (+1 -1) 📝 `packages/hoppscotch-sh-admin/src/pages/_.vue` (+3 -1) 📝 `prod.Dockerfile` (+28 -13) </details> ### 📄 Description ### Description This PR includes the changes for providing subpath-based access support in the AIO container and for individual containers. Two builds are generated for `sh-admin` to make the transition from/to subpath-based access seamless. The idea is to not call for the need to rebuild the containers while switching between multiport setup and subpath-based access. Closes HFE-252 HBE-283 HBE-284. ### Changes - Makes the service worker ignore the `/admin/*` and `/backend/*` routes such that it is always fetched from the network. The reverse proxy takes control and routes it to the corresponding service. - Two builds are generated for `sh-admin`: - The legacy build with `/` as the base path - is generated in `dist-multiport-setup`. - With `/admin` set as the base path and the necessary prefixes added wherever necessary (`/admin` for images within the public directory and set it as a base while initializing the Vue router module so the SPA considers part of the route that appears after `/admin`) - generated in `dist-subpath-access`. - Both the above directories are copied to the container file system. - `dist` -> `/site/-sh-admin-multiport-setup` - `dist-subpath-access` -> `/site/sh-admin-subpath-access` - Dedicated Caddyfiles are introduced for the AIO container corresponding to the different launch strategies (multiport setup and subpath-based access). `aio-subpath-access.Caddyfile` - `selfhost-web` SPA is served on the root path `/` by default. - `sh-admin` SPA is served at the `/admin` path. It serves the static files from `/site/sh-admin-subpath-access` with `/admin` as the base path. - Backend requests hitting `/backend` are reverse proxied to port `8080`, where the server is up and running. - In the context of `sh-admin` when you initiate a full reload while on a specific route that lacks a corresponding HTML file on the server's file system, the request is redirected to the root path. This redirection is achieved by leveraging Caddy's `try_files` directive. As a result, control is gracefully handed back to the SPA, allowing it to handle and render the appropriate view according to the requested route. Similarly, for "selfhost-web," we have implemented a catch-all route strategy. - Responds with `404` on visiting ports `3000` and `3100`. `aio-multiport-setup.Caddyfile` - Includes the current set of changes from `aio.Caddyfile` serving `selfhost-web` on port `3000` and `sh-admin` legacy build on port `3100`. - Responds with `404` on visiting port `3080` that maps to port `80` in the container. > Both the files are copied over and picked based on the value for the `ENABLE_SUBPATH_BASED_ACCESS` environment variable within the `aio_run.mjs` launch script. - Introduces 2 Caddyfiles for `sh-admin`, `sh-admin-multiport-setup.Caddyfile` & `sh-admin-subpath-access.Caddyfile`. Both listen on ports `3100` & `80` (standard HTTP ingress port) and serve the respective directories (multiport setup/subpath-based access). > Both the files are copied over to the container and the one to be consumed is determined in the `prod_run.js` script based on the value for the `ENABLE_SUBPATH_BASED_ACCESS` environment variable. - For the backend container, a new Caddyfile is added, `backend.Caddyfile` -> Acts as a reverse proxy on ports `80` (standard HTTP ingress port) and `3170` and forwards them to `localhost:8080` where the backend server is up and running. > The launch script `prod_run.mjs` starts the server and the Caddy service. > The server is made to run on port `8080` which was previously at `3170`. This was required since Caddy now sets listeners on ports `80` and `3170`. - Additional Caddyfile added for `selfhost-web`, `selfhost-web.Caddyfile` that listens on ports (standard HTTP ingress port) `80` & `3000` and serves the static files. The user needs to maintain a reverse proxy in front to achieve the subpath-based access behavior for individual containers. For instance, refer to the below Caddyfile. ``` :3500 { reverse_proxy /admin* localhost:3100 handle_path /backend* { reverse_proxy localhost:3170 } reverse_proxy localhost:3000 } ``` A `404` page is displayed if attempting to visit the `sh-admin` service individually from `localhost:3100` or `localhost:3280` while opting for subpath-based access since the build served is supposed to be from `/admin`. ### Steps to verify > Spin up the AIO container with `docker compose up hoppscotch-aio`. - #### AIO container with multiport setup - Make the following updates to `.env`. ``` WHITELISTED_ORIGINS=http://localhost:3170,http://localhost:3000,http://localhost:3100 REDIRECT_URL=http://localhost:3000 # Base URL VITE_BASE_URL=http://localhost:3000 VITE_SHORTCODE_BASE_URL=http://localhost:3000 VITE_ADMIN_URL=http://localhost:3100 # Backend URLs VITE_BACKEND_GQL_URL=http://localhost:3170/graphql VITE_BACKEND_WS_URL=ws://localhost:3170/graphql VITE_BACKEND_API_URL=http://localhost:3170/v1 ENABLE_SUBPATH_BASED_ACCESS=false ``` - Access services `selfhost-web` -> `localhost:3000` `sh-admin` -> `localhost:3100` `backend` -> `localhost:3170` - #### AIO container with subpath-based access enabled - Make the following updates to `.env`. ``` WHITELISTED_ORIGINS=http://localhost:3080,http://localhost:3080/admin REDIRECT_URL=http://localhost:3080 # Base URL VITE_BASE_URL=http://localhost:3080 VITE_SHORTCODE_BASE_URL=http://localhost:3080 VITE_ADMIN_URL=http://localhost:3080/admin # Backend URLs VITE_BACKEND_GQL_URL=http://localhost:3080/backend/graphql VITE_BACKEND_WS_URL=ws://localhost:3080/backend/graphql VITE_BACKEND_API_URL=http://localhost:3080/backend/v1 ENABLE_SUBPATH_BASED_ACCESS=true ``` - Access services `selfhost-web` -> `localhost:3080` `sh-admin` -> `localhost:3080/admin` `backend` -> `localhost:3080/backend` > Spin up the individual containers with the following commands. - `selfhost-web` -> `docker compose up hoppscotch-app`. - `sh-admin` -> `docker compose up hoppscotch-sh-admin`. - `backend` -> `docker compose up hoppscotch-backend` (Optional since the above stages have this as a dependency). - #### Individual containers with multiport setup and bound to legacy ports. - Make the following updates to `.env`. ``` WHITELISTED_ORIGINS=http://localhost:3000,http://localhost:3100,http://localhost:3170 REDIRECT_URL=http://localhost:3000 # Base URL VITE_BASE_URL=http://localhost:3000 VITE_SHORTCODE_BASE_URL=http://localhost:3000 VITE_ADMIN_URL=http://localhost:3100 # Backend URLs VITE_BACKEND_GQL_URL=http://localhost:3170/graphql VITE_BACKEND_WS_URL=ws://localhost:3170/graphql VITE_BACKEND_API_URL=http://localhost:3170/v1 ENABLE_SUBPATH_BASED_ACCESS=false ``` - Access services `selfhost-web` -> `localhost:3000` `sh-admin` -> `localhost:3100` `backend` -> `localhost:3170` - #### Individual containers with multiport setup and bound standard HTTP port (80) - Make the following updates to `.env`. ``` WHITELISTED_ORIGINS=http://localhost:3080,http://localhost:3280,http://localhost:3180 REDIRECT_URL=http://localhost:3080 # Base URL VITE_BASE_URL=http://localhost:3080 VITE_SHORTCODE_BASE_URL=http://localhost:3080 VITE_ADMIN_URL=http://localhost:3280 # Backend URLs VITE_BACKEND_GQL_URL=http://localhost:3180/graphql VITE_BACKEND_WS_URL=ws://localhost:3180/graphql VITE_BACKEND_API_URL=http://localhost:3180/v1 ENABLE_SUBPATH_BASED_ACCESS=false ``` - Access services `selfhost-web` -> `localhost:3080` `sh-admin` -> `localhost:3280` `backend` -> `localhost:3180` - #### Individual containers with subpath-based access enabled bound to legacy ports & standard HTTP port (80) - Add a `Caddyfile` to the root path. ``` :3500 { reverse_proxy /admin* localhost:3100 handle_path /backend* { reverse_proxy localhost:3170 } reverse_proxy localhost:3000 } ``` - Make the following updates to `.env`. ``` WHITELISTED_ORIGINS=http://localhost:3500,http://localhost:3500/admin,http://localhost:3100,http://localhost:3280 REDIRECT_URL=http://localhost:3500 # Base URLs VITE_BASE_URL=http://localhost:3500 VITE_SHORTCODE_BASE_URL=http://localhost:3500 VITE_ADMIN_URL=http://localhost:3500/admin # Backend URLs VITE_BACKEND_GQL_URL=http://localhost:3500/backend/graphql VITE_BACKEND_WS_URL=ws://localhost:3500/backend/graphql VITE_BACKEND_API_URL=http://localhost:3500/backend/v1 ENABLE_SUBPATH_BASED_ACCESS=true ``` - Spin up the individual containers and start Caddy with `caddy run` at the path where the above `Caddyfile` exists to access the services. `selfhost-web` -> `localhost:3500` `sh-admin` -> `localhost:3500/admin` `backend` -> `localhost:3500/backend` ### Checks - [x] My pull request adheres to the code style of this project - [x] My code requires changes to the documentation - [x] Updates required to documentation are tracked in [HP-174](https://linear.app/hopp/issue/HP-174/documentation-updates). - [x] All the tests have passed --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-17 01:55:44 +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#4388
No description provided.