Fix: Organization lookup for custom fields integrations (Bluesky, Reddit, etc.)#1209
Fix: Organization lookup for custom fields integrations (Bluesky, Reddit, etc.)#1209smcpeck wants to merge 3 commits intogitroomhq:mainfrom
Conversation
…it, etc.) Custom fields integrations (Bluesky, Reddit, Lemmy, etc.) were failing with "Organization not found" error because they skip the OAuth initialization flow that populates Redis with organization data. The frontend sends state="nostate" for these integrations, but the backend was still trying to look up "organization:nostate" in Redis, which doesn't exist. This fix: - Adds @GetOrgFromRequest() decorator to access the authenticated user's organization - Uses the request organization for custom fields integrations - Maintains the existing Redis lookup for OAuth-based integrations Fixes the issue where users couldn't connect Bluesky, Reddit, and other custom-field integrations to their self-hosted Postiz instances.
|
Someone is attempting to deploy a commit to the Listinai Team on Vercel. A member of the Team first needs to authorize it. |
… request.org The NoAuthIntegrationsController was not included in the authenticatedController array, which meant AuthMiddleware was never applied to it. This caused request.org to be undefined, breaking the custom fields integration fix. Adding it to authenticatedController ensures: - AuthMiddleware populates request.org from the JWT token - @GetOrgFromRequest() decorator returns the proper organization - Custom fields integrations (Bluesky, Reddit, etc.) can access org.id This controller already uses @CheckPolicies() decorator requiring authentication, so applying AuthMiddleware is consistent with its existing security model.
Update: Critical Fix AppliedThanks to the automated code review, a critical issue was identified and has now been fixed. The ProblemThe
Why OAuth integrations (Mastodon) worked but custom fields (Bluesky) didn'tOAuth flow (Mastodon, Twitter, etc.):
Custom fields flow (Bluesky, Reddit, etc.):
The FixAdded
Note: The controller is named "NoAuth" but already uses Commits
The PR should now be ready for proper testing and review. 🚀 |
| AutopostController, | ||
| SetsController, | ||
| ThirdPartyController, | ||
| NoAuthIntegrationsController, |
There was a problem hiding this comment.
Bug: Applying AuthMiddleware to NoAuthIntegrationsController will cause all unauthenticated OAuth integration callbacks to fail with a 403 Forbidden error, as they lack the required authentication token.
Severity: CRITICAL
Suggested Fix
Revert the change in api.module.ts by moving NoAuthIntegrationsController out of the authenticatedController array. This controller must handle unauthenticated requests for OAuth callbacks to function correctly. An alternative method should be used to provide the organization context for the routes that require it, without enforcing authentication on the entire controller.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: apps/backend/src/api/api.module.ts#L52
Potential issue: Moving `NoAuthIntegrationsController` to the `authenticatedController`
array in `api.module.ts` applies `AuthMiddleware` to all its routes. This middleware
requires an authentication token and throws a `HttpForbiddenException` if one is not
present. OAuth callbacks from external providers (e.g., X/Twitter, LinkedIn) are
inherently unauthenticated as they are server-to-server redirects without a user's JWT.
Consequently, these callbacks will be rejected with a 403 Forbidden error before
reaching the controller logic, breaking all OAuth-based channel integrations.
Thank You for the Automated ReviewWe appreciate the thorough automated code review and the feedback provided. The suggestions have already helped improve this PR significantly (specifically catching the missing AuthMiddleware configuration). Context on This ContributionWe are community contributors who encountered this bug while self-hosting Postiz. After reproducing the issue and validating a workaround (manually setting the Redis key), we traced the root cause and developed what we believe is a proper fix. However, we want to be transparent: We don't have deep knowledge of the entire Postiz codebase architecture. While we've:
We acknowledge there may be additional edge cases, architectural considerations, or codebase conventions we're not fully aware of. Our GoalWe hope this PR provides a solid starting point for the Postiz team to:
We're contributing this in the spirit of open source collaboration - identifying a real issue affecting self-hosted users and offering our best attempt at a fix. If the Postiz maintainers can take this across the finish line and refine it further, that would be fantastic for the community. Thank you for maintaining this excellent project, and we're happy to answer any questions or provide additional testing assistance! 🙏 |
Problem
Custom fields integrations (Bluesky, Reddit, Lemmy, Nostr, etc.) fail with "Organization not found" error when users attempt to connect them in self-hosted Postiz instances.
Root Cause
The issue occurs because custom fields integrations follow a different authentication flow than OAuth integrations:
OAuth integrations (Mastodon, X/Twitter, LinkedIn, etc.):
organization:{state}in RedisCustom fields integrations (Bluesky, Reddit, etc.):
state: "nostate"to the connection endpointorganization:nostatein Redis ❌The backend code assumed all integrations go through the OAuth flow with Redis state management, but custom fields integrations bypass this entirely.
Solution
This PR fixes the issue by detecting custom fields integrations and using the authenticated user's organization directly from the request context, rather than attempting a Redis lookup.
Changes
Import new dependencies:
GetOrgFromRequestdecorator to access the authenticated user's organizationOrganizationtype from Prisma clientAdd organization parameter:
@GetOrgFromRequest() requestOrg: Organizationto theconnectSocialMediamethodConditional organization lookup:
customFieldsintegrations: UserequestOrgfrom the authenticated requestThis approach:
Testing
What we tested:
Reproduced the bug:
Error: Organization not found at NoAuthIntegrationsController.connectSocialMediastate: "nostate"in request bodyorganization:nostate(doesn't exist)Validated the workaround:
organization:nostatein Redis with the user's organizationIdCode review:
@GetOrgFromRequest()decorator is used extensively in other controllersCheckPoliciesdecorator provides authentication/authorizationRecommended testing before merge:
Steps to reproduce and verify
Impact
This fix enables all custom fields integrations to work properly in self-hosted Postiz instances:
Without this fix, these integrations are completely unusable in self-hosted deployments.
Request for Review
While the code changes are minimal and follow existing patterns in the codebase, this PR has not been fully integration tested in a live environment with the actual changes deployed. The fix is based on:
Specific areas for review:
@GetOrgFromRequest()properly handle the organization context for custom fields flows?Suggested by: Community contributor (self-hosted user)
Maintainer testing recommended: Yes, before merge
Related
This issue likely affects anyone self-hosting Postiz with
IS_GENERAL: truewho attempts to connect custom fields integrations.