Skip to content

updated with some api consolidation and changes#2596

Merged
gtsteffaniak merged 2 commits into
dev/v2.0.0from
api-changes-view-download
Jul 3, 2026
Merged

updated with some api consolidation and changes#2596
gtsteffaniak merged 2 commits into
dev/v2.0.0from
api-changes-view-download

Conversation

@gtsteffaniak

@gtsteffaniak gtsteffaniak commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Description

According to the contributing guide, A PR should contain:

  • A clear description of why it was opened.
  • A short title that best describes the change.
  • Must pass unit and integration tests, which can be run checked locally prior to opening a PR.
  • Any additional details for functionality not covered by tests.

Additional Details

Summary by CodeRabbit

  • New Features

    • Added dedicated inline viewing for non-media files via a new view flow.
    • Media playback now routes through /api/media/stream (and public equivalent), enforcing audio/video-only streaming.
    • 3D previews and document/ebook viewers updated to use the new viewing flow.
  • Bug Fixes

    • Improved request timeout responses with clearer JSON error details.
    • Updated generated preview/open links to consistently use view tokens for both files and directories.
    • Added backward-compatible /raw and /api/raw download routes.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR renames stream-token based viewing to view-token based viewing across backend and frontend code, adds a dedicated inline view endpoint, updates media streaming to require media-only requests, and rewires viewer URL generation and token plumbing. It also tightens user permission normalization.

Changes

Stream-to-view token migration

Layer / File(s) Summary
ViewGrant contract and cache
backend/common/utils/stream_grant.go, backend/common/utils/cache.go, backend/indexing/iteminfo/fileinfo.go, CHANGELOG.md
Renames StreamGrant/StreamGrantsCache and file metadata StreamToken fields to ViewGrant/ViewGrantsCache and ViewToken, with changelog wording updates.
View grant minting and tests
backend/http/stream_grant.go, backend/http/stream_grant_test.go
Replaces stream-grant helpers with view-grant helpers and updates attachment and validation tests.
View handlers and routing
backend/http/view.go, backend/http/httpRouter.go
Adds authenticated and public view handlers, routes /resources/view, adds legacy raw routes, and wraps media routes with timeouts.
Stream endpoint behavior
backend/http/stream.go, backend/http/stream_range.go, backend/http/stream_range_test.go
Moves stream endpoints to viewToken, enforces media-only access, and makes range-only streaming unconditional.
Timeout and token attachment wiring
backend/http/middleware.go, backend/http/middleware_test.go, backend/http/resource.go
Adds typed timeout errors, changes token attachment to view tokens, and updates middleware/resource tests.
Media file detection and URL helpers
frontend/src/utils/mediaFile.js, frontend/src/utils/mediaFile.test.js, frontend/src/api/media.js, frontend/src/api/resources.js, frontend/src/api/resources.view.test.js
Adds media-type detection and updates URL helpers to route media and non-media viewing through view-token based endpoints.
Frontend token plumbing
frontend/src/store/types.ts, frontend/src/store/mutations.js, frontend/src/components/files/Icon.vue, frontend/src/components/files/ListingItem.vue, frontend/src/views/files/ListingView.vue
Renames frontend token fields and props to viewToken and updates prefetch wiring.
Viewer URL generation
frontend/src/views/files/DocViewer.vue, frontend/src/views/files/EpubViewer.vue, frontend/src/views/files/Preview.vue, frontend/src/utils/htmlPreview.ts, frontend/src/utils/htmlPreview.test.js, frontend/src/views/files/ThreeJs.vue
Updates viewer flows to pass viewToken, resolve sibling tokens, and load models/textures through the new view URLs.

UserEdit Permission Fix

Layer / File(s) Summary
Stricter permission null checks
frontend/src/components/prompts/UserEdit.vue
Changes permission normalization to use explicit null and undefined checks.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Poem

A rabbit hopped by moonlit view,
With tokens changed from old to new 🐇
Streams now stream with media grace,
Views find files in their proper place,
Hops and props align just right.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague and generic to convey the main change in this PR. Replace it with a concise, specific title that names the primary API/view-download token consolidation change.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch api-changes-view-download

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
backend/http/middleware.go (1)

