Commit Graph

274 Commits

Author SHA1 Message Date
Eli Bosley
73b2ce360c fix: update @unraid/shared-callbacks to version 3.0.0 (#1831)
…on and pnpm-lock.yaml

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a standalone redirect page that shows "Redirecting..." and
navigates automatically.

* **Improvements**
* Redirect preserves hash callback data, validates targets, and logs the
computed redirect.
  * Purchase callback origin changed to a different account host.
* Date/time formatting now tolerates missing or empty server formats
with safe fallbacks.
  * Redirect page included in backup/restore.

* **Tests**
  * Added tests covering date/time formatting fallbacks.

* **Chores**
  * Dependency @unraid/shared-callbacks upgraded.
  * Removed multiple demo/debug pages and related test UIs.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-12-15 16:20:18 -05:00
Eli Bosley
d6e29395c8 fix: enhance dark mode support in theme handling (#1808)
- Added PHP logic to determine if the current theme is dark and set a
CSS variable accordingly.
- Introduced a new function to retrieve the dark mode state from the CSS
variable in JavaScript.
- Updated the theme store to initialize dark mode based on the CSS
variable, ensuring consistent theme application across the application.

This improves user experience by ensuring the correct theme is applied
based on user preferences.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Server-persisted theme mutation and client action to fetch/apply
themes

* **Improvements**
* Safer theme parsing and multi-source initialization (CSS var, storage,
cookie, server)
* Robust dark-mode detection and propagation across document, modals and
teleport containers
* Responsive banner/header gradient handling with tunable CSS variables
and fallbacks

* **Tests**
* Expanded tests for theme flows, dark-mode detection, banner gradients
and manifest robustness

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-12-15 12:52:47 -05:00
Eli Bosley
317e0fa307 Revert "feat!(api): swap daemonizer to nodemon instead of PM2" (#1836)
Reverts unraid/api#1798
2025-12-12 18:32:35 -05:00
Eli Bosley
6f54206a4a feat!(api): swap daemonizer to nodemon instead of PM2 (#1798)
## Summary
- ensure the API release build copies nodemon.json into the packaged
artifacts so nodemon-managed deployments have the config available

## Testing
- pnpm --filter @unraid/api lint:fix

------
[Codex
Task](https://chatgpt.com/codex/tasks/task_e_691e1f4bde3483238726478f6fb2d52a)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Switch to Nodemon for process management and updated CLI to use it.
  * Added boot-time diagnostic logging and direct log-file writing.
  * New per-package CPU telemetry and topology exposure.

* **Bug Fixes**
  * More reliable process health detection and lifecycle handling.
  * Improved log handling and startup robustness.

* **Chores**
  * Removed PM2-related components and tests; migrated to Nodemon.
  * Consolidated pub/sub channel usage and bumped internal version.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Pujit Mehrotra <pujit@lime-technology.com>
2025-12-11 15:42:05 -05:00
ljm42
74df938e45 feat: when cancelling OS upgrade, delete any plugin files that were d… (#1823)
…ownloaded as part of the upgrade

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved cleanup of temporary plugin configuration files during update
cancellation operations.

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

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-12-08 14:18:34 -07:00
Squidly271
832e9d04f2 fix: PHP Warnings in Management Settings (#1805)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Enhanced remote access configuration handling to gracefully manage
missing or undefined parameter values.
* Improved overall system stability through safer default handling of
optional settings that may not be present.

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

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-24 12:51:17 -05:00
Eli Bosley
36c104915e fix: missing translations for expiring trials (#1800)
- Removed translation function calls from the UI components for reboot
type text, replacing them with direct references to the computed
properties.
- Enhanced ineligible update messages by integrating localization for
various conditions, ensuring clearer user feedback regarding update
eligibility.
- Added new localization strings for ineligible update scenarios in the
English locale file.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added new localization keys for OS update eligibility, reboot labels,
changelog link, and expanded uptime/trial expiry messages.

* **Bug Fixes**
* Restored translated strings and added locale-aware release date
formatting for update/ineligible messaging and badges.

* **Theme & UI**
* Streamlined theme initialization and server-driven theme application;
removed legacy CSS-variable persistence and adjusted dark/banner
behavior.

* **Tests**
* Added i18n and date/locale formatting tests and improved
local-storage-like test mocks.

* **Chores**
* Removed an auto-registered global component and strengthened
script/theme initialization and CSS-variable validation.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-20 19:30:39 -05:00
Pujit Mehrotra
d18eaf2364 fix: detection of flash backup activation state (#1769)
Resolves #1767 


plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/UpdateFlashBackup.php:415
still reads the API version from _var($mystatus,'version'), but commit
441e1805c removed the code that populates $mystatus (the parse of
/var/local/emhttp/myservers.cfg). As a result $mystatus is undefined, so
we now send api_version= to the flash activation endpoint. The PHP
runtime also emits “Undefined variable: mystatus” / “Trying to access
array offset on value of type null” notices before headers are written.
Those notices corrupt the JSON response, the keyserver rejects the
request because the api_version is missing, and the flash backup state
file is never updated—so the web GUI stays stuck at “Loading”.

Because the status request always invokes UpdateFlashBackup.php, every
page load trips the same failure path, leaving
/var/local/emhttp/flashbackup.ini with loading=Loading. The frontend
only listens for /sub/flashbackup events, so until that INI file is
rewritten the spinner never clears and the enable button never becomes
active.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* UI now initializes flash backup status on page load so backup controls
reflect current server state immediately.
* Backup state saves now publish remote updates, improving
synchronization of backup status.

* **Bug Fixes**
* Improved API version handling for flash backup operations: sends
version when available and falls back gracefully when unknown.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-07 14:52:18 -05:00
Eli Bosley
10f048ee1f chore: re-add translations.php to prevent breaking uninstalls 2025-10-15 12:05:02 -04:00
Eli Bosley
31c41027fc feat: translations now use crowdin (translate.unraid.net) (#1739)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- App-wide internationalization: dynamic locale detection/loading, many
new locale bundles, and CLI helpers to extract/sort translation keys.

- **Accessibility**
  - Brand button supports keyboard activation (Enter/Space).

- **Documentation**
  - Internationalization guidance added to API and Web READMEs.

- **Refactor**
- UI updated to use centralized i18n keys and a unified locale loading
approach.

- **Tests**
  - Test utilities updated to support i18n and localized assertions.

- **Chores**
- Crowdin config and i18n scripts added; runtime locale exposed for
selection.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-13 16:56:08 -04:00
Eli Bosley
0d165a6087 fix: add cache busting to web component extractor (#1731)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- Bug Fixes
- Ensures UI assets use content-hashed filenames so browsers load the
latest scripts and styles after updates, reducing stale-cache issues.
- Keeps scripts and their related styles in sync for consistent
rendering and fewer cache-related glitches.
- Ignores non-asset manifest entries to prevent accidental inclusion of
invalid items and ensure correct asset loading.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-09-30 12:27:48 -04:00
Eli Bosley
b7afaf4632 feat: add Tailwind scoping plugin and integrate into Vite config (#1722)
- Introduced a new PostCSS plugin, `scopeTailwindToUnapi`, to scope
Tailwind CSS classes to specific elements.
- Updated Vite configuration to include the new PostCSS plugin for CSS
processing.
- Enhanced theme management in the theme store to apply scoped classes
and dynamic CSS variables to multiple targets, including the document
root and elements with the `.unapi` class.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Scoped styling for embedded (.unapi) contexts and a PostCSS plugin to
automate it.
* Theme refresh after mount to propagate CSS variables to embedded
roots.
  * Exposed idempotent restart action for the Unraid API when offline.

* **Bug Fixes**
* Consistent dark mode and theme variable application across main and
embedded views.
  * Interactive element and SSO styles now apply in embedded contexts.
* Simplified changelog iframe with a reliable fallback renderer;
improved logs styling scope.

* **Tests**
* New unit tests for the scoping plugin, changelog iframe, and related
components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-09-26 09:56:27 -04:00
Eli Bosley
1d9ce0aa3d feat: add unraid api status manager (#1708)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- New Features
- Added “Unraid API Status” page under Management Access to view current
API status, refresh it, and restart the API with confirmation.
- Status view shows running state, detailed output, and in-app
success/error messages after actions.

- Style
- Minor theme adjustments to border colors; no layout changes expected.

- Chores
  - Updated UI text: “Unraid API” → “Unraid API Settings” in settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-09-16 13:04:01 -04:00
Eli Bosley
31a255c928 fix: false positive on verify_install script being external shell (#1704)
- Introduced a new test script for shell detection logic in
`verify_install.sh`.
- Updated the `package.json` to include a new test command for shell
detection.
- Enhanced the `verify_install.sh` script to accurately check the
current shell interpreter using `/proc` and fallback methods.

This improves the testing framework and ensures better validation of
shell detection functionality.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- Bug Fixes
- Installer now detects the actual interpreter more robustly and
strictly requires Bash; non-Bash environments produce clear error
messages and abort installation.
- Tests
- Added automated shell-detection tests to validate behavior across
environments.
- Test suite expanded to run the new shell-detection checks as part of
the standard test command.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-09-15 12:17:50 -04:00
Eli Bosley
50ea2a3ffb feat: add zsh shell detection to install script (#1539)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Installer now detects when the environment is using Zsh and halts with
clear error messages and guidance so users can move Zsh configuration to
interactive-only files.

* **Bug Fixes**
* Prevents running the installer under unsupported shell setups,
improving installation reliability and avoiding misconfigured runs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-09-10 11:00:41 -04:00
Eli Bosley
daeeba8c1f chore: add public notice to unraid-components directory 2025-09-08 14:10:31 -04:00
Pujit Mehrotra
797bf50ec7 fix(plugin): add fallback for unraid-api stop in deprecation cleanup (#1668) 2025-09-08 10:06:33 -04:00
Eli Bosley
af5ca11860 Feat/vue (#1655)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- New Features
- Introduced Docker management UI components: Overview, Logs, Console,
Preview, and Edit.
- Added responsive Card/Detail layouts with grouping, bulk actions, and
tabs.
  - New UnraidToaster component and global toaster configuration.
- Component auto-mounting improved with async loading and multi-selector
support.
- UI/UX
- Overhauled theme system (light/dark tokens, primary/orange accents)
and added theme variants.
  - Header OS version now includes integrated changelog modal.
- Registration displays warning states; multiple visual polish updates.
- API
  - CPU load now includes percentGuest and percentSteal metrics.
- Chores
  - Migrated web app to Vite; updated artifacts and manifests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mdatelle <mike@datelle.net>
Co-authored-by: Michael Datelle <mdatelle@icloud.com>
2025-09-08 10:04:49 -04:00
Pujit Mehrotra
534a07788b fix(plugin): restore cleanup behavior for unsupported unraid versions (#1658)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Adds guided warnings and an explicit cleanup/uninstall workflow for
unsupported Unraid versions, with safer removal paths by OS release.

* **Bug Fixes**
* Detects and removes both new and legacy Connect configurations,
ensuring proper sign-out and web-server reload.
* Strengthens version gating to avoid problematic pre-release builds and
advises uninstall/upgrade when needed.

* **Chores**
  * Lowers declared minimum Unraid version to broaden compatibility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-09-04 15:28:20 -04:00
Eli Bosley
88087d5201 feat: mount vue apps, not web components (#1639)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Standalone web bundle with auto-mount utilities and a self-contained
test page.
* New responsive modal components for consistent mobile/desktop dialogs.
  * Header actions to copy OS/API versions.

* **Improvements**
* Refreshed UI styles (muted borders), accessibility and animation
refinements.
  * Theming updates and Tailwind v4–aligned, component-scoped styles.
  * Runtime GraphQL endpoint override and CSRF header support.

* **Bug Fixes**
* Safer network fetching and improved manifest/asset loading with
duplicate protection.

* **Tests/Chores**
* Parallel plugin tests, new extractor test suite, and updated
build/test scripts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-09-03 15:42:21 -04:00
Eli Bosley
0fe2c2c1c8 fix: OIDC and API Key management issues (#1642) 2025-09-03 09:47:11 -04:00
Eli Bosley
4e945f5f56 feat(api): enhance OIDC redirect URI handling in service and tests (#1618)
- Updated `getRedirectUri` method in `OidcAuthService` to handle various
edge cases for redirect URIs, including full URIs, malformed URLs, and
default ports.
- Added comprehensive tests for `OidcAuthService` to validate redirect
URI construction and error handling.
- Modified `RestController` to utilize `redirect_uri` query parameter
for authorization requests.
- Updated frontend components to include `redirect_uri` in authorization
URLs, ensuring correct handling of different protocols and ports.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Stronger OIDC redirect_uri validation and an admin GraphQL endpoint to
view full OIDC configuration.
* OIDC Debug Logs UI (panel, button, modal), enhanced log viewer with
presets/filters, ANSI-colored rendering, and a File Viewer component.
* New GraphQL queries to list and fetch config files; API Config
Download page.

* **Refactor**
* Centralized, modular OIDC flows and safer redirect handling;
topic-based log subscriptions with a watcher manager for scalable live
logs.

* **Documentation**
  * Cache TTL guidance clarified to use milliseconds.

* **Chores**
* Added ansi_up and escape-html deps; improved log formatting; added
root codegen script.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-09-02 10:40:20 -04:00
Eli Bosley
674323fd87 feat: generated UI API key management + OAuth-like API Key Flows (#1609)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* API Key Authorization flow with consent screen, callback support, and
a Tools page.
* Schema-driven API Key creation UI with permission presets, templates,
and Developer Authorization Link.
* Effective Permissions preview and a new multi-select permission
control.

* **UI Improvements**
* Mask/toggle API keys, copy-to-clipboard with toasts, improved select
labels, new label styles, tab wrapping, and accordionized color
controls.

* **Documentation**
  * Public guide for the API Key authorization flow and scopes added.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-08-27 12:37:39 -04:00
google-labs-jules[bot]
6947b5d4af fix(rc.unraid-api): remove profile sourcing (#1622)
This change removes the line that sources `/etc/profile` from the
`rc.unraid-api` script. This is done to prevent unexpected side effects
and improve the script's isolation.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-08-26 13:11:16 -04:00
Zack Spear
96c120f9b2 feat: connect settings page updated for responsive webgui (#1585) 2025-08-15 09:44:06 -04:00
Pujit Mehrotra
5afca5ecba chore: reduce logging verbosity in restore_dependencies script (#1568)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Adjusted the messages displayed during the restore process for
improved clarity and specificity.
* Reduced unnecessary informational messages, focusing on more relevant
feedback during restoration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-08-07 12:54:25 -04:00
Eli Bosley
514a0ef560 fix(connect): remove unraid-api folder before creating symlink (#1556)
During plugin installation, if `/usr/local/bin/unraid-api` exists as a
directory, the installation fails because `rm -f` cannot remove a
directory. This change replaces `rm -f` with `rm -rf` to ensure that the
path is removed regardless of whether it is a file or a directory,
allowing the symlink to be created successfully.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-08-01 11:01:13 -04:00
Eli Bosley
6b3b951d82 fix: SSO not being detected (#1546)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved reliability of Single Sign-On (SSO) status detection,
ensuring the SSO state is always correctly set regardless of plugin
status.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-28 17:04:23 -04:00
Eli Bosley
3b00fec5fd chore: Remove legacy store modules and add new API key and reporting services (#1536)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added developer CLI tools for toggling GraphQL sandbox and modal
testing utilities.
* Introduced a "Show Activation Modal" developer component for UI
testing.
  * Added system initial setup detection and related GraphQL queries.
* Enhanced login and welcome pages with dynamic server info and initial
setup state.
  * Improved SSO button with internationalization and error handling.
* Added internal CLI admin API key management service and internal
GraphQL client service.
* Introduced comprehensive API report generation service for system and
service status.
* Added CLI commands and GraphQL mutations/queries for plugin and SSO
user management.
* Added new modal target components and improved teleport target
detection.

* **Enhancements**
* Refined modal dialog targeting and teleportation for flexible UI
placement.
* Updated modal components and stores for improved activation/welcome
modal control.
  * Improved plugin and SSO user management via CLI through GraphQL API.
* Refactored partner logo components to use props instead of store
dependencies.
  * Enhanced styling and accessibility for buttons and modals.
* Streamlined Tailwind CSS integration with shared styles and updated
theme variables.
* Improved GraphQL module configuration to avoid directive conflicts in
tests.
  * Adjusted Vite config for better dependency handling in test mode.
  * Improved error handling and logging in CLI commands and services.
* Reordered imports and refined component class bindings for UI
consistency.

* **Bug Fixes**
* Resolved issues with duplicate script tags and component registration
in the web UI.
* Fixed modal close button visibility and activation modal state
handling.
* Added error handling and logging improvements across CLI commands and
services.
  * Fixed newline issues in last-download-time fixture files.

* **Chores**
* Added and updated numerous tests for CLI commands, services, and UI
components.
* Updated translation files and localization resources for new UI
messages.
* Adjusted environment, configuration, and dependency files for improved
development and test workflows.
  * Cleaned up unused imports and mocks in tests.
  * Reorganized exports and barrel files in shared and UI modules.
  * Added integration and dependency resolution tests for core modules.

* **Removals & Refactoring**
* Removed legacy Redux state management, configuration, and UPnP logic
from the backend.
* Eliminated deprecated GraphQL subscriptions and client code related to
registration and mothership.
* Removed direct store manipulation and replaced with service-based
approaches in CLI commands.
  * Deleted unused or redundant test files and configuration listeners.
* Refactored SSO user service to consolidate add/remove operations into
a single update method.
* Simplified API key services with new methods for automatic key
management.
* Replaced direct plugin and SSO user service calls with GraphQL client
interactions in CLI commands.
* Removed complex theme fallback and dark mode CSS rules, replacing with
streamlined static theme variables.
* Cleaned up Tailwind CSS configuration and removed deprecated local
styles.
* Removed multiple internal utility files and replaced with simplified
or centralized implementations.
* Removed deprecated local configuration and synchronization files and
listeners.
  * Removed UPnP helper functions and job management classes.
* Refactored server resolver to dynamically construct local server data
internally.
* Removed CORS handler and replaced with simplified or externalized
logic.
* Removed store synchronization and registration event pubsub handling.
* Removed GraphQL client creation utilities for internal API
communication.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-25 15:07:37 -04:00
Eli Bosley
86b6c4f85b fix: inject Tailwind CSS into client entry point (#1537)
Added a Vite plugin to automatically inject the Tailwind CSS import into
the `unraid-components.client.js` entry file, enhancing the integration
of Tailwind CSS within the application. This change improves the setup
for styling components consistently across the project.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added automated validation to ensure Tailwind CSS styles are correctly
included in the custom elements build output.

* **Chores**
* Updated the build process to include a CSS validation step after
manifest generation.
* Enhanced development build configuration to enable CSS source maps and
optimize Tailwind CSS injection into web components.
  * Extended CSS theme with new responsive breakpoint variables.
* Improved CSS class specificity in user profile, server state, and
update modal components for consistent styling.
* Removed redundant style blocks and global CSS imports from multiple
components to streamline styling and reduce duplication.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-23 15:30:57 -04:00
Eli Bosley
eecd9b1017 fix(my.servers): improve DNS resolution robustness for backup server (#1518)
Add multiple fallback methods for DNS resolution when checking
backup.unraid.net

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved reliability of DNS resolution checks for backup services,
reducing false error reports.
* Enhanced error messages to provide clearer guidance if DNS resolution
fails, including advice to check DNS settings in network configuration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 11:33:21 -04:00
Pujit Mehrotra
441e1805c1 fix: replace myservers.cfg reads in UpdateFlashBackup.php (#1517)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added a new method for verifying user sign-in status using a dedicated
configuration handler.
* Introduced a class to manage connection configuration and status
checks.

* **Refactor**
* Updated logic for checking connection and registration status to use
new configuration handling methods for improved clarity and reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 10:30:04 -04:00
Pujit Mehrotra
29dcb7d0f0 fix: rm short-circuit in rc.unraid-api if plugin config dir is absent (#1515)
This short-circuit causes any/all `rc.unraid-api` invocations to
immediately fail on fresh 7.2 images (because
`/boot/config/dynamix.my.servers` doesn't exist).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Removed initial checks and setup for a plugin directory and default
environment file in the startup script.
* Simplified environment switching with streamlined commands and
improved error handling.
* Removed deprecated environment path references and updated related
tests.
* **Documentation**
* Added descriptive comments clarifying build and environment settings.
* **Tests**
* Updated test cases by removing assertions related to deprecated
environment paths.
* **Maintenance**
  * Updated timestamp fixtures for consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 09:48:12 -04:00
Eli Bosley
a35c8ff2f1 refactor(install): add debugging to install process
- Remove redundant log file handling and display errors directly to users
- Add debug information for troubleshooting installation issues

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved installation and verification scripts to display output and
error messages directly to the user, rather than writing to a log file.
* Enhanced error messages to provide clearer instructions when issues
occur during installation or verification.

* **New Features**
* Added detailed debug output during the API service startup to assist
with troubleshooting.

* **Chores**
* Updated script environments and streamlined directory creation for
improved reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-14 10:59:05 -04:00
Eli Bosley
39b8f453da fix: invalid state for unraid plugin (#1492)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Improved connection status handling by introducing a new service that
writes connection status to a JSON file for enhanced integration.
* Updated system components to read connection status and allowed
origins from the new JSON file, ensuring more reliable and up-to-date
information.

* **Chores**
* Expanded allowed Bash command permissions to include commands starting
with "mv:".
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-09 09:21:43 -04:00
Eli Bosley
345e83bfb0 feat: upgrade nuxt-custom-elements (#1461)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added new modal dialogs and UI components, including activation steps,
OS update feedback, and expanded notification management.
* Introduced a plugin to configure internationalization, state
management, and Apollo client support in web components.
* Added a new Log Viewer page with a streamlined interface for viewing
logs.

* **Improvements**
* Centralized Pinia state management by consolidating all stores to use
a shared global Pinia instance.
* Simplified component templates by removing redundant
internationalization host wrappers.
* Enhanced ESLint configuration with stricter rules and global variable
declarations.
* Refined custom element build process to prevent jQuery conflicts and
optimize minification.
* Updated component imports and templates for consistent structure and
maintainability.
* Streamlined log viewer dropdowns using simplified select components
with improved formatting.
* Improved notification sidebar with filtering by importance and modular
components.
* Replaced legacy notification popups with new UI components and added
automatic root session creation for localhost requests.
* Updated OS version display and user profile UI with refined styling
and component usage.

* **Bug Fixes**
* Fixed component tag capitalization and improved type annotations
across components.

* **Chores**
* Updated development dependencies including ESLint plugins and build
tools.
* Removed deprecated log viewer patch class and cleaned up related test
fixtures.
  * Removed unused imports and simplified Apollo client setup.
* Cleaned up test mocks and removed obsolete i18n host component tests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1210730229632804

---------

Co-authored-by: Pujit Mehrotra <pujit@lime-technology.com>
Co-authored-by: Zack Spear <zackspear@users.noreply.github.com>
2025-07-08 10:05:39 -04:00
Pujit Mehrotra
f542c8e0bd fix: parsing of ssoEnabled in state.php (#1455)
read `ssoSubIds` in state.php from `api.json`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added a new query to check if Single Sign-On (SSO) is enabled.
* Updated UI components to dynamically reflect SSO availability via live
data.
* **Refactor**
* Streamlined internal handling of SSO status detection for improved
reliability and maintainability.
* **Tests**
* Enhanced tests for SSO button behavior with mocked live data and added
edge case coverage for SSO callback handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 10:24:38 -04:00
Pujit Mehrotra
038c582aed fix: flash backup integration with Unraid Connect config (#1448)
read `username` from connect.json & drop minigraphConnected check

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1210592838407162

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved reliability of configuration file handling for backup and API
features.
* Resolved potential false negatives when checking connection status by
updating connection verification logic.

* **Chores**
  * Centralized configuration paths for easier future updates.
  * Minor formatting improvements for better readability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 10:09:58 -04:00
Pujit Mehrotra
a8566e9e5a build: fix doinst.sh compatibility with installpkg --root (#1446)
- Isolate plugin concerns into `.plg` plugin & api file modifiers instead of the api's
slackware package.

## Summary by CodeRabbit

* **New Features**
* Installation process modularized into package installation,
post-install setup with verification, and service startup with cleanup.
* Added logging and error detection during installation, including
symlink verification.
  * Created required log directory to support service dependencies.
* Integrated nginx service with reload capability triggered by
configuration changes.
* Added automatic patching of nginx configuration and hosts file to
improve security and iframe compatibility.
* Enhanced file modification system to handle side effects and trigger
nginx reloads as needed.

* **Refactor**
* Restructured installation scripts for clarity; setup scripts now
separate steps.
  * Removed legacy installation logic and deprecated related scripts.
  * Enabled hard link addition during package creation.
* Simplified installation scripts by removing conditional branching and
detailed logging.
* Streamlined API environment setup by removing redundant post-install
steps.
* Updated dependency injection to explicitly provide nginx service
token.
  * Improved patch application error reporting with file path details.

* **Chores**
  * Disabled legacy scripts to streamline installation.
  * Removed `.gitignore` to track previously ignored files.
* Updated tests to include new dependencies and relaxed logger
assertions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1210661184127051
2025-06-30 10:49:46 -04:00
Pujit Mehrotra
5ba4479663 chore: rm obsolete style block from myservers1.php (#1435)
Complement to https://github.com/unraid/webgui/pull/2270

Compared our dynamix.my.servers with the webgui's and made the
corresponding changes. activation code logic was omitted because it has
already been written into the api.

python script used for comparison:
https://gist.github.com/pujitm/43a4d2fc35c74f51c70cc66fe1909e6c
```py
#!/usr/bin/env python3
"""
Directory comparison script that recursively compares two directories
and shows files that exist in one but not the other, plus diffs for common files.
"""

import os
import sys
import subprocess
from pathlib import Path
from typing import Set, Tuple


def get_all_files(directory: str) -> Set[str]:
    """Get all files in a directory recursively, returning relative paths."""
    files = set()
    dir_path = Path(directory)
    
    if not dir_path.exists():
        print(f"Error: Directory '{directory}' does not exist")
        return files
    
    for root, dirs, filenames in os.walk(directory):
        for filename in filenames:
            full_path = Path(root) / filename
            # Get relative path from the base directory
            relative_path = full_path.relative_to(dir_path)
            files.add(str(relative_path))
    
    return files


def compare_directories(dir1: str, dir2: str) -> Tuple[Set[str], Set[str], Set[str]]:
    """
    Compare two directories and return files in each directory.
    
    Returns:
        - files only in dir1
        - files only in dir2  
        - files in both directories
    """
    files1 = get_all_files(dir1)
    files2 = get_all_files(dir2)
    
    only_in_dir1 = files1 - files2
    only_in_dir2 = files2 - files1
    in_both = files1 & files2
    
    return only_in_dir1, only_in_dir2, in_both


def run_diff(file1_path: str, file2_path: str, relative_path: str) -> bool:
    """
    Run diff on two files and print the output.
    Returns True if files are different, False if identical.
    """
    try:
        # Use diff -u for unified diff format
        result = subprocess.run(
            ['diff', '-u', file1_path, file2_path],
            capture_output=True,
            text=True
        )
        
        if result.returncode == 0:
            # Files are identical
            return False
        elif result.returncode == 1:
            # Files are different
            print(f"\n--- Diff for: {relative_path} ---")
            print(result.stdout)
            return True
        else:
            # Error occurred
            print(f"\nError running diff on {relative_path}: {result.stderr}")
            return False
            
    except FileNotFoundError:
        print(f"\nError: 'diff' command not found. Please install diffutils.")
        return False
    except Exception as e:
        print(f"\nError comparing {relative_path}: {e}")
        return False


def compare_file_contents(dir1: str, dir2: str, common_files: Set[str]) -> Tuple[int, int]:
    """
    Compare contents of files that exist in both directories.
    Returns (identical_count, different_count).
    """
    identical_count = 0
    different_count = 0
    
    print(f"\nComparing contents of {len(common_files)} common files...")
    print("=" * 60)
    
    for relative_path in sorted(common_files):
        file1_path = os.path.join(dir1, relative_path)
        file2_path = os.path.join(dir2, relative_path)
        
        if run_diff(file1_path, file2_path, relative_path):
            different_count += 1
        else:
            identical_count += 1
    
    return identical_count, different_count


def main():
    if len(sys.argv) < 3:
        print("Usage: python compare_directories.py <directory1> <directory2> [--no-diff]")
        print("Example: python compare_directories.py /path/to/dir1 /path/to/dir2")
        print("Use --no-diff to skip content comparison")
        sys.exit(1)
    
    dir1 = sys.argv[1]
    dir2 = sys.argv[2]
    skip_diff = '--no-diff' in sys.argv
    
    print(f"Comparing directories:")
    print(f"  Directory 1: {dir1}")
    print(f"  Directory 2: {dir2}")
    print("=" * 60)
    
    only_in_dir1, only_in_dir2, in_both = compare_directories(dir1, dir2)
    
    print(f"\nFiles only in '{dir1}' ({len(only_in_dir1)} files):")
    if only_in_dir1:
        for file in sorted(only_in_dir1):
            print(f"  - {file}")
    else:
        print("  (none)")
    
    print(f"\nFiles only in '{dir2}' ({len(only_in_dir2)} files):")
    if only_in_dir2:
        for file in sorted(only_in_dir2):
            print(f"  - {file}")
    else:
        print("  (none)")
    
    print(f"\nFiles in both directories ({len(in_both)} files):")
    if in_both:
        for file in sorted(in_both):
            print(f"  - {file}")
    else:
        print("  (none)")
    
    # Compare file contents if requested and there are common files
    identical_count = 0
    different_count = 0
    if not skip_diff and in_both:
        identical_count, different_count = compare_file_contents(dir1, dir2, in_both)
    
    print("\n" + "=" * 60)
    print(f"Summary:")
    print(f"  Total files in '{dir1}': {len(only_in_dir1) + len(in_both)}")
    print(f"  Total files in '{dir2}': {len(only_in_dir2) + len(in_both)}")
    print(f"  Files only in '{dir1}': {len(only_in_dir1)}")
    print(f"  Files only in '{dir2}': {len(only_in_dir2)}")
    print(f"  Files in both: {len(in_both)}")
    
    if not skip_diff and in_both:
        print(f"  Identical files: {identical_count}")
        print(f"  Different files: {different_count}")


if __name__ == "__main__":
    main() 
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added support for extracting and displaying activation code data,
including partner information and logos, when relevant.
- **Style**
- Removed embedded CSS styling from the server management interface
header.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-25 12:57:48 -04:00
Eli Bosley
0788756b91 feat: add management page for API keys (#1408)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added ability to update existing API keys, including name,
description, roles, and permissions, through the UI and GraphQL API.
- Introduced a modal-based interface for creating and editing API keys
with improved role and permission selection.
- Added a new API Key Manager page and custom element for centralized
API key management.
- Enhanced API key listing with detailed views, role badges, permission
counters, and copy-to-clipboard functionality.
- Introduced reusable dialog components for consistent modal
experiences.
- Added plugin management capabilities with mutations to add or remove
plugins.
- Added comprehensive support for managing remote access, network URLs,
and API key updates within the GraphQL schema.

- **Bug Fixes**
- Improved error handling and display for API key creation and update
operations.

- **Refactor**
- Centralized API key modal and editing state management using a
dedicated store.
- Updated GraphQL queries and mutations to use reusable fragments for
API key data.
- Removed deprecated or redundant remote access and allowed origins
configuration components and queries.
- Simplified and updated input types for connect settings and remote
access.

- **Tests**
- Added comprehensive tests for API key update logic and improved
coverage for API key loading.

- **Chores**
- Updated configuration files and cleaned up unused schema and component
files.
  - Added new dialog components and centralized exports for dialogs.
- Improved ESLint configuration and import statements for better type
handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-18 11:18:36 -04:00
Pujit Mehrotra
d9ab58eb83 chore: require connect plugin to enable flash backup (#1419)
## Summary by CodeRabbit

- **New Features**
- Added a check to ensure the "unraid-api-plugin-connect" plugin is
enabled before allowing flash backup functionality.
- Introduced a utility to directly verify if specific API plugins are
enabled.

- **Refactor**
- Updated internal logic to use a centralized class and script-based
checks for plugin status and version instead of manual config parsing.
- Improved script command-line interface for easier plugin status and
version checks.

- **Bug Fixes**
- Flash Backup feature and service now only activate when the required
API plugin is enabled, preventing unintended usage.
- Flash Backup UI is conditionally displayed based on the presence of
the API plugin.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1209357561531351
  - https://app.asana.com/0/0/1210541992642236
2025-06-18 10:20:59 -04:00
Pujit Mehrotra
8c8a5276b4 fix: omit Connect actions in UPC when plugin is not installed (#1417)
Removes Connect branding in dropdown when connect plugin is not installed.

Preview of dropdown:
<img width="453" alt="image"
src="https://github.com/user-attachments/assets/b3ba3954-f2d3-4760-a1e2-91556eb43903"
/>

## Summary by CodeRabbit

- **New Features**
- The Notifications Sidebar is now always visible in the user profile,
regardless of plugin installation status.

- **Refactor**
  - Improved detection logic for the connect plugin to enhance accuracy.
- Centralized and standardized the "Settings" link in the user profile
dropdown for consistent user experience.
- The account status section in Connect Settings now only appears when
the connect plugin is installed.
- Updated the Connect page title from "Unraid Connect" to "Unraid API"
for clarity.

- **Chores**
- Extended linting to include Vue files for better code quality
enforcement.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-16 11:50:37 -04:00
Pujit Mehrotra
184b76de1c chore: include node_modules in api slackware package (#1415)
instead of vendoring & uploading separately.

## Summary by CodeRabbit

- **Chores**
- Updated build process to retain the `node_modules` directory, removing
compression and archiving steps.
- Improved plugin installation by cleaning up outdated dependency
archives before reinstalling, enhancing system stability.
- Removed vendor store file references and related bundling steps from
the plugin build and installation process.
- Enhanced dependency restoration during service start to log warnings
without aborting on failure.
- Simplified dependency management scripts by removing vendor store URL
handling and download functionality.
- Streamlined build workflows by removing artifact upload/download and
validation steps related to node modules archives.
- Updated Docker Compose configuration to remove unused volume mounts
for node modules archives.
- Added repository cleanup commands to remove top-level `node_modules`
directories and common build artifact folders for easier maintenance.
2025-06-11 12:07:32 -04:00
Pujit Mehrotra
c132f28281 chore: extract connect to an API plugin (#1367)
separates Unraid Connect from the API

## Summary by CodeRabbit

- **New Features**
- Introduced a unified, JSON-schema-based settings system for API
configuration and plugin settings, accessible via new GraphQL queries
and mutations.
- Added modular NestJS plugin architecture for Unraid Connect, including
new modules for cloud, remote access, and system/network management.
- Added granular connection and remote access state tracking, with new
GraphQL types and resolvers for cloud and connection status.
- Implemented event-driven and service-based management for SSO users,
API keys, and dynamic remote access.
- Enhanced UI components and queries to support unified settings and
restart detection.

- **Improvements**
- Refactored configuration and state management to use service-based
patterns, replacing direct store access and Redux logic.
- Migrated legacy config files to new JSON formats with validation and
persistence helpers.
- Centralized global dependencies and shared services for plugins and
CLI modules.
- Improved logging, error handling, and lifecycle management for
connections and background jobs.
- Updated and expanded documentation for plugin development and settings
management.

- **Bug Fixes**
- Improved handling of missing config files and ensured safe
persistence.
- Enhanced error reporting and validation in remote access and
connection services.

- **Removals**
- Removed deprecated Redux slices, listeners, and legacy cloud/remote
access logic.
- Deleted obsolete test files, scripts, and unused code related to the
old state/store approach.

- **Tests**
- Added new unit tests for settings merging, URL resolution, and cloud
connectivity checks.

- **Style**
- Applied consistent formatting, import reorganization, and code style
improvements across modules.

- **Chores**
- Updated build scripts, Dockerfiles, and development environment setup
to support new dependencies and workflows.
- Expanded .gitignore and configuration files for improved build
artifact management.
2025-06-10 15:16:26 -04:00
Eli Bosley
83076bb940 fix: rc.unraid-api now cleans up older dependencies (#1404)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added an option to clean up old dependency files, keeping only those
needed for the current API version.
- Introduced a direct cleanup command to remove outdated dependencies
before installing new ones.

- **Bug Fixes**
- Improved handling and messaging for missing or invalid dependency
information during cleanup operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 10:23:58 -04:00
Eli Bosley
7d88b3393c fix: do not start API with doinst.sh 2025-05-20 17:42:49 -04:00
Eli Bosley
fcd6fbcdd4 feat: move to iframe for changelog (#1388)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Changelog modal now displays changelog documentation within an
embedded iframe if a URL is available, allowing navigation within the
iframe and providing a "Back to Changelog" button to return to the
original view.
- "View on Docs" button dynamically updates to reflect the current page
within the iframe.
- Added support for displaying a formatted changelog string and testing
modal behavior with or without this content.
- Introduced a new component to fetch, parse, and render changelogs from
URLs with enhanced markdown handling.
- Update OS store extended to manage changelog display and release
stability, consolidating changelog state and actions.

- **Bug Fixes**
  - Close button in modal dialogs is now visible on all screen sizes.

- **Chores**
- Updated the default server state, which may affect registration device
counts and types.
- Added new localization string for changelog titles with version
placeholders.
- Removed deprecated changelog store and related tests, simplifying
state management.
- Refined backup and restoration scripts for unraid-components directory
to use move operations with improved logging.
- Improved modal visibility state handling by consolidating changelog
modal controls into the main update OS store.
- Added URL origin and pattern checks for changelog iframe navigation
security.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-05-19 15:34:44 -04:00
Eli Bosley
4f63b4cf3b feat: native slackware package (#1381)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added detailed versioning for plugin packages incorporating
architecture and build identifiers.
- Simplified and improved install/uninstall scripts with backup and
dynamic package detection.
- Introduced comprehensive setup, verification, patching, and cleanup
scripts for the Unraid API environment.
- Enhanced service control with explicit start, stop, restart, and
status commands.
- Added robust dependency management scripts for restoring and archiving
Node.js modules.
- Implemented vendor archive metadata storage and dynamic handling
during build and runtime.
- Added new CLI options and environment schemas for consistent build
configuration.
- Introduced new shutdown scripts to gracefully stop flash-backup and
unraid-api services.
- Added utility scripts for API version detection and vendor archive
configuration.
- Added a new package description file detailing Unraid API features and
homepage link.

- **Bug Fixes**
- Improved validation and error reporting for missing manifests,
dependencies, and configuration files.
  - Enhanced fallback logic for locating and creating vendor archives.
- Fixed iframe compatibility in UI by updating HTML and Firefox
preference files.

- **Chores**
- Updated .gitignore with generated file patterns for Node.js binaries
and archives.
  - Removed obsolete internal documentation and legacy cleanup scripts.
- Refined Docker Compose and CI workflows to pass precise API versioning
and manage build artifacts.
- Centralized common environment validation and CLI option definitions
across build tools.
- Cleaned up plugin manifest by removing Node.js and PNPM-related
entities and legacy logic.
- Improved logging and error handling in build and installation scripts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-08 22:54:10 -04:00
Eli Bosley
39e83b2aa1 feat: move activation code logic into the API (#1369)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added comprehensive activation code customization service with dynamic
theming, partner branding, and UI updates.
- Introduced new GraphQL types and public queries for activation code,
partner info, and theme data.
- Implemented new web UI stores and components for activation modal,
partner logos, and theme management.
- **Improvements**
- Removed legacy activation code scripts, PHP components, and plugin
references, streamlining activation logic.
- Enhanced configuration and environment support for activation and
theming features.
- Improved error handling, validation, and type safety in activation and
customization modules.
- **Bug Fixes**
- Fixed color code validation and path handling in customization
service.
- **Chores**
  - Added pre-commit linting hooks and related configuration.
  - Cleaned up test and development environment files.
- **Tests**
- Added extensive tests covering activation customization service
initialization, data handling, and file modifications.
  - Removed obsolete tests related to legacy activation code store.
- **Refactor**
- Migrated activation and partner branding logic from legacy scripts and
PHP to TypeScript services and GraphQL resolvers.
- Reorganized store and component architecture for activation-related
features.
- **Style**
- Updated UI components for improved branding, theming, accessibility,
and layout consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Zack Spear <hi@zackspear.com>
2025-05-01 17:40:36 -04:00