MCPcopy
hub / github.com/codeaashu/claude-code / startOAuthFlow

Method startOAuthFlow

src/services/oauth/index.ts:32–132  ·  view source on GitHub ↗
(
    authURLHandler: (url: string, automaticUrl?: string) => Promise<void>,
    options?: {
      loginWithClaudeAi?: boolean
      inferenceOnly?: boolean
      expiresIn?: number
      orgUUID?: string
      loginHint?: string
      loginMethod?: string
      /**
       * Don't call openBrowser(). Caller takes both URLs via authURLHandler
       * and decides how/where to open them. Used by the SDK control protocol
       * (claude_authenticate) where the SDK client owns the user's display,
       * not this process.
       */
      skipBrowserOpen?: boolean
    },
  )

Source from the content-addressed store, hash-verified

30 }
31
32 async startOAuthFlow(
33 authURLHandler: (url: string, automaticUrl?: string) => Promise<void>,
34 options?: {
35 loginWithClaudeAi?: boolean
36 inferenceOnly?: boolean
37 expiresIn?: number
38 orgUUID?: string
39 loginHint?: string
40 loginMethod?: string
41 /**
42 * Don't call openBrowser(). Caller takes both URLs via authURLHandler
43 * and decides how/where to open them. Used by the SDK control protocol
44 * (claude_authenticate) where the SDK client owns the user's display,
45 * not this process.
46 */
47 skipBrowserOpen?: boolean
48 },
49 ): Promise<OAuthTokens> {
50 // Create OAuth callback listener and start it
51 this.authCodeListener = new AuthCodeListener()
52 this.port = await this.authCodeListener.start()
53
54 // Generate PKCE values and state
55 const codeChallenge = crypto.generateCodeChallenge(this.codeVerifier)
56 const state = crypto.generateState()
57
58 // Build auth URLs for both automatic and manual flows
59 const opts = {
60 codeChallenge,
61 state,
62 port: this.port,
63 loginWithClaudeAi: options?.loginWithClaudeAi,
64 inferenceOnly: options?.inferenceOnly,
65 orgUUID: options?.orgUUID,
66 loginHint: options?.loginHint,
67 loginMethod: options?.loginMethod,
68 }
69 const manualFlowUrl = client.buildAuthUrl({ ...opts, isManual: true })
70 const automaticFlowUrl = client.buildAuthUrl({ ...opts, isManual: false })
71
72 // Wait for either automatic or manual auth code
73 const authorizationCode = await this.waitForAuthorizationCode(
74 state,
75 async () => {
76 if (options?.skipBrowserOpen) {
77 // Hand both URLs to the caller. The automatic one still works
78 // if the caller opens it on the same host (localhost listener
79 // is running); the manual one works from anywhere.
80 await authURLHandler(manualFlowUrl, automaticFlowUrl)
81 } else {
82 await authURLHandler(manualFlowUrl) // Show manual option to user
83 await openBrowser(automaticFlowUrl) // Try automatic flow
84 }
85 },
86 )
87
88 // Check if the automatic flow is still active (has a pending response)
89 const isAutomaticFlow = this.authCodeListener?.hasPendingResponse() ?? false

Callers 4

runHeadlessStreamingFunction · 0.95
authLoginFunction · 0.95
ConsoleOAuthFlowFunction · 0.80
OAuthFlowStepFunction · 0.80

Calls 9

formatTokensMethod · 0.95
openBrowserFunction · 0.85
logEventFunction · 0.85
hasPendingResponseMethod · 0.80
handleSuccessRedirectMethod · 0.80
handleErrorRedirectMethod · 0.80
startMethod · 0.45
closeMethod · 0.45

Tested by

no test coverage detected