Skip to content

fix(api): remove user_id session check from dashboard settings#711

Merged
s0up4200 merged 2 commits intomainfrom
fix/oidc-dashboard-settings
Dec 8, 2025
Merged

fix(api): remove user_id session check from dashboard settings#711
s0up4200 merged 2 commits intomainfrom
fix/oidc-dashboard-settings

Conversation

@s0up4200
Copy link
Collaborator

@s0up4200 s0up4200 commented Dec 8, 2025

Summary by CodeRabbit

  • Refactor
    • Simplified dashboard settings handler architecture by streamlining internal request handling and data access patterns.
    • Updated database schema for dashboard settings to improve data integrity and table structure consistency.

✏️ Tip: You can customize this high-level summary in your review settings.

@s0up4200 s0up4200 added this to the v1.9.1 milestone Dec 8, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Walkthrough

This change removes session management from the DashboardSettingsHandler by eliminating the sessionManager field and its constructor parameter. Authentication logic is replaced with a hardcoded user ID (1). A database migration removes a foreign key constraint from the dashboard_settings table via table recreation (required by SQLite's limitations).

Changes

Cohort / File(s) Summary
Handler Session Removal
internal/api/handlers/dashboard_settings.go
Removed sessionManager field and updated NewDashboardSettingsHandler constructor to accept only store parameter. Modified Get and Update methods to use hardcoded user ID (1) instead of retrieving from session. Removed scs/v2 import and adjusted error logging.
Constructor Update
internal/api/server.go
Updated NewDashboardSettingsHandler call to remove sessionManager argument, now passing only the store.
Database Migration
internal/database/migrations/027_remove_dashboard_settings_fk.sql
SQL migration that removes foreign key from dashboard_settings table by recreating it with stricter user_id UNIQUE constraint, copying existing data, and adding trg_dashboard_settings_updated trigger for updated_at refresh.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review the hardcoded user ID (1) logic in dashboard_settings.go to confirm intended behavior and potential implications for multi-user systems
  • Verify the migration correctly preserves all data during table recreation and that the trigger logic is sound
  • Ensure no other code paths depend on the removed sessionManager parameter

Poem

🐰 Sessions fade like morning dew,
One user ID, the constrained view,
Foreign keys fall, rebuilt anew,
Simpler schemas, less to review!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: removing session-based user ID validation from dashboard settings handlers.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/oidc-dashboard-settings

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1aa7360 and b61999f.

📒 Files selected for processing (3)
  • internal/api/handlers/dashboard_settings.go (2 hunks)
  • internal/api/server.go (1 hunks)
  • internal/database/migrations/027_remove_dashboard_settings_fk.sql (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-19T20:04:51.737Z
Learnt from: s0up4200
Repo: autobrr/qui PR: 606
File: internal/database/migrations/016_add_instance_reannounce_settings.sql:21-27
Timestamp: 2025-11-19T20:04:51.737Z
Learning: In the autobrr/qui repository, PRAGMA recursive_triggers is never enabled in the SQLite setup. The AFTER UPDATE trigger pattern that issues a separate UPDATE statement on the same table (e.g., to update an updated_at timestamp) is used consistently across migrations and does not cause recursion with recursive_triggers disabled (the SQLite default). This pattern should remain consistent across all migrations.

Applied to files:

  • internal/database/migrations/027_remove_dashboard_settings_fk.sql
🧬 Code graph analysis (2)
internal/api/server.go (1)
internal/api/handlers/dashboard_settings.go (1)
  • NewDashboardSettingsHandler (19-23)
internal/api/handlers/dashboard_settings.go (2)
internal/models/dashboard_settings.go (1)
  • DashboardSettingsStore (50-52)
internal/api/handlers/helpers.go (1)
  • RespondError (34-38)
⏰ 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). (1)
  • GitHub Check: Run tests
🔇 Additional comments (5)
internal/database/migrations/027_remove_dashboard_settings_fk.sql (2)

28-32: Trigger pattern is correct.

The AFTER UPDATE trigger that issues a separate UPDATE statement follows the established pattern in this codebase and is safe without recursive_triggers enabled.

Based on learnings, this pattern is consistent with other migrations in the repository.


7-26: This review comment is based on a misunderstanding of SQL UNIQUE constraints and does not identify an actual issue.

The UNIQUE constraint on user_id does not create a "single shared dashboard settings row for all users." Instead, it enforces that there is one settings row per distinct user_id value—allowing user 1 to have their settings row, user 2 to have theirs, and so on. With the handler hardcoding userID = 1, this is the correct design: one application user with their own settings.

This is a deliberate single-user application architecture where OIDC handles external authentication while the application runs as a single internal user (user_id=1). The UNIQUE constraint on user_id existed in the original migration (026_add_dashboard_settings.sql) and was not introduced by this migration. Migration 027 correctly removes only the FOREIGN KEY constraint to support OIDC-only installs that lack a user table.

The code is working as intended and requires no changes.

Likely an incorrect or invalid review comment.

internal/api/handlers/dashboard_settings.go (2)

19-23: Constructor change removes session management.

The constructor signature has been simplified to remove the sessionManager parameter, aligning with the removal of per-user session-based authentication for dashboard settings.


26-26: The hardcoded userID=1 is correct by design for this single-user system.

This is not a multi-user system and not a behavior change. The database schema enforces a single-user constraint with CHECK (id = 1) on the user table. Both password and OIDC authentication methods authenticate to the same user account (ID=1). Dashboard settings correctly use this hardcoded ID, which is consistent with how all user operations in the codebase function (e.g., UserStore.Get(), UserStore.UpdatePassword() also hardcode ID=1). The middleware extracts a username from context for display/logging purposes, but the system architecture is intentionally single-user.

Likely an incorrect or invalid review comment.

internal/api/server.go (1)

271-271: Constructor call correctly updated.

The NewDashboardSettingsHandler call has been correctly updated to match the new signature that no longer requires a sessionManager parameter.

Note: The dashboard settings routes (lines 357-358) remain protected by the IsAuthenticated middleware, ensuring only authenticated users can access them. However, the handler itself uses a hardcoded userID = 1, meaning all authenticated users share the same settings.

Please clarify the intended user model for dashboard settings:

  • Is this application single-user only?
  • Should dashboard settings be global/shared across all users?
  • Is per-user dashboard settings support planned for the future?

This will help determine if the current implementation aligns with product requirements.


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

@s0up4200 s0up4200 merged commit 441418b into main Dec 8, 2025
11 checks passed
@s0up4200 s0up4200 deleted the fix/oidc-dashboard-settings branch December 8, 2025 18:07
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Dec 11, 2025
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.8.1` -> `v1.9.1` |

---

### Release Notes

<details>
<summary>autobrr/qui (ghcr.io/autobrr/qui)</summary>

### [`v1.9.1`](https://github.com/autobrr/qui/releases/tag/v1.9.1)

[Compare Source](autobrr/qui@v1.9.0...v1.9.1)

#### Changelog

##### Bug Fixes

- [`441418b`](autobrr/qui@441418b): fix(api): remove user\_id session check from dashboard settings ([#&#8203;711](autobrr/qui#711)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`bd2587b`](autobrr/qui@bd2587b): fix(db): resolve cross-seed settings mutual exclusivity lockout ([#&#8203;714](autobrr/qui#714)) ([@&#8203;s0up4200](https://github.com/s0up4200))

**Full Changelog**: <autobrr/qui@v1.9.0...v1.9.1>

#### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.9.1`
- `docker pull ghcr.io/autobrr/qui:latest`

#### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

### [`v1.9.0`](https://github.com/autobrr/qui/releases/tag/v1.9.0)

[Compare Source](autobrr/qui@v1.8.1...v1.9.0)

#### Changelog

##### Important

Cross-seeds are now added to `.cross`-suffixed categories by default. This is opt-out. The old delay logic is removed.

##### Highlights

- Customize your Dashboard-page (order, visibility)
- Tracker Breakdown section in Dashboard with import/export functionality
- Warnings and actions for cross-seeds when you attempt to delete torrents
- Show free space in torrent table footer

##### New Features

- [`1aa7360`](autobrr/qui@1aa7360): feat(dashboard): tracker breakdown and customizable layout ([#&#8203;637](autobrr/qui#637)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`85fd74b`](autobrr/qui@85fd74b): feat(jackett): propagate 429 rate limits with retry and cooldown ([#&#8203;684](autobrr/qui#684)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`a5777c4`](autobrr/qui@a5777c4): feat(reannounce): add configurable max retries setting ([#&#8203;685](autobrr/qui#685)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6451e56`](autobrr/qui@6451e56): feat(settings): add TMM relocation behavior settings ([#&#8203;664](autobrr/qui#664)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`680fd25`](autobrr/qui@680fd25): feat(torrents): add confirmation dialogs for TMM and Set Location ([#&#8203;687](autobrr/qui#687)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`7f779f9`](autobrr/qui@7f779f9): feat(torrents): warn about cross-seeded torrents in delete dialogs ([#&#8203;670](autobrr/qui#670)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1c489bc`](autobrr/qui@1c489bc): feat(ui): persist category collapse state in sidebar ([#&#8203;692](autobrr/qui#692)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`bdf807e`](autobrr/qui@bdf807e): feat(web): Torrent list details bar shows free space ([#&#8203;691](autobrr/qui#691)) ([@&#8203;finevan](https://github.com/finevan))

##### Bug Fixes

- [`9db8346`](autobrr/qui@9db8346): fix(crossseed): use matched torrent save path instead of category path ([#&#8203;700](autobrr/qui#700)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`40d7778`](autobrr/qui@40d7778): fix(instance): intern empty string on demand for bypass auth ([#&#8203;693](autobrr/qui#693)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`0aaf39e`](autobrr/qui@0aaf39e): fix(jackett): fetch indexer capabilities in parallel with retries ([#&#8203;701](autobrr/qui#701)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`50e585b`](autobrr/qui@50e585b): fix(qbittorrent): cache tracker health counts in background ([#&#8203;662](autobrr/qui#662)) ([@&#8203;KyleSanderson](https://github.com/KyleSanderson))
- [`298ca05`](autobrr/qui@298ca05): fix(search): download torrent files via backend for remote instances ([#&#8203;686](autobrr/qui#686)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`27ee31a`](autobrr/qui@27ee31a): fix(torrents): AddTorrentDialog uses the downloadPath api ([#&#8203;677](autobrr/qui#677)) ([@&#8203;finevan](https://github.com/finevan))
- [`2427fdd`](autobrr/qui@2427fdd): fix(ui): use full category paths in multi-select ([#&#8203;683](autobrr/qui#683)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`917c65e`](autobrr/qui@917c65e): fix(web): add iOS Safari compatibility for torrent file picker ([#&#8203;707](autobrr/qui#707)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`2ccdc28`](autobrr/qui@2ccdc28): fix(web): dont hide free space when disk is full ([#&#8203;694](autobrr/qui#694)) ([@&#8203;ewenjo](https://github.com/ewenjo))

##### Other Changes

- [`d684442`](autobrr/qui@d684442): chore(deps): bump the golang group with 7 updates ([#&#8203;660](autobrr/qui#660)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`e1267fa`](autobrr/qui@e1267fa): chore(deps): bump the npm group across 1 directory with 29 updates ([#&#8203;663](autobrr/qui#663)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`8671971`](autobrr/qui@8671971): docs: Update README to remove size field description ([#&#8203;695](autobrr/qui#695)) ([@&#8203;s0up4200](https://github.com/s0up4200))

**Full Changelog**: <autobrr/qui@v1.8.1...v1.9.0>

#### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.9.0`
- `docker pull ghcr.io/autobrr/qui:latest`

#### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi4zOS4xIiwidXBkYXRlZEluVmVyIjoiNDIuMzkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/2366
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to login over OIDC after v1.9 update Unable to log in using OIDC because of /api/dashboard-settings

1 participant