From 212578b42ece58aa32f81a9271f0ce5778a4309b Mon Sep 17 00:00:00 2001 From: adamhaley Date: Fri, 15 Aug 2025 17:44:38 -0700 Subject: [PATCH] added javascript extensions dir and auto-reload after oauth flow --- __init__.py | 3 ++ oauth_handler.py | 36 ++++++++++++- setup_dropbox_node.py | 4 +- web/dropbox_oauth.js | 117 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 web/dropbox_oauth.js diff --git a/__init__.py b/__init__.py index 7f364db..7e4364d 100644 --- a/__init__.py +++ b/__init__.py @@ -12,6 +12,9 @@ NODE_DISPLAY_NAME_MAPPINGS = {} NODE_DISPLAY_NAME_MAPPINGS.update(RUN_DISPLAY) NODE_DISPLAY_NAME_MAPPINGS.update(SETUP_DISPLAY) +# Define web directory for JavaScript extensions +WEB_DIRECTORY = "./web" + # Register OAuth callback route with ComfyUI server def register_oauth_routes(): """Register OAuth callback routes with ComfyUI's PromptServer""" diff --git a/oauth_handler.py b/oauth_handler.py index 4f46512..031adc9 100644 --- a/oauth_handler.py +++ b/oauth_handler.py @@ -46,6 +46,20 @@ class OAuthCallbackHandler: print(f"[OAuthHandler] Auth code exchange successful") + # Send WebSocket message to trigger ComfyUI refresh + try: + from server import PromptServer + message_data = { + "type": "dropbox_oauth_complete", + "session_id": self.session_id, + "success": True, + "message": "āœ… Dropbox connected successfully!" + } + PromptServer.instance.send_sync("dropbox_oauth_complete", message_data) + print(f"[OAuthHandler] Sent WebSocket notification for OAuth completion") + except Exception as e: + print(f"[OAuthHandler] Warning: Could not send WebSocket notification: {e}") + # Call completion callback if provided if self.completion_callback: await self.completion_callback(True, "āœ… Dropbox connected successfully!") @@ -110,9 +124,27 @@ async def handle_oauth_callback(request):

āœ… Authorization Successful!

{message}

-

You can now close this window and return to ComfyUI.

+

This window will close automatically and ComfyUI will refresh...

""", content_type='text/html') diff --git a/setup_dropbox_node.py b/setup_dropbox_node.py index 0162abf..8e8f907 100644 --- a/setup_dropbox_node.py +++ b/setup_dropbox_node.py @@ -155,12 +155,12 @@ class DropboxSetupNode: try: print(f"[DropboxSetup] Opening browser for automatic OAuth flow...") webbrowser.open(oauth_url) - message = f"šŸš€ Automatic OAuth Started!\n\n🌐 Browser opened for authorization. After you authorize in Dropbox, this will complete automatically.\n\nā³ Waiting for authorization..." + message = f"šŸš€ Automatic OAuth Started!\n\n🌐 Browser opened for authorization. After you authorize in Dropbox, ComfyUI will refresh automatically.\n\nā³ Waiting for authorization...\n\nšŸ”— OAuth URL: {oauth_url}" print(f"[DropboxSetup] Session ID: {session_id}") print(f"[DropboxSetup] Callback URL: {callback_url}") except Exception as e: print(f"[DropboxSetup] Could not auto-open browser: {e}") - message = f"šŸ”— Automatic OAuth Setup:\n\nPlease visit this URL to authorize:\n{oauth_url}\n\nAfter authorization, setup will complete automatically!" + message = f"šŸ”— Automatic OAuth Setup:\n\nPlease visit this URL to authorize:\n{oauth_url}\n\nAfter authorization, ComfyUI will refresh automatically!" else: # Manual OAuth flow (original behavior) oauth_url = auth_temp.get_oauth_url() diff --git a/web/dropbox_oauth.js b/web/dropbox_oauth.js new file mode 100644 index 0000000..93bea74 --- /dev/null +++ b/web/dropbox_oauth.js @@ -0,0 +1,117 @@ +// dropbox_oauth.js - ComfyUI extension for seamless Dropbox OAuth flow + +import { app } from "../../scripts/app.js"; +import { api } from "../../scripts/api.js"; + +// Track OAuth popup windows +let oauthPopup = null; + +app.registerExtension({ + name: "DropSendNode.OAuthHandler", + + async setup() { + console.log("[DropSendNode] OAuth extension loaded"); + + // Listen for WebSocket messages about OAuth completion + api.addEventListener("dropbox_oauth_complete", (event) => { + console.log("[DropSendNode] Received OAuth completion notification via WebSocket", event.detail); + + const data = event.detail; + if (data.success) { + console.log("[DropSendNode] OAuth successful - refreshing interface"); + this.handleOAuthSuccess(); + } else { + console.error("[DropSendNode] OAuth failed:", data.message); + } + }); + + // Listen for postMessage from OAuth popup window + window.addEventListener("message", (event) => { + if (event.data && event.data.type === 'dropbox_oauth_complete') { + console.log("[DropSendNode] Received OAuth completion notification via postMessage", event.data); + + if (event.data.success) { + console.log("[DropSendNode] OAuth successful - refreshing interface"); + this.handleOAuthSuccess(); + } else { + console.error("[DropSendNode] OAuth failed:", event.data.message); + } + } + }); + }, + + handleOAuthSuccess() { + // Close OAuth popup if it's open + if (oauthPopup && !oauthPopup.closed) { + oauthPopup.close(); + console.log("[DropSendNode] Closed OAuth popup window"); + } + + // Refresh ComfyUI interface to update node UI + setTimeout(() => { + console.log("[DropSendNode] Refreshing ComfyUI interface"); + window.location.reload(); + }, 1500); // Small delay to ensure OAuth processing is complete + }, + + // Override the webbrowser.open functionality for better popup control + async beforeRegisterNodeDef(nodeType, nodeData, app) { + if (nodeData.name === "DropboxSetupNode") { + console.log("[DropSendNode] Registered DropboxSetupNode enhancement"); + + // Add custom OAuth popup handling + const originalExecute = nodeType.prototype.onExecuted; + nodeType.prototype.onExecuted = function(message) { + // Check if this execution includes OAuth URL generation + if (message && typeof message === 'string' && message.includes('šŸš€ Automatic OAuth Started!')) { + console.log("[DropSendNode] Detected automatic OAuth start"); + + // Extract OAuth URL from the message (it should be in the callback setup) + // We'll enhance this to open a proper popup instead of a full tab + } + + if (originalExecute) { + return originalExecute.apply(this, arguments); + } + }; + } + } +}); + +// Utility function to open OAuth in a small popup window +window.openDropboxOAuth = function(url) { + console.log("[DropSendNode] Opening OAuth popup:", url); + + // Close existing popup if open + if (oauthPopup && !oauthPopup.closed) { + oauthPopup.close(); + } + + // Open small popup window + const popup = window.open( + url, + 'dropbox_oauth', + 'width=500,height=600,scrollbars=yes,resizable=yes,status=no,location=no,toolbar=no,menubar=no' + ); + + if (popup) { + oauthPopup = popup; + + // Focus the popup + popup.focus(); + + // Monitor popup closure (optional - for fallback UI updates) + const checkClosed = setInterval(() => { + if (popup.closed) { + console.log("[DropSendNode] OAuth popup closed by user"); + clearInterval(checkClosed); + oauthPopup = null; + } + }, 1000); + + return popup; + } else { + console.error("[DropSendNode] Could not open OAuth popup - popup blocked?"); + return null; + } +}; \ No newline at end of file