From 9ff91f7c046655d33351e3d87b7a4506764ebc1f Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Wed, 4 Mar 2026 10:32:30 +0100 Subject: [PATCH] feat: support OAuth2 access tokens in addition to PATs The CLI currently hardcodes the `X-Figma-Token` header for all API requests, which only works with Personal Access Tokens. OAuth2 access tokens (prefixed with `figu_`) require the `Authorization: Bearer` header instead. This change detects OAuth2 tokens by their prefix and uses the correct header, while keeping PATs working as before. Also consolidates the duplicated header construction in run_wizard.ts to use the shared `getHeaders()` function. See: https://developers.figma.com/docs/rest-api/authentication/ --- cli/src/connect/figma_rest_api.ts | 15 ++++++++++++++- cli/src/connect/wizard/run_wizard.ts | 7 ++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cli/src/connect/figma_rest_api.ts b/cli/src/connect/figma_rest_api.ts index cac9fe2..c7aaa2d 100644 --- a/cli/src/connect/figma_rest_api.ts +++ b/cli/src/connect/figma_rest_api.ts @@ -11,9 +11,22 @@ export function getApiUrl(figmaNode: string, apiUrlOverride?: string) { return 'https://api.figma.com/v1' } +/** + * Returns the appropriate headers for Figma API requests. + * + * Figma supports two authentication methods with different headers: + * - Personal Access Tokens (PAT): `X-Figma-Token` header + * - OAuth2 access tokens: `Authorization: Bearer` header + * + * OAuth2 tokens are detected by their `figu_` prefix. + * + * @see https://developers.figma.com/docs/rest-api/authentication/ + */ export function getHeaders(accessToken: string) { return { - 'X-Figma-Token': accessToken, + ...(accessToken.startsWith('figu_') + ? { Authorization: `Bearer ${accessToken}` } + : { 'X-Figma-Token': accessToken }), 'Content-Type': 'application/json', 'User-Agent': `code-connect-cli/${version}`, } diff --git a/cli/src/connect/wizard/run_wizard.ts b/cli/src/connect/wizard/run_wizard.ts index 315fefc..bd22e30 100644 --- a/cli/src/connect/wizard/run_wizard.ts +++ b/cli/src/connect/wizard/run_wizard.ts @@ -2,7 +2,7 @@ import { BaseCommand, getAccessToken, getCodeConnectObjects, getDir } from '../. import prompts from 'prompts' import fs from 'fs' import { exitWithFeedbackMessage, findComponentsInDocument, parseFileKey } from '../helpers' -import { FigmaRestApi, getApiUrl } from '../figma_rest_api' +import { FigmaRestApi, getApiUrl, getHeaders } from '../figma_rest_api' import { exitWithError, logger, success } from '../../common/logging' import { ReactProjectInfo, @@ -105,10 +105,7 @@ async function fetchTopLevelComponentsFromFile({ ) as CliDataResponse, }) : request.get(apiUrl, { - headers: { - 'X-Figma-Token': accessToken, - 'Content-Type': 'application/json', - }, + headers: getHeaders(accessToken), }) ).finally(() => { if (cmd.verbose) {