146-151: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add /raw to the fast-path skip list.
GET /raw now maps to the same publicDownloadHandler as /resources/download, but it still falls through to FileInfoFasterFunc and view-token minting here. That adds avoidable I/O and cache churn on a hot download path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/http/middleware.go` around lines 146 - 151, The fast-path skip list
in the middleware path check does not include the new GET /raw route, so
requests still fall through to FileInfoFasterFunc and view-token minting. Update
the conditional in the middleware that checks r.Method and r.URL.Path to treat
/raw the same as /resources/download, using the existing path-matching logic
alongside the other download/view exclusions.
🧹 Nitpick comments (11)
frontend/src/components/prompts/UserEdit.vue (1)

334-346: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Correct null/undefined handling.

Logic is sound: strict checks avoid misclassifying valid falsy/empty permission objects. Optionally, the repeated === null || === undefined pairs could be simplified using == null (which is true for both null and undefined in JS) to reduce verbosity.

♻️ Optional simplification
-      if ((user.permissions === null || user.permissions === undefined) && user.account?.permissions !== null && user.account?.permissions !== undefined) {
+      if (user.permissions == null && user.account?.permissions != null) {
         user.permissions = { ...user.account.permissions };
-        if (user.permissions.download === null || user.permissions.download === undefined) {
+        if (user.permissions.download == null) {
           user.permissions.download = true;
         }
       }
-      if (user.permissions === null || user.permissions === undefined) {
+      if (user.permissions == null) {
         user.permissions = this.defaultPermissions();
       }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/prompts/UserEdit.vue` around lines 334 - 346, In
normalizeFormUser, the null/undefined handling is already correct, but the
repeated strict checks for user.permissions and user.account.permissions can be
simplified. Update the permission-null checks in this method to use a single
nullish comparison pattern so the code stays equivalent while being less
verbose, and keep the existing behavior in UserEdit.vue unchanged.
CHANGELOG.md (1)

32-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Redundant/conflicting endpoint notes in same changelog block.

Line 34 still says "new resources/stream endpoint" while lines 38-39 describe moving the stream API to /media/stream and splitting non-media viewing to /api/resources/view. Both bullets describe the same endpoint evolution within the same v2.0.0 "Notes" section, which reads as contradictory to end users reading the changelog.

📝 Suggested consolidation
 **Notes**:
 - new dropdown and input styles
- - new resources/stream endpoint
 - user updates are more granular, don't include entire user payload.
 - `user.id` has been moved to a backend property and all frontend apis now query users by username. Swagger has been updated.
 - removed legacy and deprecated properties from API responses and generated config output
 - Moved stream api to `/media/stream`
 - `/api/media/stream` is audio/video only (range-based chunking). Non-media inline viewing uses `GET /api/resources/view`. Both endpoints use the same `viewToken` from file metadata.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` around lines 32 - 39, The changelog Notes section contains
duplicate/conflicting endpoint bullets, so consolidate the streaming/viewing
changes into a single clear entry. Update the relevant bullets in CHANGELOG.md
to describe the final API split using the existing stream and view endpoint
wording, and remove or rewrite the older “new resources/stream endpoint” note so
it does not contradict the later `/media/stream` and `/api/resources/view`
descriptions.
frontend/src/utils/mediaFile.js (1)

1-4: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider adding a few more common audio/video extensions.

MEDIA_EXTENSIONS omits some common formats (e.g. .3gp, .flv, .ts, .mpg/.mpeg, .m2ts). Files with these extensions will fall through to the non-media /resources/view path instead of the range-based /media/stream endpoint, degrading seek/scrub UX for those formats.

♻️ Suggested extension additions
 const MEDIA_EXTENSIONS = new Set([
   '.mp3', '.mp4', '.m4a', '.flac', '.wav', '.ogg', '.oga', '.opus',
   '.webm', '.mkv', '.avi', '.mov', '.wmv', '.m4v', '.aac', '.wma',
+  '.3gp', '.flv', '.ts', '.mpg', '.mpeg', '.m2ts',
 ])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/utils/mediaFile.js` around lines 1 - 4, MEDIA_EXTENSIONS is
