Changing to returning a boolean, but tokens still not being loaded

This commit is contained in:
Glen Maddern 2025-03-31 21:16:21 +11:00
parent 412b5d9486
commit 9fbba0509c
4 changed files with 33 additions and 20 deletions

View file

@ -42,9 +42,9 @@ async function runClient(serverUrl: string, callbackPort: number, clean: boolean
clean, clean,
}) })
// If we got auth from another instance, pre-populate with the received code // If auth was completed by another instance, just log that we'll use the auth from disk
if (skipBrowserAuth) { if (skipBrowserAuth) {
log('Using auth code from another instance') log('Authentication was completed by another instance - will use tokens from disk')
} }
// Create the client // Create the client

View file

@ -58,9 +58,9 @@ export async function isLockValid(lockData: LockfileData): Promise<boolean> {
/** /**
* Waits for authentication from another server instance * Waits for authentication from another server instance
* @param port The port to connect to * @param port The port to connect to
* @returns The auth code if successful, false otherwise * @returns True if authentication completed successfully, false otherwise
*/ */
export async function waitForAuthentication(port: number): Promise<string | false> { export async function waitForAuthentication(port: number): Promise<boolean> {
log(`Waiting for authentication from the server on port ${port}...`) log(`Waiting for authentication from the server on port ${port}...`)
try { try {
@ -70,11 +70,13 @@ export async function waitForAuthentication(port: number): Promise<string | fals
const response = await fetch(url) const response = await fetch(url)
if (response.status === 200) { if (response.status === 200) {
const code = await response.text() // Auth completed, but we don't return the code anymore
log(`Received code: ${code}`) log(`Authentication completed by other instance`)
return code // Return the auth code return true
} else if (response.status === 202) { } else if (response.status === 202) {
// do nothing, loop // Continue polling
log(`Authentication still in progress`)
await new Promise(resolve => setTimeout(resolve, 1000))
} else { } else {
log(`Unexpected response status: ${response.status}`) log(`Unexpected response status: ${response.status}`)
return false return false
@ -97,7 +99,7 @@ export async function coordinateAuth(
serverUrlHash: string, serverUrlHash: string,
callbackPort: number, callbackPort: number,
events: EventEmitter, events: EventEmitter,
): Promise<{ server: Server; waitForAuthCode: () => Promise<string>; skipBrowserAuth: boolean; authCode?: string }> { ): Promise<{ server: Server; waitForAuthCode: () => Promise<string>; skipBrowserAuth: boolean }> {
// Check for a lockfile // Check for a lockfile
const lockData = await checkLockfile(serverUrlHash) const lockData = await checkLockfile(serverUrlHash)
@ -107,19 +109,24 @@ export async function coordinateAuth(
try { try {
// Try to wait for the authentication to complete // Try to wait for the authentication to complete
const code = await waitForAuthentication(lockData.port) const authCompleted = await waitForAuthentication(lockData.port)
if (code) { if (authCompleted) {
log('Authentication completed by another instance') log('Authentication completed by another instance')
// Setup a dummy server and return a pre-resolved promise for the auth code // Setup a dummy server - the client will use tokens directly from disk
const dummyServer = express().listen(0) // Listen on any available port const dummyServer = express().listen(0) // Listen on any available port
const dummyWaitForAuthCode = () => Promise.resolve(code)
// This shouldn't actually be called in normal operation, but provide it for API compatibility
const dummyWaitForAuthCode = () => {
log('WARNING: waitForAuthCode called in secondary instance - this is unexpected')
// Return a promise that never resolves - the client should use the tokens from disk instead
return new Promise<string>(() => {})
}
return { return {
server: dummyServer, server: dummyServer,
waitForAuthCode: dummyWaitForAuthCode, waitForAuthCode: dummyWaitForAuthCode,
skipBrowserAuth: true, skipBrowserAuth: true,
authCode: code,
} }
} else { } else {
log('Taking over authentication process...') log('Taking over authentication process...')
@ -176,6 +183,6 @@ export async function coordinateAuth(
return { return {
server, server,
waitForAuthCode, waitForAuthCode,
skipBrowserAuth: false, skipBrowserAuth: false
} }
} }

View file

@ -135,9 +135,10 @@ export function setupOAuthCallbackServerWithLongPoll(options: OAuthCallbackServe
// Long-polling endpoint // Long-polling endpoint
app.get('/wait-for-auth', (req, res) => { app.get('/wait-for-auth', (req, res) => {
if (authCode) { if (authCode) {
// Auth already completed // Auth already completed - just return 200 without the actual code
log('Auth already completed, returning immediately') // Secondary instances will read tokens from disk
res.status(200).send(authCode) log('Auth already completed, returning 200')
res.status(200).send('Authentication completed')
return return
} }
@ -155,11 +156,11 @@ export function setupOAuthCallbackServerWithLongPoll(options: OAuthCallbackServe
// If auth completes while we're waiting, send the response immediately // If auth completes while we're waiting, send the response immediately
authCompletedPromise authCompletedPromise
.then((code) => { .then(() => {
clearTimeout(longPollTimeout) clearTimeout(longPollTimeout)
if (!res.headersSent) { if (!res.headersSent) {
log('Auth completed during long poll, responding with 200') log('Auth completed during long poll, responding with 200')
res.status(200).send(code) res.status(200).send('Authentication completed')
} }
}) })
.catch(() => { .catch(() => {

View file

@ -39,6 +39,11 @@ async function runProxy(serverUrl: string, callbackPort: number, clean: boolean
clean, clean,
}) })
// If auth was completed by another instance, just log that we'll use the auth from disk
if (skipBrowserAuth) {
log('Authentication was completed by another instance - will use tokens from disk')
}
// Create the STDIO transport for local connections // Create the STDIO transport for local connections
const localTransport = new StdioServerTransport() const localTransport = new StdioServerTransport()