Skip to content

Aditya Dhayapulay - Protect backend social publishing credentials - #2440

Open
adit24dhaya wants to merge 2 commits into
developmentfrom
feat/social-media-credential-security
Open

adit24dhaya wants to merge 2 commits into
developmentfrom
feat/social-media-credential-security

Conversation

@adit24dhaya

@adit24dhaya adit24dhaya commented Oct 29, 2026 •

Copy link
Copy Markdown

Description

Original task request

Original Phase I task, entry Create 100% secure method of hiding social media passwords · Task 1551. The complete original request and prior developer notes are captured below.

Complete original task, part 1
Complete original task, part 2
Complete original task, part 3

Jae's October 29 clarification, supplied by Aditya: “Definitely this: let backend publishing code use credentials without revealing them”. Jae also said he did not recognize Bitwarden or Okta and believed neither was configured. This PR implements the backend publishing scope using the existing server-side tokens; it does not add password viewing or assume a team vault/SSO deployment exists.

Provider errors could expose credential-bearing messages through publishing responses/logs and Mastodon schedule records. LinkedIn's routes also lacked Mastodon's announcements-permission gate. This change keeps those publishing paths behind the verified HGN identity and prevents raw provider errors from crossing the API/log boundary.

Related PRs

Related unfinished approach: HGNRest #2065. This is a new branch for the clarified requirement; the original contributor's branch is unchanged. It does not introduce #2065's list-all vault/password retrieval endpoints. No frontend PR is required.

Main changes explained

  • Validate backend-only Mastodon/LinkedIn configuration. Construct LinkedIn uploads using fixed HTTPS origins and documented upload paths; reject unrelated subdomains/paths and malformed URLs, preserve signed queries, and disable redirects.
  • Require the existing sendEmails announcements permission on both publishers' operations using req.user from verified JWT middleware, before LinkedIn multipart parsing. Submitted roles/requestors cannot grant access.
  • Return fixed errors and log only fixed operations/numeric statuses. Store safe scheduled errors, suppress historic raw schedule errors on read, and limit the immediate Mastodon success response to post ID/URL. Current frontend callers do not consume the removed provider fields.
  • Resolve scheduled LinkedIn tokens at delivery so stale tokens are not captured. Keep the original organization bound to its queued post; preserve existing Mastodon claim/retry rules.
  • Document operator setup and limitations in docs/social-media-publishing-security.md.

How to test

  1. Use Node 20 and the existing backend dependencies. No new dependency or real provider credential is needed for tests.
  2. Run:
    npx jest --runInBand --runTestsByPath \
      src/utilities/__tests__/socialMediaCredentials.test.js \
      src/routes/__tests__/socialPublishing.security.test.js \
      src/controllers/linkedinPostController.spec.js \
      src/controllers/linkedinUpload.security.test.js \
      src/routes/__tests__/mastodonRouter.test.js \
      src/cronjobs/__tests__/mastodonScheduleJob.test.js
  3. The tests mock provider HTTP, models and schedulers. Check allowed/denied callers, forged identities, multipart requests, missing configuration, synthetic credential echoes, scheduling, token rotation, organization changes, unsafe upload URLs and redirect settings.
  4. For live verification, an operator must provision limited-scope test-account tokens in the backend host's protected environment and use isolated test accounts/data. Do not post test messages or write test schedules to shared production accounts.

Validation at f55eb637a

  • 120 tests passed across six suites with database connections blocked and outbound sockets restricted to test servers. Provider calls are mocked/intercepted.
  • The three credential, permission and upload-URL helpers have 100% line and branch coverage; this is not whole-backend coverage.
  • Real Axios HTTP-adapter tests verify a signed image upload and reject 301/302/307/308 upload redirects without publishing afterward. Route tests reject private IPs, look-alike hosts, unrelated LinkedIn/licdn subdomains, unrelated paths, traversal, userinfo and malformed URLs; valid image/video URLs retain their signed query.
  • Mastodon tests verify local media fields are stripped without mutating the original data, and delivery-recording errors are sanitized without retrying a delivered post.
  • Babel compiled 793 files. Changed-file lint: zero errors, 25 warnings. Whitespace checks pass.
  • Earlier validation at 3b48764a5 included three isolated before/after credential-echo reproductions and four browser-driven mocked API walkthrough scenarios. The walkthrough UI is evidence tooling, not a shipped product page.

Sonar confirms all six reported findings are cleared: Quality Gate passed, zero open issues. GitHub lint, tests and Sonar checks all pass on this commit.

Screenshots or videos of changes

The complete original-task images are embedded above. Four mocked API screenshots, an actual-code screenshot and a short compressed walkthrough video are prepared locally in Week 5; they are not represented as uploaded Dropbox media.

Notes and testing limits

  • The upload allowlist supports the documented www.linkedin.com/dms-uploads/ and api.linkedin.com/mediaUpload/ endpoints. An unexpected endpoint fails closed and needs review; live provider uploads were not performed.
  • Actual secrets still need to be provisioned/revoked by an operator. No new vault service, Okta setup, real account access, database migration or production deployment was performed.
  • This protects the application/API credential boundary; it does not claim absolute security against a compromised backend or a host administrator. Existing historical logs are not modified.
  • Live Mastodon/LinkedIn authentication, real uploads and the deployed JWT/database permission stack were not exercised. Tests use synthetic verified identities and mocked permission/model operations; startup JWT assignment was inspected. The whole database-dependent backend suite was not run.
  • LinkedIn's existing in-memory scheduler remains non-durable across server restarts. Truth Social's legacy router is not mounted by current startup routes and is outside these active organization-token integrations.

Documentation cleanup: screenshots are attached directly to this description and removed from the PR commit range. Application and test files are byte-for-byte unchanged. Previously tested head f55eb637a7 corresponds to cleaned head 28cb993f03; fresh backend tests and lint pass, and the refreshed Sonar scan is running.

Keep Mastodon and LinkedIn credentials in server configuration and authorize
publishing with the existing announcements permission and verified identity.
Prevent provider errors from exposing tokens through responses, logs or
scheduled errors, and disable credential-bearing HTTP redirects.

Resolve scheduled LinkedIn tokens at delivery while preserving the original
organization. Add isolated credential-boundary, upload and retry tests and
preserve the complete original task with the clarified backend-only scope.

Refs #2065; Task 1551
Construct uploads with fixed HTTPS origins and validated paths, preserve signed queries, and reject unrelated provider destinations. Test the actual HTTP adapter against upload redirects and credential leakage.

Remove unused Mastodon fields without mutating stored data and sanitize delivery-recording failures. Refs #2440; Task 1551
adit24dhaya added a commit that referenced this pull request Oct 30, 2026
Construct uploads with fixed HTTPS origins and validated paths, preserve signed queries, and reject unrelated provider destinations. Test the actual HTTP adapter against upload redirects and credential leakage.

Remove unused Mastodon fields without mutating stored data and sanitize delivery-recording failures. Refs #2440; Task 1551
@adit24dhaya

adit24dhaya commented Oct 30, 2026 •

Copy link
Copy Markdown
Author

Updated in f55eb63. LinkedIn uploads now use only the documented upload endpoints, and redirects are blocked so the server token cannot be forwarded to another host. I also removed the unused Mastodon variables and fixed the exception handling without exposing error details.

Validation: 120 isolated tests passed, including actual Axios upload/redirect checks with intercepted HTTP. Build and lint passed; GitHub tests and lint also passed. No real social accounts or shared database data were used. Sonar has now finished: the Quality Gate passed with zero open issues. All GitHub checks pass on this commit.

@AaditTrivedi AaditTrivedi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed by Aadit Trivedi.

No conflicts with development, and the PR's tests pass (120/120).

One change needed: the PR commits three screenshots into the repository (docs/task-evidence/Task-1551-original-request-1.png, -2.png, -3.png, about 430 KB together). Once merged, these stay in the repo's history permanently and add to every clone. The same applies on frontend PR #5729.

Required action
Please remove the docs/task-evidence images from the branch and keep them in the PR description (they can be uploaded straight into the description instead of linked from the repo). Happy to re-review once removed, including a full read of the credential handling changes.

@adit24dhaya
adit24dhaya force-pushed the feat/social-media-credential-security branch from f55eb63 to 28cb993 Compare November 5, 2026 20:39
@adit24dhaya

adit24dhaya commented Nov 5, 2026 •

Copy link
Copy Markdown
Author

Moved all three pictures to direct attachments in the PR description and removed them from the PR commits. I verified that the attachments render and match the originals. Application and test files are byte-for-byte unchanged from the previously tested head. Fresh backend tests and lint pass; the refreshed Sonar scan is running. The requested image cleanup is complete. Please re-review when ready.

@sonarqubecloud

sonarqubecloud Bot commented Nov 5, 2026

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants