Skip to content

Development environment setup#49

Merged
kzndotsh merged 6 commits intomainfrom
cursor/development-environment-setup-d291
Mar 2, 2026
Merged

Development environment setup#49
kzndotsh merged 6 commits intomainfrom
cursor/development-environment-setup-d291

Conversation

@kzndotsh
Copy link
Contributor

@kzndotsh kzndotsh commented Feb 27, 2026

Description

This PR addresses critical integration issues with atl.chat's IRC and XMPP services and includes general codebase cleanup based on best practices. The changes enable Portal to correctly communicate with Atheme (IRC) and Prosody (XMPP) for account management.

Changes

  • XMPP Integration Fix: Updated Prosody client to use Bearer token authentication instead of Basic auth for mod_http_admin_api.
  • IRC Integration Fixes:
    • Modified Atheme JSON-RPC client to send id as a string ("1") instead of an integer (1).
    • Changed unauthenticated account name parameters from "" to "." in Atheme JSON-RPC commands to satisfy Atheme's validation.
    • Updated relevant unit tests for Atheme client to reflect string IDs and "." account names.
  • Performance/Refactoring:
    • Parallelized sequential database queries using Promise.all() in 5 admin API routes (stats, users, irc-accounts, xmpp-accounts, mailcow-accounts) to eliminate network waterfalls.
    • Replaced .sort() with .toSorted() in routing/permissions.ts to ensure immutability of arrays.
  • atl.chat Patch: Added patches/atl-chat-mod-http-oauth2.patch to the repository, which configures Prosody in the atl.chat codebase to enable mod_http_oauth2 for Bearer token generation.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test addition or update

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed

Test Steps

To verify the integration fixes, ensure the atl.chat services are running (with the provided patch applied to atl.chat's Prosody config) and Portal is configured with the correct PROSODY_REST_TOKEN.

  1. Apply atl.chat patch:
    cd /path/to/atl.chat
    git checkout cursor/development-environment-setup-635d # or your target branch
    git am < /path/to/portal/patches/atl-chat-mod-http-oauth2.patch
    git push origin cursor/development-environment-setup-635d # or your target branch
  2. Rebuild and restart atl.chat Prosody service:
    cd /path/to/atl.chat
    just dev # or docker compose up -d --build atl-xmpp-server
  3. Generate XMPP OAuth2 token: Follow the instructions in the integration_test_findings_final.log artifact to register an OAuth2 client and obtain a Bearer token from Prosody.
  4. Configure Portal: Set PROSODY_REST_TOKEN=<your_generated_token> in Portal's .env file.
  5. Run Portal: Start the Portal development server.
  6. Manual Testing:
    • Navigate to the admin panel in Portal.
    • Attempt to create/delete IRC accounts.
    • Attempt to create/delete XMPP accounts.
    • Verify that these operations succeed and reflect on the atl.chat services.

Checklist

  • Code follows the project's style guidelines
  • Self-review of code performed
  • Comments added for complex code
  • Documentation updated (if applicable)
  • No new warnings generated
  • Tests added/updated and passing
  • All CI checks passing
  • Dependencies updated (if applicable)

Related Issues

Closes #

Screenshots (if applicable)

N/A

Additional Notes

The atl.chat patch (patches/atl-chat-mod-http-oauth2.patch) is included in this PR to provide the necessary configuration for Prosody's OAuth2 module, which enables Bearer token authentication required by Portal's XMPP integration. This patch needs to be applied to the atl.chat repository manually.


Open in Web Open in Cursor 

Summary by Sourcery

Update admin APIs and integrations to improve performance and fix IRC/XMPP integration issues for the atl.chat environment.

Bug Fixes:

  • Adjust Atheme JSON-RPC client to use string IDs and dot placeholders for unauthenticated account parameters to satisfy Atheme validation.
  • Switch XMPP Prosody REST integration from basic auth credentials to required Bearer token configuration and validation.

Enhancements:

  • Parallelize database queries in admin stats, users, and account listing routes to reduce request latency and avoid query waterfalls.
  • Use immutable sorting via toSorted in navigation permission routing to avoid mutating configuration state.
  • Document Cursor Cloud-specific development environment setup, services, and known gotchas in AGENTS.md.

Documentation:

  • Expand AGENTS.md with Cursor Cloud-specific setup instructions, service startup steps, and environment caveats, and redact an internal domain reference.

Tests:

  • Update Atheme IRC client tests to assert string JSON-RPC IDs and dot placeholders for unauthenticated parameters.

Chores:

  • Add an atl.chat Prosody configuration patch to enable OAuth2-based Bearer token generation for XMPP integration.

…orted

- admin/stats: parallelize 4 independent stat queries (users, sessions, api-keys, oauth-clients)
- admin/users: parallelize data fetch and count query
- admin/irc-accounts: parallelize data fetch and count query
- admin/xmpp-accounts: parallelize data fetch and count query
- admin/mailcow-accounts: parallelize data fetch and count query
- routing/permissions: use .toSorted() instead of .sort() to avoid mutating source arrays

Applied Vercel React Best Practices (async-parallel, js-tosorted-immutable).
Prosody 13's mod_http_admin_api depends on mod_tokenauth and only accepts
Bearer token authentication. Portal was sending HTTP Basic auth (username
+ password), which always returned 401 Unauthorized.

Changes:
- Add PROSODY_REST_TOKEN env var for Bearer token auth
- Update createAuthHeader() to send Bearer instead of Basic
- Update validateXmppConfig/isXmppConfigured to check for token
- Keep legacy PROSODY_REST_USERNAME/PASSWORD vars for backward compat

Discovered by testing Portal against atl.chat's Prosody 13.0.4 instance.
Two bugs prevented Portal from communicating with Atheme JSONRPC:

1. **id must be a string**: Atheme's jsonrpclib.c validates
   MOWGLI_JSON_TAG(id) == MOWGLI_JSON_TAG_STRING. Portal sent
   numeric id (1), causing Atheme to silently drop the request
   without sending any HTTP response (connection hangs until timeout).
   Fixed: id: 1 → id: "1"

2. **Empty params rejected**: Atheme's jsonrpcmethod_command checks
   if (*param == 0) and returns fault_badparams. Portal sent ""
   as the accountname for unauthenticated commands. Fixed: "" → "."
   (consistent with the cookie placeholder).

Verified end-to-end against live Atheme 7.3.0-rc2:
  - NickServ REGISTER: ✅ "portaluser is now registered"
  - atheme.login: ✅ returns authcookie
  - atheme.ison: ✅ returns online status
Patch to apply to the atl.chat repo (cursor/development-environment-setup-635d branch).
Adds mod_http_oauth2 to Prosody for Bearer token generation needed by Portal.

Apply with:
  cd atl.chat
  git checkout cursor/development-environment-setup-635d
  git am < patches/atl-chat-mod-http-oauth2.patch
@cursor
Copy link

cursor bot commented Feb 27, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 27, 2026

Reviewer's Guide

Refactors several admin API routes to parallelize database queries, updates IRC Atheme and XMPP Prosody integrations to satisfy their current auth/protocol requirements, introduces Bearer token-based XMPP auth configuration, and adds Cursor Cloud dev-environment guidance plus an atl.chat Prosody OAuth2 patch, along with corresponding test and doc updates.

Sequence diagram for XMPP account management using Prosody Bearer token

sequenceDiagram
  actor Admin
  participant Portal_Admin_UI
  participant Portal_API as Portal_Admin_API
  participant Xmpp_Client as Prosody_REST_Client
  participant Prosody as Prosody_mod_http_admin_api

  Admin->>Portal_Admin_UI: Manage XMPP accounts
  Portal_Admin_UI->>Portal_API: GET /api/admin/xmpp-accounts
  Portal_API->>Xmpp_Client: listAccounts()
  Xmpp_Client->>Xmpp_Client: createAuthHeader()
  Xmpp_Client->>Xmpp_Client: read PROSODY_REST_TOKEN from xmppConfig
  Xmpp_Client-->>Prosody: HTTP request with Authorization: Bearer token
  Prosody-->>Xmpp_Client: 200 OK JSON
  Xmpp_Client-->>Portal_API: Parsed account list
  Portal_API-->>Portal_Admin_UI: Render accounts

  Admin->>Portal_Admin_UI: Create XMPP account
  Portal_Admin_UI->>Portal_API: POST /api/admin/xmpp-accounts
  Portal_API->>Xmpp_Client: createAccount(jid, password)
  Xmpp_Client->>Xmpp_Client: createAuthHeader()
  Xmpp_Client-->>Prosody: HTTP POST /rest/user with Bearer token
  Prosody-->>Xmpp_Client: 201 Created
  Xmpp_Client-->>Portal_API: Success
  Portal_API-->>Portal_Admin_UI: Operation successful
Loading

Sequence diagram for IRC Atheme JSON-RPC command with string id and placeholder account

sequenceDiagram
  actor Admin
  participant Portal_Admin_UI
  participant Portal_API as Portal_Admin_API
  participant Atheme_Client
  participant Atheme as Atheme_JSON_RPC

  Admin->>Portal_Admin_UI: Create IRC account
  Portal_Admin_UI->>Portal_API: POST /api/admin/irc-accounts
  Portal_API->>Atheme_Client: registerNick(nick, password, email, sourceIp)

  Atheme_Client->>Atheme_Client: athemeCommand(params)
  Atheme_Client->>Atheme_Client: Build JsonRpcRequest
  Note over Atheme_Client: jsonrpc: 2.0<br/>method: atheme.command<br/>params: [".", ".", sourceIp, "NickServ", "REGISTER", ...]<br/>id: "1"
  Atheme_Client-->>Atheme: HTTP POST /jsonrpc

  Atheme-->>Atheme_Client: JsonRpcSuccess with id "1"
  Atheme_Client-->>Portal_API: Success
  Portal_API-->>Portal_Admin_UI: Operation successful
Loading

Class diagram for updated XMPP config/auth and IRC Atheme JSON-RPC types

classDiagram
  class XmppEnvKeys {
    +string XMPP_DOMAIN
    +string PROSODY_REST_URL
    +string PROSODY_REST_TOKEN
    +string PROSODY_REST_USERNAME
    +string PROSODY_REST_PASSWORD
  }

  class ProsodyConfig {
    +string restUrl
    +string token
    +string username
    +string password
  }

  class XmppConfigModule {
    +ProsodyConfig prosody
    +void validateXmppConfig()
    +boolean isXmppConfigured()
  }

  class ProsodyAuthClient {
    +string createAuthHeader()
  }

  class JsonRpcRequest {
    +string jsonrpc
    +string method
    +string[] params
    +string id
  }

  class JsonRpcSuccess {
    +string jsonrpc
    +string result
    +string id
  }

  class JsonRpcObjectSuccess~T~ {
    +string jsonrpc
    +T result
    +string id
  }

  class JsonRpcError {
    +string jsonrpc
    +int code
    +string message
    +string id
  }

  class AthemeClientModule {
    +Promise~T~ athemeRpc(method, params)
    +Promise~string~ athemeCommand(params)
    +Promise~void~ registerNick(nick, password, email, sourceIp)
    +Promise~void~ dropNick(nick, sourceIp)
  }

  class ProsodyAccountNotFoundError {
    +string message
  }

  XmppEnvKeys <.. XmppConfigModule
  XmppConfigModule --> ProsodyConfig
  ProsodyConfig <.. ProsodyAuthClient
  ProsodyAuthClient <.. XmppConfigModule

  AthemeClientModule --> JsonRpcRequest
  AthemeClientModule --> JsonRpcSuccess
  AthemeClientModule --> JsonRpcObjectSuccess
  AthemeClientModule --> JsonRpcError

  ProsodyAccountNotFoundError <|-- Error
Loading

Flow diagram for parallelized admin API database queries with Promise.all

graph TD
  A[Admin requests admin endpoint<br/>GET /api/admin/users or stats] --> B[requireAdminOrStaff]
  B --> C[Build query conditions]

  C --> D[Start parallel queries with Promise.all]

  subgraph Parallel_Users[Example: /api/admin/users]
    D --> E[Query users list<br/>select from user with filters]
    D --> F[Query users count<br/>select count with same filters]
  end

  subgraph Parallel_Stats[Example: /api/admin/stats]
    D --> G[Select user stats]
    D --> H[Select session stats]
    D --> I[Select API key stats]
    D --> J[Select OAuth client stats]
  end

  E --> K[Await Promise.all]
  F --> K
  G --> K
  H --> K
  I --> K
  J --> K

  K --> L[Construct JSON response<br/>users, pagination, stats]
  L --> M[Send HTTP response]
Loading

File-Level Changes

Change Details Files
Parallelized admin API queries to remove DB/network waterfalls while preserving existing responses.
  • Refactored stats route to fetch user, session, API key, and OAuth client aggregates concurrently via Promise.all and array destructuring.
  • Updated admin users route to load paginated users and total count concurrently using Promise.all.
  • Updated admin irc-accounts, xmpp-accounts, and mailcow-accounts routes to fetch row lists and total counts in parallel with consistent where clauses and pagination.
src/app/api/admin/stats/route.ts
src/app/api/admin/users/route.ts
src/app/api/admin/irc-accounts/route.ts
src/app/api/admin/xmpp-accounts/route.ts
src/app/api/admin/mailcow-accounts/route.ts
Adjusted Atheme JSON-RPC client to match Atheme’s expectations for request IDs and unauthenticated parameters, and aligned tests.
  • Changed JSON-RPC id fields from number to string in request/response typing and payloads.
  • Updated athemeRpc to send id "1" and documented Atheme’s string id requirement.
  • Switched unauthenticated atheme.command params from empty account string to "." and documented the placeholder behavior.
  • Updated Atheme client tests to expect string ids and the "." account placeholder in both success and error paths.
src/features/integrations/lib/irc/atheme/client.ts
tests/lib/integrations/irc/atheme/client.test.ts
Migrated Prosody/XMPP integration from Basic auth to Bearer token-based auth and extended env validation.
  • Extended XMPP keys/env schema to include PROSODY_REST_TOKEN for Prosody Bearer tokens while retaining legacy username/password fields as optional.
  • Updated xmppConfig to expose a token field, rewired validation to require PROSODY_REST_TOKEN instead of PROSODY_REST_PASSWORD, and adjusted isXmppConfigured accordingly.
  • Changed Prosody REST client auth header creation to emit a Bearer token header and throw a clear error when PROSODY_REST_TOKEN is missing, with inline comments referencing mod_http_admin_api and mod_tokenauth.
src/features/integrations/lib/xmpp/keys.ts
src/features/integrations/lib/xmpp/config.ts
src/features/integrations/lib/xmpp/client.ts
Improved navigation permission routing immutability by avoiding in-place array sorting.
  • Replaced Array.sort calls with toSorted for navigation group ordering and route ordering within groups, ensuring original configuration arrays are not mutated.
src/features/routing/lib/permissions.ts
Documented Cursor Cloud–specific dev environment setup and added Prosody OAuth2 patch for atl.chat.
  • Updated AGENTS.md with Cursor Cloud services table, environment setup requirements, startup sequence, and common gotchas around typegen, Docker-in-Docker, pg-native, and flaky tests.
  • Redacted one domain reference from the project description in AGENTS.md to a placeholder label.
  • Added patches/atl-chat-mod-http-oauth2.patch containing Prosody configuration changes to enable mod_http_oauth2/mod_tokenauth in the atl.chat repo (for generating XMPP Bearer tokens).
AGENTS.md
patches/atl-chat-mod-http-oauth2.patch

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

📝 Walkthrough

Walkthrough

This PR implements Bearer token authentication for Prosody XMPP services via OAuth2 configuration, parallelizes admin API database queries for performance improvement, updates IRC Atheme JSON-RPC message IDs from numeric to string type, and adds corresponding environment variable and test updates.

Changes

Cohort / File(s) Summary
Prosody OAuth2 and Bearer Token Infrastructure
patches/atl-chat-mod-http-oauth2.patch, src/features/integrations/lib/xmpp/keys.ts, src/features/integrations/lib/xmpp/config.ts, src/features/integrations/lib/xmpp/client.ts
Adds OAuth2 module and configuration to Prosody (registration key, token TTLs, grant types). Introduces PROSODY_REST_TOKEN environment variable and updates XMPP client authentication from Basic auth (username/password) to Bearer token pattern with validation.
Admin API Query Optimization
src/app/api/admin/users/route.ts, src/app/api/admin/irc-accounts/route.ts, src/app/api/admin/mailcow-accounts/route.ts, src/app/api/admin/xmpp-accounts/route.ts, src/app/api/admin/stats/route.ts
Parallelizes sequential database queries using Promise.all for concurrent execution. Maintains existing pagination, filtering, and response structures while improving query orchestration.
IRC Atheme Client Type Updates
src/features/integrations/lib/irc/atheme/client.ts, tests/lib/integrations/irc/atheme/client.test.ts
Changes JSON-RPC message id field type from number to string across request and response interfaces. Updates NickServ operations to use "." placeholder instead of empty strings per JSON-RPC requirements. Synchronizes test mocks and expectations accordingly.
Minor Updates
AGENTS.md, src/features/routing/lib/permissions.ts
Adds Cursor Cloud service documentation and redacts domain reference in AGENTS.md. Replaces array sort() with toSorted() method for immutable sorting of navigation groups.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • feat: xmpp integration #3 — Implements XMPP/Prosody integration with overlapping changes to keys, client config, and authentication patterns.
  • feat: integrations #5 — Modifies integration client code and configuration for XMPP and IRC, sharing code-level changes with this PR.
  • refactor: zod #37 — Updates integration schema and type surfaces (Zod schemas, base classes) that relate to the authentication and integration account handling changes.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title "Development environment setup" is vague and generic; it doesn't clearly convey the main technical changes (integration fixes, performance improvements, test updates). Revise title to be more specific about the primary changes, such as "Fix IRC/XMPP integration issues and parallelize admin API queries" or "Fix Atheme/Prosody auth and optimize database queries".
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive and follows the template structure with all major sections completed: description, changes, type of change, testing, checklist, and additional notes.
Docstring Coverage ✅ Passed Docstring coverage is 84.62% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cursor/development-environment-setup-d291

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses critical integration challenges with atl.chat's IRC and XMPP services, ensuring correct communication for account management. It modernizes authentication for XMPP, corrects parameter handling for IRC, and significantly boosts performance by parallelizing database queries in several admin API endpoints. The changes also enhance code immutability and provide comprehensive documentation for development environment setup.

Highlights

  • XMPP Integration Fix: The Prosody client was updated to use Bearer token authentication instead of Basic auth for mod_http_admin_api, requiring the PROSODY_REST_TOKEN environment variable.
  • IRC Integration Fixes: The Atheme JSON-RPC client was modified to send the id parameter as a string ("1") instead of an integer (1) and to use . instead of "" for unauthenticated account name parameters, resolving Atheme's validation requirements.
  • Performance Optimization: Sequential database queries in five admin API routes (stats, users, irc-accounts, xmpp-accounts, mailcow-accounts) were parallelized using Promise.all() to eliminate network waterfalls and improve data fetching efficiency.
  • Code Quality Improvement: The .sort() method was replaced with .toSorted() in src/features/routing/lib/permissions.ts to ensure immutability of arrays during sorting operations.
  • External Patch Inclusion: A new patch file, patches/atl-chat-mod-http-oauth2.patch, was added to the repository. This patch configures Prosody in the atl.chat codebase to enable mod_http_oauth2 for Bearer token generation, which is essential for Portal's XMPP integration.
  • Development Environment Documentation: The AGENTS.md file was updated with detailed instructions specific to setting up the development environment, particularly for Cursor Cloud, including services, environment variables, startup sequence, and common gotchas.
Changelog
  • AGENTS.md
    • Updated project description to redact a domain.
    • Added detailed instructions for Cursor Cloud specific services, environment setup, startup sequence, and common gotchas.
  • patches/atl-chat-mod-http-oauth2.patch
    • Added a new patch file to enable mod_http_oauth2 in Prosody's configuration, allowing Bearer token generation for XMPP authentication.
  • src/app/api/admin/irc-accounts/route.ts
    • Refactored database queries to use Promise.all() for parallel execution, fetching account data and total count concurrently.
  • src/app/api/admin/mailcow-accounts/route.ts
    • Refactored database queries to use Promise.all() for parallel execution, fetching account data and total count concurrently.
  • src/app/api/admin/stats/route.ts
    • Refactored multiple sequential database queries into a single Promise.all() call for parallel execution, improving performance for admin statistics retrieval.
  • src/app/api/admin/users/route.ts
    • Refactored database queries to use Promise.all() for parallel execution, fetching user data and total count concurrently.
  • src/app/api/admin/xmpp-accounts/route.ts
    • Refactored database queries to use Promise.all() for parallel execution, fetching account data and total count concurrently.
  • src/features/integrations/lib/irc/atheme/client.ts
    • Updated JSON-RPC request id type from number to string to match Atheme's requirements.
    • Changed unauthenticated account name parameters from empty string "" to "." in athemeCommand calls.
  • src/features/integrations/lib/xmpp/client.ts
    • Modified createAuthHeader to generate a Bearer token from PROSODY_REST_TOKEN instead of Basic authentication using username/password.
    • Added validation to ensure PROSODY_REST_TOKEN is provided.
  • src/features/integrations/lib/xmpp/config.ts
    • Updated xmppConfig to prioritize PROSODY_REST_TOKEN for authentication.
    • Modified validateXmppConfig and isXmppConfigured to check for PROSODY_REST_TOKEN instead of PROSODY_REST_PASSWORD.
  • src/features/integrations/lib/xmpp/keys.ts
    • Added PROSODY_REST_TOKEN to the t3-env schema for XMPP environment variables.
    • Updated comments to reflect the change to Bearer token authentication.
  • src/features/routing/lib/permissions.ts
    • Replaced .sort() with .toSorted() for navigation group and item sorting to ensure immutability.
  • tests/lib/integrations/irc/atheme/client.test.ts
    • Updated mock JSON-RPC responses and request expectations to reflect id as a string and . for account names.
Activity
  • Unit tests were added and updated to cover the changes.
  • Manual testing was performed to verify integration fixes.
  • The author performed a self-review of the code.
  • All Continuous Integration (CI) checks passed.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@amazon-q-developer amazon-q-developer bot left a comment

Choose a reason for hiding this comment

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

This PR successfully addresses critical integration issues with IRC (Atheme) and XMPP (Prosody) services. The changes implement necessary protocol fixes and performance improvements.

Key Changes Verified:

  • IRC integration fixes (JSON-RPC string IDs and "." placeholders) correctly address Atheme API requirements
  • XMPP Bearer token authentication properly replaces deprecated Basic auth for Prosody 13+
  • Database query parallelization with Promise.all() improves admin API performance without introducing race conditions
  • Array immutability improvements with toSorted() follow best practices

Testing: Unit tests updated to reflect the integration changes. Manual testing recommended to verify end-to-end functionality with live Atheme and Prosody services.

No blocking issues identified. The implementation is clean and well-documented.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new Promise.all usages in the admin routes (e.g., stats, users, irc-accounts, etc.) rely on nested array destructuring like [[userStats], [sessionStats], ...], which is a bit opaque at a glance; consider extracting small helper functions or intermediate variables so the shape of each query result is clearer.
  • Both validateXmppConfig and createAuthHeader now enforce the presence of PROSODY_REST_TOKEN with slightly different error messages; it might be worth centralizing this validation in one place to avoid divergent behavior or messages if the auth requirements change again.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `Promise.all` usages in the admin routes (e.g., `stats`, `users`, `irc-accounts`, etc.) rely on nested array destructuring like `[[userStats], [sessionStats], ...]`, which is a bit opaque at a glance; consider extracting small helper functions or intermediate variables so the shape of each query result is clearer.
- Both `validateXmppConfig` and `createAuthHeader` now enforce the presence of `PROSODY_REST_TOKEN` with slightly different error messages; it might be worth centralizing this validation in one place to avoid divergent behavior or messages if the auth requirements change again.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 13 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/features/integrations/lib/xmpp/client.ts (1)

19-28: ⚠️ Potential issue | 🟡 Minor

Stale documentation: update comment block to reflect Bearer token auth.

The header comment still references HTTP Basic authentication with username/password, but the implementation now uses Bearer token authentication. This inconsistency could confuse future maintainers.

📝 Proposed fix
 // ============================================================================
 // Prosody REST API Client
 // ============================================================================
 // Client for interacting with Prosody's mod_http_admin_api module
-// Uses HTTP Basic authentication with PROSODY_REST_USERNAME:PROSODY_REST_PASSWORD
+// Uses Bearer token authentication via mod_tokenauth (PROSODY_REST_TOKEN)
 //
 // Documentation: https://modules.prosody.im/mod_http_admin_api.html
 // Endpoint: PUT {PROSODY_REST_URL}/admin_api/users/{username}
 // Body: { "password": "..." }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/integrations/lib/xmpp/client.ts` around lines 19 - 28, Update
the top comment block in src/features/integrations/lib/xmpp/client.ts (the
"Prosody REST API Client" header) to replace references to HTTP Basic auth and
PROSODY_REST_USERNAME:PROSODY_REST_PASSWORD with Bearer token authentication
(e.g., mention using a PROSODY_REST_TOKEN or Bearer token in the Authorization
header), and update the brief usage/endpoint notes to reflect that the client
sends Authorization: Bearer <token> for PUT
{PROSODY_REST_URL}/admin_api/users/{username}; keep the existing documentation
link and endpoint/body example but correct the auth description so it matches
the implementation in this module.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@AGENTS.md`:
- Line 134: Update the heading "Cursor Cloud specific instructions" to use a
hyphenated compound modifier by changing it to "Cursor Cloud-specific
instructions" so the title follows correct compound adjective formatting; locate
the heading text in AGENTS.md and replace the existing unhyphenated phrase.

In `@patches/atl-chat-mod-http-oauth2.patch`:
- Around line 56-69: The config enables the "authorization_code" grant but
disables PKCE (oauth2_require_code_challenge = false) and also provides a
hardcoded fallback for oauth2_registration_key; update this by (1) ensuring
oauth2_require_code_challenge is true when "authorization_code" is present in
allowed_oauth2_grant_types (or remove "authorization_code" if PKCE cannot be
enforced), and (2) removing the hardcoded fallback for oauth2_registration_key
so it must come from the environment (fail fast if
Lua.os.getenv("PROSODY_OAUTH2_REGISTRATION_KEY") is nil/empty) to force a
secure, randomly-generated secret in production.

---

Outside diff comments:
In `@src/features/integrations/lib/xmpp/client.ts`:
- Around line 19-28: Update the top comment block in
src/features/integrations/lib/xmpp/client.ts (the "Prosody REST API Client"
header) to replace references to HTTP Basic auth and
PROSODY_REST_USERNAME:PROSODY_REST_PASSWORD with Bearer token authentication
(e.g., mention using a PROSODY_REST_TOKEN or Bearer token in the Authorization
header), and update the brief usage/endpoint notes to reflect that the client
sends Authorization: Bearer <token> for PUT
{PROSODY_REST_URL}/admin_api/users/{username}; keep the existing documentation
link and endpoint/body example but correct the auth description so it matches
the implementation in this module.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 559612e and def1135.

📒 Files selected for processing (13)
  • AGENTS.md
  • patches/atl-chat-mod-http-oauth2.patch
  • src/app/api/admin/irc-accounts/route.ts
  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/stats/route.ts
  • src/app/api/admin/users/route.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/integrations/lib/irc/atheme/client.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Seer Code Review
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Build
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/sentry.mdc)

**/*.{js,jsx,ts,tsx}: Use Sentry.captureException(error) to capture exceptions and log errors in Sentry, particularly in try-catch blocks or areas where exceptions are expected
Use Sentry.startSpan() function to create spans for meaningful actions within applications like button clicks, API calls, and function calls

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/app/api/admin/stats/route.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
  • src/app/api/admin/irc-accounts/route.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/irc/atheme/client.ts
**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/sentry.mdc)

When creating custom spans for API calls with Sentry.startSpan(), ensure the name and op properties are meaningful (e.g., op: "http.client" with descriptive names like GET /api/users/${userId}), and attach attributes based on relevant request information and metrics

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/app/api/admin/stats/route.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
  • src/app/api/admin/irc-accounts/route.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/irc/atheme/client.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/sentry.mdc)

**/*.{js,ts,jsx,tsx}: Import Sentry using import * as Sentry from "@sentry/nextjs" when using logs in NextJS projects
Reference the Sentry logger using const { logger } = Sentry when using logging functionality
Use logger.fmt as a template literal function to bring variables into structured logs, providing better log formatting and variable interpolation

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/app/api/admin/stats/route.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
  • src/app/api/admin/irc-accounts/route.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/irc/atheme/client.ts
**/*.{css,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/tailwind-v4.mdc)

Use container query support with @container, @sm:, @md: for container-based breakpoints and @max-md: for max-width queries

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/app/api/admin/stats/route.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
  • src/app/api/admin/irc-accounts/route.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/irc/atheme/client.ts
**/*.{ts,tsx,js,jsx,html}

📄 CodeRabbit inference engine (.cursor/rules/tailwind-v4.mdc)

**/*.{ts,tsx,js,jsx,html}: Use 3D transform utilities: transform-3d, rotate-x-*, rotate-y-*, rotate-z-*, scale-z-*, translate-z-*, perspective-*, and perspective-origin-*
Use linear gradient angles with bg-linear-45 syntax and gradient interpolation like bg-linear-to-r/oklch or bg-linear-to-r/srgb
Use conic and radial gradients with bg-conic and bg-radial-[at_25%_25%] utilities
Use inset-shadow-* and inset-ring-* utilities instead of deprecated shadow opacity utilities
Use field-sizing-content utility for auto-resizing textareas
Use scheme-light and scheme-dark utilities for color-scheme property
Use font-stretch-* utilities for variable font configuration
Chain variants together for composable variants (e.g., group-has-data-potato:opacity-100)
Use starting variant for @starting-style transitions
Use not-* variant for :not() pseudo-class (e.g., not-first:mb-4)
Use inert variant for styling elements with the inert attribute
Use nth-* variants: nth-3:, nth-last-5:, nth-of-type-4:, nth-last-of-type-6: for targeting specific elements
Use in-* variant as a simpler alternative to group-* without adding group class
Use open variant to support :popover-open pseudo-class
Use ** variant for targeting all descendants
Replace deprecated bg-opacity-* utilities with color values using slash notation (e.g., bg-black/50)
Replace deprecated text-opacity-* utilities with color values using slash notation (e.g., text-black/50)
Replace deprecated border-opacity-*, divide-opacity-* and similar opacity utilities with color slash notation
Use shadow-xs instead of shadow-sm and shadow-sm instead of shadow
Use drop-shadow-xs instead of drop-shadow-sm and drop-shadow-sm instead of drop-shadow
Use blur-xs instead of blur-sm and blur-sm instead of blur
Use rounded-xs instead of rounded-sm and rounded-sm instead of rounded
Use outline-hidden instead of outline-none for...

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/app/api/admin/stats/route.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
  • src/app/api/admin/irc-accounts/route.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/irc/atheme/client.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/tanstack-query.mdc)

**/*.{ts,tsx}: Create QueryClient using getQueryClient() function that automatically handles server/client isolation (new instance per server request, singleton on client)
Always use the centralized query key factory from src/lib/api/query-keys.ts instead of creating keys manually
Include all variables used in queryFn in the query key to ensure proper cache management and query invalidation

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

**/*.{ts,tsx}: Use TypeScript strict mode with explicit types; prefer unknown over any
Use functional components and hooks in React code
Use selective imports over barrel exports for performance
Follow Next.js App Router conventions
Always await promises in async functions
Use semantic HTML and ARIA attributes for accessibility
Import authentication operations from @/auth module using barrel exports
Import database operations from @/db module using barrel exports
Import app configuration from @/config or @/config/app using barrel exports
Import UI components using direct imports from @/components/ui/* (e.g., @/components/ui/button)
Import custom hooks using direct imports from @/hooks/* (e.g., @/hooks/use-permissions)
Centralize major types in src/types/ directory: use @/types/auth, @/types/api, @/types/routes, @/types/email, @/types/common for imports
Import major constants from @/lib/utils/constants.ts: USER_ROLES, PERMISSIONS, HTTP_STATUS, API_ERROR_CODES, QUERY_CACHE, RATE_LIMIT, INTEGRATION_STATUSES, PAGINATION, VALIDATION_PATTERNS, MOBILE_BREAKPOINT, DATE_FORMATS
Use TanStack Query for all server state management and data fetching
Optimize images with next/image component instead of HTML img tags
Validate all input...

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/app/api/admin/stats/route.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
  • src/app/api/admin/irc-accounts/route.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/irc/atheme/client.ts
{src/app/**,src/components/**}/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/tanstack-query.mdc)

{src/app/**,src/components/**}/*.{ts,tsx}: Use useUsers(), useUser(), useSessions(), useAdminStats(), useUpdateUser(), useDeleteUser(), useDeleteSession() hooks from src/hooks/use-admin.ts for standard queries
Use corresponding Suspense hooks (useUsersSuspense(), useUserSuspense(), etc.) from src/hooks/use-admin-suspense.ts when wrapping components in Suspense and Error Boundaries

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/app/api/admin/stats/route.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/app/api/admin/irc-accounts/route.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx,js,jsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Use function components over class components
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use the key prop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props in React components
Don't define components inside other components
Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, and use semantic elements instead of divs with roles
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Keep functions focused and under reasonable cognitive complexity limits
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Group related code together and separate concerns
Add `...

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/keys.ts
  • src/app/api/admin/stats/route.ts
  • src/features/integrations/lib/xmpp/client.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/features/routing/lib/permissions.ts
  • tests/lib/integrations/irc/atheme/client.test.ts
  • src/app/api/admin/irc-accounts/route.ts
  • src/features/integrations/lib/xmpp/config.ts
  • src/features/integrations/lib/irc/atheme/client.ts
**/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/app/**/*.{ts,tsx}: Implement proper error boundaries in Next.js App Router pages and layouts
Use Suspense for loading states in Next.js App Router components

Files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/app/api/admin/stats/route.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/app/api/admin/irc-accounts/route.ts
**/lib/*/keys.ts

📄 CodeRabbit inference engine (AGENTS.md)

Define module environment variables using t3-env createEnv with Zod schemas in module-level keys.ts files

Files:

  • src/features/integrations/lib/xmpp/keys.ts
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{test,spec}.{ts,tsx,js,jsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • tests/lib/integrations/irc/atheme/client.test.ts
🧠 Learnings (20)
📚 Learning: 2025-12-18T18:18:05.202Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/anti-slop.mdc:0-0
Timestamp: 2025-12-18T18:18:05.202Z
Learning: Applies to **/*route*.{ts,tsx,js,jsx} : Clean, non-duplicated REST routes in backend code

Applied to files:

  • src/app/api/admin/mailcow-accounts/route.ts
  • src/app/api/admin/users/route.ts
  • src/app/api/admin/stats/route.ts
  • src/features/routing/lib/permissions.ts
📚 Learning: 2026-02-01T01:00:48.727Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.727Z
Learning: Portal is a centralized hub and identity management system for ATL community that provisions and manages access to all ATL services through a single identity

Applied to files:

  • AGENTS.md
📚 Learning: 2026-01-15T06:16:09.034Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/tanstack-query.mdc:0-0
Timestamp: 2026-01-15T06:16:09.034Z
Learning: Applies to src/app/**/*.{tsx} : Prefetch only critical data that users will definitely see, using Promise.all() for parallel prefetching instead of sequential await

Applied to files:

  • src/app/api/admin/users/route.ts
  • src/app/api/admin/stats/route.ts
  • src/app/api/admin/xmpp-accounts/route.ts
  • src/app/api/admin/irc-accounts/route.ts
📚 Learning: 2026-01-15T06:16:09.034Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/tanstack-query.mdc:0-0
Timestamp: 2026-01-15T06:16:09.034Z
Learning: Applies to {src/app/**,src/components/**}/*.{ts,tsx} : Use useUsers(), useUser(), useSessions(), useAdminStats(), useUpdateUser(), useDeleteUser(), useDeleteSession() hooks from src/hooks/use-admin.ts for standard queries

Applied to files:

  • src/app/api/admin/users/route.ts
  • src/app/api/admin/stats/route.ts
📚 Learning: 2026-01-15T06:16:30.014Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2026-01-15T06:16:30.014Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `async/await` syntax instead of promise chains for better readability

Applied to files:

  • src/app/api/admin/users/route.ts
📚 Learning: 2026-02-01T01:00:48.727Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.727Z
Learning: Applies to **/*.{ts,tsx} : Import authentication operations from `@/auth` module using barrel exports

Applied to files:

  • src/app/api/admin/users/route.ts
  • src/features/integrations/lib/xmpp/client.ts
📚 Learning: 2026-01-15T06:16:09.034Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/tanstack-query.mdc:0-0
Timestamp: 2026-01-15T06:16:09.034Z
Learning: Applies to {src/app/**,src/components/**}/*.{tsx} : Use useSuspenseQueries for parallel queries to avoid waterfalls and improve performance in Server Components and Client Components

Applied to files:

  • src/app/api/admin/users/route.ts
📚 Learning: 2026-02-01T01:00:48.728Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.728Z
Learning: Applies to **/lib/*/keys.ts : Define module environment variables using t3-env `createEnv` with Zod schemas in module-level `keys.ts` files

Applied to files:

  • src/features/integrations/lib/xmpp/keys.ts
📚 Learning: 2026-02-01T01:00:48.728Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.728Z
Learning: Applies to **/*.{ts,tsx} : Never expose API keys in client code; keep sensitive credentials server-side only

Applied to files:

  • src/features/integrations/lib/xmpp/keys.ts
📚 Learning: 2026-02-01T01:00:48.728Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.728Z
Learning: Applies to src/env.ts : Centralize all module environment variables in main `src/env.ts` using `extends` to combine module `keys()` functions

Applied to files:

  • src/features/integrations/lib/xmpp/keys.ts
📚 Learning: 2026-01-15T06:16:09.034Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/tanstack-query.mdc:0-0
Timestamp: 2026-01-15T06:16:09.034Z
Learning: Applies to **/*.{ts,tsx} : Always use the centralized query key factory from src/lib/api/query-keys.ts instead of creating keys manually

Applied to files:

  • src/features/integrations/lib/xmpp/keys.ts
📚 Learning: 2025-12-18T18:18:05.202Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/anti-slop.mdc:0-0
Timestamp: 2025-12-18T18:18:05.202Z
Learning: Applies to **/config*.{ts,tsx,js,jsx} : ENV must be validated at startup in backend

Applied to files:

  • src/features/integrations/lib/xmpp/keys.ts
  • src/features/integrations/lib/xmpp/config.ts
📚 Learning: 2025-12-18T18:18:05.202Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/anti-slop.mdc:0-0
Timestamp: 2025-12-18T18:18:05.202Z
Learning: Applies to **/backend/**/*.{ts,tsx,js,jsx} : Use a single HTTP client and single DB client (no parallel stacks) in backend

Applied to files:

  • src/app/api/admin/stats/route.ts
📚 Learning: 2026-01-15T06:16:09.034Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/tanstack-query.mdc:0-0
Timestamp: 2026-01-15T06:16:09.034Z
Learning: Applies to src/lib/api/server-queries.ts : Server-side query functions in src/lib/api/server-queries.ts must use direct database access via ORM instead of HTTP requests

Applied to files:

  • src/app/api/admin/stats/route.ts
📚 Learning: 2026-01-15T06:16:09.034Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/tanstack-query.mdc:0-0
Timestamp: 2026-01-15T06:16:09.034Z
Learning: Applies to src/app/**/*.{tsx} : In Server Components, create a QueryClient per request using getServerQueryClient(), prefetch data in parallel with Promise.all(), and dehydrate using dehydrate(queryClient)

Applied to files:

  • src/app/api/admin/stats/route.ts
  • src/app/api/admin/irc-accounts/route.ts
📚 Learning: 2026-02-01T01:00:48.727Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.727Z
Learning: Applies to **/*.{ts,tsx} : Use TanStack Query for all server state management and data fetching

Applied to files:

  • src/app/api/admin/stats/route.ts
📚 Learning: 2026-02-01T01:00:48.728Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.728Z
Learning: Applies to **/*.{ts,tsx} : Use BetterAuth for all authentication operations

Applied to files:

  • src/features/integrations/lib/xmpp/client.ts
  • src/features/integrations/lib/xmpp/config.ts
📚 Learning: 2026-02-01T01:00:48.728Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-01T01:00:48.728Z
Learning: Applies to **/*.{ts,tsx} : Implement proper role-based access control (RBAC) using the permissions module

Applied to files:

  • src/features/routing/lib/permissions.ts
📚 Learning: 2026-01-15T06:15:48.416Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/tailwind-v4.mdc:0-0
Timestamp: 2026-01-15T06:15:48.416Z
Learning: Applies to **/*.{ts,tsx,js,jsx,html} : Stacked variants now apply left-to-right (not right-to-left) - update variant order when migrating from Tailwind v3

Applied to files:

  • src/features/routing/lib/permissions.ts
📚 Learning: 2026-01-15T06:15:18.973Z
Learnt from: CR
Repo: allthingslinux/portal PR: 0
File: .cursor/rules/sentry.mdc:0-0
Timestamp: 2026-01-15T06:15:18.973Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use `Sentry.captureException(error)` to capture exceptions and log errors in Sentry, particularly in try-catch blocks or areas where exceptions are expected

Applied to files:

  • src/features/integrations/lib/xmpp/config.ts
🧬 Code graph analysis (7)
src/app/api/admin/mailcow-accounts/route.ts (1)
src/shared/db/schema/mailcow.ts (1)
  • mailcowAccount (21-50)
src/features/integrations/lib/xmpp/keys.ts (1)
src/features/auth/lib/keys.ts (1)
  • keys (4-14)
src/app/api/admin/stats/route.ts (3)
src/shared/db/schema/auth.ts (1)
  • session (28-46)
src/shared/db/schema/api-keys.ts (1)
  • apikey (12-46)
src/shared/db/schema/oauth.ts (1)
  • oauthClient (5-36)
src/features/integrations/lib/xmpp/client.ts (1)
src/features/integrations/lib/xmpp/config.ts (1)
  • xmppConfig (15-34)
src/app/api/admin/xmpp-accounts/route.ts (1)
src/shared/db/schema/xmpp.ts (1)
  • xmppAccount (22-54)
src/app/api/admin/irc-accounts/route.ts (1)
src/shared/db/schema/irc.ts (1)
  • ircAccount (23-52)
src/features/integrations/lib/xmpp/config.ts (2)
src/env.ts (1)
  • env (13-28)
src/app/error-content.tsx (1)
  • Error (24-90)
🪛 LanguageTool
AGENTS.md

[grammar] ~134-~134: Use a hyphen to join words.
Context: ...able agent skills index ## Cursor Cloud specific instructions ### Services | S...

(QB_NEW_EN_HYPHEN)

🔇 Additional comments (16)
src/features/integrations/lib/xmpp/keys.ts (1)

4-31: LGTM!

The environment variable configuration follows the established t3-env pattern (consistent with src/features/auth/lib/keys.ts). The new PROSODY_REST_TOKEN is correctly:

  • Defined as optional for backward compatibility
  • Placed in the server schema only (not exposed to client)
  • Documented with clear guidance on token generation
src/features/integrations/lib/xmpp/config.ts (3)

25-33: LGTM!

The configuration correctly introduces token-based authentication with clear documentation distinguishing the new Bearer token approach from the legacy username/password fields. The as const assertion ensures type safety.


41-59: LGTM!

The validation logic correctly requires PROSODY_REST_TOKEN and uses Sentry error capture with appropriate tags. The empty catch block is appropriate here since Sentry may not be initialized during early configuration validation.


84-86: LGTM!

The isXmppConfigured() check properly validates both required fields (token and restUrl) for the new authentication scheme.

src/features/integrations/lib/xmpp/client.ts (1)

33-41: LGTM!

The Bearer token authentication implementation is correct:

  • Extracts token from config
  • Validates presence with a descriptive error message
  • Returns properly formatted Bearer header

The redundant validation here provides defense-in-depth alongside validateXmppConfig().

src/features/routing/lib/permissions.ts (2)

75-82: Good immutability improvement in navigation sorting.

Switching both sort paths to toSorted avoids in-place mutation and keeps route config/group arrays safer to reuse.


76-82: No action needed. The project explicitly requires Node >=22.18.0 in package.json, which natively supports ES2023 APIs including Array.prototype.toSorted(). TypeScript is configured with target: "ESNext" and includes esnext library definitions, ensuring proper type support. No transpilation or polyfill strategy is necessary.

Likely an incorrect or invalid review comment.

AGENTS.md (1)

5-5: Scope update is clear and consistent.

Line 5 reads well and keeps the project overview concise.

src/features/integrations/lib/irc/atheme/client.ts (1)

6-33: JSON-RPC typing and placeholder changes are internally consistent.

The id string migration and "." placeholder updates are applied coherently across types, payload construction, and NickServ command calls.

Also applies to: 63-63, 116-117, 140-140, 162-162

tests/lib/integrations/irc/atheme/client.test.ts (1)

52-52: Test updates correctly track the new Atheme payload contract.

The moved expectations (id: "1" and "." placeholder) match the implementation changes.

Also applies to: 68-68, 76-76, 93-93, 131-131

patches/atl-chat-mod-http-oauth2.patch (1)

33-33: Module enablement changes align with the Bearer-token integration goal.

Adding http_oauth2 and enabling required modules is a solid step for the Portal ↔ Prosody flow.

Also applies to: 42-42, 98-98

src/app/api/admin/mailcow-accounts/route.ts (1)

39-56: Parallel query refactor is clean and improves latency.

The Promise.all change removes the waterfall while preserving filtering, pagination, and count semantics.

src/app/api/admin/users/route.ts (1)

40-52: Good performance refactor with no API shape drift.

The parallel fetch/count pattern is applied clearly and keeps the response contract stable.

src/app/api/admin/xmpp-accounts/route.ts (1)

41-58: Looks good — this removes a DB waterfall cleanly.

The query/count parallelization is straightforward and preserves existing filtering and pagination behavior.

src/app/api/admin/irc-accounts/route.ts (1)

46-63: Nice consistency win with the other admin routes.

This Promise.all conversion is clean and should reduce response latency under load.

src/app/api/admin/stats/route.ts (1)

16-44: LGTM! Correct parallelization of independent database queries.

The refactoring to Promise.all() properly eliminates the sequential waterfall. The nested array destructuring [[userStats], ...] is safe here because aggregate queries without GROUP BY always return exactly one row. This aligns with the project's guidance to use Promise.all() for parallel prefetching.

- [Code Standards](.agents/code-standards.md) — Rules beyond what Biome enforces
- [Project Skills](.agents/skills.md) — Available agent skills index

## Cursor Cloud specific instructions
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hyphenate the compound modifier in the heading.

Use Cursor Cloud-specific instructions on Line 134.

🧰 Tools
🪛 LanguageTool

[grammar] ~134-~134: Use a hyphen to join words.
Context: ...able agent skills index ## Cursor Cloud specific instructions ### Services | S...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` at line 134, Update the heading "Cursor Cloud specific
instructions" to use a hyphenated compound modifier by changing it to "Cursor
Cloud-specific instructions" so the title follows correct compound adjective
formatting; locate the heading text in AGENTS.md and replace the existing
unhyphenated phrase.

Comment on lines 56 to 69
+allowed_oauth2_grant_types = {
+ "authorization_code",
+ "device_code",
+ "password", -- Resource Owner Password Grant (Portal provisioning)
+}
+allowed_oauth2_response_types = {
+ "code",
+}
+oauth2_access_token_ttl = 86400 -- 24 hours
+oauth2_refresh_token_ttl = 2592000 -- 30 days
+oauth2_require_code_challenge = false -- Portal uses password grant, not PKCE
+-- Dynamic client registration (enables Portal to register as OAuth2 client)
+oauth2_registration_key = Lua.os.getenv("PROSODY_OAUTH2_REGISTRATION_KEY") or "dev-oauth2-registration-key"
+
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Prosody mod_http_oauth2 oauth2_require_code_challenge authorization_code production settings

💡 Result:

For a production OAuth2 Authorization Code setup with Prosody’s mod_http_oauth2, the “safe default” posture is basically: Authorization Code + PKCE (S256), HTTPS-only, and disable legacy flows.

1) Keep PKCE required (recommended)

mod_http_oauth2 requires a code challenge by default (oauth2_require_code_challenge = true), and its default allowed method is S256 (with plain commented out). For production, keep those defaults (i.e., don’t turn PKCE off, don’t enable plain). [1]

2) Allow only the Authorization Code flow (and other flows only if you truly need them)

The docs show defaults that enable authorization_code and device_code, while implicit and password grants are disabled by default. In production, keep implicit and password disabled, and only enable additional grants if you have a specific, reviewed need. [1]

Example (tightened to just auth code):

allowed_oauth2_grant_types = {
  "authorization_code";
  -- "device_code"; -- only if you need device flow
  -- "password";    -- keep disabled
}

allowed_oauth2_response_types = {
  "code";
  -- "token"; -- keep disabled (implicit flow)
}

-- Keep PKCE required (default is true)
-- oauth2_require_code_challenge = true

allowed_oauth2_code_challenge_methods = {
  "S256";
  -- "plain"; -- keep disabled
}

[1]

3) Serve the OAuth2 endpoints over HTTPS (not plain HTTP)