missing several common audio/video formats, so add the suggested extensions
(such as .3gp, .flv, .ts, .mpg/.mpeg, and .m2ts) to the MEDIA_EXTENSIONS set in
mediaFile.js. Keep the existing isMediaFile logic unchanged so files with these
extensions correctly route to /media/stream instead of falling through to
/resources/view.
frontend/src/api/media.js (2)

105-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No direct unit tests for the new media.js exports.

getStreamURL/getStreamURLPublic are only exercised indirectly via mocks in resources.view.test.js; their own validation branches (missing source/viewToken) and param construction aren't directly tested.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/api/media.js` around lines 105 - 142, Add direct unit coverage
for the new media helpers in media.js: create tests for getStreamURL and
getStreamURLPublic that verify the missing-source and missing-viewToken
validation branches throw as expected, and that the returned URL includes the
correct params built via getApiPath/getPublicApiPath. Use the function names
getStreamURL and getStreamURLPublic so the tests stay anchored even if
surrounding code changes.

105-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate URL-building logic across media.js and resources.js.

getStreamURL/getStreamURLPublic here are structurally identical to getRawViewURL/getRawViewURLPublic in resources.js (same validation, same params shape, same try/catch/notify pattern) — only the endpoint string differs (media/stream vs resources/view). Consider extracting a shared helper to avoid the two paths drifting apart on future fixes (e.g. sessionId handling, error messaging).

♻️ Example consolidation
+function buildResourceURL(endpoint, source, path, viewToken, errorLabel) {
+  if (!source) throw new Error('no source provided')
+  if (!viewToken) throw new Error('view token required')
+  try {
+    const params = { source, file: path, viewToken, sessionId: state.sessionId }
+    return window.origin + getApiPath(endpoint, params)
+  } catch (err) {
+    notify.showError(err.message || errorLabel)
+    throw err
+  }
+}
+
+export function getStreamURL(source, path, viewToken) {
+  return buildResourceURL('media/stream', source, path, viewToken, 'Error getting stream URL')
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/api/media.js` around lines 105 - 142, The URL-building and
validation logic in getStreamURL and getStreamURLPublic is duplicated with the
equivalent helpers in resources.js, so future fixes can drift between the two
paths. Extract the shared source/path/viewToken/sessionId construction and
notify/error handling into a common helper, then have getStreamURL and
getStreamURLPublic call it while only passing the endpoint-specific path
(media/stream vs resources/view).
frontend/src/api/resources.view.test.js (1)

1-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extend coverage to shareInfo and download-fallback branches.

Current tests only cover the non-share, viewToken-present paths. getViewURL's share-based routing (getRawViewURLPublic) and the allowDownloadFallback=true branch (getDownloadURL/getDownloadURLPublic) aren't exercised here, despite being core to the view-token migration's contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/api/resources.view.test.js` around lines 1 - 57, The getViewURL
tests currently miss the share-based and download-fallback routing paths, so
extend this suite to cover those branches. Add cases that use the mocked
store.state.shareInfo and getters.isShare to verify getRawViewURLPublic is used
when sharing is enabled, and add allowDownloadFallback=true scenarios to
exercise getDownloadURL/getDownloadURLPublic behavior. Use getViewURL and the
existing mocked `@/api/media` helpers to confirm the returned URLs switch
correctly across these branches.
frontend/src/views/files/ThreeJs.vue (2)

365-374: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate sibling-token matching logic across files.

resolveViewTokenForPath reimplements essentially the same name/path matching heuristic as viewTokenForSibling in frontend/src/utils/htmlPreview.ts. Consolidating into a single shared utility would let both the correctness fix and any future refinement (nested-path handling) be applied once.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/views/files/ThreeJs.vue` around lines 365 - 374, The sibling
token lookup logic is duplicated between resolveViewTokenForPath in ThreeJs.vue
and viewTokenForSibling in htmlPreview.ts, so please consolidate the name/path
matching into one shared utility and have resolveViewTokenForPath call it
instead of reimplementing the heuristic. Keep the existing fbdata.path and
parentDirItems behavior intact, but route both callers through the shared helper
so any future nested-path or matching fixes only need to be made once.

388-393: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant getAll fallback.

parsed.searchParams.get("file") || parsed.searchParams.getAll("file")[0]get() already returns the first value of a repeated param, so getAll("file")[0] never differs from get("file") when a match exists; this fallback is dead code.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/views/files/ThreeJs.vue` around lines 388 - 393, The URL parsing
in ThreeJs.vue has a redundant fallback in the file lookup logic:
`parsed.searchParams.get("file") || parsed.searchParams.getAll("file")[0]` in
the URL handling path. Update the code in the `resourceViewUrl`/URL parsing
block to use only `searchParams.get("file")`, since `get()` already returns the
first matching value and the `getAll()[0]` branch is dead code. Keep the
existing behavior otherwise, just simplify the `filePath` assignment and related
return flow.
backend/http/view.go (1)

39-66: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate the duplicated token/validation preamble shared with streamHandler.

viewHandler and streamHandler (backend/http/stream.go, Lines 130-159) share nearly identical logic: archive/algo rejection, single-file enforcement, viewToken extraction, SanitizePath, validateViewGrant, GetScopeForSourceName, and JoinPathAsUnix. Likewise publicViewHandler mirrors publicStreamHandler. Extracting a shared helper that returns (source, scopedPath, status, error) would remove the duplication and prevent the two flows from drifting (e.g. one endpoint tightening validation while the other lags).

As per path instructions: "reduce duplication where there is clear duplication found, use consolidated functions."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/http/view.go` around lines 39 - 66, The `viewHandler` preamble is
duplicated with `streamHandler` and the public variants, so extract the shared
archive/algo rejection, single-file check, token extraction, path sanitization,
grant validation, scope lookup, and scoped-path construction into a common
helper. Use the existing `viewHandler`, `streamHandler`, `publicViewHandler`,
`publicStreamHandler`, and `validateViewGrant` symbols to centralize the logic
and have both handlers call that helper before invoking their respective
file-serving functions.

Source: Path instructions

backend/http/stream_grant.go (1)

85-95: 🚀 Performance & Scalability | 🔵 Trivial

Per-file view-grant minting on every listing may bloat the shared cache.

attachViewTokensForDirectory mints a fresh random token (crypto RandomHex) and writes a ViewGrantsCache entry for every non-directory child on each listing request. For large directories or frequent re-listings, this is O(n) crypto + cache writes per request and can accumulate many short-lived entries in the global 15-minute cache. Consider reusing a deterministic/idempotent grant per (user, source, path) window or bounding cache size, if listings can be large or hot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/http/stream_grant.go` around lines 85 - 95, The per-file minting in
attachViewTokensForDirectory is creating a new RandomHex token and
ViewGrantsCache entry for every non-directory child on each listing, which can
bloat the shared cache and add O(n) work per request. Update the flow around
mintViewGrant and attachViewTokensForDirectory so grants are reused
deterministically or idempotently for the same (user, source, path) within the
cache window, or otherwise bound the number of cached entries created during
listings. Keep the existing childPath-based lookup and ViewToken assignment
behavior, but avoid generating fresh grants for every repeated listing.

Source: Path instructions

backend/http/httpRouter.go (1)

140-159: 📐 Maintainability & Code Quality | 🔵 Trivial

Consider consolidating repeated timeout+helper wrapping.

The withTimeout(mediaHandlerTimeout, withUserHelper(...)) / withTimeout(mediaHandlerTimeout, withHashFileHelper(...)) pattern is repeated 7 times across these two route blocks. A small local helper would reduce duplication and make future timeout tuning a single-point change.

♻️ Suggested consolidation
+	mediaTimeout := func(fn handleFunc) handleFunc { return withTimeout(mediaHandlerTimeout, withUserHelper(fn)) }
+	mediaTimeoutPublic := func(fn handleFunc) handleFunc { return withTimeout(mediaHandlerTimeout, withHashFileHelper(fn)) }
+
-	api.HandleFunc("GET /resources/view", withTimeout(mediaHandlerTimeout, withUserHelper(viewHandler)))
+	api.HandleFunc("GET /resources/view", mediaTimeout(viewHandler))
 ...
-	publicApi.HandleFunc("GET /resources/view", withTimeout(mediaHandlerTimeout, withHashFileHelper(publicViewHandler)))
+	publicApi.HandleFunc("GET /resources/view", mediaTimeoutPublic(publicViewHandler))

As per path instructions, "reduce duplication where there is clear duplication found, use consolidated functions."

Also applies to: 206-212

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/http/httpRouter.go` around lines 140 - 159, Repeated
timeout-plus-helper wrapping for resource view/preview routes is duplicated
across the api and publicApi registrations, so extract a small local helper to
centralize this pattern. Update the route setup around withTimeout,
withUserHelper, and withHashFileHelper to use that helper for the view/preview
handlers, keeping the timeout values and handler behavior unchanged while making
future timeout updates a single-point change.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/utils/htmlPreview.ts`:
- Around line 49-62: The sibling-token fallback in viewTokenForSibling is
matching by basename and endsWith, which can return a token for the wrong path
and cause getViewURL to build an invalid request. Update the lookup in
htmlPreview.ts so it only uses tokens from the resolved directory, preferably by
requiring an exact entry.path match (or equivalent directory-scoped check)
before falling back, while keeping the existing viewToken return behavior
unchanged.

In `@frontend/src/views/files/ThreeJs.vue`:
- Around line 341-374: The texture URL lookup in ThreeJs.vue is too strict:
resolveTextureUrl can rewrite bare names into nested paths, but
resolveViewTokenForPath only matches the current file or flat siblings, so
getViewURL() ends up without a token for nested assets. Update resourceViewUrl
and resolveViewTokenForPath to recognize rewritten texture paths (for example,
modelDir/textures/... and other nested sibling locations), and add a fallback
path when no exact sibling token exists so texture loading can still resolve.
Keep the existing ThreeJs.vue helpers and resourcesApi.getViewURL flow, but make
sure the lookup can derive a usable token or fallback for nested asset layouts.

---

Outside diff comments:
In `@backend/http/middleware.go`:
- Around line 146-151: The fast-path skip list in the middleware path check does
not include the new GET /raw route, so requests still fall through to
FileInfoFasterFunc and view-token minting. Update the conditional in the
middleware that checks r.Method and r.URL.Path to treat /raw the same as
/resources/download, using the existing path-matching logic alongside the other
download/view exclusions.

---

Nitpick comments:
In `@backend/http/httpRouter.go`:
- Around line 140-159: Repeated timeout-plus-helper wrapping for resource
view/preview routes is duplicated across the api and publicApi registrations, so
extract a small local helper to centralize this pattern. Update the route setup
around withTimeout, withUserHelper, and withHashFileHelper to use that helper
for the view/preview handlers, keeping the timeout values and handler behavior
unchanged while making future timeout updates a single-point change.

In `@backend/http/stream_grant.go`:
- Around line 85-95: The per-file minting in attachViewTokensForDirectory is
creating a new RandomHex token and ViewGrantsCache entry for every non-directory
child on each listing, which can bloat the shared cache and add O(n) work per
request. Update the flow around mintViewGrant and attachViewTokensForDirectory
so grants are reused deterministically or idempotently for the same (user,
source, path) within the cache window, or otherwise bound the number of cached
entries created during listings. Keep the existing childPath-based lookup and
ViewToken assignment behavior, but avoid generating fresh grants for every
repeated listing.

In `@backend/http/view.go`:
- Around line 39-66: The `viewHandler` preamble is duplicated with
`streamHandler` and the public variants, so extract the shared archive/algo
rejection, single-file check, token extraction, path sanitization, grant
validation, scope lookup, and scoped-path construction into a common helper. Use
the existing `viewHandler`, `streamHandler`, `publicViewHandler`,
`publicStreamHandler`, and `validateViewGrant` symbols to centralize the logic
and have both handlers call that helper before invoking their respective
file-serving functions.

In `@CHANGELOG.md`:
- Around line 32-39: The changelog Notes section contains duplicate/conflicting
endpoint bullets, so consolidate the streaming/viewing changes into a single
clear entry. Update the relevant bullets in CHANGELOG.md to describe the final
API split using the existing stream and view endpoint wording, and remove or
rewrite the older “new resources/stream endpoint” note so it does not contradict
the later `/media/stream` and `/api/resources/view` descriptions.

In `@frontend/src/api/media.js`:
- Around line 105-142: Add direct unit coverage for the new media helpers in
media.js: create tests for getStreamURL and getStreamURLPublic that verify the
missing-source and missing-viewToken validation branches throw as expected, and
that the returned URL includes the correct params built via
getApiPath/getPublicApiPath. Use the function names getStreamURL and
getStreamURLPublic so the tests stay anchored even if surrounding code changes.
- Around line 105-142: The URL-building and validation logic in getStreamURL and
getStreamURLPublic is duplicated with the equivalent helpers in resources.js, so
future fixes can drift between the two paths. Extract the shared
source/path/viewToken/sessionId construction and notify/error handling into a
common helper, then have getStreamURL and getStreamURLPublic call it while only
passing the endpoint-specific path (media/stream vs resources/view).

In `@frontend/src/api/resources.view.test.js`:
- Around line 1-57: The getViewURL tests currently miss the share-based and
download-fallback routing paths, so extend this suite to cover those branches.
Add cases that use the mocked store.state.shareInfo and getters.isShare to
verify getRawViewURLPublic is used when sharing is enabled, and add
allowDownloadFallback=true scenarios to exercise
getDownloadURL/getDownloadURLPublic behavior. Use getViewURL and the existing
mocked `@/api/media` helpers to confirm the returned URLs switch correctly across
these branches.

In `@frontend/src/components/prompts/UserEdit.vue`:
- Around line 334-346: In normalizeFormUser, the null/undefined handling is
already correct, but the repeated strict checks for user.permissions and
user.account.permissions can be simplified. Update the permission-null checks in
this method to use a single nullish comparison pattern so the code stays
equivalent while being less verbose, and keep the existing behavior in
UserEdit.vue unchanged.

In `@frontend/src/utils/mediaFile.js`:
- Around line 1-4: MEDIA_EXTENSIONS is missing several common audio/video
formats, so add the suggested extensions (such as .3gp, .flv, .ts, .mpg/.mpeg,
and .m2ts) to the MEDIA_EXTENSIONS set in mediaFile.js. Keep the existing
isMediaFile logic unchanged so files with these extensions correctly route to
/media/stream instead of falling through to /resources/view.

In `@frontend/src/views/files/ThreeJs.vue`:
- Around line 365-374: The sibling token lookup logic is duplicated between
resolveViewTokenForPath in ThreeJs.vue and viewTokenForSibling in
htmlPreview.ts, so please consolidate the name/path matching into one shared
utility and have resolveViewTokenForPath call it instead of reimplementing the
heuristic. Keep the existing fbdata.path and parentDirItems behavior intact, but
route both callers through the shared helper so any future nested-path or
matching fixes only need to be made once.
- Around line 388-393: The URL parsing in ThreeJs.vue has a redundant fallback
in the file lookup logic: `parsed.searchParams.get("file") ||
parsed.searchParams.getAll("file")[0]` in the URL handling path. Update the code
in the `resourceViewUrl`/URL parsing block to use only
`searchParams.get("file")`, since `get()` already returns the first matching
value and the `getAll()[0]` branch is dead code. Keep the existing behavior
otherwise, just simplify the `filePath` assignment and related return flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 62709b15-1c84-44cb-af50-98115b931740

📥 Commits

Reviewing files that changed from the base of the PR and between a58dc77 and efbea4d.

📒 Files selected for processing (31)
  • CHANGELOG.md
  • backend/common/utils/cache.go
  • backend/common/utils/stream_grant.go
  • backend/http/httpRouter.go
  • backend/http/middleware.go
  • backend/http/middleware_test.go
  • backend/http/resource.go
  • backend/http/stream.go
  • backend/http/stream_grant.go
  • backend/http/stream_grant_test.go
  • backend/http/stream_range.go
  • backend/http/stream_range_test.go
  • backend/http/view.go
  • backend/indexing/iteminfo/fileinfo.go
  • frontend/src/api/media.js
  • frontend/src/api/resources.js
  • frontend/src/api/resources.view.test.js
  • frontend/src/components/files/Icon.vue
  • frontend/src/components/files/ListingItem.vue
  • frontend/src/components/prompts/UserEdit.vue
  • frontend/src/store/mutations.js
  • frontend/src/store/types.ts
  • frontend/src/utils/htmlPreview.test.js
  • frontend/src/utils/htmlPreview.ts
  • frontend/src/utils/mediaFile.js
  • frontend/src/utils/mediaFile.test.js
  • frontend/src/views/files/DocViewer.vue
  • frontend/src/views/files/EpubViewer.vue
  • frontend/src/views/files/ListingView.vue
  • frontend/src/views/files/Preview.vue
  • frontend/src/views/files/ThreeJs.vue

Comment thread frontend/src/utils/htmlPreview.ts Outdated
Comment thread frontend/src/views/files/ThreeJs.vue

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
frontend/src/views/files/ThreeJs.vue (1)

397-438: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Skip the redundant modelDir fetch when the token is already indexed.
Icon.vue already passes viewToken and parentDirItems into ThreeJs, so the model token is usually available before prefetchAssetViewTokens() runs. Keep the /textures lookup, but avoid the extra modelDir listing request on every thumbnail.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/views/files/ThreeJs.vue` around lines 397 - 438, The prefetch
path in prefetchAssetViewTokens is doing a redundant fetch for the model
directory even though Icon.vue already supplies parentDirItems and a viewToken
that can populate the cache first. Update prefetchAssetViewTokens (and, if
needed, fetchDirectoryTokens) to skip the modelDir listing request when the
model token for normalizeAssetPath(this.fbdata.path) is already present in
viewTokenByPath, while still keeping the /textures fetch.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@frontend/src/views/files/ThreeJs.vue`:
- Around line 397-438: The prefetch path in prefetchAssetViewTokens is doing a
redundant fetch for the model directory even though Icon.vue already supplies
parentDirItems and a viewToken that can populate the cache first. Update
prefetchAssetViewTokens (and, if needed, fetchDirectoryTokens) to skip the
modelDir listing request when the model token for
normalizeAssetPath(this.fbdata.path) is already present in viewTokenByPath,
while still keeping the /textures fetch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e631f5c0-b058-40ed-8991-026ff6911778

📥 Commits

Reviewing files that changed from the base of the PR and between efbea4d and f7db4f5.

⛔ Files ignored due to path filters (3)
  • backend/swagger/docs/docs.go is excluded by !backend/swagger/**
  • backend/swagger/docs/swagger.json is excluded by !backend/swagger/**
  • backend/swagger/docs/swagger.yaml is excluded by !backend/swagger/**
📒 Files selected for processing (5)
  • CHANGELOG.md
  • frontend/src/components/files/Icon.vue
  • frontend/src/utils/htmlPreview.test.js
  • frontend/src/utils/htmlPreview.ts
  • frontend/src/views/files/ThreeJs.vue
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/files/Icon.vue

@gtsteffaniak gtsteffaniak merged commit a6a3fd1 into dev/v2.0.0 Jul 3, 2026
22 checks passed
@gtsteffaniak gtsteffaniak deleted the api-changes-view-download branch July 3, 2026 13:46
@coderabbitai coderabbitai Bot mentioned this pull request Jul 4, 2026
4 tasks
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.

1 participant