fix(dropbox): fix Invalid redirect_uri error by adding PUBLIC_BASE_URL config and URL-encoding

- Add PUBLIC_BASE_URL optional config to override auto-detected OAuth redirect URIs
  when behind a reverse proxy that doesn't forward X-Forwarded-Proto headers
- Add _build_dropbox_redirect_uri() helper in app/api/dropbox.py
- URL-encode redirect_uri in server-side Dropbox authorization URL
- Add _get_dropbox_callback_url() helper in app/views/dropbox.py
- Pass callback_url to both setup and callback templates
- Update templates to use server-provided callback_url instead of window.location.origin
- Update settings_service.py to register new setting
- Update .env.demo, ConfigurationGuide.md, and DropboxSetup.md documentation
- Add tests for new helper functions and global-authorize-url endpoint

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-20 08:19:48 +00:00
parent f2ba74a483
commit 5e3e2b1999
11 changed files with 230 additions and 6 deletions
+5 -2
View File
@@ -104,7 +104,7 @@
<h3 class="text-xl font-medium mb-4">Step 3: Set OAuth 2 Redirect URI</h3>
<ol class="list-decimal ml-6 space-y-3">
<li>In your app's settings page, go to the "OAuth 2" section</li>
<li>Add a redirect URI: <code class="bg-gray-100 p-1">{{ request.url.scheme }}://{{ request.url.netloc }}/dropbox-callback</code></li>
<li>Add a redirect URI: <code class="bg-gray-100 p-1">{{ callback_url }}</code></li>
<li>Click "Add" to save the redirect URI</li>
</ol>
</div>
@@ -298,6 +298,9 @@ DROPBOX_FOLDER={{ folder_path|default('/Documents/Uploads', true) }}</code></pre
document.addEventListener('DOMContentLoaded', function() {
const userMode = {{ 'true' if user_mode else 'false' }};
const globalCredsAvailable = {{ 'true' if global_creds_available else 'false' }};
// Redirect URI for OAuth: prefer server-provided value (respects PUBLIC_BASE_URL),
// fall back to window.location.origin for resilience.
const dropboxCallbackUrl = {{ callback_url | tojson }} || (window.location.origin + "/dropbox-callback");
// Store integration_id if provided (for per-user OAuth flow)
const integrationId = "{{ integration_id or '' }}";
@@ -390,7 +393,7 @@ document.addEventListener('DOMContentLoaded', function() {
startAuthFlowBtn.addEventListener('click', function() {
const appKey = document.getElementById('app-key').value.trim();
const appSecret = appSecretInput.value.trim();
const redirectUri = window.location.origin + "/dropbox-callback";
const redirectUri = dropboxCallbackUrl;
if (!appKey) {
showModal('error', 'Validation Error', 'Please enter your App Key');
+2 -1
View File
@@ -108,7 +108,8 @@ document.addEventListener('DOMContentLoaded', function() {
}
}
const redirectUri = window.location.origin + "/dropbox-callback";
// Use server-provided callback URL (respects PUBLIC_BASE_URL) with fallback to window.location.origin
const redirectUri = {{ callback_url | tojson }} || (window.location.origin + "/dropbox-callback");
// Automatically exchange the code for a refresh token
if (code) {