Prosody’s HTTP server provides separate http and https services; in production you generally want OAuth2 endpoints reachable via HTTPS. Ensure TLS is configured and avoid exposing cleartext HTTP externally. [2]

4) Be cautious about “production” use at all (current module limitations)

mod_http_oauth2 is explicitly marked alpha and the docs recommend it for “experimental and test deployments only”. It also notes current scope limitations that can make it unsuitable for untrusted clients (clients may effectively get “all or nothing” access). Factor that into any production rollout and threat model. [1]

Sources: Prosody module documentation for mod_http_oauth2 (PKCE requirement, supported flows, grant/response type settings, alpha/deployment notes) [1]; Prosody HTTP server documentation (HTTP/HTTPS services and port/interface behavior) [2]; general OIDC client best-practice note that PKCE is recommended for Authorization Code flows [3].


🌐 Web query:

Prosody mod_http_oauth2 registration key security best practices

💡 Result:

Security best practices for mod_http_oauth2 dynamic client registration key (oauth2_registration_key) in Prosody:

  • Treat oauth2_registration_key like a high-value signing secret (it’s the JWT/HMAC key used to enable Dynamic Client Registration; default algorithm HS256). Generate it with strong randomness (e.g., 32+ random bytes, base64/hex encoded), and don’t reuse it elsewhere. [1]
  • Lock down where the secret lives: keep Prosody config (and any included secret files) readable only by root and the Prosody service user/group; avoid leaking it via backups, support bundles, or logs. Prosody’s own TLS key guidance applies here too (tight file permissions, minimize who can read secrets). [2]
  • Consider setting a finite registration token lifetime instead of the default “unlimited”: configure oauth2_registration_ttl so registrations don’t rely on indefinitely-valid signed artifacts. [1]
  • Limit exposure/abuse of the registration endpoint (/oauth2/register): put it behind a reverse proxy/WAF rate limit, and if your deployment allows it, restrict by source IP/VPN/allowlist to reduce automated client-registration abuse. [3]
  • Prefer HTTPS-only access to the OAuth2 HTTP service (don’t publish plain HTTP for these endpoints; ensure TLS is correctly configured). Prosody’s HTTP service exposes both http and https endpoints depending on config—verify you’re serving OAuth2 over https. [4]

