Replace generic "Network error" with specific error messages:
- Show backend error message when available from HTTP response
- Display "Authorization required. Please complete Step 1 in
Settings → Astrolabe." for 401 Unauthorized errors
- Show "Search service unavailable" for 503 errors
- Keep generic network error only for actual connection failures
This helps users understand when they need to complete OAuth
authorization vs when there's an actual network problem.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename OAuthController.php to OauthController.php for consistency
- Fix Personal.php to check specifically for app password presence
using getBackgroundSyncPassword() instead of hasBackgroundSyncAccess()
for hybrid auth mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace Close button click with Escape key in app password dialog
(h2 element was intercepting pointer events)
- Make test_users_setup fixture idempotent by checking user existence
before creation and only tracking created users for cleanup
- Fix search results detection by removing wait for .app-content-wrapper
CSS class that doesn't exist in Astrolabe's Vue app
- Add progress logging during results polling
- Increase polling timeout to 30 seconds for search results
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add dbquery.py for MariaDB and sqlitequery.py for SQLite databases
in MCP service containers. Both scripts wrap docker compose exec to
simplify database inspection during development.
- dbquery.py: Query Nextcloud MariaDB with vertical/JSON output
- sqlitequery.py: Query MCP service SQLite DBs with service aliases
(mcp, oauth, keycloak, basic) and column/JSON output modes
- Document both scripts in CLAUDE.md Database Inspection section
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add explicit property type declarations to IdpTokenRefresher,
CredentialsController, OAuthController, and McpServerClient classes.
This improves type safety and allows Psalm to properly infer types,
eliminating MissingPropertyType and many MixedMethodCall errors.
Also adds IClient import where needed and validates getSystemValue
returns to ensure string types before use.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GitHub workflows should be defined only in the root .github directory,
not in the subproject directory.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Delete stored token when refresh callback fails or returns null
- Delete stored token when expired with no refresh callback available
- Fix test namespaces (Service → OCA\Astrolabe\Tests\Unit\Service)
- Update tests to verify token deletion on refresh failure
Prevents repeated refresh attempts with stale tokens that will never
succeed, improving error handling and reducing unnecessary API calls.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace NcCheckboxRadioSwitch :checked with :model-value
- Replace NcCheckboxRadioSwitch @update:checked with @update:model-value
- Replace NcButton type="primary|secondary|tertiary" with variant prop
- Bump @nextcloud/vue minimum version to ^9.3.3
These changes address deprecated APIs removed in @nextcloud/vue v9.0.0:
- :checked/:update:checked was replaced by v-model/modelValue pattern
- type prop for button variants was replaced by variant prop
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix PHP CS Fixer issues (single quotes, indentation)
- Add typed property declarations to ApiController
- Add Psalm baseline to suppress 517 pre-existing errors
- Fix workflow name references (astroglobe → astrolabe)
The CI workflow was previously watching a non-existent path and never
ran. After fixing the path trigger, these pre-existing code quality
issues were discovered. The Psalm baseline allows CI to pass while
tracking technical debt for incremental resolution.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The IdpTokenRefresher was incorrectly using overwrite.cli.url (the
external URL like http://localhost:8080) for internal token refresh
requests. This URL is not accessible from inside Docker containers
since port 8080 is only mapped on the host machine.
Changed getNextcloudBaseUrl() to:
- Always use http://localhost (internal port 80) by default
- Added optional astrolabe_internal_url config for custom setups
- Removed overwrite.cli.url usage (intended for external URLs only)
This fixes 401 errors in Astrolabe semantic search when OAuth tokens
need to be refreshed in containerized deployments.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>