RocketChat / RocketChat/EmbeddedChat
bug: OAuth login promise hangs forever if user closes popup without completing login
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 165
- Forks
- 381
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 1
Description
If a user opens the OAuth popup and closes it without finishing login, the promise in loginWithRocketChatOAuth never settles. No resolve, no reject.
The Promise constructor on line 45 only takes resolve. There's no reject. The only path to resolve() is inside the onMessage handler, which fires when the popup posts back an rc-oauth-callback message.
There IS code that detects when the popup closes (the setInterval on line 60). It cleans up the interval and the event listener, which is good. But then it just... stops. Nobody calls resolve() or reject(), so the promise sits there indefinitely:
const checkInterval = setInterval(() => {
if (popup.closed) {
clearInterval(checkInterval);
window.removeEventListener("message", onMessage);
// nothing here — promise hangs
}
}, 1000);
What happens in practice:
The caller in ChatInput.js (line 241) does:
try {
await RCInstance.auth.loginWithRocketChatOAuth();
} catch (e) {
console.error(e);
dispatchToastMessage({ type: 'error', message: e.message });
}
Since the promise never rejects, the catch block never runs. The user closes the popup and gets zero feedback — no error toast, no "login cancelled" message, nothing. The onJoin async function just silently stays stuck at the await forever.
Each time the user tries this (click JOIN, popup opens, close popup), another unresolved promise stacks up in memory. They're never garbage collected because the promise internals still hold references to the closure.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in loginWithRocketChatOAuth at the Promise constructor and the popup-close setInterval described in the issue, then check the caller in ChatInput.js around line 241. Trace the close path and verify that the caller's catch block receives the cancellation outcome and displays feedback; done means the promise no longer remains pending when the popup closes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- authentication, frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100