Sources: Prosody community module docs for mod_http_oauth2 registration settings [1], Prosody guidance on protecting key material with strict permissions [2], general DCR hardening controls (rate limits/allowlists) [3], and Prosody HTTP service exposure details [4]. [1][2][3][4]


🌐 Web query:

OAuth2 PKCE code challenge authorization_code grant security requirements

💡 Result:

OAuth 2.0 Authorization Code Grant with PKCE — security requirements (client + server)

Client (app) requirements

  • Generate a high-entropy code_verifier per authorization request using only unreserved characters (A-Z a-z 0-9 - . _ ~) and length 43–128. [1]
  • Derive and send a code_challenge in the authorization request (the code_challenge parameter is REQUIRED in PKCE). [1]
  • Use code_challenge_method=S256 whenever capable:
    • S256: BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
    • plain is only for constrained/legacy cases and should not be used in new implementations; if the client can do S256, it MUST use it. [1]
  • Do not allow downgrade to plain after attempting S256 (prevents downgrade/MITM scenarios). [2]
  • Send the original code_verifier to the token endpoint when exchanging the authorization code (Authorization Code → Tokens). [2]
  • Use standard Authorization Code protections:
    • Use and validate state when used in the request (CSRF protection pattern). [3]
    • Ensure the exact redirect_uri handling matches what’s registered/expected; authorization servers must not redirect to invalid/mismatching redirect URIs. [3]

Authorization Server (AS) requirements

  • Support PKCE (Best Current Practice: AS MUST support PKCE). [4]
  • If an authorization request includes a code_challenge, the AS MUST enforce correct code_verifier usage at the token endpoint (i.e., verify the verifier against the stored/bound challenge). [4]
  • Bind the code_challenge (+ method) to the issued authorization code, and at the token endpoint recompute + compare before issuing tokens. [2]
  • Mitigate PKCE downgrade attacks: a token request containing code_verifier must be accepted only if the original authorization request contained code_challenge. [4]
  • Advertise PKCE capabilities (recommended): publish code_challenge_methods_supported in AS metadata (RFC 8414 metadata element referenced by BCP). [4]

Sources: RFC 7636 (PKCE) [1][2], RFC 6749 (OAuth 2.0) [3], OAuth 2.0 Security Best Current Practice (IETF draft) [4].


Harden OAuth2 defaults before shipping.

Line 66 disables PKCE (oauth2_require_code_challenge = false) while authorization_code is enabled, and Line 68 falls back to a static dev registration key. Prosody's mod_http_oauth2 documentation explicitly recommends keeping PKCE enabled in production; disabling it weakens the authorization code flow. Additionally, the registration key should never fall back to a known static value—it must be a randomly-generated secret managed via environment variable with no hardcoded default.

