[GH-ISSUE #1376] Deleting organization works through web UI but not through API on self hosted #3824

Closed
opened 2026-04-20 07:58:48 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @QuuR32 on GitHub (Aug 28, 2025).
Original GitHub issue: https://github.com/fosrl/pangolin/issues/1376

Hello there,

First, thank you so much for the work done. The project is amazing and makes me want to use it and explore everything possible.

I've setup a self hosted application following this documentation, and everything for the API to work as explained here.

Everything works fine for the moment with the API, expect the DELETE /org/{orgId} endpoint. It's responding with a 500 status code and this content:

{
    "data": null,
    "success": false,
    "error": true,
    "message": "An error occurred...",
    "status": 500,
    "stack": null
}

Using the web UI, it works fine. It looks like the call made to https://my.panglin.webui.url/api/v1/org/{orgId} works but not to the internal API.

Any clue on that would help me a lot (I am building a terraform provider for pangolin).

Thanks

Originally created by @QuuR32 on GitHub (Aug 28, 2025). Original GitHub issue: https://github.com/fosrl/pangolin/issues/1376 Hello there, First, thank you so much for the work done. The project is amazing and makes me want to use it and explore everything possible. I've setup a self hosted application following this [documentation](https://docs.digpangolin.com/self-host/manual/docker-compose), and everything for the API to work as explained [here](https://docs.digpangolin.com/self-host/advanced/integration-api). Everything works fine for the moment with the API, expect the DELETE /org/{orgId} endpoint. It's responding with a 500 status code and this content: ``` { "data": null, "success": false, "error": true, "message": "An error occurred...", "status": 500, "stack": null } ``` Using the web UI, it works fine. It looks like the call made to [https://my.panglin.webui.url/api/v1/org/{orgId}](https://my.panglin.webui.url/api/v1/org/{orgId}) works but not to the internal API. Any clue on that would help me a lot (I am building a terraform provider for pangolin). Thanks
Author
Owner

@Pallavikumarimdb commented on GitHub (Aug 28, 2025):

Hi @QuuR32 , From your description, it looks like the DELETE /api/v1/org/{orgId} request is hitting the internal API (internal server port) on your self-hosted instance. This server mounts internal.ts, which does not have a deleteOrg route, so Express returns a 500 error.

The reason the web UI works is that it calls the external API server (external port), which uses external.ts and has the correct deleteOrg route.

To fix this for API access:

  • For API keys / integrations: Send your DELETE request to the integration API server on the integration_port. This server mounts integration.ts and includes the deleteOrg route.

If you need internal-only API deletion, a route can be added to internal.ts to support it. I’ll add this route in a future update.

<!-- gh-comment-id:3235180564 --> @Pallavikumarimdb commented on GitHub (Aug 28, 2025): Hi @QuuR32 , From your description, it looks like the DELETE /api/v1/org/{orgId} request is hitting the internal API (internal server port) on your self-hosted instance. This server mounts internal.ts, which does not have a deleteOrg route, so Express returns a 500 error. The reason the web UI works is that it calls the external API server (external port), which uses external.ts and has the correct deleteOrg route. **To fix this for API access:** - For API keys / integrations: Send your DELETE request to the integration API server on the integration_port. This server mounts integration.ts and includes the deleteOrg route. If you need internal-only API deletion, a route can be added to internal.ts to support it. I’ll add this route in a future update.
Author
Owner

@QuuR32 commented on GitHub (Aug 29, 2025):

Hi @Pallavikumarimdb , thanks for your quick reply.

Just to be sure, are you talking about this route ?

Image

Cause it's the only route for now that is not working for me. All the other routes work fine.

Also when I look at the logs in pangolin container, I can see those lines when calling the /org/{orgId} API route:

pangolin    | 2025-08-28T20:42:07.215Z [error]: User not authenticated
pangolin    | Stack: UnauthorizedError: User not authenticated
pangolin    |     at gs (file:///app/dist/server.mjs:22:9243)
pangolin    |     at ua (file:///app/dist/server.mjs:28:23301)
pangolin    |     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
pangolin    |     at next (/app/node_modules/express/lib/router/route.js:149:13)
pangolin    |     at file:///app/dist/server.mjs:22:27767

Even though I'm using an API key with full access:

Image

Thanks

<!-- gh-comment-id:3235769901 --> @QuuR32 commented on GitHub (Aug 29, 2025): Hi @Pallavikumarimdb , thanks for your quick reply. Just to be sure, are you talking about this route ? <img width="1439" height="763" alt="Image" src="https://github.com/user-attachments/assets/9bada649-d7ec-4dea-9bef-768df589ec8e" /> Cause it's the only route for now that is not working for me. All the other routes work fine. Also when I look at the logs in pangolin container, I can see those lines when calling the /org/{orgId} API route: ``` pangolin | 2025-08-28T20:42:07.215Z [error]: User not authenticated pangolin | Stack: UnauthorizedError: User not authenticated pangolin | at gs (file:///app/dist/server.mjs:22:9243) pangolin | at ua (file:///app/dist/server.mjs:28:23301) pangolin | at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) pangolin | at next (/app/node_modules/express/lib/router/route.js:149:13) pangolin | at file:///app/dist/server.mjs:22:27767 ``` Even though I'm using an API key with full access: <img width="814" height="503" alt="Image" src="https://github.com/user-attachments/assets/9f712dd2-9836-4565-9fe7-0ebfa38f006c" /> Thanks
Author
Owner

@Pallavikumarimdb commented on GitHub (Aug 29, 2025):

Hi @QuuR32 , Now I can see what's causing this issue:

The deleteOrg function always calls checkUserActionPermission(), which expects req.user.userId. API key authentication doesn’t populate req.user the same way as web UI authentication.

  • The DELETE /org/{orgId} API endpoint expects a logged-in user.
  • With an API key, the system doesn’t set up the user info, so it thinks you’re not authenticated even though the API key is valid.
  • Other API endpoints used by you works correctly with API keys because they don’t call checkUserActionPermission.

For now, organizations need to be deleted via the web UI.

Fix Needed:
deleteOrg should either:

  1. Skip checkUserActionPermission when using API key auth (permissions are already verified by verifyApiKeyIsRoot + verifyApiKeyHasAction), or
  2. Ensure API key middleware populates req.user properly.

Hi @oschwartz10612 , it seems this function assumes session-based auth, while the API route uses API key auth. Should deleteOrg skip the user permission check when req.apiKey exists?

<!-- gh-comment-id:3236458031 --> @Pallavikumarimdb commented on GitHub (Aug 29, 2025): Hi @QuuR32 , Now I can see what's causing this issue: The `deleteOrg` function always calls `checkUserActionPermission()`, which expects `req.user.userId`. API key authentication doesn’t populate `req.user` the same way as web UI authentication. * The DELETE `/org/{orgId}` API endpoint expects a logged-in user. * With an API key, the system doesn’t set up the user info, so it thinks you’re not authenticated even though the API key is valid. * Other API endpoints used by you works correctly with API keys because they don’t call `checkUserActionPermission`. For now, organizations need to be deleted via the web UI. **Fix Needed:** `deleteOrg` should either: 1. Skip `checkUserActionPermission` when using API key auth (permissions are already verified by `verifyApiKeyIsRoot` + `verifyApiKeyHasAction`), or 2. Ensure API key middleware populates `req.user` properly. Hi @oschwartz10612 , it seems this function assumes session-based auth, while the API route uses API key auth. Should `deleteOrg` skip the user permission check when `req.apiKey` exists?
Author
Owner

@oschwartz10612 commented on GitHub (Aug 31, 2025):

Thanks for identifying the issue @Pallavikumarimdb!

I fixed this in f37eda4739 I believe. Let
me know if you agree. I think it was simplest to just move it to the
external.ts file like the others. This might have been an old thing.

<!-- gh-comment-id:3239785864 --> @oschwartz10612 commented on GitHub (Aug 31, 2025): Thanks for identifying the issue @Pallavikumarimdb! I fixed this in f37eda473915b380fee822a9d3e91e05068c1b61 I believe. Let me know if you agree. I think it was simplest to just move it to the external.ts file like the others. This might have been an old thing.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/pangolin#3824