Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| if (headless?.username && headless?.credentials) { | ||
| // Perform headless authentication without UI | ||
| return authenticateHeadless(headless.username, headless.credentials); | ||
| } |
There was a problem hiding this comment.
Inconsistent headless detection causes hung promise on empty username
Medium Severity
Inconsistent headless mode detection between controller.ts and connect.ts can cause a hung promise. The controller checks !headlessOptions (object existence) to decide whether to open the modal, while the keychain's connect checks headless?.username && headless?.credentials (truthy property values) to decide whether to use headless authentication. When headless is provided with an empty string username, the modal isn't opened but the code falls through to the UI-based flow, which waits for user interaction callbacks that can never arrive since the modal is hidden.
Additional Locations (1)
| password, | ||
| }, | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Repeated headless login attempts fail due to singleton iframe
High Severity
The HeadlessLogin component creates a new Controller on each login attempt, but the underlying IFrame class uses singleton-style DOM element management - it checks for an existing "controller" element and won't add a second one. After the first login attempt, subsequent Controller instances have their iframes created but never added to the DOM, so the penpal connection never establishes, this.keychain remains undefined, and connect() immediately returns undefined with a "Not ready to connect" error. Users clicking the login button multiple times will see the first attempt work (or fail for unimplemented reasons) but all subsequent attempts fail instantly.
| return authenticateHeadless( | ||
| headless.username, | ||
| headless.credentials, | ||
| ).then((result) => { |
There was a problem hiding this comment.
Headless mode ignores configured chain, always uses mainnet
High Severity
The authenticateHeadless function accepts an optional chainId parameter that defaults to mainnet, but the connect handler never passes a chainId when calling it. The HeadlessOptions type doesn't include chainId, and neither does ConnectOptions, so even though users configure defaultChainId: SN_SEPOLIA in the Controller SDK, headless authentication always uses mainnet. This causes headless authentication to operate on the wrong chain regardless of configuration.
Summary
Testing