Suggested hardening
-oauth2_require_code_challenge = false -- Portal uses password grant, not PKCE
+oauth2_require_code_challenge = true -- Keep PKCE protection for authorization_code clients
 -- Dynamic client registration (enables Portal to register as OAuth2 client)
-oauth2_registration_key = Lua.os.getenv("PROSODY_OAUTH2_REGISTRATION_KEY") or "dev-oauth2-registration-key"
+oauth2_registration_key = Lua.os.getenv("PROSODY_OAUTH2_REGISTRATION_KEY")
+if not oauth2_registration_key then
+    error("PROSODY_OAUTH2_REGISTRATION_KEY must be set")
+end
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
+allowed_oauth2_grant_types = {
+ "authorization_code",
+ "device_code",
+ "password", -- Resource Owner Password Grant (Portal provisioning)
+}
+allowed_oauth2_response_types = {
+ "code",
+}
+oauth2_access_token_ttl = 86400 -- 24 hours
+oauth2_refresh_token_ttl = 2592000 -- 30 days
+oauth2_require_code_challenge = false -- Portal uses password grant, not PKCE
+-- Dynamic client registration (enables Portal to register as OAuth2 client)
+oauth2_registration_key = Lua.os.getenv("PROSODY_OAUTH2_REGISTRATION_KEY") or "dev-oauth2-registration-key"
+
allowed_oauth2_grant_types = {
"authorization_code",
"device_code",
"password", -- Resource Owner Password Grant (Portal provisioning)
}
allowed_oauth2_response_types = {
"code",
}
oauth2_access_token_ttl = 86400 -- 24 hours
oauth2_refresh_token_ttl = 2592000 -- 30 days
oauth2_require_code_challenge = true -- Keep PKCE protection for authorization_code clients
-- Dynamic client registration (enables Portal to register as OAuth2 client)
oauth2_registration_key = Lua.os.getenv("PROSODY_OAUTH2_REGISTRATION_KEY")
if not oauth2_registration_key then
error("PROSODY_OAUTH2_REGISTRATION_KEY must be set")
end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@patches/atl-chat-mod-http-oauth2.patch` around lines 56 - 69, The config
enables the "authorization_code" grant but disables PKCE
(oauth2_require_code_challenge = false) and also provides a hardcoded fallback
for oauth2_registration_key; update this by (1) ensuring
oauth2_require_code_challenge is true when "authorization_code" is present in
allowed_oauth2_grant_types (or remove "authorization_code" if PKCE cannot be
enforced), and (2) removing the hardcoded fallback for oauth2_registration_key
so it must come from the environment (fail fast if
Lua.os.getenv("PROSODY_OAUTH2_REGISTRATION_KEY") is nil/empty) to force a
secure, randomly-generated secret in production.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant improvements across several areas, addressing critical integration issues with IRC and XMPP services, enhancing performance, and improving code maintainability. The changes to the Atheme JSON-RPC client correctly handle string IDs and placeholder account names, resolving communication problems. The XMPP integration now correctly uses Bearer token authentication, aligning with modern security practices. Performance has been boosted by parallelizing database queries in multiple admin API routes using Promise.all(), effectively eliminating network waterfalls. Additionally, the use of .toSorted() instead of .sort() ensures immutability in array operations, which is a good practice for maintainability. The documentation for Cursor Cloud specific instructions has also been updated, and relevant tests have been adjusted to reflect these changes. Overall, this is a well-executed and impactful set of changes.

…h2 integration

The patch for adding OAuth2 support via mod_http_oauth2 is removed.
This reverts the previous addition of OAuth2 token generation for
Bearer token authentication in the Portal's mod_http_admin_api.
The removal is necessary due to unforeseen issues or changes in
requirements that make the OAuth2 integration no longer needed or
viable at this time.
@kzndotsh kzndotsh merged commit 0c5bfc6 into main Mar 2, 2026
11 of 14 checks passed
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