MCPcopy
hub / github.com/claude-code-best/claude-code / enrollTrustedDevice

Function enrollTrustedDevice

src/bridge/trustedDevice.ts:98–210  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

96 * (e.g. lazy enrollment on /bridge 403) will fail with 403 stale_session.
97 */
98export async function enrollTrustedDevice(): Promise<void> {
99 try {
100 // checkGate_CACHED_OR_BLOCKING awaits any in-flight GrowthBook re-init
101 // (triggered by refreshGrowthBookAfterAuthChange in login.tsx) before
102 // reading the gate, so we get the post-refresh value.
103 if (!(await checkGate_CACHED_OR_BLOCKING(TRUSTED_DEVICE_GATE))) {
104 logForDebugging(
105 `[trusted-device] Gate ${TRUSTED_DEVICE_GATE} is off, skipping enrollment`,
106 )
107 return
108 }
109 // If CLAUDE_TRUSTED_DEVICE_TOKEN is set (e.g. by an enterprise wrapper),
110 // skip enrollment — the env var takes precedence in readStoredToken() so
111 // any enrolled token would be shadowed and never used.
112 if (process.env.CLAUDE_TRUSTED_DEVICE_TOKEN) {
113 logForDebugging(
114 '[trusted-device] CLAUDE_TRUSTED_DEVICE_TOKEN env var is set, skipping enrollment (env var takes precedence)',
115 )
116 return
117 }
118 // Lazy require — utils/auth.ts transitively pulls ~1300 modules
119 // (config → file → permissions → sessionStorage → commands). Daemon callers
120 // of getTrustedDeviceToken() don't need this; only /login does.
121 /* eslint-disable @typescript-eslint/no-require-imports */
122 const { getClaudeAIOAuthTokens } =
123 require('../utils/auth.js') as typeof import('../utils/auth.js')
124 /* eslint-enable @typescript-eslint/no-require-imports */
125 const accessToken = getClaudeAIOAuthTokens()?.accessToken
126 if (!accessToken) {
127 logForDebugging('[trusted-device] No OAuth token, skipping enrollment')
128 return
129 }
130 // Always re-enroll on /login — the existing token may belong to a
131 // different account (account-switch without /logout). Skipping enrollment
132 // would send the old account's token on the new account's bridge calls.
133 const secureStorage = getSecureStorage()
134
135 if (isEssentialTrafficOnly()) {
136 logForDebugging(
137 '[trusted-device] Essential traffic only, skipping enrollment',
138 )
139 return
140 }
141
142 const baseUrl = getOauthConfig().BASE_API_URL
143 let response
144 try {
145 response = await axios.post<{
146 device_token?: string
147 device_id?: string
148 }>(
149 `${baseUrl}/api/auth/trusted_devices`,
150 { display_name: `Claude Code on ${hostname()} · ${process.platform}` },
151 {
152 headers: {
153 Authorization: `Bearer ${accessToken}`,
154 'Content-Type': 'application/json',
155 },

Callers 1

callFunction · 0.85

Calls 9

getSecureStorageFunction · 0.85
isEssentialTrafficOnlyFunction · 0.85
getOauthConfigFunction · 0.85
jsonStringifyFunction · 0.85
logForDebuggingFunction · 0.50
errorMessageFunction · 0.50
readMethod · 0.45
clearMethod · 0.45

Tested by

no test coverage detected