When viewing PDF chunks in semantic search, the PDF viewer failed with
"can't access private field" errors. This was caused by:
1. CSP blocks web workers (worker-src 'none'), forcing fake worker mode
2. Vite transforms ES private fields in the bundle, but the worker file
is untransformed, causing incompatible private field implementations
3. Vue's ref() wraps PDFDocumentProxy in a Proxy, which can't access
ES private fields
Fixed by:
- Loading pdfjs-dist externally via script tag (avoids Vite transform)
- Creating pdfjs-loader.mjs that imports pdf.mjs and sets window.pdfjsLib
- Using Util::addScript() for CSP-compliant script loading with nonces
- Using shallowRef() instead of ref() for pdfDoc to avoid Proxy wrapper
- Setting workerSrc at runtime using OC.linkTo() for correct app path
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The @nextcloud/vue library (v9.x) requires appName and appVersion to be
defined as global constants at build time. Without these, the library
logs an error: "The '@nextcloud/vue' library was used without setting /
replacing the 'appName'."
This fix reads the app ID and version from appinfo/info.xml and injects
them via Vite's define option, matching how @nextcloud/webpack-vue-config
handles this for webpack-based apps.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Two issues prevented CSS from loading correctly:
1. Entry point naming mismatch: Vite output `main.css` but Nextcloud's
`Util::addStyle('astrolabe', 'astrolabe-main')` expected `astrolabe-main.css`
2. CSS code splitting: Vite extracted @nextcloud/vue component styles
into separate chunks (e.g., NcUserBubble-*.css) that Nextcloud doesn't
load automatically. Without these styles, the UI rendered incorrectly.
Changes:
- Rename entry point from `main` to `astrolabe-main`
- Add `cssCodeSplit: false` to bundle all CSS into the entry point
- Update assetFileNames to output consistent `astrolabe-main.css`
This increases CSS bundle from 11KB to 286KB but ensures all component
styles are available when the page loads.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds complete app password provisioning workflow for multi-user BasicAuth
deployments, allowing users to independently enable background sync by
generating and storing Nextcloud app passwords.
**New Components:**
Backend (PHP):
- CredentialsController: Validates and stores app passwords
* Validates app password format and authenticity via OCS API
* Stores encrypted passwords in oc_preferences
* Provides status and credential management endpoints
- AstrolabeAdminSettings: Admin configuration page for MCP server URL
- AstrolabeAdminSettingsListener: Event listener for admin section
- Updated McpTokenStorage: Added background sync credential methods
Frontend:
- personalSettings.js: Form handling for app password entry
* AJAX submission with error handling
* Shows success/error notifications
* Triggers page reload after successful save
- settings.css: Styling for settings pages
- Updated personal.php template: Two-option UI
* Option 1: OAuth refresh token (future, not yet available)
* Option 2: App password (works today, recommended)
* Shows "Active" badge when provisioned
* Displays credential type and provisioned timestamp
Routes:
- POST /api/v1/background-sync/credentials - Store app password
- GET /api/v1/background-sync/status - Get provisioning status
- DELETE /api/v1/background-sync/credentials - Revoke credentials
- GET /api/v1/background-sync/credentials/{userId} - Admin only
**Testing:**
- test_astrolabe_settings_buttons.py: Integration test for UI buttons
**Workflow:**
1. User generates app password in Nextcloud Security settings
2. User navigates to Astrolabe personal settings
3. User enters app password in "Option 2: App Password" form
4. Backend validates password via OCS API call
5. Password stored encrypted in oc_preferences
6. Page reloads showing "Active" badge with credential details
7. MCP server can now use stored password for background operations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>