Skip to content

Fix Naver/Daum login not syncing back to the in-app WebView - #94

Closed
DusanBaek wants to merge 1 commit into
devxoul:mainfrom
DusanBaek:fix/naver-login-cookie-sync
Closed

Fix Naver/Daum login not syncing back to the in-app WebView#94
DusanBaek wants to merge 1 commit into
devxoul:mainfrom
DusanBaek:fix/naver-login-cookie-sync

Conversation

@DusanBaek

@DusanBaek DusanBaek commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Login popups (e.g. Naver's login window) were opened in the system default browser via NSWorkspace.shared.open, which uses a completely separate cookie store from the app's WKWebView. Logging in there never propagated back to the app, so the dictionary view always showed a logged-out state.
  • Popups are now presented in an in-app NSWindow backed by a WKWebView built from the exact WKWebViewConfiguration WebKit passes to createWebViewWith(_:for:windowFeatures:), so the login session is written to the same data store the main dictionary view uses.
  • When the popup closes (either via window.close() after a successful login, or the user closing it manually), the main dictionary WebView reloads to pick up the new session.

Test plan

  • Built and ran locally via tuist build / running the Debug app
  • Manually verified: open the popover, click Naver's login button, log in inside the in-app popup window, confirm the popup closes and the main view shows a logged-in state
  • Same check for Daum, if it has a similar login flow

Summary by cubic

Fixes Naver/Daum login popups so sessions sync with the in-app WKWebView. Popups now open in an in-app window using the same WKWebViewConfiguration, and the main view reloads when the popup closes.

  • Bug Fixes
    • Implemented webView(_:createWebViewWith:for:windowFeatures:) to show popups in an NSWindow with the provided WKWebViewConfiguration.
    • Added NSWindowDelegate handling to close the popup and reload the main web view (windowWillClose, webViewDidClose).
    • Removed external browser fallback using NSWorkspace.shared.open.

Written for commit 09728e0. Summary will update on new commits.

Review in cubic

Login popups were opened in the system default browser via
NSWorkspace, which stores cookies in a completely separate data
store from the app's WKWebView. Logging in there never reflected in
the app.

Popups are now presented in an in-app window using the same
WKWebViewConfiguration WebKit hands to createWebViewWith(_:for:),
so the login session lands in the same cookie store as the main
dictionary view. The main view reloads once the popup closes.
@typeey

typeey Bot commented Aug 1, 2026

Copy link
Copy Markdown

I’m checking the WebKit lifecycle and session-sharing details now; I’ll post the formal review once that’s complete.

@typeey typeey Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The in-app window/configuration approach is directionally right, but there are two issues to resolve before this is ready to merge.

NSWorkspace.shared.open(url)
}
return nil
self.popupWindow?.close()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Popup navigation is being handled as main-WebView navigation.

popupWebView.navigationDelegate = self sends the popup's callbacks through logic that mutates the shared isLoading, injects dictionary CSS into the callback's WebView, and calls focusInput() on the main WebView. During login this can make the main loading indicator inaccurate and run main-page presentation behavior for the popup.

The popup only needs uiDelegate = self for window.close(). Either omit its navigation delegate, or guard every main-specific callback with webView === self.webView and give the popup separate navigation handling.

