-
Couldn't load subscription status.
- Fork 11
feat: move to iframe for changelog #1388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis update changes the default server state from Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ChangelogModal
participant Iframe
participant Docs
User->>ChangelogModal: Open changelog modal
ChangelogModal->>Iframe: Load changelog URL
User->>Iframe: Navigate within iframe
Iframe-->>ChangelogModal: PostMessage (navigation event)
ChangelogModal->>ChangelogModal: Update navigation state
User->>ChangelogModal: Click "Back to Changelog"
ChangelogModal->>Iframe: Reset src to original changelog URL
ChangelogModal->>Docs: "View on Docs" (opens current iframe URL)
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
🔇 Additional comments (7)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (1)
web/components/UpdateOs/ChangelogModal.vue (1)
90-93: Synchronise iframe content when switching releases
watch(docsChangelogUrl, …)resets state but leaves the old document visible until Vue re-renders (which may not happen if the element is reused). Push the new URL directly to the iframe to avoid brief flashes of the previous changelog.watch(docsChangelogUrl, (newUrl) => { currentIframeUrl.value = newUrl; hasNavigated.value = false; + if (iframeRef.value && newUrl) { + iframeRef.value.src = newUrl; + } });This guarantees the iframe is always in sync with the selected release.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
web/_data/serverState.ts(1 hunks)web/components/Modal.vue(1 hunks)web/components/UpdateOs/ChangelogModal.vue(3 hunks)web/pages/changelog.vue(3 hunks)web/store/updateOsChangelog.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Test API
- GitHub Check: Build Web App
- GitHub Check: Build API
- GitHub Check: Cloudflare Pages
🔇 Additional comments (9)
web/components/Modal.vue (1)
124-124: Close button visibility improvedThe close button container is now visible on all screen sizes by removing the
hiddenclass, improving accessibility and usability across devices.web/store/updateOsChangelog.ts (1)
23-23: Added debug logging for changelog fetchingAdditional logging will be helpful for tracking when changelog data is updated and fetched.
web/pages/changelog.vue (6)
7-7: Added support for pretty-formatted changelogsThe new
changelogPrettyreactive variable will store formatted changelog content from the release JSON.
13-13: Added debug logging for changelog dataHelpful logging for development and debugging purposes.
16-16: Storing pretty-formatted changelog contentThe code now properly stores the formatted changelog content from the fetched data.
26-31: Updated changelog modal trigger with pretty contentThe function now correctly provides the pretty-formatted changelog to the modal component, along with required metadata.
34-46: Added test function for non-pretty changelog displayThis function allows testing the modal's fallback behavior when pretty-formatted content is unavailable.
55-68: Improved test UI with additional buttonThe UI now provides two distinct testing options with proper spacing, allowing for more comprehensive testing of the changelog modal functionality.
web/components/UpdateOs/ChangelogModal.vue (1)
124-128: ConfirmmutatedParsedChangelogis sanitised before injecting withv-htmlDirectly binding raw HTML invites XSS if upstream sanitisation ever slips. Please ensure the string is produced with a trusted sanitiser (e.g., DOMPurify) or add one here.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
5276cde to
05e9a00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (1)
web/pages/changelog.vue (1)
91-92:⚠️ Potential issueRaw HTML insertion is XSS-prone
v-html="changelog"renders whatever HTML the remote service returns. If that source is ever compromised, users could receive arbitrary scripts.Mitigation: sanitize with DOMPurify (or similar) before assignment.
-import { ref } from 'vue'; +import { ref } from 'vue'; +import DOMPurify from 'dompurify'; … - changelog.value = data[0].changelog; + changelog.value = DOMPurify.sanitize(data[0].changelog);This is a security fix, not a cosmetic change.
🧹 Nitpick comments (8)
plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/translations.php (1)
199-201: Typo:It\sshould beIt’sUnrelated to this PR but worth fixing while you’re touching the file—
\srenders literally.-'It\s highly recommended to review the changelog before continuing your update.' => _('It\'s highly recommended to review the changelog before continuing your update.'), +'It\'s highly recommended to review the changelog before continuing your update.' => _('It\'s highly recommended to review the changelog before continuing your update.'),web/store/updateOsChangelog.ts (2)
15-18: Returnnullconsistently for “no URL”
changelogUrlfalls back to an empty string, whereaschangelogPrettyreturnsnull. Consumers that treat the two props similarly might have to branch twice.-const changelogUrl = computed((): string => releaseForUpdate.value?.changelog || ''); +const changelogUrl = computed((): string | null => + releaseForUpdate.value?.changelog ?? null, +);Using
nullfor “absent” mirrors the optional field in the API type and keeps truthiness checks uniform.
27-39: Minor: guard against emptysha256
fetchAndConfirmInstallwill happily enqueue a callback with an empty hash. A quick guard avoids “invalid param” issues later.-const fetchAndConfirmInstall = (sha256: string) => { +const fetchAndConfirmInstall = (sha256: string) => { + if (!sha256) return;web/components/UpdateOs/RawChangelogRenderer.vue (2)
88-90: Duplicate network hit
onMounted(fetchAndParseChangelog)plus awatch(..., { immediate: true })triggers two identical requests on mount.Remove one of them to halve latency & load:
-onMounted(fetchAndParseChangelog); -watch(() => props.changelog, fetchAndParseChangelog, { immediate: true }); +watch(() => props.changelog, fetchAndParseChangelog, { immediate: true });
92-97: Fragile<h1>strippingUsing a single regex assumes the first heading is on one line and not preceded by whitespace or attributes.
markedalready gives you renderer hooks—just skip depth 1 headings instead of injecting<br />and post-processing.web/pages/changelog.vue (1)
13-13: Remove the permanent console log
console.debug('[changelog] data', data);is helpful while developing but pollutes production logs.
Swap it for a conditionalif (import.meta.env.DEV)or delete it before shipping.web/components/UpdateOs/ChangelogModal.vue (2)
113-119: Consider droppingallow-same-originIncluding
allow-same-originrestores the iframe’s normal origin, enabling it to read/write its own cookies and potentially relaxes certain sandbox protections.
If the docs page does not needdocument.cookie, switching to:sandbox="allow-scripts"further reduces the blast radius of a compromised docs site.
Up to you, but worth evaluating.
147-154: Button lackstype="button"Inside forms (Modal content could be nested in a
<form>in the future), the defaulttypeis “submit”. Adding an explicittype="button"prevents accidental submissions.-<BrandButton +<BrandButton + type="button"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 Files selected for processing (7)
plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/translations.php(2 hunks)web/components/Modal.vue(1 hunks)web/components/UpdateOs/ChangelogModal.vue(2 hunks)web/components/UpdateOs/RawChangelogRenderer.vue(1 hunks)web/locales/en_US.json(1 hunks)web/pages/changelog.vue(3 hunks)web/store/updateOsChangelog.ts(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- web/locales/en_US.json
🚧 Files skipped from review as they are similar to previous changes (1)
- web/components/Modal.vue
🧰 Additional context used
🧬 Code Graph Analysis (2)
web/store/updateOsChangelog.ts (2)
web/store/callbackActions.ts (1)
useCallbackActionsStore(26-184)web/types/server.ts (1)
ServerUpdateOsResponse(53-62)
plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/translations.php (1)
plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php (1)
_(108-108)
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: Build API
- GitHub Check: Build Web App
- GitHub Check: Test API
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/translations.php (2)
396-396: 👍 Apostrophe swap looks goodThe curly apostrophe has been replaced with a straight ASCII one, which avoids encoding headaches and keeps the key “safe-character” compliant.
No further action required.
405-405: New key added consistentlyThe new entry follows the existing sprintf pattern and placeholder style, so downstream consumers will pick it up without surprises.
Looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
web/pages/changelog.vue (1)
13-21:⚠️ Potential issueAdd network-error handling to the fetch
fetch()failures (offline, 5xx, CORS, bad JSON, etc.) will currently throw and leave the page blank.
Wrap the call intry / catchand surface a user-friendly message instead of crashing.onMounted(async () => { - const response = await fetch('https://releases.unraid.net/json'); - const data = await response.json(); - console.debug('[changelog] data', data); - if (data.length > 0) { - changelog.value = data[0].changelog; - changelogPretty.value = data[0].changelog_pretty; - } + try { + const response = await fetch('https://releases.unraid.net/json'); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const data = await response.json(); + console.debug('[changelog] data', data); + if (data.length > 0) { + changelog.value = data[0].changelog; + changelogPretty.value = data[0].changelog_pretty; + } + } catch (error) { + console.error('[changelog] Failed to fetch or parse data:', error); + // Set user-friendly error message + changelog.value = `<p>Unable to load changelog data. Please try again later.</p>`; + } });web/components/UpdateOs/ChangelogModal.vue (1)
51-66:⚠️ Potential issueFix the URL validation in the iframe message handler
The origin check at line 57 is too strict and won't account for ports (like :443) or variations in the docs domain. Additionally, the code assigns
event.data.urltocurrentIframeUrlwithout validation, which could lead to security issues.Apply this change to properly validate both the origin and URL:
- event.origin === 'https://docs.unraid.net' + typeof event.origin === 'string' && + event.origin.startsWith('https://docs.unraid.net') && + // Validate URL is also from docs domain + typeof event.data.url === 'string' && + event.data.url.startsWith('https://docs.unraid.net')This prevents potential security issues where:
- Valid origins with explicit ports might be rejected
- Malicious docs pages could emit arbitrary URLs through postMessage
🧹 Nitpick comments (2)
web/pages/changelog.vue (2)
36-60: Added testing functions for edge casesTwo new functions have been added to test the changelog modal with different data scenarios (missing pretty format and broken parsing), which helps validate fallback behavior.
Consider adding a comment explaining these are for testing/development purposes, or conditionally including them only in development environments:
+// Testing functions for development - consider hiding in production function showChangelogWithoutPretty() {
67-87: Added UI elements for testing edge casesThe template has been updated to use the new store's modal visibility state and adds buttons for testing different changelog scenarios.
Consider conditionally showing these test buttons only in development mode:
+<div v-if="import.meta.env.DEV" class="mb-6 flex gap-4"> -<div class="mb-6 flex gap-4">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 Files selected for processing (9)
web/__test__/store/updateOs.test.ts(2 hunks)web/__test__/store/updateOsChangelog.test.ts(0 hunks)web/components/Modals.ce.vue(1 hunks)web/components/UpdateOs/ChangelogModal.vue(3 hunks)web/components/UpdateOs/CheckUpdateResponseModal.vue(1 hunks)web/components/UpdateOs/RawChangelogRenderer.vue(1 hunks)web/pages/changelog.vue(1 hunks)web/store/updateOs.ts(4 hunks)web/store/updateOsChangelog.ts(0 hunks)
💤 Files with no reviewable changes (2)
- web/store/updateOsChangelog.ts
- web/test/store/updateOsChangelog.test.ts
✅ Files skipped from review due to trivial changes (1)
- web/components/Modals.ce.vue
🚧 Files skipped from review as they are similar to previous changes (1)
- web/components/UpdateOs/RawChangelogRenderer.vue
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: Test API
- GitHub Check: Build Web App
- GitHub Check: Build API
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (17)
web/__test__/store/updateOs.test.ts (2)
61-61: Updated property name for better clarityThe test now uses the more descriptive
updateOsModalVisibleproperty name instead of what was likelymodalOpen, making the test more understandable.
89-89: Property name changed consistentlyThe test has been consistently updated to use
updateOsModalVisibleinstead of the previous property name, ensuring the test matches the implementation.Also applies to: 94-94, 97-97
web/components/UpdateOs/CheckUpdateResponseModal.vue (1)
182-182: Store migration completed correctlyThe click handler now uses
updateOsStore.setReleaseForUpdate()instead of the previous changelog-specific store, aligning with the consolidation of changelog functionality into the main update OS store.web/pages/changelog.vue (3)
2-5: Imports updated for store consolidationThe imports have been updated to use the consolidated
useUpdateOsStoreinstead of the previous separate changelog store, with appropriate reactive helpers.
8-10: Added support for pretty changelog formatThe component now has a new reactive variable for formatted changelog content and correctly retrieves store properties using
storeToRefs.
23-34: Updated changelog modal function for the consolidated storeThe function now correctly includes the new
changelogPrettyfield and uses the consolidatedupdateOsStore.web/store/updateOs.ts (6)
12-13: Added required dependencies for changelog functionalityThe store now properly imports the semver
prereleasefunction for release stability checking and the callback actions store for update confirmation.
28-30: Renamed and added state properties for clarityThe
modalOpenproperty was renamed to the more descriptiveupdateOsModalVisible, and new state for managing changelog visibility and release details has been added.
66-91: Consolidated changelog functionalityChangelog-related logic previously in a separate store has been consolidated here, including URL handling, pretty format support, and update confirmation functionality.
129-129: Updated setter for renamed propertyThe
setModalOpenaction now correctly updates the renamedupdateOsModalVisibleproperty.
137-146: Exposed new state and gettersThe store now properly exposes the renamed modal visibility state and new changelog-related properties.
151-152: Exposed new actionsThe new actions for setting release details and confirming installation are now properly exposed from the store.
web/components/UpdateOs/ChangelogModal.vue (5)
109-115: Sandbox attribute looks goodThe iframe has been properly secured with a sandbox attribute that allows only the minimum required capabilities (scripts and same-origin).
143-149: Back to Changelog button implementation looks goodThe "Back to Changelog" button properly appears only when navigated away from the main changelog, and correctly resets the iframe to the initial URL.
152-159: View on Docs button correctly uses the current URLThe button now uses the current iframe URL or falls back to the original changelog URL, which ensures users can always access the documentation externally.
119-126: Good fallback implementation with RawChangelogRendererUsing the RawChangelogRenderer as a fallback when no changelog URL is available ensures users can still view changelog content even without iframe support.
86-89: Good URL tracking implementationThe watch on docsChangelogUrl ensures that the component state is reset properly when the changelog URL changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
web/pages/changelog.vue (1)
11-15:⚠️ Potential issueAdd error handling to the fetch call
The
showChangelogModalFromReleasesEndpointfunction lacks error handling for network failures, which could cause the page to crash when offline or encountering server errors.async function showChangelogModalFromReleasesEndpoint() { - const response = await fetch('https://releases.unraid.net/os?branch=stable¤t_version=6.12.3'); - const data = await response.json(); - updateOsStore.setReleaseForUpdate(data); + try { + const response = await fetch('https://releases.unraid.net/os?branch=stable¤t_version=6.12.3'); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const data = await response.json(); + updateOsStore.setReleaseForUpdate(data); + } catch (error) { + console.error('Failed to fetch changelog data:', error); + // Optional: Set an error state in the store or display a user-friendly message + } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 Files selected for processing (1)
web/pages/changelog.vue(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: Build Web App
- GitHub Check: Build API
- GitHub Check: Test API
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (3)
web/pages/changelog.vue (3)
3-8: Good use of store refactoring and Pinia best practicesThe refactoring to use the consolidated
useUpdateOsStoreand properly extracting reactive state withstoreToRefsfollows Vue 3 and Pinia best practices.
29-53: Good test coverage with edge casesThe test functions effectively cover various scenarios including missing pretty changelog URL and completely broken changelog links, which will help ensure the component handles edge cases properly.
61-85: Well-organized test UIThe test UI provides clear, visually distinct buttons for each test scenario, making it easy to test different changelog rendering conditions.
|
This plugin has been deployed to Cloudflare R2 and is available for testing. |
🤖 I have created a release *beep* *boop* --- ## [4.9.0](v4.8.0...v4.9.0) (2025-07-08) ### Features * add graphql resource for API plugins ([#1420](#1420)) ([642a220](642a220)) * add management page for API keys ([#1408](#1408)) ([0788756](0788756)) * add rclone ([#1362](#1362)) ([5517e75](5517e75)) * API key management ([#1407](#1407)) ([d37dc3b](d37dc3b)) * api plugin management via CLI ([#1416](#1416)) ([3dcbfbe](3dcbfbe)) * build out docker components ([#1427](#1427)) ([711cc9a](711cc9a)) * docker and info resolver issues ([#1423](#1423)) ([9901039](9901039)) * fix shading in UPC to be less severe ([#1438](#1438)) ([b7c2407](b7c2407)) * info resolver cleanup ([#1425](#1425)) ([1b279bb](1b279bb)) * initial codeql setup ([#1390](#1390)) ([2ade7eb](2ade7eb)) * initialize claude code in codebse ([#1418](#1418)) ([b6c4ee6](b6c4ee6)) * move api key fetching to use api key service ([#1439](#1439)) ([86bea56](86bea56)) * move to cron v4 ([#1428](#1428)) ([b8035c2](b8035c2)) * move to iframe for changelog ([#1388](#1388)) ([fcd6fbc](fcd6fbc)) * native slackware package ([#1381](#1381)) ([4f63b4c](4f63b4c)) * send active unraid theme to docs ([#1400](#1400)) ([f71943b](f71943b)) * slightly better watch mode ([#1398](#1398)) ([881f1e0](881f1e0)) * upgrade nuxt-custom-elements ([#1461](#1461)) ([345e83b](345e83b)) * use bigint instead of long ([#1403](#1403)) ([574d572](574d572)) ### Bug Fixes * activation indicator removed ([5edfd82](5edfd82)) * alignment of settings on ManagementAccess settings page ([#1421](#1421)) ([70c790f](70c790f)) * allow rclone to fail to initialize ([#1453](#1453)) ([7c6f02a](7c6f02a)) * always download 7.1 versioned files for patching ([edc0d15](edc0d15)) * api `pnpm type-check` ([#1442](#1442)) ([3122bdb](3122bdb)) * **api:** connect config `email` validation ([#1454](#1454)) ([b9a1b9b](b9a1b9b)) * backport unraid/webgui[#2269](https://github.com/unraid/api/issues/2269) rc.nginx update ([#1436](#1436)) ([a7ef06e](a7ef06e)) * bigint ([e54d27a](e54d27a)) * config migration from `myservers.cfg` ([#1440](#1440)) ([c4c9984](c4c9984)) * **connect:** fatal race-condition in websocket disposal ([#1462](#1462)) ([0ec0de9](0ec0de9)) * **connect:** mothership connection ([#1464](#1464)) ([7be8bc8](7be8bc8)) * console hidden ([9b85e00](9b85e00)) * debounce is too long ([#1426](#1426)) ([f12d231](f12d231)) * delete legacy connect keys and ensure description ([22fe91c](22fe91c)) * **deps:** pin dependencies ([#1465](#1465)) ([ba75a40](ba75a40)) * **deps:** pin dependencies ([#1470](#1470)) ([412b329](412b329)) * **deps:** storybook v9 ([#1476](#1476)) ([45bb49b](45bb49b)) * **deps:** update all non-major dependencies ([#1366](#1366)) ([291ee47](291ee47)) * **deps:** update all non-major dependencies ([#1379](#1379)) ([8f70326](8f70326)) * **deps:** update all non-major dependencies ([#1389](#1389)) ([cb43f95](cb43f95)) * **deps:** update all non-major dependencies ([#1399](#1399)) ([68df344](68df344)) * **deps:** update dependency @types/diff to v8 ([#1393](#1393)) ([00da27d](00da27d)) * **deps:** update dependency cache-manager to v7 ([#1413](#1413)) ([9492c2a](9492c2a)) * **deps:** update dependency commander to v14 ([#1394](#1394)) ([106ea09](106ea09)) * **deps:** update dependency diff to v8 ([#1386](#1386)) ([e580f64](e580f64)) * **deps:** update dependency dotenv to v17 ([#1474](#1474)) ([d613bfa](d613bfa)) * **deps:** update dependency lucide-vue-next to ^0.509.0 ([#1383](#1383)) ([469333a](469333a)) * **deps:** update dependency marked to v16 ([#1444](#1444)) ([453a5b2](453a5b2)) * **deps:** update dependency shadcn-vue to v2 ([#1302](#1302)) ([26ecf77](26ecf77)) * **deps:** update dependency vue-sonner to v2 ([#1401](#1401)) ([53ca414](53ca414)) * disable file changes on Unraid 7.2 ([#1382](#1382)) ([02de89d](02de89d)) * do not start API with doinst.sh ([7d88b33](7d88b33)) * do not uninstall fully on 7.2 ([#1484](#1484)) ([2263881](2263881)) * drop console with terser ([a87d455](a87d455)) * error logs from `cloud` query when connect is not installed ([#1450](#1450)) ([719f460](719f460)) * flash backup integration with Unraid Connect config ([#1448](#1448)) ([038c582](038c582)) * header padding regression ([#1477](#1477)) ([e791cc6](e791cc6)) * incorrect state merging in redux store ([#1437](#1437)) ([17b7428](17b7428)) * lanip copy button not present ([#1459](#1459)) ([a280786](a280786)) * move to bigint scalar ([b625227](b625227)) * node_modules dir removed on plugin update ([#1406](#1406)) ([7b005cb](7b005cb)) * omit Connect actions in UPC when plugin is not installed ([#1417](#1417)) ([8c8a527](8c8a527)) * parsing of `ssoEnabled` in state.php ([#1455](#1455)) ([f542c8e](f542c8e)) * pin ranges ([#1460](#1460)) ([f88400e](f88400e)) * pr plugin promotion workflow ([#1456](#1456)) ([13bd9bb](13bd9bb)) * proper fallback if missing paths config modules ([7067e9e](7067e9e)) * rc.unraid-api now cleans up older dependencies ([#1404](#1404)) ([83076bb](83076bb)) * remote access lifecycle during boot & shutdown ([#1422](#1422)) ([7bc583b](7bc583b)) * sign out correctly on error ([#1452](#1452)) ([d08fc94](d08fc94)) * simplify usb listing ([#1402](#1402)) ([5355115](5355115)) * theme issues when sent from graph ([#1424](#1424)) ([75ad838](75ad838)) * **ui:** notifications positioning regression ([#1445](#1445)) ([f73e5e0](f73e5e0)) * use some instead of every for connect detection ([9ce2fee](9ce2fee)) ### Reverts * revert package.json dependency updates from commit 711cc9a for api and packages/* ([94420e4](94420e4)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary by CodeRabbit
New Features
Bug Fixes
Chores