Commit Graph

3407 Commits

Author SHA1 Message Date
Matthieu B
8ede52d206 Merge pull request #1221 from wizarrrr/fix/1219-duplicate-wizard-steps-and-api-bundle
fix: deduplicate wizard steps in multi-server setups and add bundle selection to API
2026-04-01 22:36:22 +02:00
Matthieu B
6ebafbf328 fix: deduplicate wizard steps in multi-server setups and add bundle selection to API
Default wizard steps were duplicated once per server instance of the same
type (e.g., 2 Plex servers → 6 steps instead of 3). Deduplicate the
server type list before loading steps so each type's steps appear only once.

Also add the missing wizard_bundle_id parameter to the invitation creation
API, matching the existing web UI capability.

Closes #1219
2026-04-01 22:33:27 +02:00
Matthieu B
4847133026 fix: restore get_recent_items parameter names broken by linting pass
Commit 73c29458f renamed library_id/limit to _library_id/_limit to
suppress ARG002 warnings, but the widget caller passes them as keyword
arguments (limit=6), causing a silent TypeError that returns empty data.

Closes #1207
2026-04-01 22:29:39 +02:00
Matthieu B
5bfccb7f2b Merge pull request #1211 from wizarrrr/dependabot/npm_and_yarn/app/static/alpinejs-3.15.9
build(deps): bump alpinejs from 3.15.8 to 3.15.9 in /app/static
2026-04-01 22:29:15 +02:00
dependabot[bot]
40e6871a0e build(deps): bump alpinejs from 3.15.8 to 3.15.9 in /app/static
Bumps [alpinejs](https://github.com/alpinejs/alpine/tree/HEAD/packages/alpinejs) from 3.15.8 to 3.15.9.
- [Release notes](https://github.com/alpinejs/alpine/releases)
- [Commits](https://github.com/alpinejs/alpine/commits/v3.15.9/packages/alpinejs)

---
updated-dependencies:
- dependency-name: alpinejs
  dependency-version: 3.15.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-01 20:28:28 +00:00
Matthieu B
6db5edc468 Merge pull request #1217 from wizarrrr/dependabot/uv/pygments-2.20.0
build(deps): bump pygments from 2.19.2 to 2.20.0
2026-04-01 22:27:51 +02:00
Matthieu B
1b17490b7b Merge pull request #1216 from wizarrrr/dependabot/uv/setuptools-82.0.1
build(deps): bump setuptools from 82.0.0 to 82.0.1
2026-04-01 22:27:48 +02:00
Matthieu B
0d887d43b4 Merge pull request #1215 from wizarrrr/dependabot/uv/gunicorn-25.3.0
build(deps): bump gunicorn from 25.1.0 to 25.3.0
2026-04-01 22:27:45 +02:00
Matthieu B
f543349f08 Merge pull request #1214 from wizarrrr/dependabot/uv/apprise-1.9.9
build(deps): bump apprise from 1.9.7 to 1.9.9
2026-04-01 22:27:43 +02:00
Matthieu B
e58ca6e2df Merge pull request #1213 from wizarrrr/dependabot/uv/ty-0.0.26
build(deps-dev): bump ty from 0.0.19 to 0.0.26
2026-04-01 22:27:40 +02:00
Matthieu B
f13c4bed5c Merge pull request #1212 from wizarrrr/dependabot/uv/linting-tools-aeea8a7b5e
build(deps-dev): bump ruff from 0.15.7 to 0.15.8 in the linting-tools group
2026-04-01 22:27:37 +02:00
Matthieu B
077cdb3496 Merge pull request #1210 from wizarrrr/dependabot/npm_and_yarn/app/static/alpinejs/collapse-3.15.9
build(deps): bump @alpinejs/collapse from 3.15.8 to 3.15.9 in /app/static
2026-04-01 22:27:19 +02:00
Matthieu B
c554986f68 Merge pull request #1209 from wizarrrr/dependabot/npm_and_yarn/app/static/tiny-markdown-editor-0.2.25
build(deps): bump tiny-markdown-editor from 0.2.24 to 0.2.25 in /app/static
2026-04-01 22:27:16 +02:00
github-actions[bot]
46f1e6d323 i18n: refresh POT and update PO files [skip ci] 2026-04-01 05:31:50 +00:00
github-actions[bot]
fdb18791da i18n: refresh POT and update PO files [skip ci] 2026-03-31 05:19:21 +00:00
dependabot[bot]
d70be00e98 build(deps): bump pygments from 2.19.2 to 2.20.0
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to 2.20.0.
- [Release notes](https://github.com/pygments/pygments/releases)
- [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES)
- [Commits](https://github.com/pygments/pygments/compare/2.19.2...2.20.0)

---
updated-dependencies:
- dependency-name: pygments
  dependency-version: 2.20.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 19:59:55 +00:00
dependabot[bot]
7ca11a2da5 build(deps): bump setuptools from 82.0.0 to 82.0.1
Bumps [setuptools](https://github.com/pypa/setuptools) from 82.0.0 to 82.0.1.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v82.0.0...v82.0.1)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-version: 82.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 09:19:22 +00:00
dependabot[bot]
7aa8abfe07 build(deps): bump gunicorn from 25.1.0 to 25.3.0
Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 25.1.0 to 25.3.0.
- [Release notes](https://github.com/benoitc/gunicorn/releases)
- [Commits](https://github.com/benoitc/gunicorn/compare/25.1.0...25.3.0)

---
updated-dependencies:
- dependency-name: gunicorn
  dependency-version: 25.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 09:19:13 +00:00
dependabot[bot]
14bfc9c9f7 build(deps): bump apprise from 1.9.7 to 1.9.9
Bumps [apprise](https://github.com/caronc/apprise) from 1.9.7 to 1.9.9.
- [Release notes](https://github.com/caronc/apprise/releases)
- [Commits](https://github.com/caronc/apprise/compare/v1.9.7...v1.9.9)

---
updated-dependencies:
- dependency-name: apprise
  dependency-version: 1.9.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 09:19:07 +00:00
dependabot[bot]
ad9d1b9458 build(deps-dev): bump ty from 0.0.19 to 0.0.26
Bumps [ty](https://github.com/astral-sh/ty) from 0.0.19 to 0.0.26.
- [Release notes](https://github.com/astral-sh/ty/releases)
- [Changelog](https://github.com/astral-sh/ty/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ty/compare/0.0.19...0.0.26)

---
updated-dependencies:
- dependency-name: ty
  dependency-version: 0.0.26
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 09:18:59 +00:00
dependabot[bot]
444937b671 build(deps-dev): bump ruff in the linting-tools group
Bumps the linting-tools group with 1 update: [ruff](https://github.com/astral-sh/ruff).


Updates `ruff` from 0.15.7 to 0.15.8
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.15.7...0.15.8)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.15.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: linting-tools
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 09:18:50 +00:00
dependabot[bot]
d8588f55ff build(deps): bump @alpinejs/collapse in /app/static
Bumps [@alpinejs/collapse](https://github.com/alpinejs/alpine/tree/HEAD/packages/collapse) from 3.15.8 to 3.15.9.
- [Release notes](https://github.com/alpinejs/alpine/releases)
- [Commits](https://github.com/alpinejs/alpine/commits/v3.15.9/packages/collapse)

---
updated-dependencies:
- dependency-name: "@alpinejs/collapse"
  dependency-version: 3.15.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 09:17:57 +00:00
dependabot[bot]
acb27b8d63 build(deps): bump tiny-markdown-editor in /app/static
Bumps [tiny-markdown-editor](https://github.com/jefago/tiny-markdown-editor) from 0.2.24 to 0.2.25.
- [Release notes](https://github.com/jefago/tiny-markdown-editor/releases)
- [Commits](https://github.com/jefago/tiny-markdown-editor/compare/v0.2.24...v0.2.25)

---
updated-dependencies:
- dependency-name: tiny-markdown-editor
  dependency-version: 0.2.25
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 09:17:50 +00:00
github-actions[bot]
d3af9edd69 i18n: refresh POT and update PO files [skip ci] 2026-03-30 05:33:59 +00:00
Matthieu B
c57d29035e fix: clean up _alembic_tmp_ debris from prior failed migration runs
Previous failed batch_alter_table attempts leave behind
_alembic_tmp_admin_account in SQLite (no transactional DDL).
Subsequent retries fail trying to CREATE the same temp table.

Now drops any _alembic_tmp_* tables before batch operations, and
splits the admin_account alter into two paths depending on whether
prior columns already exist.
v2026.3.0
2026-03-29 17:48:46 +02:00
Matthieu B
7b316a4674 fix: make LDAP migration idempotent for crash recovery
The previous fix addressed the root cause (FK enforcement blocking
batch_alter_table), but users who already hit the bug have databases
with orphaned LDAP tables from the failed partial run. Since SQLite
has no transactional DDL, those tables persist despite the rollback.

Now the migration checks for existing tables/columns before creating
them, so it recovers cleanly regardless of database state.
2026-03-29 17:43:59 +02:00
Matthieu B
48848657db fix: disable FK enforcement during LDAP migration batch_alter_table
SQLite batch_alter_table recreates tables via DROP + CREATE. With
PRAGMA foreign_keys=ON (set by our connection handler), the DROP TABLE
admin_account fails because webauthn_credential and api_key reference
it. This caused a crash loop: tables created before the crash persisted
(no transactional DDL in SQLite), then re-running created duplicates.
2026-03-29 17:39:14 +02:00
Matthieu B
4a60ad7efb Merge pull request #1196 from wizarrrr/release/v2026.3.0
Release v2026.3.0
2026-03-29 16:54:06 +02:00
github-actions[bot]
c61e183c42 chore: release v2026.3.0 2026-03-29 14:52:02 +00:00
Matthieu B
9b8c0248cd fix: resolve double scrollbar on LDAP settings and add experimental label
Add overflow-hidden to admin layout's h-screen container to prevent
body-level scrolling competing with #content's overflow-y-auto.
Mark LDAP settings as experimental with a badge.
2026-03-29 16:51:36 +02:00
Matthieu B
8817e0a3de fix: use batch_alter_table for SQLite-compatible column addition
SQLite rejects ALTER TABLE ADD COLUMN with non-constant defaults like
datetime('now'). Wrap in batch_alter_table which recreates the table.
2026-03-29 16:42:24 +02:00
Matthieu B
c8d0853fe2 Merge pull request #1205 from wizarrrr/fix/1126-passkey-registration
fix: correct Jinja2 syntax in passkey registration template
2026-03-29 16:36:24 +02:00
Matthieu B
8298794805 Merge pull request #1081 from eleboucher/ldap
feat(ldap): add LDAP authentication and invitation integration
2026-03-29 16:35:03 +02:00
Matthieu B
7b70be9d7e fix: correct Jinja2 syntax in passkey registration template (#1126)
The `tojson` filter already outputs a complete JSON object with braces,
but the template wrapped it in extra JavaScript braces, producing invalid
syntax. This caused a SyntaxError that prevented navigator.credentials.create()
from ever being called — no passkey prompt appeared.
2026-03-29 16:34:47 +02:00
Matthieu B
ef8ad20938 style: reformat templates with djlint 2026-03-29 16:34:26 +02:00
Matthieu B
59e2cb8199 chore: merge main into ldap branch, resolve conflicts 2026-03-29 16:28:20 +02:00
Matthieu B
6cb00478da Merge pull request #1203 from wizarrrr/fix/1121-watch-time-calculation
fix: use playback position instead of file duration for watch time
2026-03-29 16:25:47 +02:00
Matthieu B
77e738f9d7 Merge pull request #1202 from wizarrrr/fix/1195-emby-library-mapping
fix: correct Emby library ID mapping and prevent silent folder fallback (#1195)
2026-03-29 16:25:45 +02:00
Matthieu B
14df208566 Merge pull request #1201 from wizarrrr/fix/1168-plex-reinvite-update
fix: update existing Plex share on re-invite instead of failing
2026-03-29 16:25:43 +02:00
Matthieu B
b642d9100b Merge pull request #1200 from wizarrrr/fix/1182-user-created-at
fix: add missing created_at column to User model
2026-03-29 16:25:40 +02:00
Matthieu B
b5cc553ee8 Merge pull request #1199 from wizarrrr/fix/1174-api-key-legacy-admin
fix: handle legacy admin user when creating API keys
2026-03-29 16:25:38 +02:00
Matthieu B
000085731f Merge pull request #1198 from wizarrrr/fix/1163-expiry-display
fix: preserve per-server expiry dates in user grouping
2026-03-29 16:25:23 +02:00
Matthieu B
06d8c94734 Merge pull request #1204 from wizarrrr/fix/tests-linting-types
fix: resolve all test failures, linting errors, and type errors
2026-03-29 16:24:36 +02:00
Matthieu B
396e940be6 style: fix djlint formatting in template 2026-03-29 16:23:22 +02:00
Matthieu B
73c29458fe fix: resolve all test failures, linting errors, and type errors
- Fix 55 test failures caused by missing request contexts and incorrect
  session_transaction() usage across 8 test files
- Fix ruff import sorting errors and unused imports
- Fix 122 type errors: rename method override parameters to match base
  classes, add None guards for fetchone()/datetime, widen dict type
  annotations, add type: ignore for SQLAlchemy stub limitations
- Add [tool.ty.rules] config to suppress unsupported-base warnings
- Fix _ variable shadowing gettext in wizard routes
- Add noqa: ARG002 for unused method arguments required by base class
2026-03-29 16:20:23 +02:00
Matthieu B
672475469d fix(ldap): security, architecture, and code quality improvements
- Fix SUBTREE→BASE scope in _fetch_user_attributes (security)
- Remove is_ldap_user threading from all 8 media client interfaces;
  set flag after join via workflow-level User.query.update instead
- Use find_user_dn (search-based) instead of build_user_dn (concatenation)
  in delete_user and reset_user_password for robustness
- Wrap all user-facing strings in _() for i18n in ldap_auth.py
- Fix username fallback from hardcoded "wizarr" to unique per-user
- Return failure from _update_existing_user when password update fails
- Replace dynamic Tailwind classes with explicit conditionals in alert
- Add stale group cleanup and upsert in sync_ldap_groups
- Remove fake @ldap.local email fallback in user_sync
2026-03-29 16:18:41 +02:00
Matthieu B
65ed356d62 fix: use playback position instead of file duration for watch time (#1121)
Jellyfin and Emby collectors were recording RunTimeTicks (total file
runtime) as the session duration, causing severe overestimation when
users stopped partway through long titles.

- JellyfinCollector._emit_session_event: on session_end, use position_ms
  (last known playback position) as duration_ms; fall back to
  raw_duration_ms only when position_ms is unavailable or zero.
- EmbyCollector._emit_session_event: identical fix (shared API shape).
- JellyfinHistoricalImporter._process_item: for partially-watched items
  (UserData.Played == false) use PlaybackPositionTicks; keep RunTimeTicks
  only for fully-played items where position has already been reset.
- historical_duration_source metadata field now accurately reflects
  which source was used (runtime_ticks, playback_position_ticks, or
  runtime_ticks_fallback).

Plex was already correct via elapsed-time tracking in SessionManager.
2026-03-29 16:15:56 +02:00
Matthieu B
e9f3c24581 fix: correct Emby library ID mapping and prevent silent folder fallback (#1195)
- Change EmbyClient.libraries() to return {Id: Name} instead of {Guid: Name}
  so Library.external_id stores the value Emby's EnabledFolders policy field
  expects, matching what JellyfinClient._set_specific_folders() resolves.
- Change EmbyClient.scan_libraries() to return {Name: Id} instead of
  {Name: Guid} for the same reason.
- Override _set_specific_folders() in EmbyClient with a mapping that includes
  {Name: Id}, {Id: Id}, and {Guid: Id} entries, providing backwards
  compatibility for existing Library records that still hold a Guid.
- In both EmbyClient._set_specific_folders() and the inherited
  JellyfinClient._set_specific_folders(), when the input names list is
  non-empty but all lookups fail (folder_ids ends up empty), log a structured
  WARNING via structlog and set EnableAllFolders: False with an empty
  EnabledFolders list — restricting access to nothing — rather than silently
  falling back to EnableAllFolders: True which would grant full access.
- Replace inline debug logging.info() calls with structlog structured events.
2026-03-29 16:15:37 +02:00
Matthieu B
751bfb67dd fix: update existing Plex share on re-invite instead of failing (#1168)
When a user who already has a Plex share uses a new invite link, the
"already sharing" error from the Plex API is now handled gracefully by
calling update_user_libraries() and update_user_permissions() instead of
propagating the error to the end-user. The route layer also switches to
a generic, translatable user-facing error message backed by structlog for
admin-visible diagnostics.
2026-03-29 16:15:24 +02:00
Matthieu B
41ca8856f0 fix: add missing created_at column to User model (#1182)
Add created_at column to the User model, an Alembic migration to
backfill existing rows via server_default, and update the API
serialization and OpenAPI spec from the stale `created` field to
`created_at` so the joined/created date is no longer returned as null.
2026-03-29 16:11:05 +02:00