(idToken: string)
| 159 | } |
| 160 | |
| 161 | function parseIdToken(idToken: string): IdTokenInfo | null { |
| 162 | try { |
| 163 | const parts = idToken.split(".") |
| 164 | if (parts.length !== 3) { |
| 165 | return null |
| 166 | } |
| 167 | const [, payloadB64] = parts |
| 168 | |
| 169 | let base64 = payloadB64.replace(/-/g, "+").replace(/_/g, "/") |
| 170 | while (base64.length % 4) { |
| 171 | base64 += "=" |
| 172 | } |
| 173 | |
| 174 | let payloadBytes: string |
| 175 | if (typeof atob !== "undefined") { |
| 176 | payloadBytes = atob(base64) |
| 177 | } else { |
| 178 | payloadBytes = Buffer.from(base64, "base64").toString("utf-8") |
| 179 | } |
| 180 | |
| 181 | const payload = JSON.parse(payloadBytes) |
| 182 | const authClaims = payload["https://api.openai.com/auth"] |
| 183 | return { |
| 184 | email: payload.email, |
| 185 | chatgpt_plan_type: authClaims?.chatgpt_plan_type, |
| 186 | chatgpt_account_id: authClaims?.chatgpt_account_id, |
| 187 | } |
| 188 | } catch { |
| 189 | return null |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | export async function requestUserCode(): Promise<DeviceCodeResponse> { |
| 194 | const response = await fetch(`${issuerPath("/api/accounts/deviceauth/usercode")}`, { |
no outgoing calls
no test coverage detected