createWebViewWith configuration: WKWebViewConfiguration,
for _: WKNavigationAction,
windowFeatures _: WKWindowFeatures,
) -> WKWebView? {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two user-facing login flows are still unverified.

The PR test plan leaves both Naver and Daum login checks unchecked, and compilation/launching does not establish shared cookies, JavaScript-driven closing, manual closing, or the reload that should pick up the new session.

Please complete and record both flows before merging, including successful window.close() and manual-close behavior. A local HTML-fixture test for window.open → popup closure → main-view reload would also be valuable if practical.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Allkdic/Views/DictionaryWebView.swift">

<violation number="1" location="Allkdic/Views/DictionaryWebView.swift:147">
P2: The popup WebView reuses the main dictionary Coordinator as both its navigation and UI delegate, but that coordinator is built to drive the single main WebView and owns shared state (`isLoading` binding, `lastLoadedURL`, `weak webView`). During a Naver/Daum login the popup performs multiple navigations (form loads, OAuth redirects) before it closes, and each one will now run through the same delegate callbacks that control the main view — so popup activity can clobber the main view's loading flag / last loaded URL, and the main view's navigation-policy handling will be applied to the popup's redirects. I'd suggest giving the popup its own lightweight delegate object (one that only tracks its window and closes on `window.close()` / user close) instead of pointing `navigationDelegate`/`uiDelegate` at the shared coordinator, so popup navigation events never interfere with the dictionary WebView's state.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

self.popupWindow?.close()

let popupWebView = WKWebView(frame: NSRect(x: 0, y: 0, width: 480, height: 640), configuration: configuration)
popupWebView.navigationDelegate = self

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The popup WebView reuses the main dictionary Coordinator as both its navigation and UI delegate, but that coordinator is built to drive the single main WebView and owns shared state (isLoading binding, lastLoadedURL, weak webView). During a Naver/Daum login the popup performs multiple navigations (form loads, OAuth redirects) before it closes, and each one will now run through the same delegate callbacks that control the main view — so popup activity can clobber the main view's loading flag / last loaded URL, and the main view's navigation-policy handling will be applied to the popup's redirects. I'd suggest giving the popup its own lightweight delegate object (one that only tracks its window and closes on window.close() / user close) instead of pointing navigationDelegate/uiDelegate at the shared coordinator, so popup navigation events never interfere with the dictionary WebView's state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Allkdic/Views/DictionaryWebView.swift, line 147:

<comment>The popup WebView reuses the main dictionary Coordinator as both its navigation and UI delegate, but that coordinator is built to drive the single main WebView and owns shared state (`isLoading` binding, `lastLoadedURL`, `weak webView`). During a Naver/Daum login the popup performs multiple navigations (form loads, OAuth redirects) before it closes, and each one will now run through the same delegate callbacks that control the main view — so popup activity can clobber the main view's loading flag / last loaded URL, and the main view's navigation-policy handling will be applied to the popup's redirects. I'd suggest giving the popup its own lightweight delegate object (one that only tracks its window and closes on `window.close()` / user close) instead of pointing `navigationDelegate`/`uiDelegate` at the shared coordinator, so popup navigation events never interfere with the dictionary WebView's state.</comment>

<file context>
@@ -131,16 +132,50 @@ private struct WebView: NSViewRepresentable {
+      self.popupWindow?.close()
+
+      let popupWebView = WKWebView(frame: NSRect(x: 0, y: 0, width: 480, height: 640), configuration: configuration)
+      popupWebView.navigationDelegate = self
+      popupWebView.uiDelegate = self
+
</file context>

@devxoul

devxoul commented Aug 2, 2026

Copy link
Copy Markdown
Owner

@DusanBaek, thanks for the PR. could you please address reviews and fix the CI failure?

@devxoul

devxoul commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Thanks for tracking this down, @DusanBaek — the diagnosis was right, and reusing the WKWebViewConfiguration WebKit hands to createWebViewWith is exactly the right mechanism for keeping the login session in the app's cookie store.

Continuing this in #95. Your commit is cherry-picked there with authorship preserved (337dced), and the follow-ups are separate commits on top:

  • CI was failing for an unrelated reason: the tuist Homebrew tap ships a cask declaring conflicts_with formula:, a key Homebrew 6 removed, so any tuist lookup through the tap aborts (Please remove conflicts_with formula definition tuist/homebrew-tuist#41). main is affected too. Replaced with a pinned mise.toml + jdx/mise-action@v2.
  • Review feedback from @typeey and cubic: the popup no longer reuses the dictionary Coordinator as its delegate. A new LoginPopupController owns the popup window, its web view and its own delegates, so popup navigations can no longer flip the main view's isLoading, inject the dictionary's CSS into the login page, or run its focus script.
  • One regression this would have shipped: removing the createWebViewWith body also removed 4d208b4 ("Fix 새 창 링크가 열리지 않는 문제 #66: Open target=_blank links in default browser"). Content links like "활용형 더보기" would have started opening in a small in-app window instead of the browser. Popups are now routed by destination — known login hosts open in the app, other http(s) links keep going to the browser — with unit tests covering both paths.

Closing in favor of #95. Credit for the fix is yours.

@devxoul devxoul closed this Aug 7, 2026
@typeey

typeey Bot commented Aug 7, 2026

Copy link
Copy Markdown

Thanks for the thorough follow-up — #95’s separation of popup ownership and routing preserves both login-session sharing and the existing external-link behavior. Closing #94 in favor of it makes sense. Nice catch on the CI issue too! (`・ω・´)ゞ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants