Files
nextcloud-mcp-server/third_party/astrolabe/templates/settings/oauth-required.php
T
Chris Coutinho 65c3f099fa feat(astrolabe): implement app password provisioning for multi-user background sync
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>
2025-12-22 19:39:13 +01:00

118 lines
3.6 KiB
PHP

<?php
/**
* OAuth authorization required template.
*
* Shown when user needs to authorize Astrolabe for semantic search.
* Implements OAuth 2.0 Authorization Code flow with PKCE.
*
* @var array $_ Template parameters
* @var string $_['oauth_url'] URL to initiate OAuth flow
* @var string $_['server_url'] Astrolabe service URL
* @var bool $_['has_expired'] Whether token exists but is expired
* @var string|null $_['error_message'] Optional error message to display
*/
use OCP\Util;
Util::addStyle('astrolabe', 'astrolabe-personalSettings');
?>
<div class="section">
<h2><?php p($l->t('Astrolabe')); ?></h2>
<p><?php p($l->t('AI-powered semantic search across your Nextcloud content.')); ?></p>
</div>
<?php if (isset($_['error_message'])): ?>
<div class="section">
<h2><?php p($l->t('Session Expired')); ?></h2>
<p><?php p($_['error_message']); ?></p>
</div>
<?php endif; ?>
<div class="section">
<h2><?php p($l->t('Enable Semantic Search')); ?></h2>
<?php if (isset($_['has_expired']) && $_['has_expired']): ?>
<p>
<?php p($l->t('Your authorization has expired. Please sign in again to continue using semantic search.')); ?>
</p>
<?php else: ?>
<p>
<?php p($l->t('To search your content by meaning, Astrolabe needs permission to index your Nextcloud data.')); ?>
</p>
<?php endif; ?>
<p>
<strong><?php p($l->t('What happens next?')); ?></strong>
</p>
<ol class="mcp-help-text">
<li><?php p($l->t('Sign in to confirm your identity')); ?></li>
<li><?php p($l->t('Grant permission to index your content')); ?></li>
<li><?php p($l->t('Your content will be indexed for semantic search')); ?></li>
<li><?php p($l->t('Start searching with natural language')); ?></li>
</ol>
<h4><?php p($l->t('Content to be Indexed')); ?></h4>
<ul class="mcp-feature-list">
<li>
<span class="icon icon-files"></span>
<div>
<strong><?php p($l->t('Notes & Files')); ?></strong>
<p><?php p($l->t('Your notes and documents will be searchable by meaning')); ?></p>
</div>
</li>
<li>
<span class="icon icon-calendar"></span>
<div>
<strong><?php p($l->t('Calendar & Tasks')); ?></strong>
<p><?php p($l->t('Find events and tasks with natural language queries')); ?></p>
</div>
</li>
<li>
<span class="icon icon-category-dashboard"></span>
<div>
<strong><?php p($l->t('Deck Cards')); ?></strong>
<p><?php p($l->t('Search across your Deck boards and cards')); ?></p>
</div>
</li>
</ul>
<div style="margin-top: 20px;">
<a href="<?php p($_['oauth_url']); ?>" class="button primary">
<span class="icon icon-play"></span>
<?php if (isset($_['has_expired']) && $_['has_expired']): ?>
<?php p($l->t('Sign In Again')); ?>
<?php else: ?>
<?php p($l->t('Enable Semantic Search')); ?>
<?php endif; ?>
</a>
</div>
<p>
<?php p($l->t('You can disable indexing at any time from this settings page.')); ?>
</p>
</div>
<div class="section">
<h2><?php p($l->t('About Astrolabe')); ?></h2>
<p>
<?php p($l->t('Astrolabe enables semantic search - finding content by meaning rather than exact keywords. Ask questions like "meeting notes from last week" or "recipes with chicken" to find relevant documents.')); ?>
</p>
<p class="mcp-help-text">
<?php p($l->t('Your content is processed to understand its meaning, enabling powerful natural language search across all your Nextcloud data.')); ?>
</p>
<ul class="mcp-links">
<li>
<a href="https://github.com/cbcoutinho/nextcloud-mcp-server" target="_blank" rel="noopener noreferrer">
<span class="icon icon-external"></span>
<?php p($l->t('Learn More')); ?>
</a>
</li>
</ul